diff -Nru a/CREDITS b/CREDITS
--- a/CREDITS	Mon Dec  9 18:46:50 2002
+++ b/CREDITS	Mon Dec  9 18:46:50 2002
@@ -1519,6 +1519,7 @@
 E: davej@suse.de
 W: http://www.codemonkey.org.uk
 D: x86 errata/setup maintenance.
+D: AGPGART driver.
 D: Backport/Forwardport merge monkey.
 D: Various Janitor work.
 S: c/o SuSE Linux UK Ltd
@@ -2248,6 +2249,15 @@
 S: Toronto, Ontario
 S: Canada
 
+N: Zwane Mwaikambo
+E: zwane@linuxpower.ca
+W: http://function.linuxpower.ca
+D: Various driver hacking
+D: Lowlevel x86 kernel hacking
+D: General debugging
+S: (ask for current address)
+S: Tanzania
+
 N: Trond Myklebust
 E: trond.myklebust@fys.uio.no
 D: current NFS client hacker.
@@ -2480,13 +2490,10 @@
 D: CDROM driver "sonycd535" (Sony CDU-535/531)
 
 N: Stelian Pop
-E: stelian.pop@fr.alcove.com
+E: stelian@popies.net
 P: 1024D/EDBB6147 7B36 0E07 04BC 11DC A7A0  D3F7 7185 9E7A EDBB 6147
 D: sonypi, meye drivers, mct_u232 usb serial hacks
-S: Alcôve
-S: 153, bd. Anatole France 
-S: 93200 Saint Denis
-S: France
+S: Paris, France
 
 N: Frederic Potter 
 E: fpotter@cirpack.com
@@ -2722,7 +2729,7 @@
 N: Thomas Sailer
 E: t.sailer@alumni.ethz.ch
 E: HB9JNX@HB9W.CHE.EU (packet radio)
-D: hfmodem, Baycom and sound card radio modem driver
+D: Baycom driver
 S: Markusstrasse 18
 S: 8006 Zuerich
 S: Switzerland
@@ -2836,6 +2843,16 @@
 S: 76131 Karlsruhe
 S: Germany
 
+N: James Simmons 
+E: jsimmons@users.sf.net 
+D: Frame buffer device maintainer
+D: input layer developement 
+D: tty/console layer
+D: various mipsel devices 
+S: 115 Carmel Avenue 
+S: El Cerrito CA 94530
+S: USA 
+
 N: Jaspreet Singh
 E: jaspreet@sangoma.com
 W: www.sangoma.com
@@ -3093,8 +3110,14 @@
 S: Germany
 
 N: Greg Ungerer
-E: gerg@moreton.com.au
+E: gerg@snapgear.com
+D: uClinux kernel hacker
+D: Port uClinux to the Motorola ColdFire CPU
 D: Author of Stallion multiport serial drivers
+S: SnapGear Inc.
+S: 825 Stanley St
+S: Woolloongabba. QLD. 4102
+S: Australia
 
 N: Jeffrey A. Uphoff
 E: juphoff@transmeta.com
diff -Nru a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
--- a/Documentation/DocBook/kernel-api.tmpl	Mon Dec  9 18:46:34 2002
+++ b/Documentation/DocBook/kernel-api.tmpl	Mon Dec  9 18:46:34 2002
@@ -365,7 +365,7 @@
 !Edrivers/video/fbmem.c
      </sect1>
      <sect1><title>Frame Buffer Console</title>
-!Edrivers/video/fbcon.c
+!Edrivers/video/console/fbcon.c
      </sect1>
      <sect1><title>Frame Buffer Colormap</title>
 !Edrivers/video/fbcmap.c
@@ -385,7 +385,7 @@
 !Idrivers/video/macmodes.c
      </sect1>
      <sect1><title>Frame Buffer Fonts</title>
-!Idrivers/video/fonts.c
+!Idrivers/video/console/fonts.c
      </sect1>
   </chapter>
 <!-- Needs ksyms to list additional exported symbols, but no specific doc.
diff -Nru a/Documentation/DocBook/kernel-locking.tmpl b/Documentation/DocBook/kernel-locking.tmpl
--- a/Documentation/DocBook/kernel-locking.tmpl	Mon Dec  9 18:46:36 2002
+++ b/Documentation/DocBook/kernel-locking.tmpl	Mon Dec  9 18:46:36 2002
@@ -1055,10 +1055,8 @@
       Another common problem is deleting timers which restart
       themselves (by calling <function>add_timer()</function> at the end 
       of their timer function).  Because this is a fairly common case 
-      which is prone to races, you can put a call to
-      <function>timer_exit()</function> at the very end of your timer function,
-      and user <function>del_timer_sync()</function> 
-      (<filename class=headerfile>include/linux/timer.h</filename>)
+      which is prone to races, you should use <function>del_timer_sync()</function> 
+      (<filename class=headerfile>include/linux/timer.h</filename>) 
       to handle this case.  It returns the number of times the timer 
       had to be deleted before we finally stopped it from adding itself back 
       in.
diff -Nru a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt
--- a/Documentation/block/biodoc.txt	Mon Dec  9 18:46:50 2002
+++ b/Documentation/block/biodoc.txt	Mon Dec  9 18:46:50 2002
@@ -1175,7 +1175,7 @@
 8.12. Multiple block-size transfers for faster raw i/o (Shailabh Nagar,
       Badari)
 8.13  Priority based i/o scheduler - prepatches (Arjan van de Ven)
-8.14  IDE Taskfile i/o patch (Andre Hedrik)
+8.14  IDE Taskfile i/o patch (Andre Hedrick)
 8.15  Multi-page writeout and readahead patches (Andrew Morton)
 8.16  Direct i/o patches for 2.5 using kvec and bio (Badari Pulavarthy)
 
diff -Nru a/Documentation/crypto/api-intro.txt b/Documentation/crypto/api-intro.txt
--- a/Documentation/crypto/api-intro.txt	Mon Dec  9 18:46:50 2002
+++ b/Documentation/crypto/api-intro.txt	Mon Dec  9 18:46:50 2002
@@ -176,7 +176,7 @@
   Nettle (http://www.lysator.liu.se/~nisse/nettle/)
     Niels Möller
 
-Original developers of the initial set of crypto algorithms:
+Original developers of the crypto algorithms:
 
   Dana L. How (DES)
   Andrew Tridgell and Steve French (MD4)
@@ -184,17 +184,24 @@
   Steve Reid (SHA1)
   Jean-Luc Cooke (SHA256)
   Kazunori Miyazawa / USAGI (HMAC)
-
-The DES code was subsequently redeveloped by:
-
+  Matthew Skala (Twofish)
+  Dag Arne Osvik (Serpent)
+  
+DES algorithm contributors:
   Raimar Falke
   Gisle Sælensminde
   Niels Möller
 
-The Blowfish code was subsequently redeveloped by:
+Blowfish algorithm contributors:
   Herbert Valerio Riedel
   Kyle McMartin
 
+Twofish algorithm contributors:
+  Werner Koch
+  Marc Mutz
+
+SHA256 algorithm contributors:
+  Andrew McDonald
 
 Please send any credits updates or corrections to:
 James Morris <jmorris@intercode.com.au>
diff -Nru a/Documentation/fb/README-sstfb.txt b/Documentation/fb/README-sstfb.txt
--- a/Documentation/fb/README-sstfb.txt	Mon Dec  9 18:46:35 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,174 +0,0 @@
-
-Introduction
-
-	  This is a frame buffer device driver for 3dfx' Voodoo Graphics 
-	(aka voodoo 1, aka sst1) and Voodoo² (aka Voodoo 2, aka CVG) based 
-	video boards. It's highly experimental code, but is guaranteed to work
-	on my computer, with my "Maxi Gamer 3D" and "Maxi Gamer 3d²" boards,
-	and with me "between chair and keyboard". Some people tested other
-	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 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@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... 
-
-
-Installation 
-
-	  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.
-
-	  Then configure your kernel as usual: choose "m" or "y" to 3Dfx Voodoo
-	Graphics in section "console". Compile, install, have fun... and please
-	drop me a report :)
-
-
-Module Usage
-	
-	Warnings.
-	# You should read completely this section before issuing any command.
-	# If you have only one monitor to play with, once you insmod the
-	  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 solution is pass the
-	  parameter vgapass=1 when insmodding the driver. (See Kernel/Modules
-	  Options)
-
-	Module insertion:
-	# insmod sstfb.o
-	  you should see some strange output frome the board: 
-	  a big blue square, a green and a red small squares and a vertical
-	  white rectangle. why ? the function's name is self explanatory :
-	  "sstfb_test()"...
-	  (if you don't have a second monitor, you'll have to plug your monitor
-	  directely to the 2D videocard to see what you're typing)
-	# con2fb /dev/fbx /dev/ttyx
-	  bind a tty to the new frame buffer. if you already have a frame
-	  buffer driver, the voodoo fb will likely be /dev/fb1. if not, 
-	  the device will be /dev/fb0. You can check this by doing a 
-	  cat /proc/fb. You can find a copy of con2fb in tools/ directory.
-	  if you don't have another fb device, this step is superfluous,
-	  as the console subsystem automagicaly binds ttys to the fb.
-	# switch to the virtual console you just mapped. "tadaaa" ...
-
-	Module removal:
-	# con2fb /dev/fbx /dev/ttyx
-	  bind the tty to the old frame buffer so the module can be removed.
-	  (how does it work with vgacon ? short answer : it doesn't work)
-	# rmmod sstfb
-
-
-Kernel/Modules Options
-
-	You can pass some otions to sstfb module, and via the kernel command
-	line when the driver is compiled in :
-	for module : insmod sstfb.o option1=value1 option2=value2 ...
-	in kernel :  video=sstfb:option1,option2:value2,option3 ...
-	
-	sstfb supports the folowing options :
-
-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
-
-	These tools are mostly for debugging purposes, but you can 
-	find some of these interesting :
-	 - con2fb , maps a tty to a fbramebuffer .
-		con2fb /dev/fb1 /dev/tty5
-	 - sst_dbg_vgapass , changes vga passthrou. You have to recompile the
-	driver with SST_DEBUG and SST_DEBUG_IOCTL set to 1
-		sst_dbg_vgapass /dev/fb1 1 (enables vga cable)
-		sst_dbg_vgapass /dev/fb1 0 (disables vga cable)
-	 - glide_reset , resets the voodoo using glide
-		use this after rmmoding sstfb, if the module refuses to
-		reinsert .
-
-Bugs
-
-	- 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), 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.
-	- The driver is not your_favorite_toy-safe. this includes SMP...
-          [Actually from inspection it seems to be safe - Alan]
-	- when using XFree86 FBdev (X over fbdev) you may see strange color
-	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. 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
-        initialisation will fail. this is specificaly true for
-	voodoo 2 boards , but it should be solved in recent versions. please
-	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
-
-	- Get rid of the previous paragraph.
-	- Buy more coffee.
-	- test/port to other arch.
-	- try to add panning using tweeks with front and back buffer .
-	- 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@laposte.net>
-
-
-$Date: 2002/05/09 20:11:45 $
-http://sstfb.sourceforge.net/README
diff -Nru a/Documentation/fb/internals.txt b/Documentation/fb/internals.txt
--- a/Documentation/fb/internals.txt	Mon Dec  9 18:46:37 2002
+++ b/Documentation/fb/internals.txt	Mon Dec  9 18:46:37 2002
@@ -3,6 +3,7 @@
 internals.
 
 Geert Uytterhoeven <geert@linux-m68k.org>, 21 July 1998
+James Simmons <jsimmons@user.sf.net>, Nov 26 2002
 
 --------------------------------------------------------------------------------
 
@@ -43,10 +44,6 @@
 
     Device dependent information that uniquely defines the video mode for this
     particular piece of hardware.
-
-  - struct display
-
-    Interface between the frame buffer device and the console driver.
 
 
 --------------------------------------------------------------------------------
diff -Nru a/Documentation/fb/sstfb.txt b/Documentation/fb/sstfb.txt
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/fb/sstfb.txt	Mon Dec  9 18:46:35 2002
@@ -0,0 +1,174 @@
+
+Introduction
+
+	  This is a frame buffer device driver for 3dfx' Voodoo Graphics 
+	(aka voodoo 1, aka sst1) and Voodoo² (aka Voodoo 2, aka CVG) based 
+	video boards. It's highly experimental code, but is guaranteed to work
+	on my computer, with my "Maxi Gamer 3D" and "Maxi Gamer 3d²" boards,
+	and with me "between chair and keyboard". Some people tested other
+	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 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@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... 
+
+
+Installation 
+
+	  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.
+
+	  Then configure your kernel as usual: choose "m" or "y" to 3Dfx Voodoo
+	Graphics in section "console". Compile, install, have fun... and please
+	drop me a report :)
+
+
+Module Usage
+	
+	Warnings.
+	# You should read completely this section before issuing any command.
+	# If you have only one monitor to play with, once you insmod the
+	  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 solution is pass the
+	  parameter vgapass=1 when insmodding the driver. (See Kernel/Modules
+	  Options)
+
+	Module insertion:
+	# insmod sstfb.o
+	  you should see some strange output frome the board: 
+	  a big blue square, a green and a red small squares and a vertical
+	  white rectangle. why ? the function's name is self explanatory :
+	  "sstfb_test()"...
+	  (if you don't have a second monitor, you'll have to plug your monitor
+	  directely to the 2D videocard to see what you're typing)
+	# con2fb /dev/fbx /dev/ttyx
+	  bind a tty to the new frame buffer. if you already have a frame
+	  buffer driver, the voodoo fb will likely be /dev/fb1. if not, 
+	  the device will be /dev/fb0. You can check this by doing a 
+	  cat /proc/fb. You can find a copy of con2fb in tools/ directory.
+	  if you don't have another fb device, this step is superfluous,
+	  as the console subsystem automagicaly binds ttys to the fb.
+	# switch to the virtual console you just mapped. "tadaaa" ...
+
+	Module removal:
+	# con2fb /dev/fbx /dev/ttyx
+	  bind the tty to the old frame buffer so the module can be removed.
+	  (how does it work with vgacon ? short answer : it doesn't work)
+	# rmmod sstfb
+
+
+Kernel/Modules Options
+
+	You can pass some otions to sstfb module, and via the kernel command
+	line when the driver is compiled in :
+	for module : insmod sstfb.o option1=value1 option2=value2 ...
+	in kernel :  video=sstfb:option1,option2:value2,option3 ...
+	
+	sstfb supports the folowing options :
+
+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
+
+	These tools are mostly for debugging purposes, but you can 
+	find some of these interesting :
+	 - con2fb , maps a tty to a fbramebuffer .
+		con2fb /dev/fb1 /dev/tty5
+	 - sst_dbg_vgapass , changes vga passthrou. You have to recompile the
+	driver with SST_DEBUG and SST_DEBUG_IOCTL set to 1
+		sst_dbg_vgapass /dev/fb1 1 (enables vga cable)
+		sst_dbg_vgapass /dev/fb1 0 (disables vga cable)
+	 - glide_reset , resets the voodoo using glide
+		use this after rmmoding sstfb, if the module refuses to
+		reinsert .
+
+Bugs
+
+	- 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), 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.
+	- The driver is not your_favorite_toy-safe. this includes SMP...
+          [Actually from inspection it seems to be safe - Alan]
+	- when using XFree86 FBdev (X over fbdev) you may see strange color
+	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. 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
+        initialisation will fail. this is specificaly true for
+	voodoo 2 boards , but it should be solved in recent versions. please
+	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
+
+	- Get rid of the previous paragraph.
+	- Buy more coffee.
+	- test/port to other arch.
+	- try to add panning using tweeks with front and back buffer .
+	- 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@laposte.net>
+
+
+$Date: 2002/05/09 20:11:45 $
+http://sstfb.sourceforge.net/README
diff -Nru a/Documentation/filesystems/vfat.txt b/Documentation/filesystems/vfat.txt
--- a/Documentation/filesystems/vfat.txt	Mon Dec  9 18:46:37 2002
+++ b/Documentation/filesystems/vfat.txt	Mon Dec  9 18:46:37 2002
@@ -8,9 +8,11 @@
 
 VFAT MOUNT OPTIONS
 ----------------------------------------------------------------------
-umask=###     -- The permission mask (see umask(1)) for the regulare file.
+umask=###     -- The permission mask (for files and directories, see umask(1)).
                  The default is the umask of current process.
 dmask=###     -- The permission mask for the directory.
+                 The default is the umask of current process.
+fmask=###     -- The permission mask for files.
                  The default is the umask of current process.
 codepage=###  -- Sets the codepage for converting to shortname characters
 		 on FAT and VFAT filesystems.  By default, codepage 437
diff -Nru a/Documentation/networking/netdevices.txt b/Documentation/networking/netdevices.txt
--- a/Documentation/networking/netdevices.txt	Mon Dec  9 18:46:35 2002
+++ b/Documentation/networking/netdevices.txt	Mon Dec  9 18:46:35 2002
@@ -12,31 +12,36 @@
 struct net_device synchronization rules
 =======================================
 dev->open:
-	Locking: Inside rtnl_lock() semaphore.
-	Sleeping: OK
+	Synchronization: rtnl_lock() semaphore.
+	Context: process
 
 dev->stop:
-	Locking: Inside rtnl_lock() semaphore.
-	Sleeping: OK
+	Synchronization: rtnl_lock() semaphore.
+	Context: process
+	Notes: netif_running() is guaranteed false when this is called
 
 dev->do_ioctl:
-	Locking: Inside rtnl_lock() semaphore.
-	Sleeping: OK
+	Synchronization: rtnl_lock() semaphore.
+	Context: process
 
 dev->get_stats:
-	Locking: Inside dev_base_lock spinlock.
-	Sleeping: NO
+	Synchronization: dev_base_lock rwlock.
+	Context: nominally process, but don't sleep inside an rwlock
 
 dev->hard_start_xmit:
-	Locking: Inside dev->xmit_lock spinlock.
-	Sleeping: NO
+	Synchronization: dev->xmit_lock spinlock.
+	Context: BHs disabled
 
 dev->tx_timeout:
-	Locking: Inside dev->xmit_lock spinlock.
-	Sleeping: NO
+	Synchronization: dev->xmit_lock spinlock.
+	Context: BHs disabled
 
 dev->set_multicast_list:
-	Locking: Inside dev->xmit_lock spinlock.
-	Sleeping: NO
+	Synchronization: dev->xmit_lock spinlock.
+	Context: BHs disabled
 
+dev->poll:
+	Synchronization: __LINK_STATE_RX_SCHED bit in dev->state.  See
+		dev_close code and comments in net/core/dev.c for more info.
+	Context: softirq
 
diff -Nru a/Documentation/s390/Debugging390.txt b/Documentation/s390/Debugging390.txt
--- a/Documentation/s390/Debugging390.txt	Mon Dec  9 18:46:35 2002
+++ b/Documentation/s390/Debugging390.txt	Mon Dec  9 18:46:35 2002
@@ -41,6 +41,7 @@
 Debugging modules
 The proc file system
 Starting points for debugging scripting languages etc.
+Dumptool & Lcrash
 SysRq
 References
 Special Thanks
@@ -237,10 +238,9 @@
 
 
 On 390 our limitations & strengths make us slightly different.
-For backward compatibility ( because of the psw address hi bit which
-indicates whether we are in 31 or 64 bit mode ) we are only allowed 
-use 31 bits (2GB) of our 32 bit addresses. However, 
-we use entirely separate address  spaces for the user & kernel.
+For backward compatibility we are only allowed use 31 bits (2GB)
+of our 32 bit addresses,however, we use entirely separate address 
+spaces for the user & kernel.
 
 This means we can support 2GB of non Extended RAM on s/390, & more
 with the Extended memory managment swap device & 
@@ -1288,14 +1288,10 @@
 circumstances as the process may change when doing a 
 TR I R <address range>.
 Thankfully after reading VM's online help I figured out how to debug
-particular processes in 31 bit mode, however, according to the current 
-VM online help documentation the method described below uses 
-TR STO or STD which don't currently work on  z/Series while in 
-64-bit mode.
+I particular process.
 
 Your first problem is to find the STD ( segment table designation )
 of the program you wish to debug.
-
 There are several ways you can do this here are a few
 1) objdump --syms <program to be debugged> | grep main
 To get the address of main in the program.
@@ -1475,12 +1471,6 @@
 D 00014CB4.20
 V00014CB4  2F646576 2F636F6E 736F6C65 00001BF5
 V00014CC4  FC00014C B4001001 E0001000 B8070707
-
-Alternatively you can do the more elegant
-D 0.20;BASE2
-BASE2 telling VM to use GPR2 as the base register.
-
-
 Now copy the text till the first 00 hex ( which is the end of the string
 to an xterm & do hex2ascii on it.
 hex2ascii 2F646576 2F636F6E 736F6C65 00 
@@ -1517,7 +1507,7 @@
 	  c=c-'0';
        if(c>='A'&&c<='F')
 	  c=c-'A'+10;
-       if(c>='a'&&c<='F')
+       if(c>='a'&&c<='f')
 	  c=c-'a'+10;
        switch(toggle)
        {
@@ -2131,12 +2121,6 @@
 p/x (*(**$sp+56))&0x7fffffff
 & so on.
 
-Another good trick to look at addresses on the stack if you've somehow lost 
-the backchain is.
-x/500xa $sp
-This displays anything the name of any known functions above the stack pointer
-for 500 bytes.
-
 Disassembling instructions without debug info
 ---------------------------------------------
 gdb typically compains if there is a lack of debugging
@@ -2472,12 +2456,48 @@
 
 
 
+Dumptool & Lcrash ( lkcd )
+==========================
+Michael Holzheu & others here at IBM have a fairly mature port of 
+SGI's lcrash tool which allows one to look at kernel structures in a
+running kernel.
+
+It also complements a tool called dumptool which dumps all the kernels
+memory pages & registers to either a tape or a disk.
+This can be used by tech support or an ambitous end user do
+post mortem debugging of a machine like gdb core dumps.
+
+Going into how to use this tool in detail will be explained
+in other documentation supplied by IBM with the patches & the 
+lcrash homepage http://oss.sgi.com/projects/lkcd/ & the lcrash manpage.
+
+How they work
+-------------
+Lcrash is a perfectly normal program,however, it requires 2 
+additional files, Kerntypes which is built using a patch to the 
+linux kernel sources in the linux root directory & the System.map.
+
+Kerntypes is an an objectfile whose sole purpose in life
+is to provide stabs debug info to lcrash, to do this
+Kerntypes is built from kerntypes.c which just includes the most commonly
+referenced header files used when debugging, lcrash can then read the
+.stabs section of this file.
+
+Debugging a live system it uses /dev/mem
+alternatively for post mortem debugging it uses the data 
+collected by dumptool.
+
+
+
 SysRq
 =====
 This is now supported by linux for s/390 & z/Architecture.
 To enable it do compile the kernel with 
 Kernel Hacking -> Magic SysRq Key Enabled
-echo "1" > /proc/sys/kernel/sysrq.
+echo "1" > /proc/sys/kernel/sysrq
+also type
+echo "8" >/proc/sys/kernel/printk
+To make printk output go to console.
 On 390 all commands are prefixed with
 ^-
 e.g.
@@ -2513,4 +2533,4 @@
 Special thanks to Neale Ferguson who maintains a much
 prettier HTML version of this page at
 http://penguinvm.princeton.edu/notes.html#Debug390
-
+Bob Grainger Stefan Bader & others for reporting bugs
diff -Nru a/Documentation/s390/cds.txt b/Documentation/s390/cds.txt
--- a/Documentation/s390/cds.txt	Mon Dec  9 18:46:50 2002
+++ b/Documentation/s390/cds.txt	Mon Dec  9 18:46:50 2002
@@ -1,14 +1,13 @@
-Linux/390
+Linux for S/390 and zSeries
 
 Common Device Support (CDS)
 Device Driver I/O Support Routines
 
-Author : Ingo Adlung
+Authors : Ingo Adlung
+	  Cornelia Huck
 
 Copyright, IBM Corp. 1999-2002
 
-ChangeLog: 02/01/2002   Cornelia Huck    brought up-to-date
-
 Introduction
 
 This document describes the common device support routines for Linux/390.
@@ -34,12 +33,24 @@
 below. Some of them implement common Linux device driver interfaces, while 
 some of them are ESA/390 platform specific.
 
-get_dev_info_by_irq() / get_dev_info_by_devno()	
-   allow a device driver to determine the devices attached (visible) to the
-   system and their current status.
-
-get_irq_by_devno() / get_devno_by_irq()	
-   get irq (subchannel) from device number and vice versa.
+Note:
+In order to write a driver for S/390, you also need to look into the interface
+described in Documentation/s390/driver-model.txt.
+
+Note for porting drivers from 2.4:
+The major changes are:
+* The functions use a ccw_device instead of an irq (subchannel).
+* All drivers must define a ccw_driver (see driver-model.txt) and the associated
+  functions.
+* request_irq() and free_irq() are no longer done by the driver.
+* The oper_handler is (kindof) replaced by the probe() and set_online() functions
+  of the ccw_driver.
+* The not_oper_handler is (kindof) replaced by the remove() and set_offline()
+  functions of the ccw_driver.
+* The channel device layer is gone.
+* The interrupt handlers must be adapted to use a ccw_device as argument.
+  Moreover, they don't return a devstat, but an irb.
+* Before initiating an io, the options must be set via ccw_device_set_options().
 
 read_dev_chars()	
    read device characteristics
@@ -47,29 +58,16 @@
 read_conf_data()
    read configuration data.
 
-request_irq()	
-   obtain ownership for a specific device.
-
-s390_request_irq_special()
-   obtain ownership for a specific device. Similar to request_irq(), but
-   allows for device not operational notification too.
-
-free_irq()	
-   release ownership for a specific device.
+ccw_device_get_ciw()
+   get commands from extended sense data.
 
-disable_irq()	
-   disable a device from presenting interrupts.
-
-enable_irq()	
-   enable a device, allowing for I/O interrupts.
-
-do_IO()	
+ccw_device_start()	
    initiate an I/O request.
 
-resume_IO()
+ccw_device_resume()
    resume channel program execution.
 
-halt_IO()	
+ccw_device_halt()	
    terminate the current I/O request processed on the device.
 
 do_IRQ()	
@@ -133,258 +131,71 @@
 subchannels to Linux as IRQs. This allows Linux/390 to support up to 64k
 different IRQs, uniquely representig a single device each.
 
+Up to kernel 2.4, Linux/390 used to provide interfaces via the IRQ (subchannel).
+For internal use of the common I/O layer, these are still there. However, 
+device drivers should use the new calling interface via the ccw_device only.
+
 During its startup the Linux/390 system checks for peripheral devices. Each
 of those devices is uniquely defined by a so called subchannel by the ESA/390
 channel subsystem. While the subchannel numbers are system generated, each
 subchannel also takes a user defined attribute, the so called device number.
-Both subchannel number and device number can not exceed 65535. The
-init_IRQ() routine gathers the information about control unit type and device
-types that imply specific I/O commands (channel command words - CCWs) in
-order to operate the device. Device drivers can retrieve this set of hardware
+Both subchannel number and device number can not exceed 65535. During driverfs
+initialisation, the information about control unit type and device types that 
+imply specific I/O commands (channel command words - CCWs) in order to operate
+the device are gathered. Device drivers can retrieve this set of hardware
 information during their initialization step to recognize the devices they
-support using get_dev_info_by_irq() or get_dev_info_by_devno() respectively.
+support using the information saved in the struct ccw_device given to them.
 This methods implies that Linux/390 doesn't require to probe for free (not
 armed) interrupt request lines (IRQs) to drive its devices with. Where
 applicable, the device drivers can use the read_dev_chars() to retrieve device
 characteristics. This can be done without having to request device ownership
 previously.
 
-When a device driver has recognized a device it wants to claim ownership for,
-it calls request_irq() with the device's subchannel id serving as pseudo irq
-line. One of the required parameters it has to specify is dev_id, defining a
-device status block which the CDS layer will use to notify the device driver's
-interrupt handler about interrupt information observed. It depends on the
-device driver to properly handle those interrupts.
-
-In order to allow for easy I/O initiation the CDS layer provides a do_IO()
-interface that takes a device specific channel program (one or more CCWs) as
-input sets up the required architecture specific control blocks and initiates
-an I/O request on behalf of the device driver. The do_IO() routine allows for
-different I/O methods, synchronous and asynchronous, and allows to specify
-whether it expects the CDS layer to notify the device driver for every
-interrupt it observes, or with final status only. It also provides a scheme
-to allow for overlapped I/O processing. See do_IO() for more details. A device
-driver must never issue ESA/390 I/O commands itself, but must use the
-Linux/390 CDS interfaces instead.
+In order to allow for easy I/O initiation the CDS layer provides a
+ccw_device_start() interface that takes a device specific channel program (one
+or more CCWs) as input sets up the required architecture specific control blocks
+and initiates an I/O request on behalf of the device driver. The
+ccw_device_start() routine allows to specify whether it expects the CDS layer
+to notify the device driver for every interrupt it observes, or with final status
+only. See ccw_device_start() for more details. A device driver must never issue
+ESA/390 I/O commands itself, but must use the Linux/390 CDS interfaces instead.
 
 For long running I/O request to be canceled, the CDS layer provides the
-halt_IO() function. Some devices require to initially issue a HALT SUBCHANNEL
-(HSCH) command without having pending I/O requests. This function is also
-covered by halt_IO().
-
-When done with a device, the device driver calls free_irq() to release its
-ownership for the device. During free_irq() processing the CDS layer also
-disables the device from presenting further interrupts - the device driver
-doesn't need to assure it. The device will be reenabled for interrupts with
-the next call to request_irq().
-
-
-
-get_irq_first() / get_irq_next() - Retrieve Information about available IRQs 
-
-A device driver can use those interface routines to retrieve information for 
-those IRQs only that have valid device information available. As 
-Linux for S/390 supports a maximum of 65535 subchannels (devices), it might 
-be a waste of CPU to scan for the max number of  devices while a fraction is 
-available/usable only. get_irq_first() will retrieve the first usable IRQ. 
-Using this as input get_irq_next() will retrieve the next IRQ available, etc..
-
-int get_irq_first( void );
-int get_irq_next( int irq );
-
-irq - defines the subchannel to start scanning with. This must be
-      a valid subchannel or an error is returned. 
-
-The get_irq_first() / get_irq_next() functions return:
-
-non-negative value - next available IRQ
-          -ENODEV  - no more IRQs available
-
-Example : 
-
- irq = get_irq_first();
- while ( irq != -ENODEV) 
- {
-  get_dev_info_by_irq( irq, &dinfo);
-  if (    dinfo.devno == devno_to_look_for 
-       || dinfo.sid_data.cu_type == cu_type_to_look_for )
-  {
-   do_some_action( irq, &dinfo ); 
-  } /* endif */
-    
-  irq = get_irq_next(irq);
- }
-
-get_dev_info_by_irq() / get_dev_info_by_devno() - Retrieve Device Information
-
-During system startup - init_IRQ() processing - the generic I/O device support
-checks for the devices available. For all devices found it collects the
-SenseID information. For those devices supporting the command it also obtains
-extended SenseID information.
-
-int get_dev_info_by_irq( int             irq,
-                         s390_dev_info_t *pdi);
-
-int get_dev_info_by_devno( __u16           devno,
-                           s390_dev_info_t *pdi);
-
-irq     - defines the subchannel status information is to be
-          returned for.
-devno   - device number.
-pdi     - pointer to a user buffer of type s390_dev_info_t that should
-          be filled with device specific information.
-
-typedef struct {
-     int          irq;                  /* irq, aka. subchannel */
-     __u16        devno;                /* device number */
-     unsigned int status;               /* device status */
-     senseid_t    sid_data;             /* senseID data */
-} s390_dev_info_t;			
-
-irq       - subchannel.
-devno     - device number as configured in the IOCDS.
-status    - device status
-sid_data  - data obtained by a SenseID call
-
-Possible status values are :
-
-DEVSTAT_NOT_OPER - device was found not-operational. In this case
-                   the caller should disregard the sid_data
-                   buffer content.
-
-//
-// sense-id response buffer layout
-//
-typedef struct {
-  /* common part */
-      __u8           reserved;     /* always 0x'FF' */
-      __u16          cu_type;      /* control unit type */
-      __u8           cu_model;     /* control unit model */
-      __u16          dev_type;     /* device type */
-      __u8           dev_model;    /* device model */
-      __u8           unused;       /* padding byte */
-  /* extended part */
-      ciw_t    ciw[MAX_CIWS];      /* variable # of CIWs */
-}  __attribute__ ((packed,aligned(4))) senseid_t;
-
-MAX_CIWS is currently defined as 8.
-
-The ESA/390 I/O architecture defines certain device specific I/O functions.
-The device returns the device specific command code together with the SenseID
-data in so called Command Information Words (CIW) :
-
-typedef struct _ciw {
-   __u32        et       :  2; // entry type
-   __u32        reserved :  2; // reserved
-   __u32        ct       :  4; // command type
-   __u32        cmd      :  8; // command
-   __u32        count    : 16; // count
-} __attribute__ ((packed)) ciw_t;
-
-Possible CIW entry types are :
-
-#define CIW_TYPE_RDC    0x0;      // read configuration data
-#define CIW_TYPE_SII    0x1;      // set interface identifier
-#define CIW_TYPE_RNI    0x2;      // read node identifier
-
-The device driver may use these commands as appropriate.
-
-The get_dev_info_by_irq() / get_dev_info_by_devno() functions return:
-
-      0 - successful completion
--ENODEV - irq or devno don't specify a known subchannel or device
-          number.
--EINVAL - invalid devinfo value.
-
-Usage Notes :
-
-In order to scan for known devices a device driver should scan all irqs by
-calling     get_dev_info() until it returns -ENODEV as there aren't any more
-available devices.
-
-If a device driver wants to request ownership for a specific device, it must
-call request_irq() prior to be able to issue any I/O request for it, including
-above mentioned   device dependent commands.
-
-Please see the "ESA/390 Common I/O-Commandss and Self Description" manual,
-with IBM form number SA22-7204 for more details on how to read the Sense-ID
-output, CIWs and device independent commands.
-
-
-
-get_irq_by_devno() / get_devno_by_irq() - Convert device identifiers
-
-While some device drivers act on the irq (subchannel) only, others take user
-defined device configurations on device number base, according to the device
-numbers configured in the IOCDS. The following routines serve the purpose to
-convert irq values into device numbers and vice versa.
-
-int get_irq_by_devno( __u16 devno );
-
-unsigned int get_devno_by_irq( int irq );
-
-The functions return :
-
-the requested irq/devno values
--1 if the requested conversion can't be accomplished.
-
-This could either be caused by irq/devno be outside the valid range
-( value > 0xffff or value < 0 ) or not identifying a known device.
+ccw_device_halt() function. Some devices require to initially issue a HALT
+SUBCHANNEL (HSCH) command without having pending I/O requests. This function is
+also covered by ccw_device_halt().
 
 
 read_dev_chars() - Read Device Characteristics
 
 This routine returns the characteristics for the device specified.
 
-The function is meant to be called without an irq handler be in place.
-However, the irq for the requested device must not be locked or this will
-cause a deadlock situation ! Further, the driver must assure that nobody
-else has claimed ownership for the requested irq yet or the owning device
-driver's internal accounting may be affected.
-
-In case of a registered interrupt handler, the interrupt handler must be
-able to properly react on interrupts related to the read_dev_chars() I/O
-commands. While the request is procesed synchronously, the device interrupt
+The function is meant to be called with an irq handler in place; that is,
+at earliest during set_online() processing.
+
+While the request is procesed synchronously, the device interrupt
 handler is called for final ending status. In case of error situations the
 interrupt handler may recover appropriately. The device irq handler can
 recognize the corresponding interrupts by the interruption parameter be
-0x00524443. If using the function with an existing device interrupt handler
-in place, the irq must be locked prior to call read_dev_chars().
+0x00524443.The ccw_device must not be locked prior to calling read_dev_chars().
 
 The function may be called enabled or disabled.
 
-int read_dev_chars( int irq, void **buffer, int length );
+int read_dev_chars(struct ccw_device *cdev, void **buffer, int length );
 
-irq    - specifies the subchannel the device characteristic
-         retrieval is requested for
+cdev   - the ccw_device the information is requested for.
 buffer - pointer to a buffer pointer. The buffer pointer itself
-         may be NULL to have the function allocate a buffer or
          must contain a valid buffer area.
-length - length of the buffer provided or to be allocated.
+length - length of the buffer provided.
 
 The read_dev_chars() function returns :
 
       0 - successful completion
--ENODEV - irq doesn't specify a valid subchannel number
--EINVAL - an invalid parameter was detected
+-ENODEV - cdev invalid
+-EINVAL - an invalid parameter was detected, or the function was called early.
 -EBUSY  - an irrecoverable I/O error occurred or the device is not
           operational.
 
-Usage Notes :
-
-The function can be used in two ways :
-
-If the caller doesn't provide a data buffer, read_dev_chars() allocates a
-data buffer and provides the device characteristics together. It's the
-caller's responsability to release the kernel memory if not longer needed.
-This behaviour is triggered by specifying a NULL buffer area (*buffer == NULL).
-
-Alternatively, if the user specifies a buffer area himself, nothing is
-allocated.
-
-In either case the caller must provide the data area length - for the buffer
-he specifies, or the buffer he wants to be allocated.
-
 
 read_conf_data() - Read Configuration Data
 
@@ -392,16 +203,15 @@
 device dependent I/O commands for the device specific layout of the node 
 descriptor elements. 
 
-The function is meant to be called without an irq handler be in place. However,
-the irq for the requested device must not be locked or this will cause a 
-deadlock situation ! 
+The function is meant to be called with an irq handler in place; that is,
+at earliest during set_online() processing.
 
-The function may be called enabled or disabled.
+The function may be called enabled or disabled, but the device must not be
+locked
 
-int read_conf_data( int irq, void **buffer, int *length, __u8 lpm);
+int read_conf_data(struct ccw_device, void **buffer, int *length, __u8 lpm);
 
-irq    - Specifies the subchannel the configuration data is to be
-         retrieved for.
+cdev   - the ccw_device the data is requested for.
 buffer - Pointer to a buffer pointer. The read_conf_data() routine
          will allocate a buffer and initialize the buffer pointer
          accordingly. It's the device driver's responsability to
@@ -412,8 +222,8 @@
 
 The read_conf_data() function returns :
           0 - Successful completion
--ENODEV     - irq doesn't specify a valid subchannel number
--EINVAL     - An invalid parameter was detected
+-ENODEV     - cdev invalid.
+-EINVAL     - An invalid parameter was detected, or the function was called early.
 -EIO        - An irrecoverable I/O error occured or the device is
               not operational.
 -ENOMEM     - The read_conf_data() routine couldn't obtain storage.
@@ -421,356 +231,65 @@
               data command.
 
 
-request_irq() - Request Device Ownership
-
-As previously discussed a device driver will scan for the devices its supports
-by calling get_dev_info(). Once it has found a device it will call
-request_irq() to request ownership for it. This call causes the subchannel to
-be enabled for interrupts if it was found operational.
-
-Note: This function is obsolete and provided for compatibility purposes only. 
-Device drivers should use s390_request_irq_special() instead. 
-
-int request_irq( unsigned int   irq,
-                 int          (*handler)( int,
-                                          void *,
-                                          struct pt_regs *),
-                 unsigned long  irqflags,
-                 const char    *devname,
-                 void          *dev_id);
-
-irq      : specifies the subchannel the ownership is requested for
-handler  : specifies the device driver's interrupt handler to be
-           called for interrupt processing
-irqflags : IRQ flags, currently ignored
-devname  : device name
-dev_id   : required pointer to a device specific buffer of type
-           devstat_t
-
-typedef struct {
-     __u16         devno;    /* device number, aka. "cuu" from irb */
-     unsigned long intparm;  /* interrupt parameter */
-     __u8          cstat;    /* channel status - accumulated */
-     __u8          dstat;    /* device status - accumulated */
-     __u8          lpum;     /* last path used mask from irb */
-     __u8          unused;   /* not used - reserved */
-     unsigned int  flag;     /* flag : see below */
-     __u32         cpa;      /* CCW address from irb at primary status */
-     __u32         rescnt;   /* res. count from irb at primary status */
-     __u32         scnt;     /* sense count, if DEVSTAT_FLAG_SENSE_AVAIL */
-     union {
-        irb_t   irb;         /* interruption response block */
-        sense_t sense;       /* sense information */
-     } ii;                /* interrupt information */
-} devstat_t;
-
-
-During request_irq() processing, the devstat_t layout does not matter as it
-won't be used during request_irq() processing. See do_IO() for a functional
-description of its usage.
-
-The request_irq() function returns :
-
-      0 - successful completion
--EINVAL - an invalid parameter was detected
--EBUSY  - device (subchannel) already owned
--ENODEV - the device is not-operational
--ENOMEM - not enough kernel memory to process request
-
-Usage Notes :
-
-While Linux for Intel defines dev_id as a unique identifier for shared
-interrupt lines it has a totally different purpose on Linux/390. Here it
-serves as a shared interrupt status area between the generic device support
-layer, and the device specific driver. The value passed to request_irq()
-must therefore point to a valid devstat_t type buffer area the device driver
-must preserve for later usage. I.e. it must not be released prior to a call
-to free_irq().
-
-Irqflags are currently ignored by the cds layer.
-The Linux/390 kernel does neither know about "fast" interrupt handlers, nor
-does it allow for interrupt sharing. Remember, the term interrupt level (irq),
-device, and subchannel are used interchangeably in Linux/390.
-
-If request_irq() was called in enabled state, or if multiple CPUs are present,
-the device may present an interrupt to the specified handler prior to
-request_irq() return to the caller  already ! This includes the possibility
-of unsolicited interrupts or a pending interrupt status from an earlier
-solicited I/O request. The device driver must be able to handle this situation
-properly or the device may become unoperational otherwise !
-
-Although the interrupt handler is defined to be called with a pointer to a
-struct pt_regs buffer area, this is not implemented by the Linux/390 generic
-I/O device driver support layer. The device driver's interrupt handler must
-therefore not rely on this parameter on function entry.
-
-
-s390_request_irq_special() - Request Device Ownership 
-
-As previously discussed a device driver will scan for the devices its supports 
-by calling get_dev_info(). Once it has found a device it will call 
-request_irq() to request ownership.
-
-Note:  This function replaces request_irq() described previously.
-
-int s390_request_irq_special( 
-                     int                      irq,
-                     io_handler_func_t        io_handler,
-                     not_oper_handler_func_t  not_oper_handler,
-                     unsigned long            irqflags,
-                     const char              *devname,
-                     void                    *dev_id);
-
-irq              : specifies the subchannel the ownership is
-                    requested for
-io_handler       : specifies the device driver's interrupt handler
-                    to be called for interrupt processing
-not_oper_handler : specifies a device driver "not operational" handler
-irqflags         : IRQ flags, currently ignored
-devname          : device name
-dev_id           : required pointer to a device specific buffer of
-                    type devstat_t
-
-
-typedef struct {
-     __u16         devno;    /* device number, aka. "cuu" from irb */
-     unsigned long intparm;  /* interrupt parameter */
-     __u8          cstat;    /* channel status - accumulated */
-     __u8          dstat;    /* device status - accumulated */
-     __u8          lpum;     /* last path used mask from irb */
-     __u8          unused;   /* not used - reserved */
-     unsigned int  flag;     /* flag : see below */
-     __u32         cpa;      /* CCW address from irb at primary status */
-     __u32         rescnt;   /* res. count from irb at primary status */
-     __u32         scnt;     /* sense count, if DEVSTAT_FLAG_SENSE_AVAIL */
-     union {
-        irb_t   irb;         /* interruption response block */
-        sense_t sense;       /* sense information */
-     } ii;                   /* interrupt information */
-} devstat_t;
-
-During request_irq() processing, the devstat_t layout does not matter as it 
-won't be used during request_irq() processing. See do_IO() for a functional 
-description of its usage.
-
-typedef  void (* io_handler_func_t) ( int             irq,
-                                      void           *devstat,
-                                      struct pt_regs *rgs);
-
-irq     : IRQ the interrupt handler is called for
-devstat : device status block
-rgs     : obsolete
-
-typedef (void)(* not_oper_handler_func_t)( int irq, 
-                                           int status );
-
-irq    : IRQ the not operational status has been encountered for
-status : device status
-         DEVSTAT_NOT_OPER    - device is not operational
-         DEVSTAT_REVALIDATE  - revalidate device number
-         DEVSTAT_DEVICE_GONE - no such device (irq)  
-
-Note: Revalidate indicates that running under VM the device number has been 
-modified by means of a DEFINE xxxx [as] yyyy command. Therewith device number 
-xxxx was altered to yyyy. It's the device drivers responsibility to decide 
-whether device ownership can be retained.
-
-Gone indicates that the device was detached under VM, or the device number 
-became invalid (native, LPAR). In order to prevent further I/O the IRQ was 
-implicitly freed on behalf of the device driver. The driver must not call 
-free_irq itself.
-
-Not Oper indicates the device became not operational. It's the device driver's 
-responsibility whether it wants to maintain ownership for the IRQ, or not. 
-
-The s390_request_irq_special() function returns :
-      0 - successful completion
--EINVAL - an invalid parameter was detected
--EBUSY  - device (subchannel) already owned 
--ENODEV - the device is not-operational
--ENOMEM - not enough kernel memory to process request
-
-Usage Notes :
- 
-While Linux for Intel defines dev_id as a unique identifier for shared 
-interrupt lines, it has a totally different purpose on Linux for S/390. Here 
-it serves as a shared interrupt status area between the generic device support 
-layer and the device specific driver. The value passed to request_irq() must 
-therefore point to a valid devstat_t type buffer area the device driver must 
-preserve for later usage. I.e. it must not be released prior to a call to 
-free_irq().
- 
-Currently, the value of irqflags is ignored. The Linux for S/390 kernel does 
-neither know about "fast" interrupt handlers, nor does it allow for interrupt 
-sharing. Remember, the term interrupt level (irq), device, and subchannel are 
-used interchangeably in Linux for S/390.
- 
-Other than request_irq(), this function does allow for a not operational 
-handler to be defined. This handler is called when a device either became not 
-operational, the last path to a device became not operational, or the device 
-was detached from the system. A detach could be a "detach" under VM or that 
-the device became unassigned by the Support Element (SE) or Hardware Management 
-Console (HMC). 
- 
-If s390_request_irq_special() was called in enabled state, or if multiple CPUs 
-are present, the device may present an interrupt to the specified handler prior 
-to request_irq() return to the caller already ! This includes the possibility 
-of unsolicited interrupts or a pending interrupt status from an earlier 
-solicited I/O request. The device driver must be able to handle this situation 
-properly or the device may become unoperational otherwise !
-
-Although the interrupt handler is defined to be called with a pointer to a 
-struct pt_regs buffer area, this is not implemented by the Linux for S/390 
-platform specific common I/O support layer. The device driver's interrupt 
-handler must therefore not rely on this parameter on function entry.
-
-
-free_irq() - Release Device Ownership
-
-A device driver may call free_irq() to release ownership of a previously
-acquired device.
-
-void free_irq( unsigned int  irq,
-               void         *dev_id);
-
-irq      : specifies the subchannel the ownership is requested for
-dev_id   : required pointer to a device specific buffer of type
-           devstat_t. This must be the same as the one specified
-           during a previous call to request_irq().
-
-Usage Notes :
-
-Unfortunately the free_irq() is defined not to return error codes. I.e. if
-called with wrong  parameters a device may still be operational although there
-is no device driver available to handle its interrupts. Further, during
-free_irq() processing we may possibly find pending interrupt conditions. As
-those need to be processed, we have to delay free_irq() returning until a
-clean device status is found by synchronously handling them.
-
-The call to free_irq() will also cause the device (subchannel) be disabled for
-interrupts. The device driver must not release any data areas required for
-interrupt processing prior to free_irq() return to the caller as interrupts
-can occur prior to free_irq() returning. This is also true when called in
-disabled state if either multiple CPUs are presents or a pending interrupt
-status was found during free_irq() processing.
-
-
-disable_irq() - Disable Interrupts for a given Device
-
-This function may be called at any time to disable interrupt processing for
-the specified irq. However, as Linux/390 maps irqs to the device (subchannel)
-one-to-one, this may require more extensive I/O processing than anticipated,
-especially if an interrupt status is found pending on the subchannel that
-requires synchronous error processing.
-
-int disable_irq( unsigned int irq );
-
-irq : specifies the subchannel to be disabled
-
-The disable-irq() routine may return :
-
-      0 - successful completion
--EBUSY  - device (subchannel) is currently processing an I/O
-          request
--ENODEV - the device is not-operational or irq doesn't specify a
-          valid subchannel
-
-Usage Notes :
-
-Unlike the Intel based hardware architecture the ESA/390 architecture does
-not have a programmable interrupt controller (PIC) where a specific interrupt
-line can be disabled. Instead the subchannel logically representing the device
-in the channel subsystem must be disabled for interrupts. However, if there
-are still inetrrupt conditions pending they must   be processed first in order
-to allow for proper processing after reenabling the device at a later time.
-This may lead to delayed disable processing.
-
-As described above the disable processing may require extensive processing.
-Therefore    disabling and re-enabling the device using disable_irq() /
-enable_irq() should be avoided and is not suitable for high frequency
-operations.
-
-Linux for Intel defines this function
-
-void disable_irq( int irq);
-
-This is suitable for the Intel PC architecture as this only causes to mask
-the requested irq line in the PIC which is not applicable for the ESA/390
-architecture. Therefore we allow   for returning error codes.
+get_ciw() - get command information word
 
+This call enables a device driver to get information about supported commands
+from the extended SenseID data.
 
-enable_irq() - Enable Interrupts for a given Device
+struct ciw *
+ccw_device_get_ciw(struct ccw_device *cdev, __u32 cmd);
 
-This function is used to enable a previously disabled device (subchannel).
-See disable_irq() for more details.
+cdev - The ccw_device for which the command is to be retrieved.
+cmd  - The command type to be retrieved.
 
-int enable_irq( unsigned int irq );
+ccw_device_get_ciw() returns:
+NULL    - No extended data available, invalid device or command not found.
+!NULL   - The command requested.
 
-irq : specifies the subchannel to be enabled
 
-The enable-irq() routine may return :
+ccw_device_start() - Initiate I/O Request
 
-      0 - successful completion
--EBUSY  - device (subchannel) is currently processing an I/O
-          request. This implies the device is already in enabled
-          state
--ENODEV - the device is not-operational or irq doesn't specify a
-          valid subchannel
-
-
-
-do_IO() - Initiate I/O Request
-
-The do_IO() routines is the I/O request front-end processor. All device driver
-I/O requests must be issued using this routine. A device driver must not issue
-ESA/390 I/O commands itself. Instead the do_IO() routine provides all
-interfaces required to drive arbitrary devices.
+The ccw_device_start() routines is the I/O request front-end processor. All
+device driver I/O requests must be issued using this routine. A device driver
+must not issue ESA/390 I/O commands itself. Instead the ccw_device_start()
+routine provides all interfaces required to drive arbitrary devices.
 
 This description also covers the status information passed to the device
 driver's interrupt handler as this is related to the rules (flags) defined
-with the associated I/O request when calling do_IO().
+with the associated I/O request when calling ccw_device_start().
 
-int do_IO( int            irq,
-           ccw1_t        *cpa,
-           unsigned long  user_intparm,
-           unsigned int   lpm,
-           unsigned long  flag);
+int ccw_device_start(struct ccw_device *cdev,
+		     struct ccw1 *cpa,
+		     unsigned long intparm,
+		     __u8 lpm,
+		     unsigned long flags);
 
-irq          : irq (subchannel) the I/O request is destined for
+cdev         : ccw_device the I/O is destined for
 cpa          : logical start address of channel program
 user_intparm : user specific interrupt information; will be presented
 	       back to the device driver's interrupt handler. Allows a
                device driver to associate the interrupt with a
                particular I/O request.
 lpm          : defines the channel path to be used for a specific I/O
-               request. Valid with flag value DOIO_VALID_LPM only.
-flag         : defines the action to e parformed for I/O processing
+               request. A value of 0 will make cio use the opm.
+flag         : defines the action to be performed for I/O processing
 
 Possible flag values are :
 
-DOIO_EARLY_NOTIFICATION  - allow for early interrupt notification
-DOIO_VALID_LPM           - LPM input parameter is valid (see usage
-                           notes below for details)
-DOIO_WAIT_FOR_INTERRUPT  - wait synchronously for final status
-DOIO_TIMEOUT             - perform a loop while waiting for final status
-			   and fail after a timeout
-DOIO_REPORT_ALL          - report all interrupt conditions
 DOIO_ALLOW_SUSPEND       - channel program may become suspended
 DOIO_DENY_PREFETCH       - don't allow for CCW prefetch; usually
                            this implies the channel program might
-                           become modified 
-DOIO_CANCEL_ON_TIMEOUT   - do a cancel_IO if there is a timeout waiting
-			   for the channel program to finish (see usage
-                           notes below for details)
+                           become modified
+DOIO_SUPPRESS_INTER     - don't call the handler on intermediate status
 
 The cpa parameter points to the first format 1 CCW of a channel program :
 
-typedef struct {
+struct ccw1 {
       __u8  cmd_code;/* command code */
       __u8  flags;   /* flags, like IDA adressing, etc. */
       __u16 count;   /* byte count */
       __u32 cda;     /* data address */
-} __attribute__ ((packed,aligned(8))) ccw1_t;
+} __attribute__ ((packed,aligned(8)));
 
 with the following CCW flags values defined :
 
@@ -783,59 +302,35 @@
 CCW_FLAG_SUSPEND   - suspend
 
 
+Via ccw_device_set_options(), the device driver may specify the following
+options for the device:
 
-The do_IO() function returns :
+DOIO_EARLY_NOTIFICATION  - allow for early interrupt notification
+DOIO_REPORT_ALL          - report all interrupt conditions
+
+
+The ccw_device_start() function returns :
 
       0 - successful completion or request successfully initiated
--EBUSY  - the do_io() function was caled out of sequence. The
-          device is currently processing a previous I/O request
--ENODEV - irq doesn't specify a valid subchannel, the device is
-          not operational (check dev_id.flags) or the irq is not
-          owned.
--EINVAL - both, DOIO_EARLY_NOTIFICATION and DOIO_REORT_ALL flags
-          have been specified. The usage of those flags is mutual
-          exclusive.
+-EBUSY  - The device is currently processing a previous I/O request, or ther is
+          a status pending at the device.
+-ENODEV - cdev is invalid, the device is not operational or the ccw_device is
+          not online.
 
 When the I/O request completes, the CDS first level interrupt handler will
-setup the dev_id buffer of type devstat_t defined during request_irq()
-processing. See request_irq() for the devstat_t data layout. The
-dev_id->intparm field in the device status area will contain the value the
-device driver has associated with a particular I/O request. If a pending
-device status was recognized dev_id->intparm will be set to 0 (zero). This
-may happen during I/O initiation or delayed by an alert status notification.
-In any case this status is not related to the current (last) I/O request. In
-case of a delayed status notification no special interrupt will be presented
-to indicate I/O completion as the I/O request was never started, even though
-do_IO() returned with successful completion.
-
-Possible dev_id->flag values are :
-
-DEVSTAT_FLAG_SENSE_AVAIL - sense data is available
-DEVSTAT_NOT_OPER         - device is not-operational
-DEVSTAT_START_FUNCTION   - interrupt is presented as result of a
-                           call to do_IO()
-DEVSTAT_HALT_FUNCTION    - interrupt is presented as result of a
-                           call to halt_IO()
-DEVSTAT_STATUS_PENDING   - a pending status was found. The I/O
-                           resquest (if any) was not initiated.
-                           This status might have been presented
-                           delayed, after do_IO() or halt_IO() have
-                           successfully be started previously.
-DEVSTAT_FINAL_STATUS     - This is a final interrupt status for the
-                           I/O requst identified by intparm.
-DEVSTAT_PCI              - A PCI was received. 
-DEVSTAT_SUSPENDED        - A "suspended" intermediate status was
-                           received.  
-
-If device status DEVSTAT_FLAG_SENSE_AVAIL is indicated in field dev_id->flag,
-field dev_id->scnt describes the numer of device specific sense bytes
-available in the sense area dev_id->ii.sense. No device sensing by the device
-driver itself is required.
-
-typedef struct {
-      __u8          res[32];   /* reserved   */
-      __u8          data[32];  /* sense data */
-   } __attribute__ ((packed)) sense_t;
+accumalate the status in a struct irb and then call the device interrupt handler.
+The intparm field will contain the value the device driver has associated with a 
+particular I/O request. If a pending device status was recognized, 
+intparm will be set to 0 (zero). This may happen during I/O initiation or delayed
+by an alert status notification. In any case this status is not related to the
+current (last) I/O request. In case of a delayed status notification no special
+interrupt will be presented to indicate I/O completion as the I/O request was
+never started, even though ccw_device_start() returned with successful completion.
+
+If the concurrent sense flag in the extended status word in the irb is set, the
+field irb->scsw.count describes the numer of device specific sense bytes
+available in the extended control word irb->scsw.ecw[0]. No device sensing by
+the device driver itself is required.
 
 The device interrupt handler can use the following definitions to investigate
 the primary unit check source coded in sense byte 0 :
@@ -851,7 +346,7 @@
 Depending on the device status, multiple of those values may be set together.
 Please refer to the device specific documentation for details.
 
-The devi_id->cstat field provides the (accumulated) subchannel status :
+The irb->scsw.cstat field provides the (accumulated) subchannel status :
 
 SCHN_STAT_PCI            - program controlled interrupt
 SCHN_STAT_INCORR_LEN     - incorrect length
@@ -862,7 +357,7 @@
 SCHN_STAT_INTF_CTRL_CHK  - interface control check
 SCHN_STAT_CHAIN_CHECK    - chaining check
 
-The dev_id->dstat field provides the (accumulated) device status :
+The irb->scsw.dstat field provides the (accumulated) device status :
 
 DEV_STAT_ATTENTION   - attention
 DEV_STAT_STAT_MOD    - status modifier
@@ -876,67 +371,36 @@
 Please see the ESA/390 Principles of Operation manual for details on the
 individual flag meanings.
 
-In rare error situations the device driver may require access to the original
-hardware interrupt data beyond the scope of above mentioned infromation. For
-those situations the Linux/390 common device support provides the interrupt
-response block (IRB) as part of the device status block in dev_id->ii.irb.
-
 Usage Notes :
 
-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 
-local_save_flags( flags). The current PSW flags are preserved and can be restored 
-by local_irq_restore( flags) at a later time.
+Prior to call ccw_device_start() 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 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
-returning to the device driver main path. In this case we will end in a
+environment an interrupt might be presented prior to the ccw_device_start()
+routine returning to the device driver main path. In this case we will end in a
 deadlock situation as the interrupt handler will try to obtain the irq
 lock the device driver still owns (see below) !
 
 The driver must assure to hold the device specific lock. This can be
 accomplished by
 
-(i)  s390irq_spin_lock( irq), or
-(ii) s390irq_spin_lock_irqsave(irq, flags)
+(i)  spin_lock(get_ccwdev_lock(cdev)), or
+(ii) spin_lock_irqsave(get_ccwdev_lock(cdev), flags)
 
 Option (i) should be used if the calling routine is running disabled for
 I/O interrupts (see above) already. Option (ii) obtains the device gate und
 puts the CPU into I/O disabled state by preserving the current PSW flags.
-See the descriptions of s390irq_spin_lock() or s390irq_spin_lock_irqsave()
-for more details.
 
-The device driver is allowed to issue the next do_IO() call from within its
-interrupt handler already. It is not required to schedule a bottom-half,
-unless an non deterministicly long running error recovery procedure or
-similar needs to be scheduled. During I/O processing the Linux/390 generic
+The device driver is allowed to issue the next ccw_device_start() call from
+within its interrupt handler already. It is not required to schedule a
+bottom-half, unless an non deterministicly long running error recovery procedure
+or similar needs to be scheduled. During I/O processing the Linux/390 generic
 I/O device driver support has already obtained the IRQ lock, i.e. the handler
-must not try to obtain it again when calling do_IO() or we end in a deadlock
-situation ! Anyway, the device driver's interrupt handler must only call
-do_IO() if the handler itself can be entered recursively if do_IO() e.g. finds
-a status pending and needs to all the interrupt handler itself.
-
-Device drivers shouldn't heavily rely on DOIO_WAIT_FOR_INTERRUPT synchronous
-I/O request processing. All I/O devices, but the console device are driven
-using a single shared interrupt subclass (ISC). For sync. processing the
-device is temporarily mapped to a special ISC while the calling CPU waits for
-I/O completion. As this special ISC is gated, all sync. requests in a SMP
-environment are serialized which may cause other CPUs to spin. This service
-is therewith primarily meant to be used during device driver initialization
-for ease of device setup.
-
-If the device driver is using the DOIO_TIMEOUT parameter, it is a good idea
-also to specify DOIO_CANCEL_ON_TIMEOUT. Otherwise, the failing channel program
-may prevent the execution of any other channel program at the subchannel.
-
-The lpm input parameter might be used for multipath devices shared among
-multiple systems as the Linux/390 CDS isn't grouping channel paths. Therefore
-its use might be required if multiple access paths to a device are available
-and the device was reserved by means of a reserve device command (for devices
-supporting this technique). When issuing this command the device driver needs
-needs to extract the dev_id->lpum value and restrict all subsequent channel
-programs to this channel path until the device is released by a device release
-command. Otherwise a deadlock may occur.
+must not try to obtain it again when calling ccw_device_start() or we end in a
+deadlock situation!
 
 If a device driver relies on an I/O request to be completed prior to start the
 next it can reduce I/O processing overhead by chaining a NoOp I/O command
@@ -967,19 +431,8 @@
 exploiting this feature will cause only primary status interrups to be
 presented to the device driver while overlapping I/O is performed. When a
 secondary status without error (alert status) is presented, this indicates
-successful completion for all overlapping do_IO() requests that have been
-issued since the last secondary (final) status.
-
-During interrupt processing the device specific interrupt handler should avoid
-basing its processing decisions on the interruption response block (IRB) that
-is part of the dev_id buffer area. The IRB area represents the interruption
-parameters from the last interrupt received. Unless the device driver has
-specified DOIO_REPORT_ALL or is called with a pending status
-(DEVSTAT_STATUS_PENDING), the IRB information may or may not show the complete
-interruption status, but the last interrupt only. Therefore the device driver
-should usually base its processing decisions on the values of dev_id->cstat
-and dev_id->dstat that represent the accumulated subchannel and device status
-information gathered since do_IO() request initiation.
+successful completion for all overlapping ccw_device_start() requests that have
+been issued since the last secondary (final) status.
 
 Channel programs that intend to set the suspend flag on a channel command word 
 (CCW)  must start the I/O operation with the DOIO_ALLOW_SUSPEND option or the 
@@ -987,56 +440,50 @@
 becomes suspended an intermediate interrupt will be generated by the channel 
 subsystem.
 
-resume_IO() - Resume Channel Program Execution 
+ccw_device_resume() - Resume Channel Program Execution 
 
 If a device driver chooses to suspend the current channel program execution by 
 setting the CCW suspend flag on a particular CCW, the channel program execution 
 is suspended. In order to resume channel program execution the CIO layer 
-provides the resume_IO() routine. 
+provides the ccw_device_resume() routine. 
 
-int resume_IO( int irq);
+int ccw_device_resume(struct ccw_device *cdev);
 
-irq     : irq (subchannel) the halt operation is requested for
+cdev - ccw_device the resume operation is requested for
 
 The resume_IO() function returns:
 
         0  - suspended channel program is resumed
 -EBUSY     - status pending
--ENODEV    - invalid or not-operational subchannel 
+-ENODEV    - cdev invalid or not-operational subchannel 
 -EINVAL    - resume function not applicable  
 -ENOTCONN  - there is no I/O request pending for completion 
 
 Usage Notes:
-Please have a look at the do_IO()  usage notes for more details on suspended 
-channel programs.
+Please have a look at the ccw_device_start() usage notes for more details on
+suspended channel programs.
 
-halt_IO() - Halt I/O Request Processing
+ccw_device_halt() - Halt I/O Request Processing
 
 Sometimes a device driver might need a possibility to stop the processing of
 a long-running channel program or the device might require to initially issue
-a halt subchannel (HSCH) I/O command. For those purposes the halt_IO() command
-is provided.
+a halt subchannel (HSCH) I/O command. For those purposes the ccw_device_halt()
+command is provided.
 
-int halt_IO( int           irq,     /* subchannel number */
-             unsigned long intparm, /* dummy intparm */
-             unsigned long flag);   /* operation mode */
+int ccw_device_halt(struct ccw_device *cdev,
+                    unsigned long intparm);
 
-irq     : irq (subchannel) the halt operation is requested for
+cdev    : ccw_device the halt operation is requested for
 intparm : interruption parameter; value is only used if no I/O
           is outstanding, otherwise the intparm associated with
           the I/O request is returned
-flag    : 0 (zero) or DOIO_WAIT_FOR_INTERRUPT
 
-The halt_IO() function returns :
+The ccw_device_halt() function returns :
 
       0 - successful completion or request successfully initiated
--EBUSY  - the device is currently performing a synchronous I/O
-          operation : do_IO() with flag DOIO_WAIT_FOR_INTERRUPT
-          or an error was encountered and the device is currently
-          be sensed
--ENODEV - the irq specified doesn't specify a valid subchannel, the
-          device is not operational (check dev_id.flags) or the irq
-          is not owned.
+-EBUSY  - the device is currently busy, or status pending.
+-ENODEV - cdev invalid.
+-EINVAL - The device is not operational or the ccw device is not online.
 
 Usage Notes :
 
@@ -1046,11 +493,8 @@
 device drivers by setting the PCI CCW flag (CCW_FLAG_PCI). Once this CCW is
 executed a program controlled interrupt (PCI) is generated. The device driver
 can then perform an appropriate action. Prior to interrupt of an outstanding
-read to a network device (with or   without PCI flag) a halt_IO() is required
-to end the pending operation.
-
-We don't allow to stop sync. I/O requests by means of a halt_IO() call. The
-function will return -EBUSY instead.
+read to a network device (with or without PCI flag) a ccw_device_halt()
+is required to end the pending operation.
 
 
 Miscellaneous Support Routines
@@ -1058,107 +502,12 @@
 This chapter describes various routines to be used in a Linux/390 device
 driver programming environment.
 
-s390irq_spin_lock() / s390irq_spin_unlock()
-
-Those two macro definitions are required to obtain the device specific IRQ
-lock. The lock needs to be obtained if the device driver intends to call
-do_IO() or halt_IO() from anywhere but the device interrupt handler (where
-the lock is already owned). Those routines must only be used if running
-disabled for interrupts already. Otherwise use s390irq_spin_lock_irqsave()
-and the corresponding unlock routine instead (see below).
-
-s390irq_spin_lock( int irq);
-s390irq_spin_unlock( int irq);
-
-
-s390irq_spin_lock_irqsave() / s390_irq_spin_unlock_irqrestore()
-
-Those two macro definitions are required to obtain the device specific IRQ
-lock. The lock needs to be obtained if the device driver intends to call
-do_IO() or halt_IO() from anywhere but the device interrupt handler (where
-the lock is already owned). Those routines should only be used if running
-enabled for interrupts. If running disabled already, the driver should use
-s390irq_spin_lock() and the corresponding unlock routine instead (see above).
-
-s390irq_spin_lock_irqsave( int irq, unsigned long flags);
-s390irq_spin_unlock_irqrestore( int irq, unsigned long flags);
-
-
-
-
-Special Console Interface Routines
-
-This chapter describes the special interface routines required for system
-console processing. Though they are an extension to the Linux/390 device
-driver interface concept, they base on the same principles. It was necessary
-to build those extensions to assure a deterministic behaviour in critical
-situations e.g. printk() messages by other device drivers running disabled
-for interrupts during I/O interrupt handling or in case of a panic() message
-being raised.
-
-set_cons_dev - Set Console Device
-
-This routine allows to specify the system console device. This is necessary
-as the console isn't driven by the same ESA/390 interrupt subclass as are
-other devices, but it is assigned ist own interrupt subclass. Only one device
-can act as system console. See wait_cons_dev() for details.
-
-int set_cons_dev( int irq);
-
-irq : subchannel identifying the system console device
-
-The set_cons_dev() function returns
-
-      0 - successful completion
--EIO    - an unhandled interrupt condition is pending for the
-          specified subchannel (irq) - status pending
--ENODEV - irq doesn't specify a valid subchannel or the devive is
-          not operational
--EBUSY  - the console device is already defined
-
-reset_cons_dev - Reset Console Device
-
-This routine allows for resetting the console device specification. See
-wait_cons_dev() for details.
-
-int reset_cons_dev( int irq);
-
-irq : subchannel identifying the system console device
-
-The reset_cons_dev() function returns
-
-      0 - successful completion
--EIO    - an unhandled interrupt condition is pending for the
-          specified subchannel (irq) - status pending
--ENODEV - irq doesn't specify a valid subchannel or the devive is
-          not operational
-
-wait_cons_dev - Synchronously Wait for Console Processing
-
-The wait_cons_dev() routine is used by the console device driver when its
-buffer pool for intermediate request queuing is exhausted and a new output
-request is received. In this case the console driver uses the wait_cons_dev()
-routine to synchronously wait until enough buffer space is gained to enqueue
-the current request. Any pending interrupt condition for the console device
-found during wait_cons_dev() processing causes its interrupt handler to be
-called.
-
-int wait_cons_dev( int irq);
-
-irq : subchannel identifying the system console device
-
-The wait_cons_dev() function  returns :
-
-      0 - successful completion
--EINVAL - the irq specified doesn't match the irq configured for
-          the console device by set_cons_dev()
-
-Usage Notes :
+get_ccwdev_lock()
 
-The function should be used carefully. Especially in a SMP environment the
-wait_cons_dev() processing requires that all but the special console ISC are
-disabled. In a SMP system this requires the other CPUs to be signaled to
-disable/enable those ISCs.
+Get the address of the device specific lock. This is then used in
+spin_lock() / spin_unlock() calls.
 
 
+__u8 ccw_device_get_path_mask(struct ccw_device *cdev);
 
+Get the mask of the path currently available for cdev.
diff -Nru a/Documentation/s390/chandev.8 b/Documentation/s390/chandev.8
--- a/Documentation/s390/chandev.8	Mon Dec  9 18:46:52 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,430 +0,0 @@
-.TH chandev 8
-.SH NAME
-channel device layer
-.Dd December 6, 2000
-.Os Linux for Zseries
-
-.SH SYNOPSIS
-The channel device layer is a layer to provide a consistent interface for
-configuration & default machine check (devices appearing & disappearing )
-handling on Linux for s/390 & z/Series channel devices.
-
-
-s/390 & z/Series channel devices include among others
-
-.Bl -item
-.It
-lcs ( the most common ethernet/token ring/fddi standard on zSeries )
-.It
-ctc/escon hi speed like serial link standard on s/390 & z/Series.
-.It
-claw used to talk to cisco routers.
-.It
-qeth gigabit ethernet.
-.It
-osad used by osa/sf to configure osa devices, e.g. to share a osa card between 2 or more vm guests. osad is just added to the channel device layer for completeness, there are no plans at the current time to write a driver to exploit this under linux.
-.It
-These devices use two channels one read & one write for configuration &
-or communication ( & a third channel the data channel in the case of gigabit ethernet ).
-The motivation behind developing this layer was that there was a lot of
-duplicate code among the channel device drivers for configuration. 
-Also the lcs & ctc drivers tended to fight over 3088/08's & 3088/1F's which could 
-be either 2216/3172 channel attached lcs compatible devices or escon/ctc pipes 
-between guests & to resolve this fight both device drivers had to be configured 
-separately,  this is now simplified by doing the configuration in a single place
-( the channel device layer ).
-
-This layer isn't invasive & it is quite okay to use channel drivers
-which don't use the channel device layer in conjunction with
-drivers which do.
-.El
-
-.SH DESCRIPTION
-The current setup can be read from /proc/chandev
-arguments can be entered by...
-.Bl -enum
-.It
-Piping to /proc/chandev.
-e.g. echo reprobe >/proc/chandev
-will cause uninitialised channel devices to be probed.
-.It
-Entering them into /etc/chandev.conf comments are prefixed with #.
-.It
-Or from the boot command line using the 'chandev=' keyword
-e.g. chandev=noauto,0x0,0x480d;noauto,0x4810,0xffff
-will allow only devno's 0x480e & 0x480f to be autodetected.
-.El
-.Bl -item
-.It
-Multiple options can be passed separated by semicolons, no spaces or newlines are allowed between parameters on the kernel parameter line as it complicates parsing, spaces are allowed in /proc/chandev & chandev.conf, newlines are allowed in chandev.conf only. To be consistent with other hotpluggable architectures the script pointed to /proc/sys/kernel/hotplug (normally /sbin/hotplug) will be called automatically on startup or a machine check of a device as follows.
-/sbin/hotplug chandev <start starting_devnames> <machine_check (devname last/pre_recovery_status) (current/post_recovery_status)>.
-The chandev layer doesn't open stdin stdout or stderr so it is advisable that you add the following lines to the start of your script, here is a sample script which starts devices as they become available.
-.It
-#!/bin/bash
-.It
-exec >/dev/console 2>&1 0>&1
-.It
-# Uncomment line below for debugging.
-.It
-# echo $*
-.It
-if [ "$1" = "chandev" ] && [ "$2" = "start" ]
-.It
-then
-.It
-    shift 2
-.It
-    while [ "$1" != "" ]  && [ "$1" != "machine_check" ]
-.It
-    do
-.It
-        isup=`ifconfig $1 2>/dev/null | grep UP`
-.It
-	if [ "$isup" = "" ]
-.It
-	then
-.It
-	     ifup $1
-.It
-	fi
-.It
-	shift
-.It
-    done
-.It
-fi
-.It
-.It
-e.g. if tr0 & ctc0 were starting up & eth0 & eth1 devices disappeared & eth2 got a revalidate machine check ( which is normally fully recoverable ) nearly simultainously the parameters would be.
-.It
-/sbin/hotplug chandev start tr0 ctc0 machine_check eth0 gone gone eth1 gone gone eth2 revalidate good
-.It
-This can be used for example to call /etc/rc.d/init.d/network start when a device appears & make the ipldelay kernel boot parameter obselete on native machines or recover from bad machine checks where the default machine check handling isn't adequete. The machine checks that can be presented as parameters are good not_operational no_path revalidate device_gone. Normally you wouldn't want to do anything like stop networking when a device disappears as this is hopefully temporary, I just added it to be complete. The chandev layer waits a few seconds for machine checks to settle before running /sbin/hotplug because several machine checks usually happen at once & the forked scripts would possibly race against each other to shutdown & start resources at the same time & behave rather stupidly.
-.El
-
-
-
-valid chandev arguments are <> indicate optional parameters, | indicate a choice.
-
-.B glossary
-.Bl -item
-.It
-devno: is a 16 bit unsigned number used to uniquely identify a subchannel to a device.
-.It
-force list: is a term specific to channel device layer describing a range of devno's to be forced to configure in a particular manner as opposed to autodetect
-.El
-
-.B commonly used options
-
-.Bl -item
-.It
-
-.Bl -item
-.It
-.B (ctc|escon|lcs|osad|qeth)<devif_num>, 
-read_devno,write_devno,<data_devno,memory_usage_in_k,port_no/protocol_no,checksum_received_ip_pkts,use_hw_stats>
-.It
-devif_num of -1 indicates you don't care what device interface number is chosen, omitting it indicates this is a range of devices for which you want to force to be detected as a particular type, qeth devices can't be forced as a range as it makes no sense for them.
-The data_devno field is only valid for qeth devices, all parameters including & after memory_usage_in_k can be set optionally, if not set they
-go to default values. memory_usage_in_k ( 0 the default ) means let the driver choose,checksum_received_ip_pkts & use_hw_stats are set to false
-.It
-e.g. ctc0,0x7c00,0x7c01
-.It
-Tells the channel layer to force ctc0 if detected to use cuu's 7c00 & 7c01 port,port_no is the relative adapter no on lcs, on ctc/escon this field is the ctc/escon protocol number ( default 0 ), don't do checksumming on received ip packets & as ctc doesn't have hardware stats so it ignores this parameter. This can be used for instance to force a device if it presents bad sense data to the IO layer & thus autodetection fails.
-.It
-lcs,0x7c00,0x7d00,4096,-1
-All devices between 0x7c00 & 7d00 should be detected as lcs, let the driver use 4096k for each instance, don't care what port relative adapter number is chosen, don't checksum received ip packets & use hw stats .
-.It
-qeth1,0x7c00,0x7c01,0x7c02
-.It
-devif_num=1,read=0x7c00,write=0x7c01,data=0x7c02, don't checksum received ip packets & use hw stats.
-.El
-.It
-.Bl -item
-.B claw devif_num, 
-read_devno,write_devno<,memory_usage_in_k,checksum_received_ip_pkts,use_hw_stats,>
-host_name,adapter_name,api_type
-.It
-CLAW currently is not autodetected as the host_name,adapter_name & api_type
-need to be set up, possibly some convention for setting these automatically
-may be contrived in the future & auto detection may be done but currently there isn't any.
-The names host_name,adapter_name,api_type may be 8 upto characters in length,
-host_name is the name of this host, adapter_name is the name of the adjacent host,
-api_type may be name 1 to 8 chars in length API & TCPIP are common values.
-The remainder of the parameters are the same as the description for other ctc escon etc. 
-.It
-A typical setup may be
-.It
-claw0,0xe00,0xe01,linuxa,rs6k,TCPIP
-.It
-.El
-.Bl -item
-.It
-.B add_parms
-,chan_type,<lo_devno,hi_devno,>string
-.It
-chan_type bitfield 
-.It
-ctc=0x1, escon=0x2, lcs=0x4, osad=0x8, qeth=0x10, claw=0x20.
-.It
-This is for device driver specific options passed as a string to the driver
-not dealt with by the channel device layer it can't contain spaces.
-low_devno & hi_devno are optional parameters to specify a range.
-The channel device layer doesn't concatenate strings if device ranges overlap,
-before passing to a device driver.
-.El
-.It
-
-.Bl -item
-.It
-.B del_parms
-<,chan_type,exact_match,lo_devno>
-.It
-This deletes some or all device driver specific options not specifying chan_type causes it to delete all the strings. exact_match=1 specifies only to remove driver parms where chan_type is exactly equal exact_match=0 specifies to remove parms where any bit matches chan_type.
-lo_devno is an optional parameter the delete to only happen if lo_devno matches a lo_devno in one of the ranges.
-.El
-.It
-
-.Bl -item
-.It
-.B noauto
-<,lo_devno,hi_devno>
-.It
-Don't probe a range of device numbers for channel devices.
-.El
-.It
-
-.Bl -item
-.It
-.B use_devno_names
-.It
-Tells the channel layer to assign device names based on the read channel cuu number.
-.It
-e.g. a token ring read channel 0x7c00 would have an interface called tr0x7c00 this avoids name collisions on devices.
-.El
-
-
-.B power user options
-
-
-.Bl -item
-
-.It
-.Bl -item
-.It
-.B del_noauto
-,<devno>
-.It
- Delete a range or all noauto ranges when devno is within a range.
-.El
-
-.It
-.Bl -item
-.It
-.B del_force
-,read_devno
-.It
-Delete a forced channel device from force list.
-.El
-
-.It
-.Bl -item
-.It
-.B dont_use_devno_names
-.It
-Opposite to use_devno_names described above.
-.El
-
-
-.It
-.Bl -item
-.It
-.B add_model
-,chan_type, cu_type, cu_model, dev_type, dev_model, max_port_no, automatic_machine_check_handling
-.It
-Tells the channel layer to probe for the device described, -1 for any of the parameters other than chan_type & automatic_machine_check_handling is a wildcard.
-Set max_port_no to 0 for non lcs devices.
-.It
-auto machine check recovery bitfield
-.It
-not_operational=0x1, no_path=0x2, revalidate=0x4, gone=0x8
-.It
-chan_type bitfield
-.It
-ctc=0x1, escon=0x2, lcs=0x4, osad=0x8, qeth=0x10, claw=0x20
-.El
-.Bl -item
-.It
-.B del_model
-,cu_type,cu_model,dev_type,dev_model
-.It
--1 for any parameter is a wildcard.
-.El
-
-.Bl -item
-.It
-.B del_all_models
-.It 
-should be obvious.
-.El
-.Bl -item
-.It
-.B  non_cautious_auto_detect
-.It
-Tells the channel device layer to attempt to auto detect devices even if their type/model pairs don't unambigously identify the device, e.g. 3088/1F's can either be escon CTC's or channel attached 3172 lcs compatible devices. If the wrong device driver attempts to probe these channels there may be big delays on startup or even a kernel lockup, use this option with caution.
-.El
-.Bl -item
-.It
-.B cautious_auto_detect
-.It
- See non_cautious_auto_detect this is the default.
-.El
-.Bl -item
-.It
-.B auto_msck
-<,lo_devno>,<hi_devno>,auto_msck_recovery
-.It
-This is used to specify the kind of machine check recovery that occurs over a device range.
-.El
-.It
-.Bl -item
-.It
-.B del_auto_msck
-<,devno>
-.It
-Delete a range or all machine check recovery ranges when devno is within a range.
-.El
-.It
-.Bl -item
-.It
-.B reset_clean
-.It
-Resets all model info, forced devices & noauto lists to null.
-.El
-.It
-.Bl -item
-.It
-.B reset_conf
-.It
-Resets all model info, forced devices & noauto lists back to default settings.
-.El
-.It
-.Bl -item
-.It
-.B reset_conf_clean
-.It
-Resets all model info, forced devices & noauto lists to empty.
-.El
-.It
-.Bl -item
-.It
-.B shutdown
-<device name|read devno>
-.It
-Shuts down a particular device by device name or read devno,
-deregisters it & releases its interrupts
-or shuts down all devices if no parameter is used.
-.El
-.It
-.Bl -item
-.It
-.B reprobe
-.It
-Calls probe method for channels whose interrupts are not owned.
-.El
-.It
-.Bl -item
-.It
-.B unregister_probe <probefunc_addr>
-.It
-unregisters a single probe function or all of them.
-.El
-.Bl -item
-.It
-.B unregister_probe_by_chan_type
-.It
-unregisters all probe functions which match the chan_type bitfield exactly,
-useful if you want a configuration to survice a kernel upgrade.
-.El
-.Bl -item
-.It
-.B read_conf
-.It
-Read instructions from /etc/chandev.conf.
-.El
-.It
-.Bl -item
-.It
-.B dont_read_conf
-.It
-Don't automatically read /etc/chandev.conf on boot.
-.El
-.Bl -item
-.It
-.B persist 
-,chan_type
-.It
-Force drivers modules to stay loaded even if no device is found,
-this is useful for debugging & one wishes to examine debug entries in 
-/proc/s390dbf/ to find out why a module failed to load.
-.It
-e.g.
-.It
-persist,-1 forces all devices to persist.
-.It
-persist,0 forces all channel devices to be non persistent.
-.El
-
-.It
-e.g the following sequence of commands should be roughly equivalent
-to rebooting for channel devices.
-.Bl -item
-.It
-shutdown
-.It
-reset_conf
-.It
-read_conf
-.It
-reprobe
-.El
-.El
-
-.SH SEE ALSO
-.Bl -item
-.It
-If you wish to write a driver channel device layer compatible
-.It
-/linux/include/asm-s390/chandev.h for the apis which are commented.
-.It
-/linux/drivers/s390/misc/chandev.c for the code.
-.El
-
-.SH FILES
-.Bl -item
-.It
-.B /proc/chandev
-.It
-cat /proc/chandev to see current options chosen.
-.It
-echo <command> >/proc/chandev to enter a new command
-.It
-.B /etc/chandev.conf 
-.It
-A file which can be used to configure the channel 
-device layer.
-.It
-kernel parameters with the 
-.B 'chandev=' 
-keyword.
-.It
-.B /sbin/hotplug
-.It 
-A user script/executable which is run when devices come online "appear"
-or go offline "disappear".
-.El
-
-
-.SH AUTHORS
-DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
-
diff -Nru a/Documentation/s390/driver-model.txt b/Documentation/s390/driver-model.txt
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/s390/driver-model.txt	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,209 @@
+S/390 driver model interfaces
+-----------------------------
+
+1. CCW devices
+--------------
+
+All devices which can be addressed by means of ccws are called 'CCW devices' -
+even if they aren't actually driven by ccws.
+
+All ccw devices are accessed via a subchannel, this is reflected in the 
+structures under root/:
+
+root/
+     - sys
+     - legacy
+     - css0/
+           - 0:0000/0:0815/
+	   - 0:0001/0:4711/
+	   - 0:0002/
+	   ...
+
+In this example, device 0815 is accessed via subchannel 0, device 4711 via 
+subchannel 1, and subchannel 2 is a non-I/O subchannel.
+
+You should address a ccw device via its bus id (e.g. 0:4711); the device can
+be found under bus/ccw/devices/.
+
+All ccw devices export some data via sysfs additional to the standard 'name'
+and 'power' entries.
+
+cutype:	    The control unit type / model.
+
+devtype:    The device type / model, if applicable.
+
+online:     An interface to set the device online and offline.
+
+The device drivers can add entries to export per-device data and interfaces.
+
+There is also some data exported on a per-subchannel basis (see under
+bus/css/devices/):
+
+chpids:	    Via which chpids the device is connected.
+
+pimpampom:  The path installed, path available and path operational masks.
+
+There also might be additional data, for example for block devices.
+
+
+1.1 Bringing up a ccw device
+----------------------------
+
+This is done in several steps.
+
+a. Some drivers need several ccw devices to make up one device. This drivers
+   provide a 'chaining' interface (driver dependend) which allows to specify
+   which ccw devices form a device.
+b. Each driver provides one or more parameter interfaces where parameters can
+   be specified. These interfaces are also in the driver's responsibility.
+c. After a. and b. have been performed, if neccessary, the device is finally
+   brought up via the 'online' interface.
+
+
+1.2 Writing a driver for ccw devices
+------------------------------------
+
+The basic struct ccw_device and struct ccw_driver data structures can be found
+under include/asm/ccwdev.h.
+
+struct ccw_device {
+        spinlock_t *ccwlock;
+        struct ccw_device_private *private;
+	struct ccw_device_id id;	
+
+	struct ccw_driver *drv;		
+	struct device dev;		
+	int online;
+
+	void (*handler) (struct ccw_device *dev, unsigned long intparm,
+                         struct irb *irb);
+};
+
+struct ccw_driver {
+	struct module *owner;		
+	struct ccw_device_id *ids;	
+	int (*probe) (struct ccw_device *); 
+	int (*remove) (struct ccw_device *);
+	void (*release) (struct ccw_driver *); 
+	int (*set_online) (struct ccw_device *);
+	int (*set_offline) (struct ccw_device *);
+	struct device_driver driver;
+	char *name;
+};
+
+The 'private' field contains data needed for internal i/o operation only, and
+is not available to the device driver.
+
+Each driver should declare in a MODULE_DEVICE_TABLE into which CU types/models
+and/or device types/models it is interested. This information can later be found
+found in the struct ccw_device_id fields:
+
+struct ccw_device_id {
+	__u16	match_flags;	
+
+	__u16	cu_type;	
+	__u16	dev_type;	
+	__u8	cu_model;	
+	__u8	dev_model;	
+
+	unsigned long driver_info;
+};
+
+The functions in ccw_driver should be used in the following way:
+probe:   This function is called by the device layer for each device the driver
+	 is interested in. The driver should only allocate private structures
+	 to put in dev->driver_data and create attributes (if needed). Also,
+	 the interrupt handler (see below) should be set here.
+
+int (*probe) (struct ccw_device *cdev); 
+
+Parameters:  cdev     - the device to be probed.
+
+
+remove:  This function is called by the device layer upon removal of the driver,
+	 the device or the module. The driver should perform cleanups here.
+
+int (*remove) (struct ccw_device *cdev);
+
+Parameters:   cdev    - the device to be removed.
+
+
+set_online: This function is called by the common I/O layer when the device is
+	    activated via the 'online' attribute. The driver should finally
+	    setup and activate the device here.
+
+int (*set_online) (struct ccw_device *);
+
+Parameters:   cdev	- the device to be activated. The common layer has
+			  verified that the device is not already online.
+
+
+set_offline: This function is called by the common I/O layer when the device is
+	     de-activated via the 'online' attribute. The driver should shut
+	     down the device, but not de-allocate its private data.
+
+int (*set_offline) (struct ccw_device *);
+
+Parameters:   cdev       - the device to be deactivated. The common layer has
+			   verified that the device is online.
+
+
+The handler field of the struct ccw_device is meant to be set to the interrupt
+handler for the device. In order to accomodate drivers which use several 
+distinct handlers (e.g. multi subchannel devices), this is a member of ccw_device
+instead of ccw_driver.
+The handler is registered with the common layer during set_online() processing
+before the driver is called, and is deregistered during set_offline() after the
+driver has been called. Also, after registering / before deregistering, path 
+grouping resp. disbanding of the path group (if applicable) are performed.
+
+void (*handler) (struct ccw_device *dev, unsigned long intparm, struct irb *irb);
+
+Parameters:	dev	- the device the handler is called for
+		intparm - the intparm which allows the device driver to identify
+                          the i/o the interrupt is associated with, or to recognize
+                          the interrupt as unsolicited.
+                irb     - interruption response block which contains the accumulated
+                          status.
+
+The device driver is called from the common ccw_device layer and can retrieve 
+information about the interrupt from the irb parameter.
+
+
+2. System devices
+-----------------
+
+2.1 Channel paths
+-----------------
+
+Every channel path is represented under sys/ as channel_path<nr>. (Unfortunately,
+<nr> is in decimal, which may look unfamiliar.)
+
+status - Can be 'online', 'logically offline' or 'n/a'.
+	 Piping 'on' or 'off' sets the chpid logically online/offline.
+
+
+2.2 xpram 
+---------
+
+xpram shows up under sys/ as 'xpram'.
+
+
+3. 'Legacy' devices
+-------------------
+
+The 'legacy' bus is for devices not detected, but specified by the user.
+
+
+3.1 Netiucv
+-----------
+
+Netiucv connections show up under legacy/ as "netiucv<ifnum>". The interface
+number is assigned sequentially at module load.
+
+user			  - the user the connection goes to.
+
+buffer			  - maximum buffer size.
+			    Pipe to it to change buffer size.
+
+
diff -Nru a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt
--- a/Documentation/scsi/scsi_mid_low_api.txt	Mon Dec  9 18:46:50 2002
+++ b/Documentation/scsi/scsi_mid_low_api.txt	Mon Dec  9 18:46:50 2002
@@ -27,8 +27,7 @@
 users to generate html, ps and pdf renderings of information within this
 file (e.g. the interface functions).
 
-This version of the document was written in the period when lk 2.5.47
-was current.
+This version of the document roughly matches lk 2.5.50 .
 
 Driver structure
 ================
@@ -43,9 +42,9 @@
 
 When a new LLD is being added to Linux, the following files (found in the
 drivers/scsi directory) will need some attention: Makefile, Config.help and
-Config.in . SCSI documentation is in the process of being moved to the 
-Documentation/scsi directory in the kernel source tree. It is probably best
-to study how existing LLDs are organized.
+Config.in . SCSI documentation is found in the Documentation/scsi directory
+of the kernel source tree. It is probably best to study how existing LLDs 
+are organized.
 
 As the 2.5 series development kernels evolve, changes are being
 introduced into this interface. An example of this is driver
@@ -75,11 +74,10 @@
 functions" below. The function pointers are placed in the members of
 "struct SHT", an instance of which is passed to scsi_register() [or
 scsi_register_host() in the passive initialization model]. Those interface
-functions that are not mandatory and that the LLD does
-not wish to supply should have NULL placed in the corresponding member
-of struct SHT. [Defining an instance of struct SHT at file scope will
-cause NULL to be placed in function pointer members not explicitly
-initialized.]
+functions that are not mandatory and that the LLD does not wish to supply
+should have NULL placed in the corresponding member of struct SHT.
+[Defining an instance of struct SHT at file scope will cause NULL to be 
+placed in function pointer members not explicitly initialized.]
 
 Those instances in group c) are slowly being removed as they tend to be
 "racy" especially in a hotplug environment.
@@ -87,42 +85,53 @@
 
 Hotplug initialization model
 ============================
-In this model a LLD controls when SCSI hosts are introduced
-and removed from the SCSI subsystem. Hosts can be introduced as early as
-driver initialization and removed as late as driver shutdown. Typically
-a driver will respond to a sysfs probe() callback that indicates a
-HBA is present (e.g. a PCI device). After confirming it is a device that
-it wants to control, it will initialize the HBA and then register a new 
-host with the SCSI mid level.
+In this model a LLD controls when SCSI hosts are introduced and removed
+from the SCSI subsystem. Hosts can be introduced as early as driver
+initialization and removed as late as driver shutdown. Typically a driver
+will respond to a sysfs probe() callback that indicates a HBA is present
+(e.g. a PCI device). After confirming it is a device that it wants to
+control, it will initialize the HBA and then register a new host with the
+SCSI mid level.
 
 Hot unplugging a HBA that controls a disk which is processing SCSI
 commands on a mounted file system is an ugly situation. Issues with
-this scenario are still being worked through. The primary concern in
+this scenario are still being worked through. The primary concern is
 the stability of the kernel (specifically the block and SCSI subsystems)
 since the effected disk can be "cleaned up" the next time it is seen.
 
-During LLD initialization the driver should register
-itself with the appropriate IO bus that it expects to find HBA(s)
-(e.g. the PCI bus). This can probably be done via sysfs (formerly known
-as driverfs). Any driver parameters (especially those that are writeable
-after the driver is loaded) could also be registered with sysfs at
-this point. At the end of driver initialization the SCSI mid level is
-typically not aware of its presence.
+During LLD initialization the driver should register itself with the
+appropriate IO bus that it expects to find HBA(s) (e.g. the PCI bus). This
+can probably be done via sysfs (formerly known as driverfs). Any driver
+parameters (especially those that are writeable after the driver is
+loaded) could also be registered with sysfs at this point. At the end of
+driver initialization the SCSI mid level is typically not aware of its
+presence.
 
 At some later time, the LLD becomes aware of a HBA and what follows
-is a typical sequence of calls (for 3 discovered SCSI devices)
-between the LLD and the mid level.
+is a typical sequence of calls between the LLD and the mid level.
+This example shows 3 devices being found and 1 device not being found:
 
 LLD                   mid level                    LLD
 ---                   ---------                    ---
 scsi_register()  -->
 scsi_add_host()  --------+
                          |
-                    slave_attach()  -->  scsi_adjust_queue_depth()
-                    slave_attach()  -->  scsi_adjust_queue_depth()
-                    slave_attach()  -->  scsi_adjust_queue_depth()
-
-The invocation of scsi_adjust_queue_depth() by the LLD is optional.
+		    slave_alloc()
+                    slave_configure() -->  scsi_adjust_queue_depth()
+			 |
+		    slave_alloc()
+                    slave_configure() -->  scsi_adjust_queue_depth()
+			 |
+		    slave_alloc()
+                    slave_configure() -->  scsi_adjust_queue_depth()
+			 |
+		    slave_alloc()   **
+                    slave_destroy() **
+
+The invocation of scsi_adjust_queue_depth() by the LLD is required
+if slave_configure() is supplied.
+** For scsi devices that the mid level tries to scan but do not
+   respond, a slave_alloc(), slave_destroy() pair is called.
 
 Here is the corresponding sequence when a host (HBA) is being
 removed:
@@ -131,29 +140,29 @@
 ---                   ---------
 scsi_remove_host()  -----+
                          |
-                    slave_detach() 
-                    slave_detach()
-                    slave_detach()
+                    slave_destroy() 
+                    slave_destroy()
+                    slave_destroy()
 scsi_unregister()  -->
 
 It is practical for a LLD to keep track of struct Scsi_Host instances
 (a pointer is returned by scsi_register() ) and struct scsi_device
-instances (a pointer is passed as the parameter to slave_attach() ).
-Both classes of instances are "owned" by the mid-level. struct scsi_devices 
-instances are freed after slave_detach(). struct Scsi_Host instances
-are freed after scsi_unregister().
+instances (a pointer is passed as the parameter to slave_alloc() and
+slave_configure() ). Both classes of instances are "owned" by the 
+mid-level. struct scsi_devices instances are freed after slave_destroy().
+struct Scsi_Host instances are freed after scsi_unregister().
 
 
 Passive initialization model
 ============================
-LLD initialization (both built-in and module) and shutdown and "wired
+LLD initialization (both built-in and module) and shutdown are "wired
 up" by passing function pointers to the module_init() and module_exit()
 macros respectively. In this model the function identified by "module_init"
 must call scsi_register_host() and the function identified by "module_exit"
 must call scsi_unregister_host().
 Most LLDs inherited from the lk 2.4 series include a file called
 "scsi_module.c" [yes the ".c" is a little surprising] in their
-source code. For it to work a declaration like this is needed before
+source code. For that file to work a declaration like this is needed before
 it is included:
     static struct SHT driver_template = DRIVER_TEMPLATE;
     #include "scsi_module.c"
@@ -164,7 +173,7 @@
 
 Here is an example of an initialization sequence when two hosts are
 detected (so detect() returns 2) and the SCSI bus scan on each host
-finds 3 SCSI devices.
+finds 1 SCSI device (and a second device does not respond).
 
 LLD                      mid level                 LLD
 ---                      ---------                 ---
@@ -175,17 +184,21 @@
                             |                scsi_register()
                             |                scsi_register()
                             |
-                      slave_attach()  -->  scsi_adjust_queue_depth()
-                      slave_attach()  -->  scsi_adjust_queue_depth()
-                      slave_attach()  -->  scsi_adjust_queue_depth()
+		      slave_alloc()
+                      slave_configure()  -->  scsi_adjust_queue_depth()
+		      slave_alloc()   **
+		      slave_destroy() **
                             |
-                      slave_attach()  -->  scsi_adjust_queue_depth()
-                      slave_attach()  -->  scsi_adjust_queue_depth()
-                      slave_attach()  -->  scsi_adjust_queue_depth()
+		      slave_alloc()
+                      slave_configure()  -->  scsi_adjust_queue_depth()
+		      slave_alloc()   **
+		      slave_destroy() **
 
-If the LLD does not supply a slave_attach() then the mid level invokes
+If the LLD does not supply a slave_configure() then the mid level invokes
 scsi_adjust_queue_depth() itself with tagged queuing off and "cmd_per_lun"
-for that host as the third parameter.
+for that host as the queue length.
+** For scsi devices that the mid level tries to scan but do not
+   respond, a slave_alloc(), slave_destroy() pair is called.
 
 Here is a LLD shutdown sequence:
 
@@ -193,17 +206,13 @@
 ---                      ---------                 ---
 scsi_unregister_host() -----+
                             |
-                     slave_detach()
-                     slave_detach()
-                     slave_detach()
+                     slave_destroy()
                         release()   -->   scsi_unregister()
                             |
-                     slave_detach()
-                     slave_detach()
-                     slave_detach()
+                     slave_destroy()
                         release()   -->   scsi_unregister()
 
-Both slave_detach() and release() are optional. If they are not supplied
+Both slave_destroy() and release() are optional. If they are not supplied
 the mid level supplies default actions.
 
 The shortcoming of the "passive initialization model" is that host
@@ -215,8 +224,7 @@
 
 Conventions
 ===========
-First there is Linus's thoughts on C coding found in file 
-Documentation/CodingStyle . 
+First Linus's thoughts on C coding found in file Documentation/CodingStyle . 
 
 Next there is a movement to "outlaw" typedefs introducing synonyms for 
 struct tags. Both can be still found in the SCSI subsystem, for example: 
@@ -264,9 +272,10 @@
  *	Returns nothing
  *
  * 	Notes: Can be invoked any time on a SCSI device controlled by this
- *	LLD. [Specifically after slave_attach() and prior to slave_detach().]
- *	Can safely be invoked from interrupt code. Actual queue depth change
- *	may be delayed until the next command is being processed.
+ *	LLD. [Specifically during and after slave_configure() and prior to
+ *	slave_destroy().] Can safely be invoked from interrupt code. Actual
+ *	queue depth change may be delayed until the next command is being
+ *	processed.
  *	Defined in drivers/scsi/scsi.c [see source code for more notes]
  *
  **/
@@ -471,11 +480,11 @@
 their function pointers are placed in an instance of struct SHT which
 is passed to scsi_register() [or scsi_register_host()]. Some
 are mandatory. Interface functions should be declared static. The 
-accepted convention is that driver "xyz" will declare its slave_attach() 
+accepted convention is that driver "xyz" will declare its slave_configure() 
 function as:
-    static int xyz_slave_attach(struct scsi_device * sdev);
+    static int xyz_slave_configure(struct scsi_device * sdev);
 
-A pointer to this function should be placed in the 'slave_attach' member
+A pointer to this function should be placed in the 'slave_configure' member
 of a "struct SHT" instance. A pointer to such an instance should
 passed to the mid level's scsi_register() [or scsi_register_host()].
 
@@ -787,13 +796,37 @@
 
 
 /**
- *      slave_attach - driver fine tuning for give device just after it
- *		       has been first scan (i.e. it responded to an
+ *      slave_alloc -	prior to any commands being sent to a new device 
+ *			(i.e. just prior to scan) this call is made
+ *      @sdp: pointer to new device (about to be scanned)
+ *
+ *      Returns 0 if ok. Any other return is assumed to be an error and
+ *	the device is ignored.
+ *
+ *      Required: no
+ *
+ *      Locks: none
+ *
+ *      Notes: Allows the driver to allocate any resources for a device
+ *	prior to its initial scan. The corresponding scsi device may not
+ *	exist but the mid level is just about to scan for it (i.e. send
+ *	and INQUIRY command plus ...). If a device is found then
+ *	slave_configure() will be called while if a device is not found
+ *	slave_destroy() is called.
+ *      For more details see the hosts.h file.
+ **/
+    int slave_alloc(struct scsi_device *sdp);
+
+
+/**
+ *      slave_configure - driver fine tuning for give device just after it
+ *		       has been first scanned (i.e. it responded to an
  *		       INQUIRY)
  *      @sdp: device that has just been attached
  *
  *      Returns 0 if ok. Any other return is assumed to be an error and
- *	the device is taken offline.
+ *	the device is taken offline. [offline devices will _not_ have
+ *	slave_destroy() called on them so clean up resources.]
  *
  *      Required: no
  *
@@ -805,16 +838,16 @@
  *	If this function is not supplied, the mid level will call
  *	scsi_adjust_queue_depth() with the struct Scsi_Host::cmd_per_lun
  *	value on behalf of the given device. If this function is
- *	supplied then its implementation is expected to call
+ *	supplied then its implementation must call
  *	scsi_adjust_queue_depth(). 	
  **/
-    int slave_attach(struct scsi_device *sdp);
+    int slave_configure(struct scsi_device *sdp);
 
 
 /**
- *      slave_detach - given device is about to be shut down. No further
- *		       commands will be sent.
- *      @sdp: device that is about to be detached
+ *      slave_destroy - given device is about to be shut down. All
+ *			activity has ceased on this device.
+ *      @sdp: device that is about to be shut down
  *
  *      Returns nothing
  *
@@ -827,10 +860,10 @@
  *	by this driver for given device should be freed now. No further
  *	commands will be sent for this sdp instance. [However the device
  *	could be re-attached in the future in which case a new instance
- *	of struct scsi_device would be supplied by a future slave_attach()
- *	call.]
+ *	of struct scsi_device would be supplied by future slave_alloc()
+ *	and slave_configure() calls.]
  **/
-    void slave_detach(struct scsi_device *sdp);
+    void slave_destroy(struct scsi_device *sdp);
 
 
 
@@ -958,7 +991,7 @@
 the SCSI subsystem now has its own (much smaller) drivers/scsi/Config.help
 file.
 
-Addition of slave_attach() and slave_detach().
+Addition of slave_alloc(), slave_configure() and slave_destroy().
 
 Addition of the "hotplug initialization model".
 
@@ -970,8 +1003,9 @@
         James Bottomley <James.Bottomley@steeleye.com> 
         Patrick Mansfield <patmans@us.ibm.com> 
 	Christoph Hellwig <hch@infradead.org>
+	Doug Ledford <dledford@redhat.com>
 
 
 Douglas Gilbert
 dgilbert@interlog.com
-17th November 2002
+29th November 2002
diff -Nru a/Documentation/sonypi.txt b/Documentation/sonypi.txt
--- a/Documentation/sonypi.txt	Mon Dec  9 18:46:34 2002
+++ b/Documentation/sonypi.txt	Mon Dec  9 18:46:34 2002
@@ -95,6 +95,7 @@
 				SONYPI_ZOOM_MASK 		0x0100
 				SONYPI_THUMBPHRASE_MASK 	0x0200
 				SONYPI_MEYE_MASK		0x0400
+				SONYPI_MEMORYSTICK_MASK		0x0800
 
 Module use:
 -----------
diff -Nru a/MAINTAINERS b/MAINTAINERS
--- a/MAINTAINERS	Mon Dec  9 18:46:38 2002
+++ b/MAINTAINERS	Mon Dec  9 18:46:38 2002
@@ -198,6 +198,11 @@
 M:	zippel@linux-m68k.org
 S:	Maintained
 
+AGPGART DRIVER
+P:	Dave Jones
+M:	davej@codemonkey.org.uk
+S:	Maintained
+
 AHA152X SCSI DRIVER
 P:	Juergen E. Fischer
 M:	Juergen Fischer <fischer@norbit.de>
@@ -261,11 +266,11 @@
 L:	linux-hams@vger.kernel.org
 S:	Maintained
 
-BAYCOM/HDLCDRV/SOUNDMODEM DRIVERS FOR AX.25
+BAYCOM/HDLCDRV DRIVERS FOR AX.25
 P:	Thomas Sailer
-M:	sailer@ife.ee.ethz.ch
+M:	t.sailer@alumni.ethz.ch
 L:	linux-hams@vger.kernel.org
-W:	http://www.ife.ee.ethz.ch/~sailer/ham/ham.html
+W:	http://www.baycom.org/~tom/ham/ham.html
 S:	Maintained
 
 BERKSHIRE PRODUCTS PC WATCHDOG DRIVER
@@ -637,6 +642,13 @@
 W:	http://www.farsite.co.uk/
 S:	Supported
 
+FRAMEBUFFER LAYER
+P:	James Simmons, Geert Uytterhoeven	
+M:	jsimmons@users.sf.net, geert@linux-m68k.org	
+L:	linux-fbdev-devel@lists.sourceforge.net	
+W:	http://www.linux-fbdev.org
+S:	Supported
+
 FILE LOCKING (flock() and fcntl()/lockf())
 P:	Matthew Wilcox
 M:	matthew@wil.cx
@@ -1112,6 +1124,12 @@
 L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
+MOTION EYE VAIO PICTUREBOOK CAMERA DRIVER
+P:	Stelian Pop
+M:	stelian@popies.net
+W:	http://popies.net/meye/
+S:	Maintained
+
 MOUSE AND MISC DEVICES [GENERAL]
 P:	Alessandro Rubini
 M:	rubini@ipvvis.unipv.it
@@ -1565,6 +1583,12 @@
 L:	linux-net@vger.kernel.org
 S:	Maintained
 
+SONY VAIO CONTROL DEVICE DRIVER
+P:	Stelian Pop
+M:	stelian@popies.net
+W:	http://popies.net/sonypi/
+S:	Maintained
+
 SOUND
 P:	Jaroslav Kysela
 M:	perex@suse.cz
@@ -1585,7 +1609,8 @@
 S:	Maintained
 
 SPARC (sparc32):
-S:	Unmaintained
+L:	sparclinux@vger.kernel.org
+S:	Unmaintained - please send patches to mailing list
 
 SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER
 P:	Roger Wolff
diff -Nru a/Makefile b/Makefile
--- a/Makefile	Mon Dec  9 18:46:34 2002
+++ b/Makefile	Mon Dec  9 18:46:34 2002
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 5
-SUBLEVEL = 50
+SUBLEVEL = 51
 EXTRAVERSION =
 
 # *DOCUMENTATION*
@@ -162,22 +162,21 @@
 MODFLAGS	= -DMODULE
 CFLAGS_MODULE   = $(MODFLAGS)
 AFLAGS_MODULE   = $(MODFLAGS)
+LDFLAGS_MODULE  = -r
 CFLAGS_KERNEL	=
 AFLAGS_KERNEL	=
+
 NOSTDINC_FLAGS  = -nostdinc -iwithprefix include
 
 CPPFLAGS	:= -D__KERNEL__ -Iinclude
 CFLAGS 		:= $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \
 	  	   -fno-strict-aliasing -fno-common
-ifndef CONFIG_FRAME_POINTER
-CFLAGS		+= -fomit-frame-pointer
-endif
 AFLAGS		:= -D__ASSEMBLY__ $(CPPFLAGS)
 
 export	VERSION PATCHLEVEL SUBLEVEL EXTRAVERSION KERNELRELEASE ARCH \
 	CONFIG_SHELL TOPDIR HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \
 	CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE \
-	HOSTCXX HOSTCXXFLAGS LDFLAGS_BLOB
+	HOSTCXX HOSTCXXFLAGS LDFLAGS_BLOB LDFLAGS_MODULE
 
 export CPPFLAGS NOSTDINC_FLAGS OBJCOPYFLAGS LDFLAGS
 export CFLAGS CFLAGS_KERNEL CFLAGS_MODULE 
@@ -203,7 +202,7 @@
 
 .PHONY: scripts
 scripts:
-	+@$(Q)$(MAKE) -f scripts/Makefile.build obj=scripts
+	$(Q)$(MAKE) -f scripts/Makefile.build obj=scripts
 
 # Objects we will link into vmlinux / subdirs we need to visit
 # ---------------------------------------------------------------------------
@@ -260,6 +259,10 @@
 export EXPORT_FLAGS := -DEXPORT_SYMTAB
 endif
 
+ifndef CONFIG_FRAME_POINTER
+CFLAGS		+= -fomit-frame-pointer
+endif
+
 #
 # INSTALL_PATH specifies where to place the updated kernel and system map
 # images.  Uncomment if you want to place them anywhere other than root.
@@ -351,12 +354,12 @@
 kallsyms.o := .tmp_kallsyms2.o
 
 quiet_cmd_kallsyms = KSYM    $@
-cmd_kallsyms = sh $(KALLSYMS) $< $@
+cmd_kallsyms = $(NM) -n $< | scripts/kallsyms > $@
 
-.tmp_kallsyms1.o: .tmp_vmlinux1
-	$(call cmd,kallsyms)
+.tmp_kallsyms1.o .tmp_kallsyms2.o: %.o: %.S scripts FORCE
+	$(call if_changed_dep,as_o_S)
 
-.tmp_kallsyms2.o: .tmp_vmlinux2
+.tmp_kallsyms%.S: .tmp_vmlinux%
 	$(call cmd,kallsyms)
 
 .tmp_vmlinux1: $(vmlinux-objs) arch/$(ARCH)/vmlinux.lds.s FORCE
@@ -435,7 +438,7 @@
 # 	with it and forgot to run make oldconfig
 
 include/linux/autoconf.h: .config
-	+@$(call descend,scripts/kconfig,scripts/kconfig/conf)
+	$(Q)$(MAKE) -f scripts/Makefile.build obj=scripts/kconfig scripts/kconfig/conf
 	./scripts/kconfig/conf -s arch/$(ARCH)/Kconfig
 
 # Generate some files
@@ -542,7 +545,7 @@
 
 .PHONY: $(patsubst %, _modinst_%, $(SUBDIRS))
 $(patsubst %, _modinst_%, $(SUBDIRS)) :
-	$(Q)$(MAKE) -f scripts/Makefile.modinst obj=$(patsubst _modinst_%,%,$@)
+	$(Q)$(MAKE) -rR -f scripts/Makefile.modinst obj=$(patsubst _modinst_%,%,$@)
 else # CONFIG_MODULES
 
 # Modules not configured
@@ -639,13 +642,13 @@
 	make_with_config
 
 scripts/kconfig/conf scripts/kconfig/mconf scripts/kconfig/qconf: scripts/fixdep FORCE
-	+@$(call descend,scripts/kconfig,$@)
+	$(Q)$(MAKE) -f scripts/Makefile.build obj=scripts/kconfig $@
 
 xconfig: scripts/kconfig/qconf
 	./scripts/kconfig/qconf arch/$(ARCH)/Kconfig
 
 menuconfig: scripts/kconfig/mconf
-	$(Q)$(MAKE) -f scripts/Makefile.build obj=scripts lxdialog
+	$(Q)$(MAKE) -f scripts/Makefile.build obj=scripts/lxdialog
 	./scripts/kconfig/mconf arch/$(ARCH)/Kconfig
 
 config: scripts/kconfig/conf
@@ -708,8 +711,9 @@
 clean: archclean $(addprefix _clean_,$(clean-dirs))
 	$(call cmd,rmclean)
 	@find . $(RCS_FIND_IGNORE) \
-	 	\( -name '*.[oas]' -o -name '.*.cmd' -o -name '.*.d' \
-		-o -name '.*.tmp' \) -type f -print | xargs rm -f
+	 	\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
+		-o -name '.*.d' -o -name '.*.tmp' \) -type f \
+		-print | xargs rm -f
 
 # mrproper - delete configuration + modules + core files
 #
@@ -795,7 +799,7 @@
 	@echo  ''
 	@echo  'Execute "make" or "make all" to build all targets marked with [*] '
 	@echo  'For further info browse Documentation/kbuild/*'
- 
+
 
 # Documentation targets
 # ---------------------------------------------------------------------------
@@ -827,7 +831,7 @@
 # ===========================================================================
 
 %:: FORCE
-	$(MAKE) $@
+	$(Q)$(MAKE) $@
 
 endif # ifeq ($(filter-out $(noconfig_targets),$(MAKECMDGOALS)),)
 endif # ifdef include_config
@@ -841,6 +845,9 @@
 quiet_cmd_as_s_S = CPP     $@
 cmd_as_s_S       = $(CPP) $(a_flags)   -o $@ $< 
 
+quiet_cmd_as_o_S = AS      $@
+cmd_as_o_S       = $(CC) $(a_flags) -c -o $@ $<
+
 # read all saved command lines
 
 targets := $(wildcard $(sort $(targets)))
@@ -888,6 +895,6 @@
 #	$(call descend,<dir>,<target>)
 #	Recursively call a sub-make in <dir> with target <target>
 
-descend = $(Q)$(MAKE) -f scripts/Makefile.build obj=$(1) $(2)
+descend =$(Q)$(MAKE) -f scripts/Makefile.build obj=$(1) $(2)
 
 FORCE:
diff -Nru a/arch/alpha/Kconfig b/arch/alpha/Kconfig
--- a/arch/alpha/Kconfig	Mon Dec  9 18:46:50 2002
+++ b/arch/alpha/Kconfig	Mon Dec  9 18:46:50 2002
@@ -900,38 +900,7 @@
 
 source "fs/Kconfig"
 
-
-menu "Console drivers"
-	depends on VT
-
-config VGA_CONSOLE
-	bool "VGA text console"
-	help
-	  Saying Y here will allow you to use Linux in text mode through a
-	  display that complies with the generic VGA standard. Virtually
-	  everyone wants that.
-
-	  The program SVGATextMode can be used to utilize SVGA video cards to
-	  their full potential in text mode. Download it from
-	  <ftp://ibiblio.org/pub/Linux/utils/console/>.
-
-	  Say Y.
-
-#  if [ "$CONFIG_PCI" = "y" -a "$CONFIG_VGA_CONSOLE" = "y" ]; then
-#    bool '   Allow VGA on any bus?' CONFIG_VGA_HOSE
-#    if [ "$CONFIG_VGA_HOSE" = "y" ]; then
-#      define_bool CONFIG_DUMMY_CONSOLE y
-#    fi
-#  fi
 source "drivers/video/Kconfig"
-
-config PCI_CONSOLE
-	bool
-	depends on FB
-	default y
-
-endmenu
-
 
 menu "Sound"
 
diff -Nru a/arch/alpha/kernel/core_cia.c b/arch/alpha/kernel/core_cia.c
--- a/arch/alpha/kernel/core_cia.c	Mon Dec  9 18:46:38 2002
+++ b/arch/alpha/kernel/core_cia.c	Mon Dec  9 18:46:38 2002
@@ -336,7 +336,7 @@
 }
 
 static inline void
-cia_prepare_tbia_workaround(int cia_rev, int is_pyxis)
+cia_prepare_tbia_workaround(int window)
 {
 	unsigned long *ppte, pte;
 	long i;
@@ -348,20 +348,10 @@
 	for (i = 0; i < CIA_BROKEN_TBIA_SIZE / sizeof(unsigned long); ++i)
 		ppte[i] = pte;
 
-	if (is_pyxis || cia_rev != 1) {
-		/* We can use W1 for SG on PYXIS/CIA rev 2. */
-		*(vip)CIA_IOC_PCI_W1_BASE = CIA_BROKEN_TBIA_BASE | 3;
-		*(vip)CIA_IOC_PCI_W1_MASK = (CIA_BROKEN_TBIA_SIZE*1024 - 1)
-					    & 0xfff00000;
-		*(vip)CIA_IOC_PCI_T1_BASE = virt_to_phys(ppte) >> 2;
-	} else {
-		/* CIA rev 1 can't use W1 or W2 for SG, apparently,
-		   so use W3, which we made sure is not used for DAC. */
-		*(vip)CIA_IOC_PCI_W3_BASE = CIA_BROKEN_TBIA_BASE | 3;
-		*(vip)CIA_IOC_PCI_W3_MASK = (CIA_BROKEN_TBIA_SIZE*1024 - 1)
-					    & 0xfff00000;
-		*(vip)CIA_IOC_PCI_T3_BASE = virt_to_phys(ppte) >> 2;
-	}
+	*(vip)CIA_IOC_PCI_Wn_BASE(window) = CIA_BROKEN_TBIA_BASE | 3;
+	*(vip)CIA_IOC_PCI_Wn_MASK(window)
+	  = (CIA_BROKEN_TBIA_SIZE*1024 - 1) & 0xfff00000;
+	*(vip)CIA_IOC_PCI_Tn_BASE(window) = virt_to_phys(ppte) >> 2;
 }
 
 static void __init
@@ -581,8 +571,7 @@
 do_init_arch(int is_pyxis)
 {
 	struct pci_controller *hose;
-	int temp;
-	int cia_rev;
+	int temp, cia_rev, tbia_window;
 
 	cia_rev = *(vip)CIA_IOC_CIA_REV & CIA_REV_MASK;
 	printk("pci: cia revision %d%s\n",
@@ -712,12 +701,18 @@
 	   elsewhere, we should not claim that we support DAC unless that
 	   4GB covers all of physical memory.
 
-	   Also, don't do DAC on CIA rev 1, it has other problems and is
-	   unlikely to have more than 2GB of memory anyway, so direct is
-	   fine.
-	*/
-	if (cia_rev == 1 || is_pyxis ||
-	    max_low_pfn > (0x100000000UL >> PAGE_SHIFT)) {
+	   On CIA rev 1, apparently W1 and W2 can't be used for SG. 
+	   At least, there are reports that it doesn't work for Alcor. 
+	   In that case, we have no choice but to use W3 for the TBIA 
+	   workaround, which means we can't use DAC at all. */ 
+
+	tbia_window = 1;
+	if (is_pyxis) {
+		*(vip)CIA_IOC_PCI_W3_BASE = 0;
+	} else if (cia_rev == 1) {
+		*(vip)CIA_IOC_PCI_W1_BASE = 0;
+		tbia_window = 3;
+	} else if (max_low_pfn > (0x100000000UL >> PAGE_SHIFT)) {
 		*(vip)CIA_IOC_PCI_W3_BASE = 0;
 	} else {
 		*(vip)CIA_IOC_PCI_W3_BASE = 0x00000000 | 1 | 8;
@@ -729,7 +724,7 @@
 	}
 
 	/* Prepare workaround for apparently broken tbia. */
-	cia_prepare_tbia_workaround(cia_rev, is_pyxis);
+	cia_prepare_tbia_workaround(tbia_window);
 }
 
 void __init
diff -Nru a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
--- a/arch/alpha/kernel/pci.c	Mon Dec  9 18:46:34 2002
+++ b/arch/alpha/kernel/pci.c	Mon Dec  9 18:46:34 2002
@@ -99,20 +99,13 @@
 	   them on.  So if we use a large direct-map window, or a large SG
 	   window, we must avoid the entire 0xfff00000-0xffffffff region.  */
 	else if (dev->class >> 8 == PCI_CLASS_BRIDGE_ISA) {
-#define DMAPSZ (max_low_pfn << PAGE_SHIFT) /* memory size, not window size */
-		if ((__direct_map_base + DMAPSZ - 1) >= 0xfff00000UL) {
+		if (__direct_map_base + __direct_map_size >= 0xfff00000UL)
 			__direct_map_size = 0xfff00000UL - __direct_map_base;
-			printk("%s: adjusting direct map size to 0x%lx\n",
-			       __FUNCTION__, __direct_map_size);
-		} else {
+		else {
 			struct pci_controller *hose = dev->sysdata;
 			struct pci_iommu_arena *pci = hose->sg_pci;
-			if (pci &&
-			    (pci->dma_base + pci->size - 1) >= 0xfff00000UL) {
+			if (pci && pci->dma_base + pci->size >= 0xfff00000UL)
 				pci->size = 0xfff00000UL - pci->dma_base;
- 				printk("%s: adjusting PCI S/G size to 0x%x\n",
-				       __FUNCTION__, pci->size);
-			}
 		}
 	}
 }
@@ -263,9 +256,20 @@
 	struct pci_dev *dev = bus->self;
 
 	if (!dev) {
-		/* Root bus */
+		/* Root bus. */
+		u32 pci_mem_end;
+		u32 sg_base = hose->sg_pci ? hose->sg_pci->dma_base : ~0;
+		unsigned long end;
+
 		bus->resource[0] = hose->io_space;
 		bus->resource[1] = hose->mem_space;
+
+		/* Adjust hose mem_space limit to prevent PCI allocations
+		   in the iommu windows. */
+		pci_mem_end = min((u32)__direct_map_base, sg_base) - 1;
+		end = hose->mem_space->start + pci_mem_end;
+		if (hose->mem_space->end > end)
+			hose->mem_space->end = end;
 	}
 
 	for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
@@ -276,10 +280,11 @@
 }
 
 void
-pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+pcibios_update_resource(struct pci_dev *dev, struct resource *parent,
 			struct resource *res, int resource)
 {
 	struct pci_controller *hose = dev->sysdata;
+	struct resource *root;
 	int where;
 	u32 reg;
 
@@ -294,8 +299,11 @@
 	/* Point root at the hose root. */
 	if (res->flags & IORESOURCE_IO)
 		root = hose->io_space;
-	if (res->flags & IORESOURCE_MEM)
+	else if (res->flags & IORESOURCE_MEM)
 		root = hose->mem_space;
+	else {
+		return; /* Don't update non-standard resources here. */
+	}
 
 	reg = (res->start - root->start) | (res->flags & 0xf);
 	pci_write_config_dword(dev, where, reg);
@@ -359,7 +367,27 @@
 int
 pcibios_enable_device(struct pci_dev *dev, int mask)
 {
-	/* Nothing to do, since we enable all devices at startup.  */
+	u16 cmd, oldcmd;
+	int i;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	oldcmd = cmd;
+
+	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+		struct resource *res = &dev->resource[i];
+
+		if (res->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		else if (res->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+
+	if (cmd != oldcmd) {
+		printk(KERN_DEBUG "PCI: Enabling device: (%s), cmd %x\n",
+		       dev->slot_name, cmd);
+		/* Enable the appropriate bits in the PCI command register.  */
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
 	return 0;
 }
 
diff -Nru a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
--- a/arch/alpha/kernel/signal.c	Mon Dec  9 18:46:37 2002
+++ b/arch/alpha/kernel/signal.c	Mon Dec  9 18:46:37 2002
@@ -587,6 +587,10 @@
 		regs->r19 = r19;
 		regs->pc -= 4;
 		break;
+	case ERESTART_RESTARTBLOCK:
+		current_thread_info()->restart_block.fn = do_no_restart_syscall;
+		regs->r0 = EINTR;
+		break;
 	}
 }
 
@@ -628,13 +632,22 @@
 		return 1;
 	}
 
-	if (r0 &&
-	    (regs->r0 == ERESTARTNOHAND ||
-	     regs->r0 == ERESTARTSYS ||
-	     regs->r0 == ERESTARTNOINTR)) {
-		regs->r0 = r0;	/* reset v0 and a3 and replay syscall */
-		regs->r19 = r19;
-		regs->pc -= 4;
+	if (r0) {
+	  	switch (regs->r0) {
+		case ERESTARTNOHAND:
+		case ERESTARTSYS:
+		case ERESTARTNOINTR:
+			/* Reset v0 and a3 and replay syscall.  */
+			regs->r0 = r0;
+			regs->r19 = r19;
+			regs->pc -= 4;
+			break;
+		case ERESTART_RESTARTBLOCK:
+			/* Force v0 to the restart syscall and reply.  */
+			regs->r0 = __NR_restart_syscall;
+			regs->pc -= 4;
+			break;
+		}
 	}
 	if (single_stepping)
 		ptrace_set_bpt(current);	/* re-set breakpoint */
diff -Nru a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S
--- a/arch/alpha/kernel/systbls.S	Mon Dec  9 18:46:49 2002
+++ b/arch/alpha/kernel/systbls.S	Mon Dec  9 18:46:49 2002
@@ -431,6 +431,7 @@
 	.quad sys_epoll_wait
 	.quad sys_remap_file_pages		/* 410 */
 	.quad sys_set_tid_address
+	.quad sys_restart_syscall
 
 	.size sys_call_table, . - sys_call_table
 	.type sys_call_table, @object
diff -Nru a/arch/alpha/lib/ev6-stxncpy.S b/arch/alpha/lib/ev6-stxncpy.S
--- a/arch/alpha/lib/ev6-stxncpy.S	Mon Dec  9 18:46:50 2002
+++ b/arch/alpha/lib/ev6-stxncpy.S	Mon Dec  9 18:46:50 2002
@@ -25,7 +25,7 @@
  *	a0  = unaligned address of the last *word* written
  *	a2  = the number of full words left in COUNT
  *
- * Furthermore, v0, a3-a5, t11, t12, and $at are untouched.
+ * Furthermore, v0, a3-a5, t11, and $at are untouched.
  *
  * Much of the information about 21264 scheduling/coding comes from:
  *	Compiler Writer's Guide for the Alpha 21264
@@ -324,7 +324,7 @@
 	extqh	t2, a1, t0	# U : extract low bits for last word (stall)
 	or	t1, t0, t1	# E : (stall)
 
-	cmpbge	zero, t1, t8	# E :
+1:	cmpbge	zero, t1, t8	# E :
 	mov	t1, t0		# E :
 
 $u_eocfin:			# end-of-count, final word
@@ -350,17 +350,17 @@
 	mskql	t6, a0, t6	# U :
 	nop
 	nop
-1:	subq	a1, t4, a1	# E : sub dest misalignment from src addr
+	subq	a1, t4, a1	# E : sub dest misalignment from src addr
 
 	/* If source misalignment is larger than dest misalignment, we need
 	   extra startup checks to avoid SEGV.  */
 
-	cmplt	t4, t5, t12	# E :
+1:	cmplt	t4, t5, t12	# E :
 	extql	t1, a1, t1	# U : shift src into place
 	lda	t2, -1		# E : for creating masks later
 	beq	t12, $u_head	# U : (stall)
 
-	mskqh	t2, t5, t2	# U : begin src byte validity mask
+	nop
 	cmpbge	zero, t1, t8	# E : is there a zero?
 	extql	t2, a1, t2	# U :
 	or	t8, t10, t5	# E : test for end-of-count too
diff -Nru a/arch/alpha/lib/stxncpy.S b/arch/alpha/lib/stxncpy.S
--- a/arch/alpha/lib/stxncpy.S	Mon Dec  9 18:46:51 2002
+++ b/arch/alpha/lib/stxncpy.S	Mon Dec  9 18:46:51 2002
@@ -25,7 +25,7 @@
  *	a0  = unaligned address of the last *word* written
  *	a2  = the number of full words left in COUNT
  *
- * Furthermore, v0, a3-a5, t11, t12, and $at are untouched.
+ * Furthermore, v0, a3-a5, t11, and $at are untouched.
  */
 
 #include <asm/regdef.h>
@@ -269,7 +269,7 @@
 	   t1 == the shifted high-order bits from the previous source word  */
 $u_eoc:
 	and	a1, 7, t6	# e1    :
-	sll	t12, t6, t6	# e0    :
+	sll	t10, t6, t6	# e0    :
 	and	t6, 0xff, t6	# e0    :
 	bne	t6, 1f		# .. e1 :
 
@@ -303,18 +303,17 @@
 	ldq_u	t0, 0(a0)	# e0    :
 	lda	t6, -1		# .. e1 :
 	mskql	t6, a0, t6	# e0    :
-1:
 	subq	a1, t4, a1	# .. e1 : sub dest misalignment from src addr
 
 	/* If source misalignment is larger than dest misalignment, we need
 	   extra startup checks to avoid SEGV.  */
 
-	cmplt	t4, t5, t12	# e1    :
+1:	cmplt	t4, t5, t12	# e1    :
 	extql	t1, a1, t1	# .. e0 : shift src into place
 	lda	t2, -1		# e0    : for creating masks later
-	beq	t12, $u_head	# e1    :
+	beq	t12, $u_head	# .. e1 :
 
-	mskqh	t2, t5, t2	# e0    : begin src byte validity mask
+	nop			# e0    :
 	cmpbge	zero, t1, t8	# .. e1 : is there a zero?
 	extql	t2, a1, t2	# e0    :
 	or	t8, t10, t5	# .. e1 : test for end-of-count too
diff -Nru a/arch/arm/Kconfig b/arch/arm/Kconfig
--- a/arch/arm/Kconfig	Mon Dec  9 18:46:38 2002
+++ b/arch/arm/Kconfig	Mon Dec  9 18:46:38 2002
@@ -1047,28 +1047,7 @@
 
 source "fs/Kconfig"
 
-
-menu "Console drivers"
-	depends on VT
-
-config VGA_CONSOLE
-	bool "VGA text console"
-	depends on !ARCH_ACORN && !ARCH_EBSA110
-	help
-	  Saying Y here will allow you to use Linux in text mode through a
-	  display that complies with the generic VGA standard. Virtually
-	  everyone wants that.
-
-	  The program SVGATextMode can be used to utilize SVGA video cards to
-	  their full potential in text mode. Download it from
-	  <ftp://ibiblio.org/pub/Linux/utils/console/>.
-
-	  Say Y.
-
 source "drivers/video/Kconfig"
-
-endmenu
-
 
 menu "Sound"
 	depends on ARCH_ACORN || ARCH_CLPS7500 || ARCH_TBOX || ARCH_SHARK || ARCH_SA1100 || PCI
diff -Nru a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
--- a/arch/arm/kernel/ptrace.c	Mon Dec  9 18:46:34 2002
+++ b/arch/arm/kernel/ptrace.c	Mon Dec  9 18:46:34 2002
@@ -711,7 +711,8 @@
 		/* are we already being traced? */
 		if (current->ptrace & PT_PTRACED)
 			goto out;
-		if ((ret = security_ptrace(current->parent, current)))
+		ret = security_ptrace(current->parent, current);
+		if (ret)
 			goto out;
 		/* set the ptrace bit in the process flags. */
 		current->ptrace |= PT_PTRACED;
diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig
--- a/arch/i386/Kconfig	Mon Dec  9 18:46:35 2002
+++ b/arch/i386/Kconfig	Mon Dec  9 18:46:35 2002
@@ -789,8 +789,6 @@
 
 menu "Power management options (ACPI, APM)"
 
-source "drivers/acpi/Kconfig"
-
 config PM
 	bool "Power Management support"
 	---help---
@@ -811,6 +809,37 @@
 	  will issue the hlt instruction if nothing is to be done, thereby
 	  sending the processor to sleep and saving power.
 
+config SOFTWARE_SUSPEND
+	bool "Software Suspend (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && PM
+	---help---
+	  Enable the possibilty of suspendig machine. It doesn't need APM.
+	  You may suspend your machine by 'swsusp' or 'shutdown -z <time>' 
+	  (patch for sysvinit needed). 
+
+	  It creates an image which is saved in your active swaps. By the next
+	  booting the, pass 'resume=/path/to/your/swap/file' and kernel will 
+	  detect the saved image, restore the memory from
+	  it and then it continues to run as before you've suspended.
+	  If you don't want the previous state to continue use the 'noresume'
+	  kernel option. However note that your partitions will be fsck'd and
+	  you must re-mkswap your swap partitions/files.
+
+	  Right now you may boot without resuming and then later resume but
+	  in meantime you cannot use those swap partitions/files which were
+	  involved in suspending. Also in this case there is a risk that buffers
+	  on disk won't match with saved ones.
+
+	  SMP is supported ``as-is''. There's a code for it but doesn't work.
+	  There have been problems reported relating SCSI.
+
+	  This option is about getting stable. However there is still some
+	  absence of features.
+
+	  For more information take a look at Documentation/swsusp.txt.
+
+source "drivers/acpi/Kconfig"
+
 config APM
 	tristate "Advanced Power Management BIOS support"
 	depends on PM
@@ -1079,6 +1108,8 @@
 	  <file:Documentation/mca.txt> (and especially the web page given
 	  there) before attempting to build an MCA bus kernel.
 
+source "drivers/mca/Kconfig"
+
 config HOTPLUG
 	bool "Support for hot-pluggable devices"
 	---help---
@@ -1414,63 +1445,8 @@
 
 source "fs/Kconfig"
 
-
-menu "Console drivers"
-	depends on VT
-
-config VGA_CONSOLE
-	bool "VGA text console"
-	help
-	  Saying Y here will allow you to use Linux in text mode through a
-	  display that complies with the generic VGA standard. Virtually
-	  everyone wants that.
-
-	  The program SVGATextMode can be used to utilize SVGA video cards to
-	  their full potential in text mode. Download it from
-	  <ftp://ibiblio.org/pub/Linux/utils/console/>.
-
-	  Say Y.
-
-config VIDEO_SELECT
-	bool "Video mode selection support"
-	---help---
-	  This enables support for text mode selection on kernel startup. If
-	  you want to take advantage of some high-resolution text mode your
-	  card's BIOS offers, but the traditional Linux utilities like
-	  SVGATextMode don't, you can say Y here and set the mode using the
-	  "vga=" option from your boot loader (lilo or loadlin) or set
-	  "vga=ask" which brings up a video mode menu on kernel startup. (Try
-	  "man bootparam" or see the documentation of your boot loader about
-	  how to pass options to the kernel.)
-
-	  Read the file <file:Documentation/svga.txt> for more information
-	  about the Video mode selection support. If unsure, say N.
-
-if EXPERIMENTAL
-
-config MDA_CONSOLE
-	tristate "MDA text console (dual-headed) (EXPERIMENTAL)"
-	---help---
-	  Say Y here if you have an old MDA or monochrome Hercules graphics
-	  adapter in your system acting as a second head ( = video card). You
-	  will then be able to use two monitors with your Linux system. Do not
-	  say Y here if your MDA card is the primary card in your system; the
-	  normal VGA driver will handle it.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted and removed from the running kernel whenever you want).
-	  The module will be called mdacon.o. If you want to compile it as
-	  a module, say M here and read <file:Documentation/modules.txt>.
-
-	  If unsure, say N.
-
 source "drivers/video/Kconfig"
 
-endif
-
-endmenu
-
-
 menu "Sound"
 
 config SOUND
@@ -1515,35 +1491,6 @@
 
 
 menu "Kernel hacking"
-
-config SOFTWARE_SUSPEND
-	bool "Software Suspend (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && PM
-	---help---
-	  Enable the possibilty of suspendig machine. It doesn't need APM.
-	  You may suspend your machine by 'swsusp' or 'shutdown -z <time>' 
-	  (patch for sysvinit needed). 
-
-	  It creates an image which is saved in your active swaps. By the next
-	  booting the, pass 'resume=/path/to/your/swap/file' and kernel will 
-	  detect the saved image, restore the memory from
-	  it and then it continues to run as before you've suspended.
-	  If you don't want the previous state to continue use the 'noresume'
-	  kernel option. However note that your partitions will be fsck'd and
-	  you must re-mkswap your swap partitions/files.
-
-	  Right now you may boot without resuming and then later resume but
-	  in meantime you cannot use those swap partitions/files which were
-	  involved in suspending. Also in this case there is a risk that buffers
-	  on disk won't match with saved ones.
-
-	  SMP is supported ``as-is''. There's a code for it but doesn't work.
-	  There have been problems reported relating SCSI.
-
-	  This option is about getting stable. However there is still some
-	  absence of features.
-
-	  For more information take a look at Documentation/swsusp.txt.
 
 config DEBUG_KERNEL
 	bool "Kernel debugging"
diff -Nru a/arch/i386/Makefile b/arch/i386/Makefile
--- a/arch/i386/Makefile	Mon Dec  9 18:46:36 2002
+++ b/arch/i386/Makefile	Mon Dec  9 18:46:36 2002
@@ -66,7 +66,7 @@
 CFLAGS += -Iarch/i386/$(MACHINE)
 AFLAGS += -Iarch/i386/$(MACHINE)
 
-makeboot = $(call descend,arch/i386/boot,$(1))
+makeboot =$(Q)$(MAKE) -f scripts/Makefile.build obj=arch/i386/boot $(1)
 
 .PHONY: zImage bzImage compressed zlilo bzlilo zdisk bzdisk install \
 		clean archclean archmrproper
@@ -77,20 +77,20 @@
 zImage zlilo zdisk: BOOTIMAGE=arch/i386/boot/zImage
 
 zImage bzImage: vmlinux
-	+@$(call makeboot,$(BOOTIMAGE))
+	$(call makeboot,$(BOOTIMAGE))
 
 compressed: zImage
 
 zlilo bzlilo: vmlinux
-	+@$(call makeboot,BOOTIMAGE=$(BOOTIMAGE) zlilo)
+	$(call makeboot,BOOTIMAGE=$(BOOTIMAGE) zlilo)
 
 zdisk bzdisk: vmlinux
-	+@$(call makeboot,BOOTIMAGE=$(BOOTIMAGE) zdisk)
+	$(call makeboot,BOOTIMAGE=$(BOOTIMAGE) zdisk)
 
 install: vmlinux
-	+@$(call makeboot,BOOTIMAGE=$(BOOTIMAGE) install)
+	$(call makeboot,BOOTIMAGE=$(BOOTIMAGE) install)
 
 archclean:
-	@$(MAKE) -f scripts/Makefile.clean obj=arch/i386/boot
+	$(Q)$(MAKE) -f scripts/Makefile.clean obj=arch/i386/boot
 
 archmrproper:
diff -Nru a/arch/i386/boot/Makefile b/arch/i386/boot/Makefile
--- a/arch/i386/boot/Makefile	Mon Dec  9 18:46:36 2002
+++ b/arch/i386/boot/Makefile	Mon Dec  9 18:46:36 2002
@@ -32,12 +32,6 @@
 
 host-progs	:= tools/build
 
-# 	Default
-
-boot: bzImage
-
-include $(TOPDIR)/Rules.make
-
 # ---------------------------------------------------------------------------
 
 $(obj)/zImage:  IMAGE_OFFSET := 0x1000
@@ -53,6 +47,7 @@
 $(obj)/zImage $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
 			      $(obj)/vmlinux.bin $(obj)/tools/build FORCE
 	$(call if_changed,image)
+	@echo 'Kernel: $@ is ready'
 
 $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
 	$(call if_changed,objcopy)
@@ -64,9 +59,8 @@
 	$(call if_changed,ld)
 
 $(obj)/compressed/vmlinux: FORCE
-	+@$(call descend,$(obj)/compressed,IMAGE_OFFSET=$(IMAGE_OFFSET) \
-		$(obj)/compressed/vmlinux)
-
+	$(Q)$(MAKE) -f scripts/Makefile.build obj=$(obj)/compressed \
+					IMAGE_OFFSET=$(IMAGE_OFFSET) $@
 
 zdisk: $(BOOTIMAGE)
 	dd bs=8192 if=$(BOOTIMAGE) of=/dev/fd0
diff -Nru a/arch/i386/boot/compressed/Makefile b/arch/i386/boot/compressed/Makefile
--- a/arch/i386/boot/compressed/Makefile	Mon Dec  9 18:46:50 2002
+++ b/arch/i386/boot/compressed/Makefile	Mon Dec  9 18:46:50 2002
@@ -13,6 +13,7 @@
 
 $(obj)/vmlinux: $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE
 	$(call if_changed,ld)
+	@:
 
 $(obj)/vmlinux.bin: vmlinux FORCE
 	$(call if_changed,objcopy)
diff -Nru a/arch/i386/kernel/acpi.c b/arch/i386/kernel/acpi.c
--- a/arch/i386/kernel/acpi.c	Mon Dec  9 18:46:51 2002
+++ b/arch/i386/kernel/acpi.c	Mon Dec  9 18:46:51 2002
@@ -446,72 +446,19 @@
 
 #ifdef CONFIG_ACPI_SLEEP
 
-#define DEBUG
-
-#ifdef DEBUG
-#include <linux/serial.h>
-#endif
-
 /* address in low memory of the wakeup routine. */
 unsigned long acpi_wakeup_address = 0;
 
-/* new page directory that we will be using */
-static pmd_t *pmd;
-
-/* saved page directory */
-static pmd_t saved_pmd;
-
-/* page which we'll use for the new page directory */
-static pte_t *ptep;
-
 extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long));
 
-/*
- * acpi_create_identity_pmd
- *
- * Create a new, identity mapped pmd.
- *
- * Do this by creating new page directory, and marking all the pages as R/W
- * Then set it as the new Page Middle Directory.
- * And, of course, flush the TLB so it takes effect.
- *
- * We save the address of the old one, for later restoration.
- */
-static void acpi_create_identity_pmd (void)
+static void init_low_mapping(pgd_t *pgd, int pgd_ofs, int pgd_limit)
 {
-	pgd_t *pgd;
-	int i;
-
-	ptep = (pte_t*)__get_free_page(GFP_KERNEL);
+	int pgd_ofs = 0;
 
-	/* fill page with low mapping */
-	for (i = 0; i < PTRS_PER_PTE; i++)
-		set_pte(ptep + i, pfn_pte(i, PAGE_SHARED));
-
-	pgd = pgd_offset(current->active_mm, 0);
-	pmd = pmd_alloc(current->mm,pgd, 0);
-
-	/* save the old pmd */
-	saved_pmd = *pmd;
-
-	/* set the new one */
-	set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(ptep)));
-
-	/* flush the TLB */
-	local_flush_tlb();
-}
-
-/*
- * acpi_restore_pmd
- *
- * Restore the old pmd saved by acpi_create_identity_pmd and
- * free the page that said function alloc'd
- */
-static void acpi_restore_pmd (void)
-{
-	set_pmd(pmd, saved_pmd);
-	local_flush_tlb();
-	free_page((unsigned long)ptep);
+	while ((pgd_ofs < pgd_limit) && (pgd_ofs + USER_PTRS_PER_PGD < PTRS_PER_PGD)) {
+		set_pgd(pgd, *(pgd+USER_PTRS_PER_PGD));
+		pgd_ofs++, pgd++;
+	}
 }
 
 /**
@@ -522,7 +469,11 @@
  */
 int acpi_save_state_mem (void)
 {
-	acpi_create_identity_pmd();
+#if CONFIG_X86_PAE
+	panic("S3 and PAE do not like each other for now.");
+	return 1;
+#endif
+	init_low_mapping(swapper_pg_dir, 0, USER_PTRS_PER_PGD);
 	acpi_copy_wakeup_routine(acpi_wakeup_address);
 
 	return 0;
@@ -542,7 +493,7 @@
  */
 void acpi_restore_state_mem (void)
 {
-	acpi_restore_pmd();
+	zap_low_mappings();
 }
 
 /**
@@ -555,7 +506,10 @@
  */
 void __init acpi_reserve_bootmem(void)
 {
+	extern char wakeup_start, wakeup_end;
 	acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE);
+	if ((&wakeup_end - &wakeup_start) > PAGE_SIZE)
+		printk(KERN_CRIT "ACPI: Wakeup code way too big, will crash on attempt to suspend\n");
 	printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address);
 }
 
diff -Nru a/arch/i386/kernel/acpi_wakeup.S b/arch/i386/kernel/acpi_wakeup.S
--- a/arch/i386/kernel/acpi_wakeup.S	Mon Dec  9 18:46:35 2002
+++ b/arch/i386/kernel/acpi_wakeup.S	Mon Dec  9 18:46:35 2002
@@ -1,12 +1,21 @@
-
 .text
 #include <linux/linkage.h>
 #include <asm/segment.h>
+#include <asm/page.h>
 
-# Do we need to deal with A20?
+#
+# wakeup_code runs in real mode, and at unknown address (determined at run-time).
+# Therefore it must only use relative jumps/calls. 
+#
+# Do we need to deal with A20? It is okay: ACPI specs says A20 must be enabled
+#
+# If physical address of wakeup_code is 0x12345, BIOS should call us with
+# cs = 0x1234, eip = 0x05
+# 
 
 ALIGN
-wakeup_start:
+	.align	4096
+ENTRY(wakeup_start)
 wakeup_code:
 	wakeup_code_start = .
 	.code16
@@ -14,49 +23,70 @@
  	movw	$0xb800, %ax
 	movw	%ax,%fs
 	movw	$0x0e00 + 'L', %fs:(0x10)
+
 	cli
 	cld
-	  
+
 	# setup data segment
 	movw	%cs, %ax
-
-	addw	$(wakeup_data - wakeup_code) >> 4, %ax
-	movw	%ax, %ds
+	movw	%ax, %ds					# Make ds:0 point to wakeup_start
 	movw	%ax, %ss
-	mov	$(wakeup_stack - wakeup_data), %sp		# Private stack is needed for ASUS board
-	movw	$0x0e00 + 'S', %fs:(0x12)	
+	mov	wakeup_stack - wakeup_code, %sp			# Private stack is needed for ASUS board
+	movw	$0x0e00 + 'S', %fs:(0x12)
 
-	movl	real_magic - wakeup_data, %eax
+	pushl	$0						# Kill any dangerous flags
+	popfl
+
+	movl	real_magic - wakeup_code, %eax
 	cmpl	$0x12345678, %eax
 	jne	bogus_real_magic
 
-	mov	video_mode - wakeup_data, %ax
+#if 1
+	lcall   $0xc000,$3
+#endif
+#if 0
+	mov	video_mode - wakeup_code, %ax
 	call	mode_set
+#endif
 
 	# set up page table
-	movl	(real_save_cr3 - wakeup_data), %eax
+#if 1
+	movl	$swapper_pg_dir-__PAGE_OFFSET, %eax
+#else
+	movl    (real_save_cr3 - wakeup_data), %eax
+#endif
 	movl	%eax, %cr3
 
 	# make sure %cr4 is set correctly (features, etc)
-	movl	(real_save_cr4 - wakeup_data), %eax
+	movl	real_save_cr4 - wakeup_code, %eax
 	movl	%eax, %cr4
 	movw	$0xb800, %ax
 	movw	%ax,%fs
 	movw	$0x0e00 + 'i', %fs:(0x12)
-
+	
 	# need a gdt
-	lgdt	real_save_gdt - wakeup_data
+	lgdt	real_save_gdt - wakeup_code
 
-	movl	(real_save_cr0 - wakeup_data), %eax
+	movl	real_save_cr0 - wakeup_code, %eax
 	movl	%eax, %cr0
+	jmp 1f
+1:
 	movw	$0x0e00 + 'n', %fs:(0x14)
 
-	movl	real_magic - wakeup_data, %eax
+	movl	real_magic - wakeup_code, %eax
 	cmpl	$0x12345678, %eax
 	jne	bogus_real_magic
 
 	ljmpl	$__KERNEL_CS,$wakeup_pmode_return
 
+real_save_gdt:	.word 0
+		.long 0
+real_save_cr0:	.long 0
+real_save_cr3:	.long 0
+real_save_cr4:	.long 0
+real_magic:	.long 0
+video_mode:	.long 0
+
 bogus_real_magic:
 	movw	$0x0e00 + 'B', %fs:(0x12)
 	jmp bogus_real_magic
@@ -129,20 +159,12 @@
 	.code32
 	ALIGN
 
-.org	0x300
-wakeup_data:
-		.word 0
-real_save_gdt:	.word 0
-		.long 0
-real_save_cr0:	.long 0
-real_save_cr3:	.long 0
-real_save_cr4:	.long 0
-real_magic:	.long 0
-video_mode:	.long 0
 
-.org	0x500
+.org	0x2000
 wakeup_stack:
-wakeup_end:
+.org	0x3000
+ENTRY(wakeup_end)
+.org	0x4000
 
 wakeup_pmode_return:
 	movl	$__KERNEL_DS, %eax
@@ -205,7 +227,6 @@
 	movw	$0x0e00 + '2', %ds:(0xb8018)
 	jmp bogus_magic2
 		
-
 ##
 # acpi_copy_wakeup_routine
 #
@@ -228,7 +249,7 @@
 
 	movl	%eax, %edi
 	leal	wakeup_start, %esi
-	movl	$(wakeup_end - wakeup_start) >> 2, %ecx
+	movl	$(wakeup_end - wakeup_start + 3) >> 2, %ecx
 
 	rep ;  movsl
 
@@ -290,8 +311,8 @@
 	ret
 	.p2align 4,,7
 .L1432:
-	movl $104,%eax
-	movw %eax, %ds
+	movl $__KERNEL_DS,%eax
+	movw %ax, %ds
 	movl saved_context_esp, %esp
 	movl saved_context_ebp, %ebp
 	movl saved_context_eax, %eax
@@ -310,5 +331,4 @@
 saved_idt:	.long	0,0
 saved_ldt:	.long	0
 saved_tss:	.long	0
-saved_cr0:	.long	0
 
diff -Nru a/arch/i386/kernel/cpu/cyrix.c b/arch/i386/kernel/cpu/cyrix.c
--- a/arch/i386/kernel/cpu/cyrix.c	Mon Dec  9 18:46:35 2002
+++ b/arch/i386/kernel/cpu/cyrix.c	Mon Dec  9 18:46:35 2002
@@ -170,7 +170,6 @@
 {
 	unsigned long flags;
 	u8 ccr3, ccr4;
-	unsigned long cr0;
 	local_irq_save(flags);
 	
 	ccr3 = getCx86(CX86_CCR3);
diff -Nru a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c
--- a/arch/i386/kernel/cpu/intel.c	Mon Dec  9 18:46:35 2002
+++ b/arch/i386/kernel/cpu/intel.c	Mon Dec  9 18:46:35 2002
@@ -3,8 +3,9 @@
 #include <linux/string.h>
 #include <linux/bitops.h>
 #include <linux/smp.h>
+#include <linux/thread_info.h>
+
 #include <asm/processor.h>
-#include <asm/thread_info.h>
 #include <asm/msr.h>
 #include <asm/uaccess.h>
 
diff -Nru a/arch/i386/kernel/cpu/mcheck/mce.c b/arch/i386/kernel/cpu/mcheck/mce.c
--- a/arch/i386/kernel/cpu/mcheck/mce.c	Mon Dec  9 18:46:50 2002
+++ b/arch/i386/kernel/cpu/mcheck/mce.c	Mon Dec  9 18:46:50 2002
@@ -7,9 +7,10 @@
 #include <linux/kernel.h>
 #include <linux/config.h>
 #include <linux/smp.h>
+#include <linux/thread_info.h>
+
 #include <asm/processor.h> 
 #include <asm/system.h>
-#include <asm/thread_info.h>
 
 #include "mce.h"
 
diff -Nru a/arch/i386/kernel/edd.c b/arch/i386/kernel/edd.c
--- a/arch/i386/kernel/edd.c	Mon Dec  9 18:46:35 2002
+++ b/arch/i386/kernel/edd.c	Mon Dec  9 18:46:35 2002
@@ -575,17 +575,25 @@
 static EDD_DEVICE_ATTR(host_bus, 0444, edd_show_host_bus, edd_has_edd30);
 
 
+/* These are default attributes that are added for every edd
+ * device discovered.
+ */
 static struct attribute * def_attrs[] = {
 	&edd_attr_raw_data.attr,
 	&edd_attr_version.attr,
 	&edd_attr_extensions.attr,
 	&edd_attr_info_flags.attr,
 	&edd_attr_sectors.attr,
-	&edd_attr_default_cylinders.attr,
-	&edd_attr_default_heads.attr,
-	&edd_attr_default_sectors_per_track.attr,
-	&edd_attr_interface.attr,
-	&edd_attr_host_bus.attr,
+	NULL,
+};
+
+/* These attributes are conditional and only added for some devices. */
+static struct edd_attribute * edd_attrs[] = {
+	&edd_attr_default_cylinders,
+	&edd_attr_default_heads,
+	&edd_attr_default_sectors_per_track,
+	&edd_attr_interface,
+	&edd_attr_host_bus,
 	NULL,
 };
 
@@ -686,18 +694,14 @@
  * The reference counting probably isn't the best it could be.
  */
 
-#define	to_scsi_host(d)	\
-	container_of(d, struct Scsi_Host, host_driverfs_dev)
 #define children_to_dev(n) container_of(n,struct device,node)
 static struct scsi_device *
 edd_find_matching_scsi_device(struct edd_device *edev)
 {
-	struct list_head *shost_node, *sdev_node;
+	struct list_head *sdev_node;
 	int rc = 1;
 	struct scsi_device *sd = NULL;
-	struct device *shost_dev, *sdev_dev;
 	struct pci_dev *pci_dev;
-	struct Scsi_Host *sh;
 
 	rc = edd_dev_is_type(edev, "SCSI");
 	if (rc)
@@ -709,29 +713,18 @@
 
 	get_device(&pci_dev->dev);
 
-	list_for_each(shost_node, &pci_dev->dev.children) {
-		shost_dev = children_to_dev(shost_node);
-		get_device(shost_dev);
-		sh = to_scsi_host(shost_dev);
-
-		list_for_each(sdev_node, &shost_dev->children) {
-			sdev_dev = children_to_dev(sdev_node);
-			get_device(sdev_dev);
-			sd = to_scsi_device(sdev_dev);
-			rc = edd_match_scsidev(edev, sd);
-			put_device(sdev_dev);
-			if (!rc)
-				break;
-		}
-		put_device(shost_dev);
+	list_for_each(sdev_node, &pci_dev->dev.children) {
+		struct device *sdev_dev = children_to_dev(sdev_node);
+		get_device(sdev_dev);
+		sd = to_scsi_device(sdev_dev);
+		rc = edd_match_scsidev(edev, sd);
+		put_device(sdev_dev);
 		if (!rc)
 			break;
 	}
 
 	put_device(&pci_dev->dev);
-	if (!rc)
-		return sd;
-	return NULL;
+	return rc ? NULL : sd;
 }
 
 static int
@@ -771,6 +764,24 @@
 	kobject_unregister(&edev->kobj);
 }
 
+static void populate_dir(struct edd_device * edev)
+{
+	struct edd_attribute * attr;
+	int error = 0;
+	int i;
+
+	for (i = 0; (attr = edd_attrs[i]) && !error; i++) {
+		if (!attr->test || 
+		    (attr->test && !attr->test(edev)))
+			error = sysfs_create_file(&edev->kobj,&attr->attr);
+	}
+	
+	if (!error) {
+		edd_create_symlink_to_pcidev(edev);
+		edd_create_symlink_to_scsidev(edev);
+	}
+}
+
 static int
 edd_device_register(struct edd_device *edev, int i)
 {
@@ -780,15 +791,12 @@
 		return 1;
 	memset(edev, 0, sizeof (*edev));
 	edd_dev_set_info(edev, &edd[i]);
-	kobject_init(&edev->kobj);
 	snprintf(edev->kobj.name, EDD_DEVICE_NAME_SIZE, "int13_dev%02x",
 		 edd[i].device);
 	edev->kobj.subsys = &edd_subsys;
 	error = kobject_register(&edev->kobj);
-	if (!error) {
-		edd_create_symlink_to_pcidev(edev);
-		edd_create_symlink_to_scsidev(edev);
-	}
+	if (!error)
+		populate_dir(edev);
 	return error;
 }
 
diff -Nru a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
--- a/arch/i386/kernel/entry.S	Mon Dec  9 18:46:35 2002
+++ b/arch/i386/kernel/entry.S	Mon Dec  9 18:46:35 2002
@@ -484,7 +484,7 @@
 
 .data
 ENTRY(sys_call_table)
-	.long sys_ni_syscall	/* 0 - old "setup()" system call*/
+	.long sys_restart_syscall	/* 0 - old "setup()" system call, used for restarting */
 	.long sys_exit
 	.long sys_fork
 	.long sys_read
diff -Nru a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
--- a/arch/i386/kernel/head.S	Mon Dec  9 18:46:34 2002
+++ b/arch/i386/kernel/head.S	Mon Dec  9 18:46:34 2002
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/i386/head.S -- the 32-bit startup code.
+ *  linux/arch/i386/kernel/head.S -- the 32-bit startup code.
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
  *
diff -Nru a/arch/i386/kernel/i387.c b/arch/i386/kernel/i387.c
--- a/arch/i386/kernel/i387.c	Mon Dec  9 18:46:52 2002
+++ b/arch/i386/kernel/i387.c	Mon Dec  9 18:46:52 2002
@@ -232,7 +232,7 @@
  * FXSR floating point environment conversions.
  */
 
-static inline int convert_fxsr_to_user( struct _fpstate *buf,
+static int convert_fxsr_to_user( struct _fpstate *buf,
 					struct i387_fxsave_struct *fxsave )
 {
 	unsigned long env[7];
@@ -254,13 +254,18 @@
 	to = &buf->_st[0];
 	from = (struct _fpxreg *) &fxsave->st_space[0];
 	for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
-		if ( __copy_to_user( to, from, sizeof(*to) ) )
+		unsigned long *t = (unsigned long *)to;
+		unsigned long *f = (unsigned long *)from;
+
+		if (__put_user(*f, t) ||
+				__put_user(*(f + 1), t + 1) ||
+				__put_user(from->exponent, &to->exponent))
 			return 1;
 	}
 	return 0;
 }
 
-static inline int convert_fxsr_from_user( struct i387_fxsave_struct *fxsave,
+static int convert_fxsr_from_user( struct i387_fxsave_struct *fxsave,
 					  struct _fpstate *buf )
 {
 	unsigned long env[7];
@@ -283,7 +288,12 @@
 	to = (struct _fpxreg *) &fxsave->st_space[0];
 	from = &buf->_st[0];
 	for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
-		if ( __copy_from_user( to, from, sizeof(*from) ) )
+		unsigned long *t = (unsigned long *)to;
+		unsigned long *f = (unsigned long *)from;
+
+		if (__get_user(*f, t) ||
+				__get_user(*(f + 1), t + 1) ||
+				__get_user(from->exponent, &to->exponent))
 			return 1;
 	}
 	return 0;
@@ -305,7 +315,7 @@
 	return 1;
 }
 
-static inline int save_i387_fxsave( struct _fpstate *buf )
+static int save_i387_fxsave( struct _fpstate *buf )
 {
 	struct task_struct *tsk = current;
 	int err = 0;
@@ -355,7 +365,7 @@
 				 sizeof(struct i387_fsave_struct) );
 }
 
-static inline int restore_i387_fxsave( struct _fpstate *buf )
+static int restore_i387_fxsave( struct _fpstate *buf )
 {
 	int err;
 	struct task_struct *tsk = current;
@@ -373,7 +383,7 @@
 
 	if ( HAVE_HWFP ) {
 		if ( cpu_has_fxsr ) {
-			err =  restore_i387_fxsave( buf );
+			err = restore_i387_fxsave( buf );
 		} else {
 			err = restore_i387_fsave( buf );
 		}
diff -Nru a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c
--- a/arch/i386/kernel/i8259.c	Mon Dec  9 18:46:51 2002
+++ b/arch/i386/kernel/i8259.c	Mon Dec  9 18:46:51 2002
@@ -367,6 +367,45 @@
 	}
 }
 
+static void setup_timer(void)
+{
+	outb_p(0x34,0x43);		/* binary, mode 2, LSB/MSB, ch 0 */
+	udelay(10);
+	outb_p(LATCH & 0xff , 0x40);	/* LSB */
+	udelay(10);
+	outb(LATCH >> 8 , 0x40);	/* MSB */
+}
+
+static int timer_resume(struct device *dev, u32 level)
+{
+	if (level == RESUME_POWER_ON)
+		setup_timer();
+	return 0;
+}
+
+static struct device_driver timer_driver = {
+	.name		= "timer",
+	.bus		= &system_bus_type,
+	.resume		= timer_resume,
+};
+
+static struct sys_device device_timer = {
+	.name		= "timer",
+	.id		= 0,
+	.dev		= {
+		.name	= "timer",
+		.driver	= &timer_driver,
+	},
+};
+
+static int __init init_timer_devicefs(void)
+{
+	driver_register(&timer_driver);
+	return sys_device_register(&device_timer);
+}
+
+device_initcall(init_timer_devicefs);
+
 void __init init_IRQ(void)
 {
 	int i;
@@ -386,16 +425,15 @@
 	}
 
 	/* setup after call gates are initialised (usually add in
-	 * the architecture specific gates */
+	 * the architecture specific gates)
+	 */
 	intr_init_hook();
 
 	/*
 	 * Set the clock to HZ Hz, we already have a valid
 	 * vector now:
 	 */
-	outb_p(0x34,0x43);		/* binary, mode 2, LSB/MSB, ch 0 */
-	outb_p(LATCH & 0xff , 0x40);	/* LSB */
-	outb(LATCH >> 8 , 0x40);	/* MSB */
+	setup_timer();
 
 	/*
 	 * External FPU? Set up irq13 if so, for
diff -Nru a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
--- a/arch/i386/kernel/io_apic.c	Mon Dec  9 18:46:35 2002
+++ b/arch/i386/kernel/io_apic.c	Mon Dec  9 18:46:35 2002
@@ -1749,10 +1749,11 @@
  *	APIC bugs then we can allow the modify fast path
  */
  
-static void __init io_apic_bug_finalize(void)
+static int __init io_apic_bug_finalize(void)
 {
 	if(sis_apic_bug == -1)
 		sis_apic_bug = 0;
+	return 0;
 }
 
 late_initcall(io_apic_bug_finalize);
diff -Nru a/arch/i386/kernel/mca.c b/arch/i386/kernel/mca.c
--- a/arch/i386/kernel/mca.c	Mon Dec  9 18:46:50 2002
+++ b/arch/i386/kernel/mca.c	Mon Dec  9 18:46:50 2002
@@ -54,54 +54,7 @@
 #include <linux/init.h>
 #include <asm/arch_hooks.h>
 
-/* This structure holds MCA information. Each (plug-in) adapter has
- * eight POS registers. Then the machine may have integrated video and
- * SCSI subsystems, which also have eight POS registers.
- * Finally, the motherboard (planar) has got POS-registers.
- * Other miscellaneous information follows.
- */
-
-typedef enum {
-	MCA_ADAPTER_NORMAL = 0,
-	MCA_ADAPTER_NONE = 1,
-	MCA_ADAPTER_DISABLED = 2,
-	MCA_ADAPTER_ERROR = 3
-} MCA_AdapterStatus;
-
-struct MCA_adapter {
-	MCA_AdapterStatus status;	/* is there a valid adapter? */
-	int id;				/* adapter id value */
-	unsigned char pos[8];		/* POS registers */
-	int driver_loaded;		/* is there a driver installed? */
-					/* 0 - No, 1 - Yes */
-	char name[48];			/* adapter-name provided by driver */
-	char procname[8];		/* name of /proc/mca file */
-	MCA_ProcFn procfn;		/* /proc info callback */
-	void* dev;			/* device/context info for callback */
-};
-
-struct MCA_info {
-	/* one for each of the 8 possible slots, plus one for integrated SCSI
-	 * and one for integrated video.
-	 */
-
-	struct MCA_adapter slot[MCA_NUMADAPTERS];
-
-	/* two potential addresses for integrated SCSI adapter - this will
-	 * track which one we think it is.
-	 */
-
-	unsigned char which_scsi;
-};
-
-/* The mca_info structure pointer. If MCA bus is present, the function
- * mca_probe() is invoked. The function puts motherboard, then all
- * adapters into setup mode, allocates and fills an MCA_info structure,
- * and points this pointer to the structure. Otherwise the pointer
- * is set to zero.
- */
-
-static struct MCA_info* mca_info = NULL;
+static unsigned char which_scsi = 0;
 
 /*
  * Motherboard register spinlock. Untested on SMP at the moment, but
@@ -109,33 +62,17 @@
  *
  * Yes - Alan
  */
-static spinlock_t mca_lock = SPIN_LOCK_UNLOCKED;
-
-/* MCA registers */
-
-#define MCA_MOTHERBOARD_SETUP_REG	0x94
-#define MCA_ADAPTER_SETUP_REG		0x96
-#define MCA_POS_REG(n)			(0x100+(n))
-
-#define MCA_ENABLED	0x01	/* POS 2, set if adapter enabled */
-
-/*--------------------------------------------------------------------*/
-
-#ifdef CONFIG_PROC_FS
-static void mca_do_proc_init(void);
-#endif
-
-/*--------------------------------------------------------------------*/
+spinlock_t mca_lock = SPIN_LOCK_UNLOCKED;
 
 /* Build the status info for the adapter */
 
-static void mca_configure_adapter_status(int slot) {
-	mca_info->slot[slot].status = MCA_ADAPTER_NONE;
+static void mca_configure_adapter_status(struct mca_device *mca_dev) {
+	mca_dev->status = MCA_ADAPTER_NONE;
 
-	mca_info->slot[slot].id = mca_info->slot[slot].pos[0]
-		+ (mca_info->slot[slot].pos[1] << 8);
+	mca_dev->pos_id = mca_dev->pos[0]
+		+ (mca_dev->pos[1] << 8);
 
-	if(!mca_info->slot[slot].id && slot < MCA_MAX_SLOT_NR) {
+	if(!mca_dev->pos_id && mca_dev->slot < MCA_MAX_SLOT_NR) {
 
 		/* id = 0x0000 usually indicates hardware failure,
 		 * however, ZP Gu (zpg@castle.net> reports that his 9556
@@ -145,10 +82,10 @@
 		 * however, this code will stay.
 		 */
 
-		mca_info->slot[slot].status = MCA_ADAPTER_ERROR;
+		mca_dev->status = MCA_ADAPTER_ERROR;
 
 		return;
-	} else if(mca_info->slot[slot].id != 0xffff) {
+	} else if(mca_dev->pos_id != 0xffff) {
 
 		/* 0xffff usually indicates that there's no adapter,
 		 * however, some integrated adapters may have 0xffff as
@@ -157,26 +94,26 @@
 		 * and possibly also the 95 ULTIMEDIA.
 		 */
 
-		mca_info->slot[slot].status = MCA_ADAPTER_NORMAL;
+		mca_dev->status = MCA_ADAPTER_NORMAL;
 	}
 
-	if((mca_info->slot[slot].id == 0xffff ||
-	   mca_info->slot[slot].id == 0x0000) && slot >= MCA_MAX_SLOT_NR) {
+	if((mca_dev->pos_id == 0xffff ||
+	    mca_dev->pos_id == 0x0000) && mca_dev->slot >= MCA_MAX_SLOT_NR) {
 		int j;
 
 		for(j = 2; j < 8; j++) {
-			if(mca_info->slot[slot].pos[j] != 0xff) {
-				mca_info->slot[slot].status = MCA_ADAPTER_NORMAL;
+			if(mca_dev->pos[j] != 0xff) {
+				mca_dev->status = MCA_ADAPTER_NORMAL;
 				break;
 			}
 		}
 	}
 
-	if(!(mca_info->slot[slot].pos[2] & MCA_ENABLED)) {
+	if(!(mca_dev->pos[2] & MCA_ENABLED)) {
 
 		/* enabled bit is in POS 2 */
 
-		mca_info->slot[slot].status = MCA_ADAPTER_DISABLED;
+		mca_dev->status = MCA_ADAPTER_DISABLED;
 	}
 } /* mca_configure_adapter_status */
 
@@ -194,366 +131,51 @@
 
 #define MCA_STANDARD_RESOURCES	(sizeof(mca_standard_resources)/sizeof(struct resource))
 
-int __init mca_init(void)
-{
-	unsigned int i, j;
-
-	/* WARNING: Be careful when making changes here. Putting an adapter
-	 * and the motherboard simultaneously into setup mode may result in
-	 * damage to chips (according to The Indispensible PC Hardware Book
-	 * by Hans-Peter Messmer). Also, we disable system interrupts (so
-	 * that we are not disturbed in the middle of this).
-	 */
-
-	/* Make sure the MCA bus is present */
-
-	if(!MCA_bus)
-		return -ENODEV;
-	printk(KERN_INFO "Micro Channel bus detected.\n");
-
-	/* Allocate MCA_info structure (at address divisible by 8) */
-
-	mca_info = (struct MCA_info *)kmalloc(sizeof(struct MCA_info), GFP_KERNEL);
-
-	if(mca_info == NULL) {
-		printk(KERN_ERR "Failed to allocate memory for mca_info!");
-		return -ENOMEM;
-	}
-	memset(mca_info, 0, sizeof(struct MCA_info));
-
-	/*
-	 * 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 */
-
-	outb_p(0, MCA_ADAPTER_SETUP_REG);
-
-	/* Read motherboard POS registers */
-
-	outb_p(0x7f, MCA_MOTHERBOARD_SETUP_REG);
-	mca_info->slot[MCA_MOTHERBOARD].name[0] = 0;
-	for(j=0; j<8; j++) {
-		mca_info->slot[MCA_MOTHERBOARD].pos[j] = inb_p(MCA_POS_REG(j));
-	}
-	mca_configure_adapter_status(MCA_MOTHERBOARD);
-
-	/* Put motherboard into video setup mode, read integrated video
-	 * POS registers, and turn motherboard setup off.
-	 */
-
-	outb_p(0xdf, MCA_MOTHERBOARD_SETUP_REG);
-	mca_info->slot[MCA_INTEGVIDEO].name[0] = 0;
-	for(j=0; j<8; j++) {
-		mca_info->slot[MCA_INTEGVIDEO].pos[j] = inb_p(MCA_POS_REG(j));
-	}
-	mca_configure_adapter_status(MCA_INTEGVIDEO);
-
-	/* Put motherboard into scsi setup mode, read integrated scsi
-	 * POS registers, and turn motherboard setup off.
-	 *
-	 * It seems there are two possible SCSI registers. Martin says that
-	 * for the 56,57, 0xf7 is the one, but fails on the 76.
-	 * Alfredo (apena@vnet.ibm.com) says
-	 * 0xfd works on his machine. We'll try both of them. I figure it's
-	 * a good bet that only one could be valid at a time. This could
-	 * screw up though if one is used for something else on the other
-	 * machine.
-	 */
-
-	outb_p(0xf7, MCA_MOTHERBOARD_SETUP_REG);
-	mca_info->slot[MCA_INTEGSCSI].name[0] = 0;
-	for(j=0; j<8; j++) {
-		if((mca_info->slot[MCA_INTEGSCSI].pos[j] = inb_p(MCA_POS_REG(j))) != 0xff)
-		{
-			/* 0xff all across means no device. 0x00 means
-			 * something's broken, but a device is probably there.
-			 * However, if you get 0x00 from a motherboard
-			 * register it won't matter what we find.  For the
-			 * record, on the 57SLC, the integrated SCSI
-			 * adapter has 0xffff for the adapter ID, but
-			 * nonzero for other registers.
-			 */
-
-			mca_info->which_scsi = 0xf7;
-		}
-	}
-	if(!mca_info->which_scsi) {
-
-		/* Didn't find it at 0xf7, try somewhere else... */
-		mca_info->which_scsi = 0xfd;
-
-		outb_p(0xfd, MCA_MOTHERBOARD_SETUP_REG);
-		for(j=0; j<8; j++)
-			mca_info->slot[MCA_INTEGSCSI].pos[j] = inb_p(MCA_POS_REG(j));
-	}
-	mca_configure_adapter_status(MCA_INTEGSCSI);
-
-	/* Turn off motherboard setup */
-
-	outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);
-
-	/* Now loop over MCA slots: put each adapter into setup mode, and
-	 * read its POS registers. Then put adapter setup off.
-	 */
-
-	for(i=0; i<MCA_MAX_SLOT_NR; i++) {
-		outb_p(0x8|(i&0xf), MCA_ADAPTER_SETUP_REG);
-		for(j=0; j<8; j++) {
-			mca_info->slot[i].pos[j]=inb_p(MCA_POS_REG(j));
-		}
-		mca_info->slot[i].name[0] = 0;
-		mca_info->slot[i].driver_loaded = 0;
-		mca_configure_adapter_status(i);
-	}
-	outb_p(0, MCA_ADAPTER_SETUP_REG);
-
-	/* Enable interrupts and return memory start */
-	spin_unlock_irq(&mca_lock);
-
-	for (i = 0; i < MCA_STANDARD_RESOURCES; i++)
-		request_resource(&ioport_resource, mca_standard_resources + i);
-
-#ifdef CONFIG_PROC_FS
-	mca_do_proc_init();
-#endif
-
-	return 0;
-}
-
-subsys_initcall(mca_init);
-
-/*--------------------------------------------------------------------*/
-
-static void mca_handle_nmi_slot(int slot, int check_flag)
-{
-	if(slot < MCA_MAX_SLOT_NR) {
-		printk(KERN_CRIT "NMI: caused by MCA adapter in slot %d (%s)\n", slot+1,
-			mca_info->slot[slot].name);
-	} else if(slot == MCA_INTEGSCSI) {
-		printk(KERN_CRIT "NMI: caused by MCA integrated SCSI adapter (%s)\n",
-			mca_info->slot[slot].name);
-	} else if(slot == MCA_INTEGVIDEO) {
-		printk(KERN_CRIT "NMI: caused by MCA integrated video adapter (%s)\n",
-			mca_info->slot[slot].name);
-	} else if(slot == MCA_MOTHERBOARD) {
-		printk(KERN_CRIT "NMI: caused by motherboard (%s)\n",
-			mca_info->slot[slot].name);
-	}
-
-	/* More info available in POS 6 and 7? */
-
-	if(check_flag) {
-		unsigned char pos6, pos7;
-
-		pos6 = mca_read_pos(slot, 6);
-		pos7 = mca_read_pos(slot, 7);
-
-		printk(KERN_CRIT "NMI: POS 6 = 0x%x, POS 7 = 0x%x\n", pos6, pos7);
-	}
-
-} /* mca_handle_nmi_slot */
-
-/*--------------------------------------------------------------------*/
-
-void mca_handle_nmi(void)
-{
-
-	int i;
-	unsigned char pos5;
-
-	/* First try - scan the various adapters and see if a specific
-	 * adapter was responsible for the error.
-	 */
-
-	for(i = 0; i < MCA_NUMADAPTERS; i++) 
-	{
-		/* Bit 7 of POS 5 is reset when this adapter has a hardware
-		 * error. Bit 7 it reset if there's error information
-		 * available in POS 6 and 7.
-		 */
-		pos5 = mca_read_pos(i, 5);
-
-		if(!(pos5 & 0x80)) {
-			mca_handle_nmi_slot(i, !(pos5 & 0x40));
-			return;
-		}
-	}
-	mca_nmi_hook();
-} /* mca_handle_nmi */
-
-/*--------------------------------------------------------------------*/
-
-/**
- *	mca_find_adapter - scan for adapters
- *	@id:	MCA identification to search for
- *	@start:	starting slot
- *
- *	Search the MCA configuration for adapters matching the 16bit
- *	ID given. The first time it should be called with start as zero
- *	and then further calls made passing the return value of the
- *	previous call until %MCA_NOTFOUND is returned.
- *
- *	Disabled adapters are not reported.
- */
-
-int mca_find_adapter(int id, int start)
-{
-	if(mca_info == NULL || id == 0xffff) {
-		return MCA_NOTFOUND;
-	}
-
-	for(; start >= 0 && start < MCA_NUMADAPTERS; start++) {
-
-		/* Not sure about this. There's no point in returning
-		 * adapters that aren't enabled, since they can't actually
-		 * be used. However, they might be needed for statistical
-		 * purposes or something... But if that is the case, the
-		 * user is free to write a routine that manually iterates
-		 * through the adapters.
-		 */
-
-		if(mca_info->slot[start].status == MCA_ADAPTER_DISABLED) {
-			continue;
-		}
-
-		if(id == mca_info->slot[start].id) {
-			return start;
-		}
-	}
-
-	return MCA_NOTFOUND;
-} /* mca_find_adapter() */
-
-EXPORT_SYMBOL(mca_find_adapter);
-
-/*--------------------------------------------------------------------*/
-
 /**
- *	mca_find_unused_adapter - scan for unused adapters
- *	@id:	MCA identification to search for
- *	@start:	starting slot
+ *	mca_read_pos - read the POS registers into a memory buffer
  *
- *	Search the MCA configuration for adapters matching the 16bit
- *	ID given. The first time it should be called with start as zero
- *	and then further calls made passing the return value of the
- *	previous call until %MCA_NOTFOUND is returned.
- *
- *	Adapters that have been claimed by drivers and those that
- *	are disabled are not reported. This function thus allows a driver
- *	to scan for further cards when some may already be driven.
+ *	Returns 1 if a card actually exists (i.e. the pos isn't
+ *	all 0xff) or 0 otherwise
  */
+static int mca_read_and_store_pos(unsigned char *pos) {
+	int j;
+	int found = 0;
 
-int mca_find_unused_adapter(int id, int start)
-{
-	if(mca_info == NULL || id == 0xffff) {
-		return MCA_NOTFOUND;
-	}
-
-	for(; start >= 0 && start < MCA_NUMADAPTERS; start++) {
-
-		/* not sure about this. There's no point in returning
-		 * adapters that aren't enabled, since they can't actually
-		 * be used. However, they might be needed for statistical
-		 * purposes or something... But if that is the case, the
-		 * user is free to write a routine that manually iterates
-		 * through the adapters.
-		 */
-
-		if(mca_info->slot[start].status == MCA_ADAPTER_DISABLED ||
-		   mca_info->slot[start].driver_loaded) {
-			continue;
-		}
+	for(j=0; j<8; j++) {
+		if((pos[j] = inb_p(MCA_POS_REG(j))) != 0xff) {
+			/* 0xff all across means no device. 0x00 means
+			 * something's broken, but a device is
+			 * probably there.  However, if you get 0x00
+			 * from a motherboard register it won't matter
+			 * what we find.  For the record, on the
+			 * 57SLC, the integrated SCSI adapter has
+			 * 0xffff for the adapter ID, but nonzero for
+			 * other registers.  */
 
-		if(id == mca_info->slot[start].id) {
-			return start;
+			found = 1;
 		}
 	}
+	return found;
+}
 
-	return MCA_NOTFOUND;
-} /* mca_find_unused_adapter() */
-
-EXPORT_SYMBOL(mca_find_unused_adapter);
-
-/*--------------------------------------------------------------------*/
-
-/**
- *	mca_read_stored_pos - read POS register from boot data
- *	@slot: slot number to read from
- *	@reg:  register to read from
- *
- *	Fetch a POS value that was stored at boot time by the kernel
- *	when it scanned the MCA space. The register value is returned.
- *	Missing or invalid registers report 0.
- */
-
-unsigned char mca_read_stored_pos(int slot, int reg)
-{
-	if(slot < 0 || slot >= MCA_NUMADAPTERS || mca_info == NULL) return 0;
-	if(reg < 0 || reg >= 8) return 0;
-	return mca_info->slot[slot].pos[reg];
-} /* mca_read_stored_pos() */
-
-EXPORT_SYMBOL(mca_read_stored_pos);
-
-/*--------------------------------------------------------------------*/
-
-/**
- *	mca_read_pos - read POS register from card
- *	@slot: slot number to read from
- *	@reg:  register to read from
- *
- *	Fetch a POS value directly from the hardware to obtain the
- *	current value. This is much slower than mca_read_stored_pos and
- *	may not be invoked from interrupt context. It handles the
- *	deep magic required for onboard devices transparently.
- */
-
-unsigned char mca_read_pos(int slot, int reg)
+static unsigned char mca_pc_read_pos(struct mca_device *mca_dev, int reg)
 {
-	unsigned int byte = 0;
+	unsigned char byte;
 	unsigned long flags;
 
-	if(slot < 0 || slot >= MCA_NUMADAPTERS || mca_info == NULL) return 0;
-	if(reg < 0 || reg >= 8) return 0;
+	if(reg < 0 || reg >= 8)
+		return 0;
 
 	spin_lock_irqsave(&mca_lock, flags);
-
-	/* Make sure motherboard setup is off */
-
-	outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);
-
-	/* Read in the appropriate register */
-
-	if(slot == MCA_INTEGSCSI && mca_info->which_scsi) {
-
-		/* Disable adapter setup, enable motherboard setup */
-
-		outb_p(0, MCA_ADAPTER_SETUP_REG);
-		outb_p(mca_info->which_scsi, MCA_MOTHERBOARD_SETUP_REG);
-
-		byte = inb_p(MCA_POS_REG(reg));
-		outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);
-	} else if(slot == MCA_INTEGVIDEO) {
-
+	if(mca_dev->pos_register) {
 		/* Disable adapter setup, enable motherboard setup */
 
 		outb_p(0, MCA_ADAPTER_SETUP_REG);
-		outb_p(0xdf, MCA_MOTHERBOARD_SETUP_REG);
+		outb_p(mca_dev->pos_register, MCA_MOTHERBOARD_SETUP_REG);
 
 		byte = inb_p(MCA_POS_REG(reg));
 		outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);
-	} else if(slot == MCA_MOTHERBOARD) {
-
-		/* Disable adapter setup, enable motherboard setup */
-		outb_p(0, MCA_ADAPTER_SETUP_REG);
-		outb_p(0x7f, MCA_MOTHERBOARD_SETUP_REG);
-
-		byte = inb_p(MCA_POS_REG(reg));
-		outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);
-	} else if(slot < MCA_MAX_SLOT_NR) {
+	} else {
 
 		/* Make sure motherboard setup is off */
 
@@ -561,58 +183,24 @@
 
 		/* Read the appropriate register */
 
-		outb_p(0x8|(slot&0xf), MCA_ADAPTER_SETUP_REG);
+		outb_p(0x8|(mca_dev->slot & 0xf), MCA_ADAPTER_SETUP_REG);
 		byte = inb_p(MCA_POS_REG(reg));
 		outb_p(0, MCA_ADAPTER_SETUP_REG);
 	}
-
-	/* Make sure the stored values are consistent, while we're here */
-
-	mca_info->slot[slot].pos[reg] = byte;
-
 	spin_unlock_irqrestore(&mca_lock, flags);
 
-	return byte;
-} /* mca_read_pos() */
-
-EXPORT_SYMBOL(mca_read_pos);
-
-/*--------------------------------------------------------------------*/
+	mca_dev->pos[reg] = byte;
 
-/**
- *	mca_write_pos - read POS register from card
- *	@slot: slot number to read from
- *	@reg:  register to read from
- *	@byte: byte to write to the POS registers
- *
- *	Store a POS value directly from the hardware. You should not
- *	normally need to use this function and should have a very good
- *	knowledge of MCA bus before you do so. Doing this wrongly can
- *	damage the hardware.
- *
- *	This function may not be used from interrupt context.
- *
- *	Note that this a technically a Bad Thing, as IBM tech stuff says
- *	you should only set POS values through their utilities.
- *	However, some devices such as the 3c523 recommend that you write
- *	back some data to make sure the configuration is consistent.
- *	I'd say that IBM is right, but I like my drivers to work.
- *
- *	This function can't do checks to see if multiple devices end up
- *	with the same resources, so you might see magic smoke if someone
- *	screws up.
- */
+	return byte;
+}
 
-void mca_write_pos(int slot, int reg, unsigned char byte)
+static void mca_pc_write_pos(struct mca_device *mca_dev, int reg,
+			     unsigned char byte)
 {
 	unsigned long flags;
 
-	if(slot < 0 || slot >= MCA_MAX_SLOT_NR)
-		return;
 	if(reg < 0 || reg >= 8)
 		return;
-	if(mca_info == NULL)
-		return;
 
 	spin_lock_irqsave(&mca_lock, flags);
 
@@ -622,7 +210,7 @@
 
 	/* Read in the appropriate register */
 
-	outb_p(0x8|(slot&0xf), MCA_ADAPTER_SETUP_REG);
+	outb_p(0x8|(mca_dev->slot&0xf), MCA_ADAPTER_SETUP_REG);
 	outb_p(byte, MCA_POS_REG(reg));
 	outb_p(0, MCA_ADAPTER_SETUP_REG);
 
@@ -630,356 +218,250 @@
 
 	/* Update the global register list, while we have the byte */
 
-	mca_info->slot[slot].pos[reg] = byte;
-} /* mca_write_pos() */
-
-EXPORT_SYMBOL(mca_write_pos);
-
-/*--------------------------------------------------------------------*/
-
-/**
- *	mca_set_adapter_name - Set the description of the card
- *	@slot: slot to name
- *	@name: text string for the namen
- *
- *	This function sets the name reported via /proc for this
- *	adapter slot. This is for user information only. Setting a
- *	name deletes any previous name.
- */
-
-void mca_set_adapter_name(int slot, char* name)
-{
-	if(mca_info == NULL) return;
+	mca_dev->pos[reg] = byte;
 
-	if(slot >= 0 && slot < MCA_NUMADAPTERS) {
-		if(name != NULL) {
-			strncpy(mca_info->slot[slot].name, name,
-				sizeof(mca_info->slot[slot].name)-1);
-			mca_info->slot[slot].name[
-				sizeof(mca_info->slot[slot].name)-1] = 0;
-		} else {
-			mca_info->slot[slot].name[0] = 0;
-		}
-	}
 }
 
-EXPORT_SYMBOL(mca_set_adapter_name);
-
-/**
- *	mca_set_adapter_procfn - Set the /proc callback
- *	@slot: slot to configure
- *	@procfn: callback function to call for /proc
- *	@dev: device information passed to the callback
- *
- *	This sets up an information callback for /proc/mca/slot?.  The
- *	function is called with the buffer, slot, and device pointer (or
- *	some equally informative context information, or nothing, if you
- *	prefer), and is expected to put useful information into the
- *	buffer.  The adapter name, ID, and POS registers get printed
- *	before this is called though, so don't do it again.
- *
- *	This should be called with a %NULL @procfn when a module
- *	unregisters, thus preventing kernel crashes and other such
- *	nastiness.
- */
-
-void mca_set_adapter_procfn(int slot, MCA_ProcFn procfn, void* dev)
+/* for the primary MCA bus, we have identity transforms */
+static int mca_dummy_transform_irq(struct mca_device * mca_dev, int irq)
 {
-	if(mca_info == NULL) return;
-
-	if(slot >= 0 && slot < MCA_NUMADAPTERS) {
-		mca_info->slot[slot].procfn = procfn;
-		mca_info->slot[slot].dev = dev;
-	}
+	return irq;
 }
 
-EXPORT_SYMBOL(mca_set_adapter_procfn);
-
-/**
- *	mca_is_adapter_used - check if claimed by driver
- *	@slot:	slot to check
- *
- *	Returns 1 if the slot has been claimed by a driver
- */
-
-int mca_is_adapter_used(int slot)
+static int mca_dummy_transform_ioport(struct mca_device * mca_dev, int port)
 {
-	return mca_info->slot[slot].driver_loaded;
+	return port;
 }
 
-EXPORT_SYMBOL(mca_is_adapter_used);
-
-/**
- *	mca_mark_as_used - claim an MCA device
- *	@slot:	slot to claim
- *	FIXME:  should we make this threadsafe
- *
- *	Claim an MCA slot for a device driver. If the
- *	slot is already taken the function returns 1,
- *	if it is not taken it is claimed and 0 is
- *	returned.
- */
-
-int mca_mark_as_used(int slot)
+static void *mca_dummy_transform_memory(struct mca_device * mca_dev, void *mem)
 {
-	if(mca_info->slot[slot].driver_loaded) return 1;
-	mca_info->slot[slot].driver_loaded = 1;
-	return 0;
+	return mem;
 }
 
-EXPORT_SYMBOL(mca_mark_as_used);
-
-/**
- *	mca_mark_as_unused - release an MCA device
- *	@slot:	slot to claim
- *
- *	Release the slot for other drives to use.
- */
 
-void mca_mark_as_unused(int slot)
+static int __init mca_init(void)
 {
-	mca_info->slot[slot].driver_loaded = 0;
-}
+	unsigned int i, j;
+	struct mca_device *mca_dev;
+	unsigned char pos[8];
+	short mca_builtin_scsi_ports[] = {0xf7, 0xfd, 0x00};
+	struct mca_bus *bus;
 
-EXPORT_SYMBOL(mca_mark_as_unused);
+	/* WARNING: Be careful when making changes here. Putting an adapter
+	 * and the motherboard simultaneously into setup mode may result in
+	 * damage to chips (according to The Indispensible PC Hardware Book
+	 * by Hans-Peter Messmer). Also, we disable system interrupts (so
+	 * that we are not disturbed in the middle of this).
+	 */
 
-/**
- *	mca_get_adapter_name - get the adapter description
- *	@slot:	slot to query
- *
- *	Return the adapter description if set. If it has not been
- *	set or the slot is out range then return NULL.
- */
+	/* Make sure the MCA bus is present */
 
-char *mca_get_adapter_name(int slot)
-{
-	if(mca_info == NULL) return 0;
+	if(!MCA_bus)
+		return -ENODEV;
+
+	printk(KERN_INFO "Micro Channel bus detected.\n");
 
-	if(slot >= 0 && slot < MCA_NUMADAPTERS) {
-		return mca_info->slot[slot].name;
+	if(mca_system_init()) {
+		printk(KERN_ERR "MCA bus system initialisation failed\n");
+		return -ENODEV;
 	}
 
-	return 0;
-}
+	/* All MCA systems have at least a primary bus */
+	bus = mca_attach_bus(MCA_PRIMARY_BUS);
+	bus->default_dma_mask = 0xffffffffLL;
+	bus->f.mca_write_pos = mca_pc_write_pos;
+	bus->f.mca_read_pos = mca_pc_read_pos;
+	bus->f.mca_transform_irq = mca_dummy_transform_irq;
+	bus->f.mca_transform_ioport = mca_dummy_transform_ioport;
+	bus->f.mca_transform_memory = mca_dummy_transform_memory;
+
+	/* get the motherboard device */
+	mca_dev = kmalloc(sizeof(struct mca_device), GFP_KERNEL);
+	if(unlikely(!mca_dev))
+		goto out_nomem;
+	memset(mca_dev, 0, sizeof(struct mca_device));
 
-EXPORT_SYMBOL(mca_get_adapter_name);
+	/*
+	 * We do not expect many MCA interrupts during initialization,
+	 * but let us be safe:
+	 */
+	spin_lock_irq(&mca_lock);
 
-/**
- *	mca_isadapter - check if the slot holds an adapter
- *	@slot:	slot to query
- *
- *	Returns zero if the slot does not hold an adapter, non zero if
- *	it does.
- */
+	/* Make sure adapter setup is off */
 
-int mca_isadapter(int slot)
-{
-	if(mca_info == NULL) return 0;
+	outb_p(0, MCA_ADAPTER_SETUP_REG);
 
-	if(slot >= 0 && slot < MCA_NUMADAPTERS) {
-		return ((mca_info->slot[slot].status == MCA_ADAPTER_NORMAL)
-			|| (mca_info->slot[slot].status == MCA_ADAPTER_DISABLED));
-	}
+	/* Read motherboard POS registers */
 
-	return 0;
-}
+	mca_dev->pos_register = 0x7f;
+	outb_p(mca_dev->pos_register, MCA_MOTHERBOARD_SETUP_REG);
+	mca_dev->dev.name[0] = 0;
+	mca_read_and_store_pos(mca_dev->pos);
+	mca_configure_adapter_status(mca_dev);
+	/* fake POS and slot for a motherboard */
+	mca_dev->pos_id = MCA_MOTHERBOARD_POS;
+	mca_dev->slot = MCA_MOTHERBOARD;
+	mca_register_device(MCA_PRIMARY_BUS, mca_dev);
+
+	mca_dev = kmalloc(sizeof(struct mca_device), GFP_ATOMIC);
+	if(unlikely(!mca_dev))
+		goto out_unlock_nomem;
+	memset(mca_dev, 0, sizeof(struct mca_device));
 
-EXPORT_SYMBOL(mca_isadapter);
 
+	/* Put motherboard into video setup mode, read integrated video
+	 * POS registers, and turn motherboard setup off.
+	 */
 
-/**
- *	mca_isadapter - check if the slot holds an adapter
- *	@slot:	slot to query
- *
- *	Returns a non zero value if the slot holds an enabled adapter
- *	and zero for any other case.
- */
+	mca_dev->pos_register = 0xdf;
+	outb_p(mca_dev->pos_register, MCA_MOTHERBOARD_SETUP_REG);
+	mca_dev->dev.name[0] = 0;
+	mca_read_and_store_pos(mca_dev->pos);
+	mca_configure_adapter_status(mca_dev);
+	/* fake POS and slot for the integrated video */
+	mca_dev->pos_id = MCA_INTEGVIDEO_POS;
+	mca_dev->slot = MCA_INTEGVIDEO;
+	mca_register_device(MCA_PRIMARY_BUS, mca_dev);
 
-int mca_isenabled(int slot)
-{
-	if(mca_info == NULL) return 0;
+	/* Put motherboard into scsi setup mode, read integrated scsi
+	 * POS registers, and turn motherboard setup off.
+	 *
+	 * It seems there are two possible SCSI registers. Martin says that
+	 * for the 56,57, 0xf7 is the one, but fails on the 76.
+	 * Alfredo (apena@vnet.ibm.com) says
+	 * 0xfd works on his machine. We'll try both of them. I figure it's
+	 * a good bet that only one could be valid at a time. This could
+	 * screw up though if one is used for something else on the other
+	 * machine.
+	 */
 
-	if(slot >= 0 && slot < MCA_NUMADAPTERS) {
-		return (mca_info->slot[slot].status == MCA_ADAPTER_NORMAL);
+	for(i = 0; (which_scsi = mca_builtin_scsi_ports[i]) != 0; i++) {
+		outb_p(which_scsi, MCA_MOTHERBOARD_SETUP_REG);
+		if(mca_read_and_store_pos(pos))
+			break;
+	}
+	if(which_scsi) {
+		/* found a scsi card */
+		mca_dev = kmalloc(sizeof(struct mca_device), GFP_ATOMIC);
+		if(unlikely(!mca_dev))
+			goto out_unlock_nomem;
+		memset(mca_dev, 0, sizeof(struct mca_device));
+
+		for(j = 0; j < 8; j++)
+			mca_dev->pos[j] = pos[j];
+
+		mca_configure_adapter_status(mca_dev);
+		/* fake POS and slot for integrated SCSI controller */
+		mca_dev->pos_id = MCA_INTEGSCSI_POS;
+		mca_dev->slot = MCA_INTEGSCSI;
+		mca_dev->pos_register = which_scsi;
+		mca_register_device(MCA_PRIMARY_BUS, mca_dev);
 	}
 
-	return 0;
-}
-
-EXPORT_SYMBOL(mca_isenabled);
-
-/*--------------------------------------------------------------------*/
-
-#ifdef CONFIG_PROC_FS
+	/* Turn off motherboard setup */
 
-int get_mca_info(char *page, char **start, off_t off,
-				 int count, int *eof, void *data)
-{
-	int i, j, len = 0;
+	outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);
 
-	if(MCA_bus && mca_info != NULL) {
-		/* Format POS registers of eight MCA slots */
+	/* Now loop over MCA slots: put each adapter into setup mode, and
+	 * read its POS registers. Then put adapter setup off.
+	 */
 
-		for(i=0; i<MCA_MAX_SLOT_NR; i++) {
-			len += sprintf(page+len, "Slot %d: ", i+1);
-			for(j=0; j<8; j++)
-				len += sprintf(page+len, "%02x ", mca_info->slot[i].pos[j]);
-			len += sprintf(page+len, " %s\n", mca_info->slot[i].name);
-		}
+	for(i=0; i<MCA_MAX_SLOT_NR; i++) {
+		outb_p(0x8|(i&0xf), MCA_ADAPTER_SETUP_REG);
+		if(!mca_read_and_store_pos(pos))
+			continue;
 
-		/* Format POS registers of integrated video subsystem */
+		mca_dev = kmalloc(sizeof(struct mca_device), GFP_ATOMIC);
+		if(unlikely(!mca_dev))
+			goto out_unlock_nomem;
+		memset(mca_dev, 0, sizeof(struct mca_device));
 
-		len += sprintf(page+len, "Video : ");
 		for(j=0; j<8; j++)
-			len += sprintf(page+len, "%02x ", mca_info->slot[MCA_INTEGVIDEO].pos[j]);
-		len += sprintf(page+len, " %s\n", mca_info->slot[MCA_INTEGVIDEO].name);
+			mca_dev->pos[j]=pos[j];
 
-		/* Format POS registers of integrated SCSI subsystem */
+		mca_dev->driver_loaded = 0;
+		mca_dev->slot = i;
+		mca_dev->pos_register = 0;
+		mca_configure_adapter_status(mca_dev);
+		mca_register_device(MCA_PRIMARY_BUS, mca_dev);
+	}
+	outb_p(0, MCA_ADAPTER_SETUP_REG);
 
-		len += sprintf(page+len, "SCSI  : ");
-		for(j=0; j<8; j++)
-			len += sprintf(page+len, "%02x ", mca_info->slot[MCA_INTEGSCSI].pos[j]);
-		len += sprintf(page+len, " %s\n", mca_info->slot[MCA_INTEGSCSI].name);
+	/* Enable interrupts and return memory start */
+	spin_unlock_irq(&mca_lock);
 
-		/* Format POS registers of motherboard */
+	for (i = 0; i < MCA_STANDARD_RESOURCES; i++)
+		request_resource(&ioport_resource, mca_standard_resources + i);
 
-		len += sprintf(page+len, "Planar: ");
-		for(j=0; j<8; j++)
-			len += sprintf(page+len, "%02x ", mca_info->slot[MCA_MOTHERBOARD].pos[j]);
-		len += sprintf(page+len, " %s\n", mca_info->slot[MCA_MOTHERBOARD].name);
-	} else {
-		/* Leave it empty if MCA not detected - this should *never*
-		 * happen!
-		 */
-	}
+	mca_do_proc_init();
 
-	if (len <= off+count) *eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len>count) len = count;
-	if (len<0) len = 0;
-	return len;
+	return 0;
+
+ out_unlock_nomem:
+	spin_unlock_irq(&mca_lock);
+ out_nomem:
+	printk(KERN_EMERG "Failed memory allocation in MCA setup!\n");
+	return -ENOMEM;
 }
 
+subsys_initcall(mca_init);
+
 /*--------------------------------------------------------------------*/
 
-static int mca_default_procfn(char* buf, struct MCA_adapter *p)
+static void mca_handle_nmi_device(struct mca_device *mca_dev, int check_flag)
 {
-	int len = 0, i;
-	int slot = p - mca_info->slot;
-
-	/* Print out the basic information */
+	int slot = mca_dev->slot;
 
-	if(slot < MCA_MAX_SLOT_NR) {
-		len += sprintf(buf+len, "Slot: %d\n", slot+1);
-	} else if(slot == MCA_INTEGSCSI) {
-		len += sprintf(buf+len, "Integrated SCSI Adapter\n");
+	if(slot == MCA_INTEGSCSI) {
+		printk(KERN_CRIT "NMI: caused by MCA integrated SCSI adapter (%s)\n",
+			mca_dev->dev.name);
 	} else if(slot == MCA_INTEGVIDEO) {
-		len += sprintf(buf+len, "Integrated Video Adapter\n");
+		printk(KERN_CRIT "NMI: caused by MCA integrated video adapter (%s)\n",
+			mca_dev->dev.name);
 	} else if(slot == MCA_MOTHERBOARD) {
-		len += sprintf(buf+len, "Motherboard\n");
-	}
-	if(p->name[0]) {
-
-		/* Drivers might register a name without /proc handler... */
-
-		len += sprintf(buf+len, "Adapter Name: %s\n",
-			p->name);
-	} else {
-		len += sprintf(buf+len, "Adapter Name: Unknown\n");
+		printk(KERN_CRIT "NMI: caused by motherboard (%s)\n",
+			mca_dev->dev.name);
 	}
-	len += sprintf(buf+len, "Id: %02x%02x\n",
-		p->pos[1], p->pos[0]);
-	len += sprintf(buf+len, "Enabled: %s\nPOS: ",
-		mca_isenabled(slot) ? "Yes" : "No");
-	for(i=0; i<8; i++) {
-		len += sprintf(buf+len, "%02x ", p->pos[i]);
-	}
-	len += sprintf(buf+len, "\nDriver Installed: %s",
-		mca_is_adapter_used(slot) ? "Yes" : "No");
-	buf[len++] = '\n';
-	buf[len] = 0;
-
-	return len;
-} /* mca_default_procfn() */
-
-static int get_mca_machine_info(char* page, char **start, off_t off,
-				 int count, int *eof, void *data)
-{
-	int len = 0;
 
-	len += sprintf(page+len, "Model Id: 0x%x\n", machine_id);
-	len += sprintf(page+len, "Submodel Id: 0x%x\n", machine_submodel_id);
-	len += sprintf(page+len, "BIOS Revision: 0x%x\n", BIOS_revision);
-
-	if (len <= off+count) *eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len>count) len = count;
-	if (len<0) len = 0;
-	return len;
-}
-
-static int mca_read_proc(char *page, char **start, off_t off,
-				 int count, int *eof, void *data)
-{
-	struct MCA_adapter *p = (struct MCA_adapter *)data;
-	int len = 0;
-
-	/* Get the standard info */
+	/* More info available in POS 6 and 7? */
 
-	len = mca_default_procfn(page, p);
+	if(check_flag) {
+		unsigned char pos6, pos7;
 
-	/* Do any device-specific processing, if there is any */
+		pos6 = mca_device_read_pos(mca_dev, 6);
+		pos7 = mca_device_read_pos(mca_dev, 7);
 
-	if(p->procfn) {
-		len += p->procfn(page+len, p-mca_info->slot, p->dev);
+		printk(KERN_CRIT "NMI: POS 6 = 0x%x, POS 7 = 0x%x\n", pos6, pos7);
 	}
-	if (len <= off+count) *eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len>count) len = count;
-	if (len<0) len = 0;
-	return len;
-} /* mca_read_proc() */
+
+} /* mca_handle_nmi_slot */
 
 /*--------------------------------------------------------------------*/
 
-void __init mca_do_proc_init(void)
+static int mca_handle_nmi_callback(struct device *dev, void *data)
 {
-	int i;
-	struct proc_dir_entry *proc_mca;
-	struct proc_dir_entry* node = NULL;
-	struct MCA_adapter *p;
-
-	if(mca_info == NULL) return;	/* Should never happen */
-
-	proc_mca = proc_mkdir("mca", &proc_root);
-	create_proc_read_entry("pos",0,proc_mca,get_mca_info,NULL);
-	create_proc_read_entry("machine",0,proc_mca,get_mca_machine_info,NULL);
-
-	/* Initialize /proc/mca entries for existing adapters */
-
-	for(i = 0; i < MCA_NUMADAPTERS; i++) {
-		p = &mca_info->slot[i];
-		p->procfn = 0;
-
-		if(i < MCA_MAX_SLOT_NR) sprintf(p->procname,"slot%d", i+1);
-		else if(i == MCA_INTEGVIDEO) sprintf(p->procname,"video");
-		else if(i == MCA_INTEGSCSI) sprintf(p->procname,"scsi");
-		else if(i == MCA_MOTHERBOARD) sprintf(p->procname,"planar");
-
-		if(!mca_isadapter(i)) continue;
+	struct mca_device *mca_dev = to_mca_device(dev);
+	unsigned char pos5;
 
-		node = create_proc_read_entry(p->procname, 0, proc_mca,
-						mca_read_proc, (void *)p);
+	pos5 = mca_device_read_pos(mca_dev, 5);
 
-		if(node == NULL) {
-			printk("Failed to allocate memory for MCA proc-entries!");
-			return;
-		}
+	if(!(pos5 & 0x80)) {
+		/* Bit 7 of POS 5 is reset when this adapter has a hardware
+		 * error. Bit 7 it reset if there's error information
+		 * available in POS 6 and 7.
+		 */
+		mca_handle_nmi_device(mca_dev, !(pos5 & 0x40));
+		return 1;
 	}
+	return 0;
+}
 
-} /* mca_do_proc_init() */
+void mca_handle_nmi(void)
+{
+	/* First try - scan the various adapters and see if a specific
+	 * adapter was responsible for the error.
+	 */
+	bus_for_each_dev(&mca_bus_type, NULL, NULL, mca_handle_nmi_callback);
 
-#endif
+	mca_nmi_hook();
+} /* mca_handle_nmi */
diff -Nru a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c
--- a/arch/i386/kernel/microcode.c	Mon Dec  9 18:46:35 2002
+++ b/arch/i386/kernel/microcode.c	Mon Dec  9 18:46:35 2002
@@ -139,6 +139,7 @@
 			&microcode_fops, NULL);
 	if (devfs_handle == NULL && error) {
 		printk(KERN_ERR "microcode: failed to devfs_register()\n");
+		misc_deregister(&microcode_dev);
 		goto out;
 	}
 	error = 0;
diff -Nru a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
--- a/arch/i386/kernel/ptrace.c	Mon Dec  9 18:46:35 2002
+++ b/arch/i386/kernel/ptrace.c	Mon Dec  9 18:46:35 2002
@@ -160,7 +160,8 @@
 		/* are we already being traced? */
 		if (current->ptrace & PT_PTRACED)
 			goto out;
-		if ((ret = security_ptrace(current->parent, current)))
+		ret = security_ptrace(current->parent, current);
+		if (ret)
 			goto out;
 		/* set the ptrace bit in the process flags. */
 		current->ptrace |= PT_PTRACED;
diff -Nru a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
--- a/arch/i386/kernel/signal.c	Mon Dec  9 18:46:36 2002
+++ b/arch/i386/kernel/signal.c	Mon Dec  9 18:46:36 2002
@@ -506,6 +506,8 @@
 	if (regs->orig_eax >= 0) {
 		/* If so, check system call restarting.. */
 		switch (regs->eax) {
+		        case -ERESTART_RESTARTBLOCK:
+				current_thread_info()->restart_block.fn = do_no_restart_syscall;
 			case -ERESTARTNOHAND:
 				regs->eax = -EINTR;
 				break;
@@ -589,6 +591,10 @@
 		    regs->eax == -ERESTARTSYS ||
 		    regs->eax == -ERESTARTNOINTR) {
 			regs->eax = regs->orig_eax;
+			regs->eip -= 2;
+		}
+		if (regs->eax == -ERESTART_RESTARTBLOCK){
+			regs->eax = __NR_restart_syscall;
 			regs->eip -= 2;
 		}
 	}
diff -Nru a/arch/i386/kernel/suspend.c b/arch/i386/kernel/suspend.c
--- a/arch/i386/kernel/suspend.c	Mon Dec  9 18:46:50 2002
+++ b/arch/i386/kernel/suspend.c	Mon Dec  9 18:46:50 2002
@@ -125,10 +125,3 @@
 	}
 
 }
-
-#ifdef CONFIG_SOFTWARE_SUSPEND
-/* Local variables for do_magic */
-int loop __nosavedata = 0;
-int loop2 __nosavedata = 0;
-
-#endif
diff -Nru a/arch/i386/kernel/suspend_asm.S b/arch/i386/kernel/suspend_asm.S
--- a/arch/i386/kernel/suspend_asm.S	Mon Dec  9 18:46:36 2002
+++ b/arch/i386/kernel/suspend_asm.S	Mon Dec  9 18:46:36 2002
@@ -1,4 +1,7 @@
 .text
+
+/* Originally gcc generated, modified by hand */
+
 #include <linux/linkage.h>
 #include <asm/segment.h>
 #include <asm/page.h>
@@ -78,3 +81,11 @@
 .L1449:
 	popl %ebx
 	ret
+
+       .section .data.nosave
+loop:
+       .quad 0
+loop2:
+       .quad 0
+       .previous
+	
\ No newline at end of file
diff -Nru a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c
--- a/arch/i386/mm/hugetlbpage.c	Mon Dec  9 18:46:51 2002
+++ b/arch/i386/mm/hugetlbpage.c	Mon Dec  9 18:46:51 2002
@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/err.h>
+#include <linux/sysctl.h>
 #include <asm/mman.h>
 #include <asm/pgalloc.h>
 #include <asm/tlb.h>
diff -Nru a/arch/i386/mm/init.c b/arch/i386/mm/init.c
--- a/arch/i386/mm/init.c	Mon Dec  9 18:46:50 2002
+++ b/arch/i386/mm/init.c	Mon Dec  9 18:46:50 2002
@@ -299,7 +299,7 @@
 #endif
 }
 
-void __init zap_low_mappings (void)
+void zap_low_mappings (void)
 {
 	int i;
 	/*
diff -Nru a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c
--- a/arch/i386/oprofile/nmi_int.c	Mon Dec  9 18:46:51 2002
+++ b/arch/i386/oprofile/nmi_int.c	Mon Dec  9 18:46:51 2002
@@ -13,7 +13,7 @@
 #include <linux/smp.h>
 #include <linux/oprofile.h>
 #include <linux/pm.h>
-#include <asm/thread_info.h>
+#include <linux/thread_info.h>
 #include <asm/nmi.h>
 #include <asm/ptrace.h>
 #include <asm/msr.h>
diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig
--- a/arch/ia64/Kconfig	Mon Dec  9 18:46:51 2002
+++ b/arch/ia64/Kconfig	Mon Dec  9 18:46:51 2002
@@ -729,32 +729,7 @@
 
 if !IA64_HP_SIM
 
-
-menu "Console drivers"
-	depends on VT
-
-config VGA_CONSOLE
-	bool "VGA text console"
-	help
-	  Saying Y here will allow you to use Linux in text mode through a
-	  display that complies with the generic VGA standard. Virtually
-	  everyone wants that.
-
-	  The program SVGATextMode can be used to utilize SVGA video cards to
-	  their full potential in text mode. Download it from
-	  <ftp://ibiblio.org/pub/Linux/utils/console/>.
-
-	  Say Y.
-
 source "drivers/video/Kconfig"
-
-config PCI_CONSOLE
-	bool
-	depends on FB
-	default y
-
-endmenu
-
 
 menu "Sound"
 
diff -Nru a/arch/ia64/kernel/efivars.c b/arch/ia64/kernel/efivars.c
--- a/arch/ia64/kernel/efivars.c	Mon Dec  9 18:46:37 2002
+++ b/arch/ia64/kernel/efivars.c	Mon Dec  9 18:46:37 2002
@@ -195,6 +195,7 @@
 	if (!new_efivar->entry) return 1;
 
 
+	new_efivar->entry->owner = THIS_MODULE;
 	new_efivar->entry->data = new_efivar;
 	new_efivar->entry->read_proc = efivar_read;
 	new_efivar->entry->write_proc = efivar_write;
@@ -224,7 +225,6 @@
 	if (!page || !data) return -EINVAL;
 
 	spin_lock(&efivars_lock);
-	MOD_INC_USE_COUNT;
 
 	memcpy(var_data, &efi_var->var, len);
 
@@ -235,7 +235,6 @@
 					    &var_data->DataSize,
 					    var_data->Data);
 
-	MOD_DEC_USE_COUNT;
 	spin_unlock(&efivars_lock);
 
 	return proc_calc_metrics(page, start, off, count, eof, len);
@@ -269,15 +268,10 @@
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
 
-	MOD_INC_USE_COUNT;
-
 	var_data = kmalloc(size, GFP_KERNEL);
-	if (!var_data) {
-		MOD_DEC_USE_COUNT;
+	if (!var_data)
 		return -ENOMEM;
-	}
 	if (copy_from_user(var_data, buffer, size)) {
-		MOD_DEC_USE_COUNT;
                 kfree(var_data);
 		return -EFAULT;
 	}
@@ -313,7 +307,6 @@
 	if (status != EFI_SUCCESS) {
 		printk(KERN_WARNING "set_variable() failed: status=%lx\n", status);
 		kfree(var_data);
-		MOD_DEC_USE_COUNT;
 		spin_unlock(&efivars_lock);
 		return -EIO;
 	}
@@ -335,7 +328,6 @@
 	}
 
 	kfree(var_data);
-	MOD_DEC_USE_COUNT;
 	spin_unlock(&efivars_lock);
 	return size;
 }
diff -Nru a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c
--- a/arch/ia64/kernel/palinfo.c	Mon Dec  9 18:46:34 2002
+++ b/arch/ia64/kernel/palinfo.c	Mon Dec  9 18:46:34 2002
@@ -893,7 +893,6 @@
 	int len=0;
 	pal_func_cpu_u_t *f = (pal_func_cpu_u_t *)&data;
 
-	MOD_INC_USE_COUNT;
 	/*
 	 * in SMP mode, we may need to call another CPU to get correct
 	 * information. PAL, by definition, is processor specific
@@ -911,8 +910,6 @@
 	if (len>count) len = count;
 	if (len<0) len = 0;
 
-	MOD_DEC_USE_COUNT;
-
 	return len;
 }
 
@@ -947,8 +944,12 @@
 
 		for (j=0; j < NR_PALINFO_ENTRIES; j++) {
 			f.func_id = j;
-			*pdir++ = create_proc_read_entry (palinfo_entries[j].name, 0, cpu_dir,
-						palinfo_read_entry, (void *)f.value);
+			*pdir = create_proc_read_entry(
+					palinfo_entries[j].name, 0, cpu_dir,
+					palinfo_read_entry, (void *)f.value);
+			if (*pdir)
+				(*pdir)->owner = THIS_MODULE;
+			pdir++;
 		}
 		*pdir++ = cpu_dir;
 	}
diff -Nru a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
--- a/arch/ia64/kernel/ptrace.c	Mon Dec  9 18:46:51 2002
+++ b/arch/ia64/kernel/ptrace.c	Mon Dec  9 18:46:51 2002
@@ -1101,7 +1101,8 @@
 		/* are we already being traced? */
 		if (current->ptrace & PT_PTRACED)
 			goto out;
-		if ((ret = security_ptrace(current->parent, current)))
+		ret = security_ptrace(current->parent, current);
+		if (ret)
 			goto out;
 		current->ptrace |= PT_PTRACED;
 		ret = 0;
diff -Nru a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c
--- a/arch/ia64/kernel/salinfo.c	Mon Dec  9 18:46:50 2002
+++ b/arch/ia64/kernel/salinfo.c	Mon Dec  9 18:46:50 2002
@@ -56,8 +56,11 @@
 
 	for (i=0; i < NR_SALINFO_ENTRIES; i++) {
 		/* pass the feature bit in question as misc data */
-		*sdir++ = create_proc_read_entry (salinfo_entries[i].name, 0, salinfo_dir,
+		*sdir = create_proc_read_entry (salinfo_entries[i].name, 0, salinfo_dir,
 						  salinfo_read, (void *)salinfo_entries[i].feature);
+		if (*sdir)
+			*sdir->owner = THIS_MODULE;
+		sdir++;
 	}
 	*sdir++ = salinfo_dir;
 
@@ -84,8 +87,6 @@
 {
 	int len = 0;
 
-	MOD_INC_USE_COUNT;
-
 	len = sprintf(page, (sal_platform_features & (unsigned long)data) ? "1\n" : "0\n");
 
 	if (len <= off+count) *eof = 1;
@@ -95,8 +96,6 @@
 
 	if (len>count) len = count;
 	if (len<0) len = 0;
-
-	MOD_DEC_USE_COUNT;
 
 	return len;
 }
diff -Nru a/arch/ia64/sn/io/hcl.c b/arch/ia64/sn/io/hcl.c
--- a/arch/ia64/sn/io/hcl.c	Mon Dec  9 18:46:50 2002
+++ b/arch/ia64/sn/io/hcl.c	Mon Dec  9 18:46:50 2002
@@ -673,8 +673,7 @@
 		 * Call devfs to get the devfs entry.
 		 */
 		namelen = (int) strlen(name);
-		target_handle = devfs_get_handle(from, name, 0, 0,
-					0, 1); /* Yes traverse symbolic links */
+		target_handle = devfs_get_handle(from, name, 1); /* Yes traverse symbolic links */
 		devfs_put(target_handle); /* Assume we're the owner */
 		if (target_handle == NULL)
 			return(-1);
@@ -955,9 +954,6 @@
 {
 	*vertex_handle_ptr = devfs_get_handle(start_vertex_handle,	/* start dir */
 					lookup_path,		/* path */
-					0,			/* major */
-					0,			/* minor */
-					0,			/* char | block */
 					1);			/* traverse symlinks */
 	devfs_put(*vertex_handle_ptr); /* Assume we're the owner */
 	if (*vertex_handle_ptr == NULL)
@@ -979,9 +975,6 @@
 
 	*found = devfs_get_handle(dir,	/* start dir */
 			    path,	/* path */
-			    0,		/* major */
-			    0,		/* minor */
-			    0,		/* char | block */
 			    1);		/* traverse symlinks */
 	devfs_put(*found); /* Assume we're the owner */
 	if (*found == NULL)
@@ -1001,9 +994,6 @@
 
 	de = devfs_get_handle(NULL,	/* start dir */
 			path,		/* path */
-		    	0,		/* major */
-		    	0,		/* minor */
-		    	0,		/* char | block */
 		    	1);
 	devfs_put(de); /* Assume we're the owner */
 	return(de);
@@ -1033,9 +1023,6 @@
 
 	de = devfs_get_handle(dir,		/* start dir */
 			"block",		/* path */
-		    	0,			/* major */
-		    	0,			/* minor */
-		    	DEVFS_SPECIAL_BLK,	/* char | block */
 		    	1);			/* traverse symlinks */
 	devfs_put(de); /* Assume we're the owner */
 	return(de);
@@ -1052,9 +1039,6 @@
 
 	de = devfs_get_handle(dir,		/* start dir */
 			"char",			/* path */
-		    	0,			/* major */
-		    	0,			/* minor */
-		    	DEVFS_SPECIAL_CHR,	/* char | block */
 		    	1);			/* traverse symlinks */
 	devfs_put(de); /* Assume we're the owner */
 	return(de);
diff -Nru a/arch/ia64/sn/io/pciba.c b/arch/ia64/sn/io/pciba.c
--- a/arch/ia64/sn/io/pciba.c	Mon Dec  9 18:46:34 2002
+++ b/arch/ia64/sn/io/pciba.c	Mon Dec  9 18:46:34 2002
@@ -281,10 +281,6 @@
 }
 #endif
 
-
-static devfs_handle_t pciba_devfs_handle;
-
-
 #if !defined(CONFIG_IA64_SGI_SN1)
 
 static status __init
@@ -296,25 +292,24 @@
 
 	TRACE();
 
-	pciba_devfs_handle = devfs_mk_dir(NULL, "pci", NULL);
-	if (pciba_devfs_handle == NULL)
+	if (!devfs_mk_dir(NULL, "pci", NULL))
 		return failure;
 
 	/* FIXME: don't forget /dev/pci/mem & /dev/pci/io */
 
 	pci_for_each_dev(dev) {
-		sprintf(devfs_path, "%02x/%02x.%x",
+		sprintf(devfs_path, "pci/%02x/%02x.%x",
 			dev->bus->number,
 			PCI_SLOT(dev->devfn),
 			PCI_FUNC(dev->devfn));
     
 		device_dir_handle =
-			devfs_mk_dir(pciba_devfs_handle, devfs_path, NULL);
+			devfs_mk_dir(NULL, devfs_path, NULL);
 		if (device_dir_handle == NULL)
 			return failure;
 
 		if (register_pci_device(device_dir_handle, dev) == failure) {
-			devfs_unregister(pciba_devfs_handle);
+			devfs_remove("pci");
 			return failure;
 		}
 	}
@@ -344,7 +339,7 @@
 			return failure;
 	
 		if (register_pci_device(device_dir_handle, dev) == failure) {
-			devfs_unregister(pciba_devfs_handle);
+			devfs_remove("pci");
 			return failure;
 		}
 	}
diff -Nru a/arch/ia64/sn/kernel/sn1/synergy.c b/arch/ia64/sn/kernel/sn1/synergy.c
--- a/arch/ia64/sn/kernel/sn1/synergy.c	Mon Dec  9 18:46:51 2002
+++ b/arch/ia64/sn/kernel/sn1/synergy.c	Mon Dec  9 18:46:51 2002
@@ -449,7 +449,7 @@
 }
 
 struct file_operations synergy_mon_fops = {
-        ioctl:		synergy_perf_ioctl,
+        .ioctl		= synergy_perf_ioctl,
 };
 
 void
diff -Nru a/arch/m68k/Kconfig b/arch/m68k/Kconfig
--- a/arch/m68k/Kconfig	Mon Dec  9 18:46:38 2002
+++ b/arch/m68k/Kconfig	Mon Dec  9 18:46:38 2002
@@ -2309,14 +2309,7 @@
 
 source "fs/Kconfig"
 
-
-menu "Console drivers"
-	depends on VT
-
 source "drivers/video/Kconfig"
-
-endmenu
-
 
 menu "Kernel hacking"
 
diff -Nru a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
--- a/arch/m68knommu/Kconfig	Mon Dec  9 18:46:50 2002
+++ b/arch/m68knommu/Kconfig	Mon Dec  9 18:46:50 2002
@@ -672,42 +672,7 @@
 
 source "fs/Kconfig"
 
-
-menu "Console drivers"
-	depends on VT
-
-config VGA_CONSOLE
-	bool "VGA text console"
-	help
-	  Saying Y here will allow you to use Linux in text mode through a
-	  display that complies with the generic VGA standard. Virtually
-	  everyone wants that.
-
-	  The program SVGATextMode can be used to utilize SVGA video cards to
-	  their full potential in text mode. Download it from
-	  <ftp://ibiblio.org/pub/Linux/utils/console/>.
-
-	  If unsure, say N.
-
-config VIDEO_SELECT
-	bool "Video mode selection support"
-	---help---
-	  This enables support for text mode selection on kernel startup. If
-	  you want to take advantage of some high-resolution text mode your
-	  card's BIOS offers, but the traditional Linux utilities like
-	  SVGATextMode don't, you can say Y here and set the mode using the
-	  "vga=" option from your boot loader (lilo or loadlin) or set
-	  "vga=ask" which brings up a video mode menu on kernel startup. (Try
-	  "man bootparam" or see the documentation of your boot loader about
-	  how to pass options to the kernel.)
-
-	  Read the file <file:Documentation/svga.txt> for more information
-	  about the Video mode selection support. If unsure, say N.
-
 source "drivers/video/Kconfig"
-
-endmenu
-
 
 menu "Sound"
 
diff -Nru a/arch/m68knommu/Makefile b/arch/m68knommu/Makefile
--- a/arch/m68knommu/Makefile	Mon Dec  9 18:46:50 2002
+++ b/arch/m68knommu/Makefile	Mon Dec  9 18:46:50 2002
@@ -42,7 +42,7 @@
 #
 # Some code support is grouped together for a common cpu-subclass (for
 # example all ColdFire cpu's are very similar). Determine the sub-class
-# for the selected cpu. ONLY need to define this for the non-core member
+# for the selected cpu. ONLY need to define this for the non-base member
 # of the family.
 #
 cpuclass-$(CONFIG_M5206)	:= 5307
@@ -53,7 +53,10 @@
 cpuclass-$(CONFIG_M68EZ328)	:= 68328
 cpuclass-$(CONFIG_M68VZ328)	:= 68328
 CPUCLASS := $(cpuclass-y)
+
+ifneq ($(CPUCLASS),)
 CLASSDIR := arch/m68knommu/platform/$(cpuclass-y)/
+endif
 
 export PLATFORM BOARD MODEL CPUCLASS
 
@@ -79,9 +82,11 @@
 CFLAGS += -D__linux__
 CFLAGS += -DUTS_SYSNAME=\"uClinux\"
 
+LDFLAGS_BLOB	:= --format binary --oformat elf32-m68k
+
 HEAD := arch/m68knommu/platform/$(platform-y)/$(board-y)/crt0_$(model-y).o
 
-clean-files := include/asm-$(ARCH)/asm-offsets.h.tmp \
+CLEAN_FILES := include/asm-$(ARCH)/asm-offsets.h.tmp \
 	       include/asm-$(ARCH)/asm-offsets.h \
 	       arch/$(ARCH)/kernel/asm-offsets.s
 
diff -Nru a/arch/m68knommu/kernel/asm-offsets.c b/arch/m68knommu/kernel/asm-offsets.c
--- a/arch/m68knommu/kernel/asm-offsets.c	Mon Dec  9 18:46:51 2002
+++ b/arch/m68knommu/kernel/asm-offsets.c	Mon Dec  9 18:46:51 2002
@@ -32,6 +32,9 @@
 	DEFINE(TASK_MM, offsetof(struct task_struct, mm));
 	DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
 
+	/* 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));
 
diff -Nru a/arch/m68knommu/kernel/m68k_ksyms.c b/arch/m68knommu/kernel/m68k_ksyms.c
--- a/arch/m68knommu/kernel/m68k_ksyms.c	Mon Dec  9 18:46:51 2002
+++ b/arch/m68knommu/kernel/m68k_ksyms.c	Mon Dec  9 18:46:51 2002
@@ -21,7 +21,7 @@
 #include <asm/current.h>
 
 extern void dump_thread(struct pt_regs *, struct user *);
-extern int dump_fpu(elf_fpregset_t *);
+extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
 
 /* platform dependent support */
 
diff -Nru a/arch/m68knommu/kernel/syscalltable.S b/arch/m68knommu/kernel/syscalltable.S
--- a/arch/m68knommu/kernel/syscalltable.S	Mon Dec  9 18:46:34 2002
+++ b/arch/m68knommu/kernel/syscalltable.S	Mon Dec  9 18:46:34 2002
@@ -145,10 +145,10 @@
 	.long sys_adjtimex
 	.long sys_ni_syscall	/* 125 */ /* sys_mprotect */
 	.long sys_sigprocmask
-	.long sys_create_module
+	.long sys_ni_syscall	/* old "creat_module" */
 	.long sys_init_module
 	.long sys_delete_module
-	.long sys_get_kernel_syms /* 130 */
+	.long sys_ni_syscall	/* 130: old "get_kernel_syms" */
 	.long sys_quotactl
 	.long sys_getpgid
 	.long sys_fchdir
@@ -185,9 +185,9 @@
 	.long sys_setresuid16
 	.long sys_getresuid16	/* 165 */
 	.long sys_ni_syscall	/* for vm86 */
-	.long sys_query_module
+	.long sys_ni_syscall	/* old "query_module" */
 	.long sys_poll
-	.long sys_ni_syscall	/*sys_nfsservctl*/
+	.long sys_ni_syscall	/* sys_nfsservctl */
 	.long sys_setresgid16	/* 170 */
 	.long sys_getresgid16
 	.long sys_prctl
@@ -236,7 +236,7 @@
 	.long sys_setfsuid	/* 215 */
 	.long sys_setfsgid
 	.long sys_pivot_root
-	.long sys_mincore
+	.long sys_ni_syscall	/* sys_mincore */
 	.long sys_ni_syscall	/* sys_madvise */
 	.long sys_getdents64	/* 220 */
 	.long sys_fcntl64
diff -Nru a/arch/m68knommu/platform/68328/Makefile b/arch/m68knommu/platform/68328/Makefile
--- a/arch/m68knommu/platform/68328/Makefile	Mon Dec  9 18:46:35 2002
+++ b/arch/m68knommu/platform/68328/Makefile	Mon Dec  9 18:46:35 2002
@@ -7,7 +7,7 @@
 obj-$(CONFIG_M68VZ328)	+= entry.o ints.o
 
 ifeq ($(CONFIG_M68328),y)
-EXTRA_TARGETS := $(BOARD)/bootlogo.rh $(BOARD/crt0_$(MODEL).o
+EXTRA_TARGETS := $(BOARD)/bootlogo.rh $(BOARD)/crt0_$(MODEL).o
 endif
 
 include $(TOPDIR)/Rules.make
diff -Nru a/arch/mips/Kconfig b/arch/mips/Kconfig
--- a/arch/mips/Kconfig	Mon Dec  9 18:46:37 2002
+++ b/arch/mips/Kconfig	Mon Dec  9 18:46:37 2002
@@ -913,7 +913,7 @@
 endmenu
 
 
-if !DECSTATION" && !SGI_IP22
+if !DECSTATION && !SGI_IP22
 source "drivers/message/i2o/Kconfig"
 endif
 
@@ -1115,28 +1115,6 @@
 	bool "Support for console on virtual terminal"
 	depends on VT
 
-config SGI_NEWPORT_CONSOLE
-	tristate "SGI Newport Console support"
-	depends on VT
-	help
-	  Say Y here if you want the console on the Newport aka XL graphics
-	  card of your Indy.  Most people say Y here.
-
-config DUMMY_CONSOLE
-	bool
-	depends on VT && SGI_NEWPORT_CONSOLE!=y
-	default y
-
-config FONT_8x16
-	bool
-	depends on VT && SGI_NEWPORT_CONSOLE=y
-	default y
-	help
-	  This is the "high resolution" font for the VGA frame buffer (the one
-	  provided by the VGA text console 80x25 mode.
-
-	  If unsure, say Y.
-
 config PSMOUSE
 	bool "PS/2 mouse support (aka \"auxiliary device\")"
 	---help---
@@ -1192,47 +1170,7 @@
 
 source "fs/Kconfig"
 
-
-menu "Console drivers"
-	depends on VT
-
-config VGA_CONSOLE
-	bool "VGA text console"
-	help
-	  Saying Y here will allow you to use Linux in text mode through a
-	  display that complies with the generic VGA standard. Virtually
-	  everyone wants that.
-
-	  The program SVGATextMode can be used to utilize SVGA video cards to
-	  their full potential in text mode. Download it from
-	  <ftp://ibiblio.org/pub/Linux/utils/console/>.
-
-	  Say Y.
-
-if EXPERIMENTAL
-
-config MDA_CONSOLE
-	tristate "MDA text console (dual-headed) (EXPERIMENTAL)"
-	---help---
-	  Say Y here if you have an old MDA or monochrome Hercules graphics
-	  adapter in your system acting as a second head ( = video card). You
-	  will then be able to use two monitors with your Linux system. Do not
-	  say Y here if your MDA card is the primary card in your system; the
-	  normal VGA driver will handle it.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted and removed from the running kernel whenever you want).
-	  The module will be called mdacon.o. If you want to compile it as
-	  a module, say M here and read <file:Documentation/modules.txt>.
-
-	  If unsure, say N.
-
 source "drivers/video/Kconfig"
-
-endif
-
-endmenu
-
 
 menu "Sound"
 	depends on !DECSTATION
diff -Nru a/arch/mips64/Kconfig b/arch/mips64/Kconfig
--- a/arch/mips64/Kconfig	Mon Dec  9 18:46:35 2002
+++ b/arch/mips64/Kconfig	Mon Dec  9 18:46:35 2002
@@ -593,30 +593,7 @@
 
 source "fs/Kconfig"
 
-
-menu "Console drivers"
-	depends on VT
-
 source "drivers/video/Kconfig"
-
-config SGI_NEWPORT_CONSOLE
-	tristate "SGI Newport Console support"
-	depends on SGI_IP22
-	help
-	  Say Y here if you want the console on the Newport aka XL graphics
-	  card of your Indy.  Most people say Y here.
-
-config DUMMY_CONSOLE
-	bool
-	depends on SGI_IP22 && SGI_NEWPORT_CONSOLE!=y
-	default y
-
-config FONT_8x16
-	bool
-	depends on SGI_IP22 && SGI_NEWPORT_CONSOLE=y
-	default y
-
-endmenu
 
 config KCORE_ELF
 	bool
diff -Nru a/arch/parisc/Kconfig b/arch/parisc/Kconfig
--- a/arch/parisc/Kconfig	Mon Dec  9 18:46:38 2002
+++ b/arch/parisc/Kconfig	Mon Dec  9 18:46:38 2002
@@ -335,37 +335,7 @@
 
 source "fs/Kconfig"
 
-
-menu "Console drivers"
-	depends on VT
-
-config STI_CONSOLE
-	bool "STI console"
-	help
-	  STI refers to the HP "Standard Text Interface" which is a set of
-	  BIOS routines contained in a ROM chip in HP PA-RISC based machines.
-	  Enabling this option will give you an 8 color text console on
-	  most of the PA-RISC systems.
-	  Really old HP boxes may not have STI, in which case you must use the
-	  PDC console or your primary serial port as a console.
-	
-	  The text console uses a strange memory layout, and changing the 
-	  plane mask to create colored characters requires calls to the STI 
-	  routines. Because of that do not expect it to be actually very fast,
-	  but it is sufficient for basic text console functions, including fonts.
-	
-	  The alternative is to use your primary serial port as a console.
-	
-	  It is safe to enable this option, so you should probably say "Y".
-
-config DUMMY_CONSOLE
-	bool
-	depends on STI_CONSOLE || SERIAL_8250_CONSOLE
-	default y
-
 source "drivers/video/Kconfig"
-
-endmenu
 
 menu "Sound"
 
diff -Nru a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile
--- a/arch/parisc/kernel/Makefile	Mon Dec  9 18:46:35 2002
+++ b/arch/parisc/kernel/Makefile	Mon Dec  9 18:46:35 2002
@@ -11,7 +11,7 @@
 AFLAGS_entry.o := -traditional
 AFLAGS_pacache.o := -traditional
 
-export-objs	:= parisc_ksyms.o keyboard.o
+export-objs	:= parisc_ksyms.o 
 
 obj-y	     	:= cache.o pacache.o setup.o traps.o time.o irq.o \
 		   pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \
@@ -22,7 +22,6 @@
 obj-$(CONFIG_SMP) += smp.o 
 obj-$(CONFIG_PA11) += pci-dma.o
 obj-$(CONFIG_PCI) += pci.o
-obj-$(CONFIG_VT) += keyboard.o
 obj-$(CONFIG_PARISC64) += binfmt_elf32.o sys_parisc32.o \
 		ioctl32.o signal32.o
 # only supported for PCX-W/U in 64-bit mode at the moment
diff -Nru a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
--- a/arch/parisc/kernel/irq.c	Mon Dec  9 18:46:36 2002
+++ b/arch/parisc/kernel/irq.c	Mon Dec  9 18:46:36 2002
@@ -112,27 +112,43 @@
  * 	do_cpu_irq_mask()	index into the matching irq_action array.
  */
 struct irqaction cpu_irq_actions[IRQ_PER_REGION] = {
-	[IRQ_OFFSET(TIMER_IRQ)] { handler: timer_interrupt, name: "timer", },
+	[IRQ_OFFSET(TIMER_IRQ)]	= {
+					.handler = timer_interrupt,
+					.name = "timer",
+				},
 #ifdef CONFIG_SMP
-	[IRQ_OFFSET(IPI_IRQ)]	{ handler: ipi_interrupt,   name: "IPI", },
+	[IRQ_OFFSET(IPI_IRQ)]	= {
+					.handler = ipi_interrupt,
+					.name = "IPI",
+				},
 #endif
 };
 
 struct irq_region_ops cpu_irq_ops = {
-	disable_cpu_irq, enable_cpu_irq, unmask_cpu_irq, unmask_cpu_irq
+	.disable_irq	= disable_cpu_irq,
+	.enable_irq	= enable_cpu_irq,
+	.mask_irq	= unmask_cpu_irq,
+	.unmask_irq	= unmask_cpu_irq
 };
 
 struct irq_region cpu0_irq_region = {
-	ops:	{ disable_cpu_irq, enable_cpu_irq, unmask_cpu_irq, unmask_cpu_irq },
-	data:	{ dev: &cpu_data[0],
-		  name: "PARISC-CPU",
-		  irqbase: IRQ_FROM_REGION(CPU_IRQ_REGION), },
-	action:	cpu_irq_actions,
+	.ops	= {
+			.disable_irq	= disable_cpu_irq,
+			.enable_irq	= enable_cpu_irq,
+			.mask_irq	= unmask_cpu_irq,
+			.unmask_irq	= unmask_cpu_irq
+	},
+	.data	= {
+			.dev		= &cpu_data[0],
+			.name		= "PARISC-CPU",
+			.irqbase 	= IRQ_FROM_REGION(CPU_IRQ_REGION),
+	},
+	.action	= cpu_irq_actions,
 };
 
 struct irq_region *irq_region[NR_IRQ_REGS] = {
-	[ 0 ]              NULL, /* reserved for EISA, else causes data page fault (aka code 15) */
-	[ CPU_IRQ_REGION ] &cpu0_irq_region,
+	[ 0 ]              = NULL, /* reserved for EISA, else causes data page fault (aka code 15) */
+	[ CPU_IRQ_REGION ] = &cpu0_irq_region,
 };
 
 
diff -Nru a/arch/parisc/kernel/keyboard.c b/arch/parisc/kernel/keyboard.c
--- a/arch/parisc/kernel/keyboard.c	Mon Dec  9 18:46:35 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,101 +0,0 @@
-/*
- *  WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
- *  ---------------------------------------------------------------
- *  This source file will be removed as soon as we have converted
- *  hp_psaux.c and hp_keyb.c to the input layer !
- *  
- */
-
-/*
- *  linux/arch/parisc/kernel/keyboard.c
- *
- *  Alex deVries <adevries@thepuffingroup.com>
- *  Copyright (1999) The Puffin Group
- *  Mostly rewritten by Philipp Rumpf <prumpf@tux.org>
- *  Copyright 2000 Philipp Rumpf
- */
-
-#include <linux/errno.h>
-#include <linux/keyboard.h>
-#include <asm/keyboard.h>
-#include <linux/module.h>
-
-static int def_setkeycode(unsigned int x, unsigned int y)
-{
-	return 0;
-}
-
-static int def_getkeycode(unsigned int x)
-{
-	return 0;
-}
-
-static int def_translate(unsigned char scancode, unsigned char *keycode,
-	char raw)
-{
-	*keycode = scancode;
-
-	return 1;
-}
-
-static char def_unexpected_up(unsigned char c)
-{
-	return 128;
-}
-
-static void def_leds(unsigned char leds)
-{
-}
-
-static void def_init_hw(void)
-{
-}
-
-static char def_sysrq_xlate[NR_KEYS];
-
-#define DEFAULT_KEYB_OPS \
-	.setkeycode	= def_setkeycode,	\
-	.getkeycode	= def_getkeycode, \
-	.translate	= def_translate, \
-	.unexpected_up	= def_unexpected_up, \
-	.leds		= def_leds, \
-	.init_hw	= def_init_hw, \
-	.sysrq_key	= 0xff, \
-	.sysrq_xlate	= def_sysrq_xlate,
-
-static struct kbd_ops def_kbd_ops = {
-	DEFAULT_KEYB_OPS
-};
-
-struct kbd_ops *kbd_ops = &def_kbd_ops;
-
-void unregister_kbd_ops(void)
-{
-	struct kbd_ops new_kbd_ops = { DEFAULT_KEYB_OPS };
-	register_kbd_ops(&new_kbd_ops);
-}
-EXPORT_SYMBOL(unregister_kbd_ops);
-
-void register_kbd_ops(struct kbd_ops *ops)
-{
-	if(ops->setkeycode)
-		kbd_ops->setkeycode = ops->setkeycode;
-	
-	if(ops->getkeycode)
-		kbd_ops->getkeycode = ops->getkeycode;
-	
-	if(ops->translate)
-		kbd_ops->translate = ops->translate;
-	
-	if(ops->unexpected_up)
-		kbd_ops->unexpected_up = ops->unexpected_up;
-	
-	if(ops->leds)
-		kbd_ops->leds = ops->leds;
-	
-	if(ops->init_hw)
-		kbd_ops->init_hw = ops->init_hw;
-	
-	kbd_ops->sysrq_key = ops->sysrq_key;
-	kbd_ops->sysrq_xlate = ops->sysrq_xlate;
-}
diff -Nru a/arch/ppc/8xx_io/cs4218_tdm.c b/arch/ppc/8xx_io/cs4218_tdm.c
--- a/arch/ppc/8xx_io/cs4218_tdm.c	Mon Dec  9 18:46:34 2002
+++ b/arch/ppc/8xx_io/cs4218_tdm.c	Mon Dec  9 18:46:34 2002
@@ -1629,7 +1629,6 @@
 
 static int mixer_open(struct inode *inode, struct file *file)
 {
-	MOD_INC_USE_COUNT;
 	mixer.busy = 1;
 	return 0;
 }
@@ -1638,7 +1637,6 @@
 static int mixer_release(struct inode *inode, struct file *file)
 {
 	mixer.busy = 0;
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
@@ -2050,7 +2048,6 @@
 {
 	int rc = 0;
 
-	MOD_INC_USE_COUNT;
 	if (file->f_mode & FMODE_WRITE) {
 		if (sq.busy) {
 			rc = -EBUSY;
@@ -2131,7 +2128,6 @@
 		WAKE_UP(read_sq.open_queue);
 	}
 err_out:
-	MOD_DEC_USE_COUNT;
 	return rc;
 }
 
@@ -2183,7 +2179,6 @@
 
 	sq_release_read_buffers();
 	sq_release_buffers();
-	MOD_DEC_USE_COUNT;
 
 	if (file->f_mode & FMODE_READ) {
 		read_sq.busy = 0;
@@ -2372,7 +2367,6 @@
 	if (state.busy)
 		return -EBUSY;
 
-	MOD_INC_USE_COUNT;
 	state.ptr = 0;
 	state.busy = 1;
 
@@ -2428,7 +2422,6 @@
 static int state_release(struct inode *inode, struct file *file)
 {
 	state.busy = 0;
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
diff -Nru a/arch/ppc/Kconfig b/arch/ppc/Kconfig
--- a/arch/ppc/Kconfig	Mon Dec  9 18:46:51 2002
+++ b/arch/ppc/Kconfig	Mon Dec  9 18:46:51 2002
@@ -1054,11 +1054,6 @@
 	  some command-line options at build time by entering them here.  In
 	  most cases you will need to specify the root device here.
 
-config FB_CONSOLE
-	bool
-	depends on APUS
-	default y
-
 config AMIGA
 	bool
 	depends on APUS
@@ -1467,24 +1462,7 @@
 
 source "drivers/isdn/Kconfig"
 
-
-menu "Console drivers"
-
-config VGA_CONSOLE
-	bool "VGA text console"
-	depends on !4xx && !8xx
-	help
-	  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.
-
 source "drivers/video/Kconfig"
-
-endmenu
-
 
 menu "iSeries device drivers"
 	depends on PPC_ISERIES
diff -Nru a/arch/ppc/Makefile b/arch/ppc/Makefile
--- a/arch/ppc/Makefile	Mon Dec  9 18:46:34 2002
+++ b/arch/ppc/Makefile	Mon Dec  9 18:46:34 2002
@@ -55,19 +55,21 @@
 drivers-$(CONFIG_4xx)		+= arch/ppc/4xx_io/
 drivers-$(CONFIG_8260)		+= arch/ppc/8260_io/
 
-makeboot = $(call descend,arch/ppc/boot,$(1))
+makeboot =$(Q)$(MAKE) -f scripts/Makefile.build obj=arch/ppc/boot $(1)
 
 BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd pImage vmlinux.sm
 
 .PHONY: $(BOOT_TARGETS) clean archclean archmrproper
 
+all: zImage
+
 AFLAGS_vmlinux.lds.o	:= -Upowerpc
 
 # All the instructions talk about "make bzImage".
 bzImage: zImage
 
 $(BOOT_TARGETS): vmlinux
-	+@$(call makeboot,$@)
+	@$(call makeboot,$@)
 
 %_config: arch/ppc/configs/%_defconfig
 	rm -f .config arch/ppc/defconfig
diff -Nru a/arch/ppc/amiga/amiints.c b/arch/ppc/amiga/amiints.c
--- a/arch/ppc/amiga/amiints.c	Mon Dec  9 18:46:34 2002
+++ b/arch/ppc/amiga/amiints.c	Mon Dec  9 18:46:34 2002
@@ -310,14 +310,14 @@
    and executes them in a loop. Having ami_badint at the end of the chain
    is a bad idea. */
 struct irqaction amiga_sys_irqaction[AUTO_IRQS] = {
-	{ handler: ami_badint, name: "spurious int" },
-	{ handler: ami_int1, name: "int1 handler" },
+	{ .handler = ami_badint, .name = "spurious int" },
+	{ .handler = ami_int1, .name = "int1 handler" },
 	{ 0, /* CIAA */ },
-	{ handler: ami_int3, name: "int3 handler" },
-	{ handler: ami_int4, name: "int4 handler" },
-	{ handler: ami_int5, name: "int5 handler" },
+	{ .handler = ami_int3, .name = "int3 handler" },
+	{ .handler = ami_int4, .name = "int4 handler" },
+	{ .handler = ami_int5, .name = "int5 handler" },
 	{ 0, /* CIAB */ },
-	{ handler: ami_int7, name: "int7 handler" },
+	{ .handler = ami_int7, .name = "int7 handler" },
 };
 #else
 void (*amiga_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
diff -Nru a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile
--- a/arch/ppc/boot/Makefile	Mon Dec  9 18:46:38 2002
+++ b/arch/ppc/boot/Makefile	Mon Dec  9 18:46:38 2002
@@ -42,4 +42,4 @@
 $(BOOT_TARGETS): $(bootdir-y)
 
 $(bootdir-y): $(addprefix $(obj)/,$(subdir-y))
-	+$(call descend,$(obj)/$@,$(MAKECMDGOALS))
+	$(Q)$(MAKE) -f scripts/Makefile.build obj=$(obj)/$@ $(MAKECMDGOALS)
diff -Nru a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c
--- a/arch/ppc/kernel/cputable.c	Mon Dec  9 18:46:38 2002
+++ b/arch/ppc/kernel/cputable.c	Mon Dec  9 18:46:38 2002
@@ -154,6 +154,24 @@
 	32, 32,
 	__setup_cpu_750
     },
+    {	/* 750FX rev 2.0 must disable HID0[DPM] */
+    	0xffffffff, 0x70000200, "750FX",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
+	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP |
+	CPU_FTR_NO_DPM,
+	COMMON_PPC,
+	32, 32,
+	__setup_cpu_750
+    },
+    {	/* 750FX (All revs except 2.0) */
+    	0xffff0000, 0x70000000, "750FX",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
+	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP,
+	COMMON_PPC,
+	32, 32,
+	__setup_cpu_750
+    },
+ 
     {	/* 740/750 (L2CR bit need fixup for 740) */
     	0xffff0000, 0x00080000, "740/750",
     	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
@@ -327,22 +345,50 @@
     	0xffff0000, 0x41610000, "NP405L",
     	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
     	PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
-	16, 8,
+	32, 32,
 	0, /*__setup_cpu_405 */
     },
     {	/* NP4GS3 */
     	0xffff0000, 0x40B10000, "NP4GS3",
     	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
     	PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
-	16, 8,
+	32, 32,
 	0, /*__setup_cpu_405 */
     },
     {   /* NP405H */
         0xffff0000, 0x41410000, "NP405H",
         CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
         PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
-        16, 8,
+        32, 32,
         0, /*__setup_cpu_405 */
+     },
+     {	/* 405GPr */
+    	0xffff0000, 0x50910000, "405GPr",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
+    	PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+	32, 32,
+	0, /*__setup_cpu_405 */
+    },
+    {   /* STBx25xx */
+        0xffff0000, 0x51510000, "STBx25xx",
+        CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
+        PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+        32, 32,
+        0, /*__setup_cpu_405 */
+     },
+     {	/* 405LP */
+    	0xffff0000, 0x41F10000, "405LP",
+    	CPU_FTR_SPLIT_ID_CACHE |  CPU_FTR_USE_TB,
+    	PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+	32, 32,
+	0, /*__setup_cpu_405 */
+     },
+     {	/* Xilinx Virtex-II Pro  */
+	0xffff0000, 0x20010000, "Virtex-II Pro",
+	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
+	PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+	32, 32,
+	0, /*__setup_cpu_405 */
      },
 
 #endif /* CONFIG_40x */
diff -Nru a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
--- a/arch/ppc/kernel/head.S	Mon Dec  9 18:46:38 2002
+++ b/arch/ppc/kernel/head.S	Mon Dec  9 18:46:38 2002
@@ -1317,7 +1317,9 @@
 setup_750_7400_hid0:
 	mfspr	r11,HID0
 	ori	r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC
+BEGIN_FTR_SECTION
 	oris	r11,r11,HID0_DPM@h	/* enable dynamic power mgmt */
+END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
 	li	r3,HID0_SPD
 	andc	r11,r11,r3		/* clear SPD: enable speculative */
  	li	r3,0
@@ -1356,7 +1358,9 @@
 	/* All of the bits we have to set.....
 	*/
 	ori	r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE | HID0_BTIC | HID0_LRSTK
+BEGIN_FTR_SECTION
 	oris	r11,r11,HID0_DPM@h	/* enable dynamic power mgmt */
+END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
 
 	/* All of the bits we have to clear....
 	*/
diff -Nru a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
--- a/arch/ppc/kernel/misc.S	Mon Dec  9 18:46:51 2002
+++ b/arch/ppc/kernel/misc.S	Mon Dec  9 18:46:51 2002
@@ -1056,7 +1056,7 @@
 	.data
 	.align 4
 _GLOBAL(sys_call_table)
-	.long sys_ni_syscall	/* 0  -  old "setup()" system call */
+	.long sys_restart_syscall /* 0 */
 	.long sys_exit
 	.long ppc_fork
 	.long sys_read
diff -Nru a/arch/ppc/kernel/module.c b/arch/ppc/kernel/module.c
--- a/arch/ppc/kernel/module.c	Mon Dec  9 18:46:35 2002
+++ b/arch/ppc/kernel/module.c	Mon Dec  9 18:46:35 2002
@@ -21,6 +21,7 @@
 #include <linux/fs.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
+#include <linux/cache.h>
 
 #if 0
 #define DEBUGP printk
@@ -105,8 +106,9 @@
 		      const char *secstrings,
 		      struct module *module)
 {
-	module->arch.core_plt_offset = module->core_size;
-	return module->core_size + get_plt_size(hdr, sechdrs, secstrings, 0);
+	module->arch.core_plt_offset = ALIGN(module->core_size, 4);
+	return module->arch.core_plt_offset
+		+ get_plt_size(hdr, sechdrs, secstrings, 0);
 }
 
 long module_init_size(const Elf32_Ehdr *hdr,
@@ -114,8 +116,9 @@
 		      const char *secstrings,
 		      struct module *module)
 {
-	module->arch.init_plt_offset = module->init_size;
-	return module->init_size + get_plt_size(hdr, sechdrs, secstrings, 1);
+	module->arch.init_plt_offset = ALIGN(module->init_size, 4);
+	return module->arch.init_plt_offset
+		+ get_plt_size(hdr, sechdrs, secstrings, 1);
 }
 
 int apply_relocate(Elf32_Shdr *sechdrs,
@@ -142,7 +145,7 @@
 {
 	struct ppc_plt_entry *entry;
 
-	DEBUGP("Doing plt for %u\n", (unsigned int)location);
+	DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
 	/* Init, or core PLT? */
 	if (location >= mod->module_core
 	    && location < mod->module_core + mod->arch.core_plt_offset)
@@ -162,6 +165,7 @@
 	entry->jump[2] = 0x7d6903a6;			/* mtctr r11 */
 	entry->jump[3] = 0x4e800420;			/* bctr */
 
+	DEBUGP("Initialized plt for 0x%x at %p\n", val, entry);
 	return (uint32_t)entry;
 }
 
diff -Nru a/arch/ppc/kernel/ppc6xx_idle.c b/arch/ppc/kernel/ppc6xx_idle.c
--- a/arch/ppc/kernel/ppc6xx_idle.c	Mon Dec  9 18:46:38 2002
+++ b/arch/ppc/kernel/ppc6xx_idle.c	Mon Dec  9 18:46:38 2002
@@ -52,7 +52,10 @@
 	if (!need_resched()) {
 		__asm__ __volatile__("mfspr %0,1008":"=r"(hid0):);
 		hid0 &= ~(HID0_NAP | HID0_SLEEP | HID0_DOZE);
-		hid0 |= (powersave_nap ? HID0_NAP : HID0_DOZE) | HID0_DPM;
+		hid0 |= (powersave_nap ? HID0_NAP : HID0_DOZE);
+		if (!(cur_cpu_spec[smp_processor_id()]->cpu_features
+		      & CPU_FTR_NO_DPM))
+			hid0 |= HID0_DPM;
 		__asm__ __volatile__("mtspr 1008,%0"::"r"(hid0));
 		/* Flush pending data streams, consider this instruction
 		 * exist on all altivec capable CPUs
diff -Nru a/arch/ppc/kernel/ptrace.c b/arch/ppc/kernel/ptrace.c
--- a/arch/ppc/kernel/ptrace.c	Mon Dec  9 18:46:35 2002
+++ b/arch/ppc/kernel/ptrace.c	Mon Dec  9 18:46:35 2002
@@ -166,7 +166,8 @@
 		/* are we already being traced? */
 		if (current->ptrace & PT_PTRACED)
 			goto out;
-		if ((ret = security_ptrace(current->parent, current)))
+		ret = security_ptrace(current->parent, current);
+		if (ret)
 			goto out;
 		/* set the ptrace bit in the process flags. */
 		current->ptrace |= PT_PTRACED;
diff -Nru a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c
--- a/arch/ppc/kernel/signal.c	Mon Dec  9 18:46:51 2002
+++ b/arch/ppc/kernel/signal.c	Mon Dec  9 18:46:51 2002
@@ -393,8 +393,12 @@
 
 	if (TRAP(regs) == 0x0C00 /* System Call! */
 	    && ((int)regs->result == -ERESTARTNOHAND ||
+		(int)regs->result == -ERESTART_RESTARTBLOCK ||
 		((int)regs->result == -ERESTARTSYS &&
 		 !(ka->sa.sa_flags & SA_RESTART)))) {
+		if ((int)regs->result == -ERESTART_RESTARTBLOCK)
+			current_thread_info()->restart_block.fn
+				= do_no_restart_syscall;
 		regs->result = -EINTR;
 		regs->gpr[3] = EINTR;
 		regs->ccr |= 0x10000000;
@@ -494,13 +498,18 @@
 		handle_signal(signr, &info, oldset, regs, &newsp, frame);
 	}
 
-	if (TRAP(regs) == 0x0C00 /* System Call! */ &&
-	    ((int)regs->result == -ERESTARTNOHAND ||
-	     (int)regs->result == -ERESTARTSYS ||
-	     (int)regs->result == -ERESTARTNOINTR)) {
-		regs->gpr[3] = regs->orig_gpr3;
-		regs->nip -= 4;		/* Back up & retry system call */
-		regs->result = 0;
+	if (TRAP(regs) == 0x0C00) {	/* System Call! */
+		if ((int)regs->result == -ERESTARTNOHAND ||
+		    (int)regs->result == -ERESTARTSYS ||
+		    (int)regs->result == -ERESTARTNOINTR) {
+			regs->gpr[3] = regs->orig_gpr3;
+			regs->nip -= 4;	/* Back up & retry system call */
+			regs->result = 0;
+		} else if ((int)regs->result == -ERESTART_RESTARTBLOCK) {
+			regs->gpr[0] = __NR_restart_syscall;
+			regs->nip -= 4;
+			regs->result = 0;
+		}
 	}
 
 	if (newsp == frame)
diff -Nru a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
--- a/arch/ppc/kernel/smp.c	Mon Dec  9 18:46:51 2002
+++ b/arch/ppc/kernel/smp.c	Mon Dec  9 18:46:51 2002
@@ -389,7 +389,7 @@
 	/* create a process for the processor */
 	/* only regs.msr is actually used, and 0 is OK for it */
 	memset(&regs, 0, sizeof(struct pt_regs));
-	p = do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL);
+	p = do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL, NULL);
 	if (IS_ERR(p))
 		panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p));
 
diff -Nru a/arch/ppc/platforms/residual.c b/arch/ppc/platforms/residual.c
--- a/arch/ppc/platforms/residual.c	Mon Dec  9 18:46:35 2002
+++ b/arch/ppc/platforms/residual.c	Mon Dec  9 18:46:35 2002
@@ -898,12 +898,13 @@
 	return n;
 }
 
-void __init
+int __init
 proc_prep_residual_init(void)
 {
 	if (res->ResidualLength)
 		create_proc_read_entry("residual", S_IRUGO, NULL,
 					proc_prep_residual_read, NULL);
+	return 0;
 }
 
 __initcall(proc_prep_residual_init);
diff -Nru a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
--- a/arch/ppc64/Kconfig	Mon Dec  9 18:46:38 2002
+++ b/arch/ppc64/Kconfig	Mon Dec  9 18:46:38 2002
@@ -33,6 +33,14 @@
 	bool
 	default y
 
+config COMPAT
+	bool
+	default y
+
+config FRAME_POINTER
+	bool
+	default y
+
 source "init/Kconfig"
 
 
@@ -63,10 +71,7 @@
 	---help---
 	  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.
+	  than one CPU, say Y.
 
 	  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
@@ -74,16 +79,15 @@
 	  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.
+	  If you don't know what to do here, say Y.
 
 config IRQ_ALL_CPUS
 	bool "Distribute interrupts on all CPUs by default"
-	depends on SMP
+	depends on SMP && PPC_PSERIES
 	help
 	  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.
+	  CPU.
 
 config NR_CPUS
 	int "Maximum number of CPUs (2-64)"
@@ -410,15 +414,8 @@
 
 source "fs/Kconfig"
 
-
-menu "Console drivers"
-	depends on VT
-
 source "drivers/video/Kconfig"
 
-endmenu
-
-
 menu "Sound"
 
 config SOUND
@@ -468,13 +465,24 @@
 
 config VIODASD
 	tristate "iSeries Virtual I/O disk support"
+	help
+	  If you are running on an iSeries system and you want to use
+ 	  virtual disks created and managed by OS/400, say Y.
 
 config VIODASD_IDE
 	bool "iSeries Virtual disk IDE emulation"
 	depends on VIODASD
+	help
+	  This causes the iSeries virtual disks to look like IDE disks.
+	  If you have programs or utilities that only support certain
+	  kinds of disks, this option will cause iSeries virtual disks
+	  to pretend to be IDE disks, which may satisfy the program.
 
 config VIOCD
 	tristate "iSeries Virtual I/O CD support"
+	help
+	  If you are running Linux on an IBM iSeries system and you want to
+	  read a CD drive owned by OS/400, say Y here.
 
 config VIOCD_AZTECH
 	bool "iSeries Virtual CD Aztech emulation"
@@ -482,6 +490,9 @@
 
 config VIOTAPE
 	tristate "iSeries Virtual Tape Support"
+	help
+	  If you are running Linux on an iSeries system and you want Linux
+	  to read and/or write a tape drive owned by OS/400, say Y here.
 
 config VETH
 	tristate "iSeries Virtual Ethernet driver support"
@@ -493,15 +504,23 @@
 	depends on PPC_ISERIES
 	default y
 
+source "arch/ppc64/oprofile/Kconfig"
 
 menu "Kernel hacking"
 
 config DEBUG_KERNEL
 	bool "Kernel debugging"
+	help
+	  Say Y here if you are developing drivers or trying to debug and
+	  identify kernel problems.
 
 config DEBUG_SLAB
 	bool "Debug memory allocations"
 	depends on DEBUG_KERNEL
+	help
+	  Say Y here to have the kernel do limited verification on memory
+	  allocation as well as poisoning memory on free to catch use of freed
+	  memory.
 
 config MAGIC_SYSRQ
 	bool "Magic SysRq key"
diff -Nru a/arch/ppc64/Makefile b/arch/ppc64/Makefile
--- a/arch/ppc64/Makefile	Mon Dec  9 18:46:35 2002
+++ b/arch/ppc64/Makefile	Mon Dec  9 18:46:35 2002
@@ -30,6 +30,9 @@
 core-y			+= arch/ppc64/kernel/ arch/ppc64/mm/ arch/ppc64/lib/
 core-$(CONFIG_XMON)	+= arch/ppc64/xmon/
 
+# FIXME: is drivers- right ?
+drivers-$(CONFIG_OPROFILE)		+= arch/ppc64/oprofile/
+
 makeboot = $(call descend,arch/ppc64/boot,$(1))
 
 ifdef CONFIG_PPC_PSERIES
diff -Nru a/arch/ppc64/defconfig b/arch/ppc64/defconfig
--- a/arch/ppc64/defconfig	Mon Dec  9 18:46:35 2002
+++ b/arch/ppc64/defconfig	Mon Dec  9 18:46:35 2002
@@ -24,9 +24,7 @@
 #
 # Loadable module support
 #
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_KMOD is not set
+# CONFIG_MODULES is not set
 
 #
 # Platform support
@@ -156,7 +154,14 @@
 #
 # Multi-device support (RAID and LVM)
 #
-# CONFIG_MD is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=y
+CONFIG_MD_RAID0=y
+CONFIG_MD_RAID1=y
+CONFIG_MD_RAID5=y
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_DM is not set
 
 #
 # Fusion MPT device support
@@ -195,7 +200,8 @@
 CONFIG_SYN_COOKIES=y
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
-CONFIG_IPV6=m
+# CONFIG_XFRM_USER is not set
+CONFIG_IPV6=y
 
 #
 # SCTP Configuration (EXPERIMENTAL)
@@ -260,6 +266,7 @@
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=y
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
 # CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
 CONFIG_E100=y
@@ -286,6 +293,7 @@
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
@@ -299,9 +307,8 @@
 # CONFIG_NET_RADIO is not set
 
 #
-# Token Ring devices
+# Token Ring devices (depends on LLC=y)
 #
-# CONFIG_TR is not set
 # CONFIG_NET_FC is not set
 # CONFIG_RCPCI is not set
 # CONFIG_SHAPER is not set
@@ -462,7 +469,10 @@
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
-# CONFIG_JFS_FS is not set
+CONFIG_JFS_FS=y
+# CONFIG_JFS_POSIX_ACL is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -501,8 +511,7 @@
 CONFIG_CIFS=y
 # CONFIG_SMB_FS is not set
 # CONFIG_NCP_FS is not set
-CONFIG_AFS_FS=y
-CONFIG_RXRPC=y
+# CONFIG_AFS_FS is not set
 
 #
 # Partition Types
@@ -616,6 +625,12 @@
 # CONFIG_BT is not set
 
 #
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+
+#
 # Kernel hacking
 #
 CONFIG_DEBUG_KERNEL=y
@@ -628,7 +643,7 @@
 #
 # Security options
 #
-CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY is not set
 
 #
 # Cryptographic options
diff -Nru a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
--- a/arch/ppc64/kernel/Makefile	Mon Dec  9 18:46:51 2002
+++ b/arch/ppc64/kernel/Makefile	Mon Dec  9 18:46:51 2002
@@ -35,6 +35,8 @@
 
 obj-$(CONFIG_SMP) += smp.o
 
+obj-$(CONFIG_PROFILING)	+= profile.o
+
 obj-y += prom.o lmb.o rtas.o rtas-proc.o chrp_setup.o i8259.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/arch/ppc64/kernel/binfmt_elf32.c b/arch/ppc64/kernel/binfmt_elf32.c
--- a/arch/ppc64/kernel/binfmt_elf32.c	Mon Dec  9 18:46:34 2002
+++ b/arch/ppc64/kernel/binfmt_elf32.c	Mon Dec  9 18:46:34 2002
@@ -21,11 +21,7 @@
 #include <linux/module.h>
 #include <linux/config.h>
 #include <linux/elfcore.h>
-
-struct timeval32
-{
-	int tv_sec, tv_usec;
-};
+#include <linux/compat.h>
 
 #define elf_prstatus elf_prstatus32
 struct elf_prstatus32
@@ -38,10 +34,10 @@
 	pid_t	pr_ppid;
 	pid_t	pr_pgrp;
 	pid_t	pr_sid;
-	struct timeval32 pr_utime;	/* User time */
-	struct timeval32 pr_stime;	/* System time */
-	struct timeval32 pr_cutime;	/* Cumulative user time */
-	struct timeval32 pr_cstime;	/* Cumulative system time */
+	struct compat_timeval pr_utime;	/* User time */
+	struct compat_timeval pr_stime;	/* System time */
+	struct compat_timeval pr_cutime;	/* Cumulative user time */
+	struct compat_timeval pr_cstime;	/* Cumulative system time */
 	elf_gregset_t pr_reg;		/* General purpose registers. */
 	int pr_fpvalid;		/* True if math co-processor being used. */
 };
@@ -64,9 +60,9 @@
 
 #include <linux/time.h>
 
-#define jiffies_to_timeval jiffies_to_timeval32
+#define jiffies_to_timeval jiffies_to_compat_timeval
 static __inline__ void
-jiffies_to_timeval32(unsigned long jiffies, struct timeval32 *value)
+jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
 {
 	value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
 	value->tv_sec = jiffies / HZ;
diff -Nru a/arch/ppc64/kernel/chrp_setup.c b/arch/ppc64/kernel/chrp_setup.c
--- a/arch/ppc64/kernel/chrp_setup.c	Mon Dec  9 18:46:34 2002
+++ b/arch/ppc64/kernel/chrp_setup.c	Mon Dec  9 18:46:34 2002
@@ -66,7 +66,6 @@
 extern volatile unsigned char *chrp_int_ack_special;
 
 void chrp_progress(char *, unsigned short);
-void chrp_request_regions(void);
 
 extern void openpic_init_IRQ(void);
 extern void init_ras_IRQ(void);
@@ -141,11 +140,12 @@
 
 	fwnmi_init();
 
+#ifndef CONFIG_PPC_ISERIES
 	/* Find and initialize PCI host bridges */
 	/* iSeries needs to be done much later. */
- 	#ifndef CONFIG_PPC_ISERIES
-		find_and_init_phbs();
- 	#endif
+	eeh_init();
+	find_and_init_phbs();
+#endif
 
 	/* Find the Open PIC if present */
 	root = find_path_device("/");
@@ -169,11 +169,6 @@
 void __init
 chrp_init2(void)
 {
-	/*
-	 * It is sensitive, when this is called (not too earlu)
-	 * -- tibit
-	 */
-	chrp_request_regions();
 	/* Manually leave the kernel version on the panel. */
 	ppc_md.progress("Linux ppc64\n", 0);
 	ppc_md.progress(UTS_RELEASE, 0);
diff -Nru a/arch/ppc64/kernel/eeh.c b/arch/ppc64/kernel/eeh.c
--- a/arch/ppc64/kernel/eeh.c	Mon Dec  9 18:46:50 2002
+++ b/arch/ppc64/kernel/eeh.c	Mon Dec  9 18:46:50 2002
@@ -43,25 +43,25 @@
 static int ibm_set_slot_reset;
 static int ibm_read_slot_reset_state;
 
-int eeh_implemented;
+static int eeh_implemented;
 #define EEH_MAX_OPTS 4096
 static char *eeh_opts;
 static int eeh_opts_last;
-static int eeh_check_opts_config(struct pci_dev *dev, int default_state);
 
+pte_t *find_linux_pte(pgd_t *pgdir, unsigned long va);	/* from htab.c */
+static int eeh_check_opts_config(struct device_node *dn,
+				 int class_code, int vendor_id, int device_id,
+				 int default_state);
 
-unsigned long eeh_token(unsigned long phb, unsigned long bus, unsigned long devfn, unsigned long offset)
+unsigned long eeh_token_to_phys(unsigned long token)
 {
-	if (phb > 0xff)
-		panic("eeh_token: phb 0x%lx is too large\n", phb);
-	if (offset & 0x0fffffff00000000)
-		panic("eeh_token: offset 0x%lx is out of range\n", offset);
-	return ((IO_UNMAPPED_REGION_ID << 60) | (phb << 48UL) | ((bus & 0xff) << 40UL) | (devfn << 32UL) | (offset & 0xffffffff));
-}
-
-int eeh_get_state(unsigned long ea)
-{
-	return 0;
+	if (REGION_ID(token) == EEH_REGION_ID) {
+		unsigned long vaddr = IO_TOKEN_TO_ADDR(token);
+		pte_t *ptep = find_linux_pte(ioremap_mm.pgd, vaddr);
+		unsigned long pa = pte_pfn(*ptep) << PAGE_SHIFT;
+		return pa | (vaddr & (PAGE_SIZE-1));
+	} else
+		return token;
 }
 
 /* Check for an eeh failure at the given token address.
@@ -73,40 +73,54 @@
  */
 unsigned long eeh_check_failure(void *token, unsigned long val)
 {
-	unsigned long config_addr = (unsigned long)token >> 24;	/* PPBBDDRR */
-	unsigned long phbidx = (config_addr >> 24) & 0xff;
-	struct pci_controller *phb;
+	unsigned long addr;
+	struct pci_dev *dev;
+	struct device_node *dn;
 	unsigned long ret, rets[2];
 
-	config_addr &= 0xffff00;  /* 00BBDD00 */
+	/* IO BAR access could get us here...or if we manually force EEH
+	 * operation on even if the hardware won't support it.
+	 */
+	if (!eeh_implemented || ibm_read_slot_reset_state == RTAS_UNKNOWN_SERVICE)
+		return val;
 
-	if (phbidx >= global_phb_number) {
-		panic("EEH: checking token %p phb index of %ld is greater than max of %d\n", token, phbidx, global_phb_number-1);
+	/* Finding the phys addr + pci device is quite expensive.
+	 * However, the RTAS call is MUCH slower.... :(
+	 */
+	addr = eeh_token_to_phys((unsigned long)token);
+	dev = pci_find_dev_by_addr(addr);
+	if (!dev) {
+		printk("EEH: no pci dev found for addr=0x%lx\n", addr);
+		return val;
 	}
-	phb = phbtab[phbidx];
+	dn = pci_device_to_OF_node(dev);
+	if (!dn) {
+		printk("EEH: no pci dn found for addr=0x%lx\n", addr);
+		return val;
+	}
+
+	/* Access to IO BARs might get this far and still not want checking. */
+	if (!(dn->eeh_mode & EEH_MODE_SUPPORTED) || dn->eeh_mode & EEH_MODE_NOCHECK)
+		return val;
+
 
-	ret = rtas_call(ibm_read_slot_reset_state, 3, 3, rets,
-			config_addr, BUID_HI(phb->buid), BUID_LO(phb->buid));
-	if (ret == 0 && rets[1] == 1 && rets[0] >= 2) {
-		struct pci_dev *dev;
-		int bus = ((unsigned long)token >> 40) & 0xffff; /* include PHB# in bus */
-		int devfn = (config_addr >> 8) & 0xff;
-
-		dev = pci_find_slot(bus, devfn);
-		if (dev) {
-			printk(KERN_ERR "EEH:  MMIO failure (%ld) on device:\n  %s %s\n",
-			      rets[0], dev->slot_name, dev->name);
-			PPCDBG_ENTER_DEBUGGER();
+	/* Now test for an EEH failure.  This is VERY expensive.
+	 * Note that the eeh_config_addr may be a parent device
+	 * in the case of a device behind a bridge, or it may be
+	 * function zero of a multi-function device.
+	 * In any case they must share a common PHB.
+	 */
+	if (dn->eeh_config_addr) {
+		ret = rtas_call(ibm_read_slot_reset_state, 3, 3, rets,
+				dn->eeh_config_addr, BUID_HI(dn->phb->buid), BUID_LO(dn->phb->buid));
+		if (ret == 0 && rets[1] == 1 && rets[0] >= 2) {
 			panic("EEH:  MMIO failure (%ld) on device:\n  %s %s\n",
-			      rets[0], dev->slot_name, dev->name);
-		} else {
-			printk(KERN_ERR "EEH:  MMIO failure (%ld) on device buid %lx, config_addr %lx\n", rets[0], phb->buid, config_addr);
-			PPCDBG_ENTER_DEBUGGER();
-			panic("EEH:  MMIO failure (%ld) on device buid %lx, config_addr %lx\n", rets[0], phb->buid, config_addr);
+			      rets[0], dev->slot_name, dev->dev.name);
 		}
 	}
 	eeh_false_positives++;
 	return val;	/* good case */
+
 }
 
 struct eeh_early_enable_info {
@@ -120,13 +134,69 @@
 {
 	struct eeh_early_enable_info *info = data;
 	long ret;
+	char *status = get_property(dn, "status", 0);
+	u32 *class_code = (u32 *)get_property(dn, "class-code", 0);
+	u32 *vendor_id =(u32 *) get_property(dn, "vendor-id", 0);
+	u32 *device_id = (u32 *)get_property(dn, "device-id", 0);
+	u32 *regs;
+	int enable;
+
+	if (status && strcmp(status, "ok") != 0)
+		return NULL;	/* ignore devices with bad status */
+
+	/* Weed out PHBs or other bad nodes. */
+	if (!class_code || !vendor_id || !device_id)
+		return NULL;
 
-	/* Try to enable eeh */
-	ret = rtas_call(ibm_set_eeh_option, 4, 1, NULL,
-			CONFIG_ADDR(dn->busno, dn->devfn),
-			info->buid_hi, info->buid_lo, EEH_ENABLE);
-	if (ret == 0)
-		info->adapters_enabled++;
+	/* Ignore known PHBs and EADs bridges */
+	if (*vendor_id == PCI_VENDOR_ID_IBM &&
+	    (*device_id == 0x0102 || *device_id == 0x008b ||
+	     *device_id == 0x0188 || *device_id == 0x0302))
+		return NULL;
+
+	/* Now decide if we are going to "Disable" EEH checking
+	 * for this device.  We still run with the EEH hardware active,
+	 * but we won't be checking for ff's.  This means a driver
+	 * could return bad data (very bad!), an interrupt handler could
+	 * hang waiting on status bits that won't change, etc.
+	 * But there are a few cases like display devices that make sense.
+	 */
+	enable = 1;	/* i.e. we will do checking */
+	if ((*class_code >> 16) == PCI_BASE_CLASS_DISPLAY)
+		enable = 0;
+
+	if (!eeh_check_opts_config(dn, *class_code, *vendor_id, *device_id, enable)) {
+		if (enable) {
+			printk(KERN_INFO "EEH: %s user requested to run without EEH.\n", dn->full_name);
+			enable = 0;
+		}
+	}
+
+	if (!enable)
+		dn->eeh_mode = EEH_MODE_NOCHECK;
+
+	/* This device may already have an EEH parent. */
+	if (dn->parent && (dn->parent->eeh_mode & EEH_MODE_SUPPORTED)) {
+		/* Parent supports EEH. */
+		dn->eeh_mode |= EEH_MODE_SUPPORTED;
+		dn->eeh_config_addr = dn->parent->eeh_config_addr;
+		return NULL;
+	}
+
+	/* Ok..see if this device supports EEH. */
+	regs = (u32 *)get_property(dn, "reg", 0);
+	if (regs) {
+		/* First register entry is addr (00BBSS00)  */
+		/* Try to enable eeh */
+		ret = rtas_call(ibm_set_eeh_option, 4, 1, NULL,
+				regs[0], info->buid_hi, info->buid_lo,
+				EEH_ENABLE);
+		if (ret == 0) {
+			info->adapters_enabled++;
+			dn->eeh_mode |= EEH_MODE_SUPPORTED;
+			dn->eeh_config_addr = regs[0];
+		}
+	}
 	return NULL; 
 }
 
@@ -157,7 +227,13 @@
 	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)
+	/* Allow user to force eeh mode on or off -- even if the hardware
+	 * doesn't exist.  This allows driver writers to at least test use
+	 * of I/O macros even if we can't actually test for EEH failure.
+	 */
+	if (eeh_force_on > eeh_force_off)
+		eeh_implemented = 1;
+	else if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE)
 		return;
 
 	if (eeh_force_off > eeh_force_on) {
@@ -168,8 +244,6 @@
 		return;
 	}
 
-	if (eeh_force_on > eeh_force_off)
-		eeh_implemented = 1;	/* User is forcing it on. */
 
 	/* Enable EEH for all adapters.  Note that eeh requires buid's */
 	info.adapters_enabled = 0;
@@ -197,44 +271,6 @@
 }
 
 
-/* Given a PCI device check if eeh should be configured or not.
- * This may look at firmware properties and/or kernel cmdline options.
- */
-int is_eeh_configured(struct pci_dev *dev)
-{
-	struct device_node *dn = pci_device_to_OF_node(dev);
-	struct pci_controller *phb = PCI_GET_PHB_PTR(dev);
-	unsigned long ret, rets[2];
-	int eeh_capable;
-	int default_state = 1;	/* default enable EEH if we can. */
-
-	if (dn == NULL || phb == NULL || !eeh_implemented)
-		return 0;
-
-	/* Hack: turn off eeh for display class devices by default.
-	 * This fixes matrox accel framebuffer.
-	 */
-	if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
-		default_state = 0;
-
-	/* Ignore known PHBs and EADs bridges */
-	if (dev->vendor == PCI_VENDOR_ID_IBM &&
-	    (dev->device == 0x0102 || dev->device == 0x008b))
-		default_state = 0;
-
-	if (!eeh_check_opts_config(dev, default_state)) {
-		if (default_state)
-			printk(KERN_INFO "EEH: %s %s user requested to run without EEH.\n", dev->slot_name, dev->name);
-		return 0;
-	}
-
-	ret = rtas_call(ibm_read_slot_reset_state, 3, 3, rets,
-			CONFIG_ADDR(dn->busno, dn->devfn),
-			BUID_HI(phb->buid), BUID_LO(phb->buid));
-	eeh_capable = (ret == 0 && rets[1] == 1);
-	return eeh_capable;
-}
-
 int eeh_set_option(struct pci_dev *dev, int option)
 {
 	struct device_node *dn = pci_device_to_OF_node(dev);
@@ -249,6 +285,30 @@
 }
 
 
+/* If EEH is implemented, find the PCI device using given phys addr
+ * and check to see if eeh failure checking is disabled.
+ * Remap the addr (trivially) to the EEH region if not.
+ * For addresses not known to PCI the vaddr is simply returned unchanged.
+ */
+void *eeh_ioremap(unsigned long addr, void *vaddr)
+{
+	struct pci_dev *dev;
+	struct device_node *dn;
+
+	if (!eeh_implemented)
+		return vaddr;
+	dev = pci_find_dev_by_addr(addr);
+	if (!dev)
+		return vaddr;
+	dn = pci_device_to_OF_node(dev);
+	if (!dn)
+		return vaddr;
+	if (dn->eeh_mode & EEH_MODE_NOCHECK)
+		return vaddr;
+
+	return (void *)IO_ADDR_TO_TOKEN(vaddr);
+}
+
 static int eeh_proc_falsepositive_read(char *page, char **start, off_t off,
 			 int count, int *eof, void *data)
 {
@@ -279,28 +339,24 @@
  * This lets the user specify stupid combinations of options,
  * but at least the result should be very predictable.
  */
-static int eeh_check_opts_config(struct pci_dev *dev, int default_state)
+static int eeh_check_opts_config(struct device_node *dn,
+				 int class_code, int vendor_id, int device_id,
+				 int default_state)
 {
-	struct device_node *dn = pci_device_to_OF_node(dev);
-	struct pci_controller *phb = PCI_GET_PHB_PTR(dev);
-	char devname[32], classname[32], phbname[32];
+	char devname[32], classname[32];
 	char *strs[8], *s;
 	int nstrs, i;
 	int ret = default_state;
 
-	if (dn == NULL || phb == NULL)
-		return 0;
 	/* Build list of strings to match */
 	nstrs = 0;
 	s = (char *)get_property(dn, "ibm,loc-code", 0);
 	if (s)
 		strs[nstrs++] = s;
-	sprintf(devname, "dev%04x:%04x", dev->vendor, dev->device);
+	sprintf(devname, "dev%04x:%04x", vendor_id, device_id);
 	strs[nstrs++] = devname;
-	sprintf(classname, "class%04x", dev->class);
+	sprintf(classname, "class%04x", class_code);
 	strs[nstrs++] = classname;
-	sprintf(phbname, "pci@%lx", phb->buid);
-	strs[nstrs++] = phbname;
 	strs[nstrs++] = "";	/* yes, this matches the empty string */
 
 	/* Now see if any string matches the eeh_opts list.
@@ -332,7 +388,6 @@
  *
  *	dev#:#    vendor:device id in hex (e.g. dev1022:2000)
  *	class#    class id in hex (e.g. class0200)
- *	pci@buid  all devices under phb (e.g. pci@fef00000)
  *
  * If no location code is specified all devices are assumed
  * so eeh-off means eeh by default is off.
@@ -340,13 +395,11 @@
 
 /* This is implemented as a null separated list of strings.
  * Each string looks like this:  "+X" or "-X"
- * where X is a loc code, dev, class or pci string (as shown above)
+ * where X is a loc code, vendor:device, class (as shown above)
  * or empty which is used to indicate all.
  *
- * We interpret this option string list during the buswalk
- * so that it will literally behave left-to-right even if
- * some combinations don't make sense.  Give the user exactly
- * what they want! :)
+ * We interpret this option string list so that it will literally
+ * behave left-to-right even if some combinations don't make sense.
  */
 
 static int __init eeh_parm(char *str, int state)
diff -Nru a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S
--- a/arch/ppc64/kernel/entry.S	Mon Dec  9 18:46:34 2002
+++ b/arch/ppc64/kernel/entry.S	Mon Dec  9 18:46:34 2002
@@ -309,9 +309,7 @@
 	blr
 
 _GLOBAL(ret_from_fork)
-#if CONFIG_SMP || CONFIG_PREEMPT
 	bl	.schedule_tail
-#endif
 	clrrdi	r4,r1,THREAD_SHIFT
 	ld	r4,TI_FLAGS(r4)
 	andi.	r4,r4,_TIF_SYSCALL_TRACE
diff -Nru a/arch/ppc64/kernel/htab.c b/arch/ppc64/kernel/htab.c
--- a/arch/ppc64/kernel/htab.c	Mon Dec  9 18:46:38 2002
+++ b/arch/ppc64/kernel/htab.c	Mon Dec  9 18:46:38 2002
@@ -393,7 +393,7 @@
 		mm = &init_mm;
 		vsid = get_kernel_vsid(ea);
 		break;
-	case IO_UNMAPPED_REGION_ID:
+	case EEH_REGION_ID:
 		/*
 		 * Should only be hit if there is an access to MMIO space
 		 * which is protected by EEH.
diff -Nru a/arch/ppc64/kernel/iSeries_pci.c b/arch/ppc64/kernel/iSeries_pci.c
--- a/arch/ppc64/kernel/iSeries_pci.c	Mon Dec  9 18:46:51 2002
+++ b/arch/ppc64/kernel/iSeries_pci.c	Mon Dec  9 18:46:51 2002
@@ -95,10 +95,23 @@
 
 struct pci_dev;
 
-extern struct list_head iSeries_Global_Device_List;
+LIST_HEAD(iSeries_Global_Device_List);
 
 int DeviceCount = 0;
 
+
+/* Counters and control flags. */
+static long   Pci_Io_Read_Count  = 0;
+static long   Pci_Io_Write_Count = 0;
+static long   Pci_Cfg_Read_Count = 0;
+static long   Pci_Cfg_Write_Count= 0;
+static long   Pci_Error_Count    = 0;
+
+static int    Pci_Retry_Max      = 3;	/* Only retry 3 times  */	
+static int    Pci_Error_Flag     = 1;	/* Set Retry Error on. */
+static int    Pci_Trace_Flag     = 0;
+
+
 /**********************************************************************************
  * Log Error infor in Flight Recorder to system Console.
  * Filter out the device not there errors.
@@ -912,17 +925,3 @@
 	//ppc_md.pcibios_write_config_dword = iSeries_Node_write_config_dword;
 }
 
-/************************************************************************/
-/* Set the slot reset line to the state passed in.                      */
-/* This is the platform specific for code for the pci_reset_device      */
-/* function.                                                            */
-/************************************************************************/
-int pci_set_reset(struct pci_dev* PciDev, int State) {
-	struct iSeries_Device_Node* DeviceNode = (struct iSeries_Device_Node*)PciDev->sysdata;
- 	if (DeviceNode == NULL) { 
-		printk("PCI: Pci Reset Failed, Device Node not found for pci_dev %p\n",PciDev);
-		return -1;
-	}
-	DeviceNode->ReturnCode = HvCallPci_setSlotReset(ISERIES_BUS(DeviceNode),0x00,DeviceNode->AgentId,State);
-	return DeviceNode->ReturnCode;
-}
diff -Nru a/arch/ppc64/kernel/ioctl32.c b/arch/ppc64/kernel/ioctl32.c
--- a/arch/ppc64/kernel/ioctl32.c	Mon Dec  9 18:46:52 2002
+++ b/arch/ppc64/kernel/ioctl32.c	Mon Dec  9 18:46:52 2002
@@ -22,6 +22,7 @@
 
 #include <linux/config.h>
 #include <linux/types.h>
+#include <linux/compat.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
@@ -397,14 +398,9 @@
 	return err;
 }
 
-struct timeval32 {
-	int tv_sec;
-	int tv_usec;
-};
-
 static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-	struct timeval32 *up = (struct timeval32 *)arg;
+	struct compat_timeval *up = (struct compat_timeval *)arg;
 	struct timeval ktv;
 	mm_segment_t old_fs = get_fs();
 	int err;
@@ -1424,8 +1420,8 @@
 #define PPPIOCSCOMPRESS32	_IOW('t', 77, struct ppp_option_data32)
 
 struct ppp_idle32 {
-	__kernel_time_t32 xmit_idle;
-	__kernel_time_t32 recv_idle;
+	compat_time_t xmit_idle;
+	compat_time_t recv_idle;
 };
 #define PPPIOCGIDLE32		_IOR('t', 63, struct ppp_idle32)
 
diff -Nru a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c
--- a/arch/ppc64/kernel/mf.c	Mon Dec  9 18:46:50 2002
+++ b/arch/ppc64/kernel/mf.c	Mon Dec  9 18:46:50 2002
@@ -410,7 +410,7 @@
 		mf_powerOff();
 	}
 	else
-		printk( KERN_ALERT "mf.c: init has been successfully notified to proceed with shutdown\n" );
+		printk( KERN_INFO "mf.c: init has been successfully notified to proceed with shutdown\n" );
 
 	return rc;
 }
@@ -436,7 +436,7 @@
 		case 0x5B:	/* power control notification */
 			if ( (event->xUnion.xCEMsgData.xCEMsg[5]&0x20) != 0 )
 			{
-				printk( KERN_ALERT "mf.c: Commencing partition shutdown\n" );
+				printk( KERN_INFO "mf.c: Commencing partition shutdown\n" );
 				if ( shutdown() == 0 )
 					signalCEMsg( "\x00\x00\x00\xDB\x00\x00\x00\x00\x00\x00\x00\x00", NULL );
 			}
@@ -479,7 +479,7 @@
 			signalEvent( NULL );
 		break;
 	case 1:	/* IT sys shutdown */
-		printk( KERN_ALERT "mf.c: Commencing system shutdown\n" );
+		printk( KERN_INFO "mf.c: Commencing system shutdown\n" );
 		shutdown();
 		break;
 	}
@@ -666,7 +666,7 @@
  */
 void mf_powerOff( void )
 {
-	printk( KERN_ALERT "mf.c: Down it goes...\n" );
+	printk( KERN_INFO "mf.c: Down it goes...\n" );
 	signalCEMsg( "\x00\x00\x00\x4D\x00\x00\x00\x00\x00\x00\x00\x00", NULL );
 	for (;;);
 }
@@ -677,7 +677,7 @@
  */
 void mf_reboot( void )
 {
-	printk( KERN_ALERT "mf.c: Preparing to bounce...\n" );
+	printk( KERN_INFO "mf.c: Preparing to bounce...\n" );
 	signalCEMsg( "\x00\x00\x00\x4E\x00\x00\x00\x00\x00\x00\x00\x00", NULL );
 	for (;;);
 }
diff -Nru a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
--- a/arch/ppc64/kernel/misc.S	Mon Dec  9 18:46:51 2002
+++ b/arch/ppc64/kernel/misc.S	Mon Dec  9 18:46:51 2002
@@ -485,8 +485,10 @@
 _GLOBAL(kernel_thread)
 	/* XXX fix this when we optimise syscall entry to not save volatiles */
 	mr	r6,r3		/* function */
+	mr	r7,r4		/* arg */
 	ori	r3,r5,CLONE_VM	/* flags */
 	oris	r3,r3,(CLONE_UNTRACED>>16)
+	li	r4,0		/* new sp (unused) */
 	li	r0,__NR_clone
 	sc
 	cmpi	0,r3,0		/* parent or child? */
@@ -496,7 +498,7 @@
 	ld	r2,8(r6)
 	ld	r6,0(r6)
 	mtlr	r6              /* fn addr in lr */
-	mr	r3,r4	        /* load arg and call fn */
+	mr	r3,r7	        /* load arg and call fn */
 	blrl
 	li	r0,__NR_exit	/* exit after child exits */
         li	r3,0
@@ -506,7 +508,7 @@
 /* Why isn't this a) automatic, b) written in 'C'? */	
 	.balign 8
 _GLOBAL(sys_call_table32)
-	.llong .sys_ni_syscall		/* 0 - old setup syscall */
+	.llong .sys_restart_syscall	/* 0 */
 	.llong .sys_exit
 	.llong .sys_fork
 	.llong .sys_read
@@ -536,7 +538,7 @@
 	.llong .sys_alarm
 	.llong .sys_ni_syscall		/* old fstat syscall */
 	.llong .sys32_pause
-	.llong .sys32_utime		/* 30 */
+	.llong .compat_sys_utime		/* 30 */
 	.llong .sys_ni_syscall		/* old stty syscall */
 	.llong .sys_ni_syscall		/* old gtty syscall */
 	.llong .sys32_access
@@ -610,8 +612,8 @@
 	.llong .sys_ioperm
 	.llong .sys32_socketcall
 	.llong .sys32_syslog
-	.llong .sys32_setitimer
-	.llong .sys32_getitimer		/* 105 */
+	.llong .compat_sys_setitimer
+	.llong .compat_sys_getitimer		/* 105 */
 	.llong .sys32_newstat
 	.llong .sys32_newlstat
 	.llong .sys32_newfstat
@@ -633,10 +635,10 @@
 	.llong .sys32_adjtimex
 	.llong .sys_mprotect		/* 125 */
 	.llong .sys32_sigprocmask
-	.llong .sys32_create_module
+	.llong .sys_ni_syscall		/* old create_module syscall */
 	.llong .sys32_init_module
 	.llong .sys32_delete_module
-	.llong .sys32_get_kernel_syms	/* 130 */
+	.llong .sys_ni_syscall		/* 130 old get_kernel_syms syscall */
 	.llong .sys_quotactl
 	.llong .sys32_getpgid
 	.llong .sys_fchdir
@@ -668,11 +670,11 @@
 	.llong .sys32_sched_get_priority_max
 	.llong .sys32_sched_get_priority_min  /* 160 */
 	.llong .sys32_sched_rr_get_interval
-	.llong .sys32_nanosleep
+	.llong .compat_sys_nanosleep
 	.llong .sys32_mremap
 	.llong .sys_setresuid
 	.llong .sys_getresuid	        /* 165 */
-	.llong .sys32_query_module
+	.llong .sys_ni_syscall		/* old query_module syscall */
 	.llong .sys_poll
 	.llong .sys32_nfsservctl
 	.llong .sys_setresgid
@@ -741,15 +743,20 @@
 	.llong .sys_ni_syscall		/* reserved for alloc_hugepages */
 	.llong .sys_ni_syscall		/* reserved for free_hugepages */
 	.llong .sys_exit_group
+	.llong .sys32_lookup_dcookie	/* 245 */
+	.llong .sys_epoll_create
+	.llong .sys_epoll_ctl
+	.llong .sys_epoll_wait
+	.llong .ppc32_remap_file_pages
 
-	.rept NR_syscalls-234
+	.rept NR_syscalls-239
 		.llong .sys_ni_syscall
 	.endr
 #endif
 
 	.balign 8
 _GLOBAL(sys_call_table)
-	.llong .sys_ni_syscall		/* 0 - old setup syscall */
+	.llong .sys_restart_syscall	/* 0 */
 	.llong .sys_exit
 	.llong .sys_fork
 	.llong .sys_read
@@ -876,10 +883,10 @@
 	.llong .sys_adjtimex
 	.llong .sys_mprotect		/* 125 */
 	.llong .sys_sigprocmask
-	.llong .sys_create_module
+	.llong .sys_ni_syscall		/* old create_module syscall */
 	.llong .sys_init_module
 	.llong .sys_delete_module
-	.llong .sys_get_kernel_syms	/* 130 */
+	.llong .sys_ni_syscall		/* 130 old get_kernel_syms syscall */
 	.llong .sys_quotactl
 	.llong .sys_getpgid
 	.llong .sys_fchdir
@@ -915,7 +922,7 @@
 	.llong .sys_mremap
 	.llong .sys_setresuid
 	.llong .sys_getresuid	        /* 165 */
-	.llong .sys_query_module
+	.llong .sys_ni_syscall		/* old query_module syscall */
 	.llong .sys_poll
 	.llong .sys_nfsservctl
 	.llong .sys_setresgid
@@ -984,7 +991,12 @@
 	.llong .sys_ni_syscall		/* reserved for alloc_hugepages */
 	.llong .sys_ni_syscall		/* reserved for free_hugepages */
 	.llong .sys_exit_group
+	.llong .sys_lookup_dcookie	/* 245 */
+	.llong .sys_epoll_create
+	.llong .sys_epoll_ctl
+	.llong .sys_epoll_wait
+	.llong .sys_remap_file_pages
 
-	.rept NR_syscalls-234
+	.rept NR_syscalls-239
 		.llong .sys_ni_syscall
 	.endr
diff -Nru a/arch/ppc64/kernel/open_pic.c b/arch/ppc64/kernel/open_pic.c
--- a/arch/ppc64/kernel/open_pic.c	Mon Dec  9 18:46:38 2002
+++ b/arch/ppc64/kernel/open_pic.c	Mon Dec  9 18:46:38 2002
@@ -11,9 +11,10 @@
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/irq.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
 #include <asm/ptrace.h>
 #include <asm/signal.h>
 #include <asm/io.h>
@@ -114,11 +115,11 @@
 #define check_arg_irq(irq) \
     if (irq < open_pic_irq_offset || irq >= (NumSources+open_pic_irq_offset)){ \
       printk(KERN_ERR "open_pic.c:%d: illegal irq %d\n", __LINE__, irq); \
-      print_backtrace(_get_SP()); }
+      dump_stack(); }
 #define check_arg_cpu(cpu) \
     if (cpu < 0 || cpu >= OPENPIC_MAX_PROCESSORS){ \
 	printk(KERN_ERR "open_pic.c:%d: illegal cpu %d\n", __LINE__, cpu); \
-	print_backtrace(_get_SP()); }
+	dump_stack(); }
 #else
 #define check_arg_ipi(ipi)	do {} while (0)
 #define check_arg_timer(timer)	do {} while (0)
diff -Nru a/arch/ppc64/kernel/pSeries_pci.c b/arch/ppc64/kernel/pSeries_pci.c
--- a/arch/ppc64/kernel/pSeries_pci.c	Mon Dec  9 18:46:52 2002
+++ b/arch/ppc64/kernel/pSeries_pci.c	Mon Dec  9 18:46:52 2002
@@ -39,7 +39,6 @@
 #include <asm/ppcdebug.h>
 #include <asm/naca.h>
 #include <asm/pci_dma.h>
-#include <asm/eeh.h>
 
 #include "xics.h"
 #include "open_pic.h"
@@ -50,8 +49,6 @@
  *******************************************************************/
 struct pci_controller *alloc_phb(struct device_node *dev, char *model,
 				 unsigned int addr_size_words) ;
-static int rtas_fake_read(struct device_node *dn, int offset, int nbytes,
-			  unsigned long *returnval);
 
 /* RTAS tokens */
 static int read_pci_config;
@@ -74,8 +71,6 @@
 	buid = dn->phb->buid;
 	if (buid) {
 		ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, addr, buid >> 32, buid & 0xffffffff, size);
-		if (ret < 0|| (returnval == 0xffffffff))
-			ret = rtas_fake_read(dn, where, size, &returnval);
 	} else {
 		ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size);
 	}
@@ -142,48 +137,6 @@
 	rtas_pci_write_config
 };
 
-/*
- * Handle the case where rtas refuses to do a pci config read.
- * This currently only happens with some PHBs in which case we totally fake
- * out the values (and call it a speedwagaon -- something we could look up
- * in the device tree).
- */
-static int
-rtas_fake_read(struct device_node *dn, int offset, int nbytes, unsigned long *returnval)
-{
-	char *device_type = (char *)get_property(dn, "device_type", 0);
-	u32 *class_code = (u32 *)get_property(dn, "class-code", 0);
-
-	*returnval = ~0;	/* float by default */
-
-	/* udbg_printf("rtas_fake_read dn=%p, offset=0x%02x, nbytes=%d, device_type=%s\n", dn, offset, nbytes, device_type ? device_type : "<none>"); */
-	if (device_type && strcmp(device_type, "pci") != 0)
-		return -3;	/* Not a phb or bridge */
-
-	/* NOTE: class_code != NULL => EADS pci bridge.  Else a PHB */
-	if (nbytes == 1) {
-		if (offset == PCI_HEADER_TYPE)
-			*returnval = 0x80;	/* multifunction */
-		else if (offset == PCI_INTERRUPT_PIN || offset == PCI_INTERRUPT_LINE)
-			*returnval = 0;
-	} else if (nbytes == 2) {
-		if (offset == PCI_SUBSYSTEM_VENDOR_ID || offset == PCI_SUBSYSTEM_ID)
-			*returnval = 0;
-		else if (offset == PCI_COMMAND)
-			*returnval = PCI_COMMAND_PARITY|PCI_COMMAND_MASTER|PCI_COMMAND_MEMORY;
-	} else if (nbytes == 4) {
-		if (offset == PCI_VENDOR_ID)
-			*returnval = 0x1014 | ((class_code ? 0x8b : 0x102) << 16); /* a phb */
-		else if (offset == PCI_REVISION_ID)
-			*returnval = (class_code ? PCI_CLASS_BRIDGE_PCI : PCI_CLASS_BRIDGE_HOST) << 16; /* revs are zero */
-		else if ((offset >= PCI_BASE_ADDRESS_0 && offset <= PCI_BASE_ADDRESS_5) || offset == PCI_ROM_ADDRESS)
-			*returnval = 0;
-	}
-
-	/* printk("fake: %s nbytes=%d, offset=%lx ret=%lx\n", class_code ? "EADS" : "PHB", nbytes, offset, *returnval); */
-	return 0;
-}
-
 /******************************************************************
  * pci_read_irq_line
  *
@@ -250,8 +203,6 @@
 	ibm_read_pci_config = rtas_token("ibm,read-pci-config");
 	ibm_write_pci_config = rtas_token("ibm,write-pci-config");
 
-	eeh_init();
-
 	if (naca->interrupt_controller == IC_OPEN_PIC) {
 		opprop = (unsigned int *)get_property(find_path_device("/"),
 				"platform-open-pic", NULL);
@@ -350,24 +301,15 @@
 				res = &phb->io_resource;
 				res->name = Pci_Node->full_name;
 				res->flags = IORESOURCE_IO;
-				if (is_eeh_implemented()) {
-					if (!isa_io_base && has_isa) {
-						/* map a page for ISA ports.  Not EEH protected. */
-						isa_io_base = (unsigned long)__ioremap(phb->io_base_phys, PAGE_SIZE, _PAGE_NO_CACHE);
-					}
-					res->start = phb->io_base_virt = eeh_token(index, 0, 0, 0);
-					res->end = eeh_token(index, 0xff, 0xff, 0xffffffff);
-				} else {
-					phb->io_base_virt = ioremap(phb->io_base_phys, range.size);
-					if (!pci_io_base) {
-						pci_io_base = (unsigned long)phb->io_base_virt;
-						if (has_isa)
-							isa_io_base = pci_io_base;
-					}
-					res->start = ((((unsigned long) range.child_addr.a_mid) << 32) | (range.child_addr.a_lo));
-					res->start += (unsigned long)phb->io_base_virt;
-					res->end =   res->start + range.size - 1;
+				phb->io_base_virt = __ioremap(phb->io_base_phys, range.size, _PAGE_NO_CACHE);
+				if (!pci_io_base) {
+					pci_io_base = (unsigned long)phb->io_base_virt;
+					if (has_isa)
+						isa_io_base = pci_io_base;
 				}
+				res->start = ((((unsigned long) range.child_addr.a_mid) << 32) | (range.child_addr.a_lo));
+				res->start += (unsigned long)phb->io_base_virt - pci_io_base;
+				res->end =   res->start + range.size - 1;
 				res->parent = NULL;
 				res->sibling = NULL;
 				res->child = NULL;
@@ -391,13 +333,8 @@
 					++memno;
 					res->name = Pci_Node->full_name;
 					res->flags = IORESOURCE_MEM;
-					if (is_eeh_implemented()) {
-						res->start = eeh_token(index, 0, 0, 0);
-						res->end =   eeh_token(index, 0xff, 0xff, 0xffffffff);
-					} else {
-						res->start = range.parent_addr;
-						res->end =   range.parent_addr + range.size - 1;
-					}
+					res->start = range.parent_addr;
+					res->end =   range.parent_addr + range.size - 1;
 					res->parent = NULL;
 					res->sibling = NULL;
 					res->child = NULL;
@@ -574,7 +511,6 @@
  	int i;
  	struct pci_controller *phb = PCI_GET_PHB_PTR(dev);
 	struct device_node *dn;
-	unsigned long eeh_disable_bit;
 
 	/* Add IBM loc code (slot) as a prefix to the device names for service */
 	dn = pci_device_to_OF_node(dev);
@@ -582,35 +518,21 @@
 		char *loc_code = get_property(dn, "ibm,loc-code", 0);
 		if (loc_code) {
 			int loc_len = strlen(loc_code);
-			if (loc_len < sizeof(dev->name)) {
-				memmove(dev->name+loc_len+1, dev->name, sizeof(dev->name)-loc_len-1);
-				memcpy(dev->name, loc_code, loc_len);
-				dev->name[loc_len] = ' ';
-				dev->name[sizeof(dev->name)-1] = '\0';
+			if (loc_len < sizeof(dev->dev.name)) {
+				memmove(dev->dev.name+loc_len+1, dev->dev.name, sizeof(dev->dev.name)-loc_len-1);
+				memcpy(dev->dev.name, loc_code, loc_len);
+				dev->dev.name[loc_len] = ' ';
+				dev->dev.name[sizeof(dev->dev.name)-1] = '\0';
 			}
 		}
 	}
 
-	if (is_eeh_implemented()) {
-		if (is_eeh_configured(dev)) {
-			eeh_disable_bit = 0;
-			if (eeh_set_option(dev, EEH_ENABLE) != 0) {
-				printk("PCI: failed to enable EEH for %s %s\n", dev->slot_name, dev->name);
-				eeh_disable_bit = EEH_TOKEN_DISABLED;
-			}
-		} else {
-			/* Assume device is by default EEH_DISABLE'd */
-			printk("PCI: eeh NOT configured for %s %s\n", dev->slot_name, dev->name);
-			eeh_disable_bit = EEH_TOKEN_DISABLED;
-		}
-	}
-
 	PPCDBG(PPCDBG_PHBINIT, "fixup_resources:\n"); 
 	PPCDBG(PPCDBG_PHBINIT, "\tphb                 = 0x%016LX\n", phb); 
 	PPCDBG(PPCDBG_PHBINIT, "\tphb->pci_io_offset  = 0x%016LX\n", phb->pci_io_offset); 
 	PPCDBG(PPCDBG_PHBINIT, "\tphb->pci_mem_offset = 0x%016LX\n", phb->pci_mem_offset); 
 
-	PPCDBG(PPCDBG_PHBINIT, "\tdev->name   = %s\n", dev->name);
+	PPCDBG(PPCDBG_PHBINIT, "\tdev->dev.name   = %s\n", dev->dev.name);
 	PPCDBG(PPCDBG_PHBINIT, "\tdev->vendor:device = 0x%04X : 0x%04X\n", dev->vendor, dev->device);
 
 	if (phb == NULL)
@@ -633,19 +555,9 @@
 		}
 
 		if (dev->resource[i].flags & IORESOURCE_IO) {
-			if (is_eeh_implemented()) {
-				unsigned int busno = dev->bus ? dev->bus->number : 0;
-				unsigned long size = dev->resource[i].end - dev->resource[i].start;
-				unsigned long addr = (unsigned long)__ioremap(dev->resource[i].start + phb->io_base_phys, size, _PAGE_NO_CACHE);
-				if (!addr)
-					panic("fixup_resources: ioremap failed!\n");
-				dev->resource[i].start = eeh_token(phb->global_number, busno, dev->devfn, addr) | eeh_disable_bit;
-				dev->resource[i].end = dev->resource[i].start + size;
-			} else {
-				unsigned long offset = (unsigned long)phb->io_base_virt;
-				dev->resource[i].start += offset;
-				dev->resource[i].end += offset;
-			}
+			unsigned long offset = (unsigned long)phb->io_base_virt - pci_io_base;
+			dev->resource[i].start += offset;
+			dev->resource[i].end += offset;
 			PPCDBG(PPCDBG_PHBINIT, "\t\t-> now [%lx .. %lx]\n",
 			       dev->resource[i].start, dev->resource[i].end);
 		} else if (dev->resource[i].flags & IORESOURCE_MEM) {
@@ -653,18 +565,8 @@
 				/* Bogus.  Probably an unused bridge. */
 				dev->resource[i].end = 0;
 			} else {
-				if (is_eeh_implemented()) {
-					unsigned int busno = dev->bus ? dev->bus->number : 0;
-					unsigned long size = dev->resource[i].end - dev->resource[i].start;
-					unsigned long addr = (unsigned long)__ioremap(dev->resource[i].start + phb->pci_mem_offset, size, _PAGE_NO_CACHE);
-					if (!addr)
-						panic("fixup_resources: ioremap failed!\n");
-					dev->resource[i].start = eeh_token(phb->global_number, busno, dev->devfn, addr) | eeh_disable_bit;
-					dev->resource[i].end = dev->resource[i].start + size;
-				} else {
-					dev->resource[i].start += phb->pci_mem_offset;
-					dev->resource[i].end += phb->pci_mem_offset;
-				}
+				dev->resource[i].start += phb->pci_mem_offset;
+				dev->resource[i].end += phb->pci_mem_offset;
 			}
 			PPCDBG(PPCDBG_PHBINIT, "\t\t-> now [%lx..%lx]\n",
 			       dev->resource[i].start, dev->resource[i].end);
@@ -699,7 +601,6 @@
 	struct pci_dev *dev;
 
 	PPCDBG(PPCDBG_PHBINIT, "pSeries_pcibios_fixup: start\n");
-	pci_assign_all_busses = 0;
 
 	check_s7a();
 	
@@ -742,12 +643,6 @@
 void 
 pSeries_pcibios_init(void)
 {
-	PPCDBG(PPCDBG_PHBINIT, "\tppc64_pcibios_init Entry.\n"); 
-
-	if (get_property(find_path_device("/rtas"),"ibm,fw-phb-id",NULL) != NULL) {
-		PPCDBG(PPCDBG_PHBINIT, "\tFound: ibm,fw-phb-id\n"); 
-		Pci_Large_Bus_System = 1;
-	}
 }
 
 /*
@@ -758,26 +653,4 @@
 {
 	ppc_md.pcibios_read_config = rtas_read_config;
 	ppc_md.pcibios_write_config = rtas_write_config;
-}
-/************************************************************************/
-/* Get a char* of the device physical location(U0.3-P1-I8)              */
-/* See the Product Topology in the RS/6000 Architecture.                */
-/************************************************************************/
-int device_Location(struct pci_dev *PciDev, char *BufPtr)
-{
-	struct device_node *DevNode = (struct device_node *)PciDev->sysdata;
-	return sprintf(BufPtr,"PCI: Bus%3d, Device%3d, Vendor %04X, Location %-12s",
-		       PciDev->bus->number,
-		       PCI_SLOT(PciDev->devfn),
-		       PciDev->vendor,
-		       (char*)get_property(DevNode,"ibm,loc-code",0));
-}
-/************************************************************************/
-/* Set the slot reset line to the state passed in.                      */
-/* This is the platform specific for code for the pci_reset_device      */
-/* function.                                                            */
-/************************************************************************/
-int pci_set_reset(struct pci_dev *PciDev, int state)
-{
-	return -1;
 }
diff -Nru a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
--- a/arch/ppc64/kernel/pci.c	Mon Dec  9 18:46:51 2002
+++ b/arch/ppc64/kernel/pci.c	Mon Dec  9 18:46:51 2002
@@ -1,6 +1,6 @@
 /*
  * Port for PPC64 David Engebretsen, IBM Corp.
- *   Contains common pci routines for ppc64 platform, pSeries and iSeries brands. 
+ * Contains common pci routines for ppc64 platform, pSeries and iSeries brands.
  * 
  *      This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -31,7 +31,6 @@
 #include <asm/naca.h>
 #include <asm/pci_dma.h>
 #include <asm/machdep.h>
-#include <asm/eeh.h>
 
 #include "pci.h"
 
@@ -43,50 +42,21 @@
  */
 unsigned long isa_io_base     = 0;	/* NULL if no ISA bus */
 unsigned long pci_io_base     = 0;
-unsigned long isa_mem_base    = 0;
-unsigned long pci_dram_offset = 0;
 
-/******************************************************************
- * Forward declare of prototypes
- ******************************************************************/
 static void pcibios_fixup_resources(struct pci_dev* dev);
 static void fixup_broken_pcnet32(struct pci_dev* dev);
 static void fixup_windbond_82c105(struct pci_dev* dev);
-void        fixup_resources(struct pci_dev* dev);
+void fixup_resources(struct pci_dev* dev);
 
 void   iSeries_pcibios_init(void);
 void   pSeries_pcibios_init(void);
 
-int    pci_assign_all_busses = 0;
 struct pci_controller* hose_head;
 struct pci_controller** hose_tail = &hose_head;
 
-LIST_HEAD(iSeries_Global_Device_List);
-
-/*******************************************************************
- * Counters and control flags. 
- *******************************************************************/
-long   Pci_Io_Read_Count  = 0;
-long   Pci_Io_Write_Count = 0;
-long   Pci_Cfg_Read_Count = 0;
-long   Pci_Cfg_Write_Count= 0;
-long   Pci_Error_Count    = 0;
-
-int    Pci_Retry_Max      = 3;	/* Only retry 3 times  */	
-int    Pci_Error_Flag     = 1;	/* Set Retry Error on. */
-int    Pci_Trace_Flag     = 0;
-
-/******************************************************************
- * 
- ******************************************************************/
 int  global_phb_number    = 0;           /* Global phb counter    */
-int  Pci_Large_Bus_System = 0;
-int  Pci_Set_IOA_Address  = 0;
-int  Pci_Manage_Phb_Space = 0;
 struct pci_controller *phbtab[PCI_MAX_PHB];
 
-static int pci_bus_count;
-
 /* Cached ISA bridge dev. */
 struct pci_dev *ppc64_isabridge_dev = NULL;
 
@@ -121,6 +91,43 @@
 }
 
 
+/* Given an mmio phys address, find a pci device that implements
+ * this address.  This is of course expensive, but only used
+ * for device initialization or error paths.
+ * For io BARs it is assumed the pci_io_base has already been added
+ * into addr.
+ *
+ * Bridges are ignored although they could be used to optimize the search.
+ */
+struct pci_dev *pci_find_dev_by_addr(unsigned long addr)
+{
+	struct pci_dev *dev;
+	int i;
+	unsigned long ioaddr;
+
+	ioaddr = (addr > isa_io_base) ? addr - isa_io_base : 0;
+
+	pci_for_each_dev(dev) {
+		if ((dev->class >> 8) == PCI_BASE_CLASS_BRIDGE)
+			continue;
+		for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+			unsigned long start = pci_resource_start(dev,i);
+			unsigned long end = pci_resource_end(dev,i);
+			unsigned int flags = pci_resource_flags(dev,i);
+			if (start == 0 || ~start == 0 ||
+			    end == 0 || ~end == 0)
+				continue;
+			if ((flags & IORESOURCE_IO) &&
+			    (ioaddr >= start && ioaddr <= end))
+				return dev;
+			else if ((flags & IORESOURCE_MEM) &&
+				 (addr >= start && addr <= end))
+				return dev;
+		}
+	}
+	return NULL;
+}
+
 void __devinit pcibios_fixup_pbus_ranges(struct pci_bus *pbus,
 					 struct pbus_set_ranges_data *pranges)
 {
@@ -402,10 +409,9 @@
 		bus = pci_scan_bus(hose->first_busno, hose->ops, hose->arch_data);
 		hose->bus = bus;
 		hose->last_busno = bus->subordinate;
-		if (pci_assign_all_busses || next_busno <= hose->last_busno)
+		if (next_busno <= hose->last_busno)
 			next_busno = hose->last_busno+1;
 	}
-	pci_bus_count = next_busno;
 
 	/* Call machine dependant fixup */
 	if (ppc_md.pcibios_fixup) {
@@ -419,6 +425,9 @@
 	pcibios_assign_resources();
 
 #ifndef CONFIG_PPC_ISERIES
+	void chrp_request_regions(void);
+	chrp_request_regions();
+
 	pci_fix_bus_sysdata();
 
 	create_tce_tables();
@@ -439,18 +448,6 @@
 
 subsys_initcall(pcibios_init);
 
-int __init
-pcibios_assign_all_busses(void)
-{
-	return pci_assign_all_busses;
-}
-
-unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
-			     unsigned long start, unsigned long size)
-{
-	return start;
-}
-
 void __init pcibios_fixup_bus(struct pci_bus *bus)
 {
 #ifndef CONFIG_PPC_ISERIES
@@ -486,21 +483,15 @@
 				/* Transparent resource -- don't try to "fix" it. */
 				continue;
 			}
-			if (is_eeh_implemented()) {
-				if (res->flags & (IORESOURCE_IO|IORESOURCE_MEM)) {
-					res->start = eeh_token(phb->global_number, bus->number, 0, 0);
-					res->end = eeh_token(phb->global_number, bus->number, 0xff, 0xffffffff);
-				}
-			} else {
-				if (res->flags & IORESOURCE_IO) {
-					res->start += (unsigned long)phb->io_base_virt;
-					res->end += (unsigned long)phb->io_base_virt;
-				} else if (phb->pci_mem_offset
-					   && (res->flags & IORESOURCE_MEM)) {
-					if (res->start < phb->pci_mem_offset) {
-						res->start += phb->pci_mem_offset;
-						res->end += phb->pci_mem_offset;
-					}
+			if (res->flags & IORESOURCE_IO) {
+				unsigned long offset = (unsigned long)phb->io_base_virt - pci_io_base;
+				res->start += offset;
+				res->end += offset;
+			} else if (phb->pci_mem_offset
+				   && (res->flags & IORESOURCE_MEM)) {
+				if (res->start < phb->pci_mem_offset) {
+					res->start += phb->pci_mem_offset;
+					res->end += phb->pci_mem_offset;
 				}
 			}
 		}
@@ -551,50 +542,6 @@
 	return 0;
 }
 
-struct pci_controller*
-pci_bus_to_hose(int bus)
-{
-	struct pci_controller* hose = hose_head;
-
-	for (; hose; hose = hose->next)
-		if (bus >= hose->first_busno && bus <= hose->last_busno)
-			return hose;
-	return NULL;
-}
-
-void*
-pci_bus_io_base(unsigned int bus)
-{
-	struct pci_controller *hose;
-
-	hose = pci_bus_to_hose(bus);
-	if (!hose)
-		return NULL;
-	return hose->io_base_virt;
-}
-
-unsigned long
-pci_bus_io_base_phys(unsigned int bus)
-{
-	struct pci_controller *hose;
-
-	hose = pci_bus_to_hose(bus);
-	if (!hose)
-		return 0;
-	return hose->io_base_phys;
-}
-
-unsigned long
-pci_bus_mem_base_phys(unsigned int bus)
-{
-	struct pci_controller *hose;
-
-	hose = pci_bus_to_hose(bus);
-	if (!hose)
-		return 0;
-	return hose->pci_mem_offset;
-}
-
 /*
  * Return the index of the PCI controller for device pdev.
  */
@@ -732,123 +679,6 @@
 	return ret;
 }
 
-/************************************************************************/
-/* Formats the device information and location for service.             */
-/* - Pass in pci_dev* pointer to the device.                            */
-/* - Pass in buffer to place the data.  Danger here is the buffer must  */
-/*   be as big as the client says it is.   Should be at least 128 bytes.*/
-/* Return will the length of the string data put in the buffer.         */
-/* The brand specific method device_Location is called.                 */
-/* Format:                                                              */
-/* PCI: Bus  0, Device 26, Vendor 0x12AE  Frame  1, Card  C10  Ethernet */
-/* PCI: Bus  0, Device 26, Vendor 0x12AE  Location U0.3-P1-I8  Ethernet */
-/* For pSeries, see the Product Topology in the RS/6000 Architecture.   */
-/* For iSeries, see the Service Manuals.                                */
-/************************************************************************/
-int  format_device_location(struct pci_dev* PciDev,char* BufPtr, int BufferSize)
-{
-	struct device_node* DevNode = (struct device_node*)PciDev->sysdata;
-	int  LineLen = 0;
-	if (DevNode != NULL && BufferSize >= 128) {
-		LineLen += device_Location(PciDev,BufPtr+LineLen);
-		LineLen += sprintf(BufPtr+LineLen," %12s",pci_class_name(PciDev->class >> 8) );
-	}
-	return LineLen;
-}
-/************************************************************************
- * Saves the config registers for a device.                             *
- ************************************************************************
- * Note: This does byte reads so the data may appear byte swapped,      *
- * The data returned in the pci_config_reg_save_area structure can be   *
- * used to the restore of the data.  If the save failed, the data       *
- * will not be restore.  Yes I know, you are most likey toast.          *
- ************************************************************************/
-int pci_save_config_regs(struct pci_dev* PciDev,struct pci_config_reg_save_area* SaveArea)
-{
-	memset(SaveArea,0x00,sizeof(struct pci_config_reg_save_area) );
-	SaveArea->PciDev    = PciDev;
-	SaveArea->RCode     = 0;
-	SaveArea->Register  = 0;
-	/******************************************************************
-	 * Save All the Regs,  NOTE: restore skips the first 16 bytes.    *
-	 ******************************************************************/
-	while (SaveArea->Register < REG_SAVE_SIZE && SaveArea->RCode == 0) {
-		SaveArea->RCode = pci_read_config_byte(PciDev, SaveArea->Register, &SaveArea->Regs[SaveArea->Register]);
-		++SaveArea->Register;
-	}
-	if (SaveArea->RCode != 0) { 	/* Ouch */
-		SaveArea->Flags = 0x80;	
-		printk("PCI: pci_restore_save_regs failed! %p\n 0x%04X",PciDev,SaveArea->RCode);
-	}
-	else {
-		SaveArea->Flags = 0x01;
-	}
-	return  SaveArea->RCode;
-}
-
-/************************************************************************
- * Restores the registers saved via the save function.  See the save    *
- * function for details.                                                *
- ************************************************************************/
-int pci_restore_config_regs(struct pci_dev* PciDev,struct pci_config_reg_save_area* SaveArea)
-{
- 	if (SaveArea->PciDev != PciDev || SaveArea->Flags == 0x80 || SaveArea->RCode != 0) {
-		printk("PCI: pci_restore_config_regs failed! %p\n",PciDev);
-		return -1;
-	}
-	/******************************************************************
-	 * Don't touch the Cmd or BIST regs, user must restore those.     *
-	 * Restore PCI_VENDOR_ID & PCI_DEVICE_ID                          *
-	 * Restore PCI_CACHE_LINE_SIZE & PCI_LATENCY_TIMER                *
-	 * Restore Saved Regs from 0x10 to 0x3F                           * 
-	 ******************************************************************/
-	SaveArea->Register = 0;
-	while(SaveArea->Register < REG_SAVE_SIZE && SaveArea->RCode == 0) {
-		SaveArea->RCode = pci_write_config_byte(PciDev,SaveArea->Register,SaveArea->Regs[SaveArea->Register]);
-		++SaveArea->Register;
-		if (     SaveArea->Register == PCI_COMMAND)     SaveArea->Register = PCI_CACHE_LINE_SIZE;
-		else if (SaveArea->Register == PCI_HEADER_TYPE) SaveArea->Register = PCI_BASE_ADDRESS_0;
-	}
-	if (SaveArea->RCode != 0) {
-		printk("PCI: pci_restore_config_regs failed! %p\n 0x%04X",PciDev,SaveArea->RCode);
-	}
-	return  SaveArea->RCode;
-}
-
-/************************************************************************/
-/* Interface to toggle the reset line                                   */
-/* Time is in .1 seconds, need for seconds.                             */
-/************************************************************************/
-int  pci_reset_device(struct pci_dev* PciDev, int AssertTime, int DelayTime)
-{
-	unsigned long AssertDelay, WaitDelay;
-	int RtnCode;
-	/********************************************************************
-	 * Set defaults, Assert is .5 second, Wait is 3 seconds.
-	 ********************************************************************/
-	if (AssertTime == 0) AssertDelay = ( 5 * HZ)/10;
-	else                 AssertDelay = (AssertTime*HZ)/10;
-	if (WaitDelay == 0)  WaitDelay   = (30 * HZ)/10;
-	else                 WaitDelay   = (DelayTime* HZ)/10;
-
-	/********************************************************************
-	 * Assert reset, wait, de-assert reset, wait for IOA to reset.
-	 * - Don't waste the CPU time on jiffies.
-	 ********************************************************************/
-	RtnCode = pci_set_reset(PciDev,1);
-	if (RtnCode == 0) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(AssertDelay);   /* Sleep for the time     */
-		RtnCode = pci_set_reset(PciDev,0);
-		set_current_state(TASK_UNINTERRUPTIBLE);  
-		schedule_timeout(WaitDelay);
-	}
-	if (RtnCode != 0) {
-		printk("PCI: Bus%3d, Device%3d, Reset Failed:0x%04X\n",PciDev->bus->number,PCI_SLOT(PciDev->devfn),RtnCode );
-	}
-	return RtnCode;
-}
-
 /*****************************************************
  * Dump Resource information
  *****************************************************/
@@ -939,7 +769,7 @@
 	int i;
 	udbg_printf("\tpci_dev*        = 0x%p\n",Pci_Dev);
 	if ( Pci_Dev == NULL )  return;
-	udbg_printf("\tname            = %s  \n",Pci_Dev->name);
+	udbg_printf("\tname            = %s  \n",Pci_Dev->dev.name);
 	udbg_printf("\tbus*            = 0x%p\n",Pci_Dev->bus);
 	udbg_printf("\tsysdata*        = 0x%p\n",Pci_Dev->sysdata);
 	udbg_printf("\tDevice          = 0x%4X%02X:%02X.%02X 0x%04X:%04X\n",
diff -Nru a/arch/ppc64/kernel/pci.h b/arch/ppc64/kernel/pci.h
--- a/arch/ppc64/kernel/pci.h	Mon Dec  9 18:46:34 2002
+++ b/arch/ppc64/kernel/pci.h	Mon Dec  9 18:46:34 2002
@@ -13,16 +13,6 @@
 #include <asm/pci-bridge.h>
 
 extern unsigned long isa_io_base;
-extern unsigned long isa_mem_base;
-extern unsigned long pci_dram_offset;
-
-/*******************************************************************
- * Platform independant variables referenced.
- *******************************************************************
- * Set pci_assign_all_busses to 1 if you want the kernel to re-assign
- * all PCI bus numbers.  
- *******************************************************************/
-extern int pci_assign_all_busses;
 
 extern struct pci_controller* pci_alloc_pci_controller(char *model, enum phb_types controller_type);
 extern struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node);
@@ -39,13 +29,8 @@
  *******************************************************************/
 extern unsigned long find_and_init_phbs(void);
 
-extern void   fixup_resources(struct pci_dev *dev);
 extern void   ppc64_pcibios_init(void);
 
-extern int    pci_set_reset(struct pci_dev*,int);
-extern int    device_Location(struct pci_dev*,char*);
-extern int    format_device_location(struct pci_dev*,char*, int );
-
 extern struct pci_dev *ppc64_isabridge_dev;	/* may be NULL if no ISA bus */
 
 /*******************************************************************
@@ -56,6 +41,7 @@
 void *traverse_pci_devices(struct device_node *start, traverse_func pre, traverse_func post, void *data);
 void *traverse_all_pci_devices(traverse_func pre);
 
+struct pci_dev *pci_find_dev_by_addr(unsigned long addr);
 void pci_devs_phb_init(void);
 void pci_fix_bus_sysdata(void);
 struct device_node *fetch_dev_dn(struct pci_dev *dev);
@@ -65,12 +51,6 @@
 void pSeries_pcibios_init(void);
 
 /*******************************************************************
- * Platform configuration flags.. (Live in pci.c)
- *******************************************************************/
-extern int  Pci_Large_Bus_System;      /* System has > 256 buses   */
-extern int  Pci_Manage_Phb_Space;      /* Manage Phb Space for IOAs*/
-
-/*******************************************************************
  * Helper macros for extracting data from pci structures.  
  *   PCI_GET_PHB_PTR(struct pci_dev*)    returns the Phb pointer.
  *   PCI_GET_PHB_NUMBER(struct pci_dev*) returns the Phb number.
@@ -87,9 +67,5 @@
 extern void dumpPci_Controller(struct pci_controller* phb);
 extern void dumpPci_Bus(struct pci_bus* Pci_Bus);
 extern void dumpPci_Dev(struct pci_dev* Pci_Dev);
-
-extern void dump_Phb_tree(void);
-extern void dump_Bus_tree(void);
-extern void dump_Dev_tree(void);
 
 #endif /* __PPC_KERNEL_PCI_H__ */
diff -Nru a/arch/ppc64/kernel/pci_dma.c b/arch/ppc64/kernel/pci_dma.c
--- a/arch/ppc64/kernel/pci_dma.c	Mon Dec  9 18:46:38 2002
+++ b/arch/ppc64/kernel/pci_dma.c	Mon Dec  9 18:46:38 2002
@@ -805,6 +805,7 @@
 /***********************************************************************/
 static struct TceTable* findHwTceTable(struct TceTable * newTceTable )
 {
+#ifdef CONFIG_PPC_ISERIES
 	struct list_head* Device_Node_Ptr    = iSeries_Global_Device_List.next;
 	/* Cache the compare values. */
 	u64  startOffset = newTceTable->startOffset;
@@ -825,6 +826,7 @@
 		/* Get next Device Node in List             */
 		Device_Node_Ptr = Device_Node_Ptr->next;
 	}
+#endif
 	return NULL;
 }
 
diff -Nru a/arch/ppc64/kernel/pci_dn.c b/arch/ppc64/kernel/pci_dn.c
--- a/arch/ppc64/kernel/pci_dn.c	Mon Dec  9 18:46:52 2002
+++ b/arch/ppc64/kernel/pci_dn.c	Mon Dec  9 18:46:52 2002
@@ -67,84 +67,6 @@
 	return NULL;
 }
 
-/*
- * Hit all the BARs of all the devices with values from OF.
- * This is unnecessary on most systems, but also harmless.
- */
-static void * __init
-write_OF_bars(struct device_node *dn, void *data)
-{
-	char *name = get_property(dn, "name", 0);
-	char *device_type = get_property(dn, "device_type", 0);
-	char devname[128];
-	sprintf(devname, "%04x:%02x.%x %s (%s)", dn->busno, PCI_SLOT(dn->devfn), PCI_FUNC(dn->devfn), name ? name : "<no name>", device_type ? device_type : "<unknown type>");
-
-	if (device_type && strcmp(device_type, "pci") == 0 &&
-	    get_property(dn, "class-code", 0) == 0)
-		return NULL;	/* This is probably a phb.  Skip it. */
-
-	if (dn->n_addrs == 0)
-		return NULL;	/* This is normal for some adapters or bridges */
-
-	if (dn->addrs == NULL) {
-		/* This shouldn't happen. */
-		printk(KERN_WARNING "write_OF_bars %s: device has %d BARs, but no addrs recorded\n", devname, dn->n_addrs);
-		return NULL;
-	}
-
-#ifndef CONFIG_PPC_ISERIES
-	int i;
-	u32 oldbar, newbar, newbartest;
-	u8 config_offset;
-
-	for (i = 0; i < dn->n_addrs; i++) {
-		newbar = dn->addrs[i].address;
-		config_offset = dn->addrs[i].space & 0xff;
-		if (ppc_md.pcibios_read_config(dn, config_offset, 4, &oldbar) != PCIBIOS_SUCCESSFUL) {
-			printk(KERN_WARNING "write_OF_bars %s: read BAR%d failed\n", devname, i);
-			continue;
-		}
-		/* Need to update this BAR. */
-		if (ppc_md.pcibios_write_config(dn, config_offset, 4, newbar) != PCIBIOS_SUCCESSFUL) {
-			printk(KERN_WARNING "write_OF_bars %s: write BAR%d with 0x%08x failed (old was 0x%08x)\n", devname, i, newbar, oldbar);
-			continue;
-		}
-		/* sanity check */
-		if (ppc_md.pcibios_read_config(dn, config_offset, 4, &newbartest) != PCIBIOS_SUCCESSFUL) {
-			printk(KERN_WARNING "write_OF_bars %s: sanity test read BAR%d failed?\n", devname, i);
-			continue;
-		}
-		if ((newbar & PCI_BASE_ADDRESS_MEM_MASK) != (newbartest & PCI_BASE_ADDRESS_MEM_MASK)) {
-			printk(KERN_WARNING "write_OF_bars %s: oops...BAR%d read back as 0x%08x%s!\n", devname, i, newbartest, (oldbar & PCI_BASE_ADDRESS_MEM_MASK) == (newbartest & PCI_BASE_ADDRESS_MEM_MASK) ? " (original value)" : "");
-			continue;
-		}
-	}
-#endif
-	return NULL; 
-}
-
-#if 0
-/* Traverse_func that starts the BIST (self test) */
-static void * __init
-startBIST(struct device_node *dn, void *data)
-{
-	struct pci_controller *phb = (struct pci_controller *)data;
-	u8 bist;
-
-	char *name = get_property(dn, "name", 0);
-	udbg_printf("startBIST: %s phb=%p, device=%p\n", name ? name : "<unknown>", phb, dn);
-
-	if (ppc_md.pcibios_read_config_byte(dn, PCI_BIST, &bist) == PCIBIOS_SUCCESSFUL) {
-		if (bist & PCI_BIST_CAPABLE) {
-			udbg_printf("  -> is BIST capable!\n", phb, dn);
-			/* Start bist here */
-		}
-	}
-	return NULL;
-}
-#endif
-
-
 /******************************************************************
  * Traverse a device tree stopping each PCI device in the tree.
  * This is done depth first.  As each node is processed, a "pre"
@@ -227,39 +149,6 @@
 	return (devfn == dn->devfn && busno == dn->busno) ? dn : NULL;
 }
 
-/* Same as is_devfn_node except ignore the "fn" part of the "devfn".
- */
-static void *
-is_devfn_sub_node(struct device_node *dn, void *data)
-{
-	int busno = ((unsigned long)data >> 8) & 0xff;
-	int devfn = ((unsigned long)data) & 0xf8;
-	return (devfn == (dn->devfn & 0xf8) && busno == dn->busno) ? dn : NULL;
-}
-
-/* Given an existing EADs (pci bridge) device node create a fake one
- * that will simulate function zero.  Make it a sibling of other_eads.
- */
-static struct device_node *
-create_eads_node(struct device_node *other_eads)
-{
-	struct device_node *eads = (struct device_node *)kmalloc(sizeof(struct device_node), GFP_KERNEL);
-
-	if (!eads) return NULL;	/* huh? */
-	*eads = *other_eads;
-	eads->devfn &= ~7;	/* make it function zero */
-	eads->tce_table = NULL;
-	/*
-	 * NOTE: share properties.  We could copy but for now this should
-	 * suffice.  The full_name is also incorrect...but seems harmless.
-	 */
-	eads->child = NULL;
-	eads->next = NULL;
-	other_eads->allnext = eads;
-	other_eads->sibling = eads;
-	return eads;
-}
-
 /* This is the "slow" path for looking up a device_node from a
  * pci_dev.  It will hunt for the device under it's parent's
  * phb and then update sysdata for a future fastpath.
@@ -285,43 +174,6 @@
 	if (dn) {
 		dev->sysdata = dn;
 		/* ToDo: call some device init hook here */
-	} else {
-		/* Now it is very possible that we can't find the device
-		 * because it is not the zero'th device of a mutifunction
-		 * device and we don't have permission to read the zero'th
-		 * device.  If this is the case, Linux would ordinarily skip
-		 * all the other functions.
-		 */
-		if ((searchval & 0x7) == 0) {
-			struct device_node *thisdevdn;
-			/* Ok, we are looking for fn == 0.  Let's check for other functions. */
-			thisdevdn = (struct device_node *)traverse_pci_devices(phb_dn, is_devfn_sub_node, NULL, (void *)searchval);
-			if (thisdevdn) {
-				/* Ah ha!  There does exist a sub function.
-				 * Now this isn't an exact match for
-				 * searchval, but in order to get Linux to
-				 * believe the sub functions exist we will
-				 * need to manufacture a fake device_node for
-				 * this zero'th function.  To keept this
-				 * simple for now we only handle pci bridges
-				 * and we just hand back the found node which
-				 * isn't correct, but Linux won't care.
-				 */
-				char *device_type = (char *)get_property(thisdevdn, "device_type", 0);
-				if (device_type && strcmp(device_type, "pci") == 0) {
-					return create_eads_node(thisdevdn);
-				}
-			}
-		}
-		/* ToDo: device not found...probe for it anyway with a fake dn?
-		struct device_node fake_dn;
-		memset(&fake_dn, 0, sizeof(fake_dn));
-		fake_dn.phb = phb;
-		fake_dn.busno = dev->bus->number;
-		fake_dn.devfn = dev->devfn;
-		... now do ppc_md.pcibios_read_config_dword(&fake_dn.....)
-		 ... if ok, alloc a real device_node and dn = real_dn;
-		 */
 	}
 	return dn;
 }
@@ -336,14 +188,6 @@
 {
 	/* This must be done first so the device nodes have valid pci info! */
 	traverse_all_pci_devices(update_dn_pci_info);
-
-	/* Hack for regatta which does not init the bars correctly */
-	traverse_all_pci_devices(write_OF_bars);
-#if 0
-	traverse_all_pci_devices(startBIST);
-	mdelay(5000);
-	traverse_all_pci_devices(checkBIST);
-#endif
 }
 
 
diff -Nru a/arch/ppc64/kernel/ppc_ksyms.c b/arch/ppc64/kernel/ppc_ksyms.c
--- a/arch/ppc64/kernel/ppc_ksyms.c	Mon Dec  9 18:46:35 2002
+++ b/arch/ppc64/kernel/ppc_ksyms.c	Mon Dec  9 18:46:35 2002
@@ -78,9 +78,7 @@
 EXPORT_SYMBOL(unregister_ioctl32_conversion);
 
 EXPORT_SYMBOL(isa_io_base);
-EXPORT_SYMBOL(isa_mem_base);
 EXPORT_SYMBOL(pci_io_base);
-EXPORT_SYMBOL(pci_dram_offset);
 
 EXPORT_SYMBOL(find_next_zero_bit);
 
@@ -245,3 +243,8 @@
 #endif
 
 EXPORT_SYMBOL(tb_ticks_per_usec);
+
+#ifdef CONFIG_PROFILING
+EXPORT_SYMBOL_GPL(register_profile_notifier);
+EXPORT_SYMBOL_GPL(unregister_profile_notifier);
+#endif
diff -Nru a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c
--- a/arch/ppc64/kernel/process.c	Mon Dec  9 18:46:38 2002
+++ b/arch/ppc64/kernel/process.c	Mon Dec  9 18:46:38 2002
@@ -103,43 +103,50 @@
 	local_irq_restore(flags);
 }
 
+static void show_tsk_stack(struct task_struct *p, unsigned long sp);
+static char *ppc_find_proc_name(unsigned *p, char *buf, unsigned buflen);
+
 void show_regs(struct pt_regs * regs)
 {
 	int i;
+	char name_buf[256];
 
-	printk("NIP: %016lX XER: %016lX LR: %016lX REGS: %p TRAP: %04lx    %s\n",
-	       regs->nip, regs->xer, regs->link, regs,regs->trap, print_tainted());
+	printk("NIP: %016lX XER: %016lX LR: %016lX\n",
+	       regs->nip, regs->xer, regs->link);
+	printk("REGS: %p TRAP: %04lx    %s\n",
+	       regs, regs->trap, print_tainted());
 	printk("MSR: %016lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
 	       regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
 	       regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
 	       regs->msr&MSR_IR ? 1 : 0,
 	       regs->msr&MSR_DR ? 1 : 0);
+	if (regs->trap == 0x300 || regs->trap == 0x380 || regs->trap == 0x600)
+		printk("DAR: %016lx, DSISR: %016lx\n", regs->dar, regs->dsisr);
 	printk("TASK = %p[%d] '%s' ",
 	       current, current->pid, current->comm);
-	printk("\nlast math %p ", last_task_used_math);
-	
+
 #ifdef CONFIG_SMP
-	/* printk(" CPU: %d last CPU: %d", current->processor,current->last_processor); */
+	printk(" CPU: %d", smp_processor_id());
 #endif /* CONFIG_SMP */
-	
-	printk("\n");
-	for (i = 0;  i < 32;  i++)
-	{
+
+	for (i = 0; i < 32; i++) {
 		long r;
-		if ((i % 4) == 0)
-		{
-			printk("GPR%02d: ", i);
+		if ((i % 4) == 0) {
+			printk("\n" KERN_INFO "GPR%02d: ", i);
 		}
-
-		if ( __get_user(r, &(regs->gpr[i])) )
+		if (__get_user(r, &(regs->gpr[i])))
 		    return;
-
 		printk("%016lX ", r);
-		if ((i % 4) == 3)
-		{
-			printk("\n");
-		}
 	}
+	printk("\n");
+	/*
+	 * Lookup NIP late so we have the best change of getting the
+	 * above info out without failing
+	 */
+	printk("NIP [%016lx] ", regs->nip);
+	printk("%s\n", ppc_find_proc_name((unsigned *)regs->nip,
+	       name_buf, 256));
+	show_tsk_stack(current, regs->gpr[1]);
 }
 
 void exit_thread(void)
@@ -170,7 +177,7 @@
 	extern void ret_from_fork(void);
 	unsigned long sp = (unsigned long)p->thread_info + THREAD_SIZE;
 
-	p->user_tid = NULL;
+	p->set_child_tid = p->clear_child_tid = NULL;
 
 	/* Copy registers */
 	sp -= sizeof(struct pt_regs);
@@ -184,8 +191,10 @@
 #ifdef CONFIG_PPC_ISERIES
 		set_ti_thread_flag(p->thread_info, TIF_RUN_LIGHT);
 #endif
-	} else
+	} else {
+		childregs->gpr[1] = usp;
 		p->thread.regs = childregs;
+	}
 	childregs->gpr[3] = 0;  /* Result from fork() */
 	sp -= STACK_FRAME_OVERHEAD;
 
@@ -259,27 +268,37 @@
 	return put_user(val, (unsigned int *) adr);
 }
 
-int sys_clone(unsigned long clone_flags, u32 p2, u32 p3, u32 p4, u32 p5,
-	      u32 p6, struct pt_regs *regs)
+int sys_clone(unsigned long clone_flags, unsigned long p2, unsigned long p3,
+	      unsigned long p4, unsigned long p5, unsigned long p6,
+	      struct pt_regs *regs)
 {
 	struct task_struct *p;
-	unsigned long tid_ptr = 0;
+	unsigned long parent_tidptr = 0;
+	unsigned long child_tidptr = 0;
 
-	if (clone_flags & (CLONE_SETTID | CLONE_CLEARTID)) {
-		tid_ptr = p3;
-		if (test_thread_flag(TIF_32BIT))
-			tid_ptr &= 0xffffffff;
+	if (p2 == 0)
+		p2 = regs->gpr[1];	/* stack pointer for child */
+
+	if (clone_flags & (CLONE_PARENT_SETTID | CLONE_CHILD_SETTID |
+			   CLONE_CHILD_CLEARTID)) {
+		parent_tidptr = p3;
+		child_tidptr = p4;
+		if (test_thread_flag(TIF_32BIT)) {
+			parent_tidptr &= 0xffffffff;
+			child_tidptr &= 0xffffffff;
+		}
 	}
 
 	if (regs->msr & MSR_FP)
 		giveup_fpu(current);
 
-	p = do_fork(clone_flags & ~CLONE_IDLETASK, regs->gpr[1], regs, 0,
-		    (int *)tid_ptr);
+	p = do_fork(clone_flags & ~CLONE_IDLETASK, p2, regs, 0,
+		    (int *)parent_tidptr, (int *)child_tidptr);
 	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
-int sys_fork(u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6,
+int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
+	     unsigned long p4, unsigned long p5, unsigned long p6,
 	     struct pt_regs *regs)
 {
 	struct task_struct *p;
@@ -287,11 +306,12 @@
 	if (regs->msr & MSR_FP)
 		giveup_fpu(current);
 
-	p = do_fork(SIGCHLD, regs->gpr[1], regs, 0, NULL);
+	p = do_fork(SIGCHLD, regs->gpr[1], regs, 0, NULL, NULL);
 	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
-int sys_vfork(u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6,
+int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
+	      unsigned long p4, unsigned long p5, unsigned long p6,
 	      struct pt_regs *regs)
 {
 	struct task_struct *p;
@@ -300,7 +320,7 @@
 		giveup_fpu(current);
 
 	p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1], regs, 0,
-	            NULL);
+	            NULL, NULL);
 	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
@@ -338,7 +358,7 @@
 		if (!cpu_possible(i))
 			continue;
 		/* Carve out storage for the hardware interrupt stack */
-		stack = __get_free_pages(GFP_KERNEL, get_order(8*PAGE_SIZE));
+		stack = __get_free_pages(GFP_ATOMIC, get_order(8*PAGE_SIZE));
 
 		if ( !stack ) {     
 			printk("ERROR, cannot find space for hardware stack.\n");
@@ -368,69 +388,62 @@
 	}
 }
 
-extern char _stext[], _etext[];
+extern char _stext[], _etext[], __init_begin[], __init_end[];
 
-char * ppc_find_proc_name( unsigned * p, char * buf, unsigned buflen )
+static char *ppc_find_proc_name(unsigned *p, char *buf, unsigned buflen)
 {
 	unsigned long tb_flags;
 	unsigned short name_len;
 	unsigned long tb_start, code_start, code_ptr, code_offset;
-	unsigned code_len;
-	strcpy( buf, "Unknown" );
+	unsigned int code_len;
+	unsigned long end;
+
+	strcpy(buf, "Unknown");
 	code_ptr = (unsigned long)p;
 	code_offset = 0;
-	if ( ( (unsigned long)p >= (unsigned long)_stext ) && ( (unsigned long)p <= (unsigned long)_etext ) ) {
-		while ( (unsigned long)p <= (unsigned long)_etext ) {
-			if ( *p == 0 ) {
-				tb_start = (unsigned long)p;
-				++p;	/* Point to traceback flags */
-				tb_flags = *((unsigned long *)p);
-				p += 2;	/* Skip over traceback flags */
-				if ( tb_flags & TB_NAME_PRESENT ) {
-					if ( tb_flags & TB_PARMINFO )
-						++p;	/* skip over parminfo data */
-					if ( tb_flags & TB_HAS_TBOFF ) {
-						code_len = *p;	/* get code length */
-						code_start = tb_start - code_len;
-						code_offset = code_ptr - code_start + 1;
-						if ( code_offset > 0x100000 )
-							break;
-						++p;		/* skip over code size */
-					}
-					name_len = *((unsigned short *)p);
-					if ( name_len > (buflen-20) )
-						name_len = buflen-20;
-					memcpy( buf, ((char *)p)+2, name_len );
-					buf[name_len] = 0;
-					if ( code_offset )
-						sprintf( buf+name_len, "+0x%lx", code_offset-1 ); 
+
+	/* handle functions in text and init sections */
+	if (((unsigned long)p >= (unsigned long)_stext) && 
+	    ((unsigned long)p < (unsigned long)_etext))
+		end = (unsigned long)_etext;
+	else if (((unsigned long)p >= (unsigned long)__init_begin) && 
+		 ((unsigned long)p < (unsigned long)__init_end))
+		end = (unsigned long)__init_end;
+	else
+		return buf;
+
+	while ((unsigned long)p < end) {
+		if (*p == 0) {
+			tb_start = (unsigned long)p;
+			++p;	/* Point to traceback flags */
+			tb_flags = *((unsigned long *)p);
+			p += 2;	/* Skip over traceback flags */
+			if (tb_flags & TB_NAME_PRESENT) {
+				if (tb_flags & TB_PARMINFO)
+					++p;	/* skip over parminfo data */
+				if (tb_flags & TB_HAS_TBOFF) {
+					code_len = *p;	/* get code length */
+					code_start = tb_start - code_len;
+					code_offset = code_ptr - code_start + 1;
+					if (code_offset > 0x100000)
+						break;
+					++p;	/* skip over code size */
 				}
-				break;
+				name_len = *((unsigned short *)p);
+				if (name_len > (buflen-20))
+					name_len = buflen-20;
+				memcpy(buf, ((char *)p)+2, name_len);
+				buf[name_len] = 0;
+				if (code_offset)
+					sprintf(buf+name_len, "+0x%lx",
+						code_offset-1); 
 			}
-			++p;
+			break;
 		}
+		++p;
 	}
-	return buf;
-}
-
-void
-print_backtrace(unsigned long *sp)
-{
-	int cnt = 0;
-	unsigned long i;
-	char name_buf[256];
 
-	printk("Call backtrace: \n");
-	while (sp) {
-		if (__get_user( i, &sp[2] ))
-			break;
-		printk("%016lX ", i);
-		printk("%s\n", ppc_find_proc_name( (unsigned *)i, name_buf, 256 ));
-		if (cnt > 32) break;
-		if (__get_user(sp, (unsigned long **)sp))
-			break;
-	}
-	printk("\n");
+	return buf;
 }
 
 /*
@@ -467,31 +480,39 @@
 	return 0;
 }
 
-void show_trace_task(struct task_struct *p)
+static void show_tsk_stack(struct task_struct *p, unsigned long sp)
 {
-	unsigned long ip, sp;
+	unsigned long ip;
 	unsigned long stack_page = (unsigned long)p->thread_info;
 	int count = 0;
+	char name_buf[256];
 
 	if (!p)
 		return;
 
-	printk("Call Trace: ");
-	sp = p->thread.ksp;
+	printk("Call Trace:\n");
 	do {
-		sp = *(unsigned long *)sp;
+		if (__get_user(sp, (unsigned long *)sp))
+			break;
 		if (sp < (stack_page + sizeof(struct thread_struct)) ||
 		    sp >= (stack_page + THREAD_SIZE))
 			break;
-		if (count > 0) {
-			ip = *(unsigned long *)(sp + 16);
-			printk("[%016lx] ", ip);
-		}
-	} while (count++ < 16);
-	printk("\n");
+		if (__get_user(ip, (unsigned long *)(sp + 16)))
+			break;
+		printk("[%016lx] ", ip);
+		printk("%s\n", ppc_find_proc_name((unsigned *)ip,
+		       name_buf, 256));
+	} while (count++ < 32);
 }
 
+extern unsigned long *_get_SP(void);
+
 void dump_stack(void)
 {
-	show_stack(NULL);
+	show_tsk_stack(current, (unsigned long)_get_SP());
+}
+
+void show_trace_task(struct task_struct *tsk)
+{
+	show_tsk_stack(tsk, tsk->thread.ksp);
 }
diff -Nru a/arch/ppc64/kernel/profile.c b/arch/ppc64/kernel/profile.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ppc64/kernel/profile.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,42 @@
+/*
+ *	linux/arch/i386/kernel/profile.c
+ *
+ *	(C) 2002 John Levon <levon@movementarian.org>
+ *
+ */
+
+#include <linux/profile.h>
+#include <linux/spinlock.h>
+#include <linux/notifier.h>
+#include <linux/irq.h>
+#include <asm/hw_irq.h> 
+ 
+static struct notifier_block * profile_listeners;
+static rwlock_t profile_lock = RW_LOCK_UNLOCKED;
+ 
+int register_profile_notifier(struct notifier_block * nb)
+{
+	int err;
+	write_lock_irq(&profile_lock);
+	err = notifier_chain_register(&profile_listeners, nb);
+	write_unlock_irq(&profile_lock);
+	return err;
+}
+
+
+int unregister_profile_notifier(struct notifier_block * nb)
+{
+	int err;
+	write_lock_irq(&profile_lock);
+	err = notifier_chain_unregister(&profile_listeners, nb);
+	write_unlock_irq(&profile_lock);
+	return err;
+}
+
+
+void ppc64_profile_hook(struct pt_regs * regs)
+{
+	read_lock(&profile_lock);
+	notifier_call_chain(&profile_listeners, 0, regs);
+	read_unlock(&profile_lock);
+}
diff -Nru a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
--- a/arch/ppc64/kernel/prom.c	Mon Dec  9 18:46:50 2002
+++ b/arch/ppc64/kernel/prom.c	Mon Dec  9 18:46:50 2002
@@ -1988,8 +1988,7 @@
 		adr = (struct address_range *) mem_start;
 		while ((l -= sizeof(struct reg_property)) >= 0) {
 			adr[i].space = rp[i].space;
-			adr[i].address = rp[i].address
-				+ (adr[i].space? 0: _ISA_MEM_BASE);
+			adr[i].address = rp[i].address;
 			adr[i].size = rp[i].size;
 			++i;
 		}
diff -Nru a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c
--- a/arch/ppc64/kernel/ptrace.c	Mon Dec  9 18:46:35 2002
+++ b/arch/ppc64/kernel/ptrace.c	Mon Dec  9 18:46:35 2002
@@ -59,7 +59,8 @@
 		/* are we already being traced? */
 		if (current->ptrace & PT_PTRACED)
 			goto out;
-		if ((ret = security_ptrace(current->parent, current)))
+		ret = security_ptrace(current->parent, current);
+		if (ret)
 			goto out;
 		/* set the ptrace bit in the process flags. */
 		current->ptrace |= PT_PTRACED;
diff -Nru a/arch/ppc64/kernel/ptrace32.c b/arch/ppc64/kernel/ptrace32.c
--- a/arch/ppc64/kernel/ptrace32.c	Mon Dec  9 18:46:38 2002
+++ b/arch/ppc64/kernel/ptrace32.c	Mon Dec  9 18:46:38 2002
@@ -48,7 +48,8 @@
 		/* are we already being traced? */
 		if (current->ptrace & PT_PTRACED)
 			goto out;
-		if ((ret = security_ptrace(current->parent, current)))
+		ret = security_ptrace(current->parent, current);
+		if (ret)
 			goto out;
 		/* set the ptrace bit in the process flags. */
 		current->ptrace |= PT_PTRACED;
diff -Nru a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c
--- a/arch/ppc64/kernel/signal.c	Mon Dec  9 18:46:34 2002
+++ b/arch/ppc64/kernel/signal.c	Mon Dec  9 18:46:34 2002
@@ -450,9 +450,14 @@
 
 	if (regs->trap == 0x0C00 /* System Call! */
 	    && ((int)regs->result == -ERESTARTNOHAND ||
+		(int)regs->result == -ERESTART_RESTARTBLOCK ||
 		((int)regs->result == -ERESTARTSYS &&
-		 !(ka->sa.sa_flags & SA_RESTART))))
+		 !(ka->sa.sa_flags & SA_RESTART)))) {
+		if ((int)regs->result == -ERESTART_RESTARTBLOCK)
+			current_thread_info()->restart_block.fn
+				= do_no_restart_syscall;
 		regs->result = -EINTR;
+	}
 
 	/* Set up Signal Frame */
 	if (ka->sa.sa_flags & SA_SIGINFO) {
@@ -560,13 +565,18 @@
 		handle_signal(signr, &info, oldset, regs, &newsp, frame);
 	}
 
-	if (regs->trap == 0x0C00 /* System Call! */ &&
-	    ((int)regs->result == -ERESTARTNOHAND ||
-	     (int)regs->result == -ERESTARTSYS ||
-	     (int)regs->result == -ERESTARTNOINTR)) {
-		regs->gpr[3] = regs->orig_gpr3;
-		regs->nip -= 4;		/* Back up & retry system call */
-		regs->result = 0;
+	if (regs->trap == 0x0C00) {	/* System Call! */
+		if ((int)regs->result == -ERESTARTNOHAND ||
+		    (int)regs->result == -ERESTARTSYS ||
+		    (int)regs->result == -ERESTARTNOINTR) {
+			regs->gpr[3] = regs->orig_gpr3;
+			regs->nip -= 4; /* Back up & retry system call */
+			regs->result = 0;
+		} else if ((int)regs->result == -ERESTART_RESTARTBLOCK) {
+			regs->gpr[0] = __NR_restart_syscall;
+			regs->nip -= 4;
+			regs->result = 0;
+		}
 	}
 
 	if (newsp == frame)
diff -Nru a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c
--- a/arch/ppc64/kernel/signal32.c	Mon Dec  9 18:46:51 2002
+++ b/arch/ppc64/kernel/signal32.c	Mon Dec  9 18:46:51 2002
@@ -22,6 +22,7 @@
 #include <linux/signal.h>
 #include <linux/errno.h>
 #include <linux/elf.h>
+#include <linux/compat.h>
 #include <asm/ppc32.h>
 #include <asm/uaccess.h>
 #include <asm/ppcdebug.h>
@@ -53,11 +54,6 @@
 #define MSR_USERCHANGE	0
 #endif
 
-struct timespec32 {
-	s32    tv_sec;
-	s32    tv_nsec;
-};
-
 struct sigregs32 {
 	/*
 	 * the gp_regs array is 32 bit representation of the pt_regs
@@ -635,8 +631,7 @@
 extern long sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
 
 
-long sys32_rt_sigpending(sigset32_t *set,
-		__kernel_size_t32 sigsetsize)
+long sys32_rt_sigpending(sigset32_t *set, compat_size_t sigsetsize)
 {
 	sigset_t s;
 	sigset32_t s32;
@@ -708,7 +703,7 @@
 		size_t sigsetsize);
 
 long sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo,
-		struct timespec32 *uts, __kernel_size_t32 sigsetsize)
+		struct compat_timespec *uts, compat_size_t sigsetsize)
 {
 	sigset_t s;
 	sigset32_t s32;
@@ -973,9 +968,14 @@
 
 	if (regs->trap == 0x0C00 /* System Call! */
 	    && ((int)regs->result == -ERESTARTNOHAND ||
+		(int)regs->result == -ERESTART_RESTARTBLOCK ||
 		((int)regs->result == -ERESTARTSYS &&
-		 !(ka->sa.sa_flags & SA_RESTART))))
+		 !(ka->sa.sa_flags & SA_RESTART)))) {
+		if ((int)regs->result == -ERESTART_RESTARTBLOCK)
+			current_thread_info()->restart_block.fn
+				= do_no_restart_syscall;
 		regs->result = -EINTR;
+	}
 
 	/*
 	 * Set up the signal frame
@@ -1137,13 +1137,18 @@
 		handle_signal32(signr, &info, oldset, regs, &newsp, frame);
 	}
 
-	if (regs->trap == 0x0C00 /* System Call! */ &&
-	    ((int)regs->result == -ERESTARTNOHAND ||
-	     (int)regs->result == -ERESTARTSYS ||
-	     (int)regs->result == -ERESTARTNOINTR)) {
-		regs->gpr[3] = regs->orig_gpr3;
-		regs->nip -= 4;		/* Back up & retry system call */
-		regs->result = 0;
+	if (regs->trap == 0x0C00) {	/* System Call! */
+		if ((int)regs->result == -ERESTARTNOHAND ||
+		    (int)regs->result == -ERESTARTSYS ||
+		    (int)regs->result == -ERESTARTNOINTR) {
+			regs->gpr[3] = regs->orig_gpr3;
+			regs->nip -= 4; /* Back up & retry system call */
+			regs->result = 0;
+		} else if ((int)regs->result == -ERESTART_RESTARTBLOCK) {
+			regs->gpr[0] = __NR_restart_syscall;
+			regs->nip -= 4;
+			regs->result = 0;
+		}
 	}
 
 	if (newsp == frame)
diff -Nru a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c
--- a/arch/ppc64/kernel/smp.c	Mon Dec  9 18:46:50 2002
+++ b/arch/ppc64/kernel/smp.c	Mon Dec  9 18:46:50 2002
@@ -613,7 +613,7 @@
 	/* create a process for the processor */
 	/* only regs.msr is actually used, and 0 is OK for it */
 	memset(&regs, 0, sizeof(struct pt_regs));
-	p = do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL);
+	p = do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL, NULL);
 	if (IS_ERR(p))
 		panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p));
 
diff -Nru a/arch/ppc64/kernel/sys32.S b/arch/ppc64/kernel/sys32.S
--- a/arch/ppc64/kernel/sys32.S	Mon Dec  9 18:46:50 2002
+++ b/arch/ppc64/kernel/sys32.S	Mon Dec  9 18:46:50 2002
@@ -40,15 +40,15 @@
 	clrldi		r8, r8, 32	/* int *addr_len parm */
 	b		.sys_recvfrom
 
-_GLOBAL(sys32_getsockopt)
-	clrldi		r7, r7, 32	/* int *optlen parm */
-	b		.sys_getsockopt
-
 _GLOBAL(ppc32_mmap2)
 	clrldi		r7, r7, 32	/* unsigned long fd parm */
 	clrldi		r8, r8, 32	/* unsigned long pgoff */
 	b		.sys32_mmap2
 
+_GLOBAL(ppc32_remap_file_pages)
+	clrldi		r7, r7, 32
+	b		.sys_remap_file_pages
+
 _GLOBAL(sys32_socketcall)	/* r3=call, r4=args */
 	cmpwi		r3, 1
 	blt-		.do_einval
@@ -134,7 +134,7 @@
 	lwz		r6,12(r10)
 	b		.sys_recv
 
-_STATIC(do_sys_sendto) /* sys32_sendto(int, u32, __kernel_size_t32, unsigned int, u32, int) */
+_STATIC(do_sys_sendto) /* sys32_sendto(int, u32, compat_size_t, unsigned int, u32, int) */
 	mr		r10,r4
 	lwa		r3,0(r10)
 	lwz		r4,4(r10)
@@ -144,7 +144,7 @@
 	lwa		r8,20(r10)
 	b		.sys32_sendto
 
-_STATIC(do_sys_recvfrom) /* sys32_recvfrom(int, u32, __kernel_size_t32, unsigned int, u32, u32) */
+_STATIC(do_sys_recvfrom) /* sys32_recvfrom(int, u32, compat_size_t, unsigned int, u32, u32) */
 	mr		r10,r4
 	lwa		r3,0(r10)
 	lwz		r4,4(r10)
diff -Nru a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c
--- a/arch/ppc64/kernel/sys_ppc32.c	Mon Dec  9 18:46:50 2002
+++ b/arch/ppc64/kernel/sys_ppc32.c	Mon Dec  9 18:46:50 2002
@@ -22,7 +22,6 @@
 #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>
@@ -51,9 +50,14 @@
 #include <linux/highmem.h>
 #include <linux/highuid.h>
 #include <linux/mman.h>
+#include <linux/ipv6.h>
+#include <linux/in.h>
+#include <linux/icmpv6.h>
 #include <linux/sysctl.h>
 #include <linux/binfmts.h>
+#include <linux/dnotify.h>
 #include <linux/security.h>
+#include <linux/compat.h>
 
 #include <asm/types.h>
 #include <asm/ipc.h>
@@ -69,117 +73,107 @@
 #include <asm/ppc32.h>
 #include <asm/mmu_context.h>
 
-extern asmlinkage long sys_utime(char * filename, struct utimbuf * times);
-
-struct utimbuf32 {
-	__kernel_time_t32 actime, modtime;
-};
-
-asmlinkage long sys32_utime(char * filename, struct utimbuf32 *times)
-{
-	struct utimbuf t;
-	mm_segment_t old_fs;
-	int ret;
-	char *filenam;
-	
-	if (!times)
-		return sys_utime(filename, NULL);
-	if (get_user(t.actime, &times->actime) || __get_user(t.modtime, &times->modtime))
-		return -EFAULT;
-	filenam = getname(filename);
-
-	ret = PTR_ERR(filenam);
-	if (!IS_ERR(filenam)) {
-		old_fs = get_fs();
-		set_fs (KERNEL_DS); 
-		ret = sys_utime(filenam, &t);
-		set_fs (old_fs);
-		putname (filenam);
-	}
-
-	return ret;
-}
+struct iovec32 { u32 iov_base; compat_size_t iov_len; };
 
-
-
-struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; };
-
-typedef ssize_t (*IO_fn_t)(struct file *, char *, size_t, loff_t *);
+typedef ssize_t (*io_fn_t)(struct file *, char *, size_t, loff_t *);
+typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *);
 
 static long do_readv_writev32(int type, struct file *file,
 			      const struct iovec32 *vector, u32 count)
 {
-	unsigned long tot_len;
+	compat_ssize_t tot_len;
 	struct iovec iovstack[UIO_FASTIOV];
 	struct iovec *iov=iovstack, *ivp;
 	struct inode *inode;
 	long retval, i;
-	IO_fn_t fn;
+	io_fn_t fn;
+	iov_fn_t fnv;
+
+	/*
+	 * SuS says "The readv() function *may* fail if the iovcnt argument
+	 * was less than or equal to 0, or greater than {IOV_MAX}.  Linux has
+	 * traditionally returned zero for zero segments, so...
+	 */
+	retval = 0;
+	if (count == 0)
+		goto out;
 
 	/* First get the "struct iovec" from user memory and
 	 * verify all the pointers
 	 */
-	if (!count)
-		return 0;
-	if(verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count))
-		return -EFAULT;
+	retval = -EINVAL;
 	if (count > UIO_MAXIOV)
-		return -EINVAL;
+		goto out;
+	if (!file->f_op)
+		goto out;
 	if (count > UIO_FASTIOV) {
+		retval = -ENOMEM;
 		iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
 		if (!iov)
-			return -ENOMEM;
+			goto out;
 	}
+	retval = -EFAULT;
+	if (verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count))
+		goto out;
 
+	/*
+	 * Single unix specification:
+	 * We should -EINVAL if an element length is not >= 0 and fitting an
+	 * ssize_t.  The total length is fitting an ssize_t
+	 *
+	 * Be careful here because iov_len is a size_t not an ssize_t
+	 */
 	tot_len = 0;
 	i = count;
 	ivp = iov;
+	retval = -EINVAL;
 	while(i > 0) {
-		u32 len;
+		compat_ssize_t tmp = tot_len;
+		compat_ssize_t len;
 		u32 buf;
 
-		__get_user(len, &vector->iov_len);
-		__get_user(buf, &vector->iov_base);
+		if (__get_user(len, &vector->iov_len) ||
+		    __get_user(buf, &vector->iov_base)) {
+			retval = -EFAULT;
+			goto out;
+		}
+		if (len < 0)	/* size_t not fitting an compat_ssize_t .. */
+			goto out;
 		tot_len += len;
+		if (tot_len < tmp) /* maths overflow on the compat_ssize_t */
+			goto out;
 		ivp->iov_base = (void *)A(buf);
 		ivp->iov_len = (__kernel_size_t) len;
 		vector++;
 		ivp++;
 		i--;
 	}
+	if (tot_len == 0) {
+		retval = 0;
+		goto out;
+	}
 
 	inode = file->f_dentry->d_inode;
 	/* VERIFY_WRITE actually means a read, as we write to user space */
-	retval = locks_verify_area((type == VERIFY_WRITE
+	retval = locks_verify_area((type == READ
 				    ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE),
 				   inode, file, file->f_pos, tot_len);
-	if (retval) {
-		if (iov != iovstack)
-			kfree(iov);
-		return retval;
-	}
+	if (retval)
+		goto out;
 
-	/* Then do the actual IO.  Note that sockets need to be handled
-	 * specially as they have atomicity guarantees and can handle
-	 * iovec's natively
-	 */
-	if (inode->i_sock) {
-		int err;
-		err = sock_readv_writev(type, inode, file, iov, count, tot_len);
-		if (iov != iovstack)
-			kfree(iov);
-		return err;
+	if (type == READ) {
+		fn = file->f_op->read;
+		fnv = file->f_op->readv;
+	} else {
+		fn = (io_fn_t)file->f_op->write;
+		fnv = file->f_op->writev;
 	}
-
-	if (!file->f_op) {
-		if (iov != iovstack)
-			kfree(iov);
-		return -EINVAL;
+	if (fnv) {
+		retval = fnv(file, iov, count, &file->f_pos);
+		goto out;
 	}
-	/* VERIFY_WRITE actually means a read, as we write to user space */
-	fn = file->f_op->read;
-	if (type == VERIFY_READ)
-		fn = (IO_fn_t) file->f_op->write;		
+
+	/* Do it by hand, with file-ops */
 	ivp = iov;
 	while (count > 0) {
 		void * base;
@@ -189,54 +183,67 @@
 		len = ivp->iov_len;
 		ivp++;
 		count--;
+
 		nr = fn(file, base, len, &file->f_pos);
+
 		if (nr < 0) {
-			if (retval)
-				break;
-			retval = nr;
+			if (!retval)
+				retval = nr;
 			break;
 		}
 		retval += nr;
 		if (nr != len)
 			break;
 	}
+out:
 	if (iov != iovstack)
 		kfree(iov);
+	if ((retval + (type == READ)) > 0)
+		dnotify_parent(file->f_dentry,
+			       (type == READ) ? DN_ACCESS : DN_MODIFY);
+
 	return retval;
 }
 
-asmlinkage long sys32_readv(u32 fd, struct iovec32 *vector, u32 count)
+asmlinkage long sys32_readv(int fd, struct iovec32 *vector, u32 count)
 {
 	struct file *file;
-	long ret = -EBADF;
-	
+	int ret = -EBADF;
+
 	file = fget(fd);
-	if(!file)
-		goto bad_file;
+	if (!file || !(file->f_mode & FMODE_READ))
+		goto out; 
 
-	if (file->f_op && (file->f_mode & FMODE_READ) &&
-	    (file->f_op->readv || file->f_op->read))
-		ret = do_readv_writev32(VERIFY_WRITE, file, vector, count);
-	fput(file);
+	ret = -EINVAL;
+	if (!file->f_op || (!file->f_op->readv && !file->f_op->read))
+		goto out;
 
-bad_file:
+	ret = do_readv_writev32(READ, file, vector, count);
+
+out:
+	if (file)
+		fput(file);
 	return ret;
 }
 
-asmlinkage long sys32_writev(u32 fd, struct iovec32 *vector, u32 count)
+asmlinkage long sys32_writev(int fd, struct iovec32 *vector, u32 count)
 {
 	struct file *file;
 	int ret = -EBADF;
-	
+
 	file = fget(fd);
-	if(!file)
-		goto bad_file;
-	if (file->f_op && (file->f_mode & FMODE_WRITE) &&
-	   (file->f_op->writev || file->f_op->write))
-		ret = do_readv_writev32(VERIFY_READ, file, vector, count);
-	fput(file);
+	if (!file || !(file->f_mode & FMODE_WRITE))
+		goto out;
 
-bad_file:
+	ret = -EINVAL;
+	if (!file->f_op || (!file->f_op->writev && !file->f_op->write))
+		goto out;
+
+	ret = do_readv_writev32(WRITE, file, vector, count);
+
+out:
+	if (file)
+		fput(file);
 	return ret;
 }
 
@@ -290,7 +297,7 @@
 	}
 }
 
-struct ncp_mount_data32 {
+struct ncp_mount_data32_v3 {
         int version;
         unsigned int ncp_fd;
         __kernel_uid_t32 mounted_uid;
@@ -305,18 +312,69 @@
         __kernel_mode_t32 dir_mode;
 };
 
+struct ncp_mount_data32_v4 {
+	int version;
+	/* all members below are "long" in ABI ... i.e. 32bit on sparc32, while 64bits on sparc64 */
+	unsigned int flags;
+	unsigned int mounted_uid;
+	int wdog_pid;
+
+	unsigned int ncp_fd;
+	unsigned int time_out;
+	unsigned int retry_count;
+
+	unsigned int uid;
+	unsigned int gid;
+	unsigned int file_mode;
+	unsigned int dir_mode;
+};
+
 static void *do_ncp_super_data_conv(void *raw_data)
 {
-	struct ncp_mount_data *n = (struct ncp_mount_data *)raw_data;
-	struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data;
-
-	n->dir_mode = n32->dir_mode;
-	n->file_mode = n32->file_mode;
-	n->gid = n32->gid;
-	n->uid = n32->uid;
-	memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int)));
-	n->wdog_pid = n32->wdog_pid;
-	n->mounted_uid = n32->mounted_uid;
+	switch (*(int*)raw_data) {
+		case NCP_MOUNT_VERSION:
+			{
+				struct ncp_mount_data news, *n = &news; 
+				struct ncp_mount_data32_v3 *n32 = (struct ncp_mount_data32_v3 *)raw_data;
+
+				n->version = n32->version;
+				n->ncp_fd = n32->ncp_fd;
+				n->mounted_uid = n32->mounted_uid;
+				n->wdog_pid = n32->wdog_pid;
+				memmove (n->mounted_vol, n32->mounted_vol, sizeof (n32->mounted_vol));
+				n->time_out = n32->time_out;
+				n->retry_count = n32->retry_count;
+				n->flags = n32->flags;
+				n->uid = n32->uid;
+				n->gid = n32->gid;
+				n->file_mode = n32->file_mode;
+				n->dir_mode = n32->dir_mode;
+				memcpy(raw_data, n, sizeof(*n)); 
+			}
+			break;
+		case NCP_MOUNT_VERSION_V4:
+			{
+				struct ncp_mount_data_v4 news, *n = &news; 
+				struct ncp_mount_data32_v4 *n32 = (struct ncp_mount_data32_v4 *)raw_data;
+
+				n->version = n32->version;
+				n->flags = n32->flags;
+				n->mounted_uid = n32->mounted_uid;
+				n->wdog_pid = n32->wdog_pid;
+				n->ncp_fd = n32->ncp_fd;
+				n->time_out = n32->time_out;
+				n->retry_count = n32->retry_count;
+				n->uid = n32->uid;
+				n->gid = n32->gid;
+				n->file_mode = n32->file_mode;
+				n->dir_mode = n32->dir_mode;
+				memcpy(raw_data, n, sizeof(*n)); 
+			}
+			break;
+		default:
+			/* do not touch unknown structures */
+			break;
+	}
 	return raw_data;
 }
 
@@ -331,7 +389,7 @@
 
 static void *do_smb_super_data_conv(void *raw_data)
 {
-	struct smb_mount_data *s = (struct smb_mount_data *)raw_data;
+	struct smb_mount_data news, *s = &news;
 	struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
 
 	if (s32->version != SMB_MOUNT_OLDVERSION)
@@ -342,6 +400,7 @@
 	s->gid = s32->gid;
 	s->file_mode = s32->file_mode;
 	s->dir_mode = s32->dir_mode;
+	memcpy(raw_data, s, sizeof(struct smb_mount_data)); 
 out:
 	return raw_data;
 }
@@ -576,20 +635,6 @@
 
 /* 32-bit timeval and related flotsam.  */
 
-struct timeval32
-{
-	int tv_sec, tv_usec;
-};
-
-struct itimerval32
-{
-	struct timeval32 it_interval;
-	struct timeval32 it_value;
-};
-
-
-
-
 /*
  * Ooo, nasty.  We need here to frob 32-bit unsigned longs to
  * 64-bit unsigned longs.
@@ -655,7 +700,7 @@
 asmlinkage long sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, u32 tvp_x)
 {
 	fd_set_bits fds;
-	struct timeval32 *tvp = (struct timeval32 *)AA(tvp_x);
+	struct compat_timeval *tvp = (struct compat_timeval *)AA(tvp_x);
 	char *bits;
 	unsigned long nn;
 	long timeout;
@@ -771,11 +816,11 @@
 	if (stat->size > MAX_NON_LFS)
 		return -EOVERFLOW;
 	err |= put_user(stat->size, &statbuf->st_size);
-	err |= put_user(stat->atime, &statbuf->st_atime);
+	err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
 	err |= put_user(0, &statbuf->__unused1);
-	err |= put_user(stat->mtime, &statbuf->st_mtime);
+	err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
 	err |= put_user(0, &statbuf->__unused2);
-	err |= put_user(stat->ctime, &statbuf->st_ctime);
+	err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
 	err |= put_user(0, &statbuf->__unused3);
 	err |= put_user(stat->blksize, &statbuf->st_blksize);
 	err |= put_user(stat->blocks, &statbuf->st_blocks);
@@ -933,7 +978,7 @@
 	u32 modes;
 	s32 offset, freq, maxerror, esterror;
 	s32 status, constant, precision, tolerance;
-	struct timeval32 time;
+	struct compat_timeval time;
 	s32 tick;
 	s32 ppsfreq, jitter, shift, stabil;
 	s32 jitcnt, calcnt, errcnt, stbcnt;
@@ -1010,7 +1055,7 @@
 
 extern asmlinkage unsigned long sys_create_module(const char *name_user, size_t size);
 
-asmlinkage unsigned long sys32_create_module(const char *name_user, __kernel_size_t32 size)
+asmlinkage unsigned long sys32_create_module(const char *name_user, compat_size_t size)
 {
 	return sys_create_module(name_user, (size_t)size);
 }
@@ -1093,7 +1138,7 @@
 }
 
 static int
-qm_modules(char *buf, size_t bufsize, __kernel_size_t32 *ret)
+qm_modules(char *buf, size_t bufsize, compat_size_t *ret)
 {
 	struct module *mod;
 	size_t nmod, space, len;
@@ -1128,7 +1173,7 @@
 }
 
 static int
-qm_deps(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
+qm_deps(struct module *mod, char *buf, size_t bufsize, compat_size_t *ret)
 {
 	size_t i, space, len;
 
@@ -1165,7 +1210,7 @@
 }
 
 static int
-qm_refs(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
+qm_refs(struct module *mod, char *buf, size_t bufsize, compat_size_t *ret)
 {
 	size_t nrefs, space, len;
 	struct module_ref *ref;
@@ -1209,7 +1254,7 @@
 }
 
 static inline int
-qm_symbols(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
+qm_symbols(struct module *mod, char *buf, size_t bufsize, compat_size_t *ret)
 {
 	size_t i, space, len;
 	struct module_symbol *s;
@@ -1268,7 +1313,7 @@
 }
 
 static inline int
-qm_info(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
+qm_info(struct module *mod, char *buf, size_t bufsize, compat_size_t *ret)
 {
 	int error = 0;
 
@@ -1301,7 +1346,7 @@
  * proper conversion (sign extension) between the register representation 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_query_module(char *name_user, u32 which, char *buf, __kernel_size_t32 bufsize, u32 ret)
+asmlinkage long sys32_query_module(char *name_user, u32 which, char *buf, compat_size_t bufsize, u32 ret)
 {
 	struct module *mod;
 	int err;
@@ -1337,19 +1382,19 @@
 		err = 0;
 		break;
 	case QM_MODULES:
-		err = qm_modules(buf, bufsize, (__kernel_size_t32 *)AA(ret));
+		err = qm_modules(buf, bufsize, (compat_size_t *)AA(ret));
 		break;
 	case QM_DEPS:
-		err = qm_deps(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
+		err = qm_deps(mod, buf, bufsize, (compat_size_t *)AA(ret));
 		break;
 	case QM_REFS:
-		err = qm_refs(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
+		err = qm_refs(mod, buf, bufsize, (compat_size_t *)AA(ret));
 		break;
 	case QM_SYMBOLS:
-		err = qm_symbols(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
+		err = qm_symbols(mod, buf, bufsize, (compat_size_t *)AA(ret));
 		break;
 	case QM_INFO:
-		err = qm_info(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
+		err = qm_info(mod, buf, bufsize, (compat_size_t *)AA(ret));
 		break;
 	default:
 		err = -EINVAL;
@@ -1775,37 +1820,6 @@
 
 
 
-struct timespec32 {
-	s32    tv_sec;
-	s32    tv_nsec;
-};
-
-extern asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
-
-asmlinkage long sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
-	struct timespec t;
-	int ret;
-	mm_segment_t old_fs = get_fs ();
-	
-	if (get_user (t.tv_sec, &rqtp->tv_sec) ||
-	    __get_user (t.tv_nsec, &rqtp->tv_nsec))
-		return -EFAULT;
-	set_fs (KERNEL_DS);
-	ret = sys_nanosleep(&t, rmtp ? &t : NULL);
-	set_fs (old_fs);
-	if (rmtp && ret == -EINTR) {
-		if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
-	    	    __put_user (t.tv_nsec, &rmtp->tv_nsec))
-			return -EFAULT;
-	}
-	
-	return ret;
-}
-
-
-
-
 /* These are here just in case some old sparc32 binary calls it. */
 asmlinkage long sys32_pause(void)
 {
@@ -1817,32 +1831,14 @@
 
 
 
-static inline long get_it32(struct itimerval *o, struct itimerval32 *i)
-{
-	return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
-		(__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
-		 __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
-		 __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
-		 __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
-}
-
-static inline long put_it32(struct itimerval32 *o, struct itimerval *i)
-{
-	return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
-		(__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
-		 __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
-		 __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
-		 __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
-}
-
-static inline long get_tv32(struct timeval *o, struct timeval32 *i)
+static inline long get_tv32(struct timeval *o, struct compat_timeval *i)
 {
 	return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
 		(__get_user(o->tv_sec, &i->tv_sec) |
 		 __get_user(o->tv_usec, &i->tv_usec)));
 }
 
-static inline long put_tv32(struct timeval32 *o, struct timeval *i)
+static inline long put_tv32(struct compat_timeval *o, struct timeval *i)
 {
 	return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
 		(__put_user(i->tv_sec, &o->tv_sec) |
@@ -1852,54 +1848,6 @@
 
 
 
-extern int do_getitimer(int which, struct itimerval *value);
-
-/* Note: it is necessary to treat which as an unsigned int, 
- * with the corresponding cast to a signed int to insure that the 
- * proper conversion (sign extension) between the register representation 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_getitimer(u32 which, struct itimerval32 *it)
-{
-	struct itimerval kit;
-	int error;
-	
-	error = do_getitimer((int)which, &kit);
-	if (!error && put_it32(it, &kit))
-		error = -EFAULT;
-
-	return error;
-}
-
-
-
-extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
-
-/* Note: it is necessary to treat which as an unsigned int, 
- * with the corresponding cast to a signed int to insure that the 
- * proper conversion (sign extension) between the register representation 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_setitimer(u32 which, struct itimerval32 *in, struct itimerval32 *out)
-{
-	struct itimerval kin, kout;
-	int error;
-	
-	if (in) {
-		if (get_it32(&kin, in))
-			return -EFAULT;
-	} else
-		memset(&kin, 0, sizeof(kin));
-
-	error = do_setitimer((int)which, &kin, out ? &kout : NULL);
-	if (error || !out)
-		return error;
-	if (put_it32(out, &kout))
-		return -EFAULT;
-
-	return 0;
-}
-
 #define RLIM_INFINITY32	0xffffffff
 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
 
@@ -1974,8 +1922,8 @@
 
 
 struct rusage32 {
-        struct timeval32 ru_utime;
-        struct timeval32 ru_stime;
+        struct compat_timeval ru_utime;
+        struct compat_timeval ru_stime;
         s32    ru_maxrss;
         s32    ru_ixrss;
         s32    ru_idrss;
@@ -2092,7 +2040,7 @@
 extern struct timezone sys_tz;
 extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
 
-asmlinkage long sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
+asmlinkage long sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz)
 {
 	if (tv) {
 		struct timeval ktv;
@@ -2110,7 +2058,7 @@
 
 
 
-asmlinkage long sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
+asmlinkage long sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz)
 {
 	struct timeval ktv;
 	struct timezone ktz;
@@ -2163,8 +2111,8 @@
 
 struct semid_ds32 {
 	struct ipc_perm sem_perm;
-	__kernel_time_t32 sem_otime;
-	__kernel_time_t32 sem_ctime;
+	compat_time_t sem_otime;
+	compat_time_t sem_ctime;
 	u32 sem_base;
 	u32 sem_pending;
 	u32 sem_pending_last;
@@ -2175,9 +2123,9 @@
 struct semid64_ds32 {
 	struct ipc64_perm sem_perm;
 	unsigned int __unused1;
-	__kernel_time_t32 sem_otime;
+	compat_time_t sem_otime;
 	unsigned int __unused2;
-	__kernel_time_t32 sem_ctime;
+	compat_time_t sem_ctime;
 	u32 sem_nsems;
 	u32 __unused3;
 	u32 __unused4;
@@ -2188,9 +2136,9 @@
 	struct ipc_perm msg_perm;
 	u32 msg_first;
 	u32 msg_last;
-	__kernel_time_t32 msg_stime;
-	__kernel_time_t32 msg_rtime;
-	__kernel_time_t32 msg_ctime;
+	compat_time_t msg_stime;
+	compat_time_t msg_rtime;
+	compat_time_t msg_ctime;
 	u32 msg_lcbytes;
 	u32 msg_lqbytes;
 	unsigned short msg_cbytes;
@@ -2203,11 +2151,11 @@
 struct msqid64_ds32 {
 	struct ipc64_perm msg_perm;
 	unsigned int __unused1;
-	__kernel_time_t32 msg_stime;
+	compat_time_t msg_stime;
 	unsigned int __unused2;
-	__kernel_time_t32 msg_rtime;
+	compat_time_t msg_rtime;
 	unsigned int __unused3;
-	__kernel_time_t32 msg_ctime;
+	compat_time_t msg_ctime;
 	unsigned int msg_cbytes;
 	unsigned int msg_qnum;
 	unsigned int msg_qbytes;
@@ -2220,9 +2168,9 @@
 struct shmid_ds32 {
 	struct ipc_perm shm_perm;
 	int shm_segsz;
-	__kernel_time_t32 shm_atime;
-	__kernel_time_t32 shm_dtime;
-	__kernel_time_t32 shm_ctime;
+	compat_time_t shm_atime;
+	compat_time_t shm_dtime;
+	compat_time_t shm_ctime;
 	__kernel_ipc_pid_t32 shm_cpid;
 	__kernel_ipc_pid_t32 shm_lpid;
 	unsigned short shm_nattch;
@@ -2234,13 +2182,13 @@
 struct shmid64_ds32 {
 	struct ipc64_perm shm_perm;
 	unsigned int __unused1;
-	__kernel_time_t32 shm_atime;
+	compat_time_t shm_atime;
 	unsigned int __unused2;
-	__kernel_time_t32 shm_dtime;
+	compat_time_t shm_dtime;
 	unsigned int __unused3;
-	__kernel_time_t32 shm_ctime;
+	compat_time_t shm_ctime;
 	unsigned int __unused4;
-	__kernel_size_t32 shm_segsz;
+	compat_size_t shm_segsz;
 	__kernel_pid_t32 shm_cpid;
 	__kernel_pid_t32 shm_lpid;
 	unsigned int shm_nattch;
@@ -2806,46 +2754,146 @@
 
 extern asmlinkage int sys_setsockopt(int fd, int level, int optname, char *optval, int optlen);
 
-asmlinkage long sys32_setsockopt(int fd, int level, int optname, char* optval, int optlen)
+static int do_set_attach_filter(int fd, int level, int optname,
+				char *optval, int optlen)
 {
-	if (optname == SO_ATTACH_FILTER) {
-		struct sock_fprog32 {
-			__u16 len;
-			__u32 filter;
-		} *fprog32 = (struct sock_fprog32 *)optval;
-		struct sock_fprog kfprog;
-		struct sock_filter *kfilter;
-		unsigned int fsize;
-		mm_segment_t old_fs;
-		__u32 uptr;
-		int ret;
+	struct sock_fprog32 {
+		__u16 len;
+		__u32 filter;
+	} *fprog32 = (struct sock_fprog32 *)optval;
+	struct sock_fprog kfprog;
+	struct sock_filter *kfilter;
+	unsigned int fsize;
+	mm_segment_t old_fs;
+	__u32 uptr;
+	int ret;
 
-		if (get_user(kfprog.len, &fprog32->len) ||
-		    __get_user(uptr, &fprog32->filter))
-			return -EFAULT;
-		kfprog.filter = (struct sock_filter *)A(uptr);
-		fsize = kfprog.len * sizeof(struct sock_filter);
-		kfilter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL);
-		if (kfilter == NULL)
-			return -ENOMEM;
-		if (copy_from_user(kfilter, kfprog.filter, fsize)) {
-			kfree(kfilter);
-			return -EFAULT;
-		}
-		kfprog.filter = kfilter;
-		old_fs = get_fs();
-		set_fs(KERNEL_DS);
-		ret = sys_setsockopt(fd, level, optname,
-				     (char *)&kfprog, sizeof(kfprog));
-		set_fs(old_fs);
+	if (get_user(kfprog.len, &fprog32->len) ||
+	    __get_user(uptr, &fprog32->filter))
+		return -EFAULT;
+
+	kfprog.filter = (struct sock_filter *)A(uptr);
+	fsize = kfprog.len * sizeof(struct sock_filter);
+
+	kfilter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL);
+	if (kfilter == NULL)
+		return -ENOMEM;
+
+	if (copy_from_user(kfilter, kfprog.filter, fsize)) {
 		kfree(kfilter);
-		return ret;
+		return -EFAULT;
+	}
+
+	kfprog.filter = kfilter;
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_setsockopt(fd, level, optname,
+			     (char *)&kfprog, sizeof(kfprog));
+	set_fs(old_fs);
+
+	kfree(kfilter);
+
+	return ret;
+}
+
+static int do_set_icmpv6_filter(int fd, int level, int optname,
+				char *optval, int optlen)
+{
+	struct icmp6_filter kfilter;
+	mm_segment_t old_fs;
+	int ret, i;
+
+	if (copy_from_user(&kfilter, optval, sizeof(kfilter)))
+		return -EFAULT;
+
+
+	for (i = 0; i < 8; i += 2) {
+		u32 tmp = kfilter.data[i];
+
+		kfilter.data[i] = kfilter.data[i + 1];
+		kfilter.data[i + 1] = tmp;
 	}
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_setsockopt(fd, level, optname,
+			     (char *) &kfilter, sizeof(kfilter));
+	set_fs(old_fs);
+
+	return ret;
+}
+
+static int do_set_sock_timeout(int fd, int level, int optname, char *optval, int optlen)
+{
+	struct compat_timeval *up = (struct compat_timeval *) optval;
+	struct timeval ktime;
+	mm_segment_t old_fs;
+	int err;
+
+	if (optlen < sizeof(*up))
+		return -EINVAL;
+	if (get_user(ktime.tv_sec, &up->tv_sec) ||
+	    __get_user(ktime.tv_usec, &up->tv_usec))
+		return -EFAULT;
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	err = sys_setsockopt(fd, level, optname, (char *) &ktime, sizeof(ktime));
+	set_fs(old_fs);
+
+	return err;
+}
+
+asmlinkage long sys32_setsockopt(int fd, int level, int optname, char* optval, int optlen)
+{
+	if (optname == SO_ATTACH_FILTER)
+		return do_set_attach_filter(fd, level, optname,
+					    optval, optlen);
+	if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)
+		return do_set_sock_timeout(fd, level, optname, optval, optlen);
+	if (level == SOL_ICMPV6 && optname == ICMPV6_FILTER)
+		return do_set_icmpv6_filter(fd, level, optname,
+					    optval, optlen);
+
 	return sys_setsockopt(fd, level, optname, optval, optlen);
 }
 
+extern asmlinkage long sys_getsockopt(int fd, int level, int optname,
+				      char *optval, int *optlen);
 
+static int do_get_sock_timeout(int fd, int level, int optname, char *optval, int *optlen)
+{
+	struct compat_timeval *up = (struct compat_timeval *) optval;
+	struct timeval ktime;
+	mm_segment_t old_fs;
+	int len, err;
 
+	if (get_user(len, optlen))
+		return -EFAULT;
+	if (len < sizeof(*up))
+		return -EINVAL;
+	len = sizeof(ktime);
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	err = sys_getsockopt(fd, level, optname, (char *) &ktime, &len);
+	set_fs(old_fs);
+
+	if (!err) {
+		if (put_user(sizeof(*up), optlen) ||
+		    put_user(ktime.tv_sec, &up->tv_sec) ||
+		    __put_user(ktime.tv_usec, &up->tv_usec))
+			err = -EFAULT;
+	}
+	return err;
+}
+
+asmlinkage int sys32_getsockopt(int fd, int level, int optname,
+				char *optval, int *optlen)
+{
+	if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)
+		return do_get_sock_timeout(fd, level, optname, optval, optlen);
+	return sys_getsockopt(fd, level, optname, optval, optlen);
+}
 
 #define MAX_SOCK_ADDR	128		/* 108 for Unix domain -  16 for IP, 16 for IPX, 24 for IPv6, about 80 for AX.25 */
 #define __CMSG32_NXTHDR(ctl, len, cmsg, cmsglen) __cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen))
@@ -2866,15 +2914,15 @@
 	u32               msg_name;
 	int               msg_namelen;
 	u32               msg_iov;
-	__kernel_size_t32 msg_iovlen;
+	compat_size_t msg_iovlen;
 	u32               msg_control;
-	__kernel_size_t32 msg_controllen;
+	compat_size_t msg_controllen;
 	unsigned          msg_flags;
 };
 
 struct cmsghdr32
 {
-	__kernel_size_t32 cmsg_len;
+	compat_size_t cmsg_len;
 	int               cmsg_level;
 	int               cmsg_type;
 };
@@ -2992,7 +3040,7 @@
 {
 	struct cmsghdr32 *ucmsg;
 	struct cmsghdr *kcmsg, *kcmsg_base;
-	__kernel_size_t32 ucmlen;
+	compat_size_t ucmlen;
 	__kernel_size_t kcmlen, tmp;
 
 	kcmlen = 0;
@@ -3259,12 +3307,12 @@
 			 * from 64-bit time values to 32-bit time values
 			 */
 		case SO_TIMESTAMP: {
-			__kernel_time_t32* ptr_time32 = CMSG32_DATA(kcmsg32);
+			compat_time_t* ptr_time32 = CMSG32_DATA(kcmsg32);
 			__kernel_time_t*   ptr_time   = CMSG_DATA(ucmsg);
 			*ptr_time32     = *ptr_time;
 			*(ptr_time32+1) = *(ptr_time+1);
 			kcmsg32->cmsg_len -= 2*(sizeof(__kernel_time_t) -
-						sizeof(__kernel_time_t32));
+						sizeof(compat_time_t));
 		}
 		default:;
 		}
@@ -3375,7 +3423,7 @@
 		err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
 	if(cmsg_ptr != 0 && err >= 0) {
 		unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control);
-		__kernel_size_t32 uclen = (__kernel_size_t32) (ucmsg_ptr - cmsg_ptr);
+		compat_size_t uclen = (compat_size_t) (ucmsg_ptr - cmsg_ptr);
 		err |= __put_user(uclen, &user_msg->msg_controllen);
 	}
 	if(err >= 0)
@@ -3521,7 +3569,8 @@
 	if ((retval = bprm.envc) < 0)
 		goto out_mm;
 
-	if ((retval = security_bprm_alloc(&bprm)))
+	retval = security_bprm_alloc(&bprm);
+	if (retval)
 		goto out;
 
 	retval = prepare_binprm(&bprm);
@@ -3632,7 +3681,7 @@
  * proper conversion (sign extension) between the register representation 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 int sys32_sched_rr_get_interval(u32 pid, struct timespec32 *interval)
+asmlinkage int sys32_sched_rr_get_interval(u32 pid, struct compat_timespec *interval)
 {
 	struct timespec t;
 	int ret;
@@ -4134,15 +4183,13 @@
 extern ssize_t sys_pwrite64(unsigned int fd, const char *buf, size_t count,
 			    loff_t pos);
 
-typedef __kernel_ssize_t32 ssize_t32;
-
-ssize_t32 sys32_pread64(unsigned int fd, char *ubuf, __kernel_size_t32 count,
+compat_ssize_t sys32_pread64(unsigned int fd, char *ubuf, compat_size_t count,
 			u32 reg6, u32 poshi, u32 poslo)
 {
 	return sys_pread64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
 }
 
-ssize_t32 sys32_pwrite64(unsigned int fd, char *ubuf, __kernel_size_t32 count,
+compat_ssize_t sys32_pwrite64(unsigned int fd, char *ubuf, compat_size_t count,
 			 u32 reg6, u32 poshi, u32 poslo)
 {
 	return sys_pwrite64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
@@ -4150,7 +4197,7 @@
 
 extern ssize_t sys_readahead(int fd, loff_t offset, size_t count);
 
-ssize_t32 sys32_readahead(int fd, u32 r4, u32 offhi, u32 offlo, u32 count)
+compat_ssize_t sys32_readahead(int fd, u32 r4, u32 offhi, u32 offlo, u32 count)
 {
         return sys_readahead(fd, ((loff_t)offhi << 32) | offlo, AA(count));
 }
@@ -4174,18 +4221,13 @@
 		return sys_ftruncate(fd, (high << 32) | low);
 }
 
-
-
 asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-     	if (cmd >= F_GETLK64 && cmd <= F_SETLKW64)
+	if (cmd >= F_GETLK64 && cmd <= F_SETLKW64)
 		return sys_fcntl(fd, cmd + F_GETLK - F_GETLK64, arg);
 	return sys32_fcntl(fd, cmd, arg);
 }
 
-
-
-
 struct __sysctl_args32 {
 	u32 name;
 	int nlen;
@@ -4234,9 +4276,9 @@
 	return error;
 }
 
-asmlinkage long sys32_time(__kernel_time_t32* tloc)
+asmlinkage long sys32_time(compat_time_t* tloc)
 {
-	__kernel_time_t32 secs;
+	compat_time_t secs;
 
 	struct timeval tv;
 
@@ -4293,7 +4335,7 @@
 				    &kernel_mask);
 	set_fs(old_fs);
 
-	if (ret == 0) {
+	if (ret > 0) {
 		if (put_user(kernel_mask, user_mask_ptr))
 			ret = -EFAULT;
 	}
@@ -4337,4 +4379,13 @@
 {
 	/* This should remain 12 even if PAGE_SIZE changes */
 	return sys_mmap(addr, len, prot, flags, fd, pgoff << 12);
+}
+
+extern int sys_lookup_dcookie(u64 cookie64, char *buf, size_t len);
+
+long sys32_lookup_dcookie(u32 cookie_high, u32 cookie_low, char *buf,
+			  size_t len)
+{
+	return sys_lookup_dcookie((u64)cookie_high << 32 | cookie_low,
+				  buf, len);
 }
diff -Nru a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c
--- a/arch/ppc64/kernel/time.c	Mon Dec  9 18:46:51 2002
+++ b/arch/ppc64/kernel/time.c	Mon Dec  9 18:46:51 2002
@@ -46,6 +46,7 @@
 #include <linux/mc146818rtc.h>
 #include <linux/time.h>
 #include <linux/init.h>
+#include <linux/profile.h>
 
 #include <asm/segment.h>
 #include <asm/io.h>
@@ -95,21 +96,35 @@
 extern unsigned long lpEvent_count;
 extern int smp_tb_synchronized;
 
-extern unsigned long prof_cpu_mask;
-extern unsigned int * prof_buffer;
-extern unsigned long prof_len;
-extern unsigned long prof_shift;
-extern char _stext;
-
 void ppc_adjtimex(void);
 
 static unsigned adjusting_time = 0;
 
-static inline void ppc_do_profile (unsigned long nip)
+/*
+ * The profiling function is SMP safe. (nothing can mess
+ * around with "current", and the profiling counters are
+ * updated with atomic operations). This is especially
+ * useful with a profiling multiplier != 1
+ */
+static inline void ppc64_do_profile(struct pt_regs *regs)
 {
+	unsigned long nip;
+	extern unsigned long prof_cpu_mask;
+	extern char _stext;
+#ifdef CONFIG_PROFILING
+	extern void ppc64_profile_hook(struct pt_regs *);
+
+	ppc64_profile_hook(regs);
+#endif
+
+	if (user_mode(regs))
+		return;
+
 	if (!prof_buffer)
 		return;
 
+	nip = instruction_pointer(regs);
+
 	/*
 	 * Only measure the CPUs specified by /proc/irq/prof_cpu_mask.
 	 * (default is all CPUs.)
@@ -129,7 +144,6 @@
 	atomic_inc((atomic_t *)&prof_buffer[nip]);
 }
 
-
 static __inline__ void timer_check_rtc(void)
 {
         /*
@@ -259,8 +273,7 @@
 	irq_enter();
 
 #ifndef CONFIG_PPC_ISERIES
-	if (!user_mode(regs))
-		ppc_do_profile(instruction_pointer(regs));
+	ppc64_do_profile(regs);
 #endif
 
 	lpaca->xLpPaca.xIntDword.xFields.xDecrInt = 0;
diff -Nru a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c
--- a/arch/ppc64/kernel/traps.c	Mon Dec  9 18:46:37 2002
+++ b/arch/ppc64/kernel/traps.c	Mon Dec  9 18:46:37 2002
@@ -67,7 +67,6 @@
 	bust_spinlocks(1);
 	printk("Oops: %s, sig: %ld\n", str, err);
 	show_regs(regs);
-	print_backtrace((unsigned long *)regs->gpr[1]);
 	bust_spinlocks(0);
 	spin_unlock_irq(&die_lock);
 
@@ -188,7 +187,6 @@
 		printk("Machine check in kernel mode.\n");
 		printk("Caused by (from SRR1=%lx): ", regs->msr);
 		show_regs(regs);
-		print_backtrace((unsigned long *)regs->gpr[1]);
 		bust_spinlocks(0);
 		spin_unlock_irq(&die_lock);
 		panic("Unrecoverable Machine Check");
diff -Nru a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c
--- a/arch/ppc64/kernel/xics.c	Mon Dec  9 18:46:38 2002
+++ b/arch/ppc64/kernel/xics.c	Mon Dec  9 18:46:38 2002
@@ -12,8 +12,9 @@
 #include <linux/types.h>
 #include <linux/threads.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/irq.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
 #include <asm/prom.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
@@ -90,6 +91,7 @@
 /* RTAS service tokens */
 int ibm_get_xive;
 int ibm_set_xive;
+int ibm_int_on;
 int ibm_int_off;
 
 struct xics_interrupt_node {
@@ -161,6 +163,14 @@
 		       irq, call_status, status);
 		return;
 	}
+	/* Now unmask the interrupt (often a no-op) */
+	call_status = rtas_call(ibm_int_on, 1, 1, (unsigned long*)&status, 
+				irq);
+	if( call_status != 0 ) {
+		printk("xics_disable_irq on: irq=%x: rtas_call failed, retn=%lx\n",
+		       irq, call_status);
+		return;
+	}
 }
 
 void
@@ -301,6 +311,7 @@
 
 	ibm_get_xive = rtas_token("ibm,get-xive");
 	ibm_set_xive = rtas_token("ibm,set-xive");
+	ibm_int_on  = rtas_token("ibm,int-on");
 	ibm_int_off = rtas_token("ibm,int-off");
 
 	np = find_type_devices("PowerPC-External-Interrupt-Presentation");
diff -Nru a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c
--- a/arch/ppc64/mm/init.c	Mon Dec  9 18:46:38 2002
+++ b/arch/ppc64/mm/init.c	Mon Dec  9 18:46:38 2002
@@ -132,12 +132,10 @@
 #ifdef CONFIG_PPC_ISERIES
 	return (void*)addr;
 #else
-	if(mem_init_done && (addr >> 60UL)) {
-		if (IS_EEH_TOKEN_DISABLED(addr))
-			return (void *)IO_TOKEN_TO_ADDR(addr);
-		return (void*)addr; /* already mapped address or EEH token. */
-	}
-	return __ioremap(addr, size, _PAGE_NO_CACHE);
+	void *ret = __ioremap(addr, size, _PAGE_NO_CACHE);
+	if(mem_init_done)
+		return eeh_ioremap(addr, ret);	/* may remap the addr */
+	return ret;
 #endif
 }
 
diff -Nru a/arch/ppc64/oprofile/Kconfig b/arch/ppc64/oprofile/Kconfig
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ppc64/oprofile/Kconfig	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,23 @@
+
+menu "Profiling support"
+	depends on EXPERIMENTAL
+
+config PROFILING
+	bool "Profiling support (EXPERIMENTAL)"
+	help
+	  Say Y here to enable the extended profiling support mechanisms used
+	  by profilers such as OProfile.
+	  
+
+config OPROFILE
+	tristate "OProfile system profiling (EXPERIMENTAL)"
+	depends on PROFILING
+	help
+	  OProfile is a profiling system capable of profiling the
+	  whole system, include the kernel, kernel modules, libraries,
+	  and applications.
+
+	  If unsure, say N.
+
+endmenu
+
diff -Nru a/arch/ppc64/oprofile/Makefile b/arch/ppc64/oprofile/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ppc64/oprofile/Makefile	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,8 @@
+obj-$(CONFIG_OPROFILE) += oprofile.o
+
+DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
+		oprof.o cpu_buffer.o buffer_sync.o \
+		event_buffer.o oprofile_files.o \
+		oprofilefs.o oprofile_stats.o )
+
+oprofile-y				:= $(DRIVER_OBJS) init.o timer_int.o
diff -Nru a/arch/ppc64/oprofile/init.c b/arch/ppc64/oprofile/init.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ppc64/oprofile/init.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,20 @@
+/**
+ * @file init.c
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon <levon@movementarian.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/oprofile.h>
+#include <linux/init.h>
+ 
+extern void timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu);
+
+int __init oprofile_arch_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu)
+{
+	timer_init(ops, cpu);
+	return 0;
+}
diff -Nru a/arch/ppc64/oprofile/timer_int.c b/arch/ppc64/oprofile/timer_int.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ppc64/oprofile/timer_int.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,56 @@
+/**
+ * @file timer_int.c
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon <levon@movementarian.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/notifier.h>
+#include <linux/smp.h>
+#include <linux/irq.h>
+#include <linux/oprofile.h>
+#include <asm/ptrace.h>
+ 
+static int timer_notify(struct notifier_block * self, unsigned long val, void * data)
+{
+	struct pt_regs * regs = (struct pt_regs *)data;
+	int cpu = smp_processor_id();
+ 
+	oprofile_add_sample(instruction_pointer(regs), 0, cpu);
+	return 0;
+}
+ 
+ 
+static struct notifier_block timer_notifier = {
+	.notifier_call	= timer_notify,
+};
+ 
+
+static int timer_start(void)
+{
+	return register_profile_notifier(&timer_notifier);
+}
+
+
+static void timer_stop(void)
+{
+	unregister_profile_notifier(&timer_notifier);
+}
+
+
+static struct oprofile_operations timer_ops = {
+	.start	= timer_start,
+	.stop	= timer_stop
+};
+
+ 
+void __init timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu)
+{
+	*ops = &timer_ops;
+	*cpu = OPROFILE_CPU_TIMER;
+	printk(KERN_INFO "oprofile: using timer interrupt.\n");
+}
diff -Nru a/arch/s390/Kconfig b/arch/s390/Kconfig
--- a/arch/s390/Kconfig	Mon Dec  9 18:46:36 2002
+++ b/arch/s390/Kconfig	Mon Dec  9 18:46:36 2002
@@ -287,11 +287,15 @@
 
 menu "Kernel hacking"
 
-#if [ "$CONFIG_CTC" = "y" ]; then
-#  bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
-#fi
+config DEBUG_KERNEL
+	bool "Kernel debugging"
+	help
+	  Say Y here if you are developing drivers or trying to debug and
+	  identify kernel problems.
+
 config MAGIC_SYSRQ
 	bool "Magic SysRq key"
+	depends on DEBUG_KERNEL
 	help
 	  If you say Y here, you will have some control over the system even
 	  if the system crashes for example during kernel debugging (e.g., you
@@ -302,6 +306,28 @@
 	  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 DEBUG_SLAB
+	bool "Debug memory allocations"
+	depends on DEBUG_KERNEL
+	help
+	  Say Y here to have the kernel do limited verification on memory
+	  allocation as well as poisoning memory on free to catch use of freed
+	  memory.
+
+config KALLSYMS
+	bool "Load all symbols for debugging/kksymoops"
+	depends on DEBUG_KERNEL
+	help
+	  Say Y here to let the kernel print out symbolic crash information and
+	  symbolic stack backtraces. This increases the size of the kernel
+	  somewhat, as all symbols have to be loaded into the kernel image.
+
+config DEBUG_SPINLOCK_SLEEP
+	bool "Sleep-inside-spinlock checking"
+	help
+	  If you say Y here, various routines which may sleep will become very
+	  noisy if they are called with a spinlock held.	
 
 endmenu
 
diff -Nru a/arch/s390/defconfig b/arch/s390/defconfig
--- a/arch/s390/defconfig	Mon Dec  9 18:46:51 2002
+++ b/arch/s390/defconfig	Mon Dec  9 18:46:51 2002
@@ -11,7 +11,6 @@
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CONFIDENTIAL=y
 
 #
 # General setup
@@ -80,6 +79,7 @@
 # S/390 block device drivers
 #
 CONFIG_DASD=y
+# CONFIG_DASD_PROFILE is not set
 CONFIG_DASD_ECKD=y
 CONFIG_DASD_FBA=y
 CONFIG_DASD_DIAG=y
@@ -108,6 +108,7 @@
 # CONFIG_TN3270 is not set
 CONFIG_TN3215=y
 CONFIG_TN3215_CONSOLE=y
+CONFIG_CCW_CONSOLE=y
 CONFIG_SCLP=y
 CONFIG_SCLP_TTY=y
 CONFIG_SCLP_CONSOLE=y
@@ -143,6 +144,7 @@
 CONFIG_LCS=m
 CONFIG_CTC=m
 CONFIG_IUCV=m
+CONFIG_CCWGROUP=m
 
 #
 # Networking options
@@ -296,18 +298,23 @@
 #
 # Kernel hacking
 #
+CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_KALLSYMS is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 
 #
 # Security options
 #
-CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY is not set
 
 #
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
 # CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
 # CONFIG_CRYPTO_SHA1 is not set
diff -Nru a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
--- a/arch/s390/kernel/debug.c	Mon Dec  9 18:46:34 2002
+++ b/arch/s390/kernel/debug.c	Mon Dec  9 18:46:34 2002
@@ -654,8 +654,10 @@
                         id->name, new_level, 0, DEBUG_MAX_LEVEL);
         } else {
                 id->level = new_level;
+#ifdef DEBUG
                 printk(KERN_INFO 
 			"debug: %s: new level %i\n",id->name,id->level);
+#endif
         }
 	spin_unlock_irqrestore(&id->lock,flags);
 }
diff -Nru a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
--- a/arch/s390/kernel/head.S	Mon Dec  9 18:46:35 2002
+++ b/arch/s390/kernel/head.S	Mon Dec  9 18:46:35 2002
@@ -466,6 +466,18 @@
         mvc   __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
 	
 #
+# clear bss memory
+#
+        l     %r2,.Lbss_bgn-.LPG1(%r13) # start of bss
+        l     %r3,.Lbss_end-.LPG1(%r13) # end of bss
+        sr    %r3,%r2                   # length of bss
+        sr    %r4,%r4                   #
+        sr    %r5,%r5                   # set src,length and pad to zero
+        sr    %r0,%r0                   #
+        mvcle %r2,%r4,0                 # clear mem
+        jo    .-4                       # branch back, if not finish
+
+#
 # find memory chunks.
 #
 	mvc   __LC_PGM_NEW_PSW(8),.Lpcmem-.LPG1(%r13)
@@ -579,6 +591,8 @@
 .Lmemsize:.long memory_size
 .Lmchunk:.long memory_chunk
 .Lmflags:.long machine_flags
+.Lbss_bgn:  .long  __bss_start
+.Lbss_end:  .long  _end
 
 	.org PARMAREA-64
 .Lduct:	.long 0,0,0,0,0,0,0,0
@@ -620,17 +634,6 @@
         ahi   %r15,-96
         xc    0(4,%r15),0(%r15)         # set backchain to zero
 
-#
-# clear bss memory
-#
-        l     %r2,.Lbss_bgn-.LPG2(%r13) # start of bss
-        l     %r3,.Lbss_end-.LPG2(%r13) # end of bss
-        sr    %r3,%r2                   # length of bss
-        sr    %r4,%r4                   #
-        sr    %r5,%r5                   # set src,length and pad to zero
-        sr    %r0,%r0                   #
-        mvcle %r2,%r4,0                 # clear mem
-        jo    .-4                       # branch back, if not finish
 # check control registers
         stctl  %c0,%c15,0(%r15)
 	oi     2(%r15),0x20             # enable sigp external interrupts
@@ -651,7 +654,5 @@
 .Ldw:	    .long  0x000a0000,0x00000000
 .Linittu:   .long  init_thread_union
 .Lstart:    .long  start_kernel
-.Lbss_bgn:  .long  __bss_start
-.Lbss_end:  .long  _end
 .Laregs:    .long  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 
diff -Nru a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
--- a/arch/s390/kernel/process.c	Mon Dec  9 18:46:50 2002
+++ b/arch/s390/kernel/process.c	Mon Dec  9 18:46:50 2002
@@ -146,7 +146,7 @@
 	regs.orig_gpr2 = -1;
 
 	/* Ok, create the new process.. */
-	p = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL);
+	p = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
 	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
@@ -188,6 +188,7 @@
         frame = ((struct stack_frame *)
 		 (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
         p->thread.ksp = (unsigned long) frame;
+	p->set_child_tid = p->clear_child_tid = NULL;
         frame->childregs = *regs;
 	frame->childregs.gprs[2] = 0;	/* child returns 0 on fork. */
         frame->childregs.gprs[15] = new_stackp;
@@ -218,7 +219,7 @@
 asmlinkage int sys_fork(struct pt_regs regs)
 {
 	struct task_struct *p;
-        p = do_fork(SIGCHLD, regs.gprs[15], &regs, 0, NULL);
+        p = do_fork(SIGCHLD, regs.gprs[15], &regs, 0, NULL, NULL);
 	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
@@ -227,14 +228,16 @@
         unsigned long clone_flags;
         unsigned long newsp;
 	struct task_struct *p;
-	int *user_tid;
+	int *parent_tidptr, *child_tidptr;
 
         clone_flags = regs.gprs[3];
         newsp = regs.orig_gpr2;
-	user_tid = (int *) regs.gprs[4];
+	parent_tidptr = (int *) regs.gprs[4];
+	child_tidptr = (int *) regs.gprs[5];
         if (!newsp)
                 newsp = regs.gprs[15];
-        p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0, user_tid);
+        p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0,
+		    parent_tidptr, child_tidptr);
 	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
@@ -252,7 +255,7 @@
 {
 	struct task_struct *p;
 	p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
-		    regs.gprs[15], &regs, 0, NULL);
+		    regs.gprs[15], &regs, 0, NULL, NULL);
 	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
diff -Nru a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
--- a/arch/s390/kernel/ptrace.c	Mon Dec  9 18:46:51 2002
+++ b/arch/s390/kernel/ptrace.c	Mon Dec  9 18:46:51 2002
@@ -30,6 +30,7 @@
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
+#include <linux/security.h>
 
 #include <asm/segment.h>
 #include <asm/page.h>
@@ -323,7 +324,8 @@
 		ret = -EPERM;
 		if (current->ptrace & PT_PTRACED)
 			goto out;
-		if ((ret = security_ptrace(current->parent, current)))
+		ret = security_ptrace(current->parent, current);
+		if (ret)
 			goto out;
 		/* set the ptrace bit in the process flags. */
 		current->ptrace |= PT_PTRACED;
diff -Nru a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
--- a/arch/s390/kernel/setup.c	Mon Dec  9 18:46:34 2002
+++ b/arch/s390/kernel/setup.c	Mon Dec  9 18:46:34 2002
@@ -47,6 +47,7 @@
  */
 unsigned int console_mode = 0;
 unsigned int console_device = -1;
+unsigned int console_irq = -1;
 unsigned long memory_size = 0;
 unsigned long machine_flags = 0;
 struct { unsigned long addr, size, type; } memory_chunk[16] = { { 0 } };
@@ -187,6 +188,10 @@
 	char *ptr;
 
         if (MACHINE_IS_VM) {
+		cpcmd("QUERY CONSOLE", query_buffer, 1024);
+		console_device = simple_strtoul(query_buffer + 5, NULL, 16);
+		ptr = strstr(query_buffer, "SUBCHANNEL =");
+		console_irq = simple_strtoul(ptr + 13, NULL, 16);
 		cpcmd("QUERY TERM", query_buffer, 1024);
 		ptr = strstr(query_buffer, "CONMODE");
 		/*
@@ -245,9 +250,13 @@
 /*
  * Reboot, halt and power_off routines for non SMP.
  */
+extern void do_reipl(unsigned long devno);
 static void do_machine_restart_nonsmp(char * __unused)
 {
-	reipl(S390_lowcore.ipl_device);
+	if (MACHINE_IS_VM)
+		cpcmd ("IPL", NULL, 0);
+	else
+		do_reipl (0x10000 | S390_lowcore.ipl_device);
 }
 
 static void do_machine_halt_nonsmp(void)
diff -Nru a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
--- a/arch/s390/kernel/smp.c	Mon Dec  9 18:46:34 2002
+++ b/arch/s390/kernel/smp.c	Mon Dec  9 18:46:34 2002
@@ -61,7 +61,7 @@
 extern char vmhalt_cmd[];
 extern char vmpoff_cmd[];
 
-extern void reipl(unsigned long devno);
+extern void do_reipl(unsigned long devno);
 
 static sigp_ccode smp_ext_bitcall(int, ec_bit_sig);
 static void smp_ext_bitcall_others(ec_bit_sig);
@@ -217,7 +217,10 @@
 		 * interrupted by an external interrupt and s390irq
 		 * locks are always held disabled).
 		 */
-		reipl(S390_lowcore.ipl_device);
+		if (MACHINE_IS_VM)
+			cpcmd ("IPL", NULL, 0);
+		else
+			do_reipl (0x10000 | S390_lowcore.ipl_device);
 	}
 	signal_processor(smp_processor_id(), sigp_stop);
 }
@@ -477,7 +480,7 @@
        /* don't care about the psw and regs settings since we'll never
           reschedule the forked task. */
        memset(&regs,0,sizeof(struct pt_regs));
-       return do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL);
+       return do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL, NULL);
 }
 
 int __cpu_up(unsigned int cpu)
diff -Nru a/arch/s390x/Kconfig b/arch/s390x/Kconfig
--- a/arch/s390x/Kconfig	Mon Dec  9 18:46:37 2002
+++ b/arch/s390x/Kconfig	Mon Dec  9 18:46:37 2002
@@ -296,11 +296,15 @@
 
 menu "Kernel hacking"
 
-#if [ "$CONFIG_CTC" = "y" ]; then
-#  bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
-#fi
+config DEBUG_KERNEL
+	bool "Kernel debugging"
+	help
+	  Say Y here if you are developing drivers or trying to debug and
+	  identify kernel problems.
+
 config MAGIC_SYSRQ
 	bool "Magic SysRq key"
+	depends on DEBUG_KERNEL
 	help
 	  If you say Y here, you will have some control over the system even
 	  if the system crashes for example during kernel debugging (e.g., you
@@ -311,6 +315,28 @@
 	  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 DEBUG_SLAB
+	bool "Debug memory allocations"
+	depends on DEBUG_KERNEL
+	help
+	  Say Y here to have the kernel do limited verification on memory
+	  allocation as well as poisoning memory on free to catch use of freed
+	  memory.
+
+config KALLSYMS
+	bool "Load all symbols for debugging/kksymoops"
+	depends on DEBUG_KERNEL
+	help
+	  Say Y here to let the kernel print out symbolic crash information and
+	  symbolic stack backtraces. This increases the size of the kernel
+	  somewhat, as all symbols have to be loaded into the kernel image.
+
+config DEBUG_SPINLOCK_SLEEP
+	bool "Sleep-inside-spinlock checking"
+	help
+	  If you say Y here, various routines which may sleep will become very
+	  noisy if they are called with a spinlock held.	
 
 endmenu
 
diff -Nru a/arch/s390x/defconfig b/arch/s390x/defconfig
--- a/arch/s390x/defconfig	Mon Dec  9 18:46:34 2002
+++ b/arch/s390x/defconfig	Mon Dec  9 18:46:34 2002
@@ -11,7 +11,6 @@
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CONFIDENTIAL=y
 
 #
 # General setup
@@ -138,6 +137,7 @@
 # S/390 block device drivers
 #
 CONFIG_DASD=y
+# CONFIG_DASD_PROFILE is not set
 CONFIG_DASD_ECKD=y
 CONFIG_DASD_FBA=y
 # CONFIG_DASD_DIAG is not set
@@ -166,6 +166,7 @@
 # CONFIG_TN3270 is not set
 CONFIG_TN3215=y
 CONFIG_TN3215_CONSOLE=y
+CONFIG_CCW_CONSOLE=y
 CONFIG_SCLP=y
 CONFIG_SCLP_TTY=y
 CONFIG_SCLP_CONSOLE=y
@@ -201,6 +202,7 @@
 CONFIG_LCS=m
 CONFIG_CTC=m
 CONFIG_IUCV=m
+CONFIG_CCWGROUP=m
 
 #
 # Networking options
@@ -357,18 +359,23 @@
 #
 # Kernel hacking
 #
+CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_KALLSYMS is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 
 #
 # Security options
 #
-CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY is not set
 
 #
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
 # CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
 # CONFIG_CRYPTO_SHA1 is not set
diff -Nru a/arch/s390x/kernel/debug.c b/arch/s390x/kernel/debug.c
--- a/arch/s390x/kernel/debug.c	Mon Dec  9 18:46:34 2002
+++ b/arch/s390x/kernel/debug.c	Mon Dec  9 18:46:34 2002
@@ -654,8 +654,10 @@
                         id->name, new_level, 0, DEBUG_MAX_LEVEL);
         } else {
                 id->level = new_level;
+#ifdef DEBUG
                 printk(KERN_INFO 
 			"debug: %s: new level %i\n",id->name,id->level);
+#endif
         }
 	spin_unlock_irqrestore(&id->lock,flags);
 }
diff -Nru a/arch/s390x/kernel/head.S b/arch/s390x/kernel/head.S
--- a/arch/s390x/kernel/head.S	Mon Dec  9 18:46:34 2002
+++ b/arch/s390x/kernel/head.S	Mon Dec  9 18:46:34 2002
@@ -467,10 +467,21 @@
 	larl  %r12,_pstart               # pointer to parameter area
 					 # move IPL device to lowcore
         mvc   __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12)
+
+#
+# clear bss memory
+#
+	larl  %r2,__bss_start           # start of bss segment
+        larl  %r3,_end                  # end of bss segment
+        sgr   %r3,%r2                   # length of bss
+        sgr   %r4,%r4                   #
+        sgr   %r5,%r5                   # set src,length and pad to zero
+        mvcle %r2,%r4,0                 # clear mem
+        jo    .-4                       # branch back, if not finish
+
 					 # set program check new psw mask
 	mvc   __LC_PGM_NEW_PSW(8),.Lpcmsk-.LPG1(%r13)
 
-
 #
 # find memory chunks.
 #
@@ -631,16 +642,7 @@
         stg   %r15,__LC_KERNEL_STACK    # set end of kernel stack
         aghi  %r15,-160
         xc    0(8,%r15),0(%r15)         # set backchain to zero
-#
-# clear bss memory
-#
-	larl  %r2,__bss_start           # start of bss segment
-        larl  %r3,_end                  # end of bss segment
-        sgr   %r3,%r2                   # length of bss
-        sgr   %r4,%r4                   #
-        sgr   %r5,%r5                   # set src,length and pad to zero
-        mvcle %r2,%r4,0                 # clear mem
-        jo    .-4                       # branch back, if not finish
+
 # check control registers
         stctg  %c0,%c15,0(%r15)
 	oi     6(%r15),0x20             # enable sigp external interrupts
diff -Nru a/arch/s390x/kernel/process.c b/arch/s390x/kernel/process.c
--- a/arch/s390x/kernel/process.c	Mon Dec  9 18:46:50 2002
+++ b/arch/s390x/kernel/process.c	Mon Dec  9 18:46:50 2002
@@ -143,7 +143,7 @@
 	regs.orig_gpr2 = -1;
 
 	/* Ok, create the new process.. */
-	p = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL);
+	p = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
 	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
@@ -185,6 +185,7 @@
         frame = ((struct stack_frame *)
 		 (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
         p->thread.ksp = (unsigned long) frame;
+	p->set_child_tid = p->clear_child_tid = NULL;
         frame->childregs = *regs;
 	frame->childregs.gprs[2] = 0;	/* child returns 0 on fork. */
         frame->childregs.gprs[15] = new_stackp;
@@ -208,7 +209,7 @@
 asmlinkage int sys_fork(struct pt_regs regs)
 {
 	struct task_struct *p;
-        p = do_fork(SIGCHLD, regs.gprs[15], &regs, 0, NULL);
+        p = do_fork(SIGCHLD, regs.gprs[15], &regs, 0, NULL, NULL);
 	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
@@ -217,14 +218,16 @@
         unsigned long clone_flags;
         unsigned long newsp;
 	struct task_struct *p;
-	int *user_tid;
+	int *parent_tidptr, *child_tidptr;
 
         clone_flags = regs.gprs[3];
         newsp = regs.orig_gpr2;
-	user_tid = (int *) regs.gprs[4];
+	parent_tidptr = (int *) regs.gprs[4];
+	child_tidptr = (int *) regs.gprs[5];
         if (!newsp)
                 newsp = regs.gprs[15];
-        p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0, user_tid);
+        p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0,
+		    parent_tidptr, child_tidptr);
 	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
@@ -242,7 +245,7 @@
 {
 	struct task_struct *p;
 	p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
-		    regs.gprs[15], &regs, 0, NULL);
+		    regs.gprs[15], &regs, 0, NULL, NULL);
 	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
diff -Nru a/arch/s390x/kernel/ptrace.c b/arch/s390x/kernel/ptrace.c
--- a/arch/s390x/kernel/ptrace.c	Mon Dec  9 18:46:34 2002
+++ b/arch/s390x/kernel/ptrace.c	Mon Dec  9 18:46:34 2002
@@ -563,7 +563,8 @@
 		ret = -EPERM;
 		if (current->ptrace & PT_PTRACED)
 			goto out;
-		if ((ret = security_ptrace(current->parent, current)))
+		ret = security_ptrace(current->parent, current);
+		if (ret)
 			goto out;
 		/* set the ptrace bit in the process flags. */
 		current->ptrace |= PT_PTRACED;
diff -Nru a/arch/s390x/kernel/setup.c b/arch/s390x/kernel/setup.c
--- a/arch/s390x/kernel/setup.c	Mon Dec  9 18:46:36 2002
+++ b/arch/s390x/kernel/setup.c	Mon Dec  9 18:46:36 2002
@@ -47,6 +47,7 @@
  */
 unsigned int console_mode = 0;
 unsigned int console_device = -1;
+unsigned int console_irq = -1;
 unsigned long memory_size = 0;
 unsigned long machine_flags = 0;
 struct { unsigned long addr, size, type; } memory_chunk[16] = { { 0 } };
@@ -187,6 +188,10 @@
 	char *ptr;
 
         if (MACHINE_IS_VM) {
+		cpcmd("QUERY CONSOLE", query_buffer, 1024);
+		console_device = simple_strtoul(query_buffer + 5, NULL, 16);
+		ptr = strstr(query_buffer, "SUBCHANNEL =");
+		console_irq = simple_strtoul(ptr + 13, NULL, 16);
 		cpcmd("QUERY TERM", query_buffer, 1024);
 		ptr = strstr(query_buffer, "CONMODE");
 		/*
@@ -245,9 +250,13 @@
 /*
  * Reboot, halt and power_off routines for non SMP.
  */
+extern void do_reipl(unsigned long devno);
 static void do_machine_restart_nonsmp(char * __unused)
 {
-	reipl(S390_lowcore.ipl_device);
+	if (MACHINE_IS_VM)
+		cpcmd ("IPL", NULL, 0);
+	else
+		do_reipl (0x10000 | S390_lowcore.ipl_device);
 }
 
 static void do_machine_halt_nonsmp(void)
diff -Nru a/arch/s390x/kernel/smp.c b/arch/s390x/kernel/smp.c
--- a/arch/s390x/kernel/smp.c	Mon Dec  9 18:46:37 2002
+++ b/arch/s390x/kernel/smp.c	Mon Dec  9 18:46:37 2002
@@ -60,7 +60,7 @@
 extern char vmhalt_cmd[];
 extern char vmpoff_cmd[];
 
-extern void reipl(unsigned long devno);
+extern void do_reipl(unsigned long devno);
 
 static sigp_ccode smp_ext_bitcall(int, ec_bit_sig);
 static void smp_ext_bitcall_others(ec_bit_sig);
@@ -216,7 +216,10 @@
 		 * interrupted by an external interrupt and s390irq
 		 * locks are always held disabled).
 		 */
-		reipl(S390_lowcore.ipl_device);
+		if (MACHINE_IS_VM)
+			cpcmd ("IPL", NULL, 0);
+		else
+			do_reipl (0x10000 | S390_lowcore.ipl_device);
 	}
 	signal_processor(smp_processor_id(), sigp_stop);
 }
@@ -461,7 +464,7 @@
        /* don't care about the psw and regs settings since we'll never
           reschedule the forked task. */
        memset(&regs,0,sizeof(struct pt_regs));
-       return do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL);
+       return do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL, NULL);
 }
 
 int __cpu_up(unsigned int cpu)
diff -Nru a/arch/sh/Kconfig b/arch/sh/Kconfig
--- a/arch/sh/Kconfig	Mon Dec  9 18:46:51 2002
+++ b/arch/sh/Kconfig	Mon Dec  9 18:46:51 2002
@@ -1190,62 +1190,7 @@
 
 source "drivers/media/Kconfig"
 
-
-menu "Console drivers"
-	depends on VT
-
-config VGA_CONSOLE
-	bool "VGA text console"
-	help
-	  Saying Y here will allow you to use Linux in text mode through a
-	  display that complies with the generic VGA standard. Virtually
-	  everyone wants that.
-
-	  The program SVGATextMode can be used to utilize SVGA video cards to
-	  their full potential in text mode. Download it from
-	  <ftp://ibiblio.org/pub/Linux/utils/console/>.
-
-	  Say Y.
-
-config VIDEO_SELECT
-	bool "Video mode selection support"
-	---help---
-	  This enables support for text mode selection on kernel startup. If
-	  you want to take advantage of some high-resolution text mode your
-	  card's BIOS offers, but the traditional Linux utilities like
-	  SVGATextMode don't, you can say Y here and set the mode using the
-	  "vga=" option from your boot loader (lilo or loadlin) or set
-	  "vga=ask" which brings up a video mode menu on kernel startup. (Try
-	  "man bootparam" or see the documentation of your boot loader about
-	  how to pass options to the kernel.)
-
-	  Read the file <file:Documentation/svga.txt> for more information
-	  about the Video mode selection support. If unsure, say N.
-
-if EXPERIMENTAL
-
-config MDA_CONSOLE
-	tristate "MDA text console (dual-headed) (EXPERIMENTAL)"
-	---help---
-	  Say Y here if you have an old MDA or monochrome Hercules graphics
-	  adapter in your system acting as a second head ( = video card). You
-	  will then be able to use two monitors with your Linux system. Do not
-	  say Y here if your MDA card is the primary card in your system; the
-	  normal VGA driver will handle it.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted and removed from the running kernel whenever you want).
-	  The module will be called mdacon.o. If you want to compile it as
-	  a module, say M here and read <file:Documentation/modules.txt>.
-
-	  If unsure, say N.
-
 source "drivers/video/Kconfig"
-
-endif
-
-endmenu
-
 
 menu "Sound"
 
diff -Nru a/arch/sparc/Kconfig b/arch/sparc/Kconfig
--- a/arch/sparc/Kconfig	Mon Dec  9 18:46:34 2002
+++ b/arch/sparc/Kconfig	Mon Dec  9 18:46:34 2002
@@ -417,23 +417,7 @@
 
 endmenu
 
-
-menu "Console drivers"
-
-config PROM_CONSOLE
-	bool "PROM console"
-	help
-	  Say Y to build a console driver for Sun machines that uses the
-	  terminal emulation built into their console PROMS.
-
-config DUMMY_CONSOLE
-	bool
-	depends on !PROM_CONSOLE
-	default y
-
 source "drivers/video/Kconfig"
-
-endmenu
 
 source "drivers/mtd/Kconfig"
 
diff -Nru a/arch/sparc/defconfig b/arch/sparc/defconfig
--- a/arch/sparc/defconfig	Mon Dec  9 18:46:50 2002
+++ b/arch/sparc/defconfig	Mon Dec  9 18:46:50 2002
@@ -1,6 +1,8 @@
 #
 # Automatically generated make config: don't edit
 #
+CONFIG_MMU=y
+CONFIG_SWAP=y
 CONFIG_UID16=y
 CONFIG_HIGHMEM=y
 CONFIG_GENERIC_ISA_DMA=y
@@ -22,7 +24,8 @@
 # Loadable module support
 #
 CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
 CONFIG_KMOD=y
 
 #
@@ -33,17 +36,12 @@
 CONFIG_HW_CONSOLE=y
 # CONFIG_SMP is not set
 CONFIG_SPARC32=y
-# CONFIG_ISA is not set
-# CONFIG_EISA is not set
-# CONFIG_MCA is not set
-# CONFIG_PCMCIA is not set
 CONFIG_SBUS=y
 CONFIG_SBUSCHAR=y
 CONFIG_SERIAL_CONSOLE=y
 CONFIG_SUN_AUXIO=y
 CONFIG_SUN_IO=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SUN_PM=y
 # CONFIG_SUN4 is not set
 CONFIG_PCI=y
@@ -59,7 +57,6 @@
 # Parallel port support
 #
 # CONFIG_PARPORT is not set
-# CONFIG_PRINTER is not set
 
 #
 # Console drivers
@@ -81,20 +78,11 @@
 # Serial drivers
 #
 # CONFIG_SERIAL_8250 is not set
-# CONFIG_SERIAL_8250_CONSOLE is not set
-# CONFIG_SERIAL_8250_CS is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
-# CONFIG_SERIAL_8250_RSA is not set
 
 #
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_SUNCORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_SUNZILOG=y
 CONFIG_SERIAL_SUNSU=y
 # CONFIG_SERIAL_SUNSAB is not set
@@ -115,15 +103,6 @@
 CONFIG_RTC=m
 
 #
-# Linux/SPARC audio subsystem (EXPERIMENTAL)
-#
-# CONFIG_SPARCAUDIO is not set
-# CONFIG_SPARCAUDIO_AMD7930 is not set
-# CONFIG_SPARCAUDIO_DBRI is not set
-# CONFIG_SPARCAUDIO_CS4231 is not set
-# CONFIG_SPARCAUDIO_DUMMY is not set
-
-#
 # Block devices
 #
 # CONFIG_BLK_DEV_FD is not set
@@ -134,13 +113,6 @@
 # Multi-device support (RAID and LVM)
 #
 # CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_BLK_DEV_INITRD=y
@@ -149,7 +121,6 @@
 # ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # ISDN subsystem
@@ -165,10 +136,6 @@
 # Fibre Channel support
 #
 # CONFIG_FC4 is not set
-# CONFIG_FC4_SOC is not set
-# CONFIG_FC4_SOCAL is not set
-# CONFIG_SCSI_PLUTO is not set
-# CONFIG_SCSI_FCAL is not set
 
 #
 # Networking options
@@ -179,6 +146,7 @@
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
+CONFIG_NET_KEY=m
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -191,12 +159,15 @@
 # CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_XFRM_USER=m
 CONFIG_IPV6=m
 
 #
-#    SCTP Configuration (EXPERIMENTAL)
+# SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=m
+CONFIG_IPV6_SCTP__=y
 CONFIG_IP_SCTP=m
 # CONFIG_SCTP_ADLER32 is not set
 # CONFIG_SCTP_DBG_MSG is not set
@@ -204,9 +175,6 @@
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_LLC is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -223,6 +191,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -239,6 +212,11 @@
 CONFIG_VORTEX=m
 
 #
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
 # Unix98 PTY support
 #
 CONFIG_UNIX98_PTYS=y
@@ -266,17 +244,10 @@
 #
 # CONFIG_GAMEPORT is not set
 CONFIG_SOUND_GAMEPORT=y
-# CONFIG_GAMEPORT_NS558 is not set
-# CONFIG_GAMEPORT_L4 is not set
-# CONFIG_GAMEPORT_EMU10K1 is not set
-# CONFIG_GAMEPORT_VORTEX is not set
-# CONFIG_GAMEPORT_FM801 is not set
-# CONFIG_GAMEPORT_CS461x is not set
 CONFIG_SERIO=m
 # CONFIG_SERIO_I8042 is not set
 CONFIG_SERIO_SERPORT=m
 # CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PARKBD is not set
 
 #
 # Input Device Drivers
@@ -289,65 +260,28 @@
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=m
 CONFIG_MOUSE_SERIAL=m
-# CONFIG_MOUSE_INPORT is not set
-# CONFIG_MOUSE_LOGIBM is not set
-# CONFIG_MOUSE_PC110PAD is not set
 # CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_JOYSTICK_ANALOG is not set
-# CONFIG_JOYSTICK_A3D is not set
-# CONFIG_JOYSTICK_ADI is not set
-# CONFIG_JOYSTICK_COBRA is not set
-# CONFIG_JOYSTICK_GF2K is not set
-# CONFIG_JOYSTICK_GRIP is not set
-# CONFIG_JOYSTICK_GRIP_MP is not set
-# CONFIG_JOYSTICK_GUILLEMOT is not set
-# CONFIG_JOYSTICK_INTERACT is not set
-# CONFIG_JOYSTICK_SIDEWINDER is not set
-# CONFIG_JOYSTICK_TMDC is not set
-# CONFIG_JOYSTICK_IFORCE is not set
-# CONFIG_JOYSTICK_WARRIOR is not set
-# CONFIG_JOYSTICK_MAGELLAN is not set
-# CONFIG_JOYSTICK_SPACEORB is not set
-# CONFIG_JOYSTICK_SPACEBALL is not set
-# CONFIG_JOYSTICK_STINGER is not set
-# CONFIG_JOYSTICK_TWIDDLER is not set
-# CONFIG_JOYSTICK_DB9 is not set
-# CONFIG_JOYSTICK_GAMECON is not set
-# CONFIG_JOYSTICK_TURBOGRAFX is not set
-# CONFIG_INPUT_JOYDUMP is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_TOUCHSCREEN_GUNZE is not set
 # CONFIG_INPUT_MISC is not set
-# CONFIG_INPUT_PCSPKR is not set
-# CONFIG_INPUT_SPARCSPKR is not set
-# CONFIG_INPUT_UINPUT is not set
 
 #
 # File systems
 #
 # CONFIG_QUOTA is not set
-# CONFIG_QFMT_V1 is not set
-# CONFIG_QFMT_V2 is not set
+CONFIG_QUOTACTL=y
 CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 # CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
-# CONFIG_JBD_DEBUG is not set
 # CONFIG_FAT_FS is not set
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
 CONFIG_RAMFS=y
@@ -355,28 +289,25 @@
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_JFS_DEBUG is not set
-# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_DEBUG is not set
-# CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
 CONFIG_PROC_FS=y
 # CONFIG_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
 CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
 CONFIG_ROMFS_FS=m
 CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
 # CONFIG_SYSV_FS is not set
 # CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
+CONFIG_XFS_FS=m
+CONFIG_XFS_RT=y
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_POSIX_ACL=y
 
 #
 # Network File Systems
@@ -385,24 +316,19 @@
 # CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_EXPORTFS is not set
+CONFIG_CIFS=m
 # CONFIG_SMB_FS is not set
 # CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
+CONFIG_AFS_FS=m
+CONFIG_RXRPC=m
+CONFIG_FS_MBCACHE=y
+CONFIG_FS_POSIX_ACL=y
 
 #
 # Partition Types
@@ -410,8 +336,59 @@
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
 CONFIG_SUN_PARTITION=y
-# CONFIG_SMB_NLS is not set
-# CONFIG_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Sound card support
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
 
 #
 # Bluetooth support
@@ -429,15 +406,30 @@
 CONFIG_DEBUG_SLAB=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 
 #
 # Security options
 #
-CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+# CONFIG_CRYPTO_TEST is not set
 
 #
 # Library routines
 #
 CONFIG_CRC32=y
-# CONFIG_ZLIB_INFLATE is not set
-# CONFIG_ZLIB_DEFLATE is not set
diff -Nru a/arch/sparc/kernel/devices.c b/arch/sparc/kernel/devices.c
--- a/arch/sparc/kernel/devices.c	Mon Dec  9 18:46:51 2002
+++ b/arch/sparc/kernel/devices.c	Mon Dec  9 18:46:51 2002
@@ -72,7 +72,7 @@
 		if (linux_num_cpus == 0) {
 			printk("No CPU nodes found, cannot continue.\n");
 			/* Probably a sun4e, Sun is trying to trick us ;-) */
-			halt();
+			prom_halt();
 		}
 		printk("Found %d CPU prom device tree node(s).\n", linux_num_cpus);
 	}
diff -Nru a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
--- a/arch/sparc/kernel/ioport.c	Mon Dec  9 18:46:51 2002
+++ b/arch/sparc/kernel/ioport.c	Mon Dec  9 18:46:51 2002
@@ -777,7 +777,7 @@
 	default:
 		printk("ioport_init: cpu type %d is unknown.\n",
 		    sparc_cpu_model);
-		halt();
+		prom_halt();
 	};
 
 }
diff -Nru a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c
--- a/arch/sparc/kernel/irq.c	Mon Dec  9 18:46:34 2002
+++ b/arch/sparc/kernel/irq.c	Mon Dec  9 18:46:34 2002
@@ -95,7 +95,7 @@
 struct irqaction static_irqaction[MAX_STATIC_ALLOC];
 int static_irq_count;
 
-struct irqaction *irq_action[NR_IRQS+1] = {
+struct irqaction *irq_action[NR_IRQS] = {
 	  NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL,
 	  NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL
 };
@@ -113,7 +113,7 @@
 		
 		return show_sun4d_interrupts(p, v);
 	}
-	for (i = 0 ; i < (NR_IRQS+1) ; i++) {
+	for (i = 0 ; i < NR_IRQS ; i++) {
 	        action = *(i + irq_action);
 		if (!action) 
 		        continue;
@@ -152,7 +152,7 @@
 		
 		return sun4d_free_irq(irq, dev_id);
 	}
-	cpu_irq = irq & NR_IRQS;
+	cpu_irq = irq & (NR_IRQS - 1);
 	action = *(cpu_irq + irq_action);
         if (cpu_irq > 14) {  /* 14 irq levels on the sparc */
                 printk("Trying to free bogus IRQ %d\n", irq);
@@ -391,7 +391,7 @@
 	struct irqaction * action;
 	unsigned int cpu_irq;
 	
-	cpu_irq = irq & NR_IRQS;
+	cpu_irq = irq & (NR_IRQS - 1);
 	action = *(cpu_irq + irq_action);
 
         printk("IO device interrupt, irq = %d\n", irq);
@@ -401,8 +401,8 @@
 		printk("Expecting: ");
         	for (i = 0; i < 16; i++)
                 	if (action->handler)
-                        	prom_printf("[%s:%d:0x%x] ", action->name,
-				    (int) i, (unsigned int) action->handler);
+                        	printk("[%s:%d:0x%x] ", action->name,
+				       (int) i, (unsigned int) action->handler);
 	}
         printk("AIEEE\n");
 	panic("bogus interrupt received");
@@ -469,7 +469,7 @@
 	extern struct tt_entry trapbase_cpu1, trapbase_cpu2, trapbase_cpu3;
 #endif
 	
-	cpu_irq = irq & NR_IRQS;
+	cpu_irq = irq & (NR_IRQS - 1);
 	if(cpu_irq > 14)
 		return -EINVAL;
 	if(!handler)
@@ -559,7 +559,7 @@
 					     unsigned long, const char *, void *);
 		return sun4d_request_irq(irq, handler, irqflags, devname, dev_id);
 	}
-	cpu_irq = irq & NR_IRQS;
+	cpu_irq = irq & (NR_IRQS - 1);
 	if(cpu_irq > 14)
 		return -EINVAL;
 
diff -Nru a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
--- a/arch/sparc/kernel/process.c	Mon Dec  9 18:46:35 2002
+++ b/arch/sparc/kernel/process.c	Mon Dec  9 18:46:35 2002
@@ -725,3 +725,39 @@
 			   "g1", "g2", "g3", "o0", "o1", "memory", "cc");
 	return retval;
 }
+
+extern void scheduling_functions_start_here(void);
+extern void scheduling_functions_end_here(void);
+
+unsigned long get_wchan(struct task_struct *task)
+{
+	unsigned long pc, fp, bias = 0;
+	unsigned long task_base = (unsigned long) task;
+        unsigned long ret = 0;
+	struct reg_window *rw;
+	int count = 0;
+
+	if (!task || task == current ||
+            task->state == TASK_RUNNING)
+		goto out;
+
+	fp = task->thread_info->ksp + bias;
+	do {
+		/* Bogus frame pointer? */
+		if (fp < (task_base + sizeof(struct task_struct)) ||
+		    fp >= (task_base + (2 * PAGE_SIZE)))
+			break;
+		rw = (struct reg_window *) fp;
+		pc = rw->ins[7];
+		if (pc < ((unsigned long) scheduling_functions_start_here) ||
+                    pc >= ((unsigned long) scheduling_functions_end_here)) {
+			ret = pc;
+			goto out;
+		}
+		fp = rw->ins[6] + bias;
+	} while (++count < 16);
+
+out:
+	return ret;
+}
+
diff -Nru a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c
--- a/arch/sparc/kernel/ptrace.c	Mon Dec  9 18:46:52 2002
+++ b/arch/sparc/kernel/ptrace.c	Mon Dec  9 18:46:52 2002
@@ -291,7 +291,8 @@
 			pt_error_return(regs, EPERM);
 			goto out;
 		}
-		if ((ret = security_ptrace(current->parent, current))) {
+		ret = security_ptrace(current->parent, current);
+		if (ret) {
 			pt_error_return(regs, -ret);
 			goto out;
 		}
diff -Nru a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
--- a/arch/sparc/kernel/signal.c	Mon Dec  9 18:46:50 2002
+++ b/arch/sparc/kernel/signal.c	Mon Dec  9 18:46:50 2002
@@ -1019,19 +1019,22 @@
 				   struct sigaction *sa)
 {
 	switch(regs->u_regs[UREG_I0]) {
-		case ERESTARTNOHAND:
-		no_system_call_restart:
-			regs->u_regs[UREG_I0] = EINTR;
-			regs->psr |= PSR_C;
-			break;
-		case ERESTARTSYS:
-			if(!(sa->sa_flags & SA_RESTART))
-				goto no_system_call_restart;
+	case ERESTART_RESTARTBLOCK:
+		current_thread_info()->restart_block.fn = do_no_restart_syscall;
+		/* fallthrough */
+	case ERESTARTNOHAND:
+	no_system_call_restart:
+		regs->u_regs[UREG_I0] = EINTR;
+		regs->psr |= PSR_C;
+		break;
+	case ERESTARTSYS:
+		if(!(sa->sa_flags & SA_RESTART))
+			goto no_system_call_restart;
 		/* fallthrough */
-		case ERESTARTNOINTR:
-			regs->u_regs[UREG_I0] = orig_i0;
-			regs->pc -= 4;
-			regs->npc -= 4;
+	case ERESTARTNOINTR:
+		regs->u_regs[UREG_I0] = orig_i0;
+		regs->pc -= 4;
+		regs->npc -= 4;
 	}
 }
 
@@ -1084,6 +1087,13 @@
 				regs->npc -= 4;
 				restart_syscall = 0;
 			}
+			if (restart_syscall &&
+			    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
+				regs->u_regs[UREG_G1] = __NR_restart_syscall;
+				regs->pc -= 4;
+				regs->npc -= 4;
+				restart_syscall = 0;
+			}
 			current->exit_code = signr;
 			set_current_state(TASK_STOPPED);
 
@@ -1181,6 +1191,12 @@
 	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
 		/* replay the system call when we are done */
 		regs->u_regs[UREG_I0] = orig_i0;
+		regs->pc -= 4;
+		regs->npc -= 4;
+	}
+	if (restart_syscall &&
+	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
+		regs->u_regs[UREG_G1] = __NR_restart_syscall;
 		regs->pc -= 4;
 		regs->npc -= 4;
 	}
diff -Nru a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
--- a/arch/sparc/kernel/sparc_ksyms.c	Mon Dec  9 18:46:34 2002
+++ b/arch/sparc/kernel/sparc_ksyms.c	Mon Dec  9 18:46:34 2002
@@ -90,11 +90,13 @@
 
 #define EXPORT_SYMBOL_DOT(sym)					\
 extern int __sparc_dot_ ## sym (int) __asm__("." #sym);		\
-__EXPORT_SYMBOL(__sparc_dot_ ## sym, "." #sym)
+const struct kernel_symbol __ksymtab___sparc_dot_##sym		\
+__attribute__((section("__ksymtab")))				\
+= { (unsigned long)&__sparc_dot_##sym , "." #sym }
 
 #define EXPORT_SYMBOL_PRIVATE(sym)				\
 extern int __sparc_priv_ ## sym (int) __asm__("__" #sym);	\
-const struct module_symbol __export_priv_##sym			\
+const struct kernel_symbol __export_priv_##sym			\
 __attribute__((section("__ksymtab"))) =				\
 { (unsigned long) &__sparc_priv_ ## sym, "__" #sym }
 
diff -Nru a/arch/sparc/kernel/sun4c_irq.c b/arch/sparc/kernel/sun4c_irq.c
--- a/arch/sparc/kernel/sun4c_irq.c	Mon Dec  9 18:46:34 2002
+++ b/arch/sparc/kernel/sun4c_irq.c	Mon Dec  9 18:46:34 2002
@@ -57,7 +57,7 @@
 	unsigned char current_mask, new_mask;
     
 	save_and_cli(flags);
-	irq_nr &= NR_IRQS;
+	irq_nr &= (NR_IRQS - 1);
 	current_mask = *interrupt_enable;
 	switch(irq_nr) {
 	case 1:
@@ -86,7 +86,7 @@
 	unsigned char current_mask, new_mask;
     
 	save_and_cli(flags);
-	irq_nr &= NR_IRQS;
+	irq_nr &= (NR_IRQS - 1);
 	current_mask = *interrupt_enable;
 	switch(irq_nr) {
 	case 1:
diff -Nru a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c
--- a/arch/sparc/kernel/sys_sunos.c	Mon Dec  9 18:46:36 2002
+++ b/arch/sparc/kernel/sys_sunos.c	Mon Dec  9 18:46:36 2002
@@ -34,6 +34,8 @@
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 
+#include <net/sock.h>
+
 #include <asm/uaccess.h>
 #ifndef KERNEL_DS
 #include <linux/segment.h>
diff -Nru a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S
--- a/arch/sparc/kernel/systbls.S	Mon Dec  9 18:46:37 2002
+++ b/arch/sparc/kernel/systbls.S	Mon Dec  9 18:46:37 2002
@@ -18,7 +18,7 @@
 
 	.globl sys_call_table
 sys_call_table:
-/*0*/	.long sys_nis_syscall, sys_exit, sys_fork, sys_read, sys_write
+/*0*/	.long sys_restart_syscall, sys_exit, sys_fork, sys_read, sys_write
 /*5*/	.long sys_open, sys_close, sys_wait4, sys_creat, sys_link
 /*10*/  .long sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys_mknod
 /*15*/	.long sys_chmod, sys_lchown16, sparc_brk, sys_nis_syscall, sys_lseek
diff -Nru a/arch/sparc/kernel/tick14.c b/arch/sparc/kernel/tick14.c
--- a/arch/sparc/kernel/tick14.c	Mon Dec  9 18:46:51 2002
+++ b/arch/sparc/kernel/tick14.c	Mon Dec  9 18:46:51 2002
@@ -16,6 +16,7 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/timex.h>
+#include <linux/interrupt.h>
 
 #include <asm/oplib.h>
 #include <asm/segment.h>
diff -Nru a/arch/sparc/mm/highmem.c b/arch/sparc/mm/highmem.c
--- a/arch/sparc/mm/highmem.c	Mon Dec  9 18:46:35 2002
+++ b/arch/sparc/mm/highmem.c	Mon Dec  9 18:46:35 2002
@@ -38,7 +38,7 @@
 		return page_address(page);
 
 	idx = type + KM_TYPE_NR*smp_processor_id();
-	vaddr = FIX_KMAP_BEGIN + idx * PAGE_SIZE;
+	vaddr = fix_kmap_begin + idx * PAGE_SIZE;
 
 /* XXX Fix - Anton */
 #if 0
@@ -67,12 +67,12 @@
 	unsigned long vaddr = (unsigned long) kvaddr;
 	unsigned long idx = type + KM_TYPE_NR*smp_processor_id();
 
-	if (vaddr < FIX_KMAP_BEGIN) { // FIXME
+	if (vaddr < fix_kmap_begin) { // FIXME
 		dec_preempt_count();
 		return;
 	}
 
-	if (vaddr != FIX_KMAP_BEGIN + idx * PAGE_SIZE)
+	if (vaddr != fix_kmap_begin + idx * PAGE_SIZE)
 		BUG();
 
 /* XXX Fix - Anton */
diff -Nru a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c
--- a/arch/sparc/mm/init.c	Mon Dec  9 18:46:36 2002
+++ b/arch/sparc/mm/init.c	Mon Dec  9 18:46:36 2002
@@ -59,13 +59,17 @@
 pte_t *kmap_pte;
 pgprot_t kmap_prot;
 
+/* These are set in {srmmu,sun4c}_paging_init() */
+unsigned long fix_kmap_begin;
+unsigned long fix_kmap_end;
+
 #define kmap_get_fixed_pte(vaddr) \
 	pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
 
 void __init kmap_init(void)
 {
 	/* cache the first kmap pte */
-	kmap_pte = kmap_get_fixed_pte(FIX_KMAP_BEGIN);
+	kmap_pte = kmap_get_fixed_pte(fix_kmap_begin);
 	kmap_prot = __pgprot(SRMMU_ET_PTE | SRMMU_PRIV | SRMMU_CACHE);
 }
 
diff -Nru a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
--- a/arch/sparc/mm/iommu.c	Mon Dec  9 18:46:51 2002
+++ b/arch/sparc/mm/iommu.c	Mon Dec  9 18:46:51 2002
@@ -192,9 +192,9 @@
 {
 	unsigned long page, oldpage = 0;
 
-	while(sz >= 0) {
+	while(sz != 0) {
 		--sz;
-		page = ((unsigned long) sg[sz].offset) & PAGE_MASK;
+		page = (unsigned long) page_address(sg[sz].page);
 		if (oldpage == page)
 			page += PAGE_SIZE; /* We flushed that page already */
 		while(page < (unsigned long)(page_address(sg[sz].page) + sg[sz].offset + sg[sz].length)) {
diff -Nru a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
--- a/arch/sparc/mm/srmmu.c	Mon Dec  9 18:46:38 2002
+++ b/arch/sparc/mm/srmmu.c	Mon Dec  9 18:46:38 2002
@@ -136,8 +136,16 @@
 
 int srmmu_cache_pagetables;
 
-/* XXX Make this dynamic based on ram size - Anton */
-#define SRMMU_NOCACHE_BITMAP_SIZE (SRMMU_NOCACHE_NPAGES * 16)
+/* these will be initialized in srmmu_nocache_calcsize() */
+int srmmu_nocache_npages;
+unsigned long srmmu_nocache_size;
+unsigned long srmmu_nocache_end;
+unsigned long pkmap_base;
+unsigned long pkmap_base_end;
+unsigned long srmmu_nocache_bitmap_size;
+extern unsigned long fix_kmap_begin;
+extern unsigned long fix_kmap_end;
+
 #define SRMMU_NOCACHE_BITMAP_SHIFT (PAGE_SHIFT - 4)
 
 void *srmmu_nocache_pool;
@@ -331,7 +339,7 @@
 	spin_lock(&srmmu_nocache_spinlock);
 
 repeat:
-	offset = find_next_zero_bit(srmmu_nocache_bitmap, SRMMU_NOCACHE_BITMAP_SIZE, offset);
+	offset = find_next_zero_bit(srmmu_nocache_bitmap, srmmu_nocache_bitmap_size, offset);
 
 	/* we align on physical address */
 	if (align) {
@@ -341,7 +349,7 @@
 		offset = (va_tmp - SRMMU_NOCACHE_VADDR) >> SRMMU_NOCACHE_BITMAP_SHIFT;
 	}
 
-	if ((SRMMU_NOCACHE_BITMAP_SIZE - offset) < size) {
+	if ((srmmu_nocache_bitmap_size - offset) < size) {
 		printk("Run out of nocached RAM!\n");
 		spin_unlock(&srmmu_nocache_spinlock);
 		return 0;
@@ -393,9 +401,9 @@
 		    vaddr, (unsigned long)SRMMU_NOCACHE_VADDR);
 		BUG();
 	}
-	if (vaddr >= SRMMU_NOCACHE_END) {
+	if (vaddr >= srmmu_nocache_end) {
 		printk("Vaddr %lx is bigger than nocache end 0x%lx\n",
-		    vaddr, (unsigned long)SRMMU_NOCACHE_END);
+		    vaddr, srmmu_nocache_end);
 		BUG();
 	}
 	if (size & (size-1)) {
@@ -429,6 +437,35 @@
 
 void srmmu_early_allocate_ptable_skeleton(unsigned long start, unsigned long end);
 
+extern unsigned long probe_memory(void);	/* in fault.c */
+
+/* Reserve nocache dynamically proportionally to the amount of
+ * system RAM. -- Tomas Szepe <szepe@pinerecords.com>, June 2002
+ */
+void srmmu_nocache_calcsize(void)
+{
+	unsigned long sysmemavail = probe_memory() / 1024;
+
+	srmmu_nocache_npages =
+		sysmemavail / SRMMU_NOCACHE_ALCRATIO / 1024 * 256;
+	if (sysmemavail % (SRMMU_NOCACHE_ALCRATIO * 1024))
+		srmmu_nocache_npages += 256;
+
+	/* anything above 1280 blows up */
+	if (srmmu_nocache_npages > 1280) srmmu_nocache_npages = 1280;
+
+	srmmu_nocache_size = srmmu_nocache_npages * PAGE_SIZE;
+	srmmu_nocache_bitmap_size = srmmu_nocache_npages * 16;
+	srmmu_nocache_end = SRMMU_NOCACHE_VADDR + srmmu_nocache_size;
+	fix_kmap_begin = srmmu_nocache_end;
+	fix_kmap_end = fix_kmap_begin + (KM_TYPE_NR * NR_CPUS - 1) * PAGE_SIZE;
+	pkmap_base = SRMMU_NOCACHE_VADDR + srmmu_nocache_size + 0x40000;
+	pkmap_base_end = pkmap_base + LAST_PKMAP * PAGE_SIZE;
+
+	/* printk("system memory available = %luk\nnocache ram size = %luk\n",
+		sysmemavail, srmmu_nocache_size / 1024); */
+}
+
 void srmmu_nocache_init(void)
 {
 	pgd_t *pgd;
@@ -437,24 +474,24 @@
 	unsigned long paddr, vaddr;
 	unsigned long pteval;
 
-	srmmu_nocache_pool = __alloc_bootmem(SRMMU_NOCACHE_SIZE, PAGE_SIZE, 0UL);
-	memset(srmmu_nocache_pool, 0, SRMMU_NOCACHE_SIZE);
+	srmmu_nocache_pool = __alloc_bootmem(srmmu_nocache_size, PAGE_SIZE, 0UL);
+	memset(srmmu_nocache_pool, 0, srmmu_nocache_size);
 
-	srmmu_nocache_bitmap = __alloc_bootmem(SRMMU_NOCACHE_BITMAP_SIZE, SMP_CACHE_BYTES, 0UL);
-	memset(srmmu_nocache_bitmap, 0, SRMMU_NOCACHE_BITMAP_SIZE);
+	srmmu_nocache_bitmap = __alloc_bootmem(srmmu_nocache_bitmap_size, SMP_CACHE_BYTES, 0UL);
+	memset(srmmu_nocache_bitmap, 0, srmmu_nocache_bitmap_size);
 
 	srmmu_swapper_pg_dir = (pgd_t *)__srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE);
 	memset(__nocache_fix(srmmu_swapper_pg_dir), 0, SRMMU_PGD_TABLE_SIZE);
 	init_mm.pgd = srmmu_swapper_pg_dir;
 
-	srmmu_early_allocate_ptable_skeleton(SRMMU_NOCACHE_VADDR, SRMMU_NOCACHE_END);
+	srmmu_early_allocate_ptable_skeleton(SRMMU_NOCACHE_VADDR, srmmu_nocache_end);
 
 	spin_lock_init(&srmmu_nocache_spinlock);
 
 	paddr = __pa((unsigned long)srmmu_nocache_pool);
 	vaddr = SRMMU_NOCACHE_VADDR;
 
-	while (vaddr < SRMMU_NOCACHE_END) {
+	while (vaddr < srmmu_nocache_end) {
 		pgd = pgd_offset_k(vaddr);
 		pmd = srmmu_pmd_offset(__nocache_fix(pgd), vaddr);
 		pte = srmmu_pte_offset(__nocache_fix(pmd), vaddr);
@@ -1286,6 +1323,7 @@
 	pages_avail = 0;
 	last_valid_pfn = bootmem_init(&pages_avail);
 
+	srmmu_nocache_calcsize();
 	srmmu_nocache_init();
         srmmu_inherit_prom_mappings(0xfe400000,(LINUX_OPPROM_ENDVM-PAGE_SIZE));
 	map_kernel();
@@ -1307,12 +1345,12 @@
 	srmmu_allocate_ptable_skeleton(DVMA_VADDR, DVMA_END);
 #endif
 
-	srmmu_allocate_ptable_skeleton(FIX_KMAP_BEGIN, FIX_KMAP_END);
-	srmmu_allocate_ptable_skeleton(PKMAP_BASE, PKMAP_BASE_END);
+	srmmu_allocate_ptable_skeleton(fix_kmap_begin, fix_kmap_end);
+	srmmu_allocate_ptable_skeleton(pkmap_base, pkmap_base_end);
 
-	pgd = pgd_offset_k(PKMAP_BASE);
-	pmd = srmmu_pmd_offset(pgd, PKMAP_BASE);
-	pte = srmmu_pte_offset(pmd, PKMAP_BASE);
+	pgd = pgd_offset_k(pkmap_base);
+	pmd = srmmu_pmd_offset(pgd, pkmap_base);
+	pte = srmmu_pte_offset(pmd, pkmap_base);
 	pkmap_page_table = pte;
 
 	flush_cache_all();
@@ -1359,7 +1397,7 @@
 		   "nocache used\t: %d\n",
 		   srmmu_name,
 		   num_contexts,
-		   SRMMU_NOCACHE_SIZE,
+		   srmmu_nocache_size,
 		   (srmmu_nocache_used << SRMMU_NOCACHE_BITMAP_SHIFT));
 }
 
diff -Nru a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
--- a/arch/sparc/mm/sun4c.c	Mon Dec  9 18:46:50 2002
+++ b/arch/sparc/mm/sun4c.c	Mon Dec  9 18:46:50 2002
@@ -2002,12 +2002,18 @@
 extern unsigned long bootmem_init(unsigned long *pages_avail);
 extern unsigned long last_valid_pfn;
 
+extern unsigned long fix_kmap_begin;
+extern unsigned long fix_kmap_end;
+
 void __init sun4c_paging_init(void)
 {
 	int i, cnt;
 	unsigned long kernel_end, vaddr;
 	extern struct resource sparc_iomap;
 	unsigned long end_pfn, pages_avail;
+
+	fix_kmap_begin = KERNBASE + SRMMU_MAXMEM; /* Why bother with SRMMU_MAXMEM? */
+	fix_kmap_end = fix_kmap_begin + ((KM_TYPE_NR*NR_CPUS)-1)*PAGE_SIZE;
 
 	kernel_end = (unsigned long) &end;
 	kernel_end += (SUN4C_REAL_PGDIR_SIZE * 4);
diff -Nru a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
--- a/arch/sparc64/Kconfig	Mon Dec  9 18:46:51 2002
+++ b/arch/sparc64/Kconfig	Mon Dec  9 18:46:51 2002
@@ -352,6 +352,11 @@
 	  This allows you to run 32-bit binaries on your Ultra.
 	  Everybody wants this; say Y.
 
+config COMPAT
+	bool
+	depends on SPARC32_COMPAT
+	default y
+
 config BINFMT_ELF32
 	tristate "Kernel support for 32-bit ELF binaries"
 	depends on SPARC32_COMPAT
@@ -525,19 +530,8 @@
 
 endmenu
 
-
-menu "Console drivers"
-
-config PROM_CONSOLE
-	bool "PROM console"
-	help
-	  Say Y to build a console driver for Sun machines that uses the
-	  terminal emulation built into their console PROMS.
-
 source "drivers/video/Kconfig"
 
-endmenu
-
 source "drivers/serial/Kconfig"
 
 source "drivers/sbus/char/Kconfig"
@@ -1641,6 +1635,7 @@
 
 endmenu
 
+source "arch/sparc64/oprofile/Kconfig"
 
 menu "Kernel hacking"
 
diff -Nru a/arch/sparc64/Makefile b/arch/sparc64/Makefile
--- a/arch/sparc64/Makefile	Mon Dec  9 18:46:51 2002
+++ b/arch/sparc64/Makefile	Mon Dec  9 18:46:51 2002
@@ -19,6 +19,7 @@
 NEW_GCC := $(shell if $(CC) -m64 -mcmodel=medlow -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo y; else echo n; fi; )
 NEW_GAS := $(shell if $(LD) -V 2>&1 | grep 'elf64_sparc' > /dev/null; then echo y; else echo n; fi)
 UNDECLARED_REGS := $(shell if $(CC) -c -x assembler /dev/null -Wa,--help | grep undeclared-regs > /dev/null; then echo y; else echo n; fi; )
+INLINE_LIMIT := $(shell if $(CC) -m64 -finline-limit=100000 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo y; else echo n; fi; )
 
 export NEW_GCC
 
@@ -51,6 +52,10 @@
   AFLAGS += -m64 -mcpu=ultrasparc $(CC_UNDECL)
 endif
 
+ifeq ($(INLINE_LIMIT),y)
+  CFLAGS := $(CFLAGS) -finline-limit=100000
+endif
+
 ifeq ($(CONFIG_MCOUNT),y)
   CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS))
   CFLAGS := $(CFLAGS) -pg
@@ -62,6 +67,9 @@
 core-$(CONFIG_SOLARIS_EMUL)	+= arch/sparc64/solaris/
 core-y				+= arch/sparc64/math-emu/
 libs-y				+= arch/sparc64/prom/ arch/sparc64/lib/
+
+# FIXME: is drivers- right?
+drivers-$(CONFIG_OPROFILE)	+= arch/sparc64/oprofile/
 
 makeboot =$(Q)$(MAKE) -f scripts/Makefile.build obj=arch/sparc64/boot $(1)
 
diff -Nru a/arch/sparc64/defconfig b/arch/sparc64/defconfig
--- a/arch/sparc64/defconfig	Mon Dec  9 18:46:35 2002
+++ b/arch/sparc64/defconfig	Mon Dec  9 18:46:35 2002
@@ -1,6 +1,8 @@
 #
 # Automatically generated make config: don't edit
 #
+CONFIG_MMU=y
+CONFIG_SWAP=y
 
 #
 # Code maturity level options
@@ -19,7 +21,8 @@
 # Loadable module support
 #
 CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_KMOD=y
 
 #
@@ -36,14 +39,8 @@
 CONFIG_SPARC64=y
 CONFIG_HOTPLUG=y
 CONFIG_HAVE_DEC_LOCK=y
-# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_GENERIC_ISA_DMA=y
-# CONFIG_ISA is not set
-# CONFIG_ISAPNP is not set
-# CONFIG_EISA is not set
-# CONFIG_MCA is not set
-# CONFIG_PCMCIA is not set
 CONFIG_SBUS=y
 CONFIG_SBUSCHAR=y
 CONFIG_SUN_AUXIO=y
@@ -54,6 +51,7 @@
 CONFIG_SUN_OPENPROMFS=m
 CONFIG_KCORE_ELF=y
 CONFIG_SPARC32_COMPAT=y
+CONFIG_COMPAT=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_AOUT32 is not set
 CONFIG_BINFMT_ELF=y
@@ -66,14 +64,8 @@
 #
 CONFIG_PARPORT=m
 CONFIG_PARPORT_PC=m
-CONFIG_PARPORT_PC_CML1=m
-# CONFIG_PARPORT_SERIAL is not set
 CONFIG_PARPORT_PC_FIFO=y
 # CONFIG_PARPORT_PC_SUPERIO is not set
-# CONFIG_PARPORT_AMIGA is not set
-# CONFIG_PARPORT_MFC3 is not set
-# CONFIG_PARPORT_ATARI is not set
-# CONFIG_PARPORT_GSC is not set
 # CONFIG_PARPORT_SUNBPP is not set
 # CONFIG_PARPORT_OTHER is not set
 CONFIG_PARPORT_1284=y
@@ -96,10 +88,13 @@
 # CONFIG_FB_CLGEN is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_RIVA is not set
-# CONFIG_FB_MATROX is not set
 CONFIG_FB_ATY=y
 CONFIG_FB_ATY_GX=y
+# CONFIG_FB_BWTWO is not set
+# CONFIG_FB_CGTHREE is not set
+CONFIG_FB_CGSIX=y
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
 CONFIG_FB_ATY_CT=y
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
@@ -111,13 +106,8 @@
 # CONFIG_FB_PM3 is not set
 CONFIG_FB_SBUS=y
 CONFIG_FB_CREATOR=y
-CONFIG_FB_CGSIX=y
-# CONFIG_FB_BWTWO is not set
-# CONFIG_FB_CGTHREE is not set
 # CONFIG_FB_LEO is not set
 CONFIG_FB_PCI=y
-CONFIG_FB_ATY=y
-CONFIG_FB_ATY_CT=y
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FBCON_ADVANCED is not set
 CONFIG_FBCON_CFB24=y
@@ -130,14 +120,6 @@
 # Serial drivers
 #
 # CONFIG_SERIAL_8250 is not set
-# CONFIG_SERIAL_8250_CONSOLE is not set
-# CONFIG_SERIAL_8250_CS is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
-# CONFIG_SERIAL_8250_RSA is not set
 
 #
 # Non-8250 serial port support
@@ -181,10 +163,8 @@
 CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID5 is not set
 # CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
 
 #
 # ATA/ATAPI/MFM/RLL device support
@@ -199,12 +179,10 @@
 #
 # Please see Documentation/ide.txt for help/info on IDE drives
 #
-# CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 # CONFIG_IDEDISK_STROKE is not set
-# CONFIG_BLK_DEV_IDECS is not set
 CONFIG_BLK_DEV_IDECD=y
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
@@ -213,53 +191,41 @@
 #
 # IDE chipset support/bugfixes
 #
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-# CONFIG_BLK_DEV_ISAPNP is not set
 CONFIG_BLK_DEV_IDEPCI=y
 # CONFIG_BLK_DEV_GENERIC is not set
 # CONFIG_IDEPCI_SHARE_IRQ is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDE_TCQ is not set
-# CONFIG_BLK_DEV_IDE_TCQ_DEFAULT is not set
 # CONFIG_BLK_DEV_OFFBOARD is not set
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
 CONFIG_IDEDMA_ONLYDISK=y
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_PCI_WIP is not set
-# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
 CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 CONFIG_BLK_DEV_ALI15X3=y
 # CONFIG_WDC_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
-# CONFIG_AMD74XX_OVERRIDE is not set
 CONFIG_BLK_DEV_CMD64X=y
 # CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
-# CONFIG_HPT34X_AUTODMA is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
 # CONFIG_BLK_DEV_NFORCE is not set
 CONFIG_BLK_DEV_NS87415=y
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
-# CONFIG_PDC202XX_BURST is not set
 # CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_PDC202XX_FORCE is not set
-# CONFIG_BLK_DEV_RZ1000 is not set
 # CONFIG_BLK_DEV_SVWKS is not set
 # CONFIG_BLK_DEV_SIIMAGE is not set
-# CONFIG_BLK_DEV_SIS5513 is not set
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_IDE_CHIPSETS is not set
 CONFIG_IDEDMA_AUTO=y
 # CONFIG_IDEDMA_IVB is not set
-# CONFIG_DMA_NONPCI is not set
 CONFIG_BLK_DEV_IDE_MODES=y
 
 #
@@ -329,12 +295,10 @@
 # Fusion MPT device support
 #
 CONFIG_FUSION=m
-# CONFIG_FUSION_BOOT is not set
 CONFIG_FUSION_MAX_SGE=40
 CONFIG_FUSION_ISENSE=m
 CONFIG_FUSION_CTL=m
 CONFIG_FUSION_LAN=m
-CONFIG_NET_FC=y
 
 #
 # IEEE 1394 (FireWire) support (EXPERIMENTAL)
@@ -350,6 +314,7 @@
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
+CONFIG_NET_KEY=m
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -359,12 +324,15 @@
 CONFIG_ARPD=y
 CONFIG_INET_ECN=y
 # CONFIG_SYN_COOKIES is not set
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_XFRM_USER=m
 CONFIG_IPV6=m
 
 #
-#    SCTP Configuration (EXPERIMENTAL)
+# SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=m
+CONFIG_IPV6_SCTP__=y
 CONFIG_IP_SCTP=m
 # CONFIG_SCTP_ADLER32 is not set
 # CONFIG_SCTP_DBG_MSG is not set
@@ -416,6 +384,11 @@
 CONFIG_NET_CLS_POLICE=y
 
 #
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -440,14 +413,7 @@
 CONFIG_SUNQE=m
 CONFIG_SUNGEM=y
 CONFIG_NET_VENDOR_3COM=y
-# CONFIG_EL1 is not set
-# CONFIG_EL2 is not set
-# CONFIG_ELPLUS is not set
-# CONFIG_EL16 is not set
-# CONFIG_ELMC is not set
-# CONFIG_ELMC_II is not set
 CONFIG_VORTEX=m
-# CONFIG_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 
@@ -463,21 +429,16 @@
 CONFIG_WINBOND_840=m
 # CONFIG_DM9102 is not set
 # CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=m
 CONFIG_ADAPTEC_STARFIRE=m
-# CONFIG_APRICOT is not set
-# CONFIG_CS89x0 is not set
+CONFIG_B44=m
 CONFIG_DGRS=m
 CONFIG_EEPRO100=m
 CONFIG_E100=m
-# CONFIG_LNE390 is not set
 CONFIG_FEALNX=m
 CONFIG_NATSEMI=m
 CONFIG_NE2K_PCI=m
-# CONFIG_NE3210 is not set
-# CONFIG_ES3210 is not set
 # CONFIG_8139CP is not set
 CONFIG_8139TOO=m
 # CONFIG_8139TOO_PIO is not set
@@ -499,11 +460,11 @@
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 # CONFIG_E1000 is not set
-# CONFIG_E1000_NAPI is not set
 CONFIG_MYRI_SBUS=m
 # CONFIG_NS83820 is not set
 CONFIG_HAMACHI=m
 CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
 CONFIG_SK98LIN=m
 CONFIG_TIGON3=m
 CONFIG_FDDI=y
@@ -514,7 +475,6 @@
 CONFIG_PLIP=m
 CONFIG_PPP=m
 # CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_FILTER is not set
 # CONFIG_PPP_ASYNC is not set
 # CONFIG_PPP_SYNC_TTY is not set
 # CONFIG_PPP_DEFLATE is not set
@@ -531,9 +491,8 @@
 # CONFIG_NET_RADIO is not set
 
 #
-# Token Ring devices
+# Token Ring devices (depends on LLC=y)
 #
-# CONFIG_TR is not set
 CONFIG_NET_FC=y
 # CONFIG_IPHASE5526 is not set
 # CONFIG_RCPCI is not set
@@ -563,13 +522,10 @@
 # CONFIG_MKISS is not set
 # CONFIG_6PACK is not set
 # CONFIG_BPQETHER is not set
-# CONFIG_SCC_DELAY is not set
-# CONFIG_SCC_TRXECHO is not set
 # CONFIG_BAYCOM_SER_FDX is not set
 # CONFIG_BAYCOM_SER_HDX is not set
 # CONFIG_BAYCOM_PAR is not set
 # CONFIG_BAYCOM_EPP is not set
-# CONFIG_SOUNDMODEM is not set
 # CONFIG_YAM is not set
 
 #
@@ -614,12 +570,6 @@
 #
 # CONFIG_GAMEPORT is not set
 CONFIG_SOUND_GAMEPORT=y
-# CONFIG_GAMEPORT_NS558 is not set
-# CONFIG_GAMEPORT_L4 is not set
-# CONFIG_GAMEPORT_EMU10K1 is not set
-# CONFIG_GAMEPORT_VORTEX is not set
-# CONFIG_GAMEPORT_FM801 is not set
-# CONFIG_GAMEPORT_CS461x is not set
 CONFIG_SERIO=y
 CONFIG_SERIO_I8042=y
 # CONFIG_SERIO_SERPORT is not set
@@ -637,34 +587,8 @@
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 CONFIG_MOUSE_SERIAL=y
-# CONFIG_MOUSE_INPORT is not set
-# CONFIG_MOUSE_LOGIBM is not set
-# CONFIG_MOUSE_PC110PAD is not set
 # CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_JOYSTICK_ANALOG is not set
-# CONFIG_JOYSTICK_A3D is not set
-# CONFIG_JOYSTICK_ADI is not set
-# CONFIG_JOYSTICK_COBRA is not set
-# CONFIG_JOYSTICK_GF2K is not set
-# CONFIG_JOYSTICK_GRIP is not set
-# CONFIG_JOYSTICK_GRIP_MP is not set
-# CONFIG_JOYSTICK_GUILLEMOT is not set
-# CONFIG_JOYSTICK_INTERACT is not set
-# CONFIG_JOYSTICK_SIDEWINDER is not set
-# CONFIG_JOYSTICK_TMDC is not set
-# CONFIG_JOYSTICK_IFORCE is not set
-# CONFIG_JOYSTICK_WARRIOR is not set
-# CONFIG_JOYSTICK_MAGELLAN is not set
-# CONFIG_JOYSTICK_SPACEORB is not set
-# CONFIG_JOYSTICK_SPACEBALL is not set
-# CONFIG_JOYSTICK_STINGER is not set
-# CONFIG_JOYSTICK_TWIDDLER is not set
-# CONFIG_JOYSTICK_DB9 is not set
-# CONFIG_JOYSTICK_GAMECON is not set
-# CONFIG_JOYSTICK_TURBOGRAFX is not set
-# CONFIG_INPUT_JOYDUMP is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_TOUCHSCREEN_GUNZE is not set
 CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_PCSPKR is not set
 CONFIG_INPUT_SPARCSPKR=y
@@ -674,30 +598,25 @@
 # File systems
 #
 # CONFIG_QUOTA is not set
-# CONFIG_QFMT_V1 is not set
-# CONFIG_QFMT_V2 is not set
+CONFIG_QUOTACTL=y
 CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 # CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
 CONFIG_AFFS_FS=m
 # CONFIG_HFS_FS is not set
 CONFIG_BEFS_FS=m
 # CONFIG_BEFS_DEBUG is not set
 CONFIG_BFS_FS=m
 CONFIG_EXT3_FS=m
-CONFIG_JBD=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FAT_FS=m
 CONFIG_MSDOS_FS=m
-# CONFIG_UMSDOS_FS is not set
 CONFIG_VFAT_FS=m
 CONFIG_EFS_FS=m
-# CONFIG_JFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
 CONFIG_RAMFS=y
@@ -705,32 +624,29 @@
 CONFIG_JOLIET=y
 # CONFIG_ZISOFS is not set
 CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
 # CONFIG_JFS_DEBUG is not set
 # CONFIG_JFS_STATISTICS is not set
 CONFIG_MINIX_FS=m
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_DEBUG is not set
-# CONFIG_NTFS_RW is not set
 CONFIG_HPFS_FS=m
 CONFIG_PROC_FS=y
 # CONFIG_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
 CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
 CONFIG_ROMFS_FS=m
 CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_SYSV_FS=m
 CONFIG_UDF_FS=m
-CONFIG_UDF_RW=y
 CONFIG_UFS_FS=m
 CONFIG_UFS_FS_WRITE=y
 CONFIG_XFS_FS=m
 # CONFIG_XFS_RT is not set
 CONFIG_XFS_QUOTA=y
-CONFIG_QUOTACTL=y
+CONFIG_XFS_POSIX_ACL=y
 
 #
 # Network File Systems
@@ -740,7 +656,6 @@
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
 CONFIG_NFS_V4=y
-# CONFIG_ROOT_NFS is not set
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
 CONFIG_NFSD_V4=y
@@ -752,16 +667,9 @@
 CONFIG_CIFS=m
 # CONFIG_SMB_FS is not set
 # CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_ZISOFS_FS is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_FS_POSIX_ACL=y
 
 #
 # Partition Types
@@ -769,7 +677,6 @@
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
 CONFIG_SUN_PARTITION=y
-# CONFIG_SMB_NLS is not set
 CONFIG_NLS=y
 
 #
@@ -838,8 +745,6 @@
 # CONFIG_SND_RTCTIMER is not set
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
-# CONFIG_SND_DEBUG_MEMORY is not set
-# CONFIG_SND_DEBUG_DETECT is not set
 
 #
 # Generic devices
@@ -900,7 +805,6 @@
 # Miscellaneous USB options
 #
 CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_LONG_TIMEOUT is not set
 # CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
 
@@ -909,7 +813,7 @@
 #
 CONFIG_USB_EHCI_HCD=m
 CONFIG_USB_OHCI_HCD=y
-# CONFIG_USB_UHCI_HCD_ALT is not set
+CONFIG_USB_UHCI_HCD=m
 
 #
 # USB Device Class drivers
@@ -936,8 +840,6 @@
 CONFIG_USB_HID=y
 CONFIG_USB_HIDINPUT=y
 # CONFIG_HID_FF is not set
-# CONFIG_HID_PID is not set
-# CONFIG_LOGITECH_FF is not set
 CONFIG_USB_HIDDEV=y
 # CONFIG_USB_AIPTEK is not set
 CONFIG_USB_WACOM=m
@@ -1011,21 +913,19 @@
 CONFIG_USB_SERIAL_MCT_U232=m
 CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_SERIAL_SAFE is not set
-# CONFIG_USB_SERIAL_SAFE_PADDED is not set
 CONFIG_USB_SERIAL_CYBERJACK=m
 CONFIG_USB_SERIAL_XIRCOM=m
 CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EZUSB=y
 
 #
 # USB Miscellaneous drivers
 #
-# CONFIG_USB_EMI26 is not set
 # CONFIG_USB_TIGL is not set
 CONFIG_USB_AUERSWALD=m
 CONFIG_USB_RIO500=m
 # CONFIG_USB_BRLVGER is not set
 CONFIG_USB_LCD=m
-# CONFIG_USB_SPEEDTOUCH is not set
 CONFIG_USB_TEST=m
 
 #
@@ -1048,9 +948,6 @@
 CONFIG_BT_HCIUART=m
 CONFIG_BT_HCIUART_H4=y
 CONFIG_BT_HCIUART_BCSP=y
-# CONFIG_BT_HCIDTL1 is not set
-# CONFIG_BT_HCIBT3C is not set
-# CONFIG_BT_HCIBLUECARD is not set
 CONFIG_BT_HCIVHCI=m
 
 #
@@ -1059,12 +956,19 @@
 # CONFIG_SOFT_WATCHDOG is not set
 
 #
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+
+#
 # Kernel hacking
 #
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SLAB is not set
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_DEBUG_DCFLUSH is not set
 # CONFIG_STACK_DEBUG is not set
@@ -1072,11 +976,25 @@
 #
 # Security options
 #
-CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+# CONFIG_CRYPTO_TEST is not set
 
 #
 # Library routines
 #
 CONFIG_CRC32=y
-# CONFIG_ZLIB_INFLATE is not set
-# CONFIG_ZLIB_DEFLATE is not set
diff -Nru a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
--- a/arch/sparc64/kernel/Makefile	Mon Dec  9 18:46:35 2002
+++ b/arch/sparc64/kernel/Makefile	Mon Dec  9 18:46:35 2002
@@ -16,6 +16,7 @@
 obj-$(CONFIG_PCI)	 += ebus.o isa.o pci_common.o pci_iommu.o \
 			    pci_psycho.o pci_sabre.o pci_schizo.o
 obj-$(CONFIG_SMP)	 += smp.o trampoline.o
+obj-$(CONFIG_PROFILING)  += profile.o
 obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o ioctl32.o
 obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o
 obj-$(CONFIG_BINFMT_AOUT32) += binfmt_aout32.o
diff -Nru a/arch/sparc64/kernel/binfmt_elf32.c b/arch/sparc64/kernel/binfmt_elf32.c
--- a/arch/sparc64/kernel/binfmt_elf32.c	Mon Dec  9 18:46:51 2002
+++ b/arch/sparc64/kernel/binfmt_elf32.c	Mon Dec  9 18:46:51 2002
@@ -86,11 +86,7 @@
 #include <linux/module.h>
 #include <linux/config.h>
 #include <linux/elfcore.h>
-
-struct timeval32
-{
-	int tv_sec, tv_usec;
-};
+#include <linux/compat.h>
 
 #define elf_prstatus elf_prstatus32
 struct elf_prstatus32
@@ -103,10 +99,10 @@
 	pid_t	pr_ppid;
 	pid_t	pr_pgrp;
 	pid_t	pr_sid;
-	struct timeval32 pr_utime;	/* User time */
-	struct timeval32 pr_stime;	/* System time */
-	struct timeval32 pr_cutime;	/* Cumulative user time */
-	struct timeval32 pr_cstime;	/* Cumulative system time */
+	struct compat_timeval pr_utime;	/* User time */
+	struct compat_timeval pr_stime;	/* System time */
+	struct compat_timeval pr_cutime;	/* Cumulative user time */
+	struct compat_timeval pr_cstime;	/* Cumulative system time */
 	elf_gregset_t pr_reg;	/* GP registers */
 	int pr_fpvalid;		/* True if math co-processor being used.  */
 };
@@ -136,9 +132,9 @@
 
 #include <linux/time.h>
 
-#define jiffies_to_timeval jiffies_to_timeval32
+#define jiffies_to_timeval jiffies_to_compat_timeval
 static __inline__ void
-jiffies_to_timeval32(unsigned long jiffies, struct timeval32 *value)
+jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
 {
 	value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
 	value->tv_sec = jiffies / HZ;
diff -Nru a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c
--- a/arch/sparc64/kernel/ioctl32.c	Mon Dec  9 18:46:51 2002
+++ b/arch/sparc64/kernel/ioctl32.c	Mon Dec  9 18:46:51 2002
@@ -10,6 +10,7 @@
 
 #include <linux/config.h>
 #include <linux/types.h>
+#include <linux/compat.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
@@ -405,14 +406,9 @@
 	return err;
 }
 
-struct timeval32 {
-	int tv_sec;
-	int tv_usec;
-};
-
 static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-	struct timeval32 *up = (struct timeval32 *)arg;
+	struct compat_timeval *up = (struct compat_timeval *)arg;
 	struct timeval ktv;
 	mm_segment_t old_fs = get_fs();
 	int err;
@@ -1743,8 +1739,8 @@
 #define PPPIOCSCOMPRESS32	_IOW('t', 77, struct ppp_option_data32)
 
 struct ppp_idle32 {
-	__kernel_time_t32 xmit_idle;
-	__kernel_time_t32 recv_idle;
+	compat_time_t xmit_idle;
+	compat_time_t recv_idle;
 };
 #define PPPIOCGIDLE32		_IOR('t', 63, struct ppp_idle32)
 
diff -Nru a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
--- a/arch/sparc64/kernel/process.c	Mon Dec  9 18:46:36 2002
+++ b/arch/sparc64/kernel/process.c	Mon Dec  9 18:46:36 2002
@@ -814,3 +814,41 @@
 out:
 	return error;
 }
+
+extern void scheduling_functions_start_here(void);
+extern void scheduling_functions_end_here(void);
+
+unsigned long get_wchan(struct task_struct *task)
+{
+	unsigned long pc, fp, bias = 0;
+	unsigned long thread_info_base;
+	struct reg_window *rw;
+        unsigned long ret = 0;
+	int count = 0; 
+
+	if (!task || task == current ||
+            task->state == TASK_RUNNING)
+		goto out;
+
+	thread_info_base = (unsigned long) task->thread_info;
+	bias = STACK_BIAS;
+	fp = task->thread_info->ksp + bias;
+
+	do {
+		/* Bogus frame pointer? */
+		if (fp < (thread_info_base + sizeof(struct thread_info)) ||
+		    fp >= (thread_info_base + THREAD_SIZE))
+			break;
+		rw = (struct reg_window *) fp;
+		pc = rw->ins[7];
+		if (pc < ((unsigned long) scheduling_functions_start_here) ||
+		    pc >= ((unsigned long) scheduling_functions_end_here)) {
+			ret = pc;
+			goto out;
+		}
+		fp = rw->ins[6] + bias;
+	} while (++count < 16);
+
+out:
+	return ret;
+}
diff -Nru a/arch/sparc64/kernel/profile.c b/arch/sparc64/kernel/profile.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/sparc64/kernel/profile.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,42 @@
+/* arch/sparc64/kernel/profile.c
+ *
+ * Almost entirely copied from ppc64 which is:
+ * (C) 2002 John Levon <levon@movementarian.org>
+ */
+
+#include <linux/profile.h>
+#include <linux/spinlock.h>
+#include <linux/notifier.h>
+#include <asm/irq.h>
+
+static struct notifier_block *profile_listeners;
+static rwlock_t profile_lock = RW_LOCK_UNLOCKED;
+
+int register_profile_notifier(struct notifier_block *nb)
+{
+	int err;
+
+	write_lock_irq(&profile_lock);
+	err = notifier_chain_register(&profile_listeners, nb);
+	write_unlock_irq(&profile_lock);
+
+	return err;
+}
+
+int unregister_profile_notifier(struct notifier_block *nb)
+{
+	int err;
+
+	write_lock_irq(&profile_lock);
+	err = notifier_chain_unregister(&profile_listeners, nb);
+	write_unlock_irq(&profile_lock);
+
+	return err;
+}
+
+void sparc64_profile_hook(struct pt_regs *regs)
+{
+	read_lock(&profile_lock);
+	notifier_call_chain(&profile_listeners, 0, regs);
+	read_unlock(&profile_lock);
+}
diff -Nru a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
--- a/arch/sparc64/kernel/ptrace.c	Mon Dec  9 18:46:51 2002
+++ b/arch/sparc64/kernel/ptrace.c	Mon Dec  9 18:46:51 2002
@@ -140,7 +140,8 @@
 			pt_error_return(regs, EPERM);
 			goto out;
 		}
-		if ((ret = security_ptrace(current->parent, current))) {
+		ret = security_ptrace(current->parent, current);
+		if (ret) {
 			pt_error_return(regs, -ret);
 			goto out;
 		}
diff -Nru a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
--- a/arch/sparc64/kernel/signal.c	Mon Dec  9 18:46:38 2002
+++ b/arch/sparc64/kernel/signal.c	Mon Dec  9 18:46:38 2002
@@ -573,19 +573,22 @@
 				     struct sigaction *sa)
 {
 	switch (regs->u_regs[UREG_I0]) {
-		case ERESTARTNOHAND:
-		no_system_call_restart:
-			regs->u_regs[UREG_I0] = EINTR;
-			regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
-			break;
-		case ERESTARTSYS:
-			if (!(sa->sa_flags & SA_RESTART))
-				goto no_system_call_restart;
+	case ERESTART_RESTARTBLOCK:
+		current_thread_info()->restart_block.fn = do_no_restart_syscall;
+		/* fallthrough */
+	case ERESTARTNOHAND:
+	no_system_call_restart:
+		regs->u_regs[UREG_I0] = EINTR;
+		regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
+		break;
+	case ERESTARTSYS:
+		if (!(sa->sa_flags & SA_RESTART))
+			goto no_system_call_restart;
 		/* fallthrough */
-		case ERESTARTNOINTR:
-			regs->u_regs[UREG_I0] = orig_i0;
-			regs->tpc -= 4;
-			regs->tnpc -= 4;
+	case ERESTARTNOINTR:
+		regs->u_regs[UREG_I0] = orig_i0;
+		regs->tpc -= 4;
+		regs->tnpc -= 4;
 	}
 }
 
@@ -634,6 +637,13 @@
 				regs->tnpc -= 4;
 				restart_syscall = 0;
 			}
+			if (restart_syscall &&
+			    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
+				regs->u_regs[UREG_G1] = __NR_restart_syscall;
+				regs->tpc -= 4;
+				regs->tnpc -= 4;
+				restart_syscall = 0;
+			}
 
 			current->exit_code = signr;
 			set_current_state(TASK_STOPPED);
@@ -724,6 +734,12 @@
 	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
 		/* replay the system call when we are done */
 		regs->u_regs[UREG_I0] = orig_i0;
+		regs->tpc -= 4;
+		regs->tnpc -= 4;
+	}
+	if (restart_syscall &&
+	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
+		regs->u_regs[UREG_G1] = __NR_restart_syscall;
 		regs->tpc -= 4;
 		regs->tnpc -= 4;
 	}
diff -Nru a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
--- a/arch/sparc64/kernel/signal32.c	Mon Dec  9 18:46:34 2002
+++ b/arch/sparc64/kernel/signal32.c	Mon Dec  9 18:46:34 2002
@@ -19,6 +19,7 @@
 #include <linux/tty.h>
 #include <linux/smp_lock.h>
 #include <linux/binfmts.h>
+#include <linux/compat.h>
 
 #include <asm/uaccess.h>
 #include <asm/bitops.h>
@@ -181,7 +182,7 @@
 	sigset_t32 set32;
         
 	/* XXX: Don't preclude handling different sized sigset_t's.  */
-	if (((__kernel_size_t32)sigsetsize) != sizeof(sigset_t)) {
+	if (((compat_size_t)sigsetsize) != sizeof(sigset_t)) {
 		regs->tstate |= TSTATE_ICARRY;
 		regs->u_regs[UREG_I0] = EINVAL;
 		return;
@@ -1252,19 +1253,22 @@
 				     struct sigaction *sa)
 {
 	switch (regs->u_regs[UREG_I0]) {
-		case ERESTARTNOHAND:
-		no_system_call_restart:
-			regs->u_regs[UREG_I0] = EINTR;
-			regs->tstate |= TSTATE_ICARRY;
-			break;
-		case ERESTARTSYS:
-			if (!(sa->sa_flags & SA_RESTART))
-				goto no_system_call_restart;
+	case ERESTART_RESTARTBLOCK:
+		current_thread_info()->restart_block.fn = do_no_restart_syscall;
+		/* fallthrough */
+	case ERESTARTNOHAND:
+	no_system_call_restart:
+		regs->u_regs[UREG_I0] = EINTR;
+		regs->tstate |= TSTATE_ICARRY;
+		break;
+	case ERESTARTSYS:
+		if (!(sa->sa_flags & SA_RESTART))
+			goto no_system_call_restart;
 		/* fallthrough */
-		case ERESTARTNOINTR:
-			regs->u_regs[UREG_I0] = orig_i0;
-			regs->tpc -= 4;
-			regs->tnpc -= 4;
+	case ERESTARTNOINTR:
+		regs->u_regs[UREG_I0] = orig_i0;
+		regs->tpc -= 4;
+		regs->tnpc -= 4;
 	}
 }
 
@@ -1305,6 +1309,13 @@
 				regs->tnpc -= 4;
 				restart_syscall = 0;
 			}
+			if (restart_syscall &&
+			    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
+				regs->u_regs[UREG_G1] = __NR_restart_syscall;
+				regs->tpc -= 4;
+				regs->tnpc -= 4;
+				restart_syscall = 0;
+			}
 
 			current->exit_code = signr;
 			set_current_state(TASK_STOPPED);
@@ -1394,6 +1405,12 @@
 	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
 		/* replay the system call when we are done */
 		regs->u_regs[UREG_I0] = orig_i0;
+		regs->tpc -= 4;
+		regs->tnpc -= 4;
+	}
+	if (restart_syscall &&
+	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
+		regs->u_regs[UREG_G1] = __NR_restart_syscall;
 		regs->tpc -= 4;
 		regs->tnpc -= 4;
 	}
diff -Nru a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
--- a/arch/sparc64/kernel/smp.c	Mon Dec  9 18:46:34 2002
+++ b/arch/sparc64/kernel/smp.c	Mon Dec  9 18:46:34 2002
@@ -145,28 +145,28 @@
 	 * purposes.  Also workaround BB_ERRATA_1 by doing a dummy
 	 * read back of %tick after writing it.
 	 */
-	__asm__ __volatile__("
-	sethi	%%hi(0x80000000), %%g1
-	ba,pt	%%xcc, 1f
-	 sllx	%%g1, 32, %%g1
-	.align	64
-1:	rd	%%tick, %%g2
-	add	%%g2, 6, %%g2
-	andn	%%g2, %%g1, %%g2
-	wrpr	%%g2, 0, %%tick
-	rdpr	%%tick, %%g0"
+	__asm__ __volatile__(
+	"sethi	%%hi(0x80000000), %%g1\n\t"
+	"ba,pt	%%xcc, 1f\n\t"
+	" sllx	%%g1, 32, %%g1\n\t"
+	".align	64\n"
+"1:	rd	%%tick, %%g2\n\t"
+	"add	%%g2, 6, %%g2\n\t"
+	"andn	%%g2, %%g1, %%g2\n\t"
+	"wrpr	%%g2, 0, %%tick\n\t"
+	"rdpr	%%tick, %%g0"
 	: /* no outputs */
 	: /* no inputs */
 	: "g1", "g2");
 
 	if (SPARC64_USE_STICK) {
 		/* Let the user get at STICK too. */
-		__asm__ __volatile__("
-			sethi	%%hi(0x80000000), %%g1
-			sllx	%%g1, 32, %%g1
-			rd	%%asr24, %%g2
-			andn	%%g2, %%g1, %%g2
-			wr	%%g2, 0, %%asr24"
+		__asm__ __volatile__(
+			"sethi	%%hi(0x80000000), %%g1\n\t"
+			"sllx	%%g1, 32, %%g1\n\t"
+			"rd	%%asr24, %%g2\n\t"
+			"andn	%%g2, %%g1, %%g2\n\t"
+			"wr	%%g2, 0, %%asr24"
 		: /* no outputs */
 		: /* no inputs */
 		: "g1", "g2");
@@ -283,18 +283,18 @@
 	 * ADDR 0x20) for the dummy read. -DaveM
 	 */
 	tmp = 0x40;
-	__asm__ __volatile__("
-	wrpr	%1, %2, %%pstate
-	stxa	%4, [%0] %3
-	stxa	%5, [%0+%8] %3
-	add	%0, %8, %0
-	stxa	%6, [%0+%8] %3
-	membar	#Sync
-	stxa	%%g0, [%7] %3
-	membar	#Sync
-	mov	0x20, %%g1
-	ldxa	[%%g1] 0x7f, %%g0
-	membar	#Sync"
+	__asm__ __volatile__(
+	"wrpr	%1, %2, %%pstate\n\t"
+	"stxa	%4, [%0] %3\n\t"
+	"stxa	%5, [%0+%8] %3\n\t"
+	"add	%0, %8, %0\n\t"
+	"stxa	%6, [%0+%8] %3\n\t"
+	"membar	#Sync\n\t"
+	"stxa	%%g0, [%7] %3\n\t"
+	"membar	#Sync\n\t"
+	"mov	0x20, %%g1\n\t"
+	"ldxa	[%%g1] 0x7f, %%g0\n\t"
+	"membar	#Sync"
 	: "=r" (tmp)
 	: "r" (pstate), "i" (PSTATE_IE), "i" (ASI_INTR_W),
 	  "r" (data0), "r" (data1), "r" (data2), "r" (target),
@@ -926,7 +926,7 @@
 	smp_cross_call(&xcall_promstop, 0, 0, 0);
 }
 
-extern void sparc64_do_profile(unsigned long pc, unsigned long o7);
+extern void sparc64_do_profile(struct pt_regs *regs);
 
 static unsigned long current_tick_offset;
 
@@ -960,9 +960,7 @@
 	}
 
 	do {
-		if (!user)
-			sparc64_do_profile(regs->tpc,
-					   regs->u_regs[UREG_RETPC]);
+		sparc64_do_profile(regs);
 		if (!--prof_counter(cpu)) {
 			if (cpu == boot_cpu_id) {
 				irq_enter();
@@ -1054,21 +1052,21 @@
 	 * read back from %tick_cmpr right after writing to it. -DaveM
 	 */
 	if (!SPARC64_USE_STICK) {
-	__asm__ __volatile__("
-		rd	%%tick, %%g1
-		ba,pt	%%xcc, 1f
-		 add	%%g1, %0, %%g1
-		.align	64
-	1:	wr	%%g1, 0x0, %%tick_cmpr
-		rd	%%tick_cmpr, %%g0"
+	__asm__ __volatile__(
+		"rd	%%tick, %%g1\n\t"
+		"ba,pt	%%xcc, 1f\n\t"
+		" add	%%g1, %0, %%g1\n\t"
+		".align	64\n"
+	"1:	wr	%%g1, 0x0, %%tick_cmpr\n\t"
+		"rd	%%tick_cmpr, %%g0"
 	: /* no outputs */
 	: "r" (current_tick_offset)
 	: "g1");
 	} else {
-	__asm__ __volatile__("
-		rd	%%asr24, %%g1
-		add	%%g1, %0, %%g1
-		wr	%%g1, 0x0, %%asr25"
+	__asm__ __volatile__(
+		"rd	%%asr24, %%g1\n\t"
+		"add	%%g1, %0, %%g1\n\t"
+		"wr	%%g1, 0x0, %%asr25"
 	: /* no outputs */
 	: "r" (current_tick_offset)
 	: "g1");
diff -Nru a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
--- a/arch/sparc64/kernel/sparc64_ksyms.c	Mon Dec  9 18:46:50 2002
+++ b/arch/sparc64/kernel/sparc64_ksyms.c	Mon Dec  9 18:46:50 2002
@@ -190,6 +190,7 @@
 EXPORT_SYMBOL(get_fb_unmapped_area);
 EXPORT_SYMBOL(flush_icache_range);
 EXPORT_SYMBOL(flush_dcache_page);
+EXPORT_SYMBOL(__flush_dcache_range);
 
 EXPORT_SYMBOL(mostek_lock);
 EXPORT_SYMBOL(mstk48t02_regs);
@@ -373,3 +374,8 @@
 
 /* for ns8703 */
 EXPORT_SYMBOL(ns87303_lock);
+
+#ifdef CONFIG_PROFILING
+EXPORT_SYMBOL_GPL(register_profile_notifier);
+EXPORT_SYMBOL_GPL(unregister_profile_notifier);
+#endif
diff -Nru a/arch/sparc64/kernel/sys32.S b/arch/sparc64/kernel/sys32.S
--- a/arch/sparc64/kernel/sys32.S	Mon Dec  9 18:46:35 2002
+++ b/arch/sparc64/kernel/sys32.S	Mon Dec  9 18:46:35 2002
@@ -175,7 +175,7 @@
 	 lduwa		[%o1 + 0x4] %asi, %o1
 	nop
 	nop
-do_sys_sendto: /* sys32_sendto(int, u32, __kernel_size_t32, unsigned int, u32, int) */
+do_sys_sendto: /* sys32_sendto(int, u32, compat_size_t, unsigned int, u32, int) */
 	ldswa		[%o1 + 0x0] %asi, %o0
 	sethi		%hi(sys32_sendto), %g1
 	lduwa		[%o1 + 0x8] %asi, %o2
@@ -184,7 +184,7 @@
 	ldswa		[%o1 + 0x14] %asi, %o5
 	jmpl		%g1 + %lo(sys32_sendto), %g0
 	 lduwa		[%o1 + 0x4] %asi, %o1
-do_sys_recvfrom: /* sys32_recvfrom(int, u32, __kernel_size_t32, unsigned int, u32, u32) */
+do_sys_recvfrom: /* sys32_recvfrom(int, u32, compat_size_t, unsigned int, u32, u32) */
 	ldswa		[%o1 + 0x0] %asi, %o0
 	sethi		%hi(sys32_recvfrom), %g1
 	lduwa		[%o1 + 0x8] %asi, %o2
diff -Nru a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
--- a/arch/sparc64/kernel/sys_sparc32.c	Mon Dec  9 18:46:49 2002
+++ b/arch/sparc64/kernel/sys_sparc32.c	Mon Dec  9 18:46:49 2002
@@ -15,7 +15,6 @@
 #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>
@@ -51,6 +50,8 @@
 #include <linux/sysctl.h>
 #include <linux/binfmts.h>
 #include <linux/dnotify.h>
+#include <linux/security.h>
+#include <linux/compat.h>
 
 #include <asm/types.h>
 #include <asm/ipc.h>
@@ -262,49 +263,20 @@
 
 /* 32-bit timeval and related flotsam.  */
 
-struct timeval32
-{
-    int tv_sec, tv_usec;
-};
-
-struct itimerval32
-{
-    struct timeval32 it_interval;
-    struct timeval32 it_value;
-};
-
-static long get_tv32(struct timeval *o, struct timeval32 *i)
+static long get_tv32(struct timeval *o, struct compat_timeval *i)
 {
 	return (!access_ok(VERIFY_READ, tv32, sizeof(*tv32)) ||
 		(__get_user(o->tv_sec, &i->tv_sec) |
 		 __get_user(o->tv_usec, &i->tv_usec)));
 }
 
-static inline long put_tv32(struct timeval32 *o, struct timeval *i)
+static inline long put_tv32(struct compat_timeval *o, struct timeval *i)
 {
 	return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
 		(__put_user(i->tv_sec, &o->tv_sec) |
 		 __put_user(i->tv_usec, &o->tv_usec)));
 }
 
-static inline long get_it32(struct itimerval *o, struct itimerval32 *i)
-{
-	return (!access_ok(VERIFY_READ, i32, sizeof(*i32)) ||
-		(__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
-		 __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
-		 __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
-		 __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
-}
-
-static long put_it32(struct itimerval32 *o, struct itimerval *i)
-{
-	return (!access_ok(VERIFY_WRITE, i32, sizeof(*i32)) ||
-		(__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
-		 __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
-		 __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
-		 __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
-}
-
 extern asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on);
 
 asmlinkage int sys32_ioperm(u32 from, u32 num, int on)
@@ -327,8 +299,8 @@
 
 struct semid_ds32 {
         struct ipc_perm32 sem_perm;               /* permissions .. see ipc.h */
-        __kernel_time_t32 sem_otime;              /* last semop time */
-        __kernel_time_t32 sem_ctime;              /* last change time */
+        compat_time_t   sem_otime;              /* last semop time */
+        compat_time_t   sem_ctime;              /* last change time */
         u32 sem_base;              /* ptr to first semaphore in array */
         u32 sem_pending;          /* pending operations to be processed */
         u32 sem_pending_last;    /* last pending operation */
@@ -339,9 +311,9 @@
 struct semid64_ds32 {
 	struct ipc64_perm sem_perm;		  /* this structure is the same on sparc32 and sparc64 */
 	unsigned int	  __pad1;
-	__kernel_time_t32 sem_otime;
+	compat_time_t   sem_otime;
 	unsigned int	  __pad2;
-	__kernel_time_t32 sem_ctime;
+	compat_time_t   sem_ctime;
 	u32 sem_nsems;
 	u32 __unused1;
 	u32 __unused2;
@@ -352,9 +324,9 @@
         struct ipc_perm32 msg_perm;
         u32 msg_first;
         u32 msg_last;
-        __kernel_time_t32 msg_stime;
-        __kernel_time_t32 msg_rtime;
-        __kernel_time_t32 msg_ctime;
+        compat_time_t   msg_stime;
+        compat_time_t   msg_rtime;
+        compat_time_t   msg_ctime;
         u32 wwait;
         u32 rwait;
         unsigned short msg_cbytes;
@@ -367,11 +339,11 @@
 struct msqid64_ds32 {
 	struct ipc64_perm msg_perm;
 	unsigned int   __pad1;
-	__kernel_time_t32 msg_stime;
+	compat_time_t   msg_stime;
 	unsigned int   __pad2;
-	__kernel_time_t32 msg_rtime;
+	compat_time_t   msg_rtime;
 	unsigned int   __pad3;
-	__kernel_time_t32 msg_ctime;
+	compat_time_t   msg_ctime;
 	unsigned int  msg_cbytes;
 	unsigned int  msg_qnum;
 	unsigned int  msg_qbytes;
@@ -385,9 +357,9 @@
 struct shmid_ds32 {
 	struct ipc_perm32       shm_perm;
 	int                     shm_segsz;
-	__kernel_time_t32       shm_atime;
-	__kernel_time_t32       shm_dtime;
-	__kernel_time_t32       shm_ctime;
+	compat_time_t         shm_atime;
+	compat_time_t         shm_dtime;
+	compat_time_t         shm_ctime;
 	__kernel_ipc_pid_t32    shm_cpid; 
 	__kernel_ipc_pid_t32    shm_lpid; 
 	unsigned short          shm_nattch;
@@ -396,12 +368,12 @@
 struct shmid64_ds32 {
 	struct ipc64_perm	shm_perm;
 	unsigned int		__pad1;
-	__kernel_time_t32	shm_atime;
+	compat_time_t  	shm_atime;
 	unsigned int		__pad2;
-	__kernel_time_t32	shm_dtime;
+	compat_time_t  	shm_dtime;
 	unsigned int		__pad3;
-	__kernel_time_t32	shm_ctime;
-	__kernel_size_t32	shm_segsz;
+	compat_time_t  	shm_ctime;
+	compat_size_t	shm_segsz;
 	__kernel_pid_t32	shm_cpid;
 	__kernel_pid_t32	shm_lpid;
 	unsigned int		shm_nattch;
@@ -964,37 +936,7 @@
 		return sys_ftruncate(fd, (high << 32) | low);
 }
 
-extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
-
-struct utimbuf32 {
-	__kernel_time_t32 actime, modtime;
-};
-
-asmlinkage int sys32_utime(char * filename, struct utimbuf32 *times)
-{
-	struct utimbuf t;
-	mm_segment_t old_fs;
-	int ret;
-	char *filenam;
-	
-	if (!times)
-		return sys_utime(filename, NULL);
-	if (get_user (t.actime, &times->actime) ||
-	    __get_user (t.modtime, &times->modtime))
-		return -EFAULT;
-	filenam = getname (filename);
-	ret = PTR_ERR(filenam);
-	if (!IS_ERR(filenam)) {
-		old_fs = get_fs();
-		set_fs (KERNEL_DS); 
-		ret = sys_utime(filenam, &t);
-		set_fs (old_fs);
-		putname (filenam);
-	}
-	return ret;
-}
-
-struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; };
+struct iovec32 { u32 iov_base; compat_size_t iov_len; };
 
 typedef ssize_t (*io_fn_t)(struct file *, char *, size_t, loff_t *);
 typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *);
@@ -1002,7 +944,7 @@
 static long do_readv_writev32(int type, struct file *file,
 			      const struct iovec32 *vector, u32 count)
 {
-	__kernel_ssize_t32 tot_len;
+	compat_ssize_t tot_len;
 	struct iovec iovstack[UIO_FASTIOV];
 	struct iovec *iov=iovstack, *ivp;
 	struct inode *inode;
@@ -1010,40 +952,58 @@
 	io_fn_t fn;
 	iov_fn_t fnv;
 
+	/*
+	 * SuS says "The readv() function *may* fail if the iovcnt argument
+	 * was less than or equal to 0, or greater than {IOV_MAX}.  Linux has
+	 * traditionally returned zero for zero segments, so...
+	 */
+	retval = 0;
+	if (count == 0)
+		goto out;
+
 	/* First get the "struct iovec" from user memory and
 	 * verify all the pointers
 	 */
-	retval = 0;
-	if (!count)
-		goto out_nofree;
-	retval = -EFAULT;
-	if (verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count))
-		goto out_nofree;
 	retval = -EINVAL;
 	if (count > UIO_MAXIOV)
-		goto out_nofree;
+		goto out;
+	if (!file->f_op)
+		goto out;
 	if (count > UIO_FASTIOV) {
 		retval = -ENOMEM;
 		iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
 		if (!iov)
-			goto out_nofree;
+			goto out;
 	}
+	retval = -EFAULT;
+	if (verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count))
+		goto out;
 
+	/*
+	 * Single unix specification:
+	 * We should -EINVAL if an element length is not >= 0 and fitting an
+	 * ssize_t.  The total length is fitting an ssize_t
+	 *
+	 * Be careful here because iov_len is a size_t not an ssize_t
+	 */
 	tot_len = 0;
 	i = count;
 	ivp = iov;
 	retval = -EINVAL;
 	while(i > 0) {
-		__kernel_ssize_t32 tmp = tot_len;
-		__kernel_ssize_t32 len;
+		compat_ssize_t tmp = tot_len;
+		compat_ssize_t len;
 		u32 buf;
 
-		__get_user(len, &vector->iov_len);
-		__get_user(buf, &vector->iov_base);
-		if (len < 0)	/* size_t not fittina an ssize_t32 .. */
+		if (__get_user(len, &vector->iov_len) ||
+		    __get_user(buf, &vector->iov_base)) {
+			retval = -EFAULT;
+			goto out;
+		}
+		if (len < 0)	/* size_t not fitting an ssize_t32 .. */
 			goto out;
 		tot_len += len;
-		if (tot_len < tmp) /* maths overflow on the ssize_t32 */
+		if (tot_len < tmp) /* maths overflow on the compat_ssize_t */
 			goto out;
 		ivp->iov_base = (void *)A(buf);
 		ivp->iov_len = (__kernel_size_t) len;
@@ -1051,25 +1011,32 @@
 		ivp++;
 		i--;
 	}
+	if (tot_len == 0) {
+		retval = 0;
+		goto out;
+	}
 
 	inode = file->f_dentry->d_inode;
 	/* VERIFY_WRITE actually means a read, as we write to user space */
-	retval = locks_verify_area((type == VERIFY_WRITE
+	retval = locks_verify_area((type == READ
 				    ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE),
 				   inode, file, file->f_pos, tot_len);
 	if (retval)
 		goto out;
 
-	/* VERIFY_WRITE actually means a read, as we write to user space */
-	fnv = (type == VERIFY_WRITE ? file->f_op->readv : file->f_op->writev);
+	if (type == READ) {
+		fn = file->f_op->read;
+		fnv = file->f_op->readv;
+	} else {
+		fn = (io_fn_t)file->f_op->write;
+		fnv = file->f_op->writev;
+	}
 	if (fnv) {
 		retval = fnv(file, iov, count, &file->f_pos);
 		goto out;
 	}
 
-	fn = (type == VERIFY_WRITE ? file->f_op->read :
-	      (io_fn_t) file->f_op->write);
-
+	/* Do it by hand, with file-ops */
 	ivp = iov;
 	while (count > 0) {
 		void * base;
@@ -1079,7 +1046,9 @@
 		len = ivp->iov_len;
 		ivp++;
 		count--;
+
 		nr = fn(file, base, len, &file->f_pos);
+
 		if (nr < 0) {
 			if (!retval)
 				retval = nr;
@@ -1092,11 +1061,9 @@
 out:
 	if (iov != iovstack)
 		kfree(iov);
-out_nofree:
-	/* VERIFY_WRITE actually means a read, as we write to user space */
-	if ((retval + (type == VERIFY_WRITE)) > 0)
+	if ((retval + (type == READ)) > 0)
 		dnotify_parent(file->f_dentry,
-			(type == VERIFY_WRITE) ? DN_MODIFY : DN_ACCESS);
+			(type == READ) ? DN_ACCESS : DN_MODIFY);
 
 	return retval;
 }
@@ -1104,35 +1071,46 @@
 asmlinkage long sys32_readv(int fd, struct iovec32 *vector, u32 count)
 {
 	struct file *file;
-	long ret = -EBADF;
+	int ret;
 
 	file = fget(fd);
 	if(!file)
-		goto bad_file;
+		return -EBADF;
 
-	if (file->f_op && (file->f_mode & FMODE_READ) &&
-	    (file->f_op->readv || file->f_op->read))
-		ret = do_readv_writev32(VERIFY_WRITE, file, vector, count);
-	fput(file);
+	ret = -EBADF;
+	if (!(file->f_mode & FMODE_READ))
+		goto out;
+	ret = -EINVAL;
+	if (!file->f_op || (!file->f_op->readv && !file->f_op->read))
+		goto out;
+
+	ret = do_readv_writev32(READ, file, vector, count);
 
-bad_file:
+out:
+	fput(file);
 	return ret;
 }
 
 asmlinkage long sys32_writev(int fd, struct iovec32 *vector, u32 count)
 {
 	struct file *file;
-	int ret = -EBADF;
+	int ret;
 
 	file = fget(fd);
 	if(!file)
-		goto bad_file;
-	if (file->f_op && (file->f_mode & FMODE_WRITE) &&
-	    (file->f_op->writev || file->f_op->write))
-		ret = do_readv_writev32(VERIFY_READ, file, vector, count);
-	fput(file);
+		return -EBADF;
+
+	ret = -EBADF;
+	if (!(file->f_mode & FMODE_WRITE))
+		goto out;
+	ret = -EINVAL;
+	if (!file->f_op || (!file->f_op->writev && !file->f_op->write))
+		goto out;
+
+	ret = do_readv_writev32(WRITE, file, vector, count);
 
-bad_file:
+out:
+	fput(file);
 	return ret;
 }
 
@@ -1330,7 +1308,7 @@
 asmlinkage int sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, u32 tvp_x)
 {
 	fd_set_bits fds;
-	struct timeval32 *tvp = (struct timeval32 *)AA(tvp_x);
+	struct compat_timeval *tvp = (struct compat_timeval *)AA(tvp_x);
 	char *bits;
 	unsigned long nn;
 	long timeout;
@@ -1691,8 +1669,8 @@
 }
 
 struct rusage32 {
-        struct timeval32 ru_utime;
-        struct timeval32 ru_stime;
+        struct compat_timeval ru_utime;
+        struct compat_timeval ru_stime;
         s32    ru_maxrss;
         s32    ru_ixrss;
         s32    ru_idrss;
@@ -1794,14 +1772,9 @@
 	return ret;
 }
 
-struct timespec32 {
-	s32    tv_sec;
-	s32    tv_nsec;
-};
-                
 extern asmlinkage int sys_sched_rr_get_interval(pid_t pid, struct timespec *interval);
 
-asmlinkage int sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
+asmlinkage int sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct compat_timespec *interval)
 {
 	struct timespec t;
 	int ret;
@@ -1816,28 +1789,6 @@
 	return ret;
 }
 
-extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
-
-asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
-	struct timespec t;
-	int ret;
-	mm_segment_t old_fs = get_fs ();
-	
-	if (get_user (t.tv_sec, &rqtp->tv_sec) ||
-	    __get_user (t.tv_nsec, &rqtp->tv_nsec))
-		return -EFAULT;
-	set_fs (KERNEL_DS);
-	ret = sys_nanosleep(&t, rmtp ? &t : NULL);
-	set_fs (old_fs);
-	if (rmtp && ret == -EINTR) {
-		if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
-	    	    __put_user (t.tv_nsec, &rmtp->tv_nsec))
-			return -EFAULT;
-	}
-	return ret;
-}
-
 extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset);
 
 asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset)
@@ -1857,7 +1808,7 @@
 
 extern asmlinkage int sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, size_t sigsetsize);
 
-asmlinkage int sys32_rt_sigprocmask(int how, sigset_t32 *set, sigset_t32 *oset, __kernel_size_t32 sigsetsize)
+asmlinkage int sys32_rt_sigprocmask(int how, sigset_t32 *set, sigset_t32 *oset, compat_size_t sigsetsize)
 {
 	sigset_t s;
 	sigset_t32 s32;
@@ -1908,7 +1859,7 @@
 
 extern asmlinkage int sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
 
-asmlinkage int sys32_rt_sigpending(sigset_t32 *set, __kernel_size_t32 sigsetsize)
+asmlinkage int sys32_rt_sigpending(sigset_t32 *set, compat_size_t sigsetsize)
 {
 	sigset_t s;
 	sigset_t32 s32;
@@ -1933,7 +1884,7 @@
 
 asmlinkage int
 sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo,
-		      struct timespec32 *uts, __kernel_size_t32 sigsetsize)
+		      struct compat_timespec *uts, compat_size_t sigsetsize)
 {
 	int ret, sig;
 	sigset_t these;
@@ -2138,14 +2089,14 @@
         u32               msg_name;
         int               msg_namelen;
         u32               msg_iov;
-        __kernel_size_t32 msg_iovlen;
+        compat_size_t msg_iovlen;
         u32               msg_control;
-        __kernel_size_t32 msg_controllen;
+        compat_size_t msg_controllen;
         unsigned          msg_flags;
 };
 
 struct cmsghdr32 {
-        __kernel_size_t32 cmsg_len;
+        compat_size_t cmsg_len;
         int               cmsg_level;
         int               cmsg_type;
 };
@@ -2279,7 +2230,7 @@
 {
 	struct cmsghdr32 *ucmsg;
 	struct cmsghdr *kcmsg, *kcmsg_base;
-	__kernel_size_t32 ucmlen;
+	compat_size_t ucmlen;
 	__kernel_size_t kcmlen, tmp;
 
 	kcmlen = 0;
@@ -2645,7 +2596,7 @@
 		err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
 	if(cmsg_ptr != 0 && err >= 0) {
 		unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control);
-		__kernel_size_t32 uclen = (__kernel_size_t32) (ucmsg_ptr - cmsg_ptr);
+		compat_size_t uclen = (compat_size_t) (ucmsg_ptr - cmsg_ptr);
 		err |= __put_user(uclen, &user_msg->msg_controllen);
 	}
 	if(err >= 0)
@@ -2733,7 +2684,7 @@
 
 static int do_set_sock_timeout(int fd, int level, int optname, char *optval, int optlen)
 {
-	struct timeval32 *up = (struct timeval32 *) optval;
+	struct compat_timeval *up = (struct compat_timeval *) optval;
 	struct timeval ktime;
 	mm_segment_t old_fs;
 	int err;
@@ -2771,7 +2722,7 @@
 
 static int do_get_sock_timeout(int fd, int level, int optname, char *optval, int *optlen)
 {
-	struct timeval32 *up = (struct timeval32 *) optval;
+	struct compat_timeval *up = (struct compat_timeval *) optval;
 	struct timeval ktime;
 	mm_segment_t old_fs;
 	int len, err;
@@ -2842,7 +2793,7 @@
 
 asmlinkage int
 sys32_rt_sigaction(int sig, struct sigaction32 *act, struct sigaction32 *oact,
-		   void *restorer, __kernel_size_t32 sigsetsize)
+		   void *restorer, compat_size_t sigsetsize)
 {
         struct k_sigaction new_ka, old_ka;
         int ret;
@@ -3026,7 +2977,8 @@
 	if ((retval = bprm.envc) < 0)
 		goto out_mm;
 
-	if ((retval = security_bprm_alloc(&bprm)))
+	retval = security_bprm_alloc(&bprm);
+	if (retval)
 		goto out;
 
 	retval = prepare_binprm(&bprm);
@@ -3479,7 +3431,7 @@
 extern struct timezone sys_tz;
 extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
 
-asmlinkage int sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
+asmlinkage int sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz)
 {
 	if (tv) {
 		struct timeval ktv;
@@ -3494,7 +3446,7 @@
 	return 0;
 }
 
-asmlinkage int sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
+asmlinkage int sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz)
 {
 	struct timeval ktv;
 	struct timezone ktz;
@@ -3511,46 +3463,9 @@
 	return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
 }
 
-extern int do_getitimer(int which, struct itimerval *value);
-
-asmlinkage int sys32_getitimer(int which, struct itimerval32 *it)
-{
-	struct itimerval kit;
-	int error;
-
-	error = do_getitimer(which, &kit);
-	if (!error && put_it32(it, &kit))
-		error = -EFAULT;
-
-	return error;
-}
-
-extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
-
-asmlinkage int sys32_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out)
-{
-	struct itimerval kin, kout;
-	int error;
-
-	if (in) {
-		if (get_it32(&kin, in))
-			return -EFAULT;
-	} else
-		memset(&kin, 0, sizeof(kin));
-
-	error = do_setitimer(which, &kin, out ? &kout : NULL);
-	if (error || !out)
-		return error;
-	if (put_it32(out, &kout))
-		return -EFAULT;
-
-	return 0;
-
-}
-
 asmlinkage int sys_utimes(char *, struct timeval *);
 
-asmlinkage int sys32_utimes(char *filename, struct timeval32 *tvs)
+asmlinkage int sys32_utimes(char *filename, struct compat_timeval *tvs)
 {
 	char *kfilename;
 	struct timeval ktvs[2];
@@ -3634,23 +3549,21 @@
 extern asmlinkage ssize_t sys_pwrite64(unsigned int fd, const char * buf,
 				     size_t count, loff_t pos);
 
-typedef __kernel_ssize_t32 ssize_t32;
-
-asmlinkage ssize_t32 sys32_pread64(unsigned int fd, char *ubuf,
-				   __kernel_size_t32 count, u32 poshi, u32 poslo)
+asmlinkage compat_ssize_t sys32_pread64(unsigned int fd, char *ubuf,
+				   compat_size_t count, u32 poshi, u32 poslo)
 {
 	return sys_pread64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
 }
 
-asmlinkage ssize_t32 sys32_pwrite64(unsigned int fd, char *ubuf,
-				    __kernel_size_t32 count, u32 poshi, u32 poslo)
+asmlinkage compat_ssize_t sys32_pwrite64(unsigned int fd, char *ubuf,
+				    compat_size_t count, u32 poshi, u32 poslo)
 {
 	return sys_pwrite64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
 }
 
 extern asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count);
 
-asmlinkage ssize_t32 sys32_readahead(int fd, u32 offhi, u32 offlo, s32 count)
+asmlinkage compat_ssize_t sys32_readahead(int fd, u32 offhi, u32 offlo, s32 count)
 {
 	return sys_readahead(fd, ((loff_t)AA(offhi) << 32) | AA(offlo), count);
 }
@@ -3703,7 +3616,7 @@
 	u32 modes;
 	s32 offset, freq, maxerror, esterror;
 	s32 status, constant, precision, tolerance;
-	struct timeval32 time;
+	struct compat_timeval time;
 	s32 tick;
 	s32 ppsfreq, jitter, shift, stabil;
 	s32 jitcnt, calcnt, errcnt, stbcnt;
@@ -3957,4 +3870,12 @@
 	}
 
 	return ret;
+}
+
+extern int sys_lookup_dcookie(u64 cookie64, char *buf, size_t len);
+
+int sys32_lookup_dcookie(u32 cookie_high, u32 cookie_low, char *buf, size_t len)
+{
+	return sys_lookup_dcookie((u64)cookie_high << 32 | cookie_low,
+				  buf, len);
 }
diff -Nru a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
--- a/arch/sparc64/kernel/sys_sunos32.c	Mon Dec  9 18:46:38 2002
+++ b/arch/sparc64/kernel/sys_sunos32.c	Mon Dec  9 18:46:38 2002
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/types.h>
+#include <linux/compat.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
@@ -528,11 +529,6 @@
 extern asmlinkage int
 sys32_select(int n, u32 inp, u32 outp, u32 exp, u32 tvp);
 
-struct timeval32
-{
-	int tv_sec, tv_usec;
-};
-
 asmlinkage int sunos_select(int width, u32 inp, u32 outp, u32 exp, u32 tvp_x)
 {
 	int ret;
@@ -540,7 +536,7 @@
 	/* SunOS binaries expect that select won't change the tvp contents */
 	ret = sys32_select (width, inp, outp, exp, tvp_x);
 	if (ret == -EINTR && tvp_x) {
-		struct timeval32 *tvp = (struct timeval32 *)A(tvp_x);
+		struct compat_timeval *tvp = (struct compat_timeval *)A(tvp_x);
 		time_t sec, usec;
 
 		__get_user(sec, &tvp->tv_sec);
@@ -948,9 +944,9 @@
         struct ipc_perm32 msg_perm;
         u32 msg_first;
         u32 msg_last;
-        __kernel_time_t32 msg_stime;
-        __kernel_time_t32 msg_rtime;
-        __kernel_time_t32 msg_ctime;
+        compat_time_t msg_stime;
+        compat_time_t msg_rtime;
+        compat_time_t msg_ctime;
         u32 wwait;
         u32 rwait;
         unsigned short msg_cbytes;
@@ -1085,9 +1081,9 @@
 struct shmid_ds32 {
         struct ipc_perm32       shm_perm;
         int                     shm_segsz;
-        __kernel_time_t32       shm_atime;
-        __kernel_time_t32       shm_dtime;
-        __kernel_time_t32       shm_ctime;
+        compat_time_t         shm_atime;
+        compat_time_t         shm_dtime;
+        compat_time_t         shm_ctime;
         __kernel_ipc_pid_t32    shm_cpid; 
         __kernel_ipc_pid_t32    shm_lpid; 
         unsigned short          shm_nattch;
diff -Nru a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
--- a/arch/sparc64/kernel/systbls.S	Mon Dec  9 18:46:36 2002
+++ b/arch/sparc64/kernel/systbls.S	Mon Dec  9 18:46:36 2002
@@ -19,13 +19,13 @@
 
 	.globl sys_call_table32
 sys_call_table32:
-/*0*/	.word sys_nis_syscall, sparc_exit, sys_fork, sys_read, sys_write
+/*0*/	.word sys_restart_syscall, sparc_exit, sys_fork, sys_read, sys_write
 /*5*/	.word sparc32_open, sys_close, sys32_wait4, sys_creat, sys_link
 /*10*/  .word sys_unlink, sunos_execv, sys_chdir, sys32_chown16, sys32_mknod
 /*15*/	.word sys32_chmod, sys32_lchown16, sparc_brk, sys_perfctr, sys32_lseek
 /*20*/	.word sys_getpid, sys_capget, sys_capset, sys32_setuid16, sys32_getuid16
 /*25*/	.word sys_time, sys_ptrace, sys_alarm, sys32_sigaltstack, sys32_pause
-/*30*/	.word sys32_utime, sys_lchown, sys_fchown, sys_access, sys_nice
+/*30*/	.word compat_sys_utime, sys_lchown, sys_fchown, sys_access, sys_nice
 	.word sys_chown, sys_sync, sys_kill, sys32_newstat, sys32_sendfile
 /*40*/	.word sys32_newlstat, sys_dup, sys_pipe, sys32_times, sys_getuid
 	.word sys_umount, sys32_setgid16, sys32_getgid16, sys_signal, sys32_geteuid16
@@ -35,8 +35,8 @@
 	.word sys_msync, sys_vfork, sys32_pread64, sys32_pwrite64, sys_geteuid
 /*70*/	.word sys_getegid, sys32_mmap, sys_setreuid, sys_munmap, sys_mprotect
 	.word sys_madvise, sys_vhangup, sys32_truncate64, sys_mincore, sys32_getgroups16
-/*80*/	.word sys32_setgroups16, sys_getpgrp, sys_setgroups, sys32_setitimer, sys32_ftruncate64
-	.word sys_swapon, sys32_getitimer, sys_setuid, sys_sethostname, sys_setgid
+/*80*/	.word sys32_setgroups16, sys_getpgrp, sys_setgroups, compat_sys_setitimer, sys32_ftruncate64
+	.word sys_swapon, compat_sys_getitimer, sys_setuid, sys_sethostname, sys_setgid
 /*90*/	.word sys_dup2, sys_setfsuid, sys32_fcntl, sys32_select, sys_setfsgid
 	.word sys_fsync, sys_setpriority32, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
 /*100*/ .word sys_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending
@@ -60,7 +60,7 @@
 /*190*/	.word sys32_init_module, sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl
 	.word sys_epoll_wait, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask
 /*200*/	.word sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys_uselib, old32_readdir
-	.word sys32_readahead, sys32_socketcall, sys_syslog, sys_lookup_dcookie, sys_nis_syscall
+	.word sys32_readahead, sys32_socketcall, sys_syslog, sys32_lookup_dcookie, sys_nis_syscall
 /*210*/	.word sys_nis_syscall, sys_nis_syscall, sys_waitpid, sys_swapoff, sys32_sysinfo
 	.word sys32_ipc, sys32_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex
 /*220*/	.word sys32_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys_getpgid
@@ -68,7 +68,7 @@
 /*230*/	.word sys32_select, sys_time, sys_nis_syscall, sys_stime, sys_alloc_hugepages
 	.word sys_free_hugepages, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
 /*240*/	.word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
-	.word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys32_sched_rr_get_interval, sys32_nanosleep
+	.word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep
 /*250*/	.word sys32_mremap, sys32_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl
 	.word sys_aplib
 
@@ -78,7 +78,7 @@
 	.globl sys_call_table64, sys_call_table
 sys_call_table64:
 sys_call_table:
-/*0*/	.word sys_nis_syscall, sparc_exit, sys_fork, sys_read, sys_write
+/*0*/	.word sys_restart_syscall, sparc_exit, sys_fork, sys_read, sys_write
 /*5*/	.word sys_open, sys_close, sys_wait4, sys_creat, sys_link
 /*10*/  .word sys_unlink, sunos_execv, sys_chdir, sys_chown, sys_mknod
 /*15*/	.word sys_chmod, sys_lchown, sparc_brk, sys_perfctr, sys_lseek
@@ -166,8 +166,8 @@
 	.word sys_mprotect, sys_madvise, sys_vhangup
 	.word sunos_nosys, sys_mincore, sys32_getgroups16
 	.word sys32_setgroups16, sys_getpgrp, sunos_setpgrp
-	.word sys32_setitimer, sunos_nosys, sys_swapon
-	.word sys32_getitimer, sys_gethostname, sys_sethostname
+	.word compat_sys_setitimer, sunos_nosys, sys_swapon
+	.word compat_sys_getitimer, sys_gethostname, sys_sethostname
 	.word sunos_getdtablesize, sys_dup2, sunos_nop
 	.word sys32_fcntl, sunos_select, sunos_nop
 	.word sys_fsync, sys_setpriority32, sunos_socket
diff -Nru a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
--- a/arch/sparc64/kernel/time.c	Mon Dec  9 18:46:37 2002
+++ b/arch/sparc64/kernel/time.c	Mon Dec  9 18:46:37 2002
@@ -84,9 +84,23 @@
 	}
 }
 
-void sparc64_do_profile(unsigned long pc, unsigned long o7)
+void sparc64_do_profile(struct pt_regs *regs)
 {
-	if (prof_buffer && current->pid) {
+	unsigned long pc = regs->tpc;
+	unsigned long o7 = regs->u_regs[UREG_RETPC];
+#ifdef CONFIG_PROFILING
+	extern void sparc64_profile_hook(struct pt_regs *);
+
+	sparc64_profile_hook(regs);
+#endif
+
+	if (user_mode(regs))
+		return;
+
+	if (!prof_buffer)
+		return;
+
+	{
 		extern int _stext;
 		extern int rwlock_impl_begin, rwlock_impl_end;
 		extern int atomic_impl_begin, atomic_impl_end;
@@ -123,8 +137,7 @@
 
 	do {
 #ifndef CONFIG_SMP
-		if ((regs->tstate & TSTATE_PRIV) != 0)
-			sparc64_do_profile(regs->tpc, regs->u_regs[UREG_RETPC]);
+		sparc64_do_profile(regs);
 #endif
 		do_timer(regs);
 
diff -Nru a/arch/sparc64/oprofile/Kconfig b/arch/sparc64/oprofile/Kconfig
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/sparc64/oprofile/Kconfig	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,23 @@
+
+menu "Profiling support"
+	depends on EXPERIMENTAL
+
+config PROFILING
+	bool "Profiling support (EXPERIMENTAL)"
+	help
+	  Say Y here to enable the extended profiling support mechanisms used
+	  by profilers such as OProfile.
+	  
+
+config OPROFILE
+	tristate "OProfile system profiling (EXPERIMENTAL)"
+	depends on PROFILING
+	help
+	  OProfile is a profiling system capable of profiling the
+	  whole system, include the kernel, kernel modules, libraries,
+	  and applications.
+
+	  If unsure, say N.
+
+endmenu
+
diff -Nru a/arch/sparc64/oprofile/Makefile b/arch/sparc64/oprofile/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/sparc64/oprofile/Makefile	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,8 @@
+obj-$(CONFIG_OPROFILE) += oprofile.o
+
+DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
+		oprof.o cpu_buffer.o buffer_sync.o \
+		event_buffer.o oprofile_files.o \
+		oprofilefs.o oprofile_stats.o )
+
+oprofile-y				:= $(DRIVER_OBJS) init.o timer_int.o
diff -Nru a/arch/sparc64/oprofile/init.c b/arch/sparc64/oprofile/init.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/sparc64/oprofile/init.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,20 @@
+/**
+ * @file init.c
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon <levon@movementarian.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/oprofile.h>
+#include <linux/init.h>
+ 
+extern void timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu);
+
+int __init oprofile_arch_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu)
+{
+	timer_init(ops, cpu);
+	return 0;
+}
diff -Nru a/arch/sparc64/oprofile/timer_int.c b/arch/sparc64/oprofile/timer_int.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/sparc64/oprofile/timer_int.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,56 @@
+/**
+ * @file timer_int.c
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon <levon@movementarian.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/notifier.h>
+#include <linux/smp.h>
+#include <linux/irq.h>
+#include <linux/oprofile.h>
+#include <asm/ptrace.h>
+ 
+static int timer_notify(struct notifier_block * self, unsigned long val, void * data)
+{
+	struct pt_regs * regs = (struct pt_regs *)data;
+	int cpu = smp_processor_id();
+ 
+	oprofile_add_sample(instruction_pointer(regs), 0, cpu);
+	return 0;
+}
+ 
+ 
+static struct notifier_block timer_notifier = {
+	.notifier_call	= timer_notify,
+};
+ 
+
+static int timer_start(void)
+{
+	return register_profile_notifier(&timer_notifier);
+}
+
+
+static void timer_stop(void)
+{
+	unregister_profile_notifier(&timer_notifier);
+}
+
+
+static struct oprofile_operations timer_ops = {
+	.start	= timer_start,
+	.stop	= timer_stop
+};
+
+ 
+void __init timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu)
+{
+	*ops = &timer_ops;
+	*cpu = OPROFILE_CPU_TIMER;
+	printk(KERN_INFO "oprofile: using timer interrupt.\n");
+}
diff -Nru a/arch/sparc64/solaris/ioctl.c b/arch/sparc64/solaris/ioctl.c
--- a/arch/sparc64/solaris/ioctl.c	Mon Dec  9 18:46:38 2002
+++ b/arch/sparc64/solaris/ioctl.c	Mon Dec  9 18:46:38 2002
@@ -369,6 +369,7 @@
 	case 106: /* SI_GETINTRANSIT */
 	case 107: /* SI_TCL_LINK */
 	case 108: /* SI_TCL_UNLINK */
+		;
 	}
 	return TNOTSUPPORT;
 }
@@ -456,6 +457,7 @@
 	case 145: /* TI_GETPEERNAME */
 	case 146: /* TI_SETMYNAME */
 	case 147: /* TI_SETPEERNAME */
+		;
 	}
 	return TNOTSUPPORT;
 }
diff -Nru a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
--- a/arch/sparc64/solaris/misc.c	Mon Dec  9 18:46:51 2002
+++ b/arch/sparc64/solaris/misc.c	Mon Dec  9 18:46:51 2002
@@ -16,6 +16,7 @@
 #include <linux/file.h>
 #include <linux/timex.h>
 #include <linux/major.h>
+#include <linux/compat.h>
 
 #include <asm/uaccess.h>
 #include <asm/string.h>
@@ -597,12 +598,8 @@
 	return ret;
 }
 
-struct timeval32 {
-	int tv_sec, tv_usec;
-};
-
 struct sol_ntptimeval {
-	struct timeval32 time;
+	struct compat_timeval time;
 	s32 maxerror;
 	s32 esterror;
 };
diff -Nru a/arch/sparc64/solaris/socket.c b/arch/sparc64/solaris/socket.c
--- a/arch/sparc64/solaris/socket.c	Mon Dec  9 18:46:50 2002
+++ b/arch/sparc64/solaris/socket.c	Mon Dec  9 18:46:50 2002
@@ -14,6 +14,7 @@
 #include <linux/socket.h>
 #include <linux/file.h>
 #include <linux/net.h>
+#include <linux/compat.h>
 
 #include <asm/uaccess.h>
 #include <asm/string.h>
@@ -378,7 +379,7 @@
 	if(kern_msg.msg_controllen) {
 		struct sol_cmsghdr *ucmsg = (struct sol_cmsghdr *)kern_msg.msg_control;
 		unsigned long *kcmsg;
-		__kernel_size_t32 cmlen;
+		compat_size_t cmlen;
 
 		if(kern_msg.msg_controllen > sizeof(ctl) &&
 		   kern_msg.msg_controllen <= 256) {
@@ -392,7 +393,7 @@
 		*kcmsg++ = (unsigned long)cmlen;
 		err = -EFAULT;
 		if(copy_from_user(kcmsg, &ucmsg->cmsg_level,
-				  kern_msg.msg_controllen - sizeof(__kernel_size_t32)))
+				  kern_msg.msg_controllen - sizeof(compat_size_t)))
 			goto out_freectl;
 		kern_msg.msg_control = ctl_buf;
 	}
diff -Nru a/arch/sparc64/solaris/socksys.c b/arch/sparc64/solaris/socksys.c
--- a/arch/sparc64/solaris/socksys.c	Mon Dec  9 18:46:36 2002
+++ b/arch/sparc64/solaris/socksys.c	Mon Dec  9 18:46:36 2002
@@ -171,8 +171,6 @@
 	.release =	socksys_release,
 };
 
-static devfs_handle_t devfs_handle;
-
 int __init
 init_socksys(void)
 {
@@ -193,10 +191,10 @@
 		printk ("Couldn't create socket\n");
 		return ret;
 	}
-	devfs_handle = devfs_register (NULL, "socksys", DEVFS_FL_DEFAULT,
-				       30, 0,
-				       S_IFCHR | S_IRUSR | S_IWUSR,
-				       &socksys_fops, NULL);
+	devfs_register (NULL, "socksys", DEVFS_FL_DEFAULT,
+		       30, 0,
+		       S_IFCHR | S_IRUSR | S_IWUSR,
+		       &socksys_fops, NULL);
 	file = fcheck(ret);
 	/* N.B. Is this valid? Suppose the f_ops are in a module ... */
 	socksys_file_ops = *file->f_op;
@@ -212,5 +210,5 @@
 {
 	if (unregister_chrdev(30, "socksys"))
 		printk ("Couldn't unregister socksys character device\n");
-	devfs_unregister (devfs_handle);
+	devfs_remove ("socksys");
 }
diff -Nru a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
--- a/arch/um/kernel/ptrace.c	Mon Dec  9 18:46:35 2002
+++ b/arch/um/kernel/ptrace.c	Mon Dec  9 18:46:35 2002
@@ -33,7 +33,8 @@
 		if (current->ptrace & PT_PTRACED)
 			goto out;
 
-		if ((ret = security_ptrace(current->parent, current)))
+		ret = security_ptrace(current->parent, current);
+		if (ret)
  			goto out;
 
 		/* set the ptrace bit in the process flags. */
diff -Nru a/arch/um/kernel/sys_call_table.c b/arch/um/kernel/sys_call_table.c
--- a/arch/um/kernel/sys_call_table.c	Mon Dec  9 18:46:50 2002
+++ b/arch/um/kernel/sys_call_table.c	Mon Dec  9 18:46:50 2002
@@ -485,9 +485,9 @@
 	[ __NR_free_hugepages ] = sys_ni_syscall,
 	[ __NR_exit_group ] = sys_exit_group,
 	[ __NR_lookup_dcookie ] = sys_lookup_dcookie,
-	[ __NR_sys_epoll_create ] = sys_epoll_create,
-	[ __NR_sys_epoll_ctl ] = sys_epoll_ctl,
-	[ __NR_sys_epoll_wait ] = sys_epoll_wait,
+	[ __NR_epoll_create ] = sys_epoll_create,
+	[ __NR_epoll_ctl ] = sys_epoll_ctl,
+	[ __NR_epoll_wait ] = sys_epoll_wait,
         [ __NR_remap_file_pages ] = sys_remap_file_pages,
 
 	ARCH_SYSCALLS
diff -Nru a/arch/v850/Kconfig b/arch/v850/Kconfig
--- a/arch/v850/Kconfig	Mon Dec  9 18:46:36 2002
+++ b/arch/v850/Kconfig	Mon Dec  9 18:46:36 2002
@@ -365,42 +365,7 @@
 
 source "fs/Kconfig"
 
-
-menu "Console drivers"
-	depends on VT
-
-config VGA_CONSOLE
-	bool "VGA text console"
-	help
-	  Saying Y here will allow you to use Linux in text mode through a
-	  display that complies with the generic VGA standard. Virtually
-	  everyone wants that.
-
-	  The program SVGATextMode can be used to utilize SVGA video cards to
-	  their full potential in text mode. Download it from
-	  <ftp://ibiblio.org/pub/Linux/utils/console/>.
-
-	  If unsure, say N.
-
-config VIDEO_SELECT
-	bool "Video mode selection support"
-	---help---
-	  This enables support for text mode selection on kernel startup. If
-	  you want to take advantage of some high-resolution text mode your
-	  card's BIOS offers, but the traditional Linux utilities like
-	  SVGATextMode don't, you can say Y here and set the mode using the
-	  "vga=" option from your boot loader (lilo or loadlin) or set
-	  "vga=ask" which brings up a video mode menu on kernel startup. (Try
-	  "man bootparam" or see the documentation of your boot loader about
-	  how to pass options to the kernel.)
-
-	  Read the file <file:Documentation/svga.txt> for more information
-	  about the Video mode selection support. If unsure, say N.
-
 source "drivers/video/Kconfig"
-
-endmenu
-
 
 menu "Sound"
 
diff -Nru a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
--- a/arch/x86_64/Kconfig	Mon Dec  9 18:46:50 2002
+++ b/arch/x86_64/Kconfig	Mon Dec  9 18:46:50 2002
@@ -588,62 +588,7 @@
 
 source "fs/Kconfig"
 
-
-menu "Console drivers"
-	depends on VT
-
-config VGA_CONSOLE
-	bool "VGA text console"
-	help
-	  Saying Y here will allow you to use Linux in text mode through a
-	  display that complies with the generic VGA standard. Virtually
-	  everyone wants that.
-
-	  The program SVGATextMode can be used to utilize SVGA video cards to
-	  their full potential in text mode. Download it from
-	  <ftp://ibiblio.org/pub/Linux/utils/console/>.
-
-	  Say Y.
-
-config VIDEO_SELECT
-	bool "Video mode selection support"
-	---help---
-	  This enables support for text mode selection on kernel startup. If
-	  you want to take advantage of some high-resolution text mode your
-	  card's BIOS offers, but the traditional Linux utilities like
-	  SVGATextMode don't, you can say Y here and set the mode using the
-	  "vga=" option from your boot loader (lilo or loadlin) or set
-	  "vga=ask" which brings up a video mode menu on kernel startup. (Try
-	  "man bootparam" or see the documentation of your boot loader about
-	  how to pass options to the kernel.)
-
-	  Read the file <file:Documentation/svga.txt> for more information
-	  about the Video mode selection support. If unsure, say N.
-
-if EXPERIMENTAL
-
-config MDA_CONSOLE
-	tristate "MDA text console (dual-headed) (EXPERIMENTAL)"
-	---help---
-	  Say Y here if you have an old MDA or monochrome Hercules graphics
-	  adapter in your system acting as a second head ( = video card). You
-	  will then be able to use two monitors with your Linux system. Do not
-	  say Y here if your MDA card is the primary card in your system; the
-	  normal VGA driver will handle it.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted and removed from the running kernel whenever you want).
-	  The module will be called mdacon.o. If you want to compile it as
-	  a module, say M here and read <file:Documentation/modules.txt>.
-
-	  If unsure, say N.
-
 source "drivers/video/Kconfig"
-
-endif
-
-endmenu
-
 
 menu "Sound"
 
diff -Nru a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
--- a/arch/x86_64/kernel/ptrace.c	Mon Dec  9 18:46:35 2002
+++ b/arch/x86_64/kernel/ptrace.c	Mon Dec  9 18:46:35 2002
@@ -178,7 +178,8 @@
 		/* are we already being traced? */
 		if (current->ptrace & PT_PTRACED)
 			goto out;
-		if ((ret = security_ptrace(current->parent, current)))
+		ret = security_ptrace(current->parent, current);
+		if (ret)
 			goto out;
 		/* set the ptrace bit in the process flags. */
 		current->ptrace |= PT_PTRACED;
diff -Nru a/crypto/Kconfig b/crypto/Kconfig
--- a/crypto/Kconfig	Mon Dec  9 18:46:51 2002
+++ b/crypto/Kconfig	Mon Dec  9 18:46:51 2002
@@ -68,6 +68,32 @@
 	  See also:
 	  http://www.counterpane.com/blowfish.html
 
+config CRYPTO_TWOFISH
+	tristate "Twofish cipher algorithm"
+	depends on CRYPTO
+	help
+	  Twofish cipher algorithm.
+	  
+	  Twofish was submitted as an AES (Advanced Encryption Standard)
+	  candidate cipher by researchers at CounterPane Systems.  It is a
+	  16 round block cipher supporting key sizes of 128, 192, and 256
+	  bits.
+	  
+	  See also:
+	  http://www.counterpane.com/twofish.html
+
+config CRYPTO_SERPENT
+	tristate "Serpent cipher algorithm"
+	depends on CRYPTO
+	help
+	  Serpent cipher algorithm, by Anderson, Biham & Knudsen.
+
+	  Keys are allowed to be from 0 to 256 bits in length, in steps
+	  of 8 bits.
+
+	  See also:
+	  http://www.cl.cam.ac.uk/~rja14/serpent.html
+
 config CRYPTO_TEST
 	tristate "Testing module"
 	depends on CRYPTO
diff -Nru a/crypto/Makefile b/crypto/Makefile
--- a/crypto/Makefile	Mon Dec  9 18:46:51 2002
+++ b/crypto/Makefile	Mon Dec  9 18:46:51 2002
@@ -5,8 +5,10 @@
 export-objs := api.o hmac.o
 
 autoload-crypto-$(CONFIG_KMOD) = autoload.o
+proc-crypto-$(CONFIG_PROC_FS) = proc.o
 
-obj-$(CONFIG_CRYPTO) += api.o cipher.o digest.o compress.o $(autoload-crypto-y)
+obj-$(CONFIG_CRYPTO) += api.o cipher.o digest.o compress.o \
+			$(autoload-crypto-y) $(proc-crypto-y)
 
 obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
 obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o
@@ -16,6 +18,8 @@
 obj-$(CONFIG_CRYPTO_SHA256) += sha256.o
 obj-$(CONFIG_CRYPTO_DES) += des.o
 obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish.o
+obj-$(CONFIG_CRYPTO_TWOFISH) += twofish.o
+obj-$(CONFIG_CRYPTO_SERPENT) += serpent.o
 
 obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
 
diff -Nru a/crypto/api.c b/crypto/api.c
--- a/crypto/api.c	Mon Dec  9 18:46:51 2002
+++ b/crypto/api.c	Mon Dec  9 18:46:51 2002
@@ -16,12 +16,11 @@
 #include <linux/init.h>
 #include <linux/crypto.h>
 #include <linux/rwsem.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
+#include <linux/slab.h>
 #include "internal.h"
 
-static LIST_HEAD(crypto_alg_list);
-static DECLARE_RWSEM(crypto_alg_sem);
+LIST_HEAD(crypto_alg_list);
+DECLARE_RWSEM(crypto_alg_sem);
 
 static inline int crypto_alg_get(struct crypto_alg *alg)
 {
@@ -124,44 +123,26 @@
 	if (alg == NULL)
 		goto out;
 	
-	tfm = kmalloc(sizeof(*tfm), GFP_KERNEL);
+	tfm = kmalloc(sizeof(*tfm) + alg->cra_ctxsize, GFP_KERNEL);
 	if (tfm == NULL)
 		goto out_put;
 
 	memset(tfm, 0, sizeof(*tfm));
 	
-	if (alg->cra_ctxsize) {
-		tfm->crt_ctx = kmalloc(alg->cra_ctxsize, GFP_KERNEL);
-		if (tfm->crt_ctx == NULL)
-			goto out_free_tfm;
-	}
+	tfm->crt_ctx = (void*) &tfm[1];
 
 	tfm->__crt_alg = alg;
 	
-	if (alg->cra_blocksize) {
-		tfm->crt_work_block = kmalloc(alg->cra_blocksize + 1,
-					      GFP_KERNEL);
-		if (tfm->crt_work_block == NULL)
-			goto out_free_ctx;
-	}
-
 	if (crypto_init_flags(tfm, flags))
-		goto out_free_work_block;
+		goto out_free_tfm;
 		
 	if (crypto_init_ops(tfm)) {
 		crypto_exit_ops(tfm);
-		goto out_free_ctx;
+		goto out_free_tfm;
 	}
 
 	goto out;
 
-out_free_work_block:
-	if (tfm->__crt_alg->cra_blocksize)
-		kfree(tfm->crt_work_block);
-
-out_free_ctx:
-	if (tfm->__crt_alg->cra_ctxsize)
-		kfree(tfm->crt_ctx);
 out_free_tfm:
 	kfree(tfm);
 	tfm = NULL;
@@ -173,12 +154,6 @@
 
 void crypto_free_tfm(struct crypto_tfm *tfm)
 {
-	if (tfm->__crt_alg->cra_ctxsize)
-		kfree(tfm->crt_ctx);
-		
-	if (tfm->__crt_alg->cra_blocksize)
-		kfree(tfm->crt_work_block);
-		
 	if (crypto_tfm_alg_type(tfm) == CRYPTO_ALG_TYPE_CIPHER)
 		if (tfm->crt_cipher.cit_iv)
 			kfree(tfm->crt_cipher.cit_iv);
@@ -187,13 +162,6 @@
 	kfree(tfm);
 }
 
-static inline int crypto_alg_blocksize_check(struct crypto_alg *alg)
-{
-	return ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK)
-			== CRYPTO_ALG_TYPE_CIPHER &&
-	         alg->cra_blocksize > CRYPTO_MAX_CIPHER_BLOCK_SIZE);
-}
-
 int crypto_register_alg(struct crypto_alg *alg)
 {
 	int ret = 0;
@@ -208,14 +176,7 @@
 		}
 	}
 	
-	if (crypto_alg_blocksize_check(alg)) {
-		printk(KERN_WARNING "%s: blocksize %u exceeds max. "
-		       "size %u\n", __FUNCTION__, alg->cra_blocksize,
-		       CRYPTO_MAX_CIPHER_BLOCK_SIZE);
-		ret = -EINVAL;
-	}
-	else
-		list_add_tail(&alg->cra_list, &crypto_alg_list);
+	list_add_tail(&alg->cra_list, &crypto_alg_list);
 out:	
 	up_write(&crypto_alg_sem);
 	return ret;
@@ -254,89 +215,10 @@
 	return ret;
 }
 
-static void *c_start(struct seq_file *m, loff_t *pos)
-{
-	struct list_head *v;
-	loff_t n = *pos;
-
-	down_read(&crypto_alg_sem);
-	list_for_each(v, &crypto_alg_list)
-		if (!n--)
-			return list_entry(v, struct crypto_alg, cra_list);
-	return NULL;
-}
-
-static void *c_next(struct seq_file *m, void *p, loff_t *pos)
-{
-	struct list_head *v = p;
-	
-	(*pos)++;
-	v = v->next;
-	return (v == &crypto_alg_list) ?
-		NULL : list_entry(v, struct crypto_alg, cra_list);
-}
-
-static void c_stop(struct seq_file *m, void *p)
-{
-	up_read(&crypto_alg_sem);
-}
-
-static int c_show(struct seq_file *m, void *p)
-{
-	struct crypto_alg *alg = (struct crypto_alg *)p;
-	
-	seq_printf(m, "name         : %s\n", alg->cra_name);
-	seq_printf(m, "module       : %s\n", module_name(alg->cra_module));
-	seq_printf(m, "blocksize    : %u\n", alg->cra_blocksize);
-	
-	switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
-	case CRYPTO_ALG_TYPE_CIPHER:
-		seq_printf(m, "min keysize  : %u\n",
-					alg->cra_cipher.cia_min_keysize);
-		seq_printf(m, "max keysize  : %u\n",
-					alg->cra_cipher.cia_max_keysize);
-		seq_printf(m, "ivsize       : %u\n",
-					alg->cra_cipher.cia_ivsize);
-		break;
-		
-	case CRYPTO_ALG_TYPE_DIGEST:
-		seq_printf(m, "digestsize   : %u\n",
-		           alg->cra_digest.dia_digestsize);
-		break;
-	}
-
-	seq_putc(m, '\n');
-	return 0;
-}
-
-static struct seq_operations crypto_seq_ops = {
-	.start		= c_start,
-	.next		= c_next,
-	.stop		= c_stop,
-	.show		= c_show
-};
-
-static int crypto_info_open(struct inode *inode, struct file *file)
-{
-	return seq_open(file, &crypto_seq_ops);
-}
-        
-struct file_operations proc_crypto_ops = {
-	.open		= crypto_info_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= seq_release
-};
-
 static int __init init_crypto(void)
 {
-	struct proc_dir_entry *proc;
-	
 	printk(KERN_INFO "Initializing Cryptographic API\n");
-	proc = create_proc_entry("crypto", 0, NULL);
-	if (proc)
-		proc->proc_fops = &proc_crypto_ops;
-		
+	crypto_init_proc();
 	return 0;
 }
 
diff -Nru a/crypto/cipher.c b/crypto/cipher.c
--- a/crypto/cipher.c	Mon Dec  9 18:46:38 2002
+++ b/crypto/cipher.c	Mon Dec  9 18:46:38 2002
@@ -29,6 +29,14 @@
 	((u32 *)a)[1] ^= ((u32 *)b)[1];
 }
 
+static inline void xor_128(u8 *a, const u8 *b)
+{
+	((u32 *)a)[0] ^= ((u32 *)b)[0];
+	((u32 *)a)[1] ^= ((u32 *)b)[1];
+	((u32 *)a)[2] ^= ((u32 *)b)[2];
+	((u32 *)a)[3] ^= ((u32 *)b)[3];
+}
+
 static inline unsigned int sglen(struct scatterlist *sg, unsigned int nsg)
 {
 	unsigned int i, n;
@@ -116,7 +124,7 @@
 {
 	unsigned int i, coff;
 	unsigned int bsize = crypto_tfm_alg_blocksize(tfm);
-	u8 tmp[CRYPTO_MAX_CIPHER_BLOCK_SIZE];
+	u8 tmp[bsize];
 
 	if (sglen(sg, nsg) % bsize) {
 		tfm->crt_flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
@@ -164,16 +172,20 @@
 static void cbc_process(struct crypto_tfm *tfm,
                         u8 *block, cryptfn_t fn, int enc)
 {
+	/* Null encryption */
+	if (!tfm->crt_cipher.cit_iv)
+		return;
+		
 	if (enc) {
-		xor_64(tfm->crt_cipher.cit_iv, block);
+		tfm->crt_u.cipher.cit_xor_block(tfm->crt_cipher.cit_iv, block);
 		fn(tfm->crt_ctx, block, tfm->crt_cipher.cit_iv);
 		memcpy(tfm->crt_cipher.cit_iv, block,
 		       crypto_tfm_alg_blocksize(tfm));
 	} else {
-		u8 buf[CRYPTO_MAX_CIPHER_BLOCK_SIZE];
+		u8 buf[crypto_tfm_alg_blocksize(tfm)];
 		
 		fn(tfm->crt_ctx, buf, block);
-		xor_64(buf, tfm->crt_cipher.cit_iv);
+		tfm->crt_u.cipher.cit_xor_block(buf, tfm->crt_cipher.cit_iv);
 		memcpy(tfm->crt_cipher.cit_iv, block,
 		       crypto_tfm_alg_blocksize(tfm));
 		memcpy(block, buf, crypto_tfm_alg_blocksize(tfm));
@@ -279,11 +291,29 @@
 	if (alg->cra_cipher.cia_ivsize &&
 	    ops->cit_mode != CRYPTO_TFM_MODE_ECB) {
 	    	
+	    	switch (crypto_tfm_alg_blocksize(tfm)) {
+	    	case 8:
+	    		ops->cit_xor_block = xor_64;
+	    		break;
+	    		
+	    	case 16:
+	    		ops->cit_xor_block = xor_128;
+	    		break;
+	    		
+	    	default:
+	    		printk(KERN_WARNING "%s: block size %u not supported\n",
+	    		       crypto_tfm_alg_name(tfm),
+	    		       crypto_tfm_alg_blocksize(tfm));
+	    		ret = -EINVAL;
+	    		goto out;
+	    	}
+	    	
 	    	ops->cit_iv = kmalloc(alg->cra_cipher.cia_ivsize, GFP_KERNEL);
 		if (ops->cit_iv == NULL)
 			ret = -ENOMEM;
 	}
-	
+
+out:	
 	return ret;
 }
 
diff -Nru a/crypto/internal.h b/crypto/internal.h
--- a/crypto/internal.h	Mon Dec  9 18:46:34 2002
+++ b/crypto/internal.h	Mon Dec  9 18:46:34 2002
@@ -11,9 +11,9 @@
  */
 #ifndef _CRYPTO_INTERNAL_H
 #define _CRYPTO_INTERNAL_H
-
 #include <linux/mm.h>
 #include <linux/highmem.h>
+#include <linux/init.h>
 #include <asm/hardirq.h>
 #include <asm/softirq.h>
 
@@ -62,6 +62,13 @@
 }
 
 static inline void crypto_free_hmac_block(struct crypto_tfm *tfm)
+{ }
+#endif
+
+#ifdef CONFIG_PROC_FS
+void __init crypto_init_proc(void);
+#else
+static inline void crypto_init_proc(void)
 { }
 #endif
 
diff -Nru a/crypto/proc.c b/crypto/proc.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/crypto/proc.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,105 @@
+/*
+ * Scatterlist Cryptographic API.
+ *
+ * Procfs information.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option) 
+ * any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/crypto.h>
+#include <linux/rwsem.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include "internal.h"
+
+extern struct list_head crypto_alg_list;
+extern struct rw_semaphore crypto_alg_sem;
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+	struct list_head *v;
+	loff_t n = *pos;
+
+	down_read(&crypto_alg_sem);
+	list_for_each(v, &crypto_alg_list)
+		if (!n--)
+			return list_entry(v, struct crypto_alg, cra_list);
+	return NULL;
+}
+
+static void *c_next(struct seq_file *m, void *p, loff_t *pos)
+{
+	struct list_head *v = p;
+	
+	(*pos)++;
+	v = v->next;
+	return (v == &crypto_alg_list) ?
+		NULL : list_entry(v, struct crypto_alg, cra_list);
+}
+
+static void c_stop(struct seq_file *m, void *p)
+{
+	up_read(&crypto_alg_sem);
+}
+
+static int c_show(struct seq_file *m, void *p)
+{
+	struct crypto_alg *alg = (struct crypto_alg *)p;
+	
+	seq_printf(m, "name         : %s\n", alg->cra_name);
+	seq_printf(m, "module       : %s\n", module_name(alg->cra_module));
+	seq_printf(m, "blocksize    : %u\n", alg->cra_blocksize);
+	
+	switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
+	case CRYPTO_ALG_TYPE_CIPHER:
+		seq_printf(m, "min keysize  : %u\n",
+					alg->cra_cipher.cia_min_keysize);
+		seq_printf(m, "max keysize  : %u\n",
+					alg->cra_cipher.cia_max_keysize);
+		seq_printf(m, "ivsize       : %u\n",
+					alg->cra_cipher.cia_ivsize);
+		break;
+		
+	case CRYPTO_ALG_TYPE_DIGEST:
+		seq_printf(m, "digestsize   : %u\n",
+		           alg->cra_digest.dia_digestsize);
+		break;
+	}
+
+	seq_putc(m, '\n');
+	return 0;
+}
+
+static struct seq_operations crypto_seq_ops = {
+	.start		= c_start,
+	.next		= c_next,
+	.stop		= c_stop,
+	.show		= c_show
+};
+
+static int crypto_info_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &crypto_seq_ops);
+}
+        
+static struct file_operations proc_crypto_ops = {
+	.open		= crypto_info_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release
+};
+
+void __init crypto_init_proc(void)
+{
+	struct proc_dir_entry *proc;
+	
+	proc = create_proc_entry("crypto", 0, NULL);
+	if (proc)
+		proc->proc_fops = &proc_crypto_ops;
+}
diff -Nru a/crypto/serpent.c b/crypto/serpent.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/crypto/serpent.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,506 @@
+/*
+ * Cryptographic API.
+ *
+ * Serpent Cipher Algorithm.
+ *
+ * Copyright (C) 2002 Dag Arne Osvik <osvik@ii.uib.no>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <asm/byteorder.h>
+#include <linux/crypto.h>
+
+/* Key is padded to the maximum of 256 bits before round key generation.
+ * Any key length <= 256 bits (32 bytes) is allowed by the algorithm.
+ */
+
+#define SERPENT_MIN_KEY_SIZE		  0
+#define SERPENT_MAX_KEY_SIZE		 32
+#define SERPENT_EXPKEY_WORDS		132
+#define SERPENT_BLOCK_SIZE		 16
+
+#define PHI 0x9e3779b9UL
+#define ROL(x,r) ((x) = ((x) << (r)) | ((x) >> (32-(r))))
+#define ROR(x,r) ((x) = ((x) >> (r)) | ((x) << (32-(r))))
+
+#define keyiter(a,b,c,d,i,j) \
+        b ^= d; b ^= c; b ^= a; b ^= PHI ^ i; ROL(b,11); k[j] = b;
+
+#define loadkeys(x0,x1,x2,x3,i) \
+	x0=k[i]; x1=k[i+1]; x2=k[i+2]; x3=k[i+3];
+
+#define storekeys(x0,x1,x2,x3,i) \
+	k[i]=x0; k[i+1]=x1; k[i+2]=x2; k[i+3]=x3;
+
+#define K(x0,x1,x2,x3,i)				\
+	x3 ^= k[4*(i)+3];        x2 ^= k[4*(i)+2];	\
+	x1 ^= k[4*(i)+1];        x0 ^= k[4*(i)+0];
+
+#define LK(x0,x1,x2,x3,x4,i)				\
+					ROL(x0,13);	\
+	ROL(x2,3);	x1 ^= x0;	x4  = x0 << 3;	\
+	x3 ^= x2;	x1 ^= x2;			\
+	ROL(x1,1);	x3 ^= x4;			\
+	ROL(x3,7);	x4  = x1;			\
+	x0 ^= x1;	x4 <<= 7;	x2 ^= x3;	\
+	x0 ^= x3;	x2 ^= x4;	x3 ^= k[4*i+3];	\
+	x1 ^= k[4*i+1];	ROL(x0,5);	ROL(x2,22);	\
+	x0 ^= k[4*i+0];	x2 ^= k[4*i+2];
+
+#define KL(x0,x1,x2,x3,x4,i)				\
+	x0 ^= k[4*i+0];	x1 ^= k[4*i+1];	x2 ^= k[4*i+2];	\
+	x3 ^= k[4*i+3];	ROR(x0,5);	ROR(x2,22);	\
+	x4 =  x1;	x2 ^= x3;	x0 ^= x3;	\
+	x4 <<= 7;	x0 ^= x1;	ROR(x1,1);	\
+	x2 ^= x4;	ROR(x3,7);	x4 = x0 << 3;	\
+	x1 ^= x0;	x3 ^= x4;	ROR(x0,13);	\
+	x1 ^= x2;	x3 ^= x2;	ROR(x2,3);
+
+#define S0(x0,x1,x2,x3,x4)				\
+					x4  = x3;	\
+	x3 |= x0;	x0 ^= x4;	x4 ^= x2;	\
+	x4 =~ x4;	x3 ^= x1;	x1 &= x0;	\
+	x1 ^= x4;	x2 ^= x0;	x0 ^= x3;	\
+	x4 |= x0;	x0 ^= x2;	x2 &= x1;	\
+	x3 ^= x2;	x1 =~ x1;	x2 ^= x4;	\
+	x1 ^= x2;
+
+#define S1(x0,x1,x2,x3,x4)				\
+					x4  = x1;	\
+	x1 ^= x0;	x0 ^= x3;	x3 =~ x3;	\
+	x4 &= x1;	x0 |= x1;	x3 ^= x2;	\
+	x0 ^= x3;	x1 ^= x3;	x3 ^= x4;	\
+	x1 |= x4;	x4 ^= x2;	x2 &= x0;	\
+	x2 ^= x1;	x1 |= x0;	x0 =~ x0;	\
+	x0 ^= x2;	x4 ^= x1;
+
+#define S2(x0,x1,x2,x3,x4)				\
+					x3 =~ x3;	\
+	x1 ^= x0;	x4  = x0;	x0 &= x2;	\
+	x0 ^= x3;	x3 |= x4;	x2 ^= x1;	\
+	x3 ^= x1;	x1 &= x0;	x0 ^= x2;	\
+	x2 &= x3;	x3 |= x1;	x0 =~ x0;	\
+	x3 ^= x0;	x4 ^= x0;	x0 ^= x2;	\
+	x1 |= x2;
+
+#define S3(x0,x1,x2,x3,x4)				\
+					x4  = x1;	\
+	x1 ^= x3;	x3 |= x0;	x4 &= x0;	\
+	x0 ^= x2;	x2 ^= x1;	x1 &= x3;	\
+	x2 ^= x3;	x0 |= x4;	x4 ^= x3;	\
+	x1 ^= x0;	x0 &= x3;	x3 &= x4;	\
+	x3 ^= x2;	x4 |= x1;	x2 &= x1;	\
+	x4 ^= x3;	x0 ^= x3;	x3 ^= x2;
+
+#define S4(x0,x1,x2,x3,x4)				\
+					x4  = x3;	\
+	x3 &= x0;	x0 ^= x4;			\
+	x3 ^= x2;	x2 |= x4;	x0 ^= x1;	\
+	x4 ^= x3;	x2 |= x0;			\
+	x2 ^= x1;	x1 &= x0;			\
+	x1 ^= x4;	x4 &= x2;	x2 ^= x3;	\
+	x4 ^= x0;	x3 |= x1;	x1 =~ x1;	\
+	x3 ^= x0;
+
+#define S5(x0,x1,x2,x3,x4)				\
+	x4  = x1;	x1 |= x0;			\
+	x2 ^= x1;	x3 =~ x3;	x4 ^= x0;	\
+	x0 ^= x2;	x1 &= x4;	x4 |= x3;	\
+	x4 ^= x0;	x0 &= x3;	x1 ^= x3;	\
+	x3 ^= x2;	x0 ^= x1;	x2 &= x4;	\
+	x1 ^= x2;	x2 &= x0;			\
+	x3 ^= x2;
+
+#define S6(x0,x1,x2,x3,x4)				\
+					x4  = x1;	\
+	x3 ^= x0;	x1 ^= x2;	x2 ^= x0;	\
+	x0 &= x3;	x1 |= x3;	x4 =~ x4;	\
+	x0 ^= x1;	x1 ^= x2;			\
+	x3 ^= x4;	x4 ^= x0;	x2 &= x0;	\
+	x4 ^= x1;	x2 ^= x3;	x3 &= x1;	\
+	x3 ^= x0;	x1 ^= x2;
+
+#define S7(x0,x1,x2,x3,x4)				\
+					x1 =~ x1;	\
+	x4  = x1;	x0 =~ x0;	x1 &= x2;	\
+	x1 ^= x3;	x3 |= x4;	x4 ^= x2;	\
+	x2 ^= x3;	x3 ^= x0;	x0 |= x1;	\
+	x2 &= x0;	x0 ^= x4;	x4 ^= x3;	\
+	x3 &= x0;	x4 ^= x1;			\
+	x2 ^= x4;	x3 ^= x1;	x4 |= x0;	\
+	x4 ^= x1;
+
+#define SI0(x0,x1,x2,x3,x4)				\
+			x4  = x3;	x1 ^= x0;	\
+	x3 |= x1;	x4 ^= x1;	x0 =~ x0;	\
+	x2 ^= x3;	x3 ^= x0;	x0 &= x1;	\
+	x0 ^= x2;	x2 &= x3;	x3 ^= x4;	\
+	x2 ^= x3;	x1 ^= x3;	x3 &= x0;	\
+	x1 ^= x0;	x0 ^= x2;	x4 ^= x3;
+
+#define SI1(x0,x1,x2,x3,x4)				\
+	x1 ^= x3;	x4  = x0;			\
+	x0 ^= x2;	x2 =~ x2;	x4 |= x1;	\
+	x4 ^= x3;	x3 &= x1;	x1 ^= x2;	\
+	x2 &= x4;	x4 ^= x1;	x1 |= x3;	\
+	x3 ^= x0;	x2 ^= x0;	x0 |= x4;	\
+	x2 ^= x4;	x1 ^= x0;			\
+	x4 ^= x1;
+
+#define SI2(x0,x1,x2,x3,x4)				\
+	x2 ^= x1;	x4  = x3;	x3 =~ x3;	\
+	x3 |= x2;	x2 ^= x4;	x4 ^= x0;	\
+	x3 ^= x1;	x1 |= x2;	x2 ^= x0;	\
+	x1 ^= x4;	x4 |= x3;	x2 ^= x3;	\
+	x4 ^= x2;	x2 &= x1;			\
+	x2 ^= x3;	x3 ^= x4;	x4 ^= x0;
+
+#define SI3(x0,x1,x2,x3,x4)				\
+					x2 ^= x1;	\
+	x4  = x1;	x1 &= x2;			\
+	x1 ^= x0;	x0 |= x4;	x4 ^= x3;	\
+	x0 ^= x3;	x3 |= x1;	x1 ^= x2;	\
+	x1 ^= x3;	x0 ^= x2;	x2 ^= x3;	\
+	x3 &= x1;	x1 ^= x0;	x0 &= x2;	\
+	x4 ^= x3;	x3 ^= x0;	x0 ^= x1;
+
+#define SI4(x0,x1,x2,x3,x4)				\
+	x2 ^= x3;	x4  = x0;	x0 &= x1;	\
+	x0 ^= x2;	x2 |= x3;	x4 =~ x4;	\
+	x1 ^= x0;	x0 ^= x2;	x2 &= x4;	\
+	x2 ^= x0;	x0 |= x4;			\
+	x0 ^= x3;	x3 &= x2;			\
+	x4 ^= x3;	x3 ^= x1;	x1 &= x0;	\
+	x4 ^= x1;	x0 ^= x3;
+
+#define SI5(x0,x1,x2,x3,x4)				\
+			x4  = x1;	x1 |= x2;	\
+	x2 ^= x4;	x1 ^= x3;	x3 &= x4;	\
+	x2 ^= x3;	x3 |= x0;	x0 =~ x0;	\
+	x3 ^= x2;	x2 |= x0;	x4 ^= x1;	\
+	x2 ^= x4;	x4 &= x0;	x0 ^= x1;	\
+	x1 ^= x3;	x0 &= x2;	x2 ^= x3;	\
+	x0 ^= x2;	x2 ^= x4;	x4 ^= x3;
+
+#define SI6(x0,x1,x2,x3,x4)				\
+			x0 ^= x2;			\
+	x4  = x0;	x0 &= x3;	x2 ^= x3;	\
+	x0 ^= x2;	x3 ^= x1;	x2 |= x4;	\
+	x2 ^= x3;	x3 &= x0;	x0 =~ x0;	\
+	x3 ^= x1;	x1 &= x2;	x4 ^= x0;	\
+	x3 ^= x4;	x4 ^= x2;	x0 ^= x1;	\
+	x2 ^= x0;
+
+#define SI7(x0,x1,x2,x3,x4)				\
+	x4  = x3;	x3 &= x0;	x0 ^= x2;	\
+	x2 |= x4;	x4 ^= x1;	x0 =~ x0;	\
+	x1 |= x3;	x4 ^= x0;	x0 &= x2;	\
+	x0 ^= x1;	x1 &= x2;	x3 ^= x2;	\
+	x4 ^= x3;	x2 &= x3;	x3 |= x0;	\
+	x1 ^= x4;	x3 ^= x4;	x4 &= x0;	\
+	x4 ^= x2;
+
+struct serpent_ctx {
+	u8 iv[SERPENT_BLOCK_SIZE];
+	u32 expkey[SERPENT_EXPKEY_WORDS];
+};
+
+static int setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
+{
+	u32 *k = ((struct serpent_ctx *)ctx)->expkey;
+	u8  *k8 = (u8 *)k;
+	u32 r0,r1,r2,r3,r4;
+	int i;
+
+	if ((keylen < SERPENT_MIN_KEY_SIZE)
+			|| (keylen > SERPENT_MAX_KEY_SIZE))
+	{
+		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+		return -EINVAL;
+	}
+
+	/* Copy key, add padding */
+
+	for (i = 0; i < keylen; ++i)
+		k8[i] = key[i];
+	if (i < SERPENT_MAX_KEY_SIZE)
+		k8[i++] = 1;
+	while (i < SERPENT_MAX_KEY_SIZE)
+		k8[i++] = 0;
+
+	/* Expand key using polynomial */
+
+	r0 = le32_to_cpu(k[3]);
+	r1 = le32_to_cpu(k[4]);
+	r2 = le32_to_cpu(k[5]);
+	r3 = le32_to_cpu(k[6]);
+	r4 = le32_to_cpu(k[7]);
+
+	keyiter(le32_to_cpu(k[0]),r0,r4,r2,0,0);
+	keyiter(le32_to_cpu(k[1]),r1,r0,r3,1,1);
+	keyiter(le32_to_cpu(k[2]),r2,r1,r4,2,2);
+	keyiter(le32_to_cpu(k[3]),r3,r2,r0,3,3);
+	keyiter(le32_to_cpu(k[4]),r4,r3,r1,4,4);
+	keyiter(le32_to_cpu(k[5]),r0,r4,r2,5,5);
+	keyiter(le32_to_cpu(k[6]),r1,r0,r3,6,6);
+	keyiter(le32_to_cpu(k[7]),r2,r1,r4,7,7);
+
+	keyiter(k[  0],r3,r2,r0,  8,  8); keyiter(k[  1],r4,r3,r1,  9,  9);
+	keyiter(k[  2],r0,r4,r2, 10, 10); keyiter(k[  3],r1,r0,r3, 11, 11);
+	keyiter(k[  4],r2,r1,r4, 12, 12); keyiter(k[  5],r3,r2,r0, 13, 13);
+	keyiter(k[  6],r4,r3,r1, 14, 14); keyiter(k[  7],r0,r4,r2, 15, 15);
+	keyiter(k[  8],r1,r0,r3, 16, 16); keyiter(k[  9],r2,r1,r4, 17, 17);
+	keyiter(k[ 10],r3,r2,r0, 18, 18); keyiter(k[ 11],r4,r3,r1, 19, 19);
+	keyiter(k[ 12],r0,r4,r2, 20, 20); keyiter(k[ 13],r1,r0,r3, 21, 21);
+	keyiter(k[ 14],r2,r1,r4, 22, 22); keyiter(k[ 15],r3,r2,r0, 23, 23);
+	keyiter(k[ 16],r4,r3,r1, 24, 24); keyiter(k[ 17],r0,r4,r2, 25, 25);
+	keyiter(k[ 18],r1,r0,r3, 26, 26); keyiter(k[ 19],r2,r1,r4, 27, 27);
+	keyiter(k[ 20],r3,r2,r0, 28, 28); keyiter(k[ 21],r4,r3,r1, 29, 29);
+	keyiter(k[ 22],r0,r4,r2, 30, 30); keyiter(k[ 23],r1,r0,r3, 31, 31);
+
+	k += 50;
+
+	keyiter(k[-26],r2,r1,r4, 32,-18); keyiter(k[-25],r3,r2,r0, 33,-17);
+	keyiter(k[-24],r4,r3,r1, 34,-16); keyiter(k[-23],r0,r4,r2, 35,-15);
+	keyiter(k[-22],r1,r0,r3, 36,-14); keyiter(k[-21],r2,r1,r4, 37,-13);
+	keyiter(k[-20],r3,r2,r0, 38,-12); keyiter(k[-19],r4,r3,r1, 39,-11);
+	keyiter(k[-18],r0,r4,r2, 40,-10); keyiter(k[-17],r1,r0,r3, 41, -9);
+	keyiter(k[-16],r2,r1,r4, 42, -8); keyiter(k[-15],r3,r2,r0, 43, -7);
+	keyiter(k[-14],r4,r3,r1, 44, -6); keyiter(k[-13],r0,r4,r2, 45, -5);
+	keyiter(k[-12],r1,r0,r3, 46, -4); keyiter(k[-11],r2,r1,r4, 47, -3);
+	keyiter(k[-10],r3,r2,r0, 48, -2); keyiter(k[ -9],r4,r3,r1, 49, -1);
+	keyiter(k[ -8],r0,r4,r2, 50,  0); keyiter(k[ -7],r1,r0,r3, 51,  1);
+	keyiter(k[ -6],r2,r1,r4, 52,  2); keyiter(k[ -5],r3,r2,r0, 53,  3);
+	keyiter(k[ -4],r4,r3,r1, 54,  4); keyiter(k[ -3],r0,r4,r2, 55,  5);
+	keyiter(k[ -2],r1,r0,r3, 56,  6); keyiter(k[ -1],r2,r1,r4, 57,  7);
+	keyiter(k[  0],r3,r2,r0, 58,  8); keyiter(k[  1],r4,r3,r1, 59,  9);
+	keyiter(k[  2],r0,r4,r2, 60, 10); keyiter(k[  3],r1,r0,r3, 61, 11);
+	keyiter(k[  4],r2,r1,r4, 62, 12); keyiter(k[  5],r3,r2,r0, 63, 13);
+	keyiter(k[  6],r4,r3,r1, 64, 14); keyiter(k[  7],r0,r4,r2, 65, 15);
+	keyiter(k[  8],r1,r0,r3, 66, 16); keyiter(k[  9],r2,r1,r4, 67, 17);
+	keyiter(k[ 10],r3,r2,r0, 68, 18); keyiter(k[ 11],r4,r3,r1, 69, 19);
+	keyiter(k[ 12],r0,r4,r2, 70, 20); keyiter(k[ 13],r1,r0,r3, 71, 21);
+	keyiter(k[ 14],r2,r1,r4, 72, 22); keyiter(k[ 15],r3,r2,r0, 73, 23);
+	keyiter(k[ 16],r4,r3,r1, 74, 24); keyiter(k[ 17],r0,r4,r2, 75, 25);
+	keyiter(k[ 18],r1,r0,r3, 76, 26); keyiter(k[ 19],r2,r1,r4, 77, 27);
+	keyiter(k[ 20],r3,r2,r0, 78, 28); keyiter(k[ 21],r4,r3,r1, 79, 29);
+	keyiter(k[ 22],r0,r4,r2, 80, 30); keyiter(k[ 23],r1,r0,r3, 81, 31);
+
+	k += 50;
+
+	keyiter(k[-26],r2,r1,r4, 82,-18); keyiter(k[-25],r3,r2,r0, 83,-17);
+	keyiter(k[-24],r4,r3,r1, 84,-16); keyiter(k[-23],r0,r4,r2, 85,-15);
+	keyiter(k[-22],r1,r0,r3, 86,-14); keyiter(k[-21],r2,r1,r4, 87,-13);
+	keyiter(k[-20],r3,r2,r0, 88,-12); keyiter(k[-19],r4,r3,r1, 89,-11);
+	keyiter(k[-18],r0,r4,r2, 90,-10); keyiter(k[-17],r1,r0,r3, 91, -9);
+	keyiter(k[-16],r2,r1,r4, 92, -8); keyiter(k[-15],r3,r2,r0, 93, -7);
+	keyiter(k[-14],r4,r3,r1, 94, -6); keyiter(k[-13],r0,r4,r2, 95, -5);
+	keyiter(k[-12],r1,r0,r3, 96, -4); keyiter(k[-11],r2,r1,r4, 97, -3);
+	keyiter(k[-10],r3,r2,r0, 98, -2); keyiter(k[ -9],r4,r3,r1, 99, -1);
+	keyiter(k[ -8],r0,r4,r2,100,  0); keyiter(k[ -7],r1,r0,r3,101,  1);
+	keyiter(k[ -6],r2,r1,r4,102,  2); keyiter(k[ -5],r3,r2,r0,103,  3);
+	keyiter(k[ -4],r4,r3,r1,104,  4); keyiter(k[ -3],r0,r4,r2,105,  5);
+	keyiter(k[ -2],r1,r0,r3,106,  6); keyiter(k[ -1],r2,r1,r4,107,  7);
+	keyiter(k[  0],r3,r2,r0,108,  8); keyiter(k[  1],r4,r3,r1,109,  9);
+	keyiter(k[  2],r0,r4,r2,110, 10); keyiter(k[  3],r1,r0,r3,111, 11);
+	keyiter(k[  4],r2,r1,r4,112, 12); keyiter(k[  5],r3,r2,r0,113, 13);
+	keyiter(k[  6],r4,r3,r1,114, 14); keyiter(k[  7],r0,r4,r2,115, 15);
+	keyiter(k[  8],r1,r0,r3,116, 16); keyiter(k[  9],r2,r1,r4,117, 17);
+	keyiter(k[ 10],r3,r2,r0,118, 18); keyiter(k[ 11],r4,r3,r1,119, 19);
+	keyiter(k[ 12],r0,r4,r2,120, 20); keyiter(k[ 13],r1,r0,r3,121, 21);
+	keyiter(k[ 14],r2,r1,r4,122, 22); keyiter(k[ 15],r3,r2,r0,123, 23);
+	keyiter(k[ 16],r4,r3,r1,124, 24); keyiter(k[ 17],r0,r4,r2,125, 25);
+	keyiter(k[ 18],r1,r0,r3,126, 26); keyiter(k[ 19],r2,r1,r4,127, 27);
+	keyiter(k[ 20],r3,r2,r0,128, 28); keyiter(k[ 21],r4,r3,r1,129, 29);
+	keyiter(k[ 22],r0,r4,r2,130, 30); keyiter(k[ 23],r1,r0,r3,131, 31);
+
+	/* Apply S-boxes */
+
+	S3(r3,r4,r0,r1,r2); storekeys(r1,r2,r4,r3, 28); loadkeys(r1,r2,r4,r3, 24);
+	S4(r1,r2,r4,r3,r0); storekeys(r2,r4,r3,r0, 24); loadkeys(r2,r4,r3,r0, 20);
+	S5(r2,r4,r3,r0,r1); storekeys(r1,r2,r4,r0, 20); loadkeys(r1,r2,r4,r0, 16);
+	S6(r1,r2,r4,r0,r3); storekeys(r4,r3,r2,r0, 16); loadkeys(r4,r3,r2,r0, 12);
+	S7(r4,r3,r2,r0,r1); storekeys(r1,r2,r0,r4, 12); loadkeys(r1,r2,r0,r4,  8);
+	S0(r1,r2,r0,r4,r3); storekeys(r0,r2,r4,r1,  8); loadkeys(r0,r2,r4,r1,  4);
+	S1(r0,r2,r4,r1,r3); storekeys(r3,r4,r1,r0,  4); loadkeys(r3,r4,r1,r0,  0);
+	S2(r3,r4,r1,r0,r2); storekeys(r2,r4,r3,r0,  0); loadkeys(r2,r4,r3,r0, -4);
+	S3(r2,r4,r3,r0,r1); storekeys(r0,r1,r4,r2, -4); loadkeys(r0,r1,r4,r2, -8);
+	S4(r0,r1,r4,r2,r3); storekeys(r1,r4,r2,r3, -8); loadkeys(r1,r4,r2,r3,-12);
+	S5(r1,r4,r2,r3,r0); storekeys(r0,r1,r4,r3,-12); loadkeys(r0,r1,r4,r3,-16);
+	S6(r0,r1,r4,r3,r2); storekeys(r4,r2,r1,r3,-16); loadkeys(r4,r2,r1,r3,-20);
+	S7(r4,r2,r1,r3,r0); storekeys(r0,r1,r3,r4,-20); loadkeys(r0,r1,r3,r4,-24);
+	S0(r0,r1,r3,r4,r2); storekeys(r3,r1,r4,r0,-24); loadkeys(r3,r1,r4,r0,-28);
+	k -= 50;
+	S1(r3,r1,r4,r0,r2); storekeys(r2,r4,r0,r3, 22); loadkeys(r2,r4,r0,r3, 18);
+	S2(r2,r4,r0,r3,r1); storekeys(r1,r4,r2,r3, 18); loadkeys(r1,r4,r2,r3, 14);
+	S3(r1,r4,r2,r3,r0); storekeys(r3,r0,r4,r1, 14); loadkeys(r3,r0,r4,r1, 10);
+	S4(r3,r0,r4,r1,r2); storekeys(r0,r4,r1,r2, 10); loadkeys(r0,r4,r1,r2,  6);
+	S5(r0,r4,r1,r2,r3); storekeys(r3,r0,r4,r2,  6); loadkeys(r3,r0,r4,r2,  2);
+	S6(r3,r0,r4,r2,r1); storekeys(r4,r1,r0,r2,  2); loadkeys(r4,r1,r0,r2, -2);
+	S7(r4,r1,r0,r2,r3); storekeys(r3,r0,r2,r4, -2); loadkeys(r3,r0,r2,r4, -6);
+	S0(r3,r0,r2,r4,r1); storekeys(r2,r0,r4,r3, -6); loadkeys(r2,r0,r4,r3,-10);
+	S1(r2,r0,r4,r3,r1); storekeys(r1,r4,r3,r2,-10); loadkeys(r1,r4,r3,r2,-14);
+	S2(r1,r4,r3,r2,r0); storekeys(r0,r4,r1,r2,-14); loadkeys(r0,r4,r1,r2,-18);
+	S3(r0,r4,r1,r2,r3); storekeys(r2,r3,r4,r0,-18); loadkeys(r2,r3,r4,r0,-22);
+	k -= 50;
+	S4(r2,r3,r4,r0,r1); storekeys(r3,r4,r0,r1, 28); loadkeys(r3,r4,r0,r1, 24);
+	S5(r3,r4,r0,r1,r2); storekeys(r2,r3,r4,r1, 24); loadkeys(r2,r3,r4,r1, 20);
+	S6(r2,r3,r4,r1,r0); storekeys(r4,r0,r3,r1, 20); loadkeys(r4,r0,r3,r1, 16);
+	S7(r4,r0,r3,r1,r2); storekeys(r2,r3,r1,r4, 16); loadkeys(r2,r3,r1,r4, 12);
+	S0(r2,r3,r1,r4,r0); storekeys(r1,r3,r4,r2, 12); loadkeys(r1,r3,r4,r2,  8);
+	S1(r1,r3,r4,r2,r0); storekeys(r0,r4,r2,r1,  8); loadkeys(r0,r4,r2,r1,  4);
+	S2(r0,r4,r2,r1,r3); storekeys(r3,r4,r0,r1,  4); loadkeys(r3,r4,r0,r1,  0);
+	S3(r3,r4,r0,r1,r2); storekeys(r1,r2,r4,r3,  0);
+
+	return 0;
+}
+
+static void encrypt(void *ctx, u8 *dst, const u8 *src)
+{
+	const u32
+		*k = ((struct serpent_ctx *)ctx)->expkey,
+		*s = (const u32 *)src;
+	u32	*d = (u32 *)dst,
+		r0, r1, r2, r3, r4;
+
+/*
+ * Note: The conversions between u8* and u32* might cause trouble
+ * on architectures with stricter alignment rules than x86
+ */
+
+	r0 = le32_to_cpu(s[0]);
+	r1 = le32_to_cpu(s[1]);
+	r2 = le32_to_cpu(s[2]);
+	r3 = le32_to_cpu(s[3]);
+
+				 K(r0,r1,r2,r3,0);
+	S0(r0,r1,r2,r3,r4);	LK(r2,r1,r3,r0,r4,1);
+	S1(r2,r1,r3,r0,r4);	LK(r4,r3,r0,r2,r1,2);
+	S2(r4,r3,r0,r2,r1);	LK(r1,r3,r4,r2,r0,3);
+	S3(r1,r3,r4,r2,r0);	LK(r2,r0,r3,r1,r4,4);
+	S4(r2,r0,r3,r1,r4);	LK(r0,r3,r1,r4,r2,5);
+	S5(r0,r3,r1,r4,r2);	LK(r2,r0,r3,r4,r1,6);
+	S6(r2,r0,r3,r4,r1);	LK(r3,r1,r0,r4,r2,7);
+	S7(r3,r1,r0,r4,r2);	LK(r2,r0,r4,r3,r1,8);
+	S0(r2,r0,r4,r3,r1);	LK(r4,r0,r3,r2,r1,9);
+	S1(r4,r0,r3,r2,r1);	LK(r1,r3,r2,r4,r0,10);
+	S2(r1,r3,r2,r4,r0);	LK(r0,r3,r1,r4,r2,11);
+	S3(r0,r3,r1,r4,r2);	LK(r4,r2,r3,r0,r1,12);
+	S4(r4,r2,r3,r0,r1);	LK(r2,r3,r0,r1,r4,13);
+	S5(r2,r3,r0,r1,r4);	LK(r4,r2,r3,r1,r0,14);
+	S6(r4,r2,r3,r1,r0);	LK(r3,r0,r2,r1,r4,15);
+	S7(r3,r0,r2,r1,r4);	LK(r4,r2,r1,r3,r0,16);
+	S0(r4,r2,r1,r3,r0);	LK(r1,r2,r3,r4,r0,17);
+	S1(r1,r2,r3,r4,r0);	LK(r0,r3,r4,r1,r2,18);
+	S2(r0,r3,r4,r1,r2);	LK(r2,r3,r0,r1,r4,19);
+	S3(r2,r3,r0,r1,r4);	LK(r1,r4,r3,r2,r0,20);
+	S4(r1,r4,r3,r2,r0);	LK(r4,r3,r2,r0,r1,21);
+	S5(r4,r3,r2,r0,r1);	LK(r1,r4,r3,r0,r2,22);
+	S6(r1,r4,r3,r0,r2);	LK(r3,r2,r4,r0,r1,23);
+	S7(r3,r2,r4,r0,r1);	LK(r1,r4,r0,r3,r2,24);
+	S0(r1,r4,r0,r3,r2);	LK(r0,r4,r3,r1,r2,25);
+	S1(r0,r4,r3,r1,r2);	LK(r2,r3,r1,r0,r4,26);
+	S2(r2,r3,r1,r0,r4);	LK(r4,r3,r2,r0,r1,27);
+	S3(r4,r3,r2,r0,r1);	LK(r0,r1,r3,r4,r2,28);
+	S4(r0,r1,r3,r4,r2);	LK(r1,r3,r4,r2,r0,29);
+	S5(r1,r3,r4,r2,r0);	LK(r0,r1,r3,r2,r4,30);
+	S6(r0,r1,r3,r2,r4);	LK(r3,r4,r1,r2,r0,31);
+	S7(r3,r4,r1,r2,r0);	 K(r0,r1,r2,r3,32);
+
+	d[0] = cpu_to_le32(r0);
+	d[1] = cpu_to_le32(r1);
+	d[2] = cpu_to_le32(r2);
+	d[3] = cpu_to_le32(r3);
+}
+
+static void decrypt(void *ctx, u8 *dst, const u8 *src)
+{
+	const u32
+		*k = ((struct serpent_ctx *)ctx)->expkey,
+		*s = (const u32 *)src;
+	u32	*d = (u32 *)dst,
+		r0, r1, r2, r3, r4;
+
+	r0 = le32_to_cpu(s[0]);
+	r1 = le32_to_cpu(s[1]);
+	r2 = le32_to_cpu(s[2]);
+	r3 = le32_to_cpu(s[3]);
+
+				K(r0,r1,r2,r3,32);
+	SI7(r0,r1,r2,r3,r4);	KL(r1,r3,r0,r4,r2,31);
+	SI6(r1,r3,r0,r4,r2);	KL(r0,r2,r4,r1,r3,30);
+	SI5(r0,r2,r4,r1,r3);	KL(r2,r3,r0,r4,r1,29);
+	SI4(r2,r3,r0,r4,r1);	KL(r2,r0,r1,r4,r3,28);
+	SI3(r2,r0,r1,r4,r3);	KL(r1,r2,r3,r4,r0,27);
+	SI2(r1,r2,r3,r4,r0);	KL(r2,r0,r4,r3,r1,26);
+	SI1(r2,r0,r4,r3,r1);	KL(r1,r0,r4,r3,r2,25);
+	SI0(r1,r0,r4,r3,r2);	KL(r4,r2,r0,r1,r3,24);
+	SI7(r4,r2,r0,r1,r3);	KL(r2,r1,r4,r3,r0,23);
+	SI6(r2,r1,r4,r3,r0);	KL(r4,r0,r3,r2,r1,22);
+	SI5(r4,r0,r3,r2,r1);	KL(r0,r1,r4,r3,r2,21);
+	SI4(r0,r1,r4,r3,r2);	KL(r0,r4,r2,r3,r1,20);
+	SI3(r0,r4,r2,r3,r1);	KL(r2,r0,r1,r3,r4,19);
+	SI2(r2,r0,r1,r3,r4);	KL(r0,r4,r3,r1,r2,18);
+	SI1(r0,r4,r3,r1,r2);	KL(r2,r4,r3,r1,r0,17);
+	SI0(r2,r4,r3,r1,r0);	KL(r3,r0,r4,r2,r1,16);
+	SI7(r3,r0,r4,r2,r1);	KL(r0,r2,r3,r1,r4,15);
+	SI6(r0,r2,r3,r1,r4);	KL(r3,r4,r1,r0,r2,14);
+	SI5(r3,r4,r1,r0,r2);	KL(r4,r2,r3,r1,r0,13);
+	SI4(r4,r2,r3,r1,r0);	KL(r4,r3,r0,r1,r2,12);
+	SI3(r4,r3,r0,r1,r2);	KL(r0,r4,r2,r1,r3,11);
+	SI2(r0,r4,r2,r1,r3);	KL(r4,r3,r1,r2,r0,10);
+	SI1(r4,r3,r1,r2,r0);	KL(r0,r3,r1,r2,r4,9);
+	SI0(r0,r3,r1,r2,r4);	KL(r1,r4,r3,r0,r2,8);
+	SI7(r1,r4,r3,r0,r2);	KL(r4,r0,r1,r2,r3,7);
+	SI6(r4,r0,r1,r2,r3);	KL(r1,r3,r2,r4,r0,6);
+	SI5(r1,r3,r2,r4,r0);	KL(r3,r0,r1,r2,r4,5);
+	SI4(r3,r0,r1,r2,r4);	KL(r3,r1,r4,r2,r0,4);
+	SI3(r3,r1,r4,r2,r0);	KL(r4,r3,r0,r2,r1,3);
+	SI2(r4,r3,r0,r2,r1);	KL(r3,r1,r2,r0,r4,2);
+	SI1(r3,r1,r2,r0,r4);	KL(r4,r1,r2,r0,r3,1);
+	SI0(r4,r1,r2,r0,r3);	K(r2,r3,r1,r4,0);
+
+	d[0] = cpu_to_le32(r2);
+	d[1] = cpu_to_le32(r3);
+	d[2] = cpu_to_le32(r1);
+	d[3] = cpu_to_le32(r4);
+}
+
+static struct crypto_alg serpent_alg = {
+	.cra_name		=	"serpent",
+	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
+	.cra_blocksize		=	SERPENT_BLOCK_SIZE,
+	.cra_ctxsize		=	sizeof(struct serpent_ctx),
+	.cra_module		=	THIS_MODULE,
+	.cra_list		=	LIST_HEAD_INIT(serpent_alg.cra_list),
+	.cra_u			=	{ .cipher = {
+	.cia_min_keysize	=	SERPENT_MIN_KEY_SIZE,
+	.cia_max_keysize	=	SERPENT_MAX_KEY_SIZE,
+	.cia_ivsize		=	SERPENT_BLOCK_SIZE,
+	.cia_setkey   		= 	setkey,
+	.cia_encrypt 		=	encrypt,
+	.cia_decrypt  		=	decrypt } }
+};
+
+static int __init init(void)
+{
+	return crypto_register_alg(&serpent_alg);
+}
+
+static void __exit fini(void)
+{
+	crypto_unregister_alg(&serpent_alg);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Serpent Cipher Algorithm");
+MODULE_AUTHOR("Dag Arne Osvik <osvik@ii.uib.no>");
diff -Nru a/crypto/tcrypt.c b/crypto/tcrypt.c
--- a/crypto/tcrypt.c	Mon Dec  9 18:46:50 2002
+++ b/crypto/tcrypt.c	Mon Dec  9 18:46:50 2002
@@ -48,6 +48,7 @@
 
 static char *check[] = {
 	"des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish",
+	"twofish", "serpent",
 	 NULL
 };
 
@@ -333,15 +334,8 @@
 
 		klen = strlen(hmac_sha256_tv[i].key);
 	
-		//printk("DS=%u\n", crypto_tfm_alg_digestsize(tfm));
-		
-		//printk("K=");
 		hexdump(hmac_sha256_tv[i].key, strlen(hmac_sha256_tv[i].key));
-		//printk("P=%s\n", hmac_sha256_tv[i].plaintext);
-		
 		crypto_hmac(tfm, hmac_sha256_tv[i].key, &klen, sg, 1, result);
-
-		//printk("H=");
 		hexdump(result, crypto_tfm_alg_digestsize(tfm));
 		printk("%s\n",
 		       memcmp(result, hmac_sha256_tv[i].digest,
@@ -1616,7 +1610,7 @@
 
 		sg[0].page = virt_to_page(p);
 		sg[0].offset = ((long) p & ~PAGE_MASK);
-		sg[0].length =  bf_tv[i].plen;;
+		sg[0].length =  bf_tv[i].plen;
 
 		crypto_cipher_set_iv(tfm, bf_tv[i].iv,
 				     crypto_tfm_alg_ivsize(tfm));
@@ -1661,7 +1655,7 @@
 
 		sg[0].page = virt_to_page(p);
 		sg[0].offset = ((long) p & ~PAGE_MASK);
-		sg[0].length =  bf_tv[i].plen;;
+		sg[0].length =  bf_tv[i].plen;
 
 		crypto_cipher_set_iv(tfm, bf_tv[i].iv,
 				     crypto_tfm_alg_ivsize(tfm));
@@ -1684,6 +1678,311 @@
 	crypto_free_tfm(tfm);
 }
 
+
+void
+test_twofish(void)
+{
+	unsigned int ret, i;
+	unsigned int tsize;
+	char *p, *q;
+	struct crypto_tfm *tfm;
+	char *key;
+	struct tf_tv *tf_tv;
+	struct scatterlist sg[1];
+
+	printk("\ntesting twofish encryption\n");
+
+	tsize = sizeof (tf_enc_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, tf_enc_tv_template, tsize);
+	tf_tv = (void *) tvmem;
+
+	tfm = crypto_alloc_tfm("twofish", 0);
+	if (tfm == NULL) {
+		printk("failed to load transform for blowfish (default ecb)\n");
+		return;
+	}
+
+	for (i = 0; i < TF_ENC_TEST_VECTORS; i++) {
+		printk("test %u (%d bit key):\n",
+			i + 1, tf_tv[i].keylen * 8);
+		key = tf_tv[i].key;
+
+		ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+
+			if (!tf_tv[i].fail)
+				goto out;
+		}
+
+		p = tf_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = tf_tv[i].plen;
+		ret = crypto_cipher_encrypt(tfm, sg, 1);
+		if (ret) {
+			printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, tf_tv[i].rlen);
+
+		printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen) ?
+			"fail" : "pass");
+	}
+
+	printk("\ntesting twofish decryption\n");
+
+	tsize = sizeof (tf_dec_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, tf_dec_tv_template, tsize);
+	tf_tv = (void *) tvmem;
+
+	for (i = 0; i < TF_DEC_TEST_VECTORS; i++) {
+		printk("test %u (%d bit key):\n",
+			i + 1, tf_tv[i].keylen * 8);
+		key = tf_tv[i].key;
+
+		ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+
+			if (!tf_tv[i].fail)
+				goto out;
+		}
+
+		p = tf_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = tf_tv[i].plen;
+		ret = crypto_cipher_decrypt(tfm, sg, 1);
+		if (ret) {
+			printk("decrypt() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, tf_tv[i].rlen);
+
+		printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen) ?
+			"fail" : "pass");
+	}
+
+	crypto_free_tfm(tfm);
+	
+	tfm = crypto_alloc_tfm("twofish", CRYPTO_TFM_MODE_CBC);
+	if (tfm == NULL) {
+		printk("failed to load transform for twofish cbc\n");
+		return;
+	}
+
+	printk("\ntesting twofish cbc encryption\n");
+
+	tsize = sizeof (tf_cbc_enc_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		goto out;
+	}
+	memcpy(tvmem, tf_cbc_enc_tv_template, tsize);
+	tf_tv = (void *) tvmem;
+
+	for (i = 0; i < TF_CBC_ENC_TEST_VECTORS; i++) {
+		printk("test %u (%d bit key):\n",
+			i + 1, tf_tv[i].keylen * 8);
+
+		key = tf_tv[i].key;
+
+		ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		p = tf_tv[i].plaintext;
+
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length =  tf_tv[i].plen;
+
+		crypto_cipher_set_iv(tfm, tf_tv[i].iv,
+				     crypto_tfm_alg_ivsize(tfm));
+
+		ret = crypto_cipher_encrypt(tfm, sg, 1);
+		if (ret) {
+			printk("blowfish_cbc_encrypt() failed flags=%x\n",
+			       tfm->crt_flags);
+			goto out;
+		}
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, tf_tv[i].rlen);
+
+		printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen)
+			? "fail" : "pass");
+	}
+
+	printk("\ntesting twofish cbc decryption\n");
+
+	tsize = sizeof (tf_cbc_dec_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		goto out;
+	}
+	memcpy(tvmem, tf_cbc_dec_tv_template, tsize);
+	tf_tv = (void *) tvmem;
+
+	for (i = 0; i < TF_CBC_DEC_TEST_VECTORS; i++) {
+		printk("test %u (%d bit key):\n",
+			i + 1, tf_tv[i].keylen * 8);
+
+		key = tf_tv[i].key;
+
+		ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		p = tf_tv[i].plaintext;
+
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length =  tf_tv[i].plen;
+
+		crypto_cipher_set_iv(tfm, tf_tv[i].iv,
+				     crypto_tfm_alg_ivsize(tfm));
+
+		ret = crypto_cipher_decrypt(tfm, sg, 1);
+		if (ret) {
+			printk("blowfish_cbc_decrypt() failed flags=%x\n",
+			       tfm->crt_flags);
+			goto out;
+		}
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, tf_tv[i].rlen);
+
+		printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen)
+			? "fail" : "pass");
+	}
+
+out:	
+	crypto_free_tfm(tfm);
+}
+
+void
+test_serpent(void)
+{
+	unsigned int ret, i, tsize;
+	u8 *p, *q, *key;
+	struct crypto_tfm *tfm;
+	struct serpent_tv *serp_tv;
+	struct scatterlist sg[1];
+
+	printk("\ntesting serpent encryption\n");
+
+	tfm = crypto_alloc_tfm("serpent", 0);
+	if (tfm == NULL) {
+		printk("failed to load transform for serpent (default ecb)\n");
+		return;
+	}
+
+	tsize = sizeof (serpent_enc_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, serpent_enc_tv_template, tsize);
+	serp_tv = (void *) tvmem;
+	for (i = 0; i < SERPENT_ENC_TEST_VECTORS; i++) {
+		printk("test %u (%d bit key):\n", i + 1, serp_tv[i].keylen * 8);
+		key = serp_tv[i].key;
+
+		ret = crypto_cipher_setkey(tfm, key, serp_tv[i].keylen);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+
+			if (!serp_tv[i].fail)
+				goto out;
+		}
+
+		p = serp_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = sizeof(serp_tv[i].plaintext);
+		ret = crypto_cipher_encrypt(tfm, sg, 1);
+		if (ret) {
+			printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, sizeof(serp_tv[i].result));
+
+		printk("%s\n", memcmp(q, serp_tv[i].result,
+			sizeof(serp_tv[i].result)) ? "fail" : "pass");
+	}
+
+	printk("\ntesting serpent decryption\n");
+
+	tsize = sizeof (serpent_dec_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, serpent_dec_tv_template, tsize);
+	serp_tv = (void *) tvmem;
+	for (i = 0; i < SERPENT_DEC_TEST_VECTORS; i++) {
+		printk("test %u (%d bit key):\n", i + 1, serp_tv[i].keylen * 8);
+		key = serp_tv[i].key;
+
+		ret = crypto_cipher_setkey(tfm, key, serp_tv[i].keylen);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+
+			if (!serp_tv[i].fail)
+				goto out;
+		}
+
+		p = serp_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = sizeof(serp_tv[i].plaintext);
+		ret = crypto_cipher_decrypt(tfm, sg, 1);
+		if (ret) {
+			printk("decrypt() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		q = kmap(sg[0].page) + sg[0].offset;
+		hexdump(q, sizeof(serp_tv[i].result));
+
+		printk("%s\n", memcmp(q, serp_tv[i].result,
+			sizeof(serp_tv[i].result)) ? "fail" : "pass");
+	}
+
+out:
+	crypto_free_tfm(tfm);
+}
+
 static void
 test_available(void)
 {
@@ -1710,6 +2009,8 @@
 		test_md4();
 		test_sha256();
 		test_blowfish();
+		test_twofish();
+		test_serpent();
 #ifdef CONFIG_CRYPTO_HMAC
 		test_hmac_md5();
 		test_hmac_sha1();
@@ -1743,6 +2044,14 @@
 	
 	case 7:
 		test_blowfish();
+		break;
+
+	case 8:
+		test_twofish();
+		break;
+
+	case 9:
+		test_serpent();
 		break;
 
 #ifdef CONFIG_CRYPTO_HMAC
diff -Nru a/crypto/tcrypt.h b/crypto/tcrypt.h
--- a/crypto/tcrypt.h	Mon Dec  9 18:46:51 2002
+++ b/crypto/tcrypt.h	Mon Dec  9 18:46:51 2002
@@ -1167,4 +1167,317 @@
 	},
 };
 
+/*
+ * Twofish test vectors.
+ */
+#define TF_ENC_TEST_VECTORS		3
+#define TF_DEC_TEST_VECTORS		3
+#define TF_CBC_ENC_TEST_VECTORS		4
+#define TF_CBC_DEC_TEST_VECTORS		4
+
+struct tf_tv {
+	unsigned int keylen;
+	unsigned int plen;
+	unsigned int rlen;
+	int fail;
+	char key[32];
+	char iv[16];
+	char plaintext[48];
+	char result[48];
+};
+
+struct tf_tv tf_enc_tv_template[] = {
+	{
+		16, 16, 16, 0,
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32,
+		  0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A }
+	},
+	{
+		24, 16, 16, 0,
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+		  0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+		  0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
+		{ 0 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0xCF, 0xD1, 0xD2, 0xE5, 0xA9, 0xBE, 0x9C, 0xDF,
+		  0x50, 0x1F, 0x13, 0xB8, 0x92, 0xBD, 0x22, 0x48 }
+	},
+	{	
+		32, 16, 16, 0,
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+		  0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+		  0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+		  0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF },
+		{ 0 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x37, 0x52, 0x7B, 0xE0, 0x05, 0x23, 0x34, 0xB8,
+		  0x9F, 0x0C, 0xFC, 0xCA, 0xE8, 0x7C, 0xFA, 0x20 }
+	},
+};
+
+struct tf_tv tf_dec_tv_template[] = {
+	{
+		16, 16, 16, 0,
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0 },
+		{ 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32,
+		  0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },  
+	},
+	{
+		24, 16, 16, 0,
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+		  0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+		  0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
+		{ 0 },
+		{ 0xCF, 0xD1, 0xD2, 0xE5, 0xA9, 0xBE, 0x9C, 0xDF,
+		  0x50, 0x1F, 0x13, 0xB8, 0x92, 0xBD, 0x22, 0x48 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+	},
+	{	
+		32, 16, 16, 0,
+		{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+		  0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+		  0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+		  0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF },
+		{ 0 },
+		{ 0x37, 0x52, 0x7B, 0xE0, 0x05, 0x23, 0x34, 0xB8,
+		  0x9F, 0x0C, 0xFC, 0xCA, 0xE8, 0x7C, 0xFA, 0x20 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+	},
+};
+
+struct tf_tv tf_cbc_enc_tv_template[] = {
+	/* Generated with Nettle */
+	{
+		16, 16, 16, 0,
+		
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  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, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
+		  0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a },
+	},
+	
+	{
+		16, 16, 16, 0,
+		
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
+		  0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
+		  0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 },
+	},
+	
+	{
+		16, 16, 16, 0,
+		
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
+		  0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26,
+		  0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 },
+	},
+	
+	{
+		16, 48, 48, 0,
+		
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  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, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
+		  0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a,
+		  0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
+		  0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19,
+		  0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26,
+		  0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 },
+	},
+};
+
+struct tf_tv tf_cbc_dec_tv_template[] = {
+	/* Reverse of the first four above */
+	{
+		16, 16, 16, 0,
+		
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  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, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
+		  0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a },		  
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+	},
+	
+	{
+		16, 16, 16, 0,
+		
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
+		  0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a },
+		{ 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
+		  0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },  
+	},
+	
+	{
+		16, 16, 16, 0,
+		
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
+		  0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 },
+		{ 0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26,
+		  0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },  
+	},
+	
+	{
+		16, 48, 48, 0,
+		
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  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, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
+		  0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a,
+		  0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
+		  0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19,
+		  0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26,
+		  0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+	},
+};
+
+/*
+ * Serpent test vectors.  These are backwards because Serpent writes
+ * octect sequences in right-to-left mode.
+ */
+#define SERPENT_ENC_TEST_VECTORS	4
+#define SERPENT_DEC_TEST_VECTORS	4
+
+struct serpent_tv {
+	unsigned int keylen, fail;
+	u8 key[32], plaintext[16], result[16];
+};
+
+struct serpent_tv serpent_enc_tv_template[] = 
+{
+	{
+		0, 0,
+		{ 0 },
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+		{ 0x12, 0x07, 0xfc, 0xce, 0x9b, 0xd0, 0xd6, 0x47,
+		  0x6a, 0xe9, 0x8f, 0xbe, 0xd1, 0x43, 0xa0, 0xe2 }
+	},
+	{
+		16, 0,
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+		{ 0x4c, 0x7d, 0x8a, 0x32, 0x80, 0x72, 0xa2, 0x2c,
+		  0x82, 0x3e, 0x4a, 0x1f, 0x3a, 0xcd, 0xa1, 0x6d }
+	},
+	{
+		32, 0,
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+		  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+		  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+		{ 0xde, 0x26, 0x9f, 0xf8, 0x33, 0xe4, 0x32, 0xb8,
+		  0x5b, 0x2e, 0x88, 0xd2, 0x70, 0x1c, 0xe7, 0x5c }
+	},
+	{
+		16, 0,
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 },
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+		{ 0xdd, 0xd2, 0x6b, 0x98, 0xa5, 0xff, 0xd8, 0x2c,
+		  0x05, 0x34, 0x5a, 0x9d, 0xad, 0xbf, 0xaf, 0x49}
+	}
+};
+
+struct serpent_tv serpent_dec_tv_template[] = 
+{
+	{
+		0, 0,
+		{ 0 },
+		{ 0x12, 0x07, 0xfc, 0xce, 0x9b, 0xd0, 0xd6, 0x47,
+		  0x6a, 0xe9, 0x8f, 0xbe, 0xd1, 0x43, 0xa0, 0xe2 },
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+
+	},
+	{
+		16, 0,
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+		{ 0x4c, 0x7d, 0x8a, 0x32, 0x80, 0x72, 0xa2, 0x2c,
+		  0x82, 0x3e, 0x4a, 0x1f, 0x3a, 0xcd, 0xa1, 0x6d },
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+	},
+	{
+		32, 0,
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+		  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+		  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
+
+		{ 0xde, 0x26, 0x9f, 0xf8, 0x33, 0xe4, 0x32, 0xb8,
+		  0x5b, 0x2e, 0x88, 0xd2, 0x70, 0x1c, 0xe7, 0x5c },
+		{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+	},
+	{
+		16, 0,
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 },
+		{ 0xdd, 0xd2, 0x6b, 0x98, 0xa5, 0xff, 0xd8, 0x2c,
+		  0x05, 0x34, 0x5a, 0x9d, 0xad, 0xbf, 0xaf, 0x49},
+		{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },  
+	}
+};
+
 #endif	/* _CRYPTO_TCRYPT_H */
diff -Nru a/crypto/twofish.c b/crypto/twofish.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/crypto/twofish.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,899 @@
+/*
+ * Twofish for CryptoAPI
+ *
+ * Originaly Twofish for GPG
+ * By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
+ * 256-bit key length added March 20, 1999
+ * Some modifications to reduce the text size by Werner Koch, April, 1998
+ * Ported to the kerneli patch by Marc Mutz <Marc@Mutz.com>
+ * Ported to CryptoAPI by Colin Slater <hoho@tacomeat.net>
+ *
+ * The original author has disclaimed all copyright interest in this
+ * code and thus put it in the public domain. The subsequent authors 
+ * have put this under the GNU General Public License.
+ *
+ * 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 code is a "clean room" implementation, written from the paper
+ * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
+ * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
+ * through http://www.counterpane.com/twofish.html
+ *
+ * For background information on multiplication in finite fields, used for
+ * the matrix operations in the key schedule, see the book _Contemporary
+ * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
+ * Third Edition.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/crypto.h>
+
+
+/* The large precomputed tables for the Twofish cipher (twofish.c)
+ * Taken from the same source as twofish.c
+ * Marc Mutz <Marc@Mutz.com>
+ */
+
+/* These two tables are the q0 and q1 permutations, exactly as described in
+ * the Twofish paper. */
+
+static const u8 q0[256] = {
+   0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78,
+   0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
+   0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30,
+   0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
+   0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE,
+   0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
+   0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45,
+   0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
+   0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF,
+   0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
+   0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED,
+   0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
+   0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B,
+   0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
+   0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F,
+   0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
+   0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17,
+   0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
+   0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68,
+   0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
+   0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42,
+   0x4A, 0x5E, 0xC1, 0xE0
+};
+
+static const u8 q1[256] = {
+   0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B,
+   0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
+   0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B,
+   0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
+   0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54,
+   0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
+   0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7,
+   0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
+   0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF,
+   0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
+   0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D,
+   0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
+   0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21,
+   0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
+   0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E,
+   0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
+   0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44,
+   0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
+   0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B,
+   0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
+   0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56,
+   0x55, 0x09, 0xBE, 0x91
+};
+
+/* These MDS tables are actually tables of MDS composed with q0 and q1,
+ * because it is only ever used that way and we can save some time by
+ * precomputing.  Of course the main saving comes from precomputing the
+ * GF(2^8) multiplication involved in the MDS matrix multiply; by looking
+ * things up in these tables we reduce the matrix multiply to four lookups
+ * and three XORs.  Semi-formally, the definition of these tables is:
+ * mds[0][i] = MDS (q1[i] 0 0 0)^T  mds[1][i] = MDS (0 q0[i] 0 0)^T
+ * mds[2][i] = MDS (0 0 q1[i] 0)^T  mds[3][i] = MDS (0 0 0 q0[i])^T
+ * where ^T means "transpose", the matrix multiply is performed in GF(2^8)
+ * represented as GF(2)[x]/v(x) where v(x)=x^8+x^6+x^5+x^3+1 as described
+ * by Schneier et al, and I'm casually glossing over the byte/word
+ * conversion issues. */
+
+static const u32 mds[4][256] = {
+   {0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B,
+    0xE2E22BFB, 0x9E9EFAC8, 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B,
+    0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, 0x3C3C57D6, 0x93938A32,
+    0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
+    0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA,
+    0xB0B0B306, 0x7575DE3F, 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B,
+    0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D, 0xAEAE2C6D, 0x7F7FABC1,
+    0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5,
+    0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490,
+    0x3131272C, 0x808065A3, 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154,
+    0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51, 0x2A2A3638, 0xC4C49CB0,
+    0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796,
+    0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228,
+    0x6767C027, 0xE9E9AF8C, 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7,
+    0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70, 0x29294CCA, 0xF0F035E3,
+    0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8,
+    0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477,
+    0xC8C81DC3, 0x9999FFCC, 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF,
+    0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2, 0xB5B53D79, 0x09090F0C,
+    0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9,
+    0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA,
+    0xEDEDD07A, 0x4343FC17, 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D,
+    0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3, 0x5656E70B, 0xE3E3DA72,
+    0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E,
+    0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76,
+    0x8181942A, 0x91910149, 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321,
+    0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9, 0x7878AEC5, 0xC5C56D39,
+    0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01,
+    0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D,
+    0x55559DF9, 0x7E7E5A48, 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E,
+    0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519, 0x0606F48D, 0x404086E5,
+    0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64,
+    0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7,
+    0x2D2D333C, 0x3030D6A5, 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544,
+    0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969, 0xD9D97929, 0x8686912E,
+    0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E,
+    0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A,
+    0xC1C112CF, 0x8585EBDC, 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B,
+    0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB, 0xABABA212, 0x6F6F3EA2,
+    0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9,
+    0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504,
+    0x04047FF6, 0x272746C2, 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756,
+    0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91},
+
+   {0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252,
+    0xA3658080, 0x76DFE4E4, 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A,
+    0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, 0x0D54E6E6, 0xC6432020,
+    0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
+    0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444,
+    0x94B1FBFB, 0x485A7E7E, 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424,
+    0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060, 0x1945FDFD, 0x5BA33A3A,
+    0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757,
+    0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383,
+    0x9B53AAAA, 0x7C635D5D, 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A,
+    0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7, 0xC0F09090, 0x8CAFE9E9,
+    0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656,
+    0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1,
+    0xB499C3C3, 0xF1975B5B, 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898,
+    0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8, 0xCCFF9999, 0x95EA1414,
+    0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3,
+    0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1,
+    0xBF7E9595, 0xBA207D7D, 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989,
+    0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB, 0x81FB0F0F, 0x793DB5B5,
+    0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282,
+    0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E,
+    0x86135050, 0xE730F7F7, 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E,
+    0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B, 0x410B9F9F, 0x7B8B0202,
+    0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC,
+    0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565,
+    0xB1C72B2B, 0xAB6F8E8E, 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A,
+    0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9, 0x91EF1313, 0x85FE0808,
+    0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272,
+    0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A,
+    0x6929A9A9, 0x647D4F4F, 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969,
+    0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED, 0xAC87D1D1, 0x7F8E0505,
+    0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5,
+    0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D,
+    0x4C5F7979, 0x02B6B7B7, 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343,
+    0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2, 0x57AC3333, 0xC718CFCF,
+    0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3,
+    0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F,
+    0x99E51D1D, 0x34392323, 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646,
+    0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA, 0xC8FA9E9E, 0xA882D6D6,
+    0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF,
+    0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A,
+    0x0FE25151, 0x00000000, 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7,
+    0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8},
+
+   {0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B,
+    0xE2FBE22B, 0x9EC89EFA, 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F,
+    0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, 0x3CD63C57, 0x9332938A,
+    0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
+    0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70,
+    0xB006B0B3, 0x753F75DE, 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3,
+    0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0, 0xAE6DAE2C, 0x7FC17FAB,
+    0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA,
+    0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4,
+    0x312C3127, 0x80A38065, 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41,
+    0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F, 0x2A382A36, 0xC4B0C49C,
+    0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07,
+    0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622,
+    0x672767C0, 0xE98CE9AF, 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18,
+    0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C, 0x29CA294C, 0xF0E3F035,
+    0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96,
+    0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84,
+    0xC8C3C81D, 0x99CC99FF, 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E,
+    0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E, 0xB579B53D, 0x090C090F,
+    0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD,
+    0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558,
+    0xED7AEDD0, 0x431743FC, 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40,
+    0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71, 0x560B56E7, 0xE372E3DA,
+    0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85,
+    0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF,
+    0x812A8194, 0x91499101, 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773,
+    0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5, 0x78C578AE, 0xC539C56D,
+    0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B,
+    0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C,
+    0x55F9559D, 0x7E487E5A, 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19,
+    0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45, 0x068D06F4, 0x40E54086,
+    0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D,
+    0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74,
+    0x2D3C2D33, 0x30A530D6, 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755,
+    0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929, 0xD929D979, 0x862E8691,
+    0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D,
+    0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4,
+    0xC1CFC112, 0x85DC85EB, 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53,
+    0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F, 0xAB12ABA2, 0x6FA26F3E,
+    0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9,
+    0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705,
+    0x04F6047F, 0x27C22746, 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7,
+    0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF},
+
+   {0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98,
+    0x6580A365, 0xDFE476DF, 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866,
+    0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, 0x54E60D54, 0x4320C643,
+    0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
+    0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9,
+    0xB1FB94B1, 0x5A7E485A, 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C,
+    0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5, 0x45FD1945, 0xA33A5BA3,
+    0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216,
+    0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F,
+    0x53AA9B53, 0x635D7C63, 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25,
+    0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123, 0xF090C0F0, 0xAFE98CAF,
+    0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7,
+    0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4,
+    0x99C3B499, 0x975BF197, 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E,
+    0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB, 0xFF99CCFF, 0xEA1495EA,
+    0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C,
+    0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12,
+    0x7E95BF7E, 0x207DBA20, 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A,
+    0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137, 0xFB0F81FB, 0x3DB5793D,
+    0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE,
+    0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A,
+    0x13508613, 0x30F7E730, 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C,
+    0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252, 0x0B9F410B, 0x8B027B8B,
+    0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4,
+    0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B,
+    0xC72BB1C7, 0x6F8EAB6F, 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3,
+    0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A, 0xEF1391EF, 0xFE0885FE,
+    0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB,
+    0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85,
+    0x29A96929, 0x7D4F647D, 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA,
+    0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0, 0x87D1AC87, 0x8E057F8E,
+    0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8,
+    0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33,
+    0x5F794C5F, 0xB6B702B6, 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC,
+    0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38, 0xAC3357AC, 0x18CFC718,
+    0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA,
+    0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8,
+    0xE51D99E5, 0x39233439, 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872,
+    0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6, 0xFA9EC8FA, 0x82D6A882,
+    0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D,
+    0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10,
+    0xE2510FE2, 0x00000000, 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6,
+    0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8}
+};
+
+/* The exp_to_poly and poly_to_exp tables are used to perform efficient
+ * operations in GF(2^8) represented as GF(2)[x]/w(x) where
+ * w(x)=x^8+x^6+x^3+x^2+1.  We care about doing that because it's part of the
+ * definition of the RS matrix in the key schedule.  Elements of that field
+ * are polynomials of degree not greater than 7 and all coefficients 0 or 1,
+ * which can be represented naturally by bytes (just substitute x=2).  In that
+ * form, GF(2^8) addition is the same as bitwise XOR, but GF(2^8)
+ * multiplication is inefficient without hardware support.  To multiply
+ * faster, I make use of the fact x is a generator for the nonzero elements,
+ * so that every element p of GF(2)[x]/w(x) is either 0 or equal to (x)^n for
+ * some n in 0..254.  Note that that caret is exponentiation in GF(2^8),
+ * *not* polynomial notation.  So if I want to compute pq where p and q are
+ * in GF(2^8), I can just say:
+ *    1. if p=0 or q=0 then pq=0
+ *    2. otherwise, find m and n such that p=x^m and q=x^n
+ *    3. pq=(x^m)(x^n)=x^(m+n), so add m and n and find pq
+ * The translations in steps 2 and 3 are looked up in the tables
+ * poly_to_exp (for step 2) and exp_to_poly (for step 3).  To see this
+ * in action, look at the CALC_S macro.  As additional wrinkles, note that
+ * one of my operands is always a constant, so the poly_to_exp lookup on it
+ * is done in advance; I included the original values in the comments so
+ * readers can have some chance of recognizing that this *is* the RS matrix
+ * from the Twofish paper.  I've only included the table entries I actually
+ * need; I never do a lookup on a variable input of zero and the biggest
+ * exponents I'll ever see are 254 (variable) and 237 (constant), so they'll
+ * never sum to more than 491.	I'm repeating part of the exp_to_poly table
+ * so that I don't have to do mod-255 reduction in the exponent arithmetic.
+ * Since I know my constant operands are never zero, I only have to worry
+ * about zero values in the variable operand, and I do it with a simple
+ * conditional branch.	I know conditionals are expensive, but I couldn't
+ * see a non-horrible way of avoiding them, and I did manage to group the
+ * statements so that each if covers four group multiplications. */
+
+static const u8 poly_to_exp[255] = {
+   0x00, 0x01, 0x17, 0x02, 0x2E, 0x18, 0x53, 0x03, 0x6A, 0x2F, 0x93, 0x19,
+   0x34, 0x54, 0x45, 0x04, 0x5C, 0x6B, 0xB6, 0x30, 0xA6, 0x94, 0x4B, 0x1A,
+   0x8C, 0x35, 0x81, 0x55, 0xAA, 0x46, 0x0D, 0x05, 0x24, 0x5D, 0x87, 0x6C,
+   0x9B, 0xB7, 0xC1, 0x31, 0x2B, 0xA7, 0xA3, 0x95, 0x98, 0x4C, 0xCA, 0x1B,
+   0xE6, 0x8D, 0x73, 0x36, 0xCD, 0x82, 0x12, 0x56, 0x62, 0xAB, 0xF0, 0x47,
+   0x4F, 0x0E, 0xBD, 0x06, 0xD4, 0x25, 0xD2, 0x5E, 0x27, 0x88, 0x66, 0x6D,
+   0xD6, 0x9C, 0x79, 0xB8, 0x08, 0xC2, 0xDF, 0x32, 0x68, 0x2C, 0xFD, 0xA8,
+   0x8A, 0xA4, 0x5A, 0x96, 0x29, 0x99, 0x22, 0x4D, 0x60, 0xCB, 0xE4, 0x1C,
+   0x7B, 0xE7, 0x3B, 0x8E, 0x9E, 0x74, 0xF4, 0x37, 0xD8, 0xCE, 0xF9, 0x83,
+   0x6F, 0x13, 0xB2, 0x57, 0xE1, 0x63, 0xDC, 0xAC, 0xC4, 0xF1, 0xAF, 0x48,
+   0x0A, 0x50, 0x42, 0x0F, 0xBA, 0xBE, 0xC7, 0x07, 0xDE, 0xD5, 0x78, 0x26,
+   0x65, 0xD3, 0xD1, 0x5F, 0xE3, 0x28, 0x21, 0x89, 0x59, 0x67, 0xFC, 0x6E,
+   0xB1, 0xD7, 0xF8, 0x9D, 0xF3, 0x7A, 0x3A, 0xB9, 0xC6, 0x09, 0x41, 0xC3,
+   0xAE, 0xE0, 0xDB, 0x33, 0x44, 0x69, 0x92, 0x2D, 0x52, 0xFE, 0x16, 0xA9,
+   0x0C, 0x8B, 0x80, 0xA5, 0x4A, 0x5B, 0xB5, 0x97, 0xC9, 0x2A, 0xA2, 0x9A,
+   0xC0, 0x23, 0x86, 0x4E, 0xBC, 0x61, 0xEF, 0xCC, 0x11, 0xE5, 0x72, 0x1D,
+   0x3D, 0x7C, 0xEB, 0xE8, 0xE9, 0x3C, 0xEA, 0x8F, 0x7D, 0x9F, 0xEC, 0x75,
+   0x1E, 0xF5, 0x3E, 0x38, 0xF6, 0xD9, 0x3F, 0xCF, 0x76, 0xFA, 0x1F, 0x84,
+   0xA0, 0x70, 0xED, 0x14, 0x90, 0xB3, 0x7E, 0x58, 0xFB, 0xE2, 0x20, 0x64,
+   0xD0, 0xDD, 0x77, 0xAD, 0xDA, 0xC5, 0x40, 0xF2, 0x39, 0xB0, 0xF7, 0x49,
+   0xB4, 0x0B, 0x7F, 0x51, 0x15, 0x43, 0x91, 0x10, 0x71, 0xBB, 0xEE, 0xBF,
+   0x85, 0xC8, 0xA1
+};
+
+static const u8 exp_to_poly[492] = {
+   0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, 0x9A, 0x79, 0xF2,
+   0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, 0xF5, 0xA7, 0x03,
+   0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, 0x8B, 0x5B, 0xB6,
+   0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52, 0xA4, 0x05, 0x0A,
+   0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0, 0xED, 0x97, 0x63,
+   0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1, 0x0F, 0x1E, 0x3C,
+   0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A, 0xF4, 0xA5, 0x07,
+   0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11, 0x22, 0x44, 0x88,
+   0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51, 0xA2, 0x09, 0x12,
+   0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66, 0xCC, 0xD5, 0xE7,
+   0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB, 0x1B, 0x36, 0x6C,
+   0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19, 0x32, 0x64, 0xC8,
+   0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D, 0x5A, 0xB4, 0x25,
+   0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56, 0xAC, 0x15, 0x2A,
+   0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE, 0x91, 0x6F, 0xDE,
+   0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9, 0x3F, 0x7E, 0xFC,
+   0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE, 0xB1, 0x2F, 0x5E,
+   0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41, 0x82, 0x49, 0x92,
+   0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E, 0x71, 0xE2, 0x89,
+   0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB, 0xDB, 0xFB, 0xBB,
+   0x3B, 0x76, 0xEC, 0x95, 0x67, 0xCE, 0xD1, 0xEF, 0x93, 0x6B, 0xD6, 0xE1,
+   0x8F, 0x53, 0xA6, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D,
+   0x9A, 0x79, 0xF2, 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC,
+   0xF5, 0xA7, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3,
+   0x8B, 0x5B, 0xB6, 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52,
+   0xA4, 0x05, 0x0A, 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0,
+   0xED, 0x97, 0x63, 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1,
+   0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A,
+   0xF4, 0xA5, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11,
+   0x22, 0x44, 0x88, 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51,
+   0xA2, 0x09, 0x12, 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66,
+   0xCC, 0xD5, 0xE7, 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB,
+   0x1B, 0x36, 0x6C, 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19,
+   0x32, 0x64, 0xC8, 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D,
+   0x5A, 0xB4, 0x25, 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56,
+   0xAC, 0x15, 0x2A, 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE,
+   0x91, 0x6F, 0xDE, 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9,
+   0x3F, 0x7E, 0xFC, 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE,
+   0xB1, 0x2F, 0x5E, 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41,
+   0x82, 0x49, 0x92, 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E,
+   0x71, 0xE2, 0x89, 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB
+};
+
+
+/* The table constants are indices of
+ * S-box entries, preprocessed through q0 and q1. */
+static const u8 calc_sb_tbl[512] = {
+    0xA9, 0x75, 0x67, 0xF3, 0xB3, 0xC6, 0xE8, 0xF4,
+    0x04, 0xDB, 0xFD, 0x7B, 0xA3, 0xFB, 0x76, 0xC8,
+    0x9A, 0x4A, 0x92, 0xD3, 0x80, 0xE6, 0x78, 0x6B,
+    0xE4, 0x45, 0xDD, 0x7D, 0xD1, 0xE8, 0x38, 0x4B,
+    0x0D, 0xD6, 0xC6, 0x32, 0x35, 0xD8, 0x98, 0xFD,
+    0x18, 0x37, 0xF7, 0x71, 0xEC, 0xF1, 0x6C, 0xE1,
+    0x43, 0x30, 0x75, 0x0F, 0x37, 0xF8, 0x26, 0x1B,
+    0xFA, 0x87, 0x13, 0xFA, 0x94, 0x06, 0x48, 0x3F,
+    0xF2, 0x5E, 0xD0, 0xBA, 0x8B, 0xAE, 0x30, 0x5B,
+    0x84, 0x8A, 0x54, 0x00, 0xDF, 0xBC, 0x23, 0x9D,
+    0x19, 0x6D, 0x5B, 0xC1, 0x3D, 0xB1, 0x59, 0x0E,
+    0xF3, 0x80, 0xAE, 0x5D, 0xA2, 0xD2, 0x82, 0xD5,
+    0x63, 0xA0, 0x01, 0x84, 0x83, 0x07, 0x2E, 0x14,
+    0xD9, 0xB5, 0x51, 0x90, 0x9B, 0x2C, 0x7C, 0xA3,
+    0xA6, 0xB2, 0xEB, 0x73, 0xA5, 0x4C, 0xBE, 0x54,
+    0x16, 0x92, 0x0C, 0x74, 0xE3, 0x36, 0x61, 0x51,
+    0xC0, 0x38, 0x8C, 0xB0, 0x3A, 0xBD, 0xF5, 0x5A,
+    0x73, 0xFC, 0x2C, 0x60, 0x25, 0x62, 0x0B, 0x96,
+    0xBB, 0x6C, 0x4E, 0x42, 0x89, 0xF7, 0x6B, 0x10,
+    0x53, 0x7C, 0x6A, 0x28, 0xB4, 0x27, 0xF1, 0x8C,
+    0xE1, 0x13, 0xE6, 0x95, 0xBD, 0x9C, 0x45, 0xC7,
+    0xE2, 0x24, 0xF4, 0x46, 0xB6, 0x3B, 0x66, 0x70,
+    0xCC, 0xCA, 0x95, 0xE3, 0x03, 0x85, 0x56, 0xCB,
+    0xD4, 0x11, 0x1C, 0xD0, 0x1E, 0x93, 0xD7, 0xB8,
+    0xFB, 0xA6, 0xC3, 0x83, 0x8E, 0x20, 0xB5, 0xFF,
+    0xE9, 0x9F, 0xCF, 0x77, 0xBF, 0xC3, 0xBA, 0xCC,
+    0xEA, 0x03, 0x77, 0x6F, 0x39, 0x08, 0xAF, 0xBF,
+    0x33, 0x40, 0xC9, 0xE7, 0x62, 0x2B, 0x71, 0xE2,
+    0x81, 0x79, 0x79, 0x0C, 0x09, 0xAA, 0xAD, 0x82,
+    0x24, 0x41, 0xCD, 0x3A, 0xF9, 0xEA, 0xD8, 0xB9,
+    0xE5, 0xE4, 0xC5, 0x9A, 0xB9, 0xA4, 0x4D, 0x97,
+    0x44, 0x7E, 0x08, 0xDA, 0x86, 0x7A, 0xE7, 0x17,
+    0xA1, 0x66, 0x1D, 0x94, 0xAA, 0xA1, 0xED, 0x1D,
+    0x06, 0x3D, 0x70, 0xF0, 0xB2, 0xDE, 0xD2, 0xB3,
+    0x41, 0x0B, 0x7B, 0x72, 0xA0, 0xA7, 0x11, 0x1C,
+    0x31, 0xEF, 0xC2, 0xD1, 0x27, 0x53, 0x90, 0x3E,
+    0x20, 0x8F, 0xF6, 0x33, 0x60, 0x26, 0xFF, 0x5F,
+    0x96, 0xEC, 0x5C, 0x76, 0xB1, 0x2A, 0xAB, 0x49,
+    0x9E, 0x81, 0x9C, 0x88, 0x52, 0xEE, 0x1B, 0x21,
+    0x5F, 0xC4, 0x93, 0x1A, 0x0A, 0xEB, 0xEF, 0xD9,
+    0x91, 0xC5, 0x85, 0x39, 0x49, 0x99, 0xEE, 0xCD,
+    0x2D, 0xAD, 0x4F, 0x31, 0x8F, 0x8B, 0x3B, 0x01,
+    0x47, 0x18, 0x87, 0x23, 0x6D, 0xDD, 0x46, 0x1F,
+    0xD6, 0x4E, 0x3E, 0x2D, 0x69, 0xF9, 0x64, 0x48,
+    0x2A, 0x4F, 0xCE, 0xF2, 0xCB, 0x65, 0x2F, 0x8E,
+    0xFC, 0x78, 0x97, 0x5C, 0x05, 0x58, 0x7A, 0x19,
+    0xAC, 0x8D, 0x7F, 0xE5, 0xD5, 0x98, 0x1A, 0x57,
+    0x4B, 0x67, 0x0E, 0x7F, 0xA7, 0x05, 0x5A, 0x64,
+    0x28, 0xAF, 0x14, 0x63, 0x3F, 0xB6, 0x29, 0xFE,
+    0x88, 0xF5, 0x3C, 0xB7, 0x4C, 0x3C, 0x02, 0xA5,
+    0xB8, 0xCE, 0xDA, 0xE9, 0xB0, 0x68, 0x17, 0x44,
+    0x55, 0xE0, 0x1F, 0x4D, 0x8A, 0x43, 0x7D, 0x69,
+    0x57, 0x29, 0xC7, 0x2E, 0x8D, 0xAC, 0x74, 0x15,
+    0xB7, 0x59, 0xC4, 0xA8, 0x9F, 0x0A, 0x72, 0x9E,
+    0x7E, 0x6E, 0x15, 0x47, 0x22, 0xDF, 0x12, 0x34,
+    0x58, 0x35, 0x07, 0x6A, 0x99, 0xCF, 0x34, 0xDC,
+    0x6E, 0x22, 0x50, 0xC9, 0xDE, 0xC0, 0x68, 0x9B,
+    0x65, 0x89, 0xBC, 0xD4, 0xDB, 0xED, 0xF8, 0xAB,
+    0xC8, 0x12, 0xA8, 0xA2, 0x2B, 0x0D, 0x40, 0x52,
+    0xDC, 0xBB, 0xFE, 0x02, 0x32, 0x2F, 0xA4, 0xA9,
+    0xCA, 0xD7, 0x10, 0x61, 0x21, 0x1E, 0xF0, 0xB4,
+    0xD3, 0x50, 0x5D, 0x04, 0x0F, 0xF6, 0x00, 0xC2,
+    0x6F, 0x16, 0x9D, 0x25, 0x36, 0x86, 0x42, 0x56,
+    0x4A, 0x55, 0x5E, 0x09, 0xC1, 0xBE, 0xE0, 0x91
+};
+
+/* Macro to perform one column of the RS matrix multiplication.  The
+ * parameters a, b, c, and d are the four bytes of output; i is the index
+ * of the key bytes, and w, x, y, and z, are the column of constants from
+ * the RS matrix, preprocessed through the poly_to_exp table. */
+
+#define CALC_S(a, b, c, d, i, w, x, y, z) \
+   if (key[i]) { \
+      tmp = poly_to_exp[key[i] - 1]; \
+      (a) ^= exp_to_poly[tmp + (w)]; \
+      (b) ^= exp_to_poly[tmp + (x)]; \
+      (c) ^= exp_to_poly[tmp + (y)]; \
+      (d) ^= exp_to_poly[tmp + (z)]; \
+   }
+
+/* Macros to calculate the key-dependent S-boxes for a 128-bit key using
+ * the S vector from CALC_S.  CALC_SB_2 computes a single entry in all
+ * four S-boxes, where i is the index of the entry to compute, and a and b
+ * are the index numbers preprocessed through the q0 and q1 tables
+ * respectively. */
+
+#define CALC_SB_2(i, a, b) \
+   ctx->s[0][i] = mds[0][q0[(a) ^ sa] ^ se]; \
+   ctx->s[1][i] = mds[1][q0[(b) ^ sb] ^ sf]; \
+   ctx->s[2][i] = mds[2][q1[(a) ^ sc] ^ sg]; \
+   ctx->s[3][i] = mds[3][q1[(b) ^ sd] ^ sh]
+
+/* Macro exactly like CALC_SB_2, but for 192-bit keys. */
+
+#define CALC_SB192_2(i, a, b) \
+   ctx->s[0][i] = mds[0][q0[q0[(b) ^ sa] ^ se] ^ si]; \
+   ctx->s[1][i] = mds[1][q0[q1[(b) ^ sb] ^ sf] ^ sj]; \
+   ctx->s[2][i] = mds[2][q1[q0[(a) ^ sc] ^ sg] ^ sk]; \
+   ctx->s[3][i] = mds[3][q1[q1[(a) ^ sd] ^ sh] ^ sl];
+
+/* Macro exactly like CALC_SB_2, but for 256-bit keys. */
+
+#define CALC_SB256_2(i, a, b) \
+   ctx->s[0][i] = mds[0][q0[q0[q1[(b) ^ sa] ^ se] ^ si] ^ sm]; \
+   ctx->s[1][i] = mds[1][q0[q1[q1[(a) ^ sb] ^ sf] ^ sj] ^ sn]; \
+   ctx->s[2][i] = mds[2][q1[q0[q0[(a) ^ sc] ^ sg] ^ sk] ^ so]; \
+   ctx->s[3][i] = mds[3][q1[q1[q0[(b) ^ sd] ^ sh] ^ sl] ^ sp];
+
+/* Macros to calculate the whitening and round subkeys.  CALC_K_2 computes the
+ * last two stages of the h() function for a given index (either 2i or 2i+1).
+ * a, b, c, and d are the four bytes going into the last two stages.  For
+ * 128-bit keys, this is the entire h() function and a and c are the index
+ * preprocessed through q0 and q1 respectively; for longer keys they are the
+ * output of previous stages.  j is the index of the first key byte to use.
+ * CALC_K computes a pair of subkeys for 128-bit Twofish, by calling CALC_K_2
+ * twice, doing the Psuedo-Hadamard Transform, and doing the necessary
+ * rotations.  Its parameters are: a, the array to write the results into,
+ * j, the index of the first output entry, k and l, the preprocessed indices
+ * for index 2i, and m and n, the preprocessed indices for index 2i+1.
+ * CALC_K192_2 expands CALC_K_2 to handle 192-bit keys, by doing an
+ * additional lookup-and-XOR stage.  The parameters a, b, c and d are the
+ * four bytes going into the last three stages.  For 192-bit keys, c = d
+ * are the index preprocessed through q0, and a = b are the index
+ * preprocessed through q1; j is the index of the first key byte to use.
+ * CALC_K192 is identical to CALC_K but for using the CALC_K192_2 macro
+ * instead of CALC_K_2.
+ * CALC_K256_2 expands CALC_K192_2 to handle 256-bit keys, by doing an
+ * additional lookup-and-XOR stage.  The parameters a and b are the index
+ * preprocessed through q0 and q1 respectively; j is the index of the first
+ * key byte to use.  CALC_K256 is identical to CALC_K but for using the
+ * CALC_K256_2 macro instead of CALC_K_2. */
+
+#define CALC_K_2(a, b, c, d, j) \
+     mds[0][q0[a ^ key[(j) + 8]] ^ key[j]] \
+   ^ mds[1][q0[b ^ key[(j) + 9]] ^ key[(j) + 1]] \
+   ^ mds[2][q1[c ^ key[(j) + 10]] ^ key[(j) + 2]] \
+   ^ mds[3][q1[d ^ key[(j) + 11]] ^ key[(j) + 3]]
+
+#define CALC_K(a, j, k, l, m, n) \
+   x = CALC_K_2 (k, l, k, l, 0); \
+   y = CALC_K_2 (m, n, m, n, 4); \
+   y = (y << 8) + (y >> 24); \
+   x += y; y += x; ctx->a[j] = x; \
+   ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+
+#define CALC_K192_2(a, b, c, d, j) \
+   CALC_K_2 (q0[a ^ key[(j) + 16]], \
+	     q1[b ^ key[(j) + 17]], \
+	     q0[c ^ key[(j) + 18]], \
+	     q1[d ^ key[(j) + 19]], j)
+
+#define CALC_K192(a, j, k, l, m, n) \
+   x = CALC_K192_2 (l, l, k, k, 0); \
+   y = CALC_K192_2 (n, n, m, m, 4); \
+   y = (y << 8) + (y >> 24); \
+   x += y; y += x; ctx->a[j] = x; \
+   ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+
+#define CALC_K256_2(a, b, j) \
+   CALC_K192_2 (q1[b ^ key[(j) + 24]], \
+	        q1[a ^ key[(j) + 25]], \
+	        q0[a ^ key[(j) + 26]], \
+	        q0[b ^ key[(j) + 27]], j)
+
+#define CALC_K256(a, j, k, l, m, n) \
+   x = CALC_K256_2 (k, l, 0); \
+   y = CALC_K256_2 (m, n, 4); \
+   y = (y << 8) + (y >> 24); \
+   x += y; y += x; ctx->a[j] = x; \
+   ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+
+
+/* Macros to compute the g() function in the encryption and decryption
+ * rounds.  G1 is the straight g() function; G2 includes the 8-bit
+ * rotation for the high 32-bit word. */
+
+#define G1(a) \
+     (ctx->s[0][(a) & 0xFF]) ^ (ctx->s[1][((a) >> 8) & 0xFF]) \
+   ^ (ctx->s[2][((a) >> 16) & 0xFF]) ^ (ctx->s[3][(a) >> 24])
+
+#define G2(b) \
+     (ctx->s[1][(b) & 0xFF]) ^ (ctx->s[2][((b) >> 8) & 0xFF]) \
+   ^ (ctx->s[3][((b) >> 16) & 0xFF]) ^ (ctx->s[0][(b) >> 24])
+
+/* Encryption and decryption Feistel rounds.  Each one calls the two g()
+ * macros, does the PHT, and performs the XOR and the appropriate bit
+ * rotations.  The parameters are the round number (used to select subkeys),
+ * and the four 32-bit chunks of the text. */
+
+#define ENCROUND(n, a, b, c, d) \
+   x = G1 (a); y = G2 (b); \
+   x += y; y += x + ctx->k[2 * (n) + 1]; \
+   (c) ^= x + ctx->k[2 * (n)]; \
+   (c) = ((c) >> 1) + ((c) << 31); \
+   (d) = (((d) << 1)+((d) >> 31)) ^ y
+
+#define DECROUND(n, a, b, c, d) \
+   x = G1 (a); y = G2 (b); \
+   x += y; y += x; \
+   (d) ^= y + ctx->k[2 * (n) + 1]; \
+   (d) = ((d) >> 1) + ((d) << 31); \
+   (c) = (((c) << 1)+((c) >> 31)); \
+   (c) ^= (x + ctx->k[2 * (n)])
+
+/* Encryption and decryption cycles; each one is simply two Feistel rounds
+ * with the 32-bit chunks re-ordered to simulate the "swap" */
+
+#define ENCCYCLE(n) \
+   ENCROUND (2 * (n), a, b, c, d); \
+   ENCROUND (2 * (n) + 1, c, d, a, b)
+
+#define DECCYCLE(n) \
+   DECROUND (2 * (n) + 1, c, d, a, b); \
+   DECROUND (2 * (n), a, b, c, d)
+
+/* Macros to convert the input and output bytes into 32-bit words,
+ * and simultaneously perform the whitening step.  INPACK packs word
+ * number n into the variable named by x, using whitening subkey number m.
+ * OUTUNPACK unpacks word number n from the variable named by x, using
+ * whitening subkey number m. */
+
+#define INPACK(n, x, m) \
+   x = in[4 * (n)] ^ (in[4 * (n) + 1] << 8) \
+     ^ (in[4 * (n) + 2] << 16) ^ (in[4 * (n) + 3] << 24) ^ ctx->w[m]
+
+#define OUTUNPACK(n, x, m) \
+   x ^= ctx->w[m]; \
+   out[4 * (n)] = x; out[4 * (n) + 1] = x >> 8; \
+   out[4 * (n) + 2] = x >> 16; out[4 * (n) + 3] = x >> 24
+
+#define TF_MIN_KEY_SIZE 16
+#define TF_MAX_KEY_SIZE 32
+#define TF_BLOCK_SIZE 16
+
+/* Structure for an expanded Twofish key.  s contains the key-dependent
+ * S-boxes composed with the MDS matrix; w contains the eight "whitening"
+ * subkeys, K[0] through K[7].	k holds the remaining, "round" subkeys.  Note
+ * that k[i] corresponds to what the Twofish paper calls K[i+8]. */
+struct twofish_ctx {
+   u32 s[4][256], w[8], k[32];
+};
+
+/* Perform the key setup. */
+static int twofish_setkey(void *cx, const u8 *key,
+                          unsigned int key_len, u32 *flags)
+{
+	
+	struct twofish_ctx *ctx = cx;
+
+	int i, j, k;
+
+	/* Temporaries for CALC_K. */
+	u32 x, y;
+
+	/* The S vector used to key the S-boxes, split up into individual bytes.
+	 * 128-bit keys use only sa through sh; 256-bit use all of them. */
+	u8 sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0, sg = 0, sh = 0;
+	u8 si = 0, sj = 0, sk = 0, sl = 0, sm = 0, sn = 0, so = 0, sp = 0;
+
+	/* Temporary for CALC_S. */
+	u8 tmp;
+
+	/* Check key length. */
+	if (key_len != 16 && key_len != 24 && key_len != 32)
+		return -EINVAL; /* unsupported key length */
+
+	/* Compute the first two words of the S vector.  The magic numbers are
+	 * the entries of the RS matrix, preprocessed through poly_to_exp. The
+	 * numbers in the comments are the original (polynomial form) matrix
+	 * entries. */
+	CALC_S (sa, sb, sc, sd, 0, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+	CALC_S (sa, sb, sc, sd, 1, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+	CALC_S (sa, sb, sc, sd, 2, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+	CALC_S (sa, sb, sc, sd, 3, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+	CALC_S (sa, sb, sc, sd, 4, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+	CALC_S (sa, sb, sc, sd, 5, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+	CALC_S (sa, sb, sc, sd, 6, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+	CALC_S (sa, sb, sc, sd, 7, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+	CALC_S (se, sf, sg, sh, 8, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+	CALC_S (se, sf, sg, sh, 9, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+	CALC_S (se, sf, sg, sh, 10, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+	CALC_S (se, sf, sg, sh, 11, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+	CALC_S (se, sf, sg, sh, 12, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+	CALC_S (se, sf, sg, sh, 13, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+	CALC_S (se, sf, sg, sh, 14, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+	CALC_S (se, sf, sg, sh, 15, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+
+	if (key_len == 24 || key_len == 32) { /* 192- or 256-bit key */
+		/* Calculate the third word of the S vector */
+		CALC_S (si, sj, sk, sl, 16, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+		CALC_S (si, sj, sk, sl, 17, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+		CALC_S (si, sj, sk, sl, 18, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+		CALC_S (si, sj, sk, sl, 19, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+		CALC_S (si, sj, sk, sl, 20, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+		CALC_S (si, sj, sk, sl, 21, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+		CALC_S (si, sj, sk, sl, 22, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+		CALC_S (si, sj, sk, sl, 23, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+	}
+
+	if (key_len == 32) { /* 256-bit key */
+		/* Calculate the fourth word of the S vector */
+		CALC_S (sm, sn, so, sp, 24, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+		CALC_S (sm, sn, so, sp, 25, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+		CALC_S (sm, sn, so, sp, 26, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+		CALC_S (sm, sn, so, sp, 27, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+		CALC_S (sm, sn, so, sp, 28, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+		CALC_S (sm, sn, so, sp, 29, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+		CALC_S (sm, sn, so, sp, 30, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+		CALC_S (sm, sn, so, sp, 31, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+
+		/* Compute the S-boxes. */
+		for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
+			CALC_SB256_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
+		}
+
+		/* Calculate whitening and round subkeys.  The constants are
+		 * indices of subkeys, preprocessed through q0 and q1. */
+		CALC_K256 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
+		CALC_K256 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+		CALC_K256 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+		CALC_K256 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+		CALC_K256 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+		CALC_K256 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
+		CALC_K256 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+		CALC_K256 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+		CALC_K256 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+		CALC_K256 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
+		CALC_K256 (k, 12, 0x18, 0x37, 0xF7, 0x71);
+		CALC_K256 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+		CALC_K256 (k, 16, 0x43, 0x30, 0x75, 0x0F);
+		CALC_K256 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
+		CALC_K256 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
+		CALC_K256 (k, 22, 0x94, 0x06, 0x48, 0x3F);
+		CALC_K256 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+		CALC_K256 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+		CALC_K256 (k, 28, 0x84, 0x8A, 0x54, 0x00);
+		CALC_K256 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+	} else if (key_len == 24) { /* 192-bit key */
+		/* Compute the S-boxes. */
+		for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
+		        CALC_SB192_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
+		}
+
+		/* Calculate whitening and round subkeys.  The constants are
+		 * indices of subkeys, preprocessed through q0 and q1. */
+		CALC_K192 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
+		CALC_K192 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+		CALC_K192 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+		CALC_K192 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+		CALC_K192 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+		CALC_K192 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
+		CALC_K192 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+		CALC_K192 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+		CALC_K192 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+		CALC_K192 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
+		CALC_K192 (k, 12, 0x18, 0x37, 0xF7, 0x71);
+		CALC_K192 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+		CALC_K192 (k, 16, 0x43, 0x30, 0x75, 0x0F);
+		CALC_K192 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
+		CALC_K192 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
+		CALC_K192 (k, 22, 0x94, 0x06, 0x48, 0x3F);
+		CALC_K192 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+		CALC_K192 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+		CALC_K192 (k, 28, 0x84, 0x8A, 0x54, 0x00);
+		CALC_K192 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+	} else { /* 128-bit key */
+		/* Compute the S-boxes. */
+		for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
+			CALC_SB_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
+		}
+
+		/* Calculate whitening and round subkeys.  The constants are
+		 * indices of subkeys, preprocessed through q0 and q1. */
+		CALC_K (w, 0, 0xA9, 0x75, 0x67, 0xF3);
+		CALC_K (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+		CALC_K (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+		CALC_K (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+		CALC_K (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+		CALC_K (k, 2, 0x80, 0xE6, 0x78, 0x6B);
+		CALC_K (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+		CALC_K (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+		CALC_K (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+		CALC_K (k, 10, 0x35, 0xD8, 0x98, 0xFD);
+		CALC_K (k, 12, 0x18, 0x37, 0xF7, 0x71);
+		CALC_K (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+		CALC_K (k, 16, 0x43, 0x30, 0x75, 0x0F);
+		CALC_K (k, 18, 0x37, 0xF8, 0x26, 0x1B);
+		CALC_K (k, 20, 0xFA, 0x87, 0x13, 0xFA);
+		CALC_K (k, 22, 0x94, 0x06, 0x48, 0x3F);
+		CALC_K (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+		CALC_K (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+		CALC_K (k, 28, 0x84, 0x8A, 0x54, 0x00);
+		CALC_K (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+	}
+
+	return 0;
+}
+
+/* Encrypt one block.  in and out may be the same. */
+static void twofish_encrypt(void *cx, u8 *out, const u8 *in)
+{
+	struct twofish_ctx *ctx = cx;
+
+	/* The four 32-bit chunks of the text. */
+	u32 a, b, c, d;
+	
+	/* Temporaries used by the round function. */
+	u32 x, y;
+
+	/* Input whitening and packing. */
+	INPACK (0, a, 0);
+	INPACK (1, b, 1);
+	INPACK (2, c, 2);
+	INPACK (3, d, 3);
+	
+	/* Encryption Feistel cycles. */
+	ENCCYCLE (0);
+	ENCCYCLE (1);
+	ENCCYCLE (2);
+	ENCCYCLE (3);
+	ENCCYCLE (4);
+	ENCCYCLE (5);
+	ENCCYCLE (6);
+	ENCCYCLE (7);
+	
+	/* Output whitening and unpacking. */
+	OUTUNPACK (0, c, 4);
+	OUTUNPACK (1, d, 5);
+	OUTUNPACK (2, a, 6);
+	OUTUNPACK (3, b, 7);
+	
+}
+
+/* Decrypt one block.  in and out may be the same. */
+static void twofish_decrypt(void *cx, u8 *out, const u8 *in)
+{
+	struct twofish_ctx *ctx = cx;
+  
+	/* The four 32-bit chunks of the text. */
+	u32 a, b, c, d;
+	
+	/* Temporaries used by the round function. */
+	u32 x, y;
+	
+	/* Input whitening and packing. */
+	INPACK (0, c, 4);
+	INPACK (1, d, 5);
+	INPACK (2, a, 6);
+	INPACK (3, b, 7);
+	
+	/* Encryption Feistel cycles. */
+	DECCYCLE (7);
+	DECCYCLE (6);
+	DECCYCLE (5);
+	DECCYCLE (4);
+	DECCYCLE (3);
+	DECCYCLE (2);
+	DECCYCLE (1);
+	DECCYCLE (0);
+
+	/* Output whitening and unpacking. */
+	OUTUNPACK (0, a, 0);
+	OUTUNPACK (1, b, 1);
+	OUTUNPACK (2, c, 2);
+	OUTUNPACK (3, d, 3);
+
+}
+
+static struct crypto_alg alg = {
+	.cra_name           =   "twofish",
+	.cra_flags          =   CRYPTO_ALG_TYPE_CIPHER,
+	.cra_blocksize      =   TF_BLOCK_SIZE,
+	.cra_ctxsize        =   sizeof(struct twofish_ctx),
+	.cra_module         =   THIS_MODULE,
+	.cra_list           =   LIST_HEAD_INIT(alg.cra_list),
+	.cra_u              =   { .cipher = {
+	.cia_min_keysize    =   TF_MIN_KEY_SIZE,
+	.cia_max_keysize    =   TF_MAX_KEY_SIZE,
+	.cia_ivsize         =   TF_BLOCK_SIZE,
+	.cia_setkey         =   twofish_setkey,
+	.cia_encrypt        =   twofish_encrypt,
+	.cia_decrypt        =   twofish_decrypt } }
+};
+
+static int __init init(void)
+{
+	return crypto_register_alg(&alg);
+}
+
+static void __exit fini(void)
+{
+	crypto_unregister_alg(&alg);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION ("Twofish Cipher Algorithm");
diff -Nru a/drivers/Makefile b/drivers/Makefile
--- a/drivers/Makefile	Mon Dec  9 18:46:50 2002
+++ b/drivers/Makefile	Mon Dec  9 18:46:50 2002
@@ -21,7 +21,7 @@
 obj-$(CONFIG_SCSI)		+= scsi/
 obj-$(CONFIG_FUSION)		+= message/
 obj-$(CONFIG_IEEE1394)		+= ieee1394/
-obj-y				+= cdrom/
+obj-y				+= cdrom/ video/
 obj-$(CONFIG_MTD)		+= mtd/
 obj-$(CONFIG_PCMCIA)		+= pcmcia/
 obj-$(CONFIG_DIO)		+= dio/
@@ -30,7 +30,6 @@
 obj-$(CONFIG_ALL_PPC)		+= macintosh/
 obj-$(CONFIG_MAC)		+= macintosh/
 obj-$(CONFIG_SGI)		+= sgi/
-obj-$(CONFIG_VT)		+= video/
 obj-$(CONFIG_PARIDE) 		+= block/paride/
 obj-$(CONFIG_TC)		+= tc/
 obj-$(CONFIG_USB)		+= usb/
@@ -44,5 +43,6 @@
 obj-$(CONFIG_BT)		+= bluetooth/
 obj-$(CONFIG_HOTPLUG_PCI)	+= hotplug/
 obj-$(CONFIG_ISDN_BOOL)		+= isdn/
+obj-$(CONFIG_MCA)		+= mca/
 
 include $(TOPDIR)/Rules.make
diff -Nru a/drivers/acorn/char/i2c.c b/drivers/acorn/char/i2c.c
--- a/drivers/acorn/char/i2c.c	Mon Dec  9 18:46:52 2002
+++ b/drivers/acorn/char/i2c.c	Mon Dec  9 18:46:52 2002
@@ -318,8 +318,11 @@
 
 	ret = i2c_bit_add_bus(&ioc_ops);
 
-	if (ret >= 0)
-		misc_register(&rtc_dev);
+	if (ret >= 0){
+		ret = misc_register(&rtc_dev);
+		if(ret < 0)
+			i2c_bit_del_bus(&ioc_ops);
+	}
 
 	return ret;
 }
diff -Nru a/drivers/acorn/scsi/acornscsi.c b/drivers/acorn/scsi/acornscsi.c
--- a/drivers/acorn/scsi/acornscsi.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/acorn/scsi/acornscsi.c	Mon Dec  9 18:46:38 2002
@@ -2935,9 +2935,9 @@
 	}
     }
 
-    p += sprintf(p, "\nAttached devices:%s\n", instance->host_queue ? "" : " none");
+    p += sprintf(p, "\nAttached devices:\n");
 
-    for (scd = instance->host_queue; scd; scd = scd->next) {
+    list_for_each_entry(scd, &instance->my_devices, siblings) {
 	int len;
 
 	proc_print_scsidevice(scd, p, &len, 0);
@@ -3051,7 +3051,7 @@
 
 	acornscsi_resetcard(ashost);
 
-	ret = scsi_add_host(host);
+	ret = scsi_add_host(host, &ec->dev);
 	if (ret == 0)
 		goto out;
 
diff -Nru a/drivers/acorn/scsi/arxescsi.c b/drivers/acorn/scsi/arxescsi.c
--- a/drivers/acorn/scsi/arxescsi.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/acorn/scsi/arxescsi.c	Mon Dec  9 18:46:38 2002
@@ -311,7 +311,7 @@
 
 	pos += sprintf (buffer+pos, "\nAttached devices:\n");
 
-	for (scd = host->host_queue; scd; scd = scd->next) {
+	list_for_each_entry(scd, &host->my_devices, siblings) {
 		pos += fas216_print_device(&info->info, scd, buffer + pos);
 
 		if (pos + begin < offset) {
@@ -398,7 +398,7 @@
 
 	fas216_init(host);
 
-	ret = scsi_add_host(host);
+	ret = scsi_add_host(host, &ec->dev);
 	if (ret == 0)
 		goto out;
 
diff -Nru a/drivers/acorn/scsi/cumana_1.c b/drivers/acorn/scsi/cumana_1.c
--- a/drivers/acorn/scsi/cumana_1.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/acorn/scsi/cumana_1.c	Mon Dec  9 18:46:34 2002
@@ -299,7 +299,7 @@
 	NCR5380_print_options(host);
 	printk("\n");
 
-	ret = scsi_add_host(host);
+	ret = scsi_add_host(host, &ec->dev);
 	if (ret == 0)
 		goto out;
 
diff -Nru a/drivers/acorn/scsi/cumana_2.c b/drivers/acorn/scsi/cumana_2.c
--- a/drivers/acorn/scsi/cumana_2.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/acorn/scsi/cumana_2.c	Mon Dec  9 18:46:50 2002
@@ -387,7 +387,7 @@
 
 	pos += sprintf(buffer+pos, "\nAttached devices:\n");
 
-	for (scd = host->host_queue; scd; scd = scd->next) {
+	list_for_each_entry(scd, &host->my_devices, siblings) {
 		int len;
 
 		proc_print_scsidevice(scd, buffer, &len, pos);
@@ -503,7 +503,7 @@
 
 	fas216_init(host);
 
-	ret = scsi_add_host(host);
+	ret = scsi_add_host(host, &ec->dev);
 	if (ret == 0)
 		goto out;
 
diff -Nru a/drivers/acorn/scsi/eesox.c b/drivers/acorn/scsi/eesox.c
--- a/drivers/acorn/scsi/eesox.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/acorn/scsi/eesox.c	Mon Dec  9 18:46:51 2002
@@ -390,7 +390,7 @@
 
 	pos += sprintf(buffer+pos, "\nAttached devices:\n");
 
-	for (scd = host->host_queue; scd; scd = scd->next) {
+	list_for_each_entry(scd, &host->my_devices, siblings) {
 		int len;
 
 		proc_print_scsidevice(scd, buffer, &len, pos);
@@ -502,7 +502,7 @@
 	}
 
 	fas216_init(host);
-	ret = scsi_add_host(host);
+	ret = scsi_add_host(host, &ec->dev);
 	if (ret == 0)
 		goto out;
 
diff -Nru a/drivers/acorn/scsi/fas216.c b/drivers/acorn/scsi/fas216.c
--- a/drivers/acorn/scsi/fas216.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/acorn/scsi/fas216.c	Mon Dec  9 18:46:36 2002
@@ -2631,7 +2631,7 @@
 	 * all command structures.  Leave the running
 	 * command in place.
 	 */
-	for (SDpnt = info->host->host_queue; SDpnt; SDpnt = SDpnt->next) {
+	list_for_each_entry(SDpnt, &info->host->my_devices, siblings) {
 		int i;
 
 		if (SDpnt->soft_reset)
diff -Nru a/drivers/acorn/scsi/oak.c b/drivers/acorn/scsi/oak.c
--- a/drivers/acorn/scsi/oak.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/acorn/scsi/oak.c	Mon Dec  9 18:46:34 2002
@@ -160,7 +160,7 @@
 	NCR5380_print_options(host);
 	printk("\n");
 
-	ret = scsi_add_host(host);
+	ret = scsi_add_host(host, &ec->dev);
 	if (ret == 0)
 		goto out;
 
diff -Nru a/drivers/acorn/scsi/powertec.c b/drivers/acorn/scsi/powertec.c
--- a/drivers/acorn/scsi/powertec.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/acorn/scsi/powertec.c	Mon Dec  9 18:46:50 2002
@@ -269,7 +269,7 @@
 
 	pos += sprintf(buffer+pos, "\nAttached devices:\n");
 
-	for (scd = host->host_queue; scd; scd = scd->next) {
+	list_for_each_entry(scd, &host->my_devices, siblings) {
 		pos += fas216_print_device(&info->info, scd, buffer + pos);
 
 		if (pos + begin < offset) {
@@ -376,7 +376,7 @@
 
 	fas216_init(host);
 
-	ret = scsi_add_host(host);
+	ret = scsi_add_host(host, &ec->dev);
 	if (ret == 0)
 		goto out;
 
diff -Nru a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
--- a/drivers/acpi/Kconfig	Mon Dec  9 18:46:52 2002
+++ b/drivers/acpi/Kconfig	Mon Dec  9 18:46:52 2002
@@ -58,8 +58,7 @@
 
 config ACPI_SLEEP
 	bool "Sleep States"
-	depends on X86 && ACPI && !ACPI_HT_ONLY
-	default SOFTWARE_SUSPEND
+	depends on X86 && ACPI && !ACPI_HT_ONLY && SOFTWARE_SUSPEND
 	---help---
 	  This option adds support for ACPI suspend states. 
 
diff -Nru a/drivers/acpi/acpi_drivers.h b/drivers/acpi/acpi_drivers.h
--- a/drivers/acpi/acpi_drivers.h	Mon Dec  9 18:46:50 2002
+++ b/drivers/acpi/acpi_drivers.h	Mon Dec  9 18:46:50 2002
@@ -142,7 +142,7 @@
 	switch (flag) {
 	case ACPI_DEBUG_LOW:
 		acpi_dbg_layer = ACPI_COMPONENT_DEFAULT | ACPI_ALL_DRIVERS;
-		acpi_dbg_level = DEBUG_DEFAULT;
+		acpi_dbg_level = ACPI_DEBUG_DEFAULT;
 		break;
 	case ACPI_DEBUG_MEDIUM:
 		acpi_dbg_layer = ACPI_COMPONENT_DEFAULT | ACPI_ALL_DRIVERS;
diff -Nru a/drivers/acpi/dispatcher/Makefile b/drivers/acpi/dispatcher/Makefile
--- a/drivers/acpi/dispatcher/Makefile	Mon Dec  9 18:46:35 2002
+++ b/drivers/acpi/dispatcher/Makefile	Mon Dec  9 18:46:35 2002
@@ -3,7 +3,8 @@
 #
 
 obj-y := dsfield.o   dsmthdat.o  dsopcode.o  dswexec.o  dswscope.o \
-	 dsmethod.o  dsobject.o  dsutils.o   dswload.o  dswstate.o
+	 dsmethod.o  dsobject.o  dsutils.o   dswload.o  dswstate.o \
+	 dsinit.o
 
 EXTRA_CFLAGS += $(ACPI_CFLAGS)
 
diff -Nru a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/acpi/dispatcher/dsinit.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,220 @@
+/******************************************************************************
+ *
+ * Module Name: dsinit - Object initialization namespace walk
+ *              $Revision: 2 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2002, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acparser.h"
+#include "amlcode.h"
+#include "acdispat.h"
+#include "acnamesp.h"
+#include "acinterp.h"
+
+#define _COMPONENT          ACPI_DISPATCHER
+	 ACPI_MODULE_NAME    ("dsinit")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ds_init_one_object
+ *
+ * PARAMETERS:  Obj_handle      - Node
+ *              Level           - Current nesting level
+ *              Context         - Points to a init info struct
+ *              Return_value    - Not used
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Callback from Acpi_walk_namespace. Invoked for every object
+ *              within the namespace.
+ *
+ *              Currently, the only objects that require initialization are:
+ *              1) Methods
+ *              2) Operation Regions
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_init_one_object (
+	acpi_handle             obj_handle,
+	u32                     level,
+	void                    *context,
+	void                    **return_value)
+{
+	acpi_object_type        type;
+	acpi_status             status;
+	acpi_init_walk_info     *info = (acpi_init_walk_info *) context;
+
+
+	ACPI_FUNCTION_NAME ("Ds_init_one_object");
+
+
+	/*
+	 * We are only interested in objects owned by the table that
+	 * was just loaded
+	 */
+	if (((acpi_namespace_node *) obj_handle)->owner_id !=
+			info->table_desc->table_id) {
+		return (AE_OK);
+	}
+
+	info->object_count++;
+
+	/* And even then, we are only interested in a few object types */
+
+	type = acpi_ns_get_type (obj_handle);
+
+	switch (type) {
+	case ACPI_TYPE_REGION:
+
+		status = acpi_ds_initialize_region (obj_handle);
+		if (ACPI_FAILURE (status)) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region %p [%4.4s] - Init failure, %s\n",
+				obj_handle, ((acpi_namespace_node *) obj_handle)->name.ascii,
+				acpi_format_exception (status)));
+		}
+
+		info->op_region_count++;
+		break;
+
+
+	case ACPI_TYPE_METHOD:
+
+		info->method_count++;
+
+		/* Print a dot for each method unless we are going to print the entire pathname */
+
+		if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
+			acpi_os_printf (".");
+		}
+
+		/*
+		 * Set the execution data width (32 or 64) based upon the
+		 * revision number of the parent ACPI table.
+		 * TBD: This is really for possible future support of integer width
+		 * on a per-table basis. Currently, we just use a global for the width.
+		 */
+		if (info->table_desc->pointer->revision == 1) {
+			((acpi_namespace_node *) obj_handle)->flags |= ANOBJ_DATA_WIDTH_32;
+		}
+
+		/*
+		 * Always parse methods to detect errors, we may delete
+		 * the parse tree below
+		 */
+		status = acpi_ds_parse_method (obj_handle);
+		if (ACPI_FAILURE (status)) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Method %p [%4.4s] - parse failure, %s\n",
+				obj_handle, ((acpi_namespace_node *) obj_handle)->name.ascii,
+				acpi_format_exception (status)));
+
+			/* This parse failed, but we will continue parsing more methods */
+
+			break;
+		}
+
+		/*
+		 * Delete the parse tree.  We simple re-parse the method
+		 * for every execution since there isn't much overhead
+		 */
+		acpi_ns_delete_namespace_subtree (obj_handle);
+		acpi_ns_delete_namespace_by_owner (((acpi_namespace_node *) obj_handle)->object->method.owning_id);
+		break;
+
+
+	case ACPI_TYPE_DEVICE:
+
+		info->device_count++;
+		break;
+
+
+	default:
+		break;
+	}
+
+	/*
+	 * We ignore errors from above, and always return OK, since
+	 * we don't want to abort the walk on a single error.
+	 */
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ds_initialize_objects
+ *
+ * PARAMETERS:  Table_desc      - Descriptor for parent ACPI table
+ *              Start_node      - Root of subtree to be initialized.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Walk the namespace starting at "Start_node" and perform any
+ *              necessary initialization on the objects found therein
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_initialize_objects (
+	acpi_table_desc         *table_desc,
+	acpi_namespace_node     *start_node)
+{
+	acpi_status             status;
+	acpi_init_walk_info     info;
+
+
+	ACPI_FUNCTION_TRACE ("Ds_initialize_objects");
+
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+		"**** Starting initialization of namespace objects ****\n"));
+	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "Parsing all Control Methods:"));
+
+	info.method_count   = 0;
+	info.op_region_count = 0;
+	info.object_count   = 0;
+	info.device_count   = 0;
+	info.table_desc     = table_desc;
+
+	/* Walk entire namespace from the supplied root */
+
+	status = acpi_walk_namespace (ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
+			  acpi_ds_init_one_object, &info, NULL);
+	if (ACPI_FAILURE (status)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Walk_namespace failed, %s\n",
+			acpi_format_exception (status)));
+	}
+
+	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
+		"\nTable [%4.4s] - %hd Objects with %hd Devices %hd Methods %hd Regions\n",
+		table_desc->pointer->signature, info.object_count,
+		info.device_count, info.method_count, info.op_region_count));
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+		"%hd Methods, %hd Regions\n", info.method_count, info.op_region_count));
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
diff -Nru a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c
--- a/drivers/acpi/dispatcher/dsmthdat.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/acpi/dispatcher/dsmthdat.c	Mon Dec  9 18:46:36 2002
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: dsmthdat - control method arguments and local variables
- *              $Revision: 66 $
+ *              $Revision: 67 $
  *
  ******************************************************************************/
 
@@ -68,7 +68,7 @@
 
 	/* Init the method arguments */
 
-	for (i = 0; i < MTH_NUM_ARGS; i++) {
+	for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) {
 		ACPI_MOVE_UNALIGNED32_TO_32 (&walk_state->arguments[i].name,
 				 NAMEOF_ARG_NTE);
 		walk_state->arguments[i].name.integer |= (i << 24);
@@ -79,7 +79,7 @@
 
 	/* Init the method locals */
 
-	for (i = 0; i < MTH_NUM_LOCALS; i++) {
+	for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) {
 		ACPI_MOVE_UNALIGNED32_TO_32 (&walk_state->local_variables[i].name,
 				 NAMEOF_LOCAL_NTE);
 
@@ -118,7 +118,7 @@
 
 	/* Detach the locals */
 
-	for (index = 0; index < MTH_NUM_LOCALS; index++) {
+	for (index = 0; index < ACPI_METHOD_NUM_LOCALS; index++) {
 		if (walk_state->local_variables[index].object) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%d=%p\n",
 					index, walk_state->local_variables[index].object));
@@ -131,7 +131,7 @@
 
 	/* Detach the arguments */
 
-	for (index = 0; index < MTH_NUM_ARGS; index++) {
+	for (index = 0; index < ACPI_METHOD_NUM_ARGS; index++) {
 		if (walk_state->arguments[index].object) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%d=%p\n",
 					index, walk_state->arguments[index].object));
@@ -182,7 +182,7 @@
 
 	/* Copy passed parameters into the new method stack frame  */
 
-	while ((index < MTH_NUM_ARGS) && (index < max_param_count) && params[index]) {
+	while ((index < ACPI_METHOD_NUM_ARGS) && (index < max_param_count) && params[index]) {
 		/*
 		 * A valid parameter.
 		 * Store the argument in the method/walk descriptor
@@ -230,9 +230,9 @@
 	switch (opcode) {
 	case AML_LOCAL_OP:
 
-		if (index > MTH_MAX_LOCAL) {
+		if (index > ACPI_METHOD_MAX_LOCAL) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Local index %d is invalid (max %d)\n",
-				index, MTH_MAX_LOCAL));
+				index, ACPI_METHOD_MAX_LOCAL));
 			return_ACPI_STATUS (AE_AML_INVALID_INDEX);
 		}
 
@@ -243,9 +243,9 @@
 
 	case AML_ARG_OP:
 
-		if (index > MTH_MAX_ARG) {
+		if (index > ACPI_METHOD_MAX_ARG) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Arg index %d is invalid (max %d)\n",
-				index, MTH_MAX_ARG));
+				index, ACPI_METHOD_MAX_ARG));
 			return_ACPI_STATUS (AE_AML_INVALID_INDEX);
 		}
 
diff -Nru a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c
--- a/drivers/acpi/dispatcher/dsobject.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/acpi/dispatcher/dsobject.c	Mon Dec  9 18:46:34 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: dsobject - Dispatcher object management routines
- *              $Revision: 110 $
+ *              $Revision: 111 $
  *
  *****************************************************************************/
 
@@ -36,187 +36,6 @@
 
 
 #ifndef ACPI_NO_METHOD_EXECUTION
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_ds_init_one_object
- *
- * PARAMETERS:  Obj_handle      - Node
- *              Level           - Current nesting level
- *              Context         - Points to a init info struct
- *              Return_value    - Not used
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Callback from Acpi_walk_namespace. Invoked for every object
- *              within the namespace.
- *
- *              Currently, the only objects that require initialization are:
- *              1) Methods
- *              2) Operation Regions
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ds_init_one_object (
-	acpi_handle             obj_handle,
-	u32                     level,
-	void                    *context,
-	void                    **return_value)
-{
-	acpi_object_type        type;
-	acpi_status             status;
-	acpi_init_walk_info     *info = (acpi_init_walk_info *) context;
-
-
-	ACPI_FUNCTION_NAME ("Ds_init_one_object");
-
-
-	/*
-	 * We are only interested in objects owned by the table that
-	 * was just loaded
-	 */
-	if (((acpi_namespace_node *) obj_handle)->owner_id !=
-			info->table_desc->table_id) {
-		return (AE_OK);
-	}
-
-	info->object_count++;
-
-	/* And even then, we are only interested in a few object types */
-
-	type = acpi_ns_get_type (obj_handle);
-
-	switch (type) {
-	case ACPI_TYPE_REGION:
-
-		status = acpi_ds_initialize_region (obj_handle);
-		if (ACPI_FAILURE (status)) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region %p [%4.4s] - Init failure, %s\n",
-				obj_handle, ((acpi_namespace_node *) obj_handle)->name.ascii,
-				acpi_format_exception (status)));
-		}
-
-		info->op_region_count++;
-		break;
-
-
-	case ACPI_TYPE_METHOD:
-
-		info->method_count++;
-
-		if (!(acpi_dbg_level & ACPI_LV_INIT)) {
-			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, "."));
-		}
-
-		/*
-		 * Set the execution data width (32 or 64) based upon the
-		 * revision number of the parent ACPI table.
-		 * TBD: This is really for possible future support of integer width
-		 * on a per-table basis. Currently, we just use a global for the width.
-		 */
-		if (info->table_desc->pointer->revision == 1) {
-			((acpi_namespace_node *) obj_handle)->flags |= ANOBJ_DATA_WIDTH_32;
-		}
-
-		/*
-		 * Always parse methods to detect errors, we may delete
-		 * the parse tree below
-		 */
-		status = acpi_ds_parse_method (obj_handle);
-		if (ACPI_FAILURE (status)) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Method %p [%4.4s] - parse failure, %s\n",
-				obj_handle, ((acpi_namespace_node *) obj_handle)->name.ascii,
-				acpi_format_exception (status)));
-
-			/* This parse failed, but we will continue parsing more methods */
-
-			break;
-		}
-
-		/*
-		 * Delete the parse tree.  We simple re-parse the method
-		 * for every execution since there isn't much overhead
-		 */
-		acpi_ns_delete_namespace_subtree (obj_handle);
-		acpi_ns_delete_namespace_by_owner (((acpi_namespace_node *) obj_handle)->object->method.owning_id);
-		break;
-
-
-	case ACPI_TYPE_DEVICE:
-
-		info->device_count++;
-		break;
-
-
-	default:
-		break;
-	}
-
-	/*
-	 * We ignore errors from above, and always return OK, since
-	 * we don't want to abort the walk on a single error.
-	 */
-	return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_ds_initialize_objects
- *
- * PARAMETERS:  Table_desc      - Descriptor for parent ACPI table
- *              Start_node      - Root of subtree to be initialized.
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Walk the namespace starting at "Start_node" and perform any
- *              necessary initialization on the objects found therein
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ds_initialize_objects (
-	acpi_table_desc         *table_desc,
-	acpi_namespace_node     *start_node)
-{
-	acpi_status             status;
-	acpi_init_walk_info     info;
-
-
-	ACPI_FUNCTION_TRACE ("Ds_initialize_objects");
-
-
-	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
-		"**** Starting initialization of namespace objects ****\n"));
-	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, "Parsing Methods:"));
-
-	info.method_count   = 0;
-	info.op_region_count = 0;
-	info.object_count   = 0;
-	info.device_count   = 0;
-	info.table_desc     = table_desc;
-
-	/* Walk entire namespace from the supplied root */
-
-	status = acpi_walk_namespace (ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
-			  acpi_ds_init_one_object, &info, NULL);
-	if (ACPI_FAILURE (status)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Walk_namespace failed, %s\n",
-			acpi_format_exception (status)));
-	}
-
-	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK,
-		"\nTable [%4.4s] - %hd Objects with %hd Devices %hd Methods %hd Regions\n",
-		table_desc->pointer->signature, info.object_count,
-		info.device_count, info.method_count, info.op_region_count));
-
-	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
-		"%hd Methods, %hd Regions\n", info.method_count, info.op_region_count));
-
-	return_ACPI_STATUS (AE_OK);
-}
-
-
 /*****************************************************************************
  *
  * FUNCTION:    Acpi_ds_build_internal_object
diff -Nru a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
--- a/drivers/acpi/dispatcher/dsopcode.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/acpi/dispatcher/dsopcode.c	Mon Dec  9 18:46:50 2002
@@ -2,7 +2,7 @@
  *
  * Module Name: dsopcode - Dispatcher Op Region support and handling of
  *                         "control" opcodes
- *              $Revision: 83 $
+ *              $Revision: 84 $
  *
  *****************************************************************************/
 
@@ -173,7 +173,7 @@
 	extra_desc = acpi_ns_get_secondary_object (obj_desc);
 	node = obj_desc->buffer_field.node;
 
-	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (node, " [Field]"));
+	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_BUFFER_FIELD, node, NULL));
 	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] Buffer_field JIT Init\n",
 		node->name.ascii));
 
@@ -317,7 +317,7 @@
 
 	node = obj_desc->region.node;
 
-	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (node, " [Operation Region]"));
+	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_REGION, node, NULL));
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] Op_region Init at AML %p\n",
 		node->name.ascii, extra_desc->extra.aml_start));
diff -Nru a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c
--- a/drivers/acpi/dispatcher/dswload.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/acpi/dispatcher/dswload.c	Mon Dec  9 18:46:34 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: dswload - Dispatcher namespace load callbacks
- *              $Revision: 78 $
+ *              $Revision: 80 $
  *
  *****************************************************************************/
 
@@ -356,6 +356,37 @@
 		}
 	}
 
+	if (op->common.aml_opcode == AML_METHOD_OP) {
+		/*
+		 * Method_op Pkg_length Name_string Method_flags Term_list
+		 *
+		 * Note: We must create the method node/object pair as soon as we
+		 * see the method declaration.  This allows later pass1 parsing
+		 * of invocations of the method (need to know the number of
+		 * arguments.)
+		 */
+		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+			"LOADING-Method: State=%p Op=%p Named_obj=%p\n",
+			walk_state, op, op->named.node));
+
+		if (!acpi_ns_get_attached_object (op->named.node)) {
+			walk_state->operands[0] = (void *) op->named.node;
+			walk_state->num_operands = 1;
+
+			status = acpi_ds_create_operands (walk_state, op->common.value.arg);
+			if (ACPI_SUCCESS (status)) {
+				status = acpi_ex_create_method (op->named.data,
+						   op->named.length, walk_state);
+			}
+			walk_state->operands[0] = NULL;
+			walk_state->num_operands = 0;
+
+			if (ACPI_FAILURE (status)) {
+				return (status);
+			}
+		}
+	}
+
 	/* Pop the scope stack */
 
 	if (acpi_ns_opens_scope (object_type)) {
@@ -651,11 +682,10 @@
 
 		status = acpi_ds_scope_stack_pop (walk_state);
 		if (ACPI_FAILURE (status)) {
-			return_ACPI_STATUS (status);
+			goto cleanup;
 		}
 	}
 
-
 	/*
 	 * Named operations are as follows:
 	 *
@@ -789,26 +819,6 @@
 	case AML_TYPE_NAMED_COMPLEX:
 
 		switch (op->common.aml_opcode) {
-		case AML_METHOD_OP:
-			/*
-			 * Method_op Pkg_length Name_string Method_flags Term_list
-			 */
-			ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
-				"LOADING-Method: State=%p Op=%p Named_obj=%p\n",
-				walk_state, op, node));
-
-			if (!acpi_ns_get_attached_object (node)) {
-				status = acpi_ds_create_operands (walk_state, arg);
-				if (ACPI_FAILURE (status)) {
-					goto cleanup;
-				}
-
-				status = acpi_ex_create_method (op->named.data,
-						   op->named.length, walk_state);
-			}
-			break;
-
-
 #ifndef ACPI_NO_METHOD_EXECUTION
 		case AML_REGION_OP:
 			/*
@@ -842,6 +852,7 @@
 
 		default:
 			/* All NAMED_COMPLEX opcodes must be handled above */
+			/* Note: Method objects were already created in Pass 1 */
 			break;
 		}
 		break;
@@ -890,7 +901,6 @@
 	default:
 		break;
 	}
-
 
 cleanup:
 
diff -Nru a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c
--- a/drivers/acpi/dispatcher/dswstate.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/acpi/dispatcher/dswstate.c	Mon Dec  9 18:46:51 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: dswstate - Dispatcher parse tree walk management routines
- *              $Revision: 70 $
+ *              $Revision: 71 $
  *
  *****************************************************************************/
 
@@ -65,7 +65,7 @@
 		return (AE_NOT_EXIST);
 	}
 
-	if (index >= OBJ_NUM_OPERANDS) {
+	if (index >= ACPI_OBJ_NUM_OPERANDS) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 			"Index out of range: %X Obj=%p State=%p Num=%X\n",
 			index, object, walk_state, state->results.num_results));
@@ -124,7 +124,7 @@
 		return (AE_NOT_EXIST);
 	}
 
-	if (index >= OBJ_MAX_OPERAND) {
+	if (index >= ACPI_OBJ_MAX_OPERAND) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 			"Index out of range: %X State=%p Num=%X\n",
 			index, walk_state, state->results.num_results));
@@ -196,7 +196,7 @@
 
 	state->results.num_results--;
 
-	for (index = OBJ_NUM_OPERANDS; index; index--) {
+	for (index = ACPI_OBJ_NUM_OPERANDS; index; index--) {
 		/* Check for a valid result object */
 
 		if (state->results.obj_desc [index -1]) {
@@ -312,7 +312,7 @@
 		return (AE_AML_INTERNAL);
 	}
 
-	if (state->results.num_results == OBJ_NUM_OPERANDS) {
+	if (state->results.num_results == ACPI_OBJ_NUM_OPERANDS) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 			"Result stack overflow: Obj=%p State=%p Num=%X\n",
 			object, walk_state, state->results.num_results));
@@ -440,7 +440,7 @@
 
 	/* The stack size is configurable, but fixed */
 
-	for (i = 0; i < OBJ_NUM_OPERANDS; i++) {
+	for (i = 0; i < ACPI_OBJ_NUM_OPERANDS; i++) {
 		if (walk_state->operands[i]) {
 			acpi_ut_remove_reference (walk_state->operands[i]);
 			walk_state->operands[i] = NULL;
@@ -474,7 +474,7 @@
 
 	/* Check for stack overflow */
 
-	if (walk_state->num_operands >= OBJ_NUM_OPERANDS) {
+	if (walk_state->num_operands >= ACPI_OBJ_NUM_OPERANDS) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 			"overflow! Obj=%p State=%p #Ops=%X\n",
 			object, walk_state, walk_state->num_operands));
@@ -922,7 +922,7 @@
 
 		/* Init the method arguments */
 
-		status = acpi_ds_method_data_init_args (params, MTH_NUM_ARGS, walk_state);
+		status = acpi_ds_method_data_init_args (params, ACPI_METHOD_NUM_ARGS, walk_state);
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
 		}
diff -Nru a/drivers/acpi/events/Makefile b/drivers/acpi/events/Makefile
--- a/drivers/acpi/events/Makefile	Mon Dec  9 18:46:34 2002
+++ b/drivers/acpi/events/Makefile	Mon Dec  9 18:46:34 2002
@@ -3,7 +3,8 @@
 #
 
 obj-y := evevent.o  evregion.o  evsci.o    evxfevnt.o \
-	 evmisc.o   evrgnini.o  evxface.o  evxfregn.o
+	 evmisc.o   evrgnini.o  evxface.o  evxfregn.o \
+	 evgpe.o
 
 EXTRA_CFLAGS += $(ACPI_CFLAGS)
 
diff -Nru a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c
--- a/drivers/acpi/events/evevent.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/acpi/events/evevent.c	Mon Dec  9 18:46:50 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
- * Module Name: evevent - Fixed and General Purpose Even handling and dispatch
- *              $Revision: 99 $
+ * Module Name: evevent - Fixed Event handling and dispatch
+ *              $Revision: 104 $
  *
  *****************************************************************************/
 
@@ -67,7 +67,7 @@
 	 */
 	status = acpi_ev_fixed_event_initialize ();
 	if (ACPI_FAILURE (status)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_FATAL,
+		ACPI_REPORT_ERROR ((
 				"Unable to initialize fixed events, %s\n",
 				acpi_format_exception (status)));
 		return_ACPI_STATUS (status);
@@ -75,7 +75,7 @@
 
 	status = acpi_ev_gpe_initialize ();
 	if (ACPI_FAILURE (status)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_FATAL,
+		ACPI_REPORT_ERROR ((
 				"Unable to initialize general purpose events, %s\n",
 				acpi_format_exception (status)));
 		return_ACPI_STATUS (status);
@@ -111,7 +111,7 @@
 
 	status = acpi_ev_install_sci_handler ();
 	if (ACPI_FAILURE (status)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_FATAL,
+		ACPI_REPORT_ERROR ((
 				"Unable to install System Control Interrupt Handler, %s\n",
 				acpi_format_exception (status)));
 		return_ACPI_STATUS (status);
@@ -121,7 +121,7 @@
 
 	status = acpi_ev_init_gpe_control_methods ();
 	if (ACPI_FAILURE (status)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_FATAL,
+		ACPI_REPORT_ERROR ((
 				"Unable to initialize GPE control methods, %s\n",
 				acpi_format_exception (status)));
 		return_ACPI_STATUS (status);
@@ -131,7 +131,7 @@
 
 	status = acpi_ev_init_global_lock_handler ();
 	if (ACPI_FAILURE (status)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_FATAL,
+		ACPI_REPORT_ERROR ((
 				"Unable to initialize Global Lock handler, %s\n",
 				acpi_format_exception (status)));
 		return_ACPI_STATUS (status);
@@ -288,666 +288,3 @@
 }
 
 
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_ev_gpe_initialize
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Initialize the GPE data structures
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ev_gpe_initialize (void)
-{
-	NATIVE_UINT_MAX32       i;
-	NATIVE_UINT_MAX32       j;
-	u32                     gpe_block;
-	u32                     gpe_register;
-	u32                     gpe_number_index;
-	u32                     gpe_number;
-	ACPI_GPE_REGISTER_INFO  *gpe_register_info;
-	acpi_status             status;
-
-
-	ACPI_FUNCTION_TRACE ("Ev_gpe_initialize");
-
-
-	/*
-	 * Initialize the GPE Block globals
-	 *
-	 * Why the GPE register block lengths divided by 2:  From the ACPI Spec,
-	 * section "General-Purpose Event Registers", we have:
-	 *
-	 * "Each register block contains two registers of equal length
-	 *  GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
-	 *  GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN
-	 *  The length of the GPE1_STS and GPE1_EN registers is equal to
-	 *  half the GPE1_LEN. If a generic register block is not supported
-	 *  then its respective block pointer and block length values in the
-	 *  FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need
-	 *  to be the same size."
-	 */
-	acpi_gbl_gpe_block_info[0].register_count = 0;
-	acpi_gbl_gpe_block_info[1].register_count = 0;
-
-	acpi_gbl_gpe_block_info[0].block_address = &acpi_gbl_FADT->Xgpe0_blk;
-	acpi_gbl_gpe_block_info[1].block_address = &acpi_gbl_FADT->Xgpe1_blk;
-
-	acpi_gbl_gpe_block_info[0].block_base_number = 0;
-	acpi_gbl_gpe_block_info[1].block_base_number = acpi_gbl_FADT->gpe1_base;
-
-
-	/*
-	 * Determine the maximum GPE number for this machine.
-	 * Note: both GPE0 and GPE1 are optional, and either can exist without
-	 * the other.
-	 * If EITHER the register length OR the block address are zero, then that
-	 * particular block is not supported.
-	 */
-	if (acpi_gbl_FADT->Xgpe0_blk.register_bit_width && ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe0_blk.address)) {
-		/* GPE block 0 exists (has length and address > 0) */
-
-		acpi_gbl_gpe_block_info[0].register_count = (u16) ACPI_DIV_16 (acpi_gbl_FADT->Xgpe0_blk.register_bit_width);
-		acpi_gbl_gpe_number_max                 = ACPI_MUL_8 (acpi_gbl_gpe_block_info[0].register_count) - 1;
-	}
-
-	if (acpi_gbl_FADT->Xgpe1_blk.register_bit_width && ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address)) {
-		/* GPE block 1 exists (has length and address > 0) */
-
-		acpi_gbl_gpe_block_info[1].register_count = (u16) ACPI_DIV_16 (acpi_gbl_FADT->Xgpe1_blk.register_bit_width);
-
-		/* Check for GPE0/GPE1 overlap (if both banks exist) */
-
-		if ((acpi_gbl_gpe_block_info[0].register_count) &&
-			(acpi_gbl_gpe_number_max >= acpi_gbl_FADT->gpe1_base)) {
-			ACPI_REPORT_ERROR ((
-				"GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d)\n",
-				acpi_gbl_gpe_number_max, acpi_gbl_FADT->gpe1_base,
-				acpi_gbl_FADT->gpe1_base + (ACPI_MUL_8 (acpi_gbl_gpe_block_info[1].register_count) - 1)));
-			return_ACPI_STATUS (AE_BAD_VALUE);
-		}
-
-		/*
-		 * GPE0 and GPE1 do not have to be contiguous in the GPE number space,
-		 * But, GPE0 always starts at zero.
-		 */
-		acpi_gbl_gpe_number_max = acpi_gbl_FADT->gpe1_base +
-				 (ACPI_MUL_8 (acpi_gbl_gpe_block_info[1].register_count) - 1);
-	}
-
-	/* Warn and exit if there are no GPE registers */
-
-	acpi_gbl_gpe_register_count = acpi_gbl_gpe_block_info[0].register_count +
-			 acpi_gbl_gpe_block_info[1].register_count;
-	if (!acpi_gbl_gpe_register_count) {
-		ACPI_REPORT_WARNING (("There are no GPE blocks defined in the FADT\n"));
-		return_ACPI_STATUS (AE_OK);
-	}
-
-	/* Check for Max GPE number out-of-range */
-
-	if (acpi_gbl_gpe_number_max > ACPI_GPE_MAX) {
-		ACPI_REPORT_ERROR (("Maximum GPE number from FADT is too large: 0x%X\n",
-			acpi_gbl_gpe_number_max));
-		return_ACPI_STATUS (AE_BAD_VALUE);
-	}
-
-	/* Allocate the GPE number-to-index translation table */
-
-	acpi_gbl_gpe_number_to_index = ACPI_MEM_CALLOCATE (
-			   sizeof (ACPI_GPE_INDEX_INFO) *
-			   ((ACPI_SIZE) acpi_gbl_gpe_number_max + 1));
-	if (!acpi_gbl_gpe_number_to_index) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Could not allocate the Gpe_number_to_index table\n"));
-		return_ACPI_STATUS (AE_NO_MEMORY);
-	}
-
-	/* Set the Gpe index table to GPE_INVALID */
-
-	ACPI_MEMSET (acpi_gbl_gpe_number_to_index, (int) ACPI_GPE_INVALID,
-			sizeof (ACPI_GPE_INDEX_INFO) * ((ACPI_SIZE) acpi_gbl_gpe_number_max + 1));
-
-	/* Allocate the GPE register information block */
-
-	acpi_gbl_gpe_register_info = ACPI_MEM_CALLOCATE (
-			  (ACPI_SIZE) acpi_gbl_gpe_register_count *
-			  sizeof (ACPI_GPE_REGISTER_INFO));
-	if (!acpi_gbl_gpe_register_info) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Could not allocate the Gpe_register_info table\n"));
-		goto error_exit1;
-	}
-
-	/*
-	 * Allocate the GPE dispatch handler block.  There are eight distinct GPEs
-	 * per register.  Initialization to zeros is sufficient.
-	 */
-	acpi_gbl_gpe_number_info = ACPI_MEM_CALLOCATE (
-			  (ACPI_SIZE) ACPI_MUL_8 (acpi_gbl_gpe_register_count) *
-			  sizeof (ACPI_GPE_NUMBER_INFO));
-	if (!acpi_gbl_gpe_number_info) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not allocate the Gpe_number_info table\n"));
-		goto error_exit2;
-	}
-
-	/*
-	 * Initialize the GPE information and validation tables.  A goal of these
-	 * tables is to hide the fact that there are two separate GPE register sets
-	 * in a given gpe hardware block, the status registers occupy the first half,
-	 * and the enable registers occupy the second half.  Another goal is to hide
-	 * the fact that there may be multiple GPE hardware blocks.
-	 */
-	gpe_register = 0;
-	gpe_number_index = 0;
-
-	for (gpe_block = 0; gpe_block < ACPI_MAX_GPE_BLOCKS; gpe_block++) {
-		for (i = 0; i < acpi_gbl_gpe_block_info[gpe_block].register_count; i++) {
-			gpe_register_info = &acpi_gbl_gpe_register_info[gpe_register];
-
-			/* Init the Register info for this entire GPE register (8 GPEs) */
-
-			gpe_register_info->base_gpe_number = (u8) (acpi_gbl_gpe_block_info[gpe_block].block_base_number
-					   + (ACPI_MUL_8 (i)));
-
-			ACPI_STORE_ADDRESS (gpe_register_info->status_address.address,
-					   (ACPI_GET_ADDRESS (acpi_gbl_gpe_block_info[gpe_block].block_address->address)
-							  + i));
-
-			ACPI_STORE_ADDRESS (gpe_register_info->enable_address.address,
-					   (ACPI_GET_ADDRESS (acpi_gbl_gpe_block_info[gpe_block].block_address->address)
-							  + i
-							  + acpi_gbl_gpe_block_info[gpe_block].register_count));
-
-			gpe_register_info->status_address.address_space_id = acpi_gbl_gpe_block_info[gpe_block].block_address->address_space_id;
-			gpe_register_info->enable_address.address_space_id = acpi_gbl_gpe_block_info[gpe_block].block_address->address_space_id;
-			gpe_register_info->status_address.register_bit_width = 8;
-			gpe_register_info->enable_address.register_bit_width = 8;
-			gpe_register_info->status_address.register_bit_offset = 8;
-			gpe_register_info->enable_address.register_bit_offset = 8;
-
-			/* Init the Index mapping info for each GPE number within this register */
-
-			for (j = 0; j < 8; j++) {
-				gpe_number = gpe_register_info->base_gpe_number + j;
-				acpi_gbl_gpe_number_to_index[gpe_number].number_index = (u8) gpe_number_index;
-
-				acpi_gbl_gpe_number_info[gpe_number_index].bit_mask = acpi_gbl_decode_to8bit[j];
-				gpe_number_index++;
-			}
-
-			/*
-			 * Clear the status/enable registers.  Note that status registers
-			 * are cleared by writing a '1', while enable registers are cleared
-			 * by writing a '0'.
-			 */
-			status = acpi_hw_low_level_write (8, 0x00, &gpe_register_info->enable_address, 0);
-			if (ACPI_FAILURE (status)) {
-				return_ACPI_STATUS (status);
-			}
-
-			status = acpi_hw_low_level_write (8, 0xFF, &gpe_register_info->status_address, 0);
-			if (ACPI_FAILURE (status)) {
-				return_ACPI_STATUS (status);
-			}
-
-			gpe_register++;
-		}
-
-		if (i) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "GPE Block%d: %X registers at %8.8X%8.8X\n",
-				(s32) gpe_block, acpi_gbl_gpe_block_info[0].register_count,
-				ACPI_HIDWORD (ACPI_GET_ADDRESS (acpi_gbl_gpe_block_info[gpe_block].block_address->address)),
-				ACPI_LODWORD (ACPI_GET_ADDRESS (acpi_gbl_gpe_block_info[gpe_block].block_address->address))));
-
-			ACPI_REPORT_INFO (("GPE Block%d defined as GPE%d to GPE%d\n",
-				(s32) gpe_block,
-				(u32) acpi_gbl_gpe_block_info[gpe_block].block_base_number,
-				(u32) (acpi_gbl_gpe_block_info[gpe_block].block_base_number +
-					((acpi_gbl_gpe_block_info[gpe_block].register_count * 8) -1))));
-		}
-	}
-
-	return_ACPI_STATUS (AE_OK);
-
-
-	/* Error cleanup */
-
-error_exit2:
-	ACPI_MEM_FREE (acpi_gbl_gpe_register_info);
-
-error_exit1:
-	ACPI_MEM_FREE (acpi_gbl_gpe_number_to_index);
-	return_ACPI_STATUS (AE_NO_MEMORY);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_ev_save_method_info
- *
- * PARAMETERS:  None
- *
- * RETURN:      None
- *
- * DESCRIPTION: Called from Acpi_walk_namespace. Expects each object to be a
- *              control method under the _GPE portion of the namespace.
- *              Extract the name and GPE type from the object, saving this
- *              information for quick lookup during GPE dispatch
- *
- *              The name of each GPE control method is of the form:
- *                  "_Lnn" or "_Enn"
- *              Where:
- *                  L      - means that the GPE is level triggered
- *                  E      - means that the GPE is edge triggered
- *                  nn     - is the GPE number [in HEX]
- *
- ******************************************************************************/
-
-static acpi_status
-acpi_ev_save_method_info (
-	acpi_handle             obj_handle,
-	u32                     level,
-	void                    *obj_desc,
-	void                    **return_value)
-{
-	u32                     gpe_number;
-	u32                     gpe_number_index;
-	NATIVE_CHAR             name[ACPI_NAME_SIZE + 1];
-	u8                      type;
-	acpi_status             status;
-
-
-	ACPI_FUNCTION_NAME ("Ev_save_method_info");
-
-
-	/* Extract the name from the object and convert to a string */
-
-	ACPI_MOVE_UNALIGNED32_TO_32 (name,
-			 &((acpi_namespace_node *) obj_handle)->name.integer);
-	name[ACPI_NAME_SIZE] = 0;
-
-	/*
-	 * Edge/Level determination is based on the 2nd character of the method name
-	 */
-	switch (name[1]) {
-	case 'L':
-		type = ACPI_EVENT_LEVEL_TRIGGERED;
-		break;
-
-	case 'E':
-		type = ACPI_EVENT_EDGE_TRIGGERED;
-		break;
-
-	default:
-		/* Unknown method type, just ignore it! */
-
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Unknown GPE method type: %s (name not of form _Lnn or _Enn)\n",
-			name));
-		return (AE_OK);
-	}
-
-	/* Convert the last two characters of the name to the GPE Number */
-
-	gpe_number = ACPI_STRTOUL (&name[2], NULL, 16);
-	if (gpe_number == ACPI_UINT32_MAX) {
-		/* Conversion failed; invalid method, just ignore it */
-
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Could not extract GPE number from name: %s (name not of form _Lnn or _Enn)\n",
-			name));
-		return (AE_OK);
-	}
-
-	/* Get GPE index and ensure that we have a valid GPE number */
-
-	gpe_number_index = acpi_ev_get_gpe_number_index (gpe_number);
-	if (gpe_number_index == ACPI_GPE_INVALID) {
-		/* Not valid, all we can do here is ignore it */
-
-		return (AE_OK);
-	}
-
-	/*
-	 * Now we can add this information to the Gpe_info block
-	 * for use during dispatch of this GPE.
-	 */
-	acpi_gbl_gpe_number_info [gpe_number_index].type  = type;
-	acpi_gbl_gpe_number_info [gpe_number_index].method_node = (acpi_namespace_node *) obj_handle;
-
-	/*
-	 * Enable the GPE (SCIs should be disabled at this point)
-	 */
-	status = acpi_hw_enable_gpe (gpe_number);
-	if (ACPI_FAILURE (status)) {
-		return (status);
-	}
-
-	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Registered GPE method %s as GPE number %2.2X\n",
-		name, gpe_number));
-	return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_ev_init_gpe_control_methods
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Obtain the control methods associated with the GPEs.
- *              NOTE: Must be called AFTER namespace initialization!
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ev_init_gpe_control_methods (void)
-{
-	acpi_status             status;
-
-
-	ACPI_FUNCTION_TRACE ("Ev_init_gpe_control_methods");
-
-
-	/* Get a permanent handle to the _GPE object */
-
-	status = acpi_get_handle (NULL, "\\_GPE", &acpi_gbl_gpe_obj_handle);
-	if (ACPI_FAILURE (status)) {
-		return_ACPI_STATUS (status);
-	}
-
-	/* Traverse the namespace under \_GPE to find all methods there */
-
-	status = acpi_walk_namespace (ACPI_TYPE_METHOD, acpi_gbl_gpe_obj_handle,
-			  ACPI_UINT32_MAX, acpi_ev_save_method_info,
-			  NULL, NULL);
-
-	return_ACPI_STATUS (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_ev_gpe_detect
- *
- * PARAMETERS:  None
- *
- * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
- *
- * DESCRIPTION: Detect if any GP events have occurred.  This function is
- *              executed at interrupt level.
- *
- ******************************************************************************/
-
-u32
-acpi_ev_gpe_detect (void)
-{
-	u32                     int_status = ACPI_INTERRUPT_NOT_HANDLED;
-	u32                     i;
-	u32                     j;
-	u8                      enabled_status_byte;
-	u8                      bit_mask;
-	ACPI_GPE_REGISTER_INFO  *gpe_register_info;
-	u32                     in_value;
-	acpi_status             status;
-
-
-	ACPI_FUNCTION_NAME ("Ev_gpe_detect");
-
-
-	/*
-	 * Read all of the 8-bit GPE status and enable registers
-	 * in both of the register blocks, saving all of it.
-	 * Find all currently active GP events.
-	 */
-	for (i = 0; i < acpi_gbl_gpe_register_count; i++) {
-		gpe_register_info = &acpi_gbl_gpe_register_info[i];
-
-		status = acpi_hw_low_level_read (8, &in_value, &gpe_register_info->status_address, 0);
-		gpe_register_info->status = (u8) in_value;
-		if (ACPI_FAILURE (status)) {
-			return (ACPI_INTERRUPT_NOT_HANDLED);
-		}
-
-		status = acpi_hw_low_level_read (8, &in_value, &gpe_register_info->enable_address, 0);
-		gpe_register_info->enable = (u8) in_value;
-		if (ACPI_FAILURE (status)) {
-			return (ACPI_INTERRUPT_NOT_HANDLED);
-		}
-
-		ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
-			"GPE block at %8.8X%8.8X - Values: Enable %02X Status %02X\n",
-			ACPI_HIDWORD (ACPI_GET_ADDRESS (gpe_register_info->enable_address.address)),
-			ACPI_LODWORD (ACPI_GET_ADDRESS (gpe_register_info->enable_address.address)),
-			gpe_register_info->enable,
-			gpe_register_info->status));
-
-		/* First check if there is anything active at all in this register */
-
-		enabled_status_byte = (u8) (gpe_register_info->status &
-				   gpe_register_info->enable);
-		if (!enabled_status_byte) {
-			/* No active GPEs in this register, move on */
-
-			continue;
-		}
-
-		/* Now look at the individual GPEs in this byte register */
-
-		for (j = 0, bit_mask = 1; j < 8; j++, bit_mask <<= 1) {
-			/* Examine one GPE bit */
-
-			if (enabled_status_byte & bit_mask) {
-				/*
-				 * Found an active GPE.  Dispatch the event to a handler
-				 * or method.
-				 */
-				int_status |= acpi_ev_gpe_dispatch (
-						  gpe_register_info->base_gpe_number + j);
-			}
-		}
-	}
-
-	return (int_status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_ev_asynch_execute_gpe_method
- *
- * PARAMETERS:  Gpe_number      - The 0-based GPE number
- *
- * RETURN:      None
- *
- * DESCRIPTION: Perform the actual execution of a GPE control method.  This
- *              function is called from an invocation of Acpi_os_queue_for_execution
- *              (and therefore does NOT execute at interrupt level) so that
- *              the control method itself is not executed in the context of
- *              the SCI interrupt handler.
- *
- ******************************************************************************/
-
-static void ACPI_SYSTEM_XFACE
-acpi_ev_asynch_execute_gpe_method (
-	void                    *context)
-{
-	u32                     gpe_number = (u32) ACPI_TO_INTEGER (context);
-	u32                     gpe_number_index;
-	ACPI_GPE_NUMBER_INFO    gpe_info;
-	acpi_status             status;
-
-
-	ACPI_FUNCTION_TRACE ("Ev_asynch_execute_gpe_method");
-
-
-	gpe_number_index = acpi_ev_get_gpe_number_index (gpe_number);
-	if (gpe_number_index == ACPI_GPE_INVALID) {
-		return_VOID;
-	}
-
-	/*
-	 * Take a snapshot of the GPE info for this level - we copy the
-	 * info to prevent a race condition with Remove_handler.
-	 */
-	status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
-	if (ACPI_FAILURE (status)) {
-		return_VOID;
-	}
-
-	gpe_info = acpi_gbl_gpe_number_info [gpe_number_index];
-	status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
-	if (ACPI_FAILURE (status)) {
-		return_VOID;
-	}
-
-	if (gpe_info.method_node) {
-		/*
-		 * Invoke the GPE Method (_Lxx, _Exx):
-		 * (Evaluate the _Lxx/_Exx control method that corresponds to this GPE.)
-		 */
-		status = acpi_ns_evaluate_by_handle (gpe_info.method_node, NULL, NULL);
-		if (ACPI_FAILURE (status)) {
-			ACPI_REPORT_ERROR (("%s while evaluating method [%4.4s] for GPE[%2.2X]\n",
-				acpi_format_exception (status),
-				gpe_info.method_node->name.ascii, gpe_number));
-		}
-	}
-
-	if (gpe_info.type & ACPI_EVENT_LEVEL_TRIGGERED) {
-		/*
-		 * GPE is level-triggered, we clear the GPE status bit after handling
-		 * the event.
-		 */
-		status = acpi_hw_clear_gpe (gpe_number);
-		if (ACPI_FAILURE (status)) {
-			return_VOID;
-		}
-	}
-
-	/*
-	 * Enable the GPE.
-	 */
-	(void) acpi_hw_enable_gpe (gpe_number);
-	return_VOID;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_ev_gpe_dispatch
- *
- * PARAMETERS:  Gpe_number      - The 0-based GPE number
- *
- * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
- *
- * DESCRIPTION: Dispatch a General Purpose Event to either a function (e.g. EC)
- *              or method (e.g. _Lxx/_Exx) handler.  This function executes
- *              at interrupt level.
- *
- ******************************************************************************/
-
-u32
-acpi_ev_gpe_dispatch (
-	u32                     gpe_number)
-{
-	u32                     gpe_number_index;
-	ACPI_GPE_NUMBER_INFO    *gpe_info;
-	acpi_status             status;
-
-
-	ACPI_FUNCTION_TRACE ("Ev_gpe_dispatch");
-
-
-	gpe_number_index = acpi_ev_get_gpe_number_index (gpe_number);
-	if (gpe_number_index == ACPI_GPE_INVALID) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "GPE[%X] is not a valid event\n", gpe_number));
-		return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
-	}
-
-	/*
-	 * We don't have to worry about mutex on Gpe_info because we are
-	 * executing at interrupt level.
-	 */
-	gpe_info = &acpi_gbl_gpe_number_info [gpe_number_index];
-
-	/*
-	 * If edge-triggered, clear the GPE status bit now.  Note that
-	 * level-triggered events are cleared after the GPE is serviced.
-	 */
-	if (gpe_info->type & ACPI_EVENT_EDGE_TRIGGERED) {
-		status = acpi_hw_clear_gpe (gpe_number);
-		if (ACPI_FAILURE (status)) {
-			ACPI_REPORT_ERROR (("Acpi_ev_gpe_dispatch: Unable to clear GPE[%2.2X]\n", gpe_number));
-			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
-		}
-	}
-
-	/*
-	 * Dispatch the GPE to either an installed handler, or the control
-	 * method associated with this GPE (_Lxx or _Exx).
-	 * If a handler exists, we invoke it and do not attempt to run the method.
-	 * If there is neither a handler nor a method, we disable the level to
-	 * prevent further events from coming in here.
-	 */
-	if (gpe_info->handler) {
-		/* Invoke the installed handler (at interrupt level) */
-
-		gpe_info->handler (gpe_info->context);
-	}
-	else if (gpe_info->method_node) {
-		/*
-		 * Disable GPE, so it doesn't keep firing before the method has a
-		 * chance to run.
-		 */
-		status = acpi_hw_disable_gpe (gpe_number);
-		if (ACPI_FAILURE (status)) {
-			ACPI_REPORT_ERROR (("Acpi_ev_gpe_dispatch: Unable to disable GPE[%2.2X]\n", gpe_number));
-			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
-		}
-
-		/*
-		 * Execute the method associated with the GPE.
-		 */
-		if (ACPI_FAILURE (acpi_os_queue_for_execution (OSD_PRIORITY_GPE,
-				 acpi_ev_asynch_execute_gpe_method,
-				 ACPI_TO_POINTER (gpe_number)))) {
-			ACPI_REPORT_ERROR (("Acpi_ev_gpe_dispatch: Unable to queue handler for GPE[%2.2X], event is disabled\n", gpe_number));
-		}
-	}
-	else {
-		/* No handler or method to run! */
-
-		ACPI_REPORT_ERROR (("Acpi_ev_gpe_dispatch: No handler or method for GPE[%2.2X], disabling event\n", gpe_number));
-
-		/*
-		 * Disable the GPE.  The GPE will remain disabled until the ACPI
-		 * Core Subsystem is restarted, or the handler is reinstalled.
-		 */
-		status = acpi_hw_disable_gpe (gpe_number);
-		if (ACPI_FAILURE (status)) {
-			ACPI_REPORT_ERROR (("Acpi_ev_gpe_dispatch: Unable to disable GPE[%2.2X]\n", gpe_number));
-			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
-		}
-	}
-
-	/*
-	 * It is now safe to clear level-triggered evnets.
-	 */
-	if (gpe_info->type & ACPI_EVENT_LEVEL_TRIGGERED) {
-		status = acpi_hw_clear_gpe (gpe_number);
-		if (ACPI_FAILURE (status)) {
-			ACPI_REPORT_ERROR (("Acpi_ev_gpe_dispatch: Unable to clear GPE[%2.2X]\n", gpe_number));
-			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
-		}
-	}
-
-	return_VALUE (ACPI_INTERRUPT_HANDLED);
-}
diff -Nru a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/acpi/events/evgpe.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,706 @@
+/******************************************************************************
+ *
+ * Module Name: evgpe - General Purpose Event handling and dispatch
+ *              $Revision: 1 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2002, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "acpi.h"
+#include "acevents.h"
+#include "acnamesp.h"
+
+#define _COMPONENT          ACPI_EVENTS
+	 ACPI_MODULE_NAME    ("evgpe")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ev_gpe_initialize
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initialize the GPE data structures
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_gpe_initialize (void)
+{
+	NATIVE_UINT_MAX32       i;
+	NATIVE_UINT_MAX32       j;
+	u32                     gpe_block;
+	u32                     gpe_register;
+	u32                     gpe_number_index;
+	u32                     gpe_number;
+	ACPI_GPE_REGISTER_INFO  *gpe_register_info;
+	acpi_status             status;
+
+
+	ACPI_FUNCTION_TRACE ("Ev_gpe_initialize");
+
+
+	/*
+	 * Initialize the GPE Block globals
+	 *
+	 * Why the GPE register block lengths are divided by 2:  From the ACPI Spec,
+	 * section "General-Purpose Event Registers", we have:
+	 *
+	 * "Each register block contains two registers of equal length
+	 *  GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
+	 *  GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN
+	 *  The length of the GPE1_STS and GPE1_EN registers is equal to
+	 *  half the GPE1_LEN. If a generic register block is not supported
+	 *  then its respective block pointer and block length values in the
+	 *  FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need
+	 *  to be the same size."
+	 */
+	acpi_gbl_gpe_block_info[0].register_count = 0;
+	acpi_gbl_gpe_block_info[1].register_count = 0;
+
+	acpi_gbl_gpe_block_info[0].block_address = &acpi_gbl_FADT->Xgpe0_blk;
+	acpi_gbl_gpe_block_info[1].block_address = &acpi_gbl_FADT->Xgpe1_blk;
+
+	acpi_gbl_gpe_block_info[0].block_base_number = 0;
+	acpi_gbl_gpe_block_info[1].block_base_number = acpi_gbl_FADT->gpe1_base;
+
+
+	/*
+	 * Determine the maximum GPE number for this machine.
+	 *
+	 * Note: both GPE0 and GPE1 are optional, and either can exist without
+	 * the other.
+	 * If EITHER the register length OR the block address are zero, then that
+	 * particular block is not supported.
+	 */
+	if (acpi_gbl_FADT->Xgpe0_blk.register_bit_width && ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe0_blk.address)) {
+		/* GPE block 0 exists (has both length and address > 0) */
+
+		acpi_gbl_gpe_block_info[0].register_count = (u16) (acpi_gbl_FADT->Xgpe0_blk.register_bit_width / (ACPI_GPE_REGISTER_WIDTH * 2));
+		acpi_gbl_gpe_number_max               = (acpi_gbl_gpe_block_info[0].register_count * ACPI_GPE_REGISTER_WIDTH) - 1;
+	}
+
+	if (acpi_gbl_FADT->Xgpe1_blk.register_bit_width && ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address)) {
+		/* GPE block 1 exists (has both length and address > 0) */
+
+		acpi_gbl_gpe_block_info[1].register_count = (u16) (acpi_gbl_FADT->Xgpe1_blk.register_bit_width / (ACPI_GPE_REGISTER_WIDTH * 2));
+
+		/* Check for GPE0/GPE1 overlap (if both banks exist) */
+
+		if ((acpi_gbl_gpe_block_info[0].register_count) &&
+			(acpi_gbl_gpe_number_max >= acpi_gbl_FADT->gpe1_base)) {
+			ACPI_REPORT_ERROR ((
+				"GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1\n",
+				acpi_gbl_gpe_number_max, acpi_gbl_FADT->gpe1_base,
+				acpi_gbl_FADT->gpe1_base + ((acpi_gbl_gpe_block_info[1].register_count * ACPI_GPE_REGISTER_WIDTH) - 1)));
+
+			/* Ignore GPE1 block by setting the register count to zero */
+
+			acpi_gbl_gpe_block_info[1].register_count = 0;
+		}
+		else {
+			/*
+			 * GPE0 and GPE1 do not have to be contiguous in the GPE number space,
+			 * But, GPE0 always starts at zero.
+			 */
+			acpi_gbl_gpe_number_max = acpi_gbl_FADT->gpe1_base +
+					 ((acpi_gbl_gpe_block_info[1].register_count * ACPI_GPE_REGISTER_WIDTH) - 1);
+		}
+	}
+
+	/* Exit if there are no GPE registers */
+
+	acpi_gbl_gpe_register_count = acpi_gbl_gpe_block_info[0].register_count +
+			 acpi_gbl_gpe_block_info[1].register_count;
+	if (!acpi_gbl_gpe_register_count) {
+		/* GPEs are not required by ACPI, this is OK */
+
+		ACPI_REPORT_INFO (("There are no GPE blocks defined in the FADT\n"));
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Check for Max GPE number out-of-range */
+
+	if (acpi_gbl_gpe_number_max > ACPI_GPE_MAX) {
+		ACPI_REPORT_ERROR (("Maximum GPE number from FADT is too large: 0x%X\n",
+			acpi_gbl_gpe_number_max));
+		return_ACPI_STATUS (AE_BAD_VALUE);
+	}
+
+	/* Allocate the GPE number-to-index translation table */
+
+	acpi_gbl_gpe_number_to_index = ACPI_MEM_CALLOCATE (
+			   sizeof (ACPI_GPE_INDEX_INFO) *
+			   ((ACPI_SIZE) acpi_gbl_gpe_number_max + 1));
+	if (!acpi_gbl_gpe_number_to_index) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Could not allocate the Gpe_number_to_index table\n"));
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/* Set the Gpe index table to GPE_INVALID */
+
+	ACPI_MEMSET (acpi_gbl_gpe_number_to_index, (int) ACPI_GPE_INVALID,
+			sizeof (ACPI_GPE_INDEX_INFO) * ((ACPI_SIZE) acpi_gbl_gpe_number_max + 1));
+
+	/* Allocate the GPE register information block */
+
+	acpi_gbl_gpe_register_info = ACPI_MEM_CALLOCATE (
+			  (ACPI_SIZE) acpi_gbl_gpe_register_count *
+			  sizeof (ACPI_GPE_REGISTER_INFO));
+	if (!acpi_gbl_gpe_register_info) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Could not allocate the Gpe_register_info table\n"));
+		goto error_exit1;
+	}
+
+	/*
+	 * Allocate the GPE dispatch handler block.  There are eight distinct GPEs
+	 * per register.  Initialization to zeros is sufficient.
+	 */
+	acpi_gbl_gpe_number_info = ACPI_MEM_CALLOCATE (
+			  (ACPI_SIZE) (acpi_gbl_gpe_register_count * ACPI_GPE_REGISTER_WIDTH) *
+			  sizeof (ACPI_GPE_NUMBER_INFO));
+	if (!acpi_gbl_gpe_number_info) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not allocate the Gpe_number_info table\n"));
+		goto error_exit2;
+	}
+
+	/*
+	 * Initialize the GPE information and validation tables.  A goal of these
+	 * tables is to hide the fact that there are two separate GPE register sets
+	 * in a given gpe hardware block, the status registers occupy the first half,
+	 * and the enable registers occupy the second half.  Another goal is to hide
+	 * the fact that there may be multiple GPE hardware blocks.
+	 */
+	gpe_register = 0;
+	gpe_number_index = 0;
+
+	for (gpe_block = 0; gpe_block < ACPI_MAX_GPE_BLOCKS; gpe_block++) {
+		for (i = 0; i < acpi_gbl_gpe_block_info[gpe_block].register_count; i++) {
+			gpe_register_info = &acpi_gbl_gpe_register_info[gpe_register];
+
+			/* Init the Register info for this entire GPE register (8 GPEs) */
+
+			gpe_register_info->base_gpe_number = (u8) (acpi_gbl_gpe_block_info[gpe_block].block_base_number
+					   + (i * ACPI_GPE_REGISTER_WIDTH));
+
+			ACPI_STORE_ADDRESS (gpe_register_info->status_address.address,
+					   (ACPI_GET_ADDRESS (acpi_gbl_gpe_block_info[gpe_block].block_address->address)
+							  + i));
+
+			ACPI_STORE_ADDRESS (gpe_register_info->enable_address.address,
+					   (ACPI_GET_ADDRESS (acpi_gbl_gpe_block_info[gpe_block].block_address->address)
+							  + i
+							  + acpi_gbl_gpe_block_info[gpe_block].register_count));
+
+			gpe_register_info->status_address.address_space_id = acpi_gbl_gpe_block_info[gpe_block].block_address->address_space_id;
+			gpe_register_info->enable_address.address_space_id = acpi_gbl_gpe_block_info[gpe_block].block_address->address_space_id;
+			gpe_register_info->status_address.register_bit_width = ACPI_GPE_REGISTER_WIDTH;
+			gpe_register_info->enable_address.register_bit_width = ACPI_GPE_REGISTER_WIDTH;
+			gpe_register_info->status_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH;
+			gpe_register_info->enable_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH;
+
+			/* Init the Index mapping info for each GPE number within this register */
+
+			for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
+				gpe_number = gpe_register_info->base_gpe_number + j;
+				acpi_gbl_gpe_number_to_index[gpe_number].number_index = (u8) gpe_number_index;
+
+				acpi_gbl_gpe_number_info[gpe_number_index].bit_mask = acpi_gbl_decode_to8bit[j];
+				gpe_number_index++;
+			}
+
+			/*
+			 * Clear the status/enable registers.  Note that status registers
+			 * are cleared by writing a '1', while enable registers are cleared
+			 * by writing a '0'.
+			 */
+			status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0x00, &gpe_register_info->enable_address, 0);
+			if (ACPI_FAILURE (status)) {
+				return_ACPI_STATUS (status);
+			}
+
+			status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0xFF, &gpe_register_info->status_address, 0);
+			if (ACPI_FAILURE (status)) {
+				return_ACPI_STATUS (status);
+			}
+
+			gpe_register++;
+		}
+
+		if (i) {
+			/* Dump info about this valid GPE block */
+
+			ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "GPE Block%d: %X registers at %8.8X%8.8X\n",
+				(s32) gpe_block, acpi_gbl_gpe_block_info[0].register_count,
+				ACPI_HIDWORD (ACPI_GET_ADDRESS (acpi_gbl_gpe_block_info[gpe_block].block_address->address)),
+				ACPI_LODWORD (ACPI_GET_ADDRESS (acpi_gbl_gpe_block_info[gpe_block].block_address->address))));
+
+			ACPI_REPORT_INFO (("GPE Block%d defined as GPE%d to GPE%d\n",
+				(s32) gpe_block,
+				(u32) acpi_gbl_gpe_block_info[gpe_block].block_base_number,
+				(u32) (acpi_gbl_gpe_block_info[gpe_block].block_base_number +
+					((acpi_gbl_gpe_block_info[gpe_block].register_count * ACPI_GPE_REGISTER_WIDTH) -1))));
+		}
+	}
+
+	return_ACPI_STATUS (AE_OK);
+
+
+	/* Error cleanup */
+
+error_exit2:
+	ACPI_MEM_FREE (acpi_gbl_gpe_register_info);
+
+error_exit1:
+	ACPI_MEM_FREE (acpi_gbl_gpe_number_to_index);
+	return_ACPI_STATUS (AE_NO_MEMORY);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ev_save_method_info
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Called from Acpi_walk_namespace. Expects each object to be a
+ *              control method under the _GPE portion of the namespace.
+ *              Extract the name and GPE type from the object, saving this
+ *              information for quick lookup during GPE dispatch
+ *
+ *              The name of each GPE control method is of the form:
+ *                  "_Lnn" or "_Enn"
+ *              Where:
+ *                  L      - means that the GPE is level triggered
+ *                  E      - means that the GPE is edge triggered
+ *                  nn     - is the GPE number [in HEX]
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ev_save_method_info (
+	acpi_handle             obj_handle,
+	u32                     level,
+	void                    *obj_desc,
+	void                    **return_value)
+{
+	u32                     gpe_number;
+	u32                     gpe_number_index;
+	NATIVE_CHAR             name[ACPI_NAME_SIZE + 1];
+	u8                      type;
+	acpi_status             status;
+
+
+	ACPI_FUNCTION_NAME ("Ev_save_method_info");
+
+
+	/* Extract the name from the object and convert to a string */
+
+	ACPI_MOVE_UNALIGNED32_TO_32 (name,
+			 &((acpi_namespace_node *) obj_handle)->name.integer);
+	name[ACPI_NAME_SIZE] = 0;
+
+	/*
+	 * Edge/Level determination is based on the 2nd character of the method name
+	 */
+	switch (name[1]) {
+	case 'L':
+		type = ACPI_EVENT_LEVEL_TRIGGERED;
+		break;
+
+	case 'E':
+		type = ACPI_EVENT_EDGE_TRIGGERED;
+		break;
+
+	default:
+		/* Unknown method type, just ignore it! */
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Unknown GPE method type: %s (name not of form _Lnn or _Enn)\n",
+			name));
+		return (AE_OK);
+	}
+
+	/* Convert the last two characters of the name to the GPE Number */
+
+	gpe_number = ACPI_STRTOUL (&name[2], NULL, 16);
+	if (gpe_number == ACPI_UINT32_MAX) {
+		/* Conversion failed; invalid method, just ignore it */
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Could not extract GPE number from name: %s (name not of form _Lnn or _Enn)\n",
+			name));
+		return (AE_OK);
+	}
+
+	/* Get GPE index and ensure that we have a valid GPE number */
+
+	gpe_number_index = acpi_ev_get_gpe_number_index (gpe_number);
+	if (gpe_number_index == ACPI_GPE_INVALID) {
+		/* Not valid, all we can do here is ignore it */
+
+		return (AE_OK);
+	}
+
+	/*
+	 * Now we can add this information to the Gpe_info block
+	 * for use during dispatch of this GPE.
+	 */
+	acpi_gbl_gpe_number_info [gpe_number_index].type  = type;
+	acpi_gbl_gpe_number_info [gpe_number_index].method_node = (acpi_namespace_node *) obj_handle;
+
+	/*
+	 * Enable the GPE (SCIs should be disabled at this point)
+	 */
+	status = acpi_hw_enable_gpe (gpe_number);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Registered GPE method %s as GPE number %2.2X\n",
+		name, gpe_number));
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ev_init_gpe_control_methods
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Obtain the control methods associated with the GPEs.
+ *              NOTE: Must be called AFTER namespace initialization!
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_init_gpe_control_methods (void)
+{
+	acpi_status             status;
+
+
+	ACPI_FUNCTION_TRACE ("Ev_init_gpe_control_methods");
+
+
+	/* Get a permanent handle to the _GPE object */
+
+	status = acpi_get_handle (NULL, "\\_GPE", &acpi_gbl_gpe_obj_handle);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Traverse the namespace under \_GPE to find all methods there */
+
+	status = acpi_walk_namespace (ACPI_TYPE_METHOD, acpi_gbl_gpe_obj_handle,
+			  ACPI_UINT32_MAX, acpi_ev_save_method_info,
+			  NULL, NULL);
+
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ev_gpe_detect
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
+ *
+ * DESCRIPTION: Detect if any GP events have occurred.  This function is
+ *              executed at interrupt level.
+ *
+ ******************************************************************************/
+
+u32
+acpi_ev_gpe_detect (void)
+{
+	u32                     int_status = ACPI_INTERRUPT_NOT_HANDLED;
+	u32                     i;
+	u32                     j;
+	u8                      enabled_status_byte;
+	u8                      bit_mask;
+	ACPI_GPE_REGISTER_INFO  *gpe_register_info;
+	u32                     in_value;
+	acpi_status             status;
+
+
+	ACPI_FUNCTION_NAME ("Ev_gpe_detect");
+
+
+	/*
+	 * Read all of the 8-bit GPE status and enable registers
+	 * in both of the register blocks, saving all of it.
+	 * Find all currently active GP events.
+	 */
+	for (i = 0; i < acpi_gbl_gpe_register_count; i++) {
+		gpe_register_info = &acpi_gbl_gpe_register_info[i];
+
+		status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value, &gpe_register_info->status_address, 0);
+		gpe_register_info->status = (u8) in_value;
+		if (ACPI_FAILURE (status)) {
+			return (ACPI_INTERRUPT_NOT_HANDLED);
+		}
+
+		status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value, &gpe_register_info->enable_address, 0);
+		gpe_register_info->enable = (u8) in_value;
+		if (ACPI_FAILURE (status)) {
+			return (ACPI_INTERRUPT_NOT_HANDLED);
+		}
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
+			"GPE block at %8.8X%8.8X - Values: Enable %02X Status %02X\n",
+			ACPI_HIDWORD (ACPI_GET_ADDRESS (gpe_register_info->enable_address.address)),
+			ACPI_LODWORD (ACPI_GET_ADDRESS (gpe_register_info->enable_address.address)),
+			gpe_register_info->enable,
+			gpe_register_info->status));
+
+		/* First check if there is anything active at all in this register */
+
+		enabled_status_byte = (u8) (gpe_register_info->status &
+				   gpe_register_info->enable);
+		if (!enabled_status_byte) {
+			/* No active GPEs in this register, move on */
+
+			continue;
+		}
+
+		/* Now look at the individual GPEs in this byte register */
+
+		for (j = 0, bit_mask = 1; j < ACPI_GPE_REGISTER_WIDTH; j++, bit_mask <<= 1) {
+			/* Examine one GPE bit */
+
+			if (enabled_status_byte & bit_mask) {
+				/*
+				 * Found an active GPE.  Dispatch the event to a handler
+				 * or method.
+				 */
+				int_status |= acpi_ev_gpe_dispatch (
+						  gpe_register_info->base_gpe_number + j);
+			}
+		}
+	}
+
+	return (int_status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ev_asynch_execute_gpe_method
+ *
+ * PARAMETERS:  Gpe_number      - The 0-based GPE number
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Perform the actual execution of a GPE control method.  This
+ *              function is called from an invocation of Acpi_os_queue_for_execution
+ *              (and therefore does NOT execute at interrupt level) so that
+ *              the control method itself is not executed in the context of
+ *              the SCI interrupt handler.
+ *
+ ******************************************************************************/
+
+static void ACPI_SYSTEM_XFACE
+acpi_ev_asynch_execute_gpe_method (
+	void                    *context)
+{
+	u32                     gpe_number = (u32) ACPI_TO_INTEGER (context);
+	u32                     gpe_number_index;
+	ACPI_GPE_NUMBER_INFO    gpe_info;
+	acpi_status             status;
+
+
+	ACPI_FUNCTION_TRACE ("Ev_asynch_execute_gpe_method");
+
+
+	gpe_number_index = acpi_ev_get_gpe_number_index (gpe_number);
+	if (gpe_number_index == ACPI_GPE_INVALID) {
+		return_VOID;
+	}
+
+	/*
+	 * Take a snapshot of the GPE info for this level - we copy the
+	 * info to prevent a race condition with Remove_handler.
+	 */
+	status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
+	if (ACPI_FAILURE (status)) {
+		return_VOID;
+	}
+
+	gpe_info = acpi_gbl_gpe_number_info [gpe_number_index];
+	status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+	if (ACPI_FAILURE (status)) {
+		return_VOID;
+	}
+
+	if (gpe_info.method_node) {
+		/*
+		 * Invoke the GPE Method (_Lxx, _Exx):
+		 * (Evaluate the _Lxx/_Exx control method that corresponds to this GPE.)
+		 */
+		status = acpi_ns_evaluate_by_handle (gpe_info.method_node, NULL, NULL);
+		if (ACPI_FAILURE (status)) {
+			ACPI_REPORT_ERROR (("%s while evaluating method [%4.4s] for GPE[%2.2X]\n",
+				acpi_format_exception (status),
+				gpe_info.method_node->name.ascii, gpe_number));
+		}
+	}
+
+	if (gpe_info.type & ACPI_EVENT_LEVEL_TRIGGERED) {
+		/*
+		 * GPE is level-triggered, we clear the GPE status bit after handling
+		 * the event.
+		 */
+		status = acpi_hw_clear_gpe (gpe_number);
+		if (ACPI_FAILURE (status)) {
+			return_VOID;
+		}
+	}
+
+	/*
+	 * Enable the GPE.
+	 */
+	(void) acpi_hw_enable_gpe (gpe_number);
+	return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ev_gpe_dispatch
+ *
+ * PARAMETERS:  Gpe_number      - The 0-based GPE number
+ *
+ * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
+ *
+ * DESCRIPTION: Dispatch a General Purpose Event to either a function (e.g. EC)
+ *              or method (e.g. _Lxx/_Exx) handler.  This function executes
+ *              at interrupt level.
+ *
+ ******************************************************************************/
+
+u32
+acpi_ev_gpe_dispatch (
+	u32                     gpe_number)
+{
+	u32                     gpe_number_index;
+	ACPI_GPE_NUMBER_INFO    *gpe_info;
+	acpi_status             status;
+
+
+	ACPI_FUNCTION_TRACE ("Ev_gpe_dispatch");
+
+
+	gpe_number_index = acpi_ev_get_gpe_number_index (gpe_number);
+	if (gpe_number_index == ACPI_GPE_INVALID) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "GPE[%X] is not a valid event\n", gpe_number));
+		return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
+	}
+
+	/*
+	 * We don't have to worry about mutex on Gpe_info because we are
+	 * executing at interrupt level.
+	 */
+	gpe_info = &acpi_gbl_gpe_number_info [gpe_number_index];
+
+	/*
+	 * If edge-triggered, clear the GPE status bit now.  Note that
+	 * level-triggered events are cleared after the GPE is serviced.
+	 */
+	if (gpe_info->type & ACPI_EVENT_EDGE_TRIGGERED) {
+		status = acpi_hw_clear_gpe (gpe_number);
+		if (ACPI_FAILURE (status)) {
+			ACPI_REPORT_ERROR (("Acpi_ev_gpe_dispatch: Unable to clear GPE[%2.2X]\n", gpe_number));
+			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
+		}
+	}
+
+	/*
+	 * Dispatch the GPE to either an installed handler, or the control
+	 * method associated with this GPE (_Lxx or _Exx).
+	 * If a handler exists, we invoke it and do not attempt to run the method.
+	 * If there is neither a handler nor a method, we disable the level to
+	 * prevent further events from coming in here.
+	 */
+	if (gpe_info->handler) {
+		/* Invoke the installed handler (at interrupt level) */
+
+		gpe_info->handler (gpe_info->context);
+	}
+	else if (gpe_info->method_node) {
+		/*
+		 * Disable GPE, so it doesn't keep firing before the method has a
+		 * chance to run.
+		 */
+		status = acpi_hw_disable_gpe (gpe_number);
+		if (ACPI_FAILURE (status)) {
+			ACPI_REPORT_ERROR (("Acpi_ev_gpe_dispatch: Unable to disable GPE[%2.2X]\n", gpe_number));
+			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
+		}
+
+		/*
+		 * Execute the method associated with the GPE.
+		 */
+		if (ACPI_FAILURE (acpi_os_queue_for_execution (OSD_PRIORITY_GPE,
+				 acpi_ev_asynch_execute_gpe_method,
+				 ACPI_TO_POINTER (gpe_number)))) {
+			ACPI_REPORT_ERROR (("Acpi_ev_gpe_dispatch: Unable to queue handler for GPE[%2.2X], event is disabled\n", gpe_number));
+		}
+	}
+	else {
+		/* No handler or method to run! */
+
+		ACPI_REPORT_ERROR (("Acpi_ev_gpe_dispatch: No handler or method for GPE[%2.2X], disabling event\n", gpe_number));
+
+		/*
+		 * Disable the GPE.  The GPE will remain disabled until the ACPI
+		 * Core Subsystem is restarted, or the handler is reinstalled.
+		 */
+		status = acpi_hw_disable_gpe (gpe_number);
+		if (ACPI_FAILURE (status)) {
+			ACPI_REPORT_ERROR (("Acpi_ev_gpe_dispatch: Unable to disable GPE[%2.2X]\n", gpe_number));
+			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
+		}
+	}
+
+	/*
+	 * It is now safe to clear level-triggered evnets.
+	 */
+	if (gpe_info->type & ACPI_EVENT_LEVEL_TRIGGERED) {
+		status = acpi_hw_clear_gpe (gpe_number);
+		if (ACPI_FAILURE (status)) {
+			ACPI_REPORT_ERROR (("Acpi_ev_gpe_dispatch: Unable to clear GPE[%2.2X]\n", gpe_number));
+			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
+		}
+	}
+
+	return_VALUE (ACPI_INTERRUPT_HANDLED);
+}
+
diff -Nru a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
--- a/drivers/acpi/events/evregion.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/acpi/events/evregion.c	Mon Dec  9 18:46:34 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: evregion - ACPI Address_space (Op_region) handler dispatch
- *              $Revision: 135 $
+ *              $Revision: 136 $
  *
  *****************************************************************************/
 
@@ -172,7 +172,7 @@
 	/*
 	 *  Execute the method, no return value
 	 */
-	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (region_obj2->extra.method_REG, " [Method]"));
+	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, region_obj2->extra.method_REG, NULL));
 	status = acpi_ns_evaluate_by_handle (region_obj2->extra.method_REG, params, NULL);
 
 	acpi_ut_remove_reference (params[1]);
diff -Nru a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c
--- a/drivers/acpi/events/evxfevnt.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/acpi/events/evxfevnt.c	Mon Dec  9 18:46:35 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable
- *              $Revision: 57 $
+ *              $Revision: 59 $
  *
  *****************************************************************************/
 
@@ -60,18 +60,18 @@
 	}
 
 	if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_OK, "Already in ACPI mode.\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "System is already in ACPI mode\n"));
 	}
 	else {
 		/* Transition to ACPI mode */
 
 		status = acpi_hw_set_mode (ACPI_SYS_MODE_ACPI);
 		if (ACPI_FAILURE (status)) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_FATAL, "Could not transition to ACPI mode.\n"));
+			ACPI_REPORT_ERROR (("Could not transition to ACPI mode.\n"));
 			return_ACPI_STATUS (status);
 		}
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_OK, "Transition to ACPI mode successful\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Transition to ACPI mode successful\n"));
 	}
 
 	return_ACPI_STATUS (status);
@@ -104,18 +104,19 @@
 	}
 
 	if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_OK, "Already in LEGACY mode.\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "System is already in legacy (non-ACPI) mode\n"));
 	}
 	else {
 		/* Transition to LEGACY mode */
+
 		status = acpi_hw_set_mode (ACPI_SYS_MODE_LEGACY);
 
 		if (ACPI_FAILURE (status)) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not transition to LEGACY mode."));
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not exit ACPI mode to legacy mode"));
 			return_ACPI_STATUS (status);
 		}
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_OK, "Transition to LEGACY mode successful\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI mode disabled\n"));
 	}
 
 	return_ACPI_STATUS (status);
diff -Nru a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c
--- a/drivers/acpi/executer/exconvrt.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/acpi/executer/exconvrt.c	Mon Dec  9 18:46:34 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: exconvrt - Object conversion routines
- *              $Revision: 44 $
+ *              $Revision: 45 $
  *
  *****************************************************************************/
 
@@ -230,7 +230,7 @@
 		 * Create a new Buffer object
 		 * Size will be the string length
 		 */
-		ret_desc = acpi_ut_create_buffer_object (obj_desc->string.length);
+		ret_desc = acpi_ut_create_buffer_object ((ACPI_SIZE) obj_desc->string.length);
 		if (!ret_desc) {
 			return_ACPI_STATUS (AE_NO_MEMORY);
 		}
diff -Nru a/drivers/acpi/executer/exfield.c b/drivers/acpi/executer/exfield.c
--- a/drivers/acpi/executer/exfield.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/acpi/executer/exfield.c	Mon Dec  9 18:46:34 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: exfield - ACPI AML (p-code) execution - field manipulation
- *              $Revision: 115 $
+ *              $Revision: 116 $
  *
  *****************************************************************************/
 
@@ -56,7 +56,7 @@
 {
 	acpi_status             status;
 	acpi_operand_object     *buffer_desc;
-	u32                     length;
+	ACPI_SIZE               length;
 	void                    *buffer;
 	u8                      locked;
 
@@ -118,7 +118,7 @@
 	 *
 	 * Note: Field.length is in bits.
 	 */
-	length = ACPI_ROUND_BITS_UP_TO_BYTES (obj_desc->field.bit_length);
+	length = (ACPI_SIZE) ACPI_ROUND_BITS_UP_TO_BYTES (obj_desc->field.bit_length);
 	if (length > acpi_gbl_integer_byte_width) {
 		/* Field is too large for an Integer, create a Buffer instead */
 
@@ -143,7 +143,7 @@
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 		"Obj=%p Type=%X Buf=%p Len=%X\n",
-		obj_desc, ACPI_GET_OBJECT_TYPE (obj_desc), buffer, length));
+		obj_desc, ACPI_GET_OBJECT_TYPE (obj_desc), buffer, (u32) length));
 	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 		"Field_write: Bit_len=%X Bit_off=%X Byte_off=%X\n",
 		obj_desc->common_field.bit_length,
@@ -156,7 +156,7 @@
 
 	/* Read from the field */
 
-	status = acpi_ex_extract_from_field (obj_desc, buffer, length);
+	status = acpi_ex_extract_from_field (obj_desc, buffer, (u32) length);
 	acpi_ex_release_global_lock (locked);
 
 
diff -Nru a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c
--- a/drivers/acpi/executer/exmisc.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/acpi/executer/exmisc.c	Mon Dec  9 18:46:50 2002
@@ -2,7 +2,7 @@
 /******************************************************************************
  *
  * Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes
- *              $Revision: 112 $
+ *              $Revision: 113 $
  *
  *****************************************************************************/
 
@@ -281,8 +281,8 @@
 
 		/* Operand0 is string  */
 
-		new_buf = ACPI_MEM_ALLOCATE ((ACPI_SIZE) obj_desc1->string.length +
-				  (ACPI_SIZE) obj_desc2->string.length + 1);
+		new_buf = ACPI_MEM_CALLOCATE ((ACPI_SIZE) obj_desc1->string.length +
+				   (ACPI_SIZE) obj_desc2->string.length + 1);
 		if (!new_buf) {
 			ACPI_REPORT_ERROR
 				(("Ex_do_concatenate: String allocation failure\n"));
diff -Nru a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c
--- a/drivers/acpi/executer/exregion.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/acpi/executer/exregion.c	Mon Dec  9 18:46:35 2002
@@ -2,7 +2,7 @@
 /******************************************************************************
  *
  * Module Name: exregion - ACPI default Op_region (address space) handlers
- *              $Revision: 80 $
+ *              $Revision: 81 $
  *
  *****************************************************************************/
 
@@ -133,8 +133,8 @@
 		 * constrain the maximum mapping size to something reasonable.
 		 */
 		window_size = (ACPI_SIZE) ((mem_info->address + mem_info->length) - address);
-		if (window_size > SYSMEM_REGION_WINDOW_SIZE) {
-			window_size = SYSMEM_REGION_WINDOW_SIZE;
+		if (window_size > ACPI_SYSMEM_REGION_WINDOW_SIZE) {
+			window_size = ACPI_SYSMEM_REGION_WINDOW_SIZE;
 		}
 
 		/* Create a new mapping starting at the address given */
diff -Nru a/drivers/acpi/executer/exstorob.c b/drivers/acpi/executer/exstorob.c
--- a/drivers/acpi/executer/exstorob.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/acpi/executer/exstorob.c	Mon Dec  9 18:46:51 2002
@@ -2,7 +2,7 @@
 /******************************************************************************
  *
  * Module Name: exstorob - AML Interpreter object store support, store to object
- *              $Revision: 46 $
+ *              $Revision: 47 $
  *
  *****************************************************************************/
 
@@ -65,15 +65,17 @@
 	length = source_desc->buffer.length;
 
 	/*
-	 * If target is a buffer of length zero, allocate a new
-	 * buffer of the proper length
+	 * If target is a buffer of length zero or is a static buffer,
+	 * allocate a new buffer of the proper length
 	 */
-	if (target_desc->buffer.length == 0) {
+	if ((target_desc->buffer.length == 0) ||
+		(target_desc->common.flags & AOPOBJ_STATIC_POINTER)) {
 		target_desc->buffer.pointer = ACPI_MEM_ALLOCATE (length);
 		if (!target_desc->buffer.pointer) {
 			return (AE_NO_MEMORY);
 		}
 
+		target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
 		target_desc->buffer.length = length;
 	}
 
@@ -137,11 +139,13 @@
 	length = source_desc->string.length;
 
 	/*
-	 * Setting a string value replaces the old string
+	 * Replace existing string value if it will fit and the string
+	 * pointer is not a static pointer (part of an ACPI table)
 	 */
-	if (length < target_desc->string.length) {
+	if ((length < target_desc->string.length) &&
+	   (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
 		/*
-		 * String will fit in existing buffer.
+		 * String will fit in existing non-static buffer.
 		 * Clear old string and copy in the new one
 		 */
 		ACPI_MEMSET (target_desc->string.pointer, 0, (ACPI_SIZE) target_desc->string.length + 1);
@@ -165,6 +169,7 @@
 			return (AE_NO_MEMORY);
 		}
 
+		target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
 		ACPI_MEMCPY (target_desc->string.pointer, buffer, length);
 	}
 
diff -Nru a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
--- a/drivers/acpi/hardware/hwregs.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/acpi/hardware/hwregs.c	Mon Dec  9 18:46:50 2002
@@ -3,7 +3,7 @@
  *
  * Module Name: hwregs - Read/write access functions for the various ACPI
  *                       control and status registers.
- *              $Revision: 134 $
+ *              $Revision: 137 $
  *
  ******************************************************************************/
 
@@ -142,6 +142,9 @@
 	status = acpi_ns_evaluate_by_name ((NATIVE_CHAR *) acpi_gbl_db_sleep_states[sleep_state],
 			  NULL, &obj_desc);
 	if (ACPI_FAILURE (status)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s while evaluating Sleep_state [%s]\n",
+			acpi_format_exception (status), acpi_gbl_db_sleep_states[sleep_state]));
+
 		return_ACPI_STATUS (status);
 	}
 
@@ -184,8 +187,8 @@
 	}
 
 	if (ACPI_FAILURE (status)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad Sleep object %p type %s\n",
-			obj_desc, acpi_ut_get_object_type_name (obj_desc)));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "While evaluating Sleep_state [%s], bad Sleep object %p type %s\n",
+			acpi_gbl_db_sleep_states[sleep_state], obj_desc, acpi_ut_get_object_type_name (obj_desc)));
 	}
 
 	acpi_ut_remove_reference (obj_desc);
diff -Nru a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
--- a/drivers/acpi/hardware/hwsleep.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/acpi/hardware/hwsleep.c	Mon Dec  9 18:46:34 2002
@@ -2,7 +2,7 @@
 /******************************************************************************
  *
  * Name: hwsleep.c - ACPI Hardware Sleep/Wake Interface
- *              $Revision: 47 $
+ *              $Revision: 48 $
  *
  *****************************************************************************/
 
@@ -236,7 +236,7 @@
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
-	ACPI_DEBUG_PRINT ((ACPI_DB_OK, "Entering S%d\n", sleep_state));
+	ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Entering sleep state [S%d]\n", sleep_state));
 
 	/* Clear SLP_EN and SLP_TYP fields */
 
diff -Nru a/drivers/acpi/include/acconfig.h b/drivers/acpi/include/acconfig.h
--- a/drivers/acpi/include/acconfig.h	Mon Dec  9 18:46:50 2002
+++ b/drivers/acpi/include/acconfig.h	Mon Dec  9 18:46:50 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acconfig.h - Global configuration constants
- *       $Revision: 119 $
+ *       $Revision: 122 $
  *
  *****************************************************************************/
 
@@ -54,7 +54,7 @@
 
 /* Version string */
 
-#define ACPI_CA_VERSION                 0x20021122
+#define ACPI_CA_VERSION                 0x20021205
 
 /* Version of ACPI supported */
 
@@ -62,28 +62,28 @@
 
 /* Maximum objects in the various object caches */
 
-#define MAX_STATE_CACHE_DEPTH           64          /* State objects for stacks */
-#define MAX_PARSE_CACHE_DEPTH           96          /* Parse tree objects */
-#define MAX_EXTPARSE_CACHE_DEPTH        64          /* Parse tree objects */
-#define MAX_OBJECT_CACHE_DEPTH          64          /* Interpreter operand objects */
-#define MAX_WALK_CACHE_DEPTH            4           /* Objects for parse tree walks */
+#define ACPI_MAX_STATE_CACHE_DEPTH      64          /* State objects for stacks */
+#define ACPI_MAX_PARSE_CACHE_DEPTH      96          /* Parse tree objects */
+#define ACPI_MAX_EXTPARSE_CACHE_DEPTH   64          /* Parse tree objects */
+#define ACPI_MAX_OBJECT_CACHE_DEPTH     64          /* Interpreter operand objects */
+#define ACPI_MAX_WALK_CACHE_DEPTH       4           /* Objects for parse tree walks */
 
 /* String size constants */
 
-#define MAX_STRING_LENGTH               512
-#define PATHNAME_MAX                    256         /* A full namespace pathname */
+#define ACPI_MAX_STRING_LENGTH          512
+#define ACPI_PATHNAME_MAX               256         /* A full namespace pathname */
 
 /* Maximum count for a semaphore object */
 
-#define MAX_SEMAPHORE_COUNT             256
+#define ACPI_MAX_SEMAPHORE_COUNT        256
 
 /* Max reference count (for debug only) */
 
-#define MAX_REFERENCE_COUNT             0x400
+#define ACPI_MAX_REFERENCE_COUNT        0x400
 
 /* Size of cached memory mapping for system memory operation region */
 
-#define SYSMEM_REGION_WINDOW_SIZE       4096
+#define ACPI_SYSMEM_REGION_WINDOW_SIZE  4096
 
 
 /******************************************************************************
@@ -106,42 +106,43 @@
  *
  *****************************************************************************/
 
-/* Number of distinct GPE register blocks */
+/* Number of distinct GPE register blocks and register width */
 
 #define ACPI_MAX_GPE_BLOCKS             2
+#define ACPI_GPE_REGISTER_WIDTH         8
 
 /*
  * Method info (in WALK_STATE), containing local variables and argumetns
  */
-#define MTH_NUM_LOCALS                  8
-#define MTH_MAX_LOCAL                   7
+#define ACPI_METHOD_NUM_LOCALS          8
+#define ACPI_METHOD_MAX_LOCAL           7
 
-#define MTH_NUM_ARGS                    7
-#define MTH_MAX_ARG                     6
+#define ACPI_METHOD_NUM_ARGS            7
+#define ACPI_METHOD_MAX_ARG             6
 
 /* Maximum length of resulting string when converting from a buffer */
 
 #define ACPI_MAX_STRING_CONVERSION      200
 
 /*
- * Operand Stack (in WALK_STATE), Must be large enough to contain MTH_MAX_ARG
+ * Operand Stack (in WALK_STATE), Must be large enough to contain METHOD_MAX_ARG
  */
-#define OBJ_NUM_OPERANDS                8
-#define OBJ_MAX_OPERAND                 7
+#define ACPI_OBJ_NUM_OPERANDS           8
+#define ACPI_OBJ_MAX_OPERAND            7
 
 /* Names within the namespace are 4 bytes long */
 
 #define ACPI_NAME_SIZE                  4
-#define PATH_SEGMENT_LENGTH             5           /* 4 chars for name + 1 char for separator */
-#define PATH_SEPARATOR                  '.'
+#define ACPI_PATH_SEGMENT_LENGTH        5           /* 4 chars for name + 1 char for separator */
+#define ACPI_PATH_SEPARATOR             '.'
 
 /* Constants used in searching for the RSDP in low memory */
 
-#define LO_RSDP_WINDOW_BASE             0           /* Physical Address */
-#define HI_RSDP_WINDOW_BASE             0xE0000     /* Physical Address */
-#define LO_RSDP_WINDOW_SIZE             0x400
-#define HI_RSDP_WINDOW_SIZE             0x20000
-#define RSDP_SCAN_STEP                  16
+#define ACPI_LO_RSDP_WINDOW_BASE        0           /* Physical Address */
+#define ACPI_HI_RSDP_WINDOW_BASE        0xE0000     /* Physical Address */
+#define ACPI_LO_RSDP_WINDOW_SIZE        0x400
+#define ACPI_HI_RSDP_WINDOW_SIZE        0x20000
+#define ACPI_RSDP_SCAN_STEP             16
 
 /* Operation regions */
 
@@ -154,12 +155,12 @@
 
 /* Array sizes.  Used for range checking also */
 
-#define NUM_ACCESS_TYPES                6
-#define NUM_UPDATE_RULES                3
-#define NUM_LOCK_RULES                  2
-#define NUM_MATCH_OPS                   6
-#define NUM_OPCODES                     256
-#define NUM_FIELD_NAMES                 2
+#define ACPI_NUM_ACCESS_TYPES           6
+#define ACPI_NUM_UPDATE_RULES           3
+#define ACPI_NUM_LOCK_RULES             2
+#define ACPI_NUM_MATCH_OPS              6
+#define ACPI_NUM_OPCODES                256
+#define ACPI_NUM_FIELD_NAMES            2
 
 /* RSDP checksums */
 
diff -Nru a/drivers/acpi/include/acdisasm.h b/drivers/acpi/include/acdisasm.h
--- a/drivers/acpi/include/acdisasm.h	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,361 +0,0 @@
-/******************************************************************************
- *
- * Name: acdisasm.h - AML disassembler
- *       $Revision: 5 $
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2002, R. Byron Moore
- *
- *  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
- */
-
-#ifndef __ACDISASM_H__
-#define __ACDISASM_H__
-
-#include "amlresrc.h"
-
-
-#define BLOCK_NONE              0
-#define BLOCK_PAREN             1
-#define BLOCK_BRACE             2
-#define BLOCK_COMMA_LIST        4
-
-extern const char               *acpi_gbl_io_decode[2];
-extern const char               *acpi_gbl_word_decode[4];
-extern const char               *acpi_gbl_consume_decode[2];
-extern const char               *acpi_gbl_min_decode[2];
-extern const char               *acpi_gbl_max_decode[2];
-extern const char               *acpi_gbl_DECdecode[2];
-extern const char               *acpi_gbl_RNGdecode[4];
-extern const char               *acpi_gbl_MEMdecode[4];
-extern const char               *acpi_gbl_RWdecode[2];
-extern const char               *acpi_gbl_irq_decode[2];
-extern const char               *acpi_gbl_HEdecode[2];
-extern const char               *acpi_gbl_LLdecode[2];
-extern const char               *acpi_gbl_SHRdecode[2];
-extern const char               *acpi_gbl_TYPdecode[4];
-extern const char               *acpi_gbl_BMdecode[2];
-extern const char               *acpi_gbl_SIZdecode[4];
-extern const NATIVE_CHAR        *acpi_gbl_lock_rule[NUM_LOCK_RULES];
-extern const NATIVE_CHAR        *acpi_gbl_access_types[NUM_ACCESS_TYPES];
-extern const NATIVE_CHAR        *acpi_gbl_update_rules[NUM_UPDATE_RULES];
-extern const NATIVE_CHAR        *acpi_gbl_match_ops[NUM_MATCH_OPS];
-
-
-typedef struct acpi_op_walk_info
-{
-	u32                     level;
-	u32                     bit_offset;
-
-} ACPI_OP_WALK_INFO;
-
-typedef
-acpi_status (*ASL_WALK_CALLBACK) (
-	acpi_parse_object           *op,
-	u32                         level,
-	void                        *context);
-
-
-/*
- * dmwalk
- */
-
-void
-acpi_dm_walk_parse_tree (
-	acpi_parse_object       *op,
-	ASL_WALK_CALLBACK       descending_callback,
-	ASL_WALK_CALLBACK       ascending_callback,
-	void                    *context);
-
-acpi_status
-acpi_dm_descending_op (
-	acpi_parse_object       *op,
-	u32                     level,
-	void                    *context);
-
-acpi_status
-acpi_dm_ascending_op (
-	acpi_parse_object       *op,
-	u32                     level,
-	void                    *context);
-
-
-/*
- * dmopcode
- */
-
-void
-acpi_dm_validate_name (
-	char                    *name,
-	acpi_parse_object       *op);
-
-u32
-acpi_dm_dump_name (
-	char                    *name);
-
-void
-acpi_dm_unicode (
-	acpi_parse_object       *op);
-
-void
-acpi_dm_disassemble (
-	acpi_walk_state         *walk_state,
-	acpi_parse_object       *origin,
-	u32                     num_opcodes);
-
-void
-acpi_dm_namestring (
-	NATIVE_CHAR             *name);
-
-void
-acpi_dm_display_path (
-	acpi_parse_object       *op);
-
-void
-acpi_dm_disassemble_one_op (
-	acpi_walk_state         *walk_state,
-	ACPI_OP_WALK_INFO       *info,
-	acpi_parse_object       *op);
-
-void
-acpi_dm_decode_internal_object (
-	acpi_operand_object     *obj_desc);
-
-void
-acpi_dm_decode_node (
-	acpi_namespace_node     *node);
-
-u32
-acpi_dm_block_type (
-	acpi_parse_object       *op);
-
-u32
-acpi_dm_list_type (
-	acpi_parse_object       *op);
-
-acpi_status
-acpi_ps_display_object_pathname (
-	acpi_walk_state         *walk_state,
-	acpi_parse_object       *op);
-
-void
-acpi_dm_method_flags (
-	acpi_parse_object       *op);
-
-void
-acpi_dm_field_flags (
-	acpi_parse_object       *op);
-
-void
-acpi_dm_address_space (
-	u8                      space_id);
-
-void
-acpi_dm_region_flags (
-	acpi_parse_object       *op);
-
-void
-acpi_dm_match_op (
-	acpi_parse_object       *op);
-
-void
-acpi_dm_match_keyword (
-	acpi_parse_object       *op);
-
-u8
-acpi_dm_comma_if_list_member (
-	acpi_parse_object       *op);
-
-void
-acpi_dm_comma_if_field_member (
-	acpi_parse_object       *op);
-
-
-/*
- * dmbuffer
- */
-
-void
-acpi_is_eisa_id (
-	acpi_parse_object       *op);
-
-void
-acpi_dm_eisa_id (
-	u32                     encoded_id);
-
-u8
-acpi_dm_is_unicode_buffer (
-	acpi_parse_object       *op);
-
-u8
-acpi_dm_is_string_buffer (
-	acpi_parse_object       *op);
-
-
-/*
- * dmresrc
- */
-
-void
-acpi_dm_disasm_byte_list (
-	u32                     level,
-	u8                      *byte_data,
-	u32                     byte_count);
-
-void
-acpi_dm_byte_list (
-	ACPI_OP_WALK_INFO       *info,
-	acpi_parse_object       *op);
-
-void
-acpi_dm_resource_descriptor (
-	ACPI_OP_WALK_INFO       *info,
-	u8                      *byte_data,
-	u32                     byte_count);
-
-u8
-acpi_dm_is_resource_descriptor (
-	acpi_parse_object       *op);
-
-void
-acpi_dm_indent (
-	u32                     level);
-
-void
-acpi_dm_bit_list (
-	u16                     mask);
-
-void
-acpi_dm_decode_attribute (
-	u8                      attribute);
-
-/*
- * dmresrcl
- */
-
-void
-acpi_dm_io_flags (
-		u8                  flags);
-
-void
-acpi_dm_memory_flags (
-	u8                      flags,
-	u8                      specific_flags);
-
-void
-acpi_dm_word_descriptor (
-	ASL_WORD_ADDRESS_DESC   *resource,
-	u32                     length,
-	u32                     level);
-
-void
-acpi_dm_dword_descriptor (
-	ASL_DWORD_ADDRESS_DESC  *resource,
-	u32                     length,
-	u32                     level);
-
-void
-acpi_dm_qword_descriptor (
-	ASL_QWORD_ADDRESS_DESC  *resource,
-	u32                     length,
-	u32                     level);
-
-void
-acpi_dm_memory24_descriptor (
-	ASL_MEMORY_24_DESC      *resource,
-	u32                     length,
-	u32                     level);
-
-void
-acpi_dm_memory32_descriptor (
-	ASL_MEMORY_32_DESC      *resource,
-	u32                     length,
-	u32                     level);
-
-void
-acpi_dm_fixed_mem32_descriptor (
-	ASL_FIXED_MEMORY_32_DESC *resource,
-	u32                     length,
-	u32                     level);
-
-void
-acpi_dm_generic_register_descriptor (
-	ASL_GENERAL_REGISTER_DESC *resource,
-	u32                     length,
-	u32                     level);
-
-void
-acpi_dm_interrupt_descriptor (
-	ASL_EXTENDED_XRUPT_DESC *resource,
-	u32                     length,
-	u32                     level);
-
-void
-acpi_dm_vendor_large_descriptor (
-	ASL_LARGE_VENDOR_DESC   *resource,
-	u32                     length,
-	u32                     level);
-
-
-/*
- * dmresrcs
- */
-
-void
-acpi_dm_irq_descriptor (
-	ASL_IRQ_FORMAT_DESC     *resource,
-	u32                     length,
-	u32                     level);
-
-void
-acpi_dm_dma_descriptor (
-	ASL_DMA_FORMAT_DESC     *resource,
-	u32                     length,
-	u32                     level);
-
-void
-acpi_dm_io_descriptor (
-	ASL_IO_PORT_DESC        *resource,
-	u32                     length,
-	u32                     level);
-
-void
-acpi_dm_fixed_io_descriptor (
-	ASL_FIXED_IO_PORT_DESC  *resource,
-	u32                     length,
-	u32                     level);
-
-void
-acpi_dm_start_dependent_descriptor (
-	ASL_START_DEPENDENT_DESC *resource,
-	u32                     length,
-	u32                     level);
-
-void
-acpi_dm_end_dependent_descriptor (
-	ASL_START_DEPENDENT_DESC *resource,
-	u32                     length,
-	u32                     level);
-
-void
-acpi_dm_vendor_small_descriptor (
-	ASL_SMALL_VENDOR_DESC   *resource,
-	u32                     length,
-	u32                     level);
-
-
-#endif  /* __ACDISASM_H__ */
diff -Nru a/drivers/acpi/include/acexcep.h b/drivers/acpi/include/acexcep.h
--- a/drivers/acpi/include/acexcep.h	Mon Dec  9 18:46:34 2002
+++ b/drivers/acpi/include/acexcep.h	Mon Dec  9 18:46:34 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acexcep.h - Exception codes returned by the ACPI subsystem
- *       $Revision: 64 $
+ *       $Revision: 65 $
  *
  *****************************************************************************/
 
@@ -75,8 +75,9 @@
 #define AE_NO_HARDWARE_RESPONSE         (acpi_status) (0x0019 | AE_CODE_ENVIRONMENTAL)
 #define AE_NO_GLOBAL_LOCK               (acpi_status) (0x001A | AE_CODE_ENVIRONMENTAL)
 #define AE_LOGICAL_ADDRESS              (acpi_status) (0x001B | AE_CODE_ENVIRONMENTAL)
+#define AE_ABORT_METHOD                 (acpi_status) (0x001C | AE_CODE_ENVIRONMENTAL)
 
-#define AE_CODE_ENV_MAX                 0x001B
+#define AE_CODE_ENV_MAX                 0x001C
 
 /*
  * Programmer exceptions
@@ -199,7 +200,8 @@
 	"AE_ALREADY_ACQUIRED",
 	"AE_NO_HARDWARE_RESPONSE",
 	"AE_NO_GLOBAL_LOCK",
-	"AE_LOGICAL_ADDRESS"
+	"AE_LOGICAL_ADDRESS",
+	"AE_ABORT_METHOD"
 };
 
 NATIVE_CHAR const   *acpi_gbl_exception_names_pgm[] =
diff -Nru a/drivers/acpi/include/acglobal.h b/drivers/acpi/include/acglobal.h
--- a/drivers/acpi/include/acglobal.h	Mon Dec  9 18:46:34 2002
+++ b/drivers/acpi/include/acglobal.h	Mon Dec  9 18:46:34 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acglobal.h - Declarations for global variables
- *       $Revision: 132 $
+ *       $Revision: 134 $
  *
  *****************************************************************************/
 
@@ -141,7 +141,7 @@
 extern u8                               acpi_gbl_shutdown;
 extern u32                              acpi_gbl_startup_flags;
 extern const u8                         acpi_gbl_decode_to8bit[8];
-extern const NATIVE_CHAR               *acpi_gbl_db_sleep_states[ACPI_NUM_SLEEP_STATES];
+extern const NATIVE_CHAR               *acpi_gbl_db_sleep_states[ACPI_S_STATE_COUNT];
 extern const acpi_opcode_info           acpi_gbl_aml_op_info[AML_NUM_OPCODES];
 extern const NATIVE_CHAR               *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS];
 
@@ -253,6 +253,7 @@
 #ifdef ACPI_DEBUGGER
 
 extern      u8                          acpi_gbl_method_executing;
+extern      u8                          acpi_gbl_abort_method;
 extern      u8                          acpi_gbl_db_terminate_threads;
 
 ACPI_EXTERN int                         optind;
diff -Nru a/drivers/acpi/include/aclocal.h b/drivers/acpi/include/aclocal.h
--- a/drivers/acpi/include/aclocal.h	Mon Dec  9 18:46:39 2002
+++ b/drivers/acpi/include/aclocal.h	Mon Dec  9 18:46:39 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: aclocal.h - Internal data types used across the ACPI subsystem
- *       $Revision: 181 $
+ *       $Revision: 182 $
  *
  *****************************************************************************/
 
@@ -496,7 +496,7 @@
 typedef struct acpi_result_values
 {
 	ACPI_STATE_COMMON
-	union acpi_operand_obj  *obj_desc [OBJ_NUM_OPERANDS];
+	union acpi_operand_obj  *obj_desc [ACPI_OBJ_NUM_OPERANDS];
 	u8                      num_results;
 	u8                      last_insert;
 
diff -Nru a/drivers/acpi/include/acmacros.h b/drivers/acpi/include/acmacros.h
--- a/drivers/acpi/include/acmacros.h	Mon Dec  9 18:46:38 2002
+++ b/drivers/acpi/include/acmacros.h	Mon Dec  9 18:46:38 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acmacros.h - C macros for the entire subsystem.
- *       $Revision: 130 $
+ *       $Revision: 133 $
  *
  *****************************************************************************/
 
@@ -367,6 +367,8 @@
 												acpi_os_printf ACPI_PARAM_LIST(fp);}
 #define ACPI_REPORT_NSERROR(s,e)            acpi_ns_report_error(_THIS_MODULE,__LINE__,_COMPONENT, s, e);
 
+#define ACPI_REPORT_METHOD_ERROR(s,n,p,e)   acpi_ns_report_method_error(_THIS_MODULE,__LINE__,_COMPONENT, s, n, p, e);
+
 #else
 
 #define ACPI_REPORT_INFO(fp)                {acpi_ut_report_info("ACPI",__LINE__,_COMPONENT); \
@@ -377,6 +379,8 @@
 												acpi_os_printf ACPI_PARAM_LIST(fp);}
 #define ACPI_REPORT_NSERROR(s,e)            acpi_ns_report_error("ACPI",__LINE__,_COMPONENT, s, e);
 
+#define ACPI_REPORT_METHOD_ERROR(s,n,p,e)   acpi_ns_report_method_error("ACPI",__LINE__,_COMPONENT, s, n, p, e);
+
 #endif
 
 /* Error reporting.  These versions pass thru the module and line# */
@@ -394,7 +398,7 @@
 
 #ifdef ACPI_DEBUG_OUTPUT
 
-#define ACPI_MODULE_NAME(name)               static char *_THIS_MODULE = name;
+#define ACPI_MODULE_NAME(name)               static char ACPI_UNUSED_VAR *_THIS_MODULE = name;
 
 /*
  * Function entry tracing.
@@ -454,7 +458,7 @@
 
 #define ACPI_DUMP_ENTRY(a,b)            acpi_ns_dump_entry (a,b)
 #define ACPI_DUMP_TABLES(a,b)           acpi_ns_dump_tables(a,b)
-#define ACPI_DUMP_PATHNAME(a,b,c,d)     (void) acpi_ns_dump_pathname(a,b,c,d)
+#define ACPI_DUMP_PATHNAME(a,b,c,d)     acpi_ns_dump_pathname(a,b,c,d)
 #define ACPI_DUMP_RESOURCE_LIST(a)      acpi_rs_dump_resource_list(a)
 #define ACPI_DUMP_BUFFER(a,b)           acpi_ut_dump_buffer((u8 *)a,b,DB_BYTE_DISPLAY,_COMPONENT)
 #define ACPI_BREAK_MSG(a)               acpi_os_signal (ACPI_SIGNAL_BREAKPOINT,(a))
diff -Nru a/drivers/acpi/include/acnamesp.h b/drivers/acpi/include/acnamesp.h
--- a/drivers/acpi/include/acnamesp.h	Mon Dec  9 18:46:34 2002
+++ b/drivers/acpi/include/acnamesp.h	Mon Dec  9 18:46:34 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acnamesp.h - Namespace subcomponent prototypes and defines
- *       $Revision: 129 $
+ *       $Revision: 131 $
  *
  *****************************************************************************/
 
@@ -210,7 +210,7 @@
 	acpi_handle             handle,
 	u32                     debug_level);
 
-acpi_status
+void
 acpi_ns_dump_pathname (
 	acpi_handle             handle,
 	NATIVE_CHAR             *msg,
@@ -429,6 +429,21 @@
 	u32                     component_id,
 	char                    *internal_name,
 	acpi_status             lookup_status);
+
+void
+acpi_ns_report_method_error (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id,
+	char                    *message,
+	acpi_namespace_node     *node,
+	char                    *path,
+	acpi_status             lookup_status);
+
+void
+acpi_ns_print_node_pathname (
+	acpi_namespace_node     *node,
+	NATIVE_CHAR             *msg);
 
 acpi_status
 acpi_ns_build_internal_name (
diff -Nru a/drivers/acpi/include/acoutput.h b/drivers/acpi/include/acoutput.h
--- a/drivers/acpi/include/acoutput.h	Mon Dec  9 18:46:36 2002
+++ b/drivers/acpi/include/acoutput.h	Mon Dec  9 18:46:36 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acoutput.h -- debug output
- *       $Revision: 90 $
+ *       $Revision: 91 $
  *
  *****************************************************************************/
 
@@ -53,7 +53,6 @@
 #define ACPI_TOOLS                  0x00002000
 
 #define ACPI_ALL_COMPONENTS         0x00003FFF
-
 #define ACPI_COMPONENT_DEFAULT      (ACPI_ALL_COMPONENTS)
 
 
@@ -61,21 +60,20 @@
 
 #define ACPI_ALL_DRIVERS            0xFFFF0000
 
+
 /*
  * Raw debug output levels, do not use these in the DEBUG_PRINT macros
  */
-
-#define ACPI_LV_OK                  0x00000001
-#define ACPI_LV_INFO                0x00000002
-#define ACPI_LV_WARN                0x00000004
-#define ACPI_LV_ERROR               0x00000008
-#define ACPI_LV_FATAL               0x00000010
-#define ACPI_LV_DEBUG_OBJECT        0x00000020
-#define ACPI_LV_ALL_EXCEPTIONS      0x0000003F
-
+#define ACPI_LV_ERROR               0x00000001
+#define ACPI_LV_WARN                0x00000002
+#define ACPI_LV_INIT                0x00000004
+#define ACPI_LV_DEBUG_OBJECT        0x00000008
+#define ACPI_LV_INFO                0x00000010
+#define ACPI_LV_ALL_EXCEPTIONS      0x0000001F
 
 /* Trace verbosity level 1 [Standard Trace Level] */
 
+#define ACPI_LV_INIT_NAMES          0x00000020
 #define ACPI_LV_PARSE               0x00000040
 #define ACPI_LV_LOAD                0x00000080
 #define ACPI_LV_DISPATCH            0x00000100
@@ -89,8 +87,7 @@
 #define ACPI_LV_RESOURCES           0x00010000
 #define ACPI_LV_USER_REQUESTS       0x00020000
 #define ACPI_LV_PACKAGE             0x00040000
-#define ACPI_LV_INIT                0x00080000
-#define ACPI_LV_VERBOSITY1          0x000FFF40 | ACPI_LV_ALL_EXCEPTIONS
+#define ACPI_LV_VERBOSITY1          0x0007FF40 | ACPI_LV_ALL_EXCEPTIONS
 
 /* Trace verbosity level 2 [Function tracing and memory allocation] */
 
@@ -121,22 +118,21 @@
 /*
  * Debug level macros that are used in the DEBUG_PRINT macros
  */
-
 #define ACPI_DEBUG_LEVEL(dl)       dl,__LINE__,&_dbg
 
 /* Exception level -- used in the global "Debug_level" */
 
-#define ACPI_DB_OK                  ACPI_DEBUG_LEVEL (ACPI_LV_OK)
-#define ACPI_DB_INFO                ACPI_DEBUG_LEVEL (ACPI_LV_INFO)
-#define ACPI_DB_WARN                ACPI_DEBUG_LEVEL (ACPI_LV_WARN)
 #define ACPI_DB_ERROR               ACPI_DEBUG_LEVEL (ACPI_LV_ERROR)
-#define ACPI_DB_FATAL               ACPI_DEBUG_LEVEL (ACPI_LV_FATAL)
+#define ACPI_DB_WARN                ACPI_DEBUG_LEVEL (ACPI_LV_WARN)
+#define ACPI_DB_INIT                ACPI_DEBUG_LEVEL (ACPI_LV_INIT)
 #define ACPI_DB_DEBUG_OBJECT        ACPI_DEBUG_LEVEL (ACPI_LV_DEBUG_OBJECT)
+#define ACPI_DB_INFO                ACPI_DEBUG_LEVEL (ACPI_LV_INFO)
 #define ACPI_DB_ALL_EXCEPTIONS      ACPI_DEBUG_LEVEL (ACPI_LV_ALL_EXCEPTIONS)
 
 
 /* Trace level -- also used in the global "Debug_level" */
 
+#define ACPI_DB_INIT_NAMES          ACPI_DEBUG_LEVEL (ACPI_LV_INIT_NAMES)
 #define ACPI_DB_THREADS             ACPI_DEBUG_LEVEL (ACPI_LV_THREADS)
 #define ACPI_DB_PARSE               ACPI_DEBUG_LEVEL (ACPI_LV_PARSE)
 #define ACPI_DB_DISPATCH            ACPI_DEBUG_LEVEL (ACPI_LV_DISPATCH)
@@ -157,23 +153,15 @@
 #define ACPI_DB_USER_REQUESTS       ACPI_DEBUG_LEVEL (ACPI_LV_USER_REQUESTS)
 #define ACPI_DB_PACKAGE             ACPI_DEBUG_LEVEL (ACPI_LV_PACKAGE)
 #define ACPI_DB_MUTEX               ACPI_DEBUG_LEVEL (ACPI_LV_MUTEX)
-#define ACPI_DB_INIT                ACPI_DEBUG_LEVEL (ACPI_LV_INIT)
 
 #define ACPI_DB_ALL                 ACPI_DEBUG_LEVEL (ACPI_LV_ALL)
 
 
 /* Defaults for Debug_level, debug and normal */
 
-#define DEBUG_DEFAULT               (ACPI_LV_OK | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT)
-#define NORMAL_DEFAULT              (ACPI_LV_OK | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT)
-#define DEBUG_ALL                   (ACPI_LV_AML_DISASSEMBLE | ACPI_LV_ALL_EXCEPTIONS | ACPI_LV_ALL)
-
-/* Misc defines */
-
-#define HEX                         0x01
-#define ASCII                       0x02
-#define FULL_ADDRESS                0x04
-#define CHARS_PER_LINE              16          /* used in Dump_buf function */
+#define ACPI_DEBUG_DEFAULT          (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT)
+#define ACPI_NORMAL_DEFAULT         (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT)
+#define ACPI_DEBUG_ALL              (ACPI_LV_AML_DISASSEMBLE | ACPI_LV_ALL_EXCEPTIONS | ACPI_LV_ALL)
 
 
 #endif /* __ACOUTPUT_H__ */
diff -Nru a/drivers/acpi/include/acstruct.h b/drivers/acpi/include/acstruct.h
--- a/drivers/acpi/include/acstruct.h	Mon Dec  9 18:46:34 2002
+++ b/drivers/acpi/include/acstruct.h	Mon Dec  9 18:46:34 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acstruct.h - Internal structs
- *       $Revision: 20 $
+ *       $Revision: 21 $
  *
  *****************************************************************************/
 
@@ -71,16 +71,16 @@
 
 
 	u8                      *aml_last_while;
-	struct acpi_node        arguments[MTH_NUM_ARGS];            /* Control method arguments */
+	struct acpi_node        arguments[ACPI_METHOD_NUM_ARGS];    /* Control method arguments */
 	union acpi_operand_obj  **caller_return_desc;
 	acpi_generic_state      *control_state;                     /* List of control states (nested IFs) */
-	struct acpi_node        local_variables[MTH_NUM_LOCALS];    /* Control method locals */
+	struct acpi_node        local_variables[ACPI_METHOD_NUM_LOCALS];    /* Control method locals */
 	struct acpi_node        *method_call_node;                  /* Called method Node*/
 	acpi_parse_object       *method_call_op;                    /* Method_call Op if running a method */
 	union acpi_operand_obj  *method_desc;                       /* Method descriptor if running a method */
 	struct acpi_node        *method_node;                       /* Method Node if running a method */
 	acpi_parse_object       *op;                                /* Current parser op */
-	union acpi_operand_obj  *operands[OBJ_NUM_OPERANDS+1];      /* Operands passed to the interpreter (+1 for NULL terminator) */
+	union acpi_operand_obj  *operands[ACPI_OBJ_NUM_OPERANDS+1];      /* Operands passed to the interpreter (+1 for NULL terminator) */
 	const acpi_opcode_info  *op_info;                           /* Info on current opcode */
 	acpi_parse_object       *origin;                            /* Start of walk [Obsolete] */
 	union acpi_operand_obj  **params;
diff -Nru a/drivers/acpi/include/actypes.h b/drivers/acpi/include/actypes.h
--- a/drivers/acpi/include/actypes.h	Mon Dec  9 18:46:38 2002
+++ b/drivers/acpi/include/actypes.h	Mon Dec  9 18:46:38 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: actypes.h - Common data types for the entire ACPI subsystem
- *       $Revision: 241 $
+ *       $Revision: 242 $
  *
  *****************************************************************************/
 
@@ -861,11 +861,6 @@
 	u8                          *mapped_logical_address;
 	ACPI_SIZE                   mapped_length;
 } acpi_mem_space_context;
-
-
-/* Sleep states */
-
-#define ACPI_NUM_SLEEP_STATES           7
 
 
 /*
diff -Nru a/drivers/acpi/include/acutils.h b/drivers/acpi/include/acutils.h
--- a/drivers/acpi/include/acutils.h	Mon Dec  9 18:46:34 2002
+++ b/drivers/acpi/include/acutils.h	Mon Dec  9 18:46:34 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acutils.h -- prototypes for the common (subsystem-wide) procedures
- *       $Revision: 148 $
+ *       $Revision: 149 $
  *
  *****************************************************************************/
 
@@ -448,6 +448,13 @@
 
 
 acpi_status
+acpi_ut_evaluate_object (
+	acpi_namespace_node     *prefix_node,
+	NATIVE_CHAR             *path,
+	u32                     expected_return_btypes,
+	acpi_operand_object     **return_desc);
+
+acpi_status
 acpi_ut_evaluate_numeric_object (
 	NATIVE_CHAR             *object_name,
 	acpi_namespace_node     *device_node,
@@ -698,7 +705,8 @@
 #ifdef ACPI_DEBUG_OUTPUT
 void
 acpi_ut_display_init_pathname (
-	acpi_handle             obj_handle,
+	u8                      type,
+	acpi_namespace_node     *obj_handle,
 	char                    *path);
 
 #endif
diff -Nru a/drivers/acpi/include/platform/acgcc.h b/drivers/acpi/include/platform/acgcc.h
--- a/drivers/acpi/include/platform/acgcc.h	Mon Dec  9 18:46:51 2002
+++ b/drivers/acpi/include/platform/acgcc.h	Mon Dec  9 18:46:51 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Name: acgcc.h - GCC specific defines, etc.
- *       $Revision: 23 $
+ *       $Revision: 24 $
  *
  *****************************************************************************/
 
@@ -30,5 +30,12 @@
  * some compilers (like GCC) can catch printf format string problems.
  */
 #define ACPI_PRINTF_LIKE_FUNC __attribute__ ((__format__ (__printf__, 4, 5)))
+
+/* Some compilers complain about unused variables. Sometimes we don't want to
+ * use all the variables (most specifically for _THIS_MODULE). This allow us
+ * to to tell the compiler warning in a per-variable manner that a variable
+ * is unused.
+ */
+#define ACPI_UNUSED_VAR __attribute__ ((unused))
 
 #endif /* __ACGCC_H__ */
diff -Nru a/drivers/acpi/namespace/Makefile b/drivers/acpi/namespace/Makefile
--- a/drivers/acpi/namespace/Makefile	Mon Dec  9 18:46:50 2002
+++ b/drivers/acpi/namespace/Makefile	Mon Dec  9 18:46:50 2002
@@ -4,7 +4,8 @@
 
 obj-y := nsaccess.o  nsdumpdv.o  nsload.o    nssearch.o  nsxfeval.o \
 	 nsalloc.o   nseval.o    nsnames.o   nsutils.o   nsxfname.o \
-	 nsdump.o    nsinit.o    nsobject.o  nswalk.o    nsxfobj.o
+	 nsdump.o    nsinit.o    nsobject.o  nswalk.o    nsxfobj.o  \
+	 nsparse.o
 
 EXTRA_CFLAGS += $(ACPI_CFLAGS)
 
diff -Nru a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c
--- a/drivers/acpi/namespace/nsdump.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/acpi/namespace/nsdump.c	Mon Dec  9 18:46:51 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: nsdump - table dumping routines for debug
- *              $Revision: 146 $
+ *              $Revision: 149 $
  *
  *****************************************************************************/
 
@@ -90,16 +90,13 @@
  *
  ******************************************************************************/
 
-acpi_status
+void
 acpi_ns_dump_pathname (
 	acpi_handle             handle,
 	NATIVE_CHAR             *msg,
 	u32                     level,
 	u32                     component)
 {
-	acpi_buffer             buffer;
-	acpi_status             status;
-
 
 	ACPI_FUNCTION_TRACE ("Ns_dump_pathname");
 
@@ -107,20 +104,14 @@
 	/* Do this only if the requested debug level and component are enabled */
 
 	if (!(acpi_dbg_level & level) || !(acpi_dbg_layer & component)) {
-		return_ACPI_STATUS (AE_OK);
+		return_VOID;
 	}
 
 	/* Convert handle to a full pathname and print it (with supplied message) */
 
-	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
-
-	status = acpi_ns_handle_to_pathname (handle, &buffer);
-	if (ACPI_SUCCESS (status)) {
-		acpi_os_printf ("%s %s (Node %p)\n", msg, (char *) buffer.pointer, handle);
-		ACPI_MEM_FREE (buffer.pointer);
-	}
-
-	return_ACPI_STATUS (status);
+	acpi_ns_print_node_pathname (handle, msg);
+	acpi_os_printf ("\n");
+	return_VOID;
 }
 
 
diff -Nru a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c
--- a/drivers/acpi/namespace/nsinit.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/acpi/namespace/nsinit.c	Mon Dec  9 18:46:36 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: nsinit - namespace initialization
- *              $Revision: 50 $
+ *              $Revision: 52 $
  *
  *****************************************************************************/
 
@@ -59,7 +59,7 @@
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
 		"**** Starting initialization of namespace objects ****\n"));
-	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, "Completing Region/Field/Buffer/Package initialization:"));
+	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "Completing Region/Field/Buffer/Package initialization:"));
 
 	/* Set all init info to zero */
 
@@ -75,12 +75,13 @@
 			acpi_format_exception (status)));
 	}
 
-	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK,
+	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
 		"\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd Buffers %hd/%hd Packages (%hd nodes)\n",
 		info.op_region_init, info.op_region_count,
 		info.field_init,    info.field_count,
 		info.buffer_init,   info.buffer_count,
 		info.package_init,  info.package_count, info.object_count));
+
 	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
 		"%hd Control Methods found\n", info.method_count));
 	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
@@ -123,7 +124,7 @@
 	info.num_STA = 0;
 	info.num_INI = 0;
 
-	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, "Executing all Device _STA and_INI methods:"));
+	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "Executing all Device _STA and_INI methods:"));
 
 	/* Walk namespace for all objects of type Device */
 
@@ -135,7 +136,7 @@
 			acpi_format_exception (status)));
 	}
 
-	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK,
+	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
 		"\n%hd Devices found containing: %hd _STA, %hd _INI methods\n",
 		info.device_count, info.num_STA, info.num_INI));
 
@@ -274,8 +275,10 @@
 				node->name.ascii, acpi_ut_get_type_name (type), acpi_format_exception (status)));
 	}
 
-	if (!(acpi_dbg_level & ACPI_LV_INIT)) {
-		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, "."));
+	/* Print a dot for each object unless we are going to print the entire pathname */
+
+	if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
+		acpi_os_printf (".");
 	}
 
 	/*
@@ -318,7 +321,7 @@
 
 
 	if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) && (!(acpi_dbg_level & ACPI_LV_INFO))) {
-		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, "."));
+		acpi_os_printf (".");
 	}
 
 	info->device_count++;
@@ -342,7 +345,7 @@
 	/*
 	 * Run _STA to determine if we can run _INI on the device.
 	 */
-	ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (node, "_STA [Method]"));
+	ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, node, "_STA"));
 	status = acpi_ut_execute_STA (node, &flags);
 	if (ACPI_FAILURE (status)) {
 		/* Ignore error and move on to next device */
@@ -361,7 +364,7 @@
 	/*
 	 * The device is present. Run _INI.
 	 */
-	ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (obj_handle, "_INI [Method]"));
+	ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, obj_handle, "_INI"));
 	status = acpi_ns_evaluate_relative (obj_handle, "_INI", NULL, NULL);
 	if (ACPI_FAILURE (status)) {
 		/* No _INI (AE_NOT_FOUND) means device requires no initialization */
diff -Nru a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c
--- a/drivers/acpi/namespace/nsload.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/acpi/namespace/nsload.c	Mon Dec  9 18:46:51 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: nsload - namespace loading/expanding/contracting procedures
- *              $Revision: 59 $
+ *              $Revision: 61 $
  *
  *****************************************************************************/
 
@@ -34,122 +34,6 @@
 	 ACPI_MODULE_NAME    ("nsload")
 
 
-/*******************************************************************************
- *
- * FUNCTION:    Ns_one_complete_parse
- *
- * PARAMETERS:  Pass_number             - 1 or 2
- *              Table_desc              - The table to be parsed.
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Perform one complete parse of an ACPI/AML table.
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ns_one_complete_parse (
-	u32                     pass_number,
-	acpi_table_desc         *table_desc)
-{
-	acpi_parse_object       *parse_root;
-	acpi_status             status;
-	acpi_walk_state         *walk_state;
-
-
-	ACPI_FUNCTION_TRACE ("Ns_one_complete_parse");
-
-
-	/* Create and init a Root Node */
-
-	parse_root = acpi_ps_create_scope_op ();
-	if (!parse_root) {
-		return_ACPI_STATUS (AE_NO_MEMORY);
-	}
-
-
-	/* Create and initialize a new walk state */
-
-	walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT,
-			   NULL, NULL, NULL);
-	if (!walk_state) {
-		acpi_ps_free_op (parse_root);
-		return_ACPI_STATUS (AE_NO_MEMORY);
-	}
-
-	status = acpi_ds_init_aml_walk (walk_state, parse_root, NULL, table_desc->aml_start,
-			  table_desc->aml_length, NULL, NULL, pass_number);
-	if (ACPI_FAILURE (status)) {
-		acpi_ds_delete_walk_state (walk_state);
-		return_ACPI_STATUS (status);
-	}
-
-	/* Parse the AML */
-
-	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "*PARSE* pass %d parse\n", pass_number));
-	status = acpi_ps_parse_aml (walk_state);
-
-	acpi_ps_delete_parse_tree (parse_root);
-	return_ACPI_STATUS (status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    Acpi_ns_parse_table
- *
- * PARAMETERS:  Table_desc      - An ACPI table descriptor for table to parse
- *              Start_node      - Where to enter the table into the namespace
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Parse AML within an ACPI table and return a tree of ops
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ns_parse_table (
-	acpi_table_desc         *table_desc,
-	acpi_namespace_node     *start_node)
-{
-	acpi_status             status;
-
-
-	ACPI_FUNCTION_TRACE ("Ns_parse_table");
-
-
-	/*
-	 * AML Parse, pass 1
-	 *
-	 * In this pass, we load most of the namespace.  Control methods
-	 * are not parsed until later.  A parse tree is not created.  Instead,
-	 * each Parser Op subtree is deleted when it is finished.  This saves
-	 * a great deal of memory, and allows a small cache of parse objects
-	 * to service the entire parse.  The second pass of the parse then
-	 * performs another complete parse of the AML..
-	 */
-	status = acpi_ns_one_complete_parse (1, table_desc);
-	if (ACPI_FAILURE (status)) {
-		return_ACPI_STATUS (status);
-	}
-
-	/*
-	 * AML Parse, pass 2
-	 *
-	 * In this pass, we resolve forward references and other things
-	 * that could not be completed during the first pass.
-	 * Another complete parse of the AML is performed, but the
-	 * overhead of this is compensated for by the fact that the
-	 * parse objects are all cached.
-	 */
-	status = acpi_ns_one_complete_parse (2, table_desc);
-	if (ACPI_FAILURE (status)) {
-		return_ACPI_STATUS (status);
-	}
-
-	return_ACPI_STATUS (status);
-}
-
 #ifndef ACPI_NO_METHOD_EXECUTION
 
 /*******************************************************************************
@@ -411,7 +295,7 @@
 	(void) acpi_ns_load_table_by_type (ACPI_TABLE_SSDT);
 	(void) acpi_ns_load_table_by_type (ACPI_TABLE_PSDT);
 
-	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK,
+	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
 		"ACPI Namespace successfully loaded at root %p\n",
 		acpi_gbl_root_node));
 
diff -Nru a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c
--- a/drivers/acpi/namespace/nsnames.c	Mon Dec  9 18:46:52 2002
+++ b/drivers/acpi/namespace/nsnames.c	Mon Dec  9 18:46:52 2002
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: nsnames - Name manipulation and search
- *              $Revision: 79 $
+ *              $Revision: 80 $
  *
  ******************************************************************************/
 
@@ -86,7 +86,7 @@
 		/* Prefix name with the path separator */
 
 		index--;
-		name_buffer[index] = PATH_SEPARATOR;
+		name_buffer[index] = ACPI_PATH_SEPARATOR;
 	}
 
 	/* Overwrite final separator with the root prefix character */
@@ -180,7 +180,7 @@
 	next_node = node;
 
 	while (next_node && (next_node != acpi_gbl_root_node)) {
-		size += PATH_SEGMENT_LENGTH;
+		size += ACPI_PATH_SEGMENT_LENGTH;
 		next_node = acpi_ns_get_parent_node (next_node);
 	}
 
diff -Nru a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/acpi/namespace/nsparse.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,153 @@
+/******************************************************************************
+ *
+ * Module Name: nsparse - namespace interface to AML parser
+ *              $Revision: 1 $
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2002, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acnamesp.h"
+#include "acparser.h"
+#include "acdispat.h"
+
+
+#define _COMPONENT          ACPI_NAMESPACE
+	 ACPI_MODULE_NAME    ("nsparse")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Ns_one_complete_parse
+ *
+ * PARAMETERS:  Pass_number             - 1 or 2
+ *              Table_desc              - The table to be parsed.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Perform one complete parse of an ACPI/AML table.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_one_complete_parse (
+	u32                     pass_number,
+	acpi_table_desc         *table_desc)
+{
+	acpi_parse_object       *parse_root;
+	acpi_status             status;
+	acpi_walk_state         *walk_state;
+
+
+	ACPI_FUNCTION_TRACE ("Ns_one_complete_parse");
+
+
+	/* Create and init a Root Node */
+
+	parse_root = acpi_ps_create_scope_op ();
+	if (!parse_root) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+
+	/* Create and initialize a new walk state */
+
+	walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT,
+			   NULL, NULL, NULL);
+	if (!walk_state) {
+		acpi_ps_free_op (parse_root);
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	status = acpi_ds_init_aml_walk (walk_state, parse_root, NULL, table_desc->aml_start,
+			  table_desc->aml_length, NULL, NULL, pass_number);
+	if (ACPI_FAILURE (status)) {
+		acpi_ds_delete_walk_state (walk_state);
+		return_ACPI_STATUS (status);
+	}
+
+	/* Parse the AML */
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "*PARSE* pass %d parse\n", pass_number));
+	status = acpi_ps_parse_aml (walk_state);
+
+	acpi_ps_delete_parse_tree (parse_root);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ns_parse_table
+ *
+ * PARAMETERS:  Table_desc      - An ACPI table descriptor for table to parse
+ *              Start_node      - Where to enter the table into the namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Parse AML within an ACPI table and return a tree of ops
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_parse_table (
+	acpi_table_desc         *table_desc,
+	acpi_namespace_node     *start_node)
+{
+	acpi_status             status;
+
+
+	ACPI_FUNCTION_TRACE ("Ns_parse_table");
+
+
+	/*
+	 * AML Parse, pass 1
+	 *
+	 * In this pass, we load most of the namespace.  Control methods
+	 * are not parsed until later.  A parse tree is not created.  Instead,
+	 * each Parser Op subtree is deleted when it is finished.  This saves
+	 * a great deal of memory, and allows a small cache of parse objects
+	 * to service the entire parse.  The second pass of the parse then
+	 * performs another complete parse of the AML..
+	 */
+	status = acpi_ns_one_complete_parse (1, table_desc);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * AML Parse, pass 2
+	 *
+	 * In this pass, we resolve forward references and other things
+	 * that could not be completed during the first pass.
+	 * Another complete parse of the AML is performed, but the
+	 * overhead of this is compensated for by the fact that the
+	 * parse objects are all cached.
+	 */
+	status = acpi_ns_one_complete_parse (2, table_desc);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	return_ACPI_STATUS (status);
+}
+
+
diff -Nru a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c
--- a/drivers/acpi/namespace/nsutils.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/acpi/namespace/nsutils.c	Mon Dec  9 18:46:37 2002
@@ -2,7 +2,7 @@
  *
  * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
  *                        parents and siblings and Scope manipulation
- *              $Revision: 116 $
+ *              $Revision: 118 $
  *
  *****************************************************************************/
 
@@ -88,6 +88,82 @@
 
 /*******************************************************************************
  *
+ * FUNCTION:    Acpi_ns_report_method_error
+ *
+ * PARAMETERS:  Module_name         - Caller's module name (for error output)
+ *              Line_number         - Caller's line number (for error output)
+ *              Component_id        - Caller's component ID (for error output)
+ *              Message             - Error message to use on failure
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print warning message with full pathname
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_report_method_error (
+	NATIVE_CHAR             *module_name,
+	u32                     line_number,
+	u32                     component_id,
+	char                    *message,
+	acpi_namespace_node     *prefix_node,
+	char                    *path,
+	acpi_status             method_status)
+{
+	acpi_status             status;
+	acpi_namespace_node     *node = prefix_node;
+
+
+	if (path) {
+		status = acpi_ns_get_node_by_path (path, prefix_node, ACPI_NS_NO_UPSEARCH, &node);
+		if (ACPI_FAILURE (status)) {
+			acpi_os_printf ("Report_method_error: Could not get node\n");
+			return;
+		}
+	}
+
+	acpi_os_printf ("%8s-%04d: *** Error: ", module_name, line_number);
+	acpi_ns_print_node_pathname (node, message);
+	acpi_os_printf (", %s\n", acpi_format_exception (method_status));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ns_print_node_pathname
+ *
+ * PARAMETERS:  Node                - Object
+ *              Msg                 - Prefix message
+ *
+ * DESCRIPTION: Print an object's full namespace pathname
+ *              Manages allocation/freeing of a pathname buffer
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_print_node_pathname (
+	acpi_namespace_node     *node,
+	NATIVE_CHAR             *msg)
+{
+	acpi_buffer             buffer;
+	acpi_status             status;
+
+
+	/* Convert handle to a full pathname and print it (with supplied message) */
+
+	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+
+	status = acpi_ns_handle_to_pathname (node, &buffer);
+	if (ACPI_SUCCESS (status)) {
+		acpi_os_printf ("%s [%s] (Node %p)", msg, (char *) buffer.pointer, node);
+		ACPI_MEM_FREE (buffer.pointer);
+	}
+}
+
+
+/*******************************************************************************
+ *
  * FUNCTION:    Acpi_ns_valid_root_prefix
  *
  * PARAMETERS:  Prefix          - Character to be checked
@@ -802,15 +878,13 @@
 	ACPI_FUNCTION_TRACE_PTR ("Ns_get_node_by_path", pathname);
 
 
-	if (!pathname) {
-		return_ACPI_STATUS (AE_BAD_PARAMETER);
-	}
+	if (pathname) {
+		/* Convert path to internal representation */
 
-	/* Convert path to internal representation */
-
-	status = acpi_ns_internalize_name (pathname, &internal_path);
-	if (ACPI_FAILURE (status)) {
-		return_ACPI_STATUS (status);
+		status = acpi_ns_internalize_name (pathname, &internal_path);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
 	}
 
 	/* Must lock namespace during lookup */
@@ -838,7 +912,10 @@
 	/* Cleanup */
 
 	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
-	ACPI_MEM_FREE (internal_path);
+
+	if (internal_path) {
+		ACPI_MEM_FREE (internal_path);
+	}
 	return_ACPI_STATUS (status);
 }
 
diff -Nru a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c
--- a/drivers/acpi/namespace/nsxfname.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/acpi/namespace/nsxfname.c	Mon Dec  9 18:46:35 2002
@@ -2,7 +2,7 @@
  *
  * Module Name: nsxfname - Public interfaces to the ACPI subsystem
  *                         ACPI Namespace oriented interfaces
- *              $Revision: 91 $
+ *              $Revision: 92 $
  *
  *****************************************************************************/
 
@@ -173,7 +173,7 @@
 
 	/* Validate/Allocate/Clear caller buffer */
 
-	status = acpi_ut_initialize_buffer (buffer, PATH_SEGMENT_LENGTH);
+	status = acpi_ut_initialize_buffer (buffer, ACPI_PATH_SEGMENT_LENGTH);
 	if (ACPI_FAILURE (status)) {
 		goto unlock_and_exit;
 	}
diff -Nru a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c
--- a/drivers/acpi/namespace/nsxfobj.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/acpi/namespace/nsxfobj.c	Mon Dec  9 18:46:34 2002
@@ -141,7 +141,7 @@
 	*ret_handle =
 		acpi_ns_convert_entry_to_handle (acpi_ns_get_parent_node (node));
 
-	/* Return exception if parent is null */
+	/* Return exeption if parent is null */
 
 	if (!acpi_ns_get_parent_node (node)) {
 		status = AE_NULL_ENTRY;
diff -Nru a/drivers/acpi/osl.c b/drivers/acpi/osl.c
--- a/drivers/acpi/osl.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/acpi/osl.c	Mon Dec  9 18:46:50 2002
@@ -484,7 +484,7 @@
 	return (result ? AE_ERROR : AE_OK);
 }
 
-/* TODO: Rewrite this code!!! */
+/* TODO: Change code to take advantage of driver model more */
 void
 acpi_os_derive_pci_id (
 	acpi_handle     rhandle,        /* upper bound  */
@@ -650,7 +650,7 @@
 		task = (void *)(dpc+1);
 		INIT_WORK(task, acpi_os_schedule_exec, (void*)dpc);
 
-		if (schedule_work(task) < 0) {
+		if (!schedule_work(task)) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Call to schedule_work() failed.\n"));
 			kfree(dpc);
 			status = AE_ERROR;
diff -Nru a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c
--- a/drivers/acpi/parser/psparse.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/acpi/parser/psparse.c	Mon Dec  9 18:46:35 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: psparse - Parser top level AML parse routines
- *              $Revision: 135 $
+ *              $Revision: 137 $
  *
  *****************************************************************************/
 
@@ -1099,10 +1099,8 @@
 			status = AE_OK;
 		}
 		else if (status != AE_OK) {
-			ACPI_REPORT_ERROR (("Method execution failed, %s\n",
-				acpi_format_exception (status)));
-			ACPI_DUMP_PATHNAME (walk_state->method_node, "Method pathname: ",
-				ACPI_LV_ERROR, _COMPONENT);
+			ACPI_REPORT_METHOD_ERROR ("Method execution failed",
+				walk_state->method_node, NULL, status);
 		}
 
 		/* We are done with this walk, move on to the parent if any */
diff -Nru a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c
--- a/drivers/acpi/pci_bind.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/acpi/pci_bind.c	Mon Dec  9 18:46:50 2002
@@ -124,8 +124,8 @@
 	acpi_status		status = AE_OK;
 	struct acpi_pci_data	*data = NULL;
 	struct acpi_pci_data	*pdata = NULL;
-	char			pathname[PATHNAME_MAX] = {0};
-	acpi_buffer		buffer = {PATHNAME_MAX, pathname};
+	char			pathname[ACPI_PATHNAME_MAX] = {0};
+	acpi_buffer		buffer = {ACPI_PATHNAME_MAX, pathname};
 	acpi_handle		handle = NULL;
 
 	ACPI_FUNCTION_TRACE("acpi_pci_bind");
@@ -267,8 +267,8 @@
 	int			result = 0;
 	acpi_status		status = AE_OK;
 	struct acpi_pci_data	*data = NULL;
-	char			pathname[PATHNAME_MAX] = {0};
-	acpi_buffer		buffer = {PATHNAME_MAX, pathname};
+	char			pathname[ACPI_PATHNAME_MAX] = {0};
+	acpi_buffer		buffer = {ACPI_PATHNAME_MAX, pathname};
 
 	ACPI_FUNCTION_TRACE("acpi_pci_bind_root");
 
diff -Nru a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
--- a/drivers/acpi/pci_irq.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/acpi/pci_irq.c	Mon Dec  9 18:46:36 2002
@@ -158,7 +158,7 @@
 	int			bus)
 {
 	acpi_status		status = AE_OK;
-	char			pathname[PATHNAME_MAX] = {0};
+	char			pathname[ACPI_PATHNAME_MAX] = {0};
 	acpi_buffer		buffer = {0, NULL};
 	acpi_pci_routing_table	*prt = NULL;
 	acpi_pci_routing_table	*entry = NULL;
@@ -346,9 +346,13 @@
 	 */
 	if (!irq) {
 		printk(KERN_WARNING PREFIX "No IRQ known for interrupt pin %c of device %s", ('A' + pin), dev->slot_name);
-		if (dev->irq) 
+		/* Interrupt Line values above 0xF are forbidden */
+		if (dev->irq && dev->irq >= 0xF) {
 			printk(" - using IRQ %d\n", dev->irq);
-		return_VALUE(dev->irq);
+			return_VALUE(dev->irq);
+		}
+		else
+			return_VALUE(0);
  	}
 
 	dev->irq = irq;
diff -Nru a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c
--- a/drivers/acpi/resources/rscalc.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/acpi/resources/rscalc.c	Mon Dec  9 18:46:38 2002
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: rscalc - Calculate stream and list lengths
- *              $Revision: 44 $
+ *              $Revision: 45 $
  *
  ******************************************************************************/
 
@@ -791,10 +791,10 @@
 		if (name_found) {
 			if (ACPI_GET_OBJECT_TYPE (*sub_object_list) == ACPI_TYPE_STRING) {
 				/*
-				 * The length String.Length field includes the
-				 * terminating NULL
+				 * The length String.Length field does not include the
+				 * terminating NULL, add 1
 				 */
-				temp_size_needed += (*sub_object_list)->string.length;
+				temp_size_needed += ((*sub_object_list)->string.length + 1);
 			}
 			else {
 				temp_size_needed += acpi_ns_get_pathname_length (
diff -Nru a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c
--- a/drivers/acpi/resources/rscreate.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/acpi/resources/rscreate.c	Mon Dec  9 18:46:36 2002
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: rscreate - Create resource lists/tables
- *              $Revision: 61 $
+ *              $Revision: 62 $
  *
  ******************************************************************************/
 
@@ -286,9 +286,9 @@
 
 			ACPI_STRCPY (user_prt->source, obj_desc->string.pointer);
 
-			/* Add to the Length field the length of the string */
+			/* Add to the Length field the length of the string (add 1 for terminator) */
 
-			user_prt->length += obj_desc->string.length;
+			user_prt->length += obj_desc->string.length + 1;
 			break;
 
 
diff -Nru a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c
--- a/drivers/acpi/resources/rsutils.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/acpi/resources/rsutils.c	Mon Dec  9 18:46:34 2002
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: rsutils - Utilities for the resource manager
- *              $Revision: 33 $
+ *              $Revision: 34 $
  *
  ******************************************************************************/
 
@@ -66,32 +66,13 @@
 	/* Parameters guaranteed valid by caller */
 
 	/*
-	 *  Execute the method, no parameters
+	 * Execute the method, no parameters
 	 */
-	status = acpi_ns_evaluate_relative (handle, "_PRT", NULL, &obj_desc);
+	status = acpi_ut_evaluate_object (handle, "_PRT", ACPI_BTYPE_PACKAGE, &obj_desc);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
 
-	if (!obj_desc) {
-		/* Return object is required */
-
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from _PRT\n"));
-		return_ACPI_STATUS (AE_TYPE);
-	}
-
-	/*
-	 * The return object must be a package, so check the parameters.  If the
-	 * return object is not a package, then the underlying AML code is corrupt
-	 * or improperly written.
-	 */
-	if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_PACKAGE) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "_PRT did not return a Package, returned %s\n",
-				acpi_ut_get_object_type_name (obj_desc)));
-		status = AE_AML_OPERAND_TYPE;
-		goto cleanup;
-	}
-
 	/*
 	 * Create a resource linked list from the byte stream buffer that comes
 	 * back from the _CRS method execution.
@@ -100,8 +81,6 @@
 
 	/* On exit, we must delete the object returned by Evaluate_object */
 
-cleanup:
-
 	acpi_ut_remove_reference (obj_desc);
 	return_ACPI_STATUS (status);
 }
@@ -142,31 +121,11 @@
 	/*
 	 * Execute the method, no parameters
 	 */
-	status = acpi_ns_evaluate_relative (handle, "_CRS", NULL, &obj_desc);
+	status = acpi_ut_evaluate_object (handle, "_CRS", ACPI_BTYPE_BUFFER, &obj_desc);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
 
-	if (!obj_desc) {
-		/* Return object is required */
-
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from _CRS\n"));
-		return_ACPI_STATUS (AE_TYPE);
-	}
-
-	/*
-	 * The return object will be a buffer, but check the
-	 * parameters.  If the return object is not a buffer,
-	 * then the underlying AML code is corrupt or improperly
-	 * written.
-	 */
-	if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_BUFFER) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "_CRS did not return a Buffer, returned %s\n",
-				acpi_ut_get_object_type_name (obj_desc)));
-		status = AE_AML_OPERAND_TYPE;
-		goto cleanup;
-	}
-
 	/*
 	 * Make the call to create a resource linked list from the
 	 * byte stream buffer that comes back from the _CRS method
@@ -176,8 +135,6 @@
 
 	/* On exit, we must delete the object returned by evaluate_object */
 
-cleanup:
-
 	acpi_ut_remove_reference (obj_desc);
 	return_ACPI_STATUS (status);
 }
@@ -218,31 +175,11 @@
 	/*
 	 * Execute the method, no parameters
 	 */
-	status = acpi_ns_evaluate_relative (handle, "_PRS", NULL, &obj_desc);
+	status = acpi_ut_evaluate_object (handle, "_PRS", ACPI_BTYPE_BUFFER, &obj_desc);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
 
-	if (!obj_desc) {
-		/* Return object is required */
-
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from _PRS\n"));
-		return_ACPI_STATUS (AE_TYPE);
-	}
-
-	/*
-	 * The return object will be a buffer, but check the
-	 * parameters.  If the return object is not a buffer,
-	 * then the underlying AML code is corrupt or improperly
-	 * written..
-	 */
-	if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_BUFFER) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "_PRS did not return a Buffer, returned %s\n",
-				acpi_ut_get_object_type_name (obj_desc)));
-		status = AE_AML_OPERAND_TYPE;
-		goto cleanup;
-	}
-
 	/*
 	 * Make the call to create a resource linked list from the
 	 * byte stream buffer that comes back from the _CRS method
@@ -251,8 +188,6 @@
 	status = acpi_rs_create_resource_list (obj_desc, ret_buffer);
 
 	/* On exit, we must delete the object returned by evaluate_object */
-
-cleanup:
 
 	acpi_ut_remove_reference (obj_desc);
 	return_ACPI_STATUS (status);
diff -Nru a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
--- a/drivers/acpi/tables/tbxface.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/acpi/tables/tbxface.c	Mon Dec  9 18:46:51 2002
@@ -2,7 +2,7 @@
  *
  * Module Name: tbxface - Public interfaces to the ACPI subsystem
  *                         ACPI table oriented interfaces
- *              $Revision: 59 $
+ *              $Revision: 60 $
  *
  *****************************************************************************/
 
@@ -96,7 +96,7 @@
 		goto error_exit;
 	}
 
-	ACPI_DEBUG_PRINT ((ACPI_DB_OK, "ACPI Tables successfully acquired\n"));
+	ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI Tables successfully acquired\n"));
 
 
 	/* Load the namespace from the tables */
diff -Nru a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c
--- a/drivers/acpi/tables/tbxfroot.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/acpi/tables/tbxfroot.c	Mon Dec  9 18:46:50 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: tbxfroot - Find the root ACPI table (RSDT)
- *              $Revision: 65 $
+ *              $Revision: 66 $
  *
  *****************************************************************************/
 
@@ -342,7 +342,7 @@
 
 	for (offset = 0, mem_rover = start_address;
 		 offset < length;
-		 offset += RSDP_SCAN_STEP, mem_rover += RSDP_SCAN_STEP) {
+		 offset += ACPI_RSDP_SCAN_STEP, mem_rover += ACPI_RSDP_SCAN_STEP) {
 
 		/* The signature and checksum must both be correct */
 
@@ -404,21 +404,21 @@
 		/*
 		 * 1) Search EBDA (low memory) paragraphs
 		 */
-		status = acpi_os_map_memory ((u64) LO_RSDP_WINDOW_BASE, LO_RSDP_WINDOW_SIZE,
+		status = acpi_os_map_memory ((u64) ACPI_LO_RSDP_WINDOW_BASE, ACPI_LO_RSDP_WINDOW_SIZE,
 				  (void **) &table_ptr);
 		if (ACPI_FAILURE (status)) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %X for length %X\n",
-				LO_RSDP_WINDOW_BASE, LO_RSDP_WINDOW_SIZE));
+				ACPI_LO_RSDP_WINDOW_BASE, ACPI_LO_RSDP_WINDOW_SIZE));
 			return_ACPI_STATUS (status);
 		}
 
-		mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, LO_RSDP_WINDOW_SIZE);
-		acpi_os_unmap_memory (table_ptr, LO_RSDP_WINDOW_SIZE);
+		mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, ACPI_LO_RSDP_WINDOW_SIZE);
+		acpi_os_unmap_memory (table_ptr, ACPI_LO_RSDP_WINDOW_SIZE);
 
 		if (mem_rover) {
 			/* Found it, return the physical address */
 
-			phys_addr = LO_RSDP_WINDOW_BASE;
+			phys_addr = ACPI_LO_RSDP_WINDOW_BASE;
 			phys_addr += ACPI_PTR_DIFF (mem_rover,table_ptr);
 
 			table_info->physical_address = phys_addr;
@@ -428,21 +428,21 @@
 		/*
 		 * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h
 		 */
-		status = acpi_os_map_memory ((u64) HI_RSDP_WINDOW_BASE, HI_RSDP_WINDOW_SIZE,
+		status = acpi_os_map_memory ((u64) ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE,
 				  (void **) &table_ptr);
 		if (ACPI_FAILURE (status)) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %X for length %X\n",
-				HI_RSDP_WINDOW_BASE, HI_RSDP_WINDOW_SIZE));
+				ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE));
 			return_ACPI_STATUS (status);
 		}
 
-		mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, HI_RSDP_WINDOW_SIZE);
-		acpi_os_unmap_memory (table_ptr, HI_RSDP_WINDOW_SIZE);
+		mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
+		acpi_os_unmap_memory (table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
 
 		if (mem_rover) {
 			/* Found it, return the physical address */
 
-			phys_addr = HI_RSDP_WINDOW_BASE;
+			phys_addr = ACPI_HI_RSDP_WINDOW_BASE;
 			phys_addr += ACPI_PTR_DIFF (mem_rover, table_ptr);
 
 			table_info->physical_address = phys_addr;
@@ -457,8 +457,8 @@
 		/*
 		 * 1) Search EBDA (low memory) paragraphs
 		 */
-		mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (LO_RSDP_WINDOW_BASE),
-				  LO_RSDP_WINDOW_SIZE);
+		mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (ACPI_LO_RSDP_WINDOW_BASE),
+				  ACPI_LO_RSDP_WINDOW_SIZE);
 		if (mem_rover) {
 			/* Found it, return the physical address */
 
@@ -469,8 +469,8 @@
 		/*
 		 * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h
 		 */
-		mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (HI_RSDP_WINDOW_BASE),
-				  HI_RSDP_WINDOW_SIZE);
+		mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (ACPI_HI_RSDP_WINDOW_BASE),
+				  ACPI_HI_RSDP_WINDOW_SIZE);
 		if (mem_rover) {
 			/* Found it, return the physical address */
 
diff -Nru a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c
--- a/drivers/acpi/utilities/utalloc.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/acpi/utilities/utalloc.c	Mon Dec  9 18:46:34 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: utalloc - local cache and memory allocation routines
- *              $Revision: 127 $
+ *              $Revision: 128 $
  *
  *****************************************************************************/
 
@@ -968,11 +968,11 @@
 	/* Print summary */
 
 	if (!num_outstanding) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_OK,
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 			"No outstanding allocations.\n"));
 	}
 	else {
-		ACPI_DEBUG_PRINT ((ACPI_DB_OK,
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 			"%d(%X) Outstanding allocations\n",
 			num_outstanding, num_outstanding));
 	}
diff -Nru a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c
--- a/drivers/acpi/utilities/utcopy.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/acpi/utilities/utcopy.c	Mon Dec  9 18:46:36 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: utcopy - Internal to external object translation utilities
- *              $Revision: 106 $
+ *              $Revision: 107 $
  *
  *****************************************************************************/
 
@@ -625,8 +625,23 @@
 		dest_desc->buffer.node = NULL;
 		dest_desc->common.flags = source_desc->common.flags;
 
-		/* Fall through to common string/buffer case */
-		/*lint -fallthrough */
+		/*
+		 * Allocate and copy the actual buffer if and only if:
+		 * 1) There is a valid buffer (length > 0)
+		 * 2) The buffer is not static (not in an ACPI table) (in this case,
+		 *    the actual pointer was already copied above)
+		 */
+		if ((source_desc->buffer.length) &&
+			(!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
+			dest_desc->buffer.pointer = ACPI_MEM_ALLOCATE (source_desc->buffer.length);
+			if (!dest_desc->buffer.pointer) {
+				return (AE_NO_MEMORY);
+			}
+
+			ACPI_MEMCPY (dest_desc->buffer.pointer, source_desc->buffer.pointer,
+					  source_desc->buffer.length);
+		}
+		break;
 
 	case ACPI_TYPE_STRING:
 
@@ -638,13 +653,13 @@
 		 */
 		if ((source_desc->string.length) &&
 			(!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
-			dest_desc->string.pointer = ACPI_MEM_ALLOCATE (source_desc->string.length);
+			dest_desc->string.pointer = ACPI_MEM_ALLOCATE (source_desc->string.length + 1);
 			if (!dest_desc->string.pointer) {
 				return (AE_NO_MEMORY);
 			}
 
 			ACPI_MEMCPY (dest_desc->string.pointer, source_desc->string.pointer,
-					  source_desc->string.length);
+					  source_desc->string.length + 1);
 		}
 		break;
 
diff -Nru a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
--- a/drivers/acpi/utilities/utdelete.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/acpi/utilities/utdelete.c	Mon Dec  9 18:46:37 2002
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: utdelete - object deletion and reference count utilities
- *              $Revision: 92 $
+ *              $Revision: 93 $
  *
  ******************************************************************************/
 
@@ -329,7 +329,7 @@
 	 * Sanity check the reference count, for debug purposes only.
 	 * (A deleted object will have a huge reference count)
 	 */
-	if (count > MAX_REFERENCE_COUNT) {
+	if (count > ACPI_MAX_REFERENCE_COUNT) {
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_WARN,
 			"**** Warning **** Large Reference Count (%X) in object %p\n\n",
diff -Nru a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
--- a/drivers/acpi/utilities/uteval.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/acpi/utilities/uteval.c	Mon Dec  9 18:46:34 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: uteval - Object evaluation
- *              $Revision: 41 $
+ *              $Revision: 42 $
  *
  *****************************************************************************/
 
@@ -35,80 +35,157 @@
 
 /*******************************************************************************
  *
- * FUNCTION:    Acpi_ut_evaluate_numeric_object
+ * FUNCTION:    Acpi_ut_evaluate_object
  *
- * PARAMETERS:  *Object_name        - Object name to be evaluated
- *              Device_node         - Node for the device
- *              *Address            - Where the value is returned
+ * PARAMETERS:  Prefix_node         - Starting node
+ *              Path                - Path to object from starting node
+ *              Expected_return_types - Bitmap of allowed return types
+ *              Return_desc         - Where a return value is stored
  *
  * RETURN:      Status
  *
- * DESCRIPTION: evaluates a numeric namespace object for a selected device
- *              and stores results in *Address.
+ * DESCRIPTION: Evaluates a namespace object and verifies the type of the
+ *              return object.  Common code that simplifies accessing objects
+ *              that have required return objects of fixed types.
  *
  *              NOTE: Internal function, no parameter validation
  *
  ******************************************************************************/
 
 acpi_status
-acpi_ut_evaluate_numeric_object (
-	NATIVE_CHAR             *object_name,
-	acpi_namespace_node     *device_node,
-	acpi_integer            *address)
+acpi_ut_evaluate_object (
+	acpi_namespace_node     *prefix_node,
+	NATIVE_CHAR             *path,
+	u32                     expected_return_btypes,
+	acpi_operand_object     **return_desc)
 {
 	acpi_operand_object     *obj_desc;
 	acpi_status             status;
+	u32                     return_btype;
 
 
-	ACPI_FUNCTION_TRACE ("Ut_evaluate_numeric_object");
+	ACPI_FUNCTION_TRACE ("Ut_evaluate_object");
 
 
-	/* Execute the method */
+	/* Evaluate the object/method */
 
-	status = acpi_ns_evaluate_relative (device_node, object_name, NULL, &obj_desc);
+	status = acpi_ns_evaluate_relative (prefix_node, path, NULL, &obj_desc);
 	if (ACPI_FAILURE (status)) {
 		if (status == AE_NOT_FOUND) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s on %4.4s was not found\n",
-				object_name, device_node->name.ascii));
+			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n",
+				prefix_node->name.ascii, path));
 		}
 		else {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s on %4.4s failed with status %s\n",
-				object_name, device_node->name.ascii,
-				acpi_format_exception (status)));
+			ACPI_REPORT_METHOD_ERROR ("Method execution failed",
+				prefix_node, path, status);
 		}
 
 		return_ACPI_STATUS (status);
 	}
 
-
 	/* Did we get a return object? */
 
 	if (!obj_desc) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from %s\n",
-			object_name));
-		return_ACPI_STATUS (AE_TYPE);
+		if (expected_return_btypes) {
+			ACPI_REPORT_METHOD_ERROR ("No object was returned from",
+				prefix_node, path, AE_NOT_EXIST);
+
+			return_ACPI_STATUS (AE_NOT_EXIST);
+		}
+
+		return_ACPI_STATUS (AE_OK);
 	}
 
-	/* Is the return object of the correct type? */
+	/* Map the return object type to the bitmapped type */
+
+	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+	case ACPI_TYPE_INTEGER:
+		return_btype = ACPI_BTYPE_INTEGER;
+		break;
+
+	case ACPI_TYPE_BUFFER:
+		return_btype = ACPI_BTYPE_BUFFER;
+		break;
+
+	case ACPI_TYPE_STRING:
+		return_btype = ACPI_BTYPE_STRING;
+		break;
+
+	case ACPI_TYPE_PACKAGE:
+		return_btype = ACPI_BTYPE_PACKAGE;
+		break;
+
+	default:
+		return_btype = 0;
+		break;
+	}
+
+	/* Is the return object one of the expected types? */
+
+	if (!(expected_return_btypes & return_btype)) {
+		ACPI_REPORT_METHOD_ERROR ("Return object type is incorrect",
+			prefix_node, path, AE_TYPE);
 
-	if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_INTEGER) {
-		status = AE_TYPE;
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Type returned from %s was not an Integer: %X \n",
-			object_name, ACPI_GET_OBJECT_TYPE (obj_desc)));
+			"Type returned from %s was incorrect: %X\n",
+			path, ACPI_GET_OBJECT_TYPE (obj_desc)));
+
+		/* On error exit, we must delete the return object */
+
+		acpi_ut_remove_reference (obj_desc);
+		return_ACPI_STATUS (AE_TYPE);
 	}
-	else {
-		/*
-		 * Since the structure is a union, setting any field will set all
-		 * of the variables in the union
-		 */
-		*address = obj_desc->integer.value;
+
+	/* Object type is OK, return it */
+
+	*return_desc = obj_desc;
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_ut_evaluate_numeric_object
+ *
+ * PARAMETERS:  *Object_name        - Object name to be evaluated
+ *              Device_node         - Node for the device
+ *              *Address            - Where the value is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Evaluates a numeric namespace object for a selected device
+ *              and stores result in *Address.
+ *
+ *              NOTE: Internal function, no parameter validation
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_evaluate_numeric_object (
+	NATIVE_CHAR             *object_name,
+	acpi_namespace_node     *device_node,
+	acpi_integer            *address)
+{
+	acpi_operand_object     *obj_desc;
+	acpi_status             status;
+
+
+	ACPI_FUNCTION_TRACE ("Ut_evaluate_numeric_object");
+
+
+	status = acpi_ut_evaluate_object (device_node, object_name,
+			 ACPI_BTYPE_INTEGER, &obj_desc);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
 	}
 
+	/* Get the returned Integer */
+
+	*address = obj_desc->integer.value;
+
 	/* On exit, we must delete the return object */
 
 	acpi_ut_remove_reference (obj_desc);
-
 	return_ACPI_STATUS (status);
 }
 
@@ -141,59 +218,26 @@
 	ACPI_FUNCTION_TRACE ("Ut_execute_HID");
 
 
-	/* Execute the method */
-
-	status = acpi_ns_evaluate_relative (device_node,
-			 METHOD_NAME__HID, NULL, &obj_desc);
+	status = acpi_ut_evaluate_object (device_node, METHOD_NAME__HID,
+			 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &obj_desc);
 	if (ACPI_FAILURE (status)) {
-		if (status == AE_NOT_FOUND) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "_HID on %4.4s was not found\n",
-				device_node->name.ascii));
-		}
-		else {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "_HID on %4.4s failed %s\n",
-				device_node->name.ascii, acpi_format_exception (status)));
-		}
-
 		return_ACPI_STATUS (status);
 	}
 
-	/* Did we get a return object? */
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
+		/* Convert the Numeric HID to string */
 
-	if (!obj_desc) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from _HID\n"));
-		return_ACPI_STATUS (AE_TYPE);
-	}
-
-	/*
-	 *  A _HID can return either a Number (32 bit compressed EISA ID) or
-	 *  a string
-	 */
-	if ((ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_INTEGER) &&
-		(ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_STRING)) {
-		status = AE_TYPE;
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Type returned from _HID not a number or string: %s(%X) \n",
-			acpi_ut_get_object_type_name (obj_desc),
-			ACPI_GET_OBJECT_TYPE (obj_desc)));
+		acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, hid->buffer);
 	}
 	else {
-		if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
-			/* Convert the Numeric HID to string */
+		/* Copy the String HID from the returned object */
 
-			acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, hid->buffer);
-		}
-		else {
-			/* Copy the String HID from the returned object */
-
-			ACPI_STRNCPY (hid->buffer, obj_desc->string.pointer, sizeof(hid->buffer));
-		}
+		ACPI_STRNCPY (hid->buffer, obj_desc->string.pointer, sizeof(hid->buffer));
 	}
 
 	/* On exit, we must delete the return object */
 
 	acpi_ut_remove_reference (obj_desc);
-
 	return_ACPI_STATUS (status);
 }
 
@@ -225,30 +269,13 @@
 
 	ACPI_FUNCTION_TRACE ("Ut_execute_CID");
 
-	/* Execute the method */
 
-	status = acpi_ns_evaluate_relative (device_node,
-			 METHOD_NAME__CID, NULL, &obj_desc);
+	status = acpi_ut_evaluate_object (device_node, METHOD_NAME__CID,
+			 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_PACKAGE, &obj_desc);
 	if (ACPI_FAILURE (status)) {
-		if (status == AE_NOT_FOUND) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "_CID on %4.4s was not found\n",
-				device_node->name.ascii));
-		}
-		else {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "_CID on %4.4s failed %s\n",
-				device_node->name.ascii, acpi_format_exception (status)));
-		}
-
 		return_ACPI_STATUS (status);
 	}
 
-	/* Did we get a return object? */
-
-	if (!obj_desc) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from _CID\n"));
-		return_ACPI_STATUS (AE_TYPE);
-	}
-
 	/*
 	 *  A _CID can return either a single compatible ID or a package of compatible
 	 *  IDs.  Each compatible ID can be a Number (32 bit compressed EISA ID) or
@@ -266,28 +293,25 @@
 
 		/* Copy the String CID from the returned object */
 
-		ACPI_STRNCPY (cid->buffer, obj_desc->string.pointer, sizeof(cid->buffer));
+		ACPI_STRNCPY (cid->buffer, obj_desc->string.pointer, sizeof (cid->buffer));
 		break;
 
 	case ACPI_TYPE_PACKAGE:
 
 		/* TBD: Parse package elements; need different return struct, etc. */
+
+		status = AE_SUPPORT;
 		break;
 
 	default:
 
 		status = AE_TYPE;
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Type returned from _CID not a number, string, or package: %s(%X) \n",
-			acpi_ut_get_object_type_name (obj_desc),
-			ACPI_GET_OBJECT_TYPE (obj_desc)));
 		break;
 	}
 
 	/* On exit, we must delete the return object */
 
 	acpi_ut_remove_reference (obj_desc);
-
 	return_ACPI_STATUS (status);
 }
 
@@ -317,64 +341,30 @@
 	acpi_status             status;
 
 
-	ACPI_FUNCTION_NAME ("Ut_execute_UID");
-
+	ACPI_FUNCTION_TRACE ("Ut_execute_UID");
 
-	/* Execute the method */
 
-	status = acpi_ns_evaluate_relative (device_node,
-			 METHOD_NAME__UID, NULL, &obj_desc);
+	status = acpi_ut_evaluate_object (device_node, METHOD_NAME__UID,
+			 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &obj_desc);
 	if (ACPI_FAILURE (status)) {
-		if (status == AE_NOT_FOUND) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "_UID on %4.4s was not found\n",
-				device_node->name.ascii));
-		}
-		else {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-				"_UID on %4.4s failed %s\n",
-				device_node->name.ascii, acpi_format_exception (status)));
-		}
-
-		return (status);
+		return_ACPI_STATUS (status);
 	}
 
-	/* Did we get a return object? */
+	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
+		/* Convert the Numeric UID to string */
 
-	if (!obj_desc) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from _UID\n"));
-		return (AE_TYPE);
-	}
-
-	/*
-	 *  A _UID can return either a Number (32 bit compressed EISA ID) or
-	 *  a string
-	 */
-	if ((ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_INTEGER) &&
-		(ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_STRING)) {
-		status = AE_TYPE;
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Type returned from _UID was not a number or string: %X \n",
-			ACPI_GET_OBJECT_TYPE (obj_desc)));
+		acpi_ex_unsigned_integer_to_string (obj_desc->integer.value, uid->buffer);
 	}
 	else {
-		if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
-			/* Convert the Numeric UID to string */
+		/* Copy the String UID from the returned object */
 
-			acpi_ex_unsigned_integer_to_string (obj_desc->integer.value, uid->buffer);
-		}
-		else {
-			/* Copy the String UID from the returned object */
-
-			ACPI_STRNCPY (uid->buffer, obj_desc->string.pointer, sizeof(uid->buffer));
-		}
+		ACPI_STRNCPY (uid->buffer, obj_desc->string.pointer, sizeof (uid->buffer));
 	}
 
-
 	/* On exit, we must delete the return object */
 
 	acpi_ut_remove_reference (obj_desc);
-
-	return (status);
+	return_ACPI_STATUS (status);
 }
 
 
@@ -406,51 +396,27 @@
 	ACPI_FUNCTION_TRACE ("Ut_execute_STA");
 
 
-	/* Execute the method */
-
-	status = acpi_ns_evaluate_relative (device_node,
-			 METHOD_NAME__STA, NULL, &obj_desc);
-	if (AE_NOT_FOUND == status) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
-			"_STA on %4.4s was not found, assuming present.\n",
-			device_node->name.ascii));
-
-		*flags = 0x0F;
-		status = AE_OK;
-	}
-
-	else if (ACPI_FAILURE (status)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "_STA on %4.4s failed %s\n",
-			device_node->name.ascii,
-			acpi_format_exception (status)));
-	}
-
-	else /* success */ {
-		/* Did we get a return object? */
+	status = acpi_ut_evaluate_object (device_node, METHOD_NAME__STA,
+			 ACPI_BTYPE_INTEGER, &obj_desc);
+	if (ACPI_FAILURE (status)) {
+		if (AE_NOT_FOUND == status) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+				"_STA on %4.4s was not found, assuming device is present\n",
+				device_node->name.ascii));
 
-		if (!obj_desc) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No object was returned from _STA\n"));
-			return_ACPI_STATUS (AE_TYPE);
+			*flags = 0x0F;
+			status = AE_OK;
 		}
 
-		/* Is the return object of the correct type? */
-
-		if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_INTEGER) {
-			status = AE_TYPE;
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-				"Type returned from _STA was not a number: %X \n",
-				ACPI_GET_OBJECT_TYPE (obj_desc)));
-		}
-		else {
-			/* Extract the status flags */
+		return_ACPI_STATUS (status);
+	}
 
-			*flags = (u32) obj_desc->integer.value;
-		}
+	/* Extract the status flags */
 
-		/* On exit, we must delete the return object */
+	*flags = (u32) obj_desc->integer.value;
 
-		acpi_ut_remove_reference (obj_desc);
-	}
+	/* On exit, we must delete the return object */
 
+	acpi_ut_remove_reference (obj_desc);
 	return_ACPI_STATUS (status);
 }
diff -Nru a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
--- a/drivers/acpi/utilities/utglobal.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/acpi/utilities/utglobal.c	Mon Dec  9 18:46:34 2002
@@ -1,7 +1,7 @@
 /******************************************************************************
  *
  * Module Name: utglobal - Global variables for the ACPI subsystem
- *              $Revision: 172 $
+ *              $Revision: 176 $
  *
  *****************************************************************************/
 
@@ -126,9 +126,9 @@
 /* Debug switch - level and trace mask */
 
 #ifdef ACPI_DEBUG_OUTPUT
-u32                         acpi_dbg_level = DEBUG_DEFAULT;
+u32                         acpi_dbg_level = ACPI_DEBUG_DEFAULT;
 #else
-u32                         acpi_dbg_level = NORMAL_DEFAULT;
+u32                         acpi_dbg_level = ACPI_NORMAL_DEFAULT;
 #endif
 
 /* Debug switch - layer (component) mask */
@@ -140,6 +140,7 @@
 /* Debugger globals */
 
 u8                          acpi_gbl_db_terminate_threads = FALSE;
+u8                          acpi_gbl_abort_method = FALSE;
 u8                          acpi_gbl_method_executing = FALSE;
 
 /* System flags */
@@ -152,9 +153,13 @@
 
 const u8                    acpi_gbl_decode_to8bit [8] = {1,2,4,8,16,32,64,128};
 
-const NATIVE_CHAR           *acpi_gbl_db_sleep_states[ACPI_NUM_SLEEP_STATES] = {
-			  "\\_S0_","\\_S1_","\\_S2_","\\_S3_",
-			  "\\_S4_","\\_S5_","\\_S4B"};
+const NATIVE_CHAR           *acpi_gbl_db_sleep_states[ACPI_S_STATE_COUNT] = {
+			  "\\_S0_",
+			  "\\_S1_",
+			  "\\_S2_",
+			  "\\_S3_",
+			  "\\_S4_",
+			  "\\_S5_"};
 
 
 /******************************************************************************
@@ -669,11 +674,11 @@
 	acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].object_size    = sizeof (acpi_operand_object);
 	acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].object_size       = sizeof (acpi_walk_state);
 
-	acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].max_cache_depth  = MAX_STATE_CACHE_DEPTH;
-	acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].max_cache_depth = MAX_PARSE_CACHE_DEPTH;
-	acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].max_cache_depth = MAX_EXTPARSE_CACHE_DEPTH;
-	acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].max_cache_depth = MAX_OBJECT_CACHE_DEPTH;
-	acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].max_cache_depth   = MAX_WALK_CACHE_DEPTH;
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].max_cache_depth  = ACPI_MAX_STATE_CACHE_DEPTH;
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].max_cache_depth = ACPI_MAX_PARSE_CACHE_DEPTH;
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].max_cache_depth = ACPI_MAX_EXTPARSE_CACHE_DEPTH;
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].max_cache_depth = ACPI_MAX_OBJECT_CACHE_DEPTH;
+	acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].max_cache_depth   = ACPI_MAX_WALK_CACHE_DEPTH;
 
 	ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].list_name    = "Global Memory Allocation");
 	ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].list_name    = "Namespace Nodes");
diff -Nru a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
--- a/drivers/acpi/utilities/utmisc.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/acpi/utilities/utmisc.c	Mon Dec  9 18:46:34 2002
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Module Name: utmisc - common utility procedures
- *              $Revision: 87 $
+ *              $Revision: 90 $
  *
  ******************************************************************************/
 
@@ -200,39 +200,66 @@
  * FUNCTION:    Acpi_ut_display_init_pathname
  *
  * PARAMETERS:  Obj_handle          - Handle whose pathname will be displayed
- *              Path                - Additional path string to be appended
+ *              Path                - Additional path string to be appended.
+ *                                      (NULL if no extra path)
  *
  * RETURN:      acpi_status
  *
- * DESCRIPTION: Display full pathnbame of an object, DEBUG ONLY
+ * DESCRIPTION: Display full pathname of an object, DEBUG ONLY
  *
  ******************************************************************************/
 
 void
 acpi_ut_display_init_pathname (
-	acpi_handle             obj_handle,
+	u8                      type,
+	acpi_namespace_node     *obj_handle,
 	char                    *path)
 {
 	acpi_status             status;
 	acpi_buffer             buffer;
 
 
-	ACPI_FUNCTION_NAME ("Ut_display_init_pathname");
+	ACPI_FUNCTION_ENTRY ();
 
 
-	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+	/* Only print the path if the appropriate debug level is enabled */
+
+	if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
+		return;
+	}
 
+	/* Get the full pathname to the node */
+
+	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
 	status = acpi_ns_handle_to_pathname (obj_handle, &buffer);
-	if (ACPI_SUCCESS (status)) {
-		if (path) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "%s.%s\n", (char *) buffer.pointer, path));
-		}
-		else {
-			ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "%s\n", (char *) buffer.pointer));
-		}
+	if (ACPI_FAILURE (status)) {
+		return;
+	}
+
+	/* Print what we're doing */
 
-		ACPI_MEM_FREE (buffer.pointer);
+	switch (type) {
+	case ACPI_TYPE_METHOD:
+		acpi_os_printf ("Executing  ");
+		break;
+
+	default:
+		acpi_os_printf ("Initializing ");
+		break;
 	}
+
+	/* Print the object type and pathname */
+
+	acpi_os_printf ("%-12s %s", acpi_ut_get_type_name (type), (char *) buffer.pointer);
+
+	/* Extra path is used to append names like _STA, _INI, etc. */
+
+	if (path) {
+		acpi_os_printf (".%s", path);
+	}
+	acpi_os_printf ("\n");
+
+	ACPI_MEM_FREE (buffer.pointer);
 }
 #endif
 
diff -Nru a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c
--- a/drivers/atm/ambassador.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/atm/ambassador.c	Mon Dec  9 18:46:34 2002
@@ -795,7 +795,6 @@
   return;
 }
 
-#ifdef MODULE
 static void drain_rx_pools (amb_dev * dev) {
   unsigned char pool;
   
@@ -803,10 +802,7 @@
   
   for (pool = 0; pool < NUM_RX_POOLS; ++pool)
     drain_rx_pool (dev, pool);
-  
-  return;
 }
-#endif
 
 static inline void fill_rx_pool (amb_dev * dev, unsigned char pool, int priority) {
   rx_in rx;
diff -Nru a/drivers/atm/ambassador.h b/drivers/atm/ambassador.h
--- a/drivers/atm/ambassador.h	Mon Dec  9 18:46:52 2002
+++ b/drivers/atm/ambassador.h	Mon Dec  9 18:46:52 2002
@@ -627,7 +627,7 @@
 
 struct amb_dev {
   u8               irq;
-  u8               flags;
+  long		   flags;
   u32              iobase;
   u32 *            membase;
 
diff -Nru a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
--- a/drivers/atm/atmtcp.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/atm/atmtcp.c	Mon Dec  9 18:46:50 2002
@@ -315,15 +315,9 @@
 
 
 static struct atm_dev atmtcp_control_dev = {
-	&atmtcp_c_dev_ops,
-	NULL,		/* no PHY */
-	"atmtcp",	/* type */
-	999,		/* dummy device number */
-	NULL,NULL,	/* pretend not to have any VCCs */
-	NULL,NULL,	/* no data */
-	{ 0 },		/* no flags */
-	NULL,		/* no local address */
-	{ 0 }		/* no ESI, no statistics */
+	.ops		= &atmtcp_c_dev_ops,
+	.type		= "atmtcp",
+	.number		= 999,
 };
 
 
diff -Nru a/drivers/atm/horizon.c b/drivers/atm/horizon.c
--- a/drivers/atm/horizon.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/atm/horizon.c	Mon Dec  9 18:46:34 2002
@@ -603,8 +603,7 @@
   
   // note: rounding the rate down means rounding 'p' up
   
-  const unsigned long br = test_bit (ultra, (hrz_flags *) &dev->flags) ?
-    BR_ULT : BR_HRZ;
+  const unsigned long br = test_bit(ultra, &dev->flags) ? BR_ULT : BR_HRZ;
   
   u32 div = CR_MIND;
   u32 pre;
@@ -1106,9 +1105,9 @@
 
 static inline int tx_hold (hrz_dev * dev) {
   while (test_and_set_bit (tx_busy, &dev->flags)) {
-    PRINTD (DBG_TX, "sleeping at tx lock %p %u", dev, dev->flags);
+    PRINTD (DBG_TX, "sleeping at tx lock %p %lu", dev, dev->flags);
     interruptible_sleep_on (&dev->tx_queue);
-    PRINTD (DBG_TX, "woken at tx lock %p %u", dev, dev->flags);
+    PRINTD (DBG_TX, "woken at tx lock %p %lu", dev, dev->flags);
     if (signal_pending (current))
       return -1;
   }
diff -Nru a/drivers/atm/horizon.h b/drivers/atm/horizon.h
--- a/drivers/atm/horizon.h	Mon Dec  9 18:46:51 2002
+++ b/drivers/atm/horizon.h	Mon Dec  9 18:46:51 2002
@@ -429,7 +429,7 @@
 #endif
 
   u8                  irq;
-  u8                  flags;
+  long		      flags;
   u8                  tx_last;
   u8                  tx_idle;
 
diff -Nru a/drivers/base/base.h b/drivers/base/base.h
--- a/drivers/base/base.h	Mon Dec  9 18:46:36 2002
+++ b/drivers/base/base.h	Mon Dec  9 18:46:36 2002
@@ -1,13 +1,5 @@
 #undef DEBUG
 
-#ifdef DEBUG
-# define DBG(x...) printk(x)
-#else
-# define DBG(x...)
-#endif
-
-extern struct list_head global_device_list;
-extern spinlock_t device_lock;
 extern struct semaphore device_sem;
 
 extern int bus_add_device(struct device * dev);
@@ -22,8 +14,8 @@
 extern int devclass_add_driver(struct device_driver *);
 extern void devclass_remove_driver(struct device_driver *);
 
-extern int interface_add(struct device_class *, struct device *);
-extern void interface_remove(struct device_class *, struct device *);
+extern int interface_add_dev(struct device *);
+extern void interface_remove_dev(struct device *);
 
 
 #ifdef CONFIG_HOTPLUG
diff -Nru a/drivers/base/bus.c b/drivers/base/bus.c
--- a/drivers/base/bus.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/base/bus.c	Mon Dec  9 18:46:35 2002
@@ -133,6 +133,91 @@
 
 
 /**
+ *	bus_for_each_dev - device iterator.
+ *	@bus:	bus type.
+ *	@start:	device to start iterating from.
+ *	@data:	data for the callback.
+ *	@fn:	function to be called for each device.
+ *
+ *	Iterate over @bus's list of devices, and call @fn for each,
+ *	passing it @data. If @start is not NULL, we use that device to
+ *	begin iterating from.
+ *
+ *	We check the return of @fn each time. If it returns anything
+ *	other than 0, we break out and return that value.
+ *
+ *	NOTE: The device that returns a non-zero value is not retained
+ *	in any way, nor is its refcount incremented. If the caller needs
+ *	to retain this data, it should do, and increment the reference 
+ *	count in the supplied callback.
+ */
+int bus_for_each_dev(struct bus_type * bus, struct device * start, 
+		     void * data, int (*fn)(struct device *, void *))
+{
+	struct list_head * head, * entry;
+	int error = 0;
+
+	if (!(bus = get_bus(bus)))
+		return -EINVAL;
+
+	head = start ? &start->bus_list : &bus->devices;
+
+	down_read(&bus->subsys.rwsem);
+	list_for_each(entry,head) {
+		struct device * dev = get_device(to_dev(entry));
+		error = fn(dev,data);
+		put_device(dev);
+		if (error)
+			break;
+	}
+	up_read(&bus->subsys.rwsem);
+	return error;
+}
+
+/**
+ *	bus_for_each_drv - driver iterator
+ *	@bus:	bus we're dealing with.
+ *	@start:	driver to start iterating on.
+ *	@data:	data to pass to the callback.
+ *	@fn:	function to call for each driver.
+ *
+ *	This is nearly identical to the device iterator above.
+ *	We iterate over each driver that belongs to @bus, and call
+ *	@fn for each. If @fn returns anything but 0, we break out
+ *	and return it. If @start is not NULL, we use it as the head
+ *	of the list.
+ *
+ *	NOTE: we don't return the driver that returns a non-zero 
+ *	value, nor do we leave the reference count incremented for that
+ *	driver. If the caller needs to know that info, it must set it
+ *	in the callback. It must also be sure to increment the refcount
+ *	so it doesn't disappear before returning to the caller.
+ */
+
+int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
+		     void * data, int (*fn)(struct device_driver *, void *))
+{
+	struct list_head * head, * entry;
+	int error = 0;
+
+	if(!(bus = get_bus(bus)))
+		return -EINVAL;
+
+	head = start ? &start->bus_list : &bus->drivers;
+
+	down_read(&bus->subsys.rwsem);
+	list_for_each(entry,head) {
+		struct device_driver * drv = get_driver(to_drv(entry));
+		error = fn(drv,data);
+		put_driver(drv);
+		if(error)
+			break;
+	}
+	up_read(&bus->subsys.rwsem);
+	return error;
+}
+
+/**
  *	attach - add device to driver.
  *	@dev:	device.
  *	
@@ -190,7 +275,7 @@
  */
 static int device_attach(struct device * dev)
 {
-	struct bus_type * bus = dev->bus;
+ 	struct bus_type * bus = dev->bus;
 	struct list_head * entry;
 	int error = 0;
 
@@ -454,6 +539,9 @@
 }
 
 core_initcall(bus_subsys_init);
+
+EXPORT_SYMBOL(bus_for_each_dev);
+EXPORT_SYMBOL(bus_for_each_drv);
 
 EXPORT_SYMBOL(bus_add_device);
 EXPORT_SYMBOL(bus_remove_device);
diff -Nru a/drivers/base/class.c b/drivers/base/class.c
--- a/drivers/base/class.c	Mon Dec  9 18:46:52 2002
+++ b/drivers/base/class.c	Mon Dec  9 18:46:52 2002
@@ -2,7 +2,7 @@
  * class.c - basic device class management
  */
 
-#undef DEBUG
+#define DEBUG
 
 #include <linux/device.h>
 #include <linux/module.h>
@@ -98,7 +98,6 @@
 }
 
 
-
 int devclass_add_driver(struct device_driver * drv)
 {
 	struct device_class * cls = get_devclass(drv->devclass);
@@ -172,9 +171,11 @@
 				error = cls->add_device(dev);
 			if (!error) {
 				enum_device(cls,dev);
-				interface_add(cls,dev);
+				interface_add_dev(dev);
 			}
 
+			list_add_tail(&dev->class_list,&cls->devices);
+
 			/* notify userspace (call /sbin/hotplug) */
 			class_hotplug (dev, "add");
 
@@ -196,9 +197,11 @@
 			down_write(&cls->subsys.rwsem);
 			pr_debug("device class %s: removing device %s\n",
 				 cls->name,dev->name);
-			interface_remove(cls,dev);
+			interface_remove_dev(dev);
 			unenum_device(cls,dev);
 
+			list_del(&dev->class_list);
+
 			/* notify userspace (call /sbin/hotplug) */
 			class_hotplug (dev, "remove");
 
@@ -224,6 +227,7 @@
 int devclass_register(struct device_class * cls)
 {
 	INIT_LIST_HEAD(&cls->drivers);
+	INIT_LIST_HEAD(&cls->devices);
 
 	pr_debug("device class '%s': registering\n",cls->name);
 	strncpy(cls->subsys.kobj.name,cls->name,KOBJ_NAME_LEN);
diff -Nru a/drivers/base/core.c b/drivers/base/core.c
--- a/drivers/base/core.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/base/core.c	Mon Dec  9 18:46:34 2002
@@ -18,15 +18,11 @@
 
 #include "base.h"
 
-LIST_HEAD(global_device_list);
-
 int (*platform_notify)(struct device * dev) = NULL;
 int (*platform_notify_remove)(struct device * dev) = NULL;
 
 DECLARE_MUTEX(device_sem);
 
-spinlock_t device_lock = SPIN_LOCK_UNLOCKED;
-
 #define to_dev(obj) container_of(obj,struct device,kobj)
 
 
@@ -146,11 +142,10 @@
 	kobject_init(&dev->kobj);
 	INIT_LIST_HEAD(&dev->node);
 	INIT_LIST_HEAD(&dev->children);
-	INIT_LIST_HEAD(&dev->g_list);
 	INIT_LIST_HEAD(&dev->driver_list);
 	INIT_LIST_HEAD(&dev->bus_list);
+	INIT_LIST_HEAD(&dev->class_list);
 	INIT_LIST_HEAD(&dev->intf_list);
-//	spin_lock_init(&dev->lock);
 }
 
 /**
@@ -188,13 +183,11 @@
 		goto register_done;
 
 	/* now take care of our own registration */
-	down(&device_sem);
 	if (parent) {
-		list_add_tail(&dev->g_list,&dev->parent->g_list);
+		down(&device_sem);
 		list_add_tail(&dev->node,&parent->children);
-	} else
-		list_add_tail(&dev->g_list,&global_device_list);
-	up(&device_sem);
+		up(&device_sem);
+	}
 
 	bus_add_device(dev);
 
@@ -276,10 +269,11 @@
 {
 	struct device * parent = dev->parent;
 
-	down(&device_sem);
-	list_del_init(&dev->node);
-	list_del_init(&dev->g_list);
-	up(&device_sem);
+	if (parent) {
+		down(&device_sem);
+		list_del_init(&dev->node);
+		up(&device_sem);
+	}
 
 	/* Notify the platform of the removal, in case they
 	 * need to do anything...
diff -Nru a/drivers/base/intf.c b/drivers/base/intf.c
--- a/drivers/base/intf.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/base/intf.c	Mon Dec  9 18:46:50 2002
@@ -2,7 +2,7 @@
  * intf.c - class-specific interface management
  */
 
-#undef DEBUG
+#define DEBUG
 
 #include <linux/device.h>
 #include <linux/module.h>
@@ -10,98 +10,267 @@
 #include "base.h"
 
 
-#define to_intf(node) container_of(node,struct device_interface,kobj.entry)
+#define to_intf(node) container_of(node,struct device_interface,subsys.kobj.entry)
+
+#define to_data(e) container_of(e,struct intf_data,kobj.entry)
+
+#define intf_from_data(d) container_of(d->kobj.subsys,struct device_interface, subsys);
+
 
 /**
- * intf_dev_link - symlink from interface's directory to device's directory
+ *	intf_dev_link - create sysfs symlink for interface.
+ *	@data:	interface data descriptor.
  *
+ *	Create a symlink 'phys' in the interface's directory to 
  */
+
 static int intf_dev_link(struct intf_data * data)
 {
-	char	linkname[16];
-
-	snprintf(linkname,16,"%u",data->intf_num);
-	return sysfs_create_link(&data->intf->kobj,&data->dev->kobj,linkname);
+	char	name[16];
+	snprintf(name,16,"%d",data->intf_num);
+	return sysfs_create_link(&data->intf->subsys.kobj,&data->dev->kobj,name);
 }
 
+/**
+ *	intf_dev_unlink - remove symlink for interface.
+ *	@intf:	interface data descriptor.
+ *
+ */
+
 static void intf_dev_unlink(struct intf_data * data)
 {
-	char	linkname[16];
-	snprintf(linkname,16,"%u",data->intf_num);
-	sysfs_remove_link(&data->intf->kobj,linkname);
+	char	name[16];
+	snprintf(name,16,"%d",data->intf_num);
+	sysfs_remove_link(&data->intf->subsys.kobj,name);
+}
+
+
+/**
+ *	interface_add_data - attach data descriptor
+ *	@data:	interface data descriptor.
+ *
+ *	This attaches the per-instance interface object to the
+ *	interface (by registering its kobject) and the device
+ *	itself (by inserting it into the device's list).
+ *
+ *	Note that there is no explicit protection done in this
+ *	function. This should be called from the interface's 
+ *	add_device() method, which is called under the protection
+ *	of the class's rwsem.
+ */
+
+int interface_add_data(struct intf_data * data)
+{
+	struct device_interface * intf = intf_from_data(data);
+
+	data->intf_num = data->intf->devnum++;
+	data->kobj.subsys = &intf->subsys;
+	kobject_register(&data->kobj);
+
+	list_add_tail(&data->dev_entry,&data->dev->intf_list);
+	intf_dev_link(data);
+	return 0;
+}
+
+
+/**
+ *	interface_remove_data - detach data descriptor.
+ *	@data:	interface data descriptor.
+ *
+ *	This detaches the per-instance data descriptor by removing 
+ *	it from the device's list and unregistering the kobject from
+ *	the subsystem.
+ */
+
+void interface_remove_data(struct intf_data * data)
+{
+	intf_dev_unlink(data);
+	list_del_init(&data->dev_entry);
+	kobject_unregister(&data->kobj);
+}
+
+
+/**
+ *	add - attach device to interface
+ *	@intf:	interface.
+ *	@dev:	device.
+ *
+ *	This is just a simple helper. Check the interface's interface
+ *	helper and call it. This is called when adding an interface
+ *	the class's devices, or a device to the class's interfaces.
+ */
+
+static int add(struct device_interface * intf, struct device * dev)
+{
+	int error = 0;
+
+	if (intf->add_device) 
+		error = intf->add_device(dev);
+	pr_debug(" -> %s (%d)\n",dev->bus_id,error);
+	return error;
+}
+
+/**
+ *	del - detach device from interface.
+ *	@data:	interface data descriptor.
+ *
+ *	Another simple helper. Remove the data descriptor from 
+ *	the device and the interface, then call the interface's 
+ *	remove_device() method.
+ */
+
+static void del(struct intf_data * data)
+{
+	struct device_interface * intf = intf_from_data(data);
+
+	pr_debug(" -> %s ",data->intf->name);
+	interface_remove_data(data);
+	if (intf->remove_device)
+		intf->remove_device(data);
+}
+
+#define to_dev(entry) container_of(entry,struct device,class_list)
+
+
+/**
+ *	add_intf - add class's devices to interface.
+ *	@intf:	interface.
+ *
+ *	Loop over the devices registered with the class, and call
+ *	the interface's add_device() method for each.
+ *
+ *	On an error, we won't break, but we will print debugging info.
+ */
+static void add_intf(struct device_interface * intf)
+{
+	struct device_class * cls = intf->devclass;
+	struct list_head * entry;
+
+	down_write(&cls->subsys.rwsem);
+	list_for_each(entry,&cls->devices)
+		add(intf,to_dev(entry));
+	up_write(&cls->subsys.rwsem);
 }
 
+/**
+ *	interface_register - register an interface with a device class.
+ *	@intf:	interface.
+ *
+ *	An interface may be loaded after drivers and devices have been
+ *	added to the class. So, we must add each device already known to
+ *	the class to the interface as its registered.
+ */
 
 int interface_register(struct device_interface * intf)
 {
 	struct device_class * cls = get_devclass(intf->devclass);
-	int error = 0;
 
 	if (cls) {
 		pr_debug("register interface '%s' with class '%s'\n",
 			 intf->name,cls->name);
-		strncpy(intf->kobj.name,intf->name,KOBJ_NAME_LEN);
-		intf->kobj.subsys = &cls->subsys;
-		kobject_register(&intf->kobj);
-	} else
-		error = -EINVAL;
-	return error;
+
+		strncpy(intf->subsys.kobj.name,intf->name,KOBJ_NAME_LEN);
+		intf->subsys.kobj.subsys = &cls->subsys;
+		subsystem_register(&intf->subsys);
+		add_intf(intf);
+	}
+	return 0;
 }
 
+
+/**
+ *	del_intf - remove devices from interface.
+ *	@intf:	interface being unloaded.
+ *
+ *	This loops over the devices registered with a class and 
+ *	calls the interface's remove_device() method for each.
+ *	This is called when an interface is being unregistered.
+ */
+
+static void del_intf(struct device_interface * intf)
+{
+	struct list_head * entry;
+
+	down_write(&intf->devclass->subsys.rwsem);
+	list_for_each(entry,&intf->subsys.list) {
+		struct intf_data * data = to_data(entry);
+		del(data);
+	}
+	up_write(&intf->devclass->subsys.rwsem);
+}
+
+/**
+ *	interface_unregister - remove interface from class.
+ *	@intf:	interface.
+ *
+ *	This is called when an interface in unloaded, giving it a
+ *	chance to remove itself from devicse that have been added to 
+ *	it.
+ */
+
 void interface_unregister(struct device_interface * intf)
 {
-	pr_debug("unregistering interface '%s' from class '%s'\n",
-		 intf->name,intf->devclass->name);
-	kobject_unregister(&intf->kobj);
+	struct device_class * cls = intf->devclass;
+	if (cls) {
+		pr_debug("unregistering interface '%s' from class '%s'\n",
+			 intf->name,cls->name);
+		del_intf(intf);
+		subsystem_unregister(&intf->subsys);
+		put_devclass(cls);
+	}
 }
 
-int interface_add(struct device_class * cls, struct device * dev)
+
+/**
+ *	interface_add_dev - add device to interfaces.
+ *	@dev:	device.
+ *
+ *	This is a helper for the class driver core. When a 
+ *	device is being added to a class, this is called to add
+ *	the device to all the interfaces in the class.
+ *
+ *	The operation is simple enough: loop over the interfaces
+ *	and call add() [above] for each. The class rwsem is assumed
+ *	to be held.
+ */
+
+int interface_add_dev(struct device * dev)
 {
+	struct device_class * cls = dev->driver->devclass;
 	struct list_head * node;
-	int error = 0;
 
-	pr_debug("adding '%s' to %s class interfaces\n",dev->name,cls->name);
+	pr_debug("interfaces: adding device %s\n",dev->name);
 
 	list_for_each(node,&cls->subsys.list) {
 		struct device_interface * intf = to_intf(node);
-		if (intf->add_device) {
-			error = intf->add_device(dev);
-			if (error)
-				pr_debug("%s:%s: adding '%s' failed: %d\n",
-					 cls->name,intf->name,dev->name,error);
-		}
-		
+		add(intf,dev);
 	}
 	return 0;
 }
 
-void interface_remove(struct device_class * cls, struct device * dev)
+
+/**
+ *	interface_remove_dev - remove device from interfaces.
+ *	@dev:	device.
+ *
+ *	This is another helper for the class driver core, and called
+ *	when the device is being removed from the class. 
+ *	
+ *	We iterate over the list of interface data descriptors attached
+ *	to the device, and call del() [above] for each. Again, the 
+ *	class's rwsem is assumed to be held during this.
+ */
+
+void interface_remove_dev(struct device * dev)
 {
-	struct list_head * node;
-	struct list_head * next;
+	struct list_head * entry, * next;
 
-	pr_debug("remove '%s' from %s class interfaces: ",dev->name,cls->name);
+	pr_debug("interfaces: removing device %s\n",dev->name);
 
-	list_for_each_safe(node,next,&dev->intf_list) {
-		struct intf_data * intf_data = container_of(node,struct intf_data,node);
-		list_del_init(&intf_data->node);
-
-		intf_dev_unlink(intf_data);
-		pr_debug("%s ",intf_data->intf->name);
-		if (intf_data->intf->remove_device)
-			intf_data->intf->remove_device(intf_data);
+	list_for_each_safe(entry,next,&dev->intf_list) {
+		struct intf_data * intf_data = to_data(entry);
+		del(intf_data);
 	}
-	pr_debug("\n");
-}
-
-int interface_add_data(struct intf_data * data)
-{
-	down_write(&data->intf->devclass->subsys.rwsem);
-	list_add_tail(&data->node,&data->dev->intf_list);
-	data->intf_num = data->intf->devnum++;
-	intf_dev_link(data);
-	up_write(&data->intf->devclass->subsys.rwsem);
-	return 0;
 }
 
 EXPORT_SYMBOL(interface_register);
diff -Nru a/drivers/base/node.c b/drivers/base/node.c
--- a/drivers/base/node.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/base/node.c	Mon Dec  9 18:46:35 2002
@@ -93,7 +93,7 @@
 
 static int __init register_node_type(void)
 {
-	driver_register(&node_driver);
-	return devclass_register(&node_devclass);
+	devclass_register(&node_devclass);
+	return driver_register(&node_driver);
 }
 postcore_initcall(register_node_type);
diff -Nru a/drivers/base/power.c b/drivers/base/power.c
--- a/drivers/base/power.c	Mon Dec  9 18:46:49 2002
+++ b/drivers/base/power.c	Mon Dec  9 18:46:49 2002
@@ -15,7 +15,9 @@
 #include <asm/semaphore.h>
 #include "base.h"
 
-#define to_dev(node) container_of(node,struct device,g_list)
+#define to_dev(node) container_of(node,struct device,kobj.entry)
+
+extern struct subsystem device_subsys;
 
 /**
  * device_suspend - suspend/remove all devices on the device ree
@@ -35,8 +37,8 @@
 
 	printk(KERN_EMERG "Suspending devices\n");
 
-	down(&device_sem);
-	list_for_each(node,&global_device_list) {
+	down_write(&device_subsys.rwsem);
+	list_for_each(node,&device_subsys.list) {
 		struct device * dev = to_dev(node);
 		if (dev->driver && dev->driver->suspend) {
 			pr_debug("suspending device %s\n",dev->name);
@@ -45,7 +47,7 @@
 				printk(KERN_ERR "%s: suspend returned %d\n",dev->name,error);
 		}
 	}
-	up(&device_sem);
+	up_write(&device_subsys.rwsem);
 	return error;
 }
 
@@ -61,15 +63,15 @@
 {
 	struct list_head * node;
 
-	down(&device_sem);
-	list_for_each_prev(node,&global_device_list) {
+	down_write(&device_subsys.rwsem);
+	list_for_each_prev(node,&device_subsys.list) {
 		struct device * dev = to_dev(node);
 		if (dev->driver && dev->driver->resume) {
 			pr_debug("resuming device %s\n",dev->name);
 			dev->driver->resume(dev,level);
 		}
 	}
-	up(&device_sem);
+	up_write(&device_subsys.rwsem);
 
 	printk(KERN_EMERG "Devices Resumed\n");
 }
@@ -83,15 +85,15 @@
 	
 	printk(KERN_EMERG "Shutting down devices\n");
 
-	down(&device_sem);
-	list_for_each(entry,&global_device_list) {
+	down_write(&device_subsys.rwsem);
+	list_for_each(entry,&device_subsys.list) {
 		struct device * dev = to_dev(entry);
 		if (dev->driver && dev->driver->shutdown) {
 			pr_debug("shutting down %s\n",dev->name);
 			dev->driver->shutdown(dev);
 		}
 	}
-	up(&device_sem);
+	up_write(&device_subsys.rwsem);
 }
 
 EXPORT_SYMBOL(device_suspend);
diff -Nru a/drivers/block/acsi.c b/drivers/block/acsi.c
--- a/drivers/block/acsi.c	Mon Dec  9 18:46:52 2002
+++ b/drivers/block/acsi.c	Mon Dec  9 18:46:52 2002
@@ -43,9 +43,6 @@
  *
  */
 
-#define MAJOR_NR ACSI_MAJOR
-#define DEVICE_NAME "ACSI"
-
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/errno.h>
@@ -971,7 +968,7 @@
 	aip = disk->private_data;
 	if (CURRENT->bh) {
 		if (!CURRENT->bh && !buffer_locked(CURRENT->bh))
-			panic(DEVICE_NAME ": block not locked");
+			panic("ACSI: block not locked");
 	}
 
 	block = CURRENT->sector;
@@ -1627,8 +1624,8 @@
 #endif
 	if (!MACH_IS_ATARI || !ATARIHW_PRESENT(ACSI))
 		return 0;
-	if (register_blkdev( MAJOR_NR, "ad", &acsi_fops )) {
-		printk( KERN_ERR "Unable to get major %d for ACSI\n", MAJOR_NR );
+	if (register_blkdev( ACSI_MAJOR, "ad", &acsi_fops )) {
+		printk( KERN_ERR "Unable to get major %d for ACSI\n", ACSI_MAJOR );
 		err = -EBUSY;
 		goto out1;
 	}
@@ -1731,7 +1728,7 @@
 	for( i = 0; i < NDevices; ++i ) {
 		struct gendisk *disk = acsi_gendisk[i];
 		sprintf(disk->disk_name, "ad%c", 'a'+i);
-		disk->major = MAJOR_NR;
+		disk->major = ACSI_MAJOR;
 		disk->first_minor = i << 4;
 		if (acsi_info[i].type != HARDDISK) {
 			disk->minor_shift = 0;
@@ -1751,7 +1748,7 @@
 	blk_cleanup_queue(&acsi_queue);
 	atari_stram_free( acsi_buffer );
 out2:
-	unregister_blkdev( MAJOR_NR, "ad" );
+	unregister_blkdev( ACSI_MAJOR, "ad" );
 out1:
 	return err;
 }
@@ -1778,7 +1775,7 @@
 	blk_cleanup_queue(&acsi_queue);
 	atari_stram_free( acsi_buffer );
 
-	if (unregister_blkdev( MAJOR_NR, "ad" ) != 0)
+	if (unregister_blkdev( ACSI_MAJOR, "ad" ) != 0)
 		printk( KERN_ERR "acsi: cleanup_module failed\n");
 
 	for (i = 0; i < NDevices; i++) {
diff -Nru a/drivers/block/acsi_slm.c b/drivers/block/acsi_slm.c
--- a/drivers/block/acsi_slm.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/block/acsi_slm.c	Mon Dec  9 18:46:34 2002
@@ -95,8 +95,6 @@
  */
 #define	SLM_CONT_CNT_REPROG
 
-#define MAJOR_NR ACSI_MAJOR
-
 #define CMDSET_TARG_LUN(cmd,targ,lun)			\
     do {										\
 		cmd[0] = (cmd[0] & ~0xe0) | (targ)<<5;	\
@@ -993,28 +991,31 @@
 	return( 1 );
 }
 
-static devfs_handle_t devfs_handle;
-
 int slm_init( void )
 
 {
-	if (register_chrdev( MAJOR_NR, "slm", &slm_fops )) {
-		printk( KERN_ERR "Unable to get major %d for ACSI SLM\n", MAJOR_NR );
+	int i;
+	if (register_chrdev( ACSI_MAJOR, "slm", &slm_fops )) {
+		printk( KERN_ERR "Unable to get major %d for ACSI SLM\n", ACSI_MAJOR );
 		return -EBUSY;
 	}
 	
 	if (!(SLMBuffer = atari_stram_alloc( SLM_BUFFER_SIZE, NULL, "SLM" ))) {
 		printk( KERN_ERR "Unable to get SLM ST-Ram buffer.\n" );
-		unregister_chrdev( MAJOR_NR, "slm" );
+		unregister_chrdev( ACSI_MAJOR, "slm" );
 		return -ENOMEM;
 	}
 	BufferP = SLMBuffer;
 	SLMState = IDLE;
 	
-	devfs_handle = devfs_mk_dir (NULL, "slm", NULL);
-	devfs_register_series (devfs_handle, "%u", MAX_SLM, DEVFS_FL_DEFAULT,
-			       MAJOR_NR, 0, S_IFCHR | S_IRUSR | S_IWUSR,
+	devfs_mk_dir (NULL, "slm", NULL);
+	for (i = 0; i < MAX_SLM; i++) {
+		char name[16];
+		sprintf(name, "slm/%d", i);
+		devfs_register(NULL, name, DEVFS_FL_DEFAULT,
+			       ACSI_MAJOR, i, S_IFCHR | S_IRUSR | S_IWUSR,
 			       &slm_fops, NULL);
+	}
 	return 0;
 }
 
@@ -1037,8 +1038,11 @@
 
 void cleanup_module(void)
 {
-	devfs_unregister (devfs_handle);
-	if (unregister_chrdev( MAJOR_NR, "slm" ) != 0)
+	int i;
+	for (i = 0; i < MAX_SLM; i++)
+		devfs_remove("slm/%d", i);
+	devfs_remove("slm");
+	if (unregister_chrdev( ACSI_MAJOR, "slm" ) != 0)
 		printk( KERN_ERR "acsi_slm: cleanup_module failed\n");
 	atari_stram_free( SLMBuffer );
 }
diff -Nru a/drivers/block/amiflop.c b/drivers/block/amiflop.c
--- a/drivers/block/amiflop.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/block/amiflop.c	Mon Dec  9 18:46:37 2002
@@ -120,9 +120,6 @@
 MODULE_LICENSE("GPL");
 
 static struct request_queue floppy_queue;
-
-#define MAJOR_NR FLOPPY_MAJOR
-#define DEVICE_NAME "floppy"
 #define QUEUE (&floppy_queue)
 #define CURRENT elv_next_request(&floppy_queue)
 
@@ -1620,7 +1617,7 @@
 	restore_flags(flags);
 
 	if (old_dev != system)
-		invalidate_buffers(mk_kdev(MAJOR_NR, drive + (system << 2)));
+		invalidate_buffers(mk_kdev(FLOPPY_MAJOR, drive + (system << 2)));
 
 	unit[drive].dtype=&data_types[system];
 	unit[drive].blocks=unit[drive].type->heads*unit[drive].type->tracks*
@@ -1727,7 +1724,7 @@
 			nomem = 1;
 		}
 		printk("fd%d ",drive);
-		disk->major = MAJOR_NR;
+		disk->major = FLOPPY_MAJOR;
 		disk->first_minor = drive;
 		disk->fops = &floppy_fops;
 		sprintf(disk->disk_name, "fd%d", drive);
@@ -1762,8 +1759,8 @@
 	if (!AMIGAHW_PRESENT(AMI_FLOPPY))
 		return -ENXIO;
 
-	if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
-		printk("fd: Unable to get major %d for floppy\n",MAJOR_NR);
+	if (register_blkdev(FLOPPY_MAJOR,"fd",&floppy_fops)) {
+		printk("fd: Unable to get major %d for floppy\n",FLOPPY_MAJOR);
 		return -EBUSY;
 	}
 	/*
@@ -1772,21 +1769,21 @@
 	 */
 	if (!request_mem_region(CUSTOM_PHYSADDR+0x20, 8, "amiflop [Paula]")) {
 		printk("fd: cannot get floppy registers\n");
-		unregister_blkdev(MAJOR_NR,"fd");
+		unregister_blkdev(FLOPPY_MAJOR,"fd");
 		return -EBUSY;
 	}
 	if ((raw_buf = (char *)amiga_chip_alloc (RAW_BUF_SIZE, "Floppy")) ==
 	    NULL) {
 		printk("fd: cannot get chip mem buffer\n");
 		release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
-		unregister_blkdev(MAJOR_NR,"fd");
+		unregister_blkdev(FLOPPY_MAJOR,"fd");
 		return -ENOMEM;
 	}
 	if (request_irq(IRQ_AMIGA_DSKBLK, fd_block_done, 0, "floppy_dma", NULL)) {
 		printk("fd: cannot get irq for dma\n");
 		amiga_chip_free(raw_buf);
 		release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
-		unregister_blkdev(MAJOR_NR,"fd");
+		unregister_blkdev(FLOPPY_MAJOR,"fd");
 		return -EBUSY;
 	}
 	if (request_irq(IRQ_AMIGA_CIAA_TB, ms_isr, 0, "floppy_timer", NULL)) {
@@ -1794,7 +1791,7 @@
 		free_irq(IRQ_AMIGA_DSKBLK, NULL);
 		amiga_chip_free(raw_buf);
 		release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
-		unregister_blkdev(MAJOR_NR,"fd");
+		unregister_blkdev(FLOPPY_MAJOR,"fd");
 		return -EBUSY;
 	}
 	if (fd_probe_drives() < 1) { /* No usable drives */
@@ -1802,10 +1799,10 @@
 		free_irq(IRQ_AMIGA_DSKBLK, NULL);
 		amiga_chip_free(raw_buf);
 		release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
-		unregister_blkdev(MAJOR_NR,"fd");
+		unregister_blkdev(FLOPPY_MAJOR,"fd");
 		return -ENXIO;
 	}
-	blk_register_region(MKDEV(MAJOR_NR, 0), 256, THIS_MODULE,
+	blk_register_region(MKDEV(FLOPPY_MAJOR, 0), 256, THIS_MODULE,
 				floppy_find, NULL, NULL);
 
 	/* initialize variables */
@@ -1866,13 +1863,13 @@
 			kfree(unit[i].trackbuf);
 		}
 	}
-	blk_unregister_region(MKDEV(MAJOR_NR, 0), 256);
+	blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
 	free_irq(IRQ_AMIGA_CIAA_TB, NULL);
 	free_irq(IRQ_AMIGA_DSKBLK, NULL);
 	custom.dmacon = DMAF_DISK; /* disable DMA */
 	amiga_chip_free(raw_buf);
 	blk_cleanup_queue(&floppy_queue);
 	release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
-	unregister_blkdev(MAJOR_NR, "fd");
+	unregister_blkdev(FLOPPY_MAJOR, "fd");
 }
 #endif
diff -Nru a/drivers/block/ataflop.c b/drivers/block/ataflop.c
--- a/drivers/block/ataflop.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/block/ataflop.c	Mon Dec  9 18:46:35 2002
@@ -100,8 +100,6 @@
 
 static struct request_queue floppy_queue;
 
-#define MAJOR_NR FLOPPY_MAJOR
-#define DEVICE_NAME "floppy"
 #define QUEUE (&floppy_queue)
 #define CURRENT elv_next_request(&floppy_queue)
 
@@ -1936,8 +1934,8 @@
 		/* Hades doesn't have Atari-compatible floppy */
 		return -ENXIO;
 
-	if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
-		printk(KERN_ERR "Unable to get major %d for floppy\n",MAJOR_NR);
+	if (register_blkdev(FLOPPY_MAJOR,"fd",&floppy_fops)) {
+		printk(KERN_ERR "Unable to get major %d for floppy\n",FLOPPY_MAJOR);
 		return -EBUSY;
 	}
 
@@ -1973,7 +1971,7 @@
 	for (i = 0; i < FD_MAX_UNITS; i++) {
 		unit[i].track = -1;
 		unit[i].flags = 0;
-		unit[i].disk->major = MAJOR_NR;
+		unit[i].disk->major = FLOPPY_MAJOR;
 		unit[i].disk->first_minor = i;
 		sprintf(unit[i].disk->disk_name, "fd%d", i);
 		unit[i].disk->fops = &floppy_fops;
@@ -1983,7 +1981,7 @@
 		add_disk(unit[i].disk);
 	}
 
-	blk_register_region(MKDEV(MAJOR_NR, 0), 256, THIS_MODULE,
+	blk_register_region(MKDEV(FLOPPY_MAJOR, 0), 256, THIS_MODULE,
 				floppy_find, NULL, NULL);
 
 	printk(KERN_INFO "Atari floppy driver: max. %cD, %strack buffering\n",
@@ -1995,7 +1993,7 @@
 Enomem:
 	while (i--)
 		put_disk(unit[i].disk);
-	unregister_blkdev(MAJOR_NR, "fd");
+	unregister_blkdev(FLOPPY_MAJOR, "fd");
 	return -ENOMEM;
 }
 
@@ -2042,12 +2040,12 @@
 void cleanup_module (void)
 {
 	int i;
-	blk_unregister_region(MKDEV(MAJOR_NR, 0), 256);
+	blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
 	for (i = 0; i < FD_MAX_UNITS; i++) {
 		del_gendisk(unit[i].disk);
 		put_disk(unit[i].disk);
 	}
-	unregister_blkdev(MAJOR_NR, "fd");
+	unregister_blkdev(FLOPPY_MAJOR, "fd");
 
 	blk_cleanup_queue(&floppy_queue);
 	del_timer_sync(&fd_timer);
diff -Nru a/drivers/block/cciss.c b/drivers/block/cciss.c
--- a/drivers/block/cciss.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/block/cciss.c	Mon Dec  9 18:46:51 2002
@@ -338,7 +338,7 @@
  */
 static int cciss_open(struct inode *inode, struct file *filep)
 {
-	int ctlr = major(inode->i_rdev) - MAJOR_NR;
+	int ctlr = major(inode->i_rdev) - COMPAQ_CISS_MAJOR;
 	int dsk  = minor(inode->i_rdev) >> NWD_SHIFT;
 
 #ifdef CCISS_DEBUG
@@ -368,7 +368,7 @@
  */
 static int cciss_release(struct inode *inode, struct file *filep)
 {
-	int ctlr = major(inode->i_rdev) - MAJOR_NR;
+	int ctlr = major(inode->i_rdev) - COMPAQ_CISS_MAJOR;
 	int dsk  = minor(inode->i_rdev) >> NWD_SHIFT;
 
 #ifdef CCISS_DEBUG
@@ -388,7 +388,7 @@
 static int cciss_ioctl(struct inode *inode, struct file *filep, 
 		unsigned int cmd, unsigned long arg)
 {
-	int ctlr = major(inode->i_rdev) - MAJOR_NR;
+	int ctlr = major(inode->i_rdev) - COMPAQ_CISS_MAJOR;
 	int dsk  = minor(inode->i_rdev) >> NWD_SHIFT;
 
 #ifdef CCISS_DEBUG
@@ -723,7 +723,7 @@
 	int ctlr, i;
 	unsigned long flags;
 
-	ctlr = major(dev) - MAJOR_NR;
+	ctlr = major(dev) - COMPAQ_CISS_MAJOR;
         if (minor(dev) != 0)
                 return -ENXIO;
 
@@ -2344,10 +2344,10 @@
 		return -ENODEV;
 	}
 
-	if( register_blkdev(MAJOR_NR+i, hba[i]->devname, &cciss_fops))
+	if( register_blkdev(COMPAQ_CISS_MAJOR+i, hba[i]->devname, &cciss_fops))
 	{
 		printk(KERN_ERR "cciss:  Unable to get major number "
-			"%d for %s\n", MAJOR_NR+i, hba[i]->devname);
+			"%d for %s\n", COMPAQ_CISS_MAJOR+i, hba[i]->devname);
 		release_io_mem(hba[i]);
 		free_hba(i);
 		return(-1);
@@ -2360,7 +2360,7 @@
 	{
 		printk(KERN_ERR "ciss: Unable to get irq %d for %s\n",
 			hba[i]->intr, hba[i]->devname);
-		unregister_blkdev( MAJOR_NR+i, hba[i]->devname);
+		unregister_blkdev( COMPAQ_CISS_MAJOR+i, hba[i]->devname);
 		release_io_mem(hba[i]);
 		free_hba(i);
 		return(-1);
@@ -2388,7 +2388,7 @@
 				hba[i]->errinfo_pool, 
 				hba[i]->errinfo_pool_dhandle);
                 free_irq(hba[i]->intr, hba[i]);
-                unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
+                unregister_blkdev(COMPAQ_CISS_MAJOR+i, hba[i]->devname);
 		release_io_mem(hba[i]);
 		free_hba(i);
                 printk( KERN_ERR "cciss: out of memory");
@@ -2435,7 +2435,7 @@
 		struct gendisk *disk = hba[i]->gendisk[j];
 
 		sprintf(disk->disk_name, "cciss/c%dd%d", i, j);
-		disk->major = MAJOR_NR + i;
+		disk->major = COMPAQ_CISS_MAJOR + i;
 		disk->first_minor = j << NWD_SHIFT;
 		disk->fops = &cciss_fops;
 		disk->queue = &hba[i]->queue;
@@ -2486,7 +2486,7 @@
 	pci_set_drvdata(pdev, NULL);
 	iounmap((void*)hba[i]->vaddr);
 	cciss_unregister_scsi(i);  /* unhook from SCSI subsystem */
-	unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
+	unregister_blkdev(COMPAQ_CISS_MAJOR+i, hba[i]->devname);
 	remove_proc_entry(hba[i]->devname, proc_cciss);	
 	
 	/* remove it from the disk list */
diff -Nru a/drivers/block/cciss.h b/drivers/block/cciss.h
--- a/drivers/block/cciss.h	Mon Dec  9 18:46:34 2002
+++ b/drivers/block/cciss.h	Mon Dec  9 18:46:34 2002
@@ -13,8 +13,6 @@
 #define IO_OK		0
 #define IO_ERROR	1
 
-#define MAJOR_NR COMPAQ_CISS_MAJOR 
-
 struct ctlr_info;
 typedef struct ctlr_info ctlr_info_t;
 
diff -Nru a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
--- a/drivers/block/cpqarray.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/block/cpqarray.c	Mon Dec  9 18:46:35 2002
@@ -38,6 +38,9 @@
 #include <linux/init.h>
 #include <linux/hdreg.h>
 #include <linux/spinlock.h>
+#include <linux/blk.h>
+#include <linux/blkdev.h>
+#include <linux/genhd.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
@@ -53,14 +56,6 @@
 MODULE_DESCRIPTION("Driver for Compaq Smart2 Array Controllers");
 MODULE_LICENSE("GPL");
 
-#define MAJOR_NR COMPAQ_SMART2_MAJOR
-#define LOCAL_END_REQUEST
-#define DEVICE_NAME "ida"
-#define DEVICE_NR(device) (minor(device) >> 4)
-#include <linux/blk.h>
-#include <linux/blkdev.h>
-#include <linux/genhd.h>
-
 #include "cpqarray.h"
 #include "ida_cmd.h"
 #include "smart1,2.h"
@@ -295,7 +290,7 @@
 		}
 		free_irq(hba[i]->intr, hba[i]);
 		iounmap(hba[i]->vaddr);
-		unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
+		unregister_blkdev(COMPAQ_SMART2_MAJOR+i, hba[i]->devname);
 		del_timer(&hba[i]->timer);
 		blk_cleanup_queue(&hba[i]->queue);
 		remove_proc_entry(hba[i]->devname, proc_array);
@@ -307,6 +302,7 @@
 		for (j = 0; j < NWD; j++) {
 			if (ida_gendisk[i][j]->flags & GENHD_FL_UP)
 				del_gendisk(ida_gendisk[i][j]);
+			devfs_remove("ida/c%dd%d",i,j);
 			put_disk(ida_gendisk[i][j]);
 		}
 	}
@@ -343,9 +339,9 @@
 	for(i=0; i < nr_ctlr; i++) {
 	  	/* If this successful it should insure that we are the only */
 		/* instance of the driver */	
-		if (register_blkdev(MAJOR_NR+i, hba[i]->devname, &ida_fops)) {
+		if (register_blkdev(COMPAQ_SMART2_MAJOR+i, hba[i]->devname, &ida_fops)) {
                         printk(KERN_ERR "cpqarray: Unable to get major number %d for ida\n",
-                                MAJOR_NR+i);
+                                COMPAQ_SMART2_MAJOR+i);
                         continue;
                 }
 		hba[i]->access.set_intr_mask(hba[i], 0);
@@ -354,7 +350,7 @@
 
 			printk(KERN_ERR "cpqarray: Unable to get irq %d for %s\n", 
 				hba[i]->intr, hba[i]->devname);
-			unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
+			unregister_blkdev(COMPAQ_SMART2_MAJOR+i, hba[i]->devname);
 			continue;
 		}
 		num_cntlrs_reg++;
@@ -404,7 +400,7 @@
 			struct gendisk *disk = ida_gendisk[i][j];
 			drv_info_t *drv = &hba[i]->drv[j];
 			sprintf(disk->disk_name, "ida/c%dd%d", i, j);
-			disk->major = MAJOR_NR + i;
+			disk->major = COMPAQ_SMART2_MAJOR + i;
 			disk->first_minor = j<<NWD_SHIFT;
 			disk->flags = GENHD_FL_DEVFS;
 			disk->fops = &ida_fops; 
@@ -432,12 +428,11 @@
 		ida_gendisk[i][j] = NULL;
 	}
 	free_irq(hba[i]->intr, hba[i]);
-	unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
+	unregister_blkdev(COMPAQ_SMART2_MAJOR+i, hba[i]->devname);
 	num_cntlrs_reg--;
 	printk( KERN_ERR "cpqarray: out of memory");
 
 	if (!num_cntlrs_reg) {
-		devfs_remove("ida");
 		remove_proc_entry("cpqarray", proc_root_driver);
 		return -ENODEV;
 	}
@@ -712,7 +707,7 @@
  */
 static int ida_open(struct inode *inode, struct file *filep)
 {
-	int ctlr = major(inode->i_rdev) - MAJOR_NR;
+	int ctlr = major(inode->i_rdev) - COMPAQ_SMART2_MAJOR;
 	int dsk  = minor(inode->i_rdev) >> NWD_SHIFT;
 
 	DBGINFO(printk("ida_open %x (%x:%x)\n", inode->i_rdev, ctlr, dsk) );
@@ -741,7 +736,7 @@
  */
 static int ida_release(struct inode *inode, struct file *filep)
 {
-	int ctlr = major(inode->i_rdev) - MAJOR_NR;
+	int ctlr = major(inode->i_rdev) - COMPAQ_SMART2_MAJOR;
 	hba[ctlr]->usage_count--;
 	return 0;
 }
@@ -1022,7 +1017,7 @@
  */
 static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg)
 {
-	int ctlr = major(inode->i_rdev) - MAJOR_NR;
+	int ctlr = major(inode->i_rdev) - COMPAQ_SMART2_MAJOR;
 	int dsk  = minor(inode->i_rdev) >> NWD_SHIFT;
 	int error;
 	int diskinfo[4];
@@ -1402,7 +1397,7 @@
 	if (minor(dev) != 0)
 		return -ENXIO;
 
-	ctlr = major(dev) - MAJOR_NR;
+	ctlr = major(dev) - COMPAQ_SMART2_MAJOR;
 
 	spin_lock_irqsave(IDA_LOCK(ctlr), flags);
 	if (hba[ctlr]->usage_count > 1) {
diff -Nru a/drivers/block/floppy.c b/drivers/block/floppy.c
--- a/drivers/block/floppy.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/block/floppy.c	Mon Dec  9 18:46:35 2002
@@ -220,7 +220,6 @@
 void floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs);
 static int set_dor(int fdc, char mask, char data);
 static void register_devfs_entries (int drive) __init;
-static devfs_handle_t devfs_handle;
 
 #define K_64	0x10000		/* 64KB */
 
@@ -241,9 +240,8 @@
 static int irqdma_allocated;
 
 #define LOCAL_END_REQUEST
-#define MAJOR_NR FLOPPY_MAJOR
 #define DEVICE_NAME "floppy"
-#define DEVICE_NR(device) ( (minor(device) & 3) | ((minor(device) & 0x80 ) >> 5 ))
+
 #include <linux/blk.h>
 #include <linux/blkpg.h>
 #include <linux/cdrom.h> /* for the compatibility eject ioctl */
@@ -3946,22 +3944,22 @@
 	.media_changed	= check_floppy_change,
 	.revalidate_disk= floppy_revalidate,
 };
+static char *table[] =
+{"", "d360", "h1200", "u360", "u720", "h360", "h720",
+"u1440", "u2880", "CompaQ", "h1440", "u1680", "h410",
+"u820", "h1476", "u1722", "h420", "u830", "h1494", "u1743",
+"h880", "u1040", "u1120", "h1600", "u1760", "u1920",
+"u3200", "u3520", "u3840", "u1840", "u800", "u1600",
+NULL
+};
+static int t360[] = {1,0}, t1200[] = {2,5,6,10,12,14,16,18,20,23,0},
+t3in[] = {8,9,26,27,28, 7,11,15,19,24,25,29,31, 3,4,13,17,21,22,30,0};
+static int *table_sup[] = 
+{NULL, t360, t1200, t3in+5+8, t3in+5, t3in, t3in};
 
 static void __init register_devfs_entries (int drive)
 {
     int base_minor, i;
-    static char *table[] =
-    {"", "d360", "h1200", "u360", "u720", "h360", "h720",
-     "u1440", "u2880", "CompaQ", "h1440", "u1680", "h410",
-     "u820", "h1476", "u1722", "h420", "u830", "h1494", "u1743",
-     "h880", "u1040", "u1120", "h1600", "u1760", "u1920",
-     "u3200", "u3520", "u3840", "u1840", "u800", "u1600",
-     NULL
-    };
-    static int t360[] = {1,0}, t1200[] = {2,5,6,10,12,14,16,18,20,23,0},
-      t3in[] = {8,9,26,27,28, 7,11,15,19,24,25,29,31, 3,4,13,17,21,22,30,0};
-    static int *table_sup[] = 
-    {NULL, t360, t1200, t3in+5+8, t3in+5, t3in, t3in};
 
     base_minor = (drive < 4) ? drive : (124 + drive);
     if (UDP->cmos < NUMBER(default_drive_params)) {
@@ -3969,8 +3967,8 @@
 	do {
 	    char name[16];
 
-	    sprintf (name, "%d%s", drive, table[table_sup[UDP->cmos][i]]);
-	    devfs_register (devfs_handle, name, DEVFS_FL_DEFAULT, MAJOR_NR,
+	    sprintf(name, "floppy/%d%s", drive, table[table_sup[UDP->cmos][i]]);
+	    devfs_register(NULL, name, DEVFS_FL_DEFAULT, FLOPPY_MAJOR,
 			    base_minor + (table_sup[UDP->cmos][i] << 2),
 			    S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP |S_IWGRP,
 			    &floppy_fops, NULL);
@@ -4229,21 +4227,21 @@
 			goto Enomem;
 	}
 
-	devfs_handle = devfs_mk_dir (NULL, "floppy", NULL);
-	if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
-		printk("Unable to get major %d for floppy\n",MAJOR_NR);
+	devfs_mk_dir (NULL, "floppy", NULL);
+	if (register_blkdev(FLOPPY_MAJOR,"fd",&floppy_fops)) {
+		printk("Unable to get major %d for floppy\n",FLOPPY_MAJOR);
 		err = -EBUSY;
 		goto out;
 	}
 
 	for (i=0; i<N_DRIVE; i++) {
-		disks[i]->major = MAJOR_NR;
+		disks[i]->major = FLOPPY_MAJOR;
 		disks[i]->first_minor = TOMINOR(i);
 		disks[i]->fops = &floppy_fops;
 		sprintf(disks[i]->disk_name, "fd%d", i);
 	}
 
-	blk_register_region(MKDEV(MAJOR_NR, 0), 256, THIS_MODULE,
+	blk_register_region(MKDEV(FLOPPY_MAJOR, 0), 256, THIS_MODULE,
 				floppy_find, NULL, NULL);
 
 	for (i=0; i<256; i++)
@@ -4367,8 +4365,8 @@
 out1:
 	del_timer(&fd_timeout);
 out2:
-	blk_unregister_region(MKDEV(MAJOR_NR, 0), 256);
-	unregister_blkdev(MAJOR_NR,"fd");
+	blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
+	unregister_blkdev(FLOPPY_MAJOR,"fd");
 	blk_cleanup_queue(&floppy_queue);
 out:
 	for (i=0; i<N_DRIVE; i++)
@@ -4532,6 +4530,18 @@
 
 char *floppy;
 
+static void unregister_devfs_entries (int drive)
+{
+    int i;
+
+    if (UDP->cmos < NUMBER(default_drive_params)) {
+	i = 0;
+	do {
+	    devfs_remove("floppy/%d%s", drive, table[table_sup[UDP->cmos][i]]);
+	} while (table_sup[UDP->cmos][i++]);
+    }
+}
+
 static void __init parse_floppy_cfg_string(char *cfg)
 {
 	char *ptr;
@@ -4561,15 +4571,17 @@
 	int drive;
 		
 	platform_device_unregister(&floppy_device);
-	devfs_unregister (devfs_handle);
-	blk_unregister_region(MKDEV(MAJOR_NR, 0), 256);
-	unregister_blkdev(MAJOR_NR, "fd");
+	blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
+	unregister_blkdev(FLOPPY_MAJOR, "fd");
 	for (drive = 0; drive < N_DRIVE; drive++) {
 		if ((allowed_drive_mask & (1 << drive)) &&
-		    fdc_state[FDC(drive)].version != FDC_NONE)
+		    fdc_state[FDC(drive)].version != FDC_NONE) {
 			del_gendisk(disks[drive]);
+			unregister_devfs_entries(drive);
+		}
 		put_disk(disks[drive]);
 	}
+	devfs_remove("floppy");
 
 	blk_cleanup_queue(&floppy_queue);
 	/* eject disk, if any */
diff -Nru a/drivers/block/genhd.c b/drivers/block/genhd.c
--- a/drivers/block/genhd.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/block/genhd.c	Mon Dec  9 18:46:37 2002
@@ -344,9 +344,11 @@
 		"%8u %8u %8llu %8u "
 		"%8u %8u %8u"
 		"\n",
-		disk->reads, disk->read_merges, (u64)disk->read_sectors,
+		disk->reads, disk->read_merges,
+		(unsigned long long)disk->read_sectors,
 		jiffies_to_msec(disk->read_ticks),
-		disk->writes, disk->write_merges, (u64)disk->write_sectors,
+		disk->writes, disk->write_merges,
+		(unsigned long long)disk->write_sectors,
 		jiffies_to_msec(disk->write_ticks),
 		disk->in_flight, jiffies_to_msec(disk->io_ticks),
 		jiffies_to_msec(disk->time_in_queue));
@@ -408,11 +410,11 @@
 		disk->minors = minors;
 		while (minors >>= 1)
 			disk->minor_shift++;
-		kobject_init(&disk->kobj);
 		disk->kobj.subsys = &block_subsys;
+		kobject_init(&disk->kobj);
 		INIT_LIST_HEAD(&disk->full_list);
+		rand_initialize_disk(disk);
 	}
-	rand_initialize_disk(disk);
 	return disk;
 }
 
diff -Nru a/drivers/block/loop.c b/drivers/block/loop.c
--- a/drivers/block/loop.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/block/loop.c	Mon Dec  9 18:46:38 2002
@@ -79,12 +79,9 @@
 
 #include <asm/uaccess.h>
 
-#define MAJOR_NR LOOP_MAJOR
-
 static int max_loop = 8;
 static struct loop_device *loop_dev;
 static struct gendisk **disks;
-static devfs_handle_t devfs_handle;      /*  For the directory */
 
 /*
  * Transfer functions
@@ -1016,17 +1013,13 @@
 		max_loop = 8;
 	}
 
-	if (register_blkdev(MAJOR_NR, "loop", &lo_fops)) {
+	if (register_blkdev(LOOP_MAJOR, "loop", &lo_fops)) {
 		printk(KERN_WARNING "Unable to get major number %d for loop"
-				    " device\n", MAJOR_NR);
+				    " device\n", LOOP_MAJOR);
 		return -EIO;
 	}
 
-	devfs_handle = devfs_mk_dir(NULL, "loop", NULL);
-	devfs_register_series(devfs_handle, "%u", max_loop, DEVFS_FL_DEFAULT,
-			      MAJOR_NR, 0,
-			      S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP,
-			      &lo_fops, NULL);
+	devfs_mk_dir(NULL, "loop", NULL);
 
 	loop_dev = kmalloc(max_loop * sizeof(struct loop_device), GFP_KERNEL);
 	if (!loop_dev)
@@ -1043,6 +1036,7 @@
 	}
 
 	for (i = 0; i < max_loop; i++) {
+		char name[16];
 		struct loop_device *lo = &loop_dev[i];
 		struct gendisk *disk = disks[i];
 		memset(lo, 0, sizeof(*lo));
@@ -1058,6 +1052,11 @@
 		disk->private_data = lo;
 		disk->queue = &lo->lo_queue;
 		add_disk(disk);
+		sprintf(name, "loop/%d", i);
+		devfs_register(NULL, name, DEVFS_FL_DEFAULT,
+			      disk->major, disk->first_minor,
+			      S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP,
+			      disk->fops, NULL);
 	}
 	printk(KERN_INFO "loop: loaded (max %d devices)\n", max_loop);
 	return 0;
@@ -1078,9 +1077,10 @@
 	for (i = 0; i < max_loop; i++) {
 		del_gendisk(disks[i]);
 		put_disk(disks[i]);
+		devfs_remove("loop/%d", i);
 	}
-	devfs_unregister(devfs_handle);
-	if (unregister_blkdev(MAJOR_NR, "loop"))
+	devfs_remove("loop");
+	if (unregister_blkdev(LOOP_MAJOR, "loop"))
 		printk(KERN_WARNING "loop: cannot unregister blkdev\n");
 
 	kfree(disks);
diff -Nru a/drivers/block/nbd.c b/drivers/block/nbd.c
--- a/drivers/block/nbd.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/block/nbd.c	Mon Dec  9 18:46:35 2002
@@ -37,6 +37,8 @@
 #define PARANOIA
 #include <linux/major.h>
 
+#include <linux/blk.h>
+#include <linux/blkdev.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/sched.h>
@@ -46,6 +48,8 @@
 #include <linux/errno.h>
 #include <linux/file.h>
 #include <linux/ioctl.h>
+#include <linux/blkdev.h>
+#include <linux/blk.h>
 #include <net/sock.h>
 
 #include <linux/devfs_fs_kernel.h>
@@ -53,13 +57,11 @@
 #include <asm/uaccess.h>
 #include <asm/types.h>
 
-#define MAJOR_NR NBD_MAJOR
 #include <linux/nbd.h>
 
 #define LO_MAGIC 0x68797548
 
 static struct nbd_device nbd_dev[MAX_NBD];
-static devfs_handle_t devfs_handle;
 
 static spinlock_t nbd_lock = SPIN_LOCK_UNLOCKED;
 
@@ -70,6 +72,29 @@
 static int requests_in;
 static int requests_out;
 
+static void nbd_end_request(struct request *req)
+{
+	int uptodate = (req->errors == 0) ? 1 : 0;
+	request_queue_t *q = req->q;
+	struct bio *bio;
+	unsigned nsect;
+	unsigned long flags;
+
+#ifdef PARANOIA
+	requests_out++;
+#endif
+	spin_lock_irqsave(q->queue_lock, flags);
+	while((bio = req->bio) != NULL) {
+		nsect = bio_sectors(bio);
+		blk_finished_io(nsect);
+		req->bio = bio->bi_next;
+		bio->bi_next = NULL;
+		bio_endio(bio, nsect << 9, uptodate ? 0 : -EIO);
+	}
+	blk_put_request(req);
+	spin_unlock_irqrestore(q->queue_lock, flags);
+}
+
 static int nbd_open(struct inode *inode, struct file *file)
 {
 	struct nbd_device *lo = inode->i_bdev->bd_disk->private_data;
@@ -170,7 +195,8 @@
 	down(&lo->tx_lock);
 
 	if (!sock || !lo->sock) {
-		FAIL("Attempted sendmsg to closed socket\n");
+		printk(KERN_ERR "NBD: Attempted sendmsg to closed socket\n");
+		goto error_out;
 	}
 
 	result = nbd_xmit(1, sock, (char *) &request, sizeof(request), nbd_cmd(req) == NBD_CMD_WRITE ? MSG_MORE : 0);
@@ -538,18 +564,20 @@
 		nbd_dev[i].disk = disk;
 	}
 
-	if (register_blkdev(MAJOR_NR, "nbd", &nbd_fops)) {
+	if (register_blkdev(NBD_MAJOR, "nbd", &nbd_fops)) {
 		printk("Unable to get major number %d for NBD\n",
-		       MAJOR_NR);
+		       NBD_MAJOR);
 		err = -EIO;
 		goto out;
 	}
 #ifdef MODULE
-	printk("nbd: registered device at major %d\n", MAJOR_NR);
+	printk("nbd: registered device at major %d\n", NBD_MAJOR);
 #endif
 	blk_init_queue(&nbd_queue, do_nbd_request, &nbd_lock);
+	devfs_mk_dir (NULL, "nbd", NULL);
 	for (i = 0; i < MAX_NBD; i++) {
 		struct gendisk *disk = nbd_dev[i].disk;
+		char name[16];
 		nbd_dev[i].refcnt = 0;
 		nbd_dev[i].file = NULL;
 		nbd_dev[i].magic = LO_MAGIC;
@@ -560,19 +588,19 @@
 		nbd_dev[i].blksize = 1024;
 		nbd_dev[i].blksize_bits = 10;
 		nbd_dev[i].bytesize = ((u64)0x7ffffc00) << 10; /* 2TB */
-		disk->major = MAJOR_NR;
+		disk->major = NBD_MAJOR;
 		disk->first_minor = i;
 		disk->fops = &nbd_fops;
 		disk->private_data = &nbd_dev[i];
 		sprintf(disk->disk_name, "nbd%d", i);
 		set_capacity(disk, 0x3ffffe);
 		add_disk(disk);
-	}
-	devfs_handle = devfs_mk_dir (NULL, "nbd", NULL);
-	devfs_register_series (devfs_handle, "%u", MAX_NBD,
-			       DEVFS_FL_DEFAULT, MAJOR_NR, 0,
+		sprintf(name, "nbd/%d", i);
+		devfs_register(NULL, name, DEVFS_FL_DEFAULT,
+			       disk->major, disk->first_minor,
 			       S_IFBLK | S_IRUSR | S_IWUSR,
-			       &nbd_fops, NULL);
+			       disk->fops, NULL);
+	}
 
 	return 0;
 out:
@@ -587,14 +615,11 @@
 	for (i = 0; i < MAX_NBD; i++) {
 		del_gendisk(nbd_dev[i].disk);
 		put_disk(nbd_dev[i].disk);
+		devfs_remove("nbd/%d", i);
 	}
-	devfs_unregister (devfs_handle);
+	devfs_remove("nbd");
 	blk_cleanup_queue(&nbd_queue);
-
-	if (unregister_blkdev(MAJOR_NR, "nbd") != 0)
-		printk("nbd: cleanup_module failed\n");
-	else
-		printk("nbd: module cleaned up.\n");
+	unregister_blkdev(NBD_MAJOR, "nbd");
 }
 
 module_init(nbd_init);
diff -Nru a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
--- a/drivers/block/paride/pcd.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/block/paride/pcd.c	Mon Dec  9 18:46:51 2002
@@ -137,7 +137,7 @@
 #include <linux/delay.h>
 #include <linux/cdrom.h>
 #include <linux/spinlock.h>
-
+#include <linux/blk.h>
 #include <asm/uaccess.h>
 
 static spinlock_t pcd_lock;
@@ -172,13 +172,6 @@
 MODULE_PARM(drive3, "1-6i");
 
 #include "paride.h"
-
-/* set up defines for blk.h,  why don't all drivers do it this way ? */
-
-#define MAJOR_NR	major
-
-#include <linux/blk.h>
-
 #include "pseudo.h"
 
 #define PCD_RETRIES	     5
@@ -949,8 +942,8 @@
 	/* 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);
+	if (register_blkdev(major, name, &pcd_bdops)) {
+		printk("pcd: unable to get major number %d\n", major);
 		for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++)
 			put_disk(cd->disk);
 		return -1;
@@ -984,7 +977,7 @@
 		put_disk(cd->disk);
 	}
 	blk_cleanup_queue(&pcd_queue);
-	unregister_blkdev(MAJOR_NR, name);
+	unregister_blkdev(major, name);
 }
 
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
--- a/drivers/block/paride/pd.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/block/paride/pd.c	Mon Dec  9 18:46:50 2002
@@ -150,7 +150,8 @@
 #include <linux/delay.h>
 #include <linux/hdreg.h>
 #include <linux/cdrom.h>	/* for the eject ioctl */
-
+#include <linux/blk.h>
+#include <linux/blkpg.h>
 #include <asm/uaccess.h>
 
 static spinlock_t pd_lock = SPIN_LOCK_UNLOCKED;
@@ -187,12 +188,6 @@
 MODULE_PARM(drive3, "1-8i");
 
 #include "paride.h"
-
-#define MAJOR_NR   major
-
-#include <linux/blk.h>
-#include <linux/blkpg.h>
-
 #include "pseudo.h"
 
 #define PD_BITS    4
@@ -895,7 +890,7 @@
 {
 	if (disable)
 		return -1;
-	if (register_blkdev(MAJOR_NR, name, &pd_fops)) {
+	if (register_blkdev(major, name, &pd_fops)) {
 		printk("%s: unable to get major number %d\n", name, major);
 		return -1;
 	}
@@ -906,7 +901,7 @@
 	       name, name, PD_VERSION, major, cluster, nice);
 	pd_init_units();
 	if (!pd_detect()) {
-		unregister_blkdev(MAJOR_NR, name);
+		unregister_blkdev(major, name);
 		return -1;
 	}
 	return 0;
@@ -916,7 +911,7 @@
 {
 	struct pd_unit *disk;
 	int unit;
-	unregister_blkdev(MAJOR_NR, name);
+	unregister_blkdev(major, name);
 	for (unit = 0, disk = pd; unit < PD_UNITS; unit++, disk++) {
 		if (disk->present) {
 			struct gendisk *p = disk->gd;
diff -Nru a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
--- a/drivers/block/paride/pf.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/block/paride/pf.c	Mon Dec  9 18:46:50 2002
@@ -150,7 +150,8 @@
 #include <linux/hdreg.h>
 #include <linux/cdrom.h>
 #include <linux/spinlock.h>
-
+#include <linux/blk.h>
+#include <linux/blkpg.h>
 #include <asm/uaccess.h>
 
 static spinlock_t pf_spin_lock;
@@ -187,14 +188,6 @@
 MODULE_PARM(drive3, "1-7i");
 
 #include "paride.h"
-
-/* set up defines for blk.h,  why don't all drivers do it this way ? */
-
-#define MAJOR_NR   major
-
-#include <linux/blk.h>
-#include <linux/blkpg.h>
-
 #include "pseudo.h"
 
 /* constants for faking geometry numbers */
@@ -316,7 +309,7 @@
 		pf->drive = (*drives[unit])[D_SLV];
 		pf->lun = (*drives[unit])[D_LUN];
 		snprintf(pf->name, PF_NAMELEN, "%s%d", name, unit);
-		disk->major = MAJOR_NR;
+		disk->major = major;
 		disk->first_minor = unit;
 		strcpy(disk->disk_name, pf->name);
 		disk->fops = &pf_fops;
@@ -964,7 +957,7 @@
 		return -1;
 	pf_busy = 0;
 
-	if (register_blkdev(MAJOR_NR, name, &pf_fops)) {
+	if (register_blkdev(major, name, &pf_fops)) {
 		printk("pf_init: unable to get major number %d\n", major);
 		for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++)
 			put_disk(pf->disk);
@@ -989,7 +982,7 @@
 {
 	struct pf_unit *pf;
 	int unit;
-	unregister_blkdev(MAJOR_NR, name);
+	unregister_blkdev(major, name);
 	for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) {
 		if (!pf->present)
 			continue;
diff -Nru a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
--- a/drivers/block/paride/pg.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/block/paride/pg.c	Mon Dec  9 18:46:50 2002
@@ -281,8 +281,6 @@
 	}
 } 
 
-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))
 
@@ -644,10 +642,15 @@
 		  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,
+	devfs_mk_dir (NULL, "pg", NULL);
+	for (unit=0; unit<PG_UNITS; unit++)
+		if (PG.present) {
+			char name[16];
+			sprintf(name, "pg/%u", unit);
+			devfs_register(NULL, name, DEVFS_FL_DEFAULT,
+			       major, unit, S_IFCHR | S_IRUSR | S_IWUSR,
 			       &pg_fops, NULL);
+		}
 	return 0;
 }
 
@@ -655,7 +658,11 @@
 {
 	int unit;
 
-	devfs_unregister (devfs_handle);
+	for (unit=0; unit<PG_UNITS; unit++)
+		if (PG.present)
+			devfs_remove("pg/%u", unit);
+
+	devfs_remove ("pg");
 	unregister_chrdev(major,name);
 
 	for (unit=0;unit<PG_UNITS;unit++)
diff -Nru a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
--- a/drivers/block/paride/pt.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/block/paride/pt.c	Mon Dec  9 18:46:35 2002
@@ -285,8 +285,6 @@
         }
 }
 
-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))
 
@@ -915,20 +913,31 @@
 		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,
+	devfs_mk_dir (NULL, "pt", NULL);
+	for (unit=0;unit<PT_UNITS;unit++)
+		if (PT.present) {
+			char name[16];
+			sprintf(name, "pt/%d", unit);
+			devfs_register(NULL, name, DEVFS_FL_DEFAULT,
+			       major, unit, 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,
+			sprintf(name, "pt/%dn", unit);
+			devfs_register(NULL, name, DEVFS_FL_DEFAULT,
+			       major, 128 + unit, S_IFCHR | S_IRUSR | S_IWUSR,
 			       &pt_fops, NULL);
+		}
 	return 0;
 }
 
 static void __exit pt_exit(void)
 {
 	int unit;
-	devfs_unregister (devfs_handle);
+	for (unit=0;unit<PT_UNITS;unit++)
+		if (PT.present) {
+			devfs_remove("pt/%d", unit);
+			devfs_remove("pt/%dn", unit);
+		}
+	devfs_remove("pt");
 	unregister_chrdev(major,name);
 	for (unit=0;unit<PT_UNITS;unit++)
 		if (PT.present)
diff -Nru a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c
--- a/drivers/block/ps2esdi.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/block/ps2esdi.c	Mon Dec  9 18:46:34 2002
@@ -27,15 +27,10 @@
    + reset after read/write error
  */
 
-#include <linux/config.h>
-#include <linux/major.h>
-
-#ifdef  CONFIG_BLK_DEV_PS2
-
-#define MAJOR_NR PS2ESDI_MAJOR
 #define DEVICE_NAME "PS/2 ESDI"
-#define DEVICE_NR(device) (minor(device) >> 6)
 
+#include <linux/config.h>
+#include <linux/major.h>
 #include <linux/errno.h>
 #include <linux/wait.h>
 #include <linux/interrupt.h>
@@ -153,8 +148,9 @@
 
 	/* register the device - pass the name, major number and operations
 	   vector .                                                 */
-	if (register_blkdev(MAJOR_NR, "ed", &ps2esdi_fops)) {
-		printk("%s: Unable to get major number %d\n", DEVICE_NAME, MAJOR_NR);
+	if (register_blkdev(PS2ESDI_MAJOR, "ed", &ps2esdi_fops)) {
+		printk("%s: Unable to get major number %d\n", DEVICE_NAME,
+				PS2ESDI_MAJOR);
 		return -1;
 	}
 	/* set up some global information - indicating device specific info */
@@ -165,7 +161,7 @@
 	if (error) {
 		printk(KERN_WARNING "PS2ESDI: error initialising"
 			" device, releasing resources\n");
-		unregister_blkdev(MAJOR_NR, "ed");
+		unregister_blkdev(PS2ESDI_MAJOR, "ed");
 		blk_cleanup_queue(&ps2esdi_queue);
 		return error;
 	}
@@ -214,7 +210,7 @@
 	release_region(io_base, 4);
 	free_dma(dma_arb_level);
 	free_irq(PS2ESDI_IRQ, &ps2esdi_gendisk);
-	unregister_blkdev(MAJOR_NR, "ed");
+	unregister_blkdev(PS2ESDI_MAJOR, "ed");
 	blk_cleanup_queue(&ps2esdi_queue);
 	for (i = 0; i < ps2esdi_drives; i++) {
 		del_gendisk(ps2esdi_gendisk[i]);
@@ -421,7 +417,7 @@
 		struct gendisk *disk = alloc_disk(64);
 		if (!disk)
 			goto err_out4;
-		disk->major = MAJOR_NR;
+		disk->major = PS2ESDI_MAJOR;
 		disk->first_minor = i<<6;
 		sprintf(disk->disk_name, "ed%c", 'a'+i);
 		disk->fops = &ps2esdi_fops;
@@ -1090,5 +1086,3 @@
 	}
 	wake_up(&ps2esdi_int);
 }
-
-#endif
diff -Nru a/drivers/block/rd.c b/drivers/block/rd.c
--- a/drivers/block/rd.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/block/rd.c	Mon Dec  9 18:46:38 2002
@@ -52,17 +52,9 @@
 #include <linux/devfs_fs_kernel.h>
 #include <linux/buffer_head.h>		/* for invalidate_bdev() */
 #include <linux/backing-dev.h>
-#include <asm/uaccess.h>
-
-/*
- * 35 has been officially registered as the RAMDISK major number, but
- * so is the original MAJOR number of 1.  We're using 1 in
- * include/linux/major.h for now
- */
-#define MAJOR_NR RAMDISK_MAJOR
-#define DEVICE_NR(device) (minor(device))
 #include <linux/blk.h>
 #include <linux/blkpg.h>
+#include <asm/uaccess.h>
 
 /* The RAM disk size is now a parameter */
 #define NUM_RAMDISKS 16		/* This cannot be overridden (yet) */ 
@@ -78,7 +70,6 @@
  */
 
 static struct gendisk *rd_disks[NUM_RAMDISKS];
-static devfs_handle_t devfs_handle;
 static struct block_device *rd_bdev[NUM_RAMDISKS];/* Protected device data */
 
 /*
@@ -380,13 +371,14 @@
 		}
 		del_gendisk(rd_disks[i]);
 		put_disk(rd_disks[i]);
+		devfs_remove("rd/%d", i);
 	}
 #ifdef CONFIG_BLK_DEV_INITRD
 	put_disk(initrd_disk);
+	devfs_remove("rd/initrd");
 #endif
-
-	devfs_unregister (devfs_handle);
-	unregister_blkdev( MAJOR_NR, "ramdisk" );
+	devfs_remove("rd");
+	unregister_blkdev(RAMDISK_MAJOR, "ramdisk" );
 }
 
 static struct request_queue rd_queue;
@@ -407,7 +399,7 @@
 	initrd_disk = alloc_disk(1);
 	if (!initrd_disk)
 		return -ENOMEM;
-	initrd_disk->major = MAJOR_NR;
+	initrd_disk->major = RAMDISK_MAJOR;
 	initrd_disk->first_minor = INITRD_MINOR;
 	initrd_disk->fops = &rd_bd_op;	
 	sprintf(initrd_disk->disk_name, "initrd");
@@ -418,29 +410,32 @@
 			goto out;
 	}
 
-	if (register_blkdev(MAJOR_NR, "ramdisk", &rd_bd_op)) {
-		printk("RAMDISK: Could not get major %d", MAJOR_NR);
+	if (register_blkdev(RAMDISK_MAJOR, "ramdisk", &rd_bd_op)) {
+		printk("RAMDISK: Could not get major %d", RAMDISK_MAJOR);
 		err = -EIO;
 		goto out;
 	}
 
 	blk_queue_make_request(&rd_queue, &rd_make_request);
 
+	devfs_mk_dir (NULL, "rd", NULL);
+
 	for (i = 0; i < NUM_RAMDISKS; i++) {
 		struct gendisk *disk = rd_disks[i];
+		char name[16];
 		/* rd_size is given in kB */
-		disk->major = MAJOR_NR;
+		disk->major = RAMDISK_MAJOR;
 		disk->first_minor = i;
 		disk->fops = &rd_bd_op;
 		disk->queue = &rd_queue;
 		sprintf(disk->disk_name, "ram%d", i);
 		set_capacity(disk, rd_size * 2);
-	}
-	devfs_handle = devfs_mk_dir (NULL, "rd", NULL);
-	devfs_register_series (devfs_handle, "%u", NUM_RAMDISKS,
-			       DEVFS_FL_DEFAULT, MAJOR_NR, 0,
+		sprintf(name, "rd/%d", i);
+		devfs_register(NULL, name, DEVFS_FL_DEFAULT,
+			       disk->major, disk->first_minor,
 			       S_IFBLK | S_IRUSR | S_IWUSR,
-			       &rd_bd_op, NULL);
+			       disk->fops, NULL);
+	}
 
 	for (i = 0; i < NUM_RAMDISKS; i++)
 		add_disk(rd_disks[i]);
@@ -449,7 +444,7 @@
 	/* We ought to separate initrd operations here */
 	set_capacity(initrd_disk, (initrd_end-initrd_start+511)>>9);
 	add_disk(initrd_disk);
-	devfs_register(devfs_handle, "initrd", DEVFS_FL_DEFAULT, MAJOR_NR,
+	devfs_register(NULL, "rd/initrd", DEVFS_FL_DEFAULT, RAMDISK_MAJOR,
 			INITRD_MINOR, S_IFBLK | S_IRUSR, &rd_bd_op, NULL);
 #endif
 
diff -Nru a/drivers/block/swim3.c b/drivers/block/swim3.c
--- a/drivers/block/swim3.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/block/swim3.c	Mon Dec  9 18:46:36 2002
@@ -24,6 +24,8 @@
 #include <linux/delay.h>
 #include <linux/fd.h>
 #include <linux/ioctl.h>
+#include <linux/blk.h>
+#include <linux/devfs_fs_kernel.h>
 #include <asm/io.h>
 #include <asm/dbdma.h>
 #include <asm/prom.h>
@@ -32,11 +34,6 @@
 #include <asm/machdep.h>
 #include <asm/pmac_feature.h>
 
-#define MAJOR_NR	FLOPPY_MAJOR
-#define DEVICE_NAME "floppy"
-#include <linux/blk.h>
-#include <linux/devfs_fs_kernel.h>
-
 static struct request_queue swim3_queue;
 static struct gendisk *disks[2];
 static struct request *fd_req;
@@ -1007,15 +1004,16 @@
 			goto out;
 	}
 
-	if (register_blkdev(MAJOR_NR, "fd", &floppy_fops)) {
-		printk(KERN_ERR"Unable to get major %d for floppy\n", MAJOR_NR);
+	if (register_blkdev(FLOPPY_MAJOR, "fd", &floppy_fops)) {
+		printk(KERN_ERR"Unable to get major %d for floppy\n",
+				FLOPPY_MAJOR);
 		err = -EBUSY;
 		goto out;
 	}
 	blk_init_queue(&swim3_queue, do_fd_request, &swim3_lock);
 	for (i = 0; i < floppy_count; i++) {
 		struct gendisk *disk = disks[i];
-		disk->major = MAJOR_NR;
+		disk->major = FLOPPY_MAJOR;
 		disk->first_minor = i;
 		disk->fops = &floppy_fops;
 		disk->private_data = &floppy_states[i];
@@ -1102,7 +1100,7 @@
 	sprintf(floppy_name, "%s%d", floppy_devfs_handle ? "" : "floppy",
 			floppy_count);
 	floppy_handle = devfs_register(floppy_devfs_handle, floppy_name, 
-			DEVFS_FL_DEFAULT, MAJOR_NR, floppy_count, 
+			DEVFS_FL_DEFAULT, FLOPPY_MAJOR, floppy_count, 
 			S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP |S_IWGRP, 
 			&floppy_fops, NULL);
 
diff -Nru a/drivers/block/swim_iop.c b/drivers/block/swim_iop.c
--- a/drivers/block/swim_iop.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/block/swim_iop.c	Mon Dec  9 18:46:34 2002
@@ -78,9 +78,6 @@
 static struct floppy_state floppy_states[MAX_FLOPPIES];
 static spinlock_t swim_iop_lock = SPIN_LOCK_UNLOCKED;
 
-#define MAJOR_NR  FLOPPY_MAJOR
-#define DEVICE_NAME "floppy"
-#define QUEUE (&swim_queue)
 #define CURRENT elv_next_request(&swim_queue)
 
 static char *drive_names[7] = {
@@ -142,9 +139,9 @@
 
 	if (!iop_ism_present) return -ENODEV;
 
-	if (register_blkdev(MAJOR_NR, "fd", &floppy_fops)) {
+	if (register_blkdev(FLOPPY_MAJOR, "fd", &floppy_fops)) {
 		printk(KERN_ERR "SWIM-IOP: Unable to get major %d for floppy\n",
-		       MAJOR_NR);
+		       FLOPPY_MAJOR);
 		return -EBUSY;
 	}
 	blk_init_queue(&swim_queue, do_fd_request, &swim_iop_lock);
@@ -190,7 +187,7 @@
 		struct gendisk *disk = alloc_disk(1);
 		if (!disk)
 			continue;
-		disk->major = MAJOR_NR;
+		disk->major = FLOPPY_MAJOR;
 		disk->first_minor = i;
 		disk->fops = &floppy_fops;
 		sprintf(disk->disk_name, "fd%d", i);
@@ -523,9 +520,9 @@
 		wake_up(&fs->wait);
 		return;
 	}
-	while (!blk_queue_empty(QUEUE) && fs->state == idle) {
+	while (!blk_queue_empty(&swim_queue) && fs->state == idle) {
 		if (CURRENT->bh && !buffer_locked(CURRENT->bh))
-			panic(DEVICE_NAME ": block not locked");
+			panic("floppy: block not locked");
 #if 0
 		printk("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%ld buf=%p\n",
 		       CURRENT->rq_disk->disk_name, CURRENT->cmd,
diff -Nru a/drivers/block/umem.c b/drivers/block/umem.c
--- a/drivers/block/umem.c	Mon Dec  9 18:46:52 2002
+++ b/drivers/block/umem.c	Mon Dec  9 18:46:52 2002
@@ -97,15 +97,10 @@
 static int pci_cmds;
 
 static int major_nr;
-#define MAJOR_NR	(major_nr)
 
 #include <linux/blk.h>
 #include <linux/blkpg.h>
 
-
-static devfs_handle_t devfs_handle;      /*  For the directory */
-
-
 struct cardinfo {
 	int		card_number;
 	struct pci_dev	*dev;
@@ -1160,7 +1155,7 @@
 		if (!mm_gendisk[i])
 			goto out;
 	}
-	devfs_handle = devfs_mk_dir(NULL, "umem", NULL);
+	devfs_mk_dir(NULL, "umem", NULL);
 
 	for (i = 0; i < num_cards; i++) {
 		struct gendisk *disk = mm_gendisk[i];
@@ -1181,7 +1176,7 @@
 	return 0;
 
 out:
-	unregister_blkdev(MAJOR_NR, "umem");
+	unregister_blkdev(major_nr, "umem");
 	while (i--)
 		put_disk(mm_gendisk[i]);
 	return -ENOMEM;
@@ -1201,13 +1196,11 @@
 		del_gendisk(mm_gendisk[i]);
 		put_disk(mm_gendisk[i]);
 	}
-	if (devfs_handle)
-		devfs_unregister(devfs_handle);
-	devfs_handle = NULL;
+	devfs_remove("umem");
 
 	pci_unregister_driver(&mm_pci_driver);
 
-	unregister_blkdev(MAJOR_NR, "umem");
+	unregister_blkdev(major_nr, "umem");
 }
 
 module_init(mm_init);
diff -Nru a/drivers/block/xd.c b/drivers/block/xd.c
--- a/drivers/block/xd.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/block/xd.c	Mon Dec  9 18:46:50 2002
@@ -46,16 +46,14 @@
 #include <linux/init.h>
 #include <linux/wait.h>
 #include <linux/devfs_fs_kernel.h>
+#include <linux/blk.h>
+#include <linux/blkpg.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/dma.h>
 
-#define MAJOR_NR XT_DISK_MAJOR
-#include <linux/blk.h>
-#include <linux/blkpg.h>
-
 #include "xd.h"
 
 static void __init do_xd_setup (int *integers);
@@ -146,8 +144,6 @@
 
 static struct request_queue xd_queue;
 
-static devfs_handle_t devfs_handle = NULL;
-
 /* xd_init: register the block device number and set up pointer tables */
 static int __init xd_init(void)
 {
@@ -174,11 +170,11 @@
 	}
 
 	err = -EBUSY;
-	if (register_blkdev(MAJOR_NR,"xd",&xd_fops)) {
-		printk("xd: Unable to get major number %d\n",MAJOR_NR);
+	if (register_blkdev(XT_DISK_MAJOR,"xd",&xd_fops)) {
+		printk("xd: Unable to get major number %d\n",XT_DISK_MAJOR);
 		goto out1;
 	}
-	devfs_handle = devfs_mk_dir (NULL, "xd", NULL);
+	devfs_mk_dir(NULL, "xd", NULL);
 	blk_init_queue(&xd_queue, do_xd_request, &xd_lock);
 	if (xd_detect(&controller,&address)) {
 
@@ -207,7 +203,7 @@
 		if (!disk)
 			goto Enomem;
 		p->unit = i;
-		disk->major = MAJOR_NR;
+		disk->major = XT_DISK_MAJOR;
 		disk->first_minor = i<<6;
 		sprintf(disk->disk_name, "xd%c", i+'a');
 		disk->fops = &xd_fops;
@@ -246,8 +242,9 @@
 out3:
 	release_region(xd_iobase,4);
 out2:
+	devfs_remove("xd");
 	blk_cleanup_queue(&xd_queue);
-	unregister_blkdev(MAJOR_NR, "xd");
+	unregister_blkdev(XT_DISK_MAJOR, "xd");
 out1:
 	if (xd_dma_buffer)
 		xd_dma_mem_free((unsigned long)xd_dma_buffer,
@@ -1048,14 +1045,14 @@
 void cleanup_module(void)
 {
 	int i;
-	unregister_blkdev(MAJOR_NR, "xd");
+	unregister_blkdev(XT_DISK_MAJOR, "xd");
 	for (i = 0; i < xd_drives; i++) {
 		del_gendisk(xd_gendisk[i]);
 		put_disk(xd_gendisk[i]);
 	}
 	blk_cleanup_queue(&xd_queue);
 	release_region(xd_iobase,4);
-	devfs_unregister (devfs_handle);
+	devfs_remove("xd");
 	if (xd_drives) {
 		free_irq(xd_irq, NULL);
 		free_dma(xd_dma);
diff -Nru a/drivers/block/z2ram.c b/drivers/block/z2ram.c
--- a/drivers/block/z2ram.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/block/z2ram.c	Mon Dec  9 18:46:50 2002
@@ -25,9 +25,7 @@
 ** implied warranty.
 */
 
-#define MAJOR_NR    Z2RAM_MAJOR
 #define DEVICE_NAME "Z2RAM"
-#define DEVICE_NR(device) (minor(device))
 
 #include <linux/major.h>
 #include <linux/slab.h>
@@ -155,7 +153,7 @@
 	sizeof( z2ram_map[0] );
     int rc = -ENOMEM;
 
-    device = DEVICE_NR( inode->i_rdev );
+    device = minor( inode->i_rdev );
 
     if ( current_device != -1 && current_device != device )
     {
@@ -341,18 +339,18 @@
     if ( !MACH_IS_AMIGA )
 	return -ENXIO;
 
-    if ( register_blkdev( MAJOR_NR, DEVICE_NAME, &z2_fops ) )
+    if ( register_blkdev( Z2RAM_MAJOR, DEVICE_NAME, &z2_fops ) )
     {
 	printk( KERN_ERR DEVICE_NAME ": Unable to get major %d\n",
-	    MAJOR_NR );
+	    Z2RAM_MAJOR );
 	return -EBUSY;
     }
     z2ram_gendisk = alloc_disk(1);
     if (!z2ram_gendisk) {
-	unregister_blkdev( MAJOR_NR, DEVICE_NAME );
+	unregister_blkdev( Z2RAM_MAJOR, DEVICE_NAME );
 	return -ENOMEM;
     }
-    z2ram_gendisk->major = MAJOR_NR;
+    z2ram_gendisk->major = Z2RAM_MAJOR;
     z2ram_gendisk->first_minor = 0;
     z2ram_gendisk->fops = &z2_fops;
     sprintf(z2ram_gendisk->disk_name, "z2ram");
@@ -360,7 +358,7 @@
     blk_init_queue(&z2_queue, do_z2_request, &z2ram_lock);
     z2ram_gendisk->queue = &z2_queue;
     add_disk(z2ram_gendisk);
-    blk_register_region(MKDEV(MAJOR_NR, 0), Z2MINOR_COUNT, THIS_MODULE,
+    blk_register_region(MKDEV(Z2RAM_MAJOR, 0), Z2MINOR_COUNT, THIS_MODULE,
 				z2_find, NULL, NULL);
 
     return 0;
@@ -388,8 +386,8 @@
 cleanup_module( void )
 {
     int i, j;
-    blk_unregister_region(MKDEV(MAJOR_NR, 0), 256);
-    if ( unregister_blkdev( MAJOR_NR, DEVICE_NAME ) != 0 )
+    blk_unregister_region(MKDEV(Z2RAM_MAJOR, 0), 256);
+    if ( unregister_blkdev( Z2RAM_MAJOR, DEVICE_NAME ) != 0 )
 	printk( KERN_ERR DEVICE_NAME ": unregister of device failed\n");
 
     del_gendisk(z2ram_gendisk);
diff -Nru a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c
--- a/drivers/bluetooth/hci_h4.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/bluetooth/hci_h4.c	Mon Dec  9 18:46:36 2002
@@ -33,7 +33,6 @@
 #include <linux/module.h>
 
 #include <linux/version.h>
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/sched.h>
diff -Nru a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
--- a/drivers/bluetooth/hci_usb.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/bluetooth/hci_usb.c	Mon Dec  9 18:46:51 2002
@@ -92,9 +92,9 @@
 	{ }	/* Terminating entry */
 };
 
-static void hci_usb_interrupt(struct urb *urb);
-static void hci_usb_rx_complete(struct urb *urb);
-static void hci_usb_tx_complete(struct urb *urb);
+static void hci_usb_interrupt(struct urb *urb, struct pt_regs *regs);
+static void hci_usb_rx_complete(struct urb *urb, struct pt_regs *regs);
+static void hci_usb_tx_complete(struct urb *urb, struct pt_regs *regs);
 
 static struct urb *hci_usb_get_completed(struct hci_usb *husb)
 {
@@ -429,7 +429,7 @@
 	return 0;
 }
 
-static void hci_usb_interrupt(struct urb *urb)
+static void hci_usb_interrupt(struct urb *urb, struct pt_regs *regs)
 {
 	struct hci_usb *husb = (void *) urb->context;
 	struct hci_usb_scb *scb;
@@ -531,7 +531,7 @@
 				husb->hdev.name, status);
 }
 
-static void hci_usb_tx_complete(struct urb *urb)
+static void hci_usb_tx_complete(struct urb *urb, struct pt_regs *regs)
 {
 	struct sk_buff *skb  = (struct sk_buff *) urb->context;
 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
@@ -563,7 +563,7 @@
 	return;
 }
 
-static void hci_usb_rx_complete(struct urb *urb)
+static void hci_usb_rx_complete(struct urb *urb, struct pt_regs *regs)
 {
 	struct sk_buff *skb  = (struct sk_buff *) urb->context;
 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
diff -Nru a/drivers/cdrom/aztcd.c b/drivers/cdrom/aztcd.c
--- a/drivers/cdrom/aztcd.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/cdrom/aztcd.c	Mon Dec  9 18:46:51 2002
@@ -1907,16 +1907,14 @@
 			goto err_out;
 		}
 	}
-	devfs_register(NULL, "aztcd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
-		       S_IFBLK | S_IRUGO | S_IWUGO, &azt_fops, NULL);
 	azt_disk = alloc_disk(1);
 	if (!azt_disk)
-		goto err_out2;
+		goto err_out;
 	if (register_blkdev(MAJOR_NR, "aztcd", &azt_fops) != 0) {
 		printk(KERN_WARNING "aztcd: Unable to get major %d for Aztech"
 		       " CD-ROM\n", MAJOR_NR);
 		ret = -EIO;
-		goto err_out3;
+		goto err_out2;
 	}
 	blk_init_queue(&azt_queue, do_aztcd_request, &aztSpin);
 	blk_queue_hardsect_size(&azt_queue, 2048);
@@ -1926,15 +1924,16 @@
 	sprintf(azt_disk->disk_name, "aztcd");
 	azt_disk->queue = &azt_queue;
 	add_disk(azt_disk);
+	devfs_register(NULL, "aztcd", DEVFS_FL_DEFAULT,
+		       azt_disk->major, azt_disk->first_minor,
+		       S_IFBLK | S_IRUGO | S_IWUGO, azt_disk->fops, NULL);
 
 	azt_invalidate_buffers();
 	aztPresent = 1;
 	aztCloseDoor();
 	return (0);
-err_out3:
-	put_disk(azt_disk);
 err_out2:
-	devfs_remove("aztcd");
+	put_disk(azt_disk);
 err_out:
 	if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
 		SWITCH_IDE_MASTER;
diff -Nru a/drivers/cdrom/gscd.c b/drivers/cdrom/gscd.c
--- a/drivers/cdrom/gscd.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/cdrom/gscd.c	Mon Dec  9 18:46:34 2002
@@ -268,7 +268,7 @@
 		goto out;
 
 	if (req->cmd != READ) {
-		printk("GSCD: bad cmd %d\n", rq_data_dir(req));
+		printk("GSCD: bad cmd %lu\n", rq_data_dir(req));
 		end_request(req, 0);
 		goto repeat;
 	}
diff -Nru a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c
--- a/drivers/cdrom/sbpcd.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/cdrom/sbpcd.c	Mon Dec  9 18:46:35 2002
@@ -5637,8 +5637,6 @@
  *  Called once at boot or load time.
  */
 
-static devfs_handle_t devfs_handle;
-
 /* FIXME: cleanups after failed allocations are too ugly for words */
 #ifdef MODULE
 int __init __sbpcd_init(void)
@@ -5808,7 +5806,7 @@
 	}
 	blk_init_queue(&sbpcd_queue, do_sbpcd_request, &sbpcd_lock);
 
-	devfs_handle = devfs_mk_dir (NULL, "sbp", NULL);
+	devfs_mk_dir (NULL, "sbp", NULL);
 
 	for (j=0;j<NR_SBPCD;j++)
 	{
@@ -5902,12 +5900,12 @@
 	}
 	release_region(CDo_command,4);
 	blk_cleanup_queue(&sbpcd_queue);
-	devfs_unregister (devfs_handle);
 	for (j=0;j<NR_SBPCD;j++)
 	{
 		if (D_S[j].drv_id==-1) continue;
 		del_gendisk(D_S[j].disk);
 		put_disk(D_S[j].disk);
+		devfs_remove("sbp/c0t%d", j);
 		vfree(D_S[j].sbp_buf);
 		if (D_S[j].sbp_audsiz>0) vfree(D_S[j].aud_buf);
 		if ((unregister_cdrom(D_S[j].sbpcd_infop) == -EINVAL))
@@ -5917,6 +5915,7 @@
 		}
 		vfree(D_S[j].sbpcd_infop);
 	}
+	devfs_remove("sbp");
 	msg(DBG_INF, "%s module released.\n", major_name);
 }
 
diff -Nru a/drivers/cdrom/sonycd535.c b/drivers/cdrom/sonycd535.c
--- a/drivers/cdrom/sonycd535.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/cdrom/sonycd535.c	Mon Dec  9 18:46:35 2002
@@ -1445,7 +1445,6 @@
 	int  got_result = 0;
 	int  tmp_irq;
 	int  i;
-	devfs_handle_t sony_devfs_handle;
 	int err;
 
 	/* Setting the base I/O address to 0 will disable it. */
@@ -1547,11 +1546,6 @@
 		printk("IRQ%d, ", tmp_irq);
 	printk("using %d byte buffer\n", sony_buffer_size);
 
-	sony_devfs_handle = devfs_register (NULL, CDU535_HANDLE,
-					DEVFS_FL_DEFAULT,
-					MAJOR_NR, 0,
-					S_IFBLK | S_IRUGO | S_IWUGO,
-					&cdu_fops, NULL);
 	if (register_blkdev(MAJOR_NR, CDU535_HANDLE, &cdu_fops)) {
 		printk("Unable to get major %d for %s\n",
 				MAJOR_NR, CDU535_MESSAGE_NAME);
@@ -1595,6 +1589,10 @@
 	}
 	cdu_disk->queue = &sonycd535_queue;
 	add_disk(cdu_disk);
+	devfs_register (NULL, CDU535_HANDLE, DEVFS_FL_DEFAULT,
+			cdu_disk->major, cdu_disk->first_minor,
+			S_IFBLK | S_IRUGO | S_IWUGO,
+			cdu_disk->fops, NULL);
 	return 0;
 
 out7:
@@ -1613,7 +1611,6 @@
 	blk_cleanup_queue(&sonycd535_queue);
 	unregister_blkdev(MAJOR_NR, CDU535_HANDLE);
 out1:
-	devfs_unregister(sony_devfs_handle);
 	if (sony535_irq_used)
 		free_irq(sony535_irq_used, NULL);
 	return err;
diff -Nru a/drivers/char/Makefile b/drivers/char/Makefile
--- a/drivers/char/Makefile	Mon Dec  9 18:46:51 2002
+++ b/drivers/char/Makefile	Mon Dec  9 18:46:51 2002
@@ -12,7 +12,7 @@
 # All of the (potential) objects that export symbols.
 # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
 
-export-objs     :=	busmouse.o vt.o generic_serial.o ip2main.o \
+export-objs     :=	busmouse.o vt.o generic_serial.o ip2main.o consolemap.o\
 			ite_gpio.o keyboard.o misc.o nvram.o random.o rtc.o \
 			selection.o sonypi.o sysrq.o tty_io.o tty_ioctl.o
 
diff -Nru a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
--- a/drivers/char/agp/Kconfig	Mon Dec  9 18:46:38 2002
+++ b/drivers/char/agp/Kconfig	Mon Dec  9 18:46:38 2002
@@ -39,13 +39,13 @@
 	  You should say Y here if you use XFree86 3.3.6 or 4.x and want to
 	  use GLX or DRI.  If unsure, say N.
 
-config AGP_I810
-	bool "Intel I810/I815/I830M (on-board) support"
-	depends on AGP
-	help
-	  This option gives you AGP support for the Xserver on the Intel 810
-	  815 and 830m chipset boards for their on-board integrated graphics. This
-	  is required to do any useful video modes with these boards.
+#config AGP_I810
+#	bool "Intel I810/I815/I830M (on-board) support"
+#	depends on AGP
+#	help
+#	  This option gives you AGP support for the Xserver on the Intel 810
+#	  815 and 830m chipset boards for their on-board integrated graphics. This
+#	  is required to do any useful video modes with these boards.
 
 config AGP_VIA
 	bool "VIA chipset support"
@@ -107,7 +107,11 @@
 
 config AGP_AMD_8151
 	bool "AMD 8151 support"
-	depends on AGP && !GART_IOMMU
+	depends on AGP
+	default GART_IOMMU
+	help
+	  Say Y here to support the AMD 8151 AGP bridge and the builtin
+	  GART on the AMD Athlon64/Opteron ("Hammer") CPUs.
 
 config AGP_I460
 	bool "Intel 460GX support"
diff -Nru a/drivers/char/agp/Makefile b/drivers/char/agp/Makefile
--- a/drivers/char/agp/Makefile	Mon Dec  9 18:46:35 2002
+++ b/drivers/char/agp/Makefile	Mon Dec  9 18:46:35 2002
@@ -3,22 +3,19 @@
 # space ioctl interface to use agp memory.  It also adds a kernel interface
 # that other drivers could use to manipulate agp memory.
 
-export-objs := agp.o
+export-objs := backend.o
 
-agpgart-y := agp.o frontend.o
-
-agpgart-$(CONFIG_AGP_INTEL)	+= i8x0-agp.o
-agpgart-$(CONFIG_AGP_I810)	+= i810-agp.o
-agpgart-$(CONFIG_AGP_VIA)	+= via-agp.o
-agpgart-$(CONFIG_AGP_AMD)	+= amd-agp.o
-agpgart-$(CONFIG_AGP_SIS)	+= sis-agp.o
-agpgart-$(CONFIG_AGP_ALI)	+= ali-agp.o
-agpgart-$(CONFIG_AGP_SWORKS)	+= sworks-agp.o
-agpgart-$(CONFIG_AGP_I460)	+= i460-agp.o
-agpgart-$(CONFIG_AGP_HP_ZX1)	+= hp-agp.o
-agpgart-$(CONFIG_AGP_AMD_8151)	+= k8-agp.o
+agpgart-y := backend.o frontend.o generic.o
 agpgart-objs := $(agpgart-y)
-
 obj-$(CONFIG_AGP) += agpgart.o
 
-include $(TOPDIR)/Rules.make
+obj-$(CONFIG_AGP_INTEL)		+= intel-agp.o
+obj-$(CONFIG_AGP_VIA)		+= via-agp.o
+obj-$(CONFIG_AGP_AMD)		+= amd-k7-agp.o
+obj-$(CONFIG_AGP_SIS)		+= sis-agp.o
+obj-$(CONFIG_AGP_ALI)		+= ali-agp.o
+obj-$(CONFIG_AGP_SWORKS)	+= sworks-agp.o
+obj-$(CONFIG_AGP_I460)		+= i460-agp.o
+obj-$(CONFIG_AGP_HP_ZX1)	+= hp-agp.o
+obj-$(CONFIG_AGP_AMD_8151)	+= amd-k8-agp.o
+
diff -Nru a/drivers/char/agp/agp.c b/drivers/char/agp/agp.c
--- a/drivers/char/agp/agp.c	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1706 +0,0 @@
-/*
- * AGPGART module version 0.99
- * Copyright (C) 1999 Jeff Hartmann
- * Copyright (C) 1999 Precision Insight, Inc.
- * Copyright (C) 1999 Xi Graphics, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
- * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * TODO: 
- * - Allocate more than order 0 pages to avoid too much linear map splitting.
- */
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/pagemap.h>
-#include <linux/miscdevice.h>
-#include <linux/pm.h>
-#include <linux/agp_backend.h>
-#include "agp.h"
-
-MODULE_AUTHOR("Jeff Hartmann <jhartmann@precisioninsight.com>");
-MODULE_PARM(agp_try_unsupported, "1i");
-MODULE_LICENSE("GPL and additional rights");
-EXPORT_SYMBOL(agp_free_memory);
-EXPORT_SYMBOL(agp_allocate_memory);
-EXPORT_SYMBOL(agp_copy_info);
-EXPORT_SYMBOL(agp_bind_memory);
-EXPORT_SYMBOL(agp_unbind_memory);
-EXPORT_SYMBOL(agp_enable);
-EXPORT_SYMBOL(agp_backend_acquire);
-EXPORT_SYMBOL(agp_backend_release);
-
-struct agp_bridge_data agp_bridge = { .type = NOT_SUPPORTED };
-static int agp_try_unsupported __initdata = 0;
-
-int agp_memory_reserved;
-__u32 *agp_gatt_table; 
-
-int agp_backend_acquire(void)
-{
-	if (agp_bridge.type == NOT_SUPPORTED)
-		return -EINVAL;
-
-	atomic_inc(&agp_bridge.agp_in_use);
-
-	if (atomic_read(&agp_bridge.agp_in_use) != 1) {
-		atomic_dec(&agp_bridge.agp_in_use);
-		return -EBUSY;
-	}
-	MOD_INC_USE_COUNT;
-	return 0;
-}
-
-void agp_backend_release(void)
-{
-	if (agp_bridge.type == NOT_SUPPORTED)
-		return;
-
-	atomic_dec(&agp_bridge.agp_in_use);
-	MOD_DEC_USE_COUNT;
-}
-
-/* 
- * Generic routines for handling agp_memory structures -
- * They use the basic page allocation routines to do the
- * brunt of the work.
- */
-
-
-void agp_free_key(int key)
-{
-
-	if (key < 0)
-		return;
-
-	if (key < MAXKEY)
-		clear_bit(key, agp_bridge.key_list);
-}
-
-static int agp_get_key(void)
-{
-	int bit;
-
-	bit = find_first_zero_bit(agp_bridge.key_list, MAXKEY);
-	if (bit < MAXKEY) {
-		set_bit(bit, agp_bridge.key_list);
-		return bit;
-	}
-	return -1;
-}
-
-agp_memory *agp_create_memory(int scratch_pages)
-{
-	agp_memory *new;
-
-	new = kmalloc(sizeof(agp_memory), GFP_KERNEL);
-
-	if (new == NULL)
-		return NULL;
-
-	memset(new, 0, sizeof(agp_memory));
-	new->key = agp_get_key();
-
-	if (new->key < 0) {
-		kfree(new);
-		return NULL;
-	}
-	new->memory = vmalloc(PAGE_SIZE * scratch_pages);
-
-	if (new->memory == NULL) {
-		agp_free_key(new->key);
-		kfree(new);
-		return NULL;
-	}
-	new->num_scratch_pages = scratch_pages;
-	return new;
-}
-
-void agp_free_memory(agp_memory * curr)
-{
-	int i;
-
-	if ((agp_bridge.type == NOT_SUPPORTED) || (curr == NULL))
-		return;
-
-	if (curr->is_bound == TRUE)
-		agp_unbind_memory(curr);
-
-	if (curr->type != 0) {
-		agp_bridge.free_by_type(curr);
-		return;
-	}
-	if (curr->page_count != 0) {
-		for (i = 0; i < curr->page_count; i++) {
-			curr->memory[i] &= ~(0x00000fff);
-			agp_bridge.agp_destroy_page(phys_to_virt(curr->memory[i]));
-		}
-	}
-	agp_free_key(curr->key);
-	vfree(curr->memory);
-	kfree(curr);
-	MOD_DEC_USE_COUNT;
-}
-
-#define ENTRIES_PER_PAGE		(PAGE_SIZE / sizeof(unsigned long))
-
-agp_memory *agp_allocate_memory(size_t page_count, u32 type)
-{
-	int scratch_pages;
-	agp_memory *new;
-	int i;
-
-	if (agp_bridge.type == NOT_SUPPORTED)
-		return NULL;
-
-	if ((atomic_read(&agp_bridge.current_memory_agp) + page_count) >
-	    agp_bridge.max_memory_agp) {
-		return NULL;
-	}
-
-	if (type != 0) {
-		new = agp_bridge.alloc_by_type(page_count, type);
-		return new;
-	}
-      	/* We always increase the module count, since free auto-decrements
-	 * it
-	 */
-
-	MOD_INC_USE_COUNT;
-
-	scratch_pages = (page_count + ENTRIES_PER_PAGE - 1) / ENTRIES_PER_PAGE;
-
-	new = agp_create_memory(scratch_pages);
-
-	if (new == NULL) {
-		MOD_DEC_USE_COUNT;
-		return NULL;
-	}
-
-	for (i = 0; i < page_count; i++) {
-		void *addr = agp_bridge.agp_alloc_page();
-
-		if (addr == NULL) {
-			/* Free this structure */
-			agp_free_memory(new);
-			return NULL;
-		}
-		new->memory[i] = agp_bridge.mask_memory(virt_to_phys(addr), type);
-		new->page_count++;
-	}
-
-	flush_agp_mappings();
-
-	return new;
-}
-
-/* End - Generic routines for handling agp_memory structures */
-
-static int agp_return_size(void)
-{
-	int current_size;
-	void *temp;
-
-	temp = agp_bridge.current_size;
-
-	switch (agp_bridge.size_type) {
-	case U8_APER_SIZE:
-		current_size = A_SIZE_8(temp)->size;
-		break;
-	case U16_APER_SIZE:
-		current_size = A_SIZE_16(temp)->size;
-		break;
-	case U32_APER_SIZE:
-		current_size = A_SIZE_32(temp)->size;
-		break;
-	case LVL2_APER_SIZE:
-		current_size = A_SIZE_LVL2(temp)->size;
-		break;
-	case FIXED_APER_SIZE:
-		current_size = A_SIZE_FIX(temp)->size;
-		break;
-	default:
-		current_size = 0;
-		break;
-	}
-
-	return current_size;
-}
-
-/* Routine to copy over information structure */
-
-int agp_copy_info(agp_kern_info * info)
-{
-	unsigned long page_mask = 0;
-	int i;
-
-	memset(info, 0, sizeof(agp_kern_info));
-	if (agp_bridge.type == NOT_SUPPORTED) {
-		info->chipset = agp_bridge.type;
-		return -EIO;
-	}
-	info->version.major = agp_bridge.version->major;
-	info->version.minor = agp_bridge.version->minor;
-	info->device = agp_bridge.dev;
-	info->chipset = agp_bridge.type;
-	info->mode = agp_bridge.mode;
-	info->aper_base = agp_bridge.gart_bus_addr;
-	info->aper_size = agp_return_size();
-	info->max_memory = agp_bridge.max_memory_agp;
-	info->current_memory = atomic_read(&agp_bridge.current_memory_agp);
-	info->cant_use_aperture = agp_bridge.cant_use_aperture;
-
-	for(i = 0; i < agp_bridge.num_of_masks; i++)
-		page_mask |= agp_bridge.mask_memory(page_mask, i);
-
-	info->page_mask = ~page_mask;
-	return 0;
-}
-
-/* End - Routine to copy over information structure */
-
-/*
- * Routines for handling swapping of agp_memory into the GATT -
- * These routines take agp_memory and insert them into the GATT.
- * They call device specific routines to actually write to the GATT.
- */
-
-int agp_bind_memory(agp_memory * curr, off_t pg_start)
-{
-	int ret_val;
-
-	if ((agp_bridge.type == NOT_SUPPORTED) ||
-	    (curr == NULL) || (curr->is_bound == TRUE)) {
-		return -EINVAL;
-	}
-	if (curr->is_flushed == FALSE) {
-		CACHE_FLUSH();
-		curr->is_flushed = TRUE;
-	}
-	ret_val = agp_bridge.insert_memory(curr, pg_start, curr->type);
-
-	if (ret_val != 0)
-		return ret_val;
-
-	curr->is_bound = TRUE;
-	curr->pg_start = pg_start;
-	return 0;
-}
-
-int agp_unbind_memory(agp_memory * curr)
-{
-	int ret_val;
-
-	if ((agp_bridge.type == NOT_SUPPORTED) || (curr == NULL))
-		return -EINVAL;
-
-	if (curr->is_bound != TRUE)
-		return -EINVAL;
-
-	ret_val = agp_bridge.remove_memory(curr, curr->pg_start, curr->type);
-
-	if (ret_val != 0)
-		return ret_val;
-
-	curr->is_bound = FALSE;
-	curr->pg_start = 0;
-	return 0;
-}
-
-/* End - Routines for handling swapping of agp_memory into the GATT */
-
-/* 
- * Driver routines - start
- * Currently this module supports the following chipsets:
- * i810, i815, 440lx, 440bx, 440gx, i830, i840, i845, i850, i860, via vp3,
- * via mvp3, via kx133, via kt133, amd irongate, amd 761, amd 762, ALi M1541,
- * and generic support for the SiS chipsets.
- */
-
-/* Generic Agp routines - Start */
-
-void agp_generic_agp_enable(u32 mode)
-{
-	struct pci_dev *device = NULL;
-	u32 command, scratch; 
-	u8 cap_ptr;
-
-	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx + 4, &command);
-
-	/*
-	 * PASS1: go throu all devices that claim to be
-	 *        AGP devices and collect their data.
-	 */
-
-
-	pci_for_each_dev(device) {
-		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (cap_ptr != 0x00) {
-			/*
-			 * Ok, here we have a AGP device. Disable impossible 
-			 * settings, and adjust the readqueue to the minimum.
-			 */
-
-			pci_read_config_dword(device, cap_ptr + 4, &scratch);
-
-			/* adjust RQ depth */
-			command = ((command & ~0xff000000) |
-			     min_t(u32, (mode & 0xff000000),
-				 min_t(u32, (command & 0xff000000),
-				     (scratch & 0xff000000))));
-
-			/* disable SBA if it's not supported */
-			if (!((command & 0x00000200) &&
-			      (scratch & 0x00000200) &&
-			      (mode & 0x00000200)))
-				command &= ~0x00000200;
-
-			/* disable FW if it's not supported */
-			if (!((command & 0x00000010) &&
-			      (scratch & 0x00000010) &&
-			      (mode & 0x00000010)))
-				command &= ~0x00000010;
-
-			if (!((command & 4) &&
-			      (scratch & 4) &&
-			      (mode & 4)))
-				command &= ~0x00000004;
-
-			if (!((command & 2) &&
-			      (scratch & 2) &&
-			      (mode & 2)))
-				command &= ~0x00000002;
-
-			if (!((command & 1) &&
-			      (scratch & 1) &&
-			      (mode & 1)))
-				command &= ~0x00000001;
-		}
-	}
-	/*
-	 * PASS2: Figure out the 4X/2X/1X setting and enable the
-	 *        target (our motherboard chipset).
-	 */
-
-	if (command & 4)
-		command &= ~3;	/* 4X */
-
-	if (command & 2)
-		command &= ~5;	/* 2X */
-
-	if (command & 1)
-		command &= ~6;	/* 1X */
-
-	command |= 0x00000100;
-
-	pci_write_config_dword(agp_bridge.dev,
-			       agp_bridge.capndx + 8,
-			       command);
-
-	/*
-	 * PASS3: Go throu all AGP devices and update the
-	 *        command registers.
-	 */
-
-	pci_for_each_dev(device) {
-		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (cap_ptr != 0x00)
-			pci_write_config_dword(device, cap_ptr + 8, command);
-	}
-}
-
-int agp_generic_create_gatt_table(void)
-{
-	char *table;
-	char *table_end;
-	int size;
-	int page_order;
-	int num_entries;
-	int i;
-	void *temp;
-	struct page *page;
-
-	/* The generic routines can't handle 2 level gatt's */
-	if (agp_bridge.size_type == LVL2_APER_SIZE) {
-		return -EINVAL;
-	}
-
-	table = NULL;
-	i = agp_bridge.aperture_size_idx;
-	temp = agp_bridge.current_size;
-	size = page_order = num_entries = 0;
-
-	if (agp_bridge.size_type != FIXED_APER_SIZE) {
-		do {
-			switch (agp_bridge.size_type) {
-			case U8_APER_SIZE:
-				size = A_SIZE_8(temp)->size;
-				page_order =
-				    A_SIZE_8(temp)->page_order;
-				num_entries =
-				    A_SIZE_8(temp)->num_entries;
-				break;
-			case U16_APER_SIZE:
-				size = A_SIZE_16(temp)->size;
-				page_order = A_SIZE_16(temp)->page_order;
-				num_entries = A_SIZE_16(temp)->num_entries;
-				break;
-			case U32_APER_SIZE:
-				size = A_SIZE_32(temp)->size;
-				page_order = A_SIZE_32(temp)->page_order;
-				num_entries = A_SIZE_32(temp)->num_entries;
-				break;
-				/* This case will never really happen. */
-			case FIXED_APER_SIZE:
-			case LVL2_APER_SIZE:
-			default:
-				size = page_order = num_entries = 0;
-				break;
-			}
-
-			table = (char *) __get_free_pages(GFP_KERNEL,
-							  page_order);
-
-			if (table == NULL) {
-				i++;
-				switch (agp_bridge.size_type) {
-				case U8_APER_SIZE:
-					agp_bridge.current_size = A_IDX8();
-					break;
-				case U16_APER_SIZE:
-					agp_bridge.current_size = A_IDX16();
-					break;
-				case U32_APER_SIZE:
-					agp_bridge.current_size = A_IDX32();
-					break;
-					/* This case will never really 
-					 * happen. 
-					 */
-				case FIXED_APER_SIZE:
-				case LVL2_APER_SIZE:
-				default:
-					agp_bridge.current_size =
-					    agp_bridge.current_size;
-					break;
-				}
-				temp = agp_bridge.current_size;	
-			} else {
-				agp_bridge.aperture_size_idx = i;
-			}
-		} while ((table == NULL) &&
-			 (i < agp_bridge.num_aperture_sizes));
-	} else {
-		size = ((struct aper_size_info_fixed *) temp)->size;
-		page_order = ((struct aper_size_info_fixed *) temp)->page_order;
-		num_entries = ((struct aper_size_info_fixed *) temp)->num_entries;
-		table = (char *) __get_free_pages(GFP_KERNEL, page_order);
-	}
-
-	if (table == NULL)
-		return -ENOMEM;
-
-	table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
-
-	for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
-		SetPageReserved(page);
-
-	agp_bridge.gatt_table_real = (unsigned long *) table;
-	agp_gatt_table = (void *)table; 
-	CACHE_FLUSH();
-	agp_bridge.gatt_table = ioremap_nocache(virt_to_phys(table),
-					(PAGE_SIZE * (1 << page_order)));
-	CACHE_FLUSH();
-
-	if (agp_bridge.gatt_table == NULL) {
-		for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
-			ClearPageReserved(page);
-
-		free_pages((unsigned long) table, page_order);
-
-		return -ENOMEM;
-	}
-	agp_bridge.gatt_bus_addr = virt_to_phys(agp_bridge.gatt_table_real);
-
-	for (i = 0; i < num_entries; i++)
-		agp_bridge.gatt_table[i] = (unsigned long) agp_bridge.scratch_page;
-
-	return 0;
-}
-
-int agp_generic_suspend(void)
-{
-	return 0;
-}
-
-void agp_generic_resume(void)
-{
-	return;
-}
-
-int agp_generic_free_gatt_table(void)
-{
-	int page_order;
-	char *table, *table_end;
-	void *temp;
-	struct page *page;
-
-	temp = agp_bridge.current_size;
-
-	switch (agp_bridge.size_type) {
-	case U8_APER_SIZE:
-		page_order = A_SIZE_8(temp)->page_order;
-		break;
-	case U16_APER_SIZE:
-		page_order = A_SIZE_16(temp)->page_order;
-		break;
-	case U32_APER_SIZE:
-		page_order = A_SIZE_32(temp)->page_order;
-		break;
-	case FIXED_APER_SIZE:
-		page_order = A_SIZE_FIX(temp)->page_order;
-		break;
-	case LVL2_APER_SIZE:
-		/* The generic routines can't deal with 2 level gatt's */
-		return -EINVAL;
-		break;
-	default:
-		page_order = 0;
-		break;
-	}
-
-	/* Do not worry about freeing memory, because if this is
-	 * called, then all agp memory is deallocated and removed
-	 * from the table.
-	 */
-
-	iounmap(agp_bridge.gatt_table);
-	table = (char *) agp_bridge.gatt_table_real;
-	table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
-
-	for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
-		ClearPageReserved(page);
-
-	free_pages((unsigned long) agp_bridge.gatt_table_real, page_order);
-	return 0;
-}
-
-int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type)
-{
-	int i, j, num_entries;
-	void *temp;
-
-	temp = agp_bridge.current_size;
-
-	switch (agp_bridge.size_type) {
-	case U8_APER_SIZE:
-		num_entries = A_SIZE_8(temp)->num_entries;
-		break;
-	case U16_APER_SIZE:
-		num_entries = A_SIZE_16(temp)->num_entries;
-		break;
-	case U32_APER_SIZE:
-		num_entries = A_SIZE_32(temp)->num_entries;
-		break;
-	case FIXED_APER_SIZE:
-		num_entries = A_SIZE_FIX(temp)->num_entries;
-		break;
-	case LVL2_APER_SIZE:
-		/* The generic routines can't deal with 2 level gatt's */
-		return -EINVAL;
-		break;
-	default:
-		num_entries = 0;
-		break;
-	}
-
-	num_entries -= agp_memory_reserved/PAGE_SIZE;
-	if (num_entries < 0) num_entries = 0;
-
-	if (type != 0 || mem->type != 0) {
-		/* The generic routines know nothing of memory types */
-		return -EINVAL;
-	}
-
-	if ((pg_start + mem->page_count) > num_entries)
-		return -EINVAL;
-
-	j = pg_start;
-
-	while (j < (pg_start + mem->page_count)) {
-		if (!PGE_EMPTY(agp_bridge.gatt_table[j])) {
-			return -EBUSY;
-		}
-		j++;
-	}
-
-	if (mem->is_flushed == FALSE) {
-		CACHE_FLUSH();
-		mem->is_flushed = TRUE;
-	}
-
-	for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
-		agp_bridge.gatt_table[j] = mem->memory[i];
-
-	agp_bridge.tlb_flush(mem);
-	return 0;
-}
-
-int agp_generic_remove_memory(agp_memory * mem, off_t pg_start, int type)
-{
-	int i;
-
-	if (type != 0 || mem->type != 0) {
-		/* The generic routines know nothing of memory types */
-		return -EINVAL;
-	}
-	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
-		agp_bridge.gatt_table[i] =
-		    (unsigned long) agp_bridge.scratch_page;
-	}
-
-	agp_bridge.tlb_flush(mem);
-	return 0;
-}
-
-agp_memory *agp_generic_alloc_by_type(size_t page_count, int type)
-{
-	return NULL;
-}
-
-void agp_generic_free_by_type(agp_memory * curr)
-{
-	if (curr->memory != NULL)
-		vfree(curr->memory);
-
-	agp_free_key(curr->key);
-	kfree(curr);
-}
-
-/* 
- * Basic Page Allocation Routines -
- * These routines handle page allocation
- * and by default they reserve the allocated 
- * memory.  They also handle incrementing the
- * current_memory_agp value, Which is checked
- * against a maximum value.
- */
-
-void *agp_generic_alloc_page(void)
-{
-	struct page * page;
-	
-	page = alloc_page(GFP_KERNEL);
-	if (page == NULL)
-		return 0;
-
-	map_page_into_agp(page);
-
-	get_page(page);
-	SetPageLocked(page);
-	atomic_inc(&agp_bridge.current_memory_agp);
-	return page_address(page);
-}
-
-void agp_generic_destroy_page(void *addr)
-{
-	struct page *page;
-
-	if (addr == NULL)
-		return;
-
-	page = virt_to_page(addr);
-	unmap_page_from_agp(page);
-	put_page(page);
-	unlock_page(page);
-	free_page((unsigned long)addr);
-	atomic_dec(&agp_bridge.current_memory_agp);
-}
-
-/* End Basic Page Allocation Routines */
-
-void agp_enable(u32 mode)
-{
-	if (agp_bridge.type == NOT_SUPPORTED)
-		return;
-	agp_bridge.agp_enable(mode);
-}
-
-/* End - Generic Agp routines */
-
-
-/* per-chipset initialization data.
- * note -- all chipsets for a single vendor MUST be grouped together
- */
-static struct {
-	unsigned short device_id; /* first, to make table easier to read */
-	unsigned short vendor_id;
-	enum chipset_type chipset;
-	const char *vendor_name;
-	const char *chipset_name;
-	int (*chipset_setup) (struct pci_dev *pdev);
-} agp_bridge_info[] __initdata = {
-
-#ifdef CONFIG_AGP_ALI
-	{
-		.device_id	= PCI_DEVICE_ID_AL_M1541,
-		.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,
-		.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,
-		.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,
-		.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,
-		.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,
-		.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,
-		.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,
-		.vendor_id	= PCI_VENDOR_ID_AL,
-		.chipset	= ALI_M1651,
-		.vendor_name	= "Ali",
-		.chipset_name	= "M1651",
-		.chipset_setup	= ali_generic_setup,
-	},
-	{
-		.device_id	= PCI_DEVICE_ID_AL_M1671,
-		.vendor_id	= PCI_VENDOR_ID_AL,
-		.chipset	= ALI_M1671,
-		.vendor_name	= "Ali",
-		.chipset_name	= "M1671",
-		.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_8151
-	{ 
-		.device_id	= PCI_DEVICE_ID_AMD_8151_0,
-		.vendor_id  = PCI_VENDOR_ID_AMD,
-		.chipset    = AMD_8151,
-		.vendor_name = "AMD",
-		.chipset_name = "8151",
-		.chipset_setup = amd_8151_setup 
-	},
-#endif /* CONFIG_AGP_AMD */
-
-#ifdef CONFIG_AGP_AMD
-	{
-		.device_id	= PCI_DEVICE_ID_AMD_FE_GATE_7006,
-		.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_FE_GATE_700E,
-		.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_FE_GATE_700C,
-		.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_82815_MC,
-		.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_82820_HB,
-		.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_82820_UP_HB,
-		.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_82830_HB,
-		.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_82845G_HB,
-		.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_82840_HB,
-		.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_82845_HB,
-		.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_82850_HB,
-		.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_82860_HB,
-		.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_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
-	},
-#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,
-		.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	= PCI_DEVICE_ID_VIA_8377_0,
-		.vendor_id	= PCI_VENDOR_ID_VIA,
-		.chipset	= VIA_APOLLO_KT400,
-		.vendor_name	= "Via",
-		.chipset_name	= "Apollo Pro KT400",
-		.chipset_setup	= via_generic_setup
-	},
-	{
-		.device_id	= PCI_DEVICE_ID_VIA_8653_0,
-		.vendor_id	= PCI_VENDOR_ID_VIA,
-		.chipset	= VIA_APOLLO_PRO,
-		.vendor_name	= "Via",
-		.chipset_name	= "Apollo Pro266T",
-		.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
-	},
-#endif
-
-	{ }, /* dummy final entry, always present */
-};
-
-
-/* scan table above for supported devices */
-static int __init agp_lookup_host_bridge (struct pci_dev *pdev)
-{
-	int i;
-	
-	for (i = 0; i < ARRAY_SIZE (agp_bridge_info); i++)
-		if (pdev->vendor == agp_bridge_info[i].vendor_id)
-			break;
-
-	if (i >= ARRAY_SIZE (agp_bridge_info)) {
-		printk (KERN_DEBUG PFX "unsupported bridge\n");
-		return -ENODEV;
-	}
-
-	while ((i < ARRAY_SIZE (agp_bridge_info)) &&
-	       (agp_bridge_info[i].vendor_id == pdev->vendor)) {
-		if (pdev->device == agp_bridge_info[i].device_id) {
-#ifdef CONFIG_AGP_ALI
-			if (pdev->device == PCI_DEVICE_ID_AL_M1621) {
-				u8 hidden_1621_id;
-
-				pci_read_config_byte(pdev, 0xFB, &hidden_1621_id);
-				switch (hidden_1621_id) {
-				case 0x31:
-					agp_bridge_info[i].chipset_name="M1631";
-					break;
-				case 0x32:
-					agp_bridge_info[i].chipset_name="M1632";
-					break;
-				case 0x41:
-					agp_bridge_info[i].chipset_name="M1641";
-					break;
-				case 0x43:
-					break;
-				case 0x47:
-					agp_bridge_info[i].chipset_name="M1647";
-					break;
-				case 0x51:
-					agp_bridge_info[i].chipset_name="M1651";
-					break;
-				default:
-					break;
-				}
-			}
-#endif
-
-			printk (KERN_INFO PFX "Detected %s %s chipset\n",
-				agp_bridge_info[i].vendor_name,
-				agp_bridge_info[i].chipset_name);
-			agp_bridge.type = agp_bridge_info[i].chipset;
-			return agp_bridge_info[i].chipset_setup (pdev);
-		}
-		
-		i++;
-	}
-
-	i--; /* point to vendor generic entry (device_id == 0) */
-
-	/* try init anyway, if user requests it AND
-	 * there is a 'generic' bridge entry for this vendor */
-	if (agp_try_unsupported && agp_bridge_info[i].device_id == 0) {
-		printk(KERN_WARNING PFX "Trying generic %s routines"
-		       " for device id: %04x\n",
-		       agp_bridge_info[i].vendor_name, pdev->device);
-		agp_bridge.type = agp_bridge_info[i].chipset;
-		return agp_bridge_info[i].chipset_setup (pdev);
-	}
-
-	printk(KERN_ERR PFX "Unsupported %s chipset (device id: %04x),"
-	       " you might want to try agp_try_unsupported=1.\n",
-	       agp_bridge_info[i].vendor_name, pdev->device);
-	return -ENODEV;
-}
-
-
-/* Supported Device Scanning routine */
-
-static int __init agp_find_supported_device(struct pci_dev *dev)
-{
-	u8 cap_ptr = 0x00;
-
-	agp_bridge.dev = dev;
-
-	/* Need to test for I810 here */
-#ifdef CONFIG_AGP_I810
-	if (dev->vendor == PCI_VENDOR_ID_INTEL) {
-		struct pci_dev *i810_dev;
-
-		switch (dev->device) {
-		case PCI_DEVICE_ID_INTEL_82810_MC1:
-			i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
-					       PCI_DEVICE_ID_INTEL_82810_IG1,
-						   NULL);
-			if (i810_dev == NULL) {
-				printk(KERN_ERR PFX "Detected an Intel i810,"
-				       " but could not find the secondary"
-				       " device.\n");
-				return -ENODEV;
-			}
-			printk(KERN_INFO PFX "Detected an Intel "
-			       "i810 Chipset.\n");
-			agp_bridge.type = INTEL_I810;
-			return intel_i810_setup (i810_dev);
-
-		case PCI_DEVICE_ID_INTEL_82810_MC3:
-			i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
-					 PCI_DEVICE_ID_INTEL_82810_IG3,
-						   NULL);
-			if (i810_dev == NULL) {
-				printk(KERN_ERR PFX "Detected an Intel i810 "
-				       "DC100, but could not find the "
-				       "secondary device.\n");
-				return -ENODEV;
-			}
-			printk(KERN_INFO PFX "Detected an Intel i810 "
-			       "DC100 Chipset.\n");
-			agp_bridge.type = INTEL_I810;
-			return intel_i810_setup(i810_dev);
-
-		case PCI_DEVICE_ID_INTEL_82810E_MC:
-			i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
-					     PCI_DEVICE_ID_INTEL_82810E_IG,
-						   NULL);
-			if (i810_dev == NULL) {
-				printk(KERN_ERR PFX "Detected an Intel i810 E"
-				    ", but could not find the secondary "
-				       "device.\n");
-				return -ENODEV;
-			}
-			printk(KERN_INFO PFX "Detected an Intel i810 E "
-			       "Chipset.\n");
-			agp_bridge.type = INTEL_I810;
-			return intel_i810_setup(i810_dev);
-
-		 case PCI_DEVICE_ID_INTEL_82815_MC:
-		   /* The i815 can operate either as an i810 style
-		    * integrated device, or as an AGP4X motherboard.
-		    *
-		    * This only addresses the first mode:
-		    */
-			i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
-						PCI_DEVICE_ID_INTEL_82815_CGC,
-						   NULL);
-			if (i810_dev == NULL) {
-				printk(KERN_ERR PFX "agpgart: Detected an "
-					"Intel i815, but could not find the"
-					" secondary device. Assuming a "
-					"non-integrated video card.\n");
-				break;
-			}
-			printk(KERN_INFO PFX "agpgart: Detected an Intel i815 "
-				"Chipset.\n");
-			agp_bridge.type = INTEL_I810;
-			return intel_i810_setup(i810_dev);
-
-		case PCI_DEVICE_ID_INTEL_82845G_HB:
-			i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
-					PCI_DEVICE_ID_INTEL_82845G_IG, NULL);
-			if(i810_dev && PCI_FUNC(i810_dev->devfn) != 0) {
-				i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
-					PCI_DEVICE_ID_INTEL_82845G_IG, i810_dev);
-			}
-
-			if (i810_dev == NULL) {
-				/* 
-				 * We probably have a I845MP chipset
-				 * with an external graphics
-				 * card. It will be initialized later 
-				 */
-				agp_bridge.type = INTEL_I845_G;
-				break;
-			}
-			printk(KERN_INFO PFX "Detected an Intel "
-				   "845G Chipset.\n");
-			agp_bridge.type = INTEL_I810;
-			return intel_i830_setup(i810_dev);
-		   
-		case PCI_DEVICE_ID_INTEL_82830_HB:
-			i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
-						   PCI_DEVICE_ID_INTEL_82830_CGC,
-						   NULL);
-			if(i810_dev && PCI_FUNC(i810_dev->devfn) != 0) {
-				i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
-							   PCI_DEVICE_ID_INTEL_82830_CGC,
-							   i810_dev);
-			}
-
-			if (i810_dev == NULL) {
-				/* Intel 830MP with external graphic card */
-				/* It will be initialized later */
-				agp_bridge.type = INTEL_I830_M;
-				break;
-			}
-			printk(KERN_INFO PFX "Detected an Intel "
-				   "830M Chipset.\n");
-			agp_bridge.type = INTEL_I810;
-			return intel_i830_setup(i810_dev);
-		default:
-			break;
-		}
-	}
-#endif /* CONFIG_AGP_I810 */
-
-#ifdef CONFIG_AGP_SWORKS
-	/* Everything is on func 1 here so we are hardcoding function one */
-	if (dev->vendor == PCI_VENDOR_ID_SERVERWORKS) {
-		struct pci_dev *bridge_dev;
-
-		bridge_dev = pci_find_slot ((unsigned int)dev->bus->number, 
-					    PCI_DEVFN(0, 1));
-		if(bridge_dev == NULL) {
-			printk(KERN_INFO PFX "agpgart: Detected a Serverworks "
-			       "Chipset, but could not find the secondary "
-			       "device.\n");
-			return -ENODEV;
-		}
-
-		switch (dev->device) {
-		case PCI_DEVICE_ID_SERVERWORKS_HE:
-			agp_bridge.type = SVWRKS_HE;
-			return serverworks_setup(bridge_dev);
-
-		case PCI_DEVICE_ID_SERVERWORKS_LE:
-		case 0x0007:
-			agp_bridge.type = SVWRKS_LE;
-			return serverworks_setup(bridge_dev);
-
-		default:
-			if(agp_try_unsupported) {
-				agp_bridge.type = SVWRKS_GENERIC;
-				return serverworks_setup(bridge_dev);
-			}
-			break;
-		}
-	}
-
-#endif /* CONFIG_AGP_SWORKS */
-
-#ifdef CONFIG_AGP_HP_ZX1
-	if (dev->vendor == PCI_VENDOR_ID_HP) {
-		/* ZX1 LBAs can be either PCI or AGP bridges */
-		if (pci_find_capability(dev, PCI_CAP_ID_AGP)) {
-			printk(KERN_INFO PFX "Detected HP ZX1 AGP "
-			       "chipset at %s\n", dev->slot_name);
-			agp_bridge.type = HP_ZX1;
-			agp_bridge.dev = dev;
-			return hp_zx1_setup(dev);
-		}
-		return -ENODEV;
-	}
-#endif /* CONFIG_AGP_HP_ZX1 */
-
-	/* find capndx */
-	cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP);
-	if (cap_ptr == 0x00)
-		return -ENODEV;
-	agp_bridge.capndx = cap_ptr;
-
-	/* Fill in the mode register */
-	pci_read_config_dword(agp_bridge.dev,
-			      agp_bridge.capndx + 4,
-			      &agp_bridge.mode);
-
-	/* probe for known chipsets */
-	return agp_lookup_host_bridge (dev);
-}
-
-struct agp_max_table {
-	int mem;
-	int agp;
-};
-
-static struct agp_max_table maxes_table[9] __initdata =
-{
-	{0, 0},
-	{32, 4},
-	{64, 28},
-	{128, 96},
-	{256, 204},
-	{512, 440},
-	{1024, 942},
-	{2048, 1920},
-	{4096, 3932}
-};
-
-static int __init agp_find_max (void)
-{
-	long memory, index, result;
-
-	memory = virt_to_phys(high_memory) >> 20;
-	index = 1;
-
-	while ((memory > maxes_table[index].mem) &&
-	       (index < 8)) {
-		index++;
-	}
-
-	result = maxes_table[index - 1].agp +
-	   ( (memory - maxes_table[index - 1].mem)  *
-	     (maxes_table[index].agp - maxes_table[index - 1].agp)) /
-	   (maxes_table[index].mem - maxes_table[index - 1].mem);
-
-	printk(KERN_INFO PFX "Maximum main memory to use "
-	       "for agp memory: %ldM\n", result);
-	result = result << (20 - PAGE_SHIFT);
-        return result;
-}
-
-#define AGPGART_VERSION_MAJOR 0
-#define AGPGART_VERSION_MINOR 99
-
-static struct agp_version agp_current_version =
-{
-	.major	= AGPGART_VERSION_MAJOR,
-	.minor	= AGPGART_VERSION_MINOR,
-};
-
-static int __init agp_backend_initialize(struct pci_dev *dev)
-{
-	int size_value, rc, got_gatt=0, got_keylist=0;
-
-	memset(&agp_bridge, 0, sizeof(struct agp_bridge_data));
-	agp_bridge.type = NOT_SUPPORTED;
-	agp_bridge.max_memory_agp = agp_find_max();
-	agp_bridge.version = &agp_current_version;
-
-	rc = agp_find_supported_device(dev);
-	if (rc) {
-		/* not KERN_ERR because error msg should have already printed */
-		printk(KERN_DEBUG PFX "no supported devices found.\n");
-		return rc;
-	}
-
-	if (agp_bridge.needs_scratch_page == TRUE) {
-		void *addr;
-		addr = agp_bridge.agp_alloc_page();
-
-		if (addr == NULL) {
-			printk(KERN_ERR PFX "unable to get memory for "
-			       "scratch page.\n");
-			return -ENOMEM;
-		}
-		agp_bridge.scratch_page = virt_to_phys(addr);
-		agp_bridge.scratch_page =
-		    agp_bridge.mask_memory(agp_bridge.scratch_page, 0);
-	}
-
-	size_value = agp_bridge.fetch_size();
-
-	if (size_value == 0) {
-		printk(KERN_ERR PFX "unable to determine aperture size.\n");
-		rc = -EINVAL;
-		goto err_out;
-	}
-	if (agp_bridge.create_gatt_table()) {
-		printk(KERN_ERR PFX "unable to get memory for graphics "
-		       "translation table.\n");
-		rc = -ENOMEM;
-		goto err_out;
-	}
-	got_gatt = 1;
-	
-	agp_bridge.key_list = vmalloc(PAGE_SIZE * 4);
-	if (agp_bridge.key_list == NULL) {
-		printk(KERN_ERR PFX "error allocating memory for key lists.\n");
-		rc = -ENOMEM;
-		goto err_out;
-	}
-	got_keylist = 1;
-	
-	/* FIXME vmalloc'd memory not guaranteed contiguous */
-	memset(agp_bridge.key_list, 0, PAGE_SIZE * 4);
-
-	if (agp_bridge.configure()) {
-		printk(KERN_ERR PFX "error configuring host chipset.\n");
-		rc = -EINVAL;
-		goto err_out;
-	}
-
-	printk(KERN_INFO PFX "AGP aperture is %dM @ 0x%lx\n",
-	       size_value, agp_bridge.gart_bus_addr);
-
-	return 0;
-
-err_out:
-	if (agp_bridge.needs_scratch_page == TRUE) {
-		agp_bridge.scratch_page &= ~(0x00000fff);
-		agp_bridge.agp_destroy_page(phys_to_virt(agp_bridge.scratch_page));
-	}
-	if (got_gatt)
-		agp_bridge.free_gatt_table();
-	if (got_keylist)
-		vfree(agp_bridge.key_list);
-	return rc;
-}
-
-
-/* cannot be __exit b/c as it could be called from __init code */
-static void agp_backend_cleanup(void)
-{
-	agp_bridge.cleanup();
-	agp_bridge.free_gatt_table();
-	vfree(agp_bridge.key_list);
-
-	if (agp_bridge.needs_scratch_page == TRUE) {
-		agp_bridge.scratch_page &= ~(0x00000fff);
-		agp_bridge.agp_destroy_page(phys_to_virt(agp_bridge.scratch_page));
-	}
-}
-
-static int agp_power(struct pm_dev *dev, pm_request_t rq, void *data)
-{
-	switch(rq)
-	{
-		case PM_SUSPEND:
-			return agp_bridge.suspend();
-		case PM_RESUME:
-			agp_bridge.resume();
-			return 0;
-	}		
-	return 0;
-}
-
-extern int agp_frontend_initialize(void);
-extern void agp_frontend_cleanup(void);
-
-static const drm_agp_t drm_agp = {
-	&agp_free_memory,
-	&agp_allocate_memory,
-	&agp_bind_memory,
-	&agp_unbind_memory,
-	&agp_enable,
-	&agp_backend_acquire,
-	&agp_backend_release,
-	&agp_copy_info
-};
-
-static int agp_probe (struct pci_dev *dev, const struct pci_device_id *ent)
-{
-	int ret_val;
-
-	if (agp_bridge.type != NOT_SUPPORTED) {
-		printk (KERN_DEBUG PFX "Oops, don't init more than one agpgart device.\n");
-		return -ENODEV;
-	}
-
-	ret_val = agp_backend_initialize(dev);
-	if (ret_val) {
-		agp_bridge.type = NOT_SUPPORTED;
-		return ret_val;
-	}
-	ret_val = agp_frontend_initialize();
-	if (ret_val) {
-		agp_bridge.type = NOT_SUPPORTED;
-		agp_backend_cleanup();
-		return ret_val;
-	}
-
-	inter_module_register("drm_agp", THIS_MODULE, &drm_agp);
-	
-	pm_register(PM_PCI_DEV, PM_PCI_ID(agp_bridge.dev), agp_power);
-	return 0;
-}
-
-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,
-	},
-	{ }
-};
-
-MODULE_DEVICE_TABLE(pci, agp_pci_table);
-
-static struct pci_driver agp_pci_driver = {
-	.name		= "agpgart",
-	.id_table	= agp_pci_table,
-	.probe		= agp_probe,
-};
-
-int __init agp_init(void)
-{
-	int ret_val;
-
-	printk(KERN_INFO "Linux agpgart interface v%d.%d (c) Jeff Hartmann\n",
-	       AGPGART_VERSION_MAJOR, AGPGART_VERSION_MINOR);
-
-	ret_val = pci_module_init(&agp_pci_driver);
-	if (ret_val) {
-		agp_bridge.type = NOT_SUPPORTED;
-		return ret_val;
-	}
-	return 0;
-}
-
-static void __exit agp_cleanup(void)
-{
-	pci_unregister_driver(&agp_pci_driver);
-	if (agp_bridge.type != NOT_SUPPORTED) {
-		pm_unregister_all(agp_power);
-		agp_frontend_cleanup();
-		agp_backend_cleanup();
-		inter_module_unregister("drm_agp");
-	}
-}
-
-#ifndef CONFIG_GART_IOMMU
-module_init(agp_init);
-module_exit(agp_cleanup);
-#endif
diff -Nru a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
--- a/drivers/char/agp/agp.h	Mon Dec  9 18:46:36 2002
+++ b/drivers/char/agp/agp.h	Mon Dec  9 18:46:36 2002
@@ -47,6 +47,7 @@
 void agp_free_key(int key);
 
 /* chipset specific init routines. */
+/*
 int __init ali_generic_setup (struct pci_dev *pdev);
 int __init amd_irongate_setup (struct pci_dev *pdev);
 int __init amd_8151_setup (struct pci_dev *pdev);
@@ -65,10 +66,12 @@
 int __init serverworks_setup (struct pci_dev *pdev);
 int __init sis_generic_setup (struct pci_dev *pdev);
 int __init via_generic_setup (struct pci_dev *pdev);
+*/
 
-#define AGPGART_MODULE_NAME	"agpgart"
-#define PFX			AGPGART_MODULE_NAME ": "
+#define PFX "agpgart: "
 
+int agp_register_driver (struct pci_dev *dev);
+int agp_unregister_driver(void);
 
 #ifdef CONFIG_SMP
 static void ipi_handler(void *null)
@@ -380,5 +383,27 @@
 #define HP_ZX1_TCNFG		0x318
 #define HP_ZX1_PDIR_BASE	0x320
 #define HP_ZX1_CACHE_FLUSH	0x428
+
+struct agp_device_ids {
+	unsigned short device_id; /* first, to make table easier to read */
+	enum chipset_type chipset;
+	const char *chipset_name;
+	int (*chipset_setup) (struct pci_dev *pdev);	/* used to override generic */
+};
+
+struct agp_bridge_info {
+	unsigned short vendor_id;
+	const char *vendor_name;
+	int (*chipset_setup) (struct pci_dev *pdev);
+	struct agp_device_ids *ids;
+};
+
+extern struct agp_bridge_info ali_agp_bridge_info;
+extern struct agp_bridge_info amd_k8_agp_bridge_info;
+extern struct agp_bridge_info amd_agp_bridge_info;
+extern struct agp_bridge_info intel_agp_bridge_info;
+extern struct agp_bridge_info sis_agp_bridge_info;
+extern struct agp_bridge_info via_agp_bridge_info;
+extern struct agp_bridge_info hp_agp_bridge_info;
 
 #endif				/* _AGP_BACKEND_PRIV_H */
diff -Nru a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
--- a/drivers/char/agp/ali-agp.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/char/agp/ali-agp.c	Mon Dec  9 18:46:50 2002
@@ -1,38 +1,16 @@
 /*
- * AGPGART module version 0.99
- * Copyright (C) 1999 Jeff Hartmann
- * Copyright (C) 1999 Precision Insight, Inc.
- * Copyright (C) 1999 Xi Graphics, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
- * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * TODO: 
- * - Allocate more than order 0 pages to avoid too much linear map splitting.
+ * ALi AGPGART routines.
  */
-#include <linux/config.h>
+
 #include <linux/types.h>
-#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/agp_backend.h>
 #include "agp.h"
 
+static int agp_try_unsupported __initdata = 0;
+
 static int ali_fetch_size(void)
 {
 	int i;
@@ -96,21 +74,8 @@
 	pci_write_config_dword(agp_bridge.dev, ALI_ATTBASE, temp);
 
 	/* tlb control */
-
-	/*
-	 *	Question: Jeff, ALi's patch deletes this:
-	 *
-	 *	pci_read_config_dword(agp_bridge.dev, ALI_TLBCTRL, &temp);
-	 *	pci_write_config_dword(agp_bridge.dev, ALI_TLBCTRL,
-	 *			       ((temp & 0xffffff00) | 0x00000010));
-	 *
-	 *	and replaces it with the following, which seems to duplicate the
-	 *	next couple of lines below it. I suspect this was an oversight,
-	 *	but you might want to check up on this?
-	 */
-	
-	pci_read_config_dword(agp_bridge.dev, ALI_APBASE, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+	pci_read_config_dword(agp_bridge.dev, ALI_TLBCTRL, &temp);
+	pci_write_config_dword(agp_bridge.dev, ALI_TLBCTRL, ((temp & 0xffffff00) | 0x00000010));
 
 	/* address to map to */
 	pci_read_config_dword(agp_bridge.dev, ALI_APBASE, &temp);
@@ -257,9 +222,180 @@
 	agp_bridge.suspend = agp_generic_suspend;
 	agp_bridge.resume = agp_generic_resume;
 	agp_bridge.cant_use_aperture = 0;
-
 	return 0;
+}
+
+struct agp_device_ids ali_agp_device_ids[] __initdata =
+{
+	{
+		.device_id	= PCI_DEVICE_ID_AL_M1541,
+		.chipset	= ALI_M1541,
+		.chipset_name	= "M1541",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_AL_M1621,
+		.chipset	= ALI_M1621,
+		.chipset_name	= "M1621",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_AL_M1631,
+		.chipset	= ALI_M1631,
+		.chipset_name	= "M1631",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_AL_M1632,
+		.chipset	= ALI_M1632,
+		.chipset_name	= "M1632",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_AL_M1641,
+		.chipset	= ALI_M1641,
+		.chipset_name	= "M1641",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_AL_M1644,
+		.chipset	= ALI_M1644,
+		.chipset_name	= "M1644",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_AL_M1647,
+		.chipset	= ALI_M1647,
+		.chipset_name	= "M1647",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_AL_M1651,
+		.chipset	= ALI_M1651,
+		.chipset_name	= "M1651",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_AL_M1671,
+		.chipset	= ALI_M1671,
+		.chipset_name	= "M1671",
+	},
+	{ }, /* dummy final entry, always present */
+};
+
+/* scan table above for supported devices */
+static int __init agp_lookup_host_bridge (struct pci_dev *pdev)
+{
+	int j=0;
+	struct agp_device_ids *devs;
 	
-	(void) pdev; /* unused */
+	devs = ali_agp_device_ids;
+
+	while (devs[j].chipset_name != NULL) {
+		if (pdev->device == devs[j].device_id) {
+			if (pdev->device == PCI_DEVICE_ID_AL_M1621) {
+				u8 hidden_1621_id;
+
+				pci_read_config_byte(pdev, 0xFB, &hidden_1621_id);
+				switch (hidden_1621_id) {
+				case 0x31:
+					devs[j].chipset_name="M1631";
+					break;
+				case 0x32:
+					devs[j].chipset_name="M1632";
+					break;
+				case 0x41:
+					devs[j].chipset_name="M1641";
+					break;
+				case 0x43:
+					break;
+				case 0x47:
+					devs[j].chipset_name="M1647";
+					break;
+				case 0x51:
+					devs[j].chipset_name="M1651";
+					break;
+				default:
+					break;
+				}
+			}
+
+			printk (KERN_INFO PFX "Detected ALi %s chipset\n",
+				devs[j].chipset_name);
+			agp_bridge.type = devs[j].chipset;
+
+			if (devs[j].chipset_setup != NULL)
+				return devs[j].chipset_setup(pdev);
+			else
+				return ali_generic_setup(pdev);
+		}
+		j++;
+	}
+
+	/* try init anyway, if user requests it */
+	if (agp_try_unsupported) {
+		printk(KERN_WARNING PFX "Trying generic ALi routines"
+		       " for device id: %04x\n", pdev->device);
+		agp_bridge.type = ALI_GENERIC;
+		return ali_generic_setup(pdev);
+	}
+
+	printk(KERN_ERR PFX "Unsupported ALi chipset (device id: %04x),"
+		" you might want to try agp_try_unsupported=1.\n", pdev->device);
+	return -ENODEV;
 }
+
+
+
+
+static int agp_ali_probe (struct pci_dev *dev, const struct pci_device_id *ent)
+{
+	if (pci_find_capability(dev, PCI_CAP_ID_AGP)==0)
+		return -ENODEV;
+
+	agp_bridge.dev = dev;
+
+	/* probe for known chipsets */
+	if (agp_lookup_host_bridge (dev) != -ENODEV ) {
+		agp_register_driver(dev);
+		return 0;
+	}
+	return -ENODEV;	
+}
+
+static struct pci_device_id agp_ali_pci_table[] __initdata = {
+	{
+	.class		= (PCI_CLASS_BRIDGE_HOST << 8),
+	.class_mask	= ~0,
+	.vendor		= PCI_VENDOR_ID_AL,
+	.device		= PCI_ANY_ID,
+	.subvendor	= PCI_ANY_ID,
+	.subdevice	= PCI_ANY_ID,
+	},
+	{ }
+};
+
+MODULE_DEVICE_TABLE(pci, agp_ali_pci_table);
+
+static struct pci_driver agp_ali_pci_driver = {
+	.name		= "agpgart-ali",
+	.id_table	= agp_ali_pci_table,
+	.probe		= agp_ali_probe,
+};
+
+static int __init agp_ali_init(void)
+{
+	int ret_val;
+
+	ret_val = pci_module_init(&agp_ali_pci_driver);
+	if (ret_val)
+		agp_bridge.type = NOT_SUPPORTED;
+
+	return ret_val;
+}
+
+static void __exit agp_ali_cleanup(void)
+{
+	agp_unregister_driver();
+	pci_unregister_driver(&agp_ali_pci_driver);
+}
+
+module_init(agp_ali_init);
+module_exit(agp_ali_cleanup);
+
+MODULE_PARM(agp_try_unsupported, "1i");
+MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
+MODULE_LICENSE("GPL and additional rights");
 
diff -Nru a/drivers/char/agp/amd-agp.c b/drivers/char/agp/amd-agp.c
--- a/drivers/char/agp/amd-agp.c	Mon Dec  9 18:46:52 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,408 +0,0 @@
-/*
- * AGPGART module version 0.99
- * Copyright (C) 1999 Jeff Hartmann
- * Copyright (C) 1999 Precision Insight, Inc.
- * Copyright (C) 1999 Xi Graphics, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
- * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * TODO: 
- * - Allocate more than order 0 pages to avoid too much linear map splitting.
- */
-
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/agp_backend.h>
-#include "agp.h"
-
-struct amd_page_map {
-	unsigned long *real;
-	unsigned long *remapped;
-};
-
-static struct _amd_irongate_private {
-	volatile u8 *registers;
-	struct amd_page_map **gatt_pages;
-	int num_tables;
-} amd_irongate_private;
-
-static int amd_create_page_map(struct amd_page_map *page_map)
-{
-	int i;
-
-	page_map->real = (unsigned long *) __get_free_page(GFP_KERNEL);
-	if (page_map->real == NULL) {
-		return -ENOMEM;
-	}
-	SetPageReserved(virt_to_page(page_map->real));
-	CACHE_FLUSH();
-	page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), 
-					    PAGE_SIZE);
-	if (page_map->remapped == NULL) {
-		ClearPageReserved(virt_to_page(page_map->real));
-		free_page((unsigned long) page_map->real);
-		page_map->real = NULL;
-		return -ENOMEM;
-	}
-	CACHE_FLUSH();
-
-	for(i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) {
-		page_map->remapped[i] = agp_bridge.scratch_page;
-	}
-
-	return 0;
-}
-
-static void amd_free_page_map(struct amd_page_map *page_map)
-{
-	iounmap(page_map->remapped);
-	ClearPageReserved(virt_to_page(page_map->real));
-	free_page((unsigned long) page_map->real);
-}
-
-static void amd_free_gatt_pages(void)
-{
-	int i;
-	struct amd_page_map **tables;
-	struct amd_page_map *entry;
-
-	tables = amd_irongate_private.gatt_pages;
-	for(i = 0; i < amd_irongate_private.num_tables; i++) {
-		entry = tables[i];
-		if (entry != NULL) {
-			if (entry->real != NULL) {
-				amd_free_page_map(entry);
-			}
-			kfree(entry);
-		}
-	}
-	kfree(tables);
-}
-
-static int amd_create_gatt_pages(int nr_tables)
-{
-	struct amd_page_map **tables;
-	struct amd_page_map *entry;
-	int retval = 0;
-	int i;
-
-	tables = kmalloc((nr_tables + 1) * sizeof(struct amd_page_map *), 
-			 GFP_KERNEL);
-	if (tables == NULL) {
-		return -ENOMEM;
-	}
-	memset(tables, 0, sizeof(struct amd_page_map *) * (nr_tables + 1));
-	for (i = 0; i < nr_tables; i++) {
-		entry = kmalloc(sizeof(struct amd_page_map), GFP_KERNEL);
-		if (entry == NULL) {
-			retval = -ENOMEM;
-			break;
-		}
-		memset(entry, 0, sizeof(struct amd_page_map));
-		tables[i] = entry;
-		retval = amd_create_page_map(entry);
-		if (retval != 0) break;
-	}
-	amd_irongate_private.num_tables = nr_tables;
-	amd_irongate_private.gatt_pages = tables;
-
-	if (retval != 0) amd_free_gatt_pages();
-
-	return retval;
-}
-
-/* Since we don't need contigious memory we just try
- * to get the gatt table once
- */
-
-#define GET_PAGE_DIR_OFF(addr) (addr >> 22)
-#define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr) - \
-	GET_PAGE_DIR_OFF(agp_bridge.gart_bus_addr))
-#define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12) 
-#define GET_GATT(addr) (amd_irongate_private.gatt_pages[\
-	GET_PAGE_DIR_IDX(addr)]->remapped)
-
-static int amd_create_gatt_table(void)
-{
-	struct aper_size_info_lvl2 *value;
-	struct amd_page_map page_dir;
-	unsigned long addr;
-	int retval;
-	u32 temp;
-	int i;
-
-	value = A_SIZE_LVL2(agp_bridge.current_size);
-	retval = amd_create_page_map(&page_dir);
-	if (retval != 0) {
-		return retval;
-	}
-
-	retval = amd_create_gatt_pages(value->num_entries / 1024);
-	if (retval != 0) {
-		amd_free_page_map(&page_dir);
-		return retval;
-	}
-
-	agp_bridge.gatt_table_real = page_dir.real;
-	agp_bridge.gatt_table = page_dir.remapped;
-	agp_bridge.gatt_bus_addr = virt_to_phys(page_dir.real);
-
-	/* Get the address for the gart region.
-	 * This is a bus address even on the alpha, b/c its
-	 * used to program the agp master not the cpu
-	 */
-
-	pci_read_config_dword(agp_bridge.dev, AMD_APBASE, &temp);
-	addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
-	agp_bridge.gart_bus_addr = addr;
-
-	/* Calculate the agp offset */
-	for(i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) {
-		page_dir.remapped[GET_PAGE_DIR_OFF(addr)] =
-			virt_to_phys(amd_irongate_private.gatt_pages[i]->real);
-		page_dir.remapped[GET_PAGE_DIR_OFF(addr)] |= 0x00000001;
-	}
-
-	return 0;
-}
-
-static int amd_free_gatt_table(void)
-{
-	struct amd_page_map page_dir;
-   
-	page_dir.real = agp_bridge.gatt_table_real;
-	page_dir.remapped = agp_bridge.gatt_table;
-
-	amd_free_gatt_pages();
-	amd_free_page_map(&page_dir);
-	return 0;
-}
-
-static int amd_irongate_fetch_size(void)
-{
-	int i;
-	u32 temp;
-	struct aper_size_info_lvl2 *values;
-
-	pci_read_config_dword(agp_bridge.dev, AMD_APSIZE, &temp);
-	temp = (temp & 0x0000000e);
-	values = A_SIZE_LVL2(agp_bridge.aperture_sizes);
-	for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
-		if (temp == values[i].size_value) {
-			agp_bridge.previous_size =
-			    agp_bridge.current_size = (void *) (values + i);
-
-			agp_bridge.aperture_size_idx = i;
-			return values[i].size;
-		}
-	}
-
-	return 0;
-}
-
-static int amd_irongate_configure(void)
-{
-	struct aper_size_info_lvl2 *current_size;
-	u32 temp;
-	u16 enable_reg;
-
-	current_size = A_SIZE_LVL2(agp_bridge.current_size);
-
-	/* Get the memory mapped registers */
-	pci_read_config_dword(agp_bridge.dev, AMD_MMBASE, &temp);
-	temp = (temp & PCI_BASE_ADDRESS_MEM_MASK);
-	amd_irongate_private.registers = (volatile u8 *) ioremap(temp, 4096);
-
-	/* Write out the address of the gatt table */
-	OUTREG32(amd_irongate_private.registers, AMD_ATTBASE,
-		 agp_bridge.gatt_bus_addr);
-
-	/* Write the Sync register */
-	pci_write_config_byte(agp_bridge.dev, AMD_MODECNTL, 0x80);
-   
-   	/* Set indexing mode */
-   	pci_write_config_byte(agp_bridge.dev, AMD_MODECNTL2, 0x00);
-
-	/* Write the enable register */
-	enable_reg = INREG16(amd_irongate_private.registers, AMD_GARTENABLE);
-	enable_reg = (enable_reg | 0x0004);
-	OUTREG16(amd_irongate_private.registers, AMD_GARTENABLE, enable_reg);
-
-	/* Write out the size register */
-	pci_read_config_dword(agp_bridge.dev, AMD_APSIZE, &temp);
-	temp = (((temp & ~(0x0000000e)) | current_size->size_value)
-		| 0x00000001);
-	pci_write_config_dword(agp_bridge.dev, AMD_APSIZE, temp);
-
-	/* Flush the tlb */
-	OUTREG32(amd_irongate_private.registers, AMD_TLBFLUSH, 0x00000001);
-
-	return 0;
-}
-
-static void amd_irongate_cleanup(void)
-{
-	struct aper_size_info_lvl2 *previous_size;
-	u32 temp;
-	u16 enable_reg;
-
-	previous_size = A_SIZE_LVL2(agp_bridge.previous_size);
-
-	enable_reg = INREG16(amd_irongate_private.registers, AMD_GARTENABLE);
-	enable_reg = (enable_reg & ~(0x0004));
-	OUTREG16(amd_irongate_private.registers, AMD_GARTENABLE, enable_reg);
-
-	/* Write back the previous size and disable gart translation */
-	pci_read_config_dword(agp_bridge.dev, AMD_APSIZE, &temp);
-	temp = ((temp & ~(0x0000000f)) | previous_size->size_value);
-	pci_write_config_dword(agp_bridge.dev, AMD_APSIZE, temp);
-	iounmap((void *) amd_irongate_private.registers);
-}
-
-/*
- * This routine could be implemented by taking the addresses
- * written to the GATT, and flushing them individually.  However
- * currently it just flushes the whole table.  Which is probably
- * more efficent, since agp_memory blocks can be a large number of
- * entries.
- */
-
-static void amd_irongate_tlbflush(agp_memory * temp)
-{
-	OUTREG32(amd_irongate_private.registers, AMD_TLBFLUSH, 0x00000001);
-}
-
-static unsigned long amd_irongate_mask_memory(unsigned long addr, int type)
-{
-	/* Only type 0 is supported by the irongate */
-
-	return addr | agp_bridge.masks[0].mask;
-}
-
-static int amd_insert_memory(agp_memory * mem,
-			     off_t pg_start, int type)
-{
-	int i, j, num_entries;
-	unsigned long *cur_gatt;
-	unsigned long addr;
-
-	num_entries = A_SIZE_LVL2(agp_bridge.current_size)->num_entries;
-
-	if (type != 0 || mem->type != 0) {
-		return -EINVAL;
-	}
-	if ((pg_start + mem->page_count) > num_entries) {
-		return -EINVAL;
-	}
-
-	j = pg_start;
-	while (j < (pg_start + mem->page_count)) {
-		addr = (j * PAGE_SIZE) + agp_bridge.gart_bus_addr;
-		cur_gatt = GET_GATT(addr);
-		if (!PGE_EMPTY(cur_gatt[GET_GATT_OFF(addr)])) {
-			return -EBUSY;
-		}
-		j++;
-	}
-
-	if (mem->is_flushed == FALSE) {
-		CACHE_FLUSH();
-		mem->is_flushed = TRUE;
-	}
-
-	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
-		addr = (j * PAGE_SIZE) + agp_bridge.gart_bus_addr;
-		cur_gatt = GET_GATT(addr);
-		cur_gatt[GET_GATT_OFF(addr)] = mem->memory[i];
-	}
-	agp_bridge.tlb_flush(mem);
-	return 0;
-}
-
-static int amd_remove_memory(agp_memory * mem, off_t pg_start,
-			     int type)
-{
-	int i;
-	unsigned long *cur_gatt;
-	unsigned long addr;
-
-	if (type != 0 || mem->type != 0) {
-		return -EINVAL;
-	}
-	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
-		addr = (i * PAGE_SIZE) + agp_bridge.gart_bus_addr;
-		cur_gatt = GET_GATT(addr);
-		cur_gatt[GET_GATT_OFF(addr)] = 
-			(unsigned long) agp_bridge.scratch_page;
-	}
-
-	agp_bridge.tlb_flush(mem);
-	return 0;
-}
-
-static struct aper_size_info_lvl2 amd_irongate_sizes[7] =
-{
-	{2048, 524288, 0x0000000c},
-	{1024, 262144, 0x0000000a},
-	{512, 131072, 0x00000008},
-	{256, 65536, 0x00000006},
-	{128, 32768, 0x00000004},
-	{64, 16384, 0x00000002},
-	{32, 8192, 0x00000000}
-};
-
-static struct gatt_mask amd_irongate_masks[] =
-{
-	{.mask = 0x00000001, .type = 0}
-};
-
-int __init amd_irongate_setup (struct pci_dev *pdev)
-{
-	agp_bridge.masks = amd_irongate_masks;
-	agp_bridge.num_of_masks = 1;
-	agp_bridge.aperture_sizes = (void *) amd_irongate_sizes;
-	agp_bridge.size_type = LVL2_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 7;
-	agp_bridge.dev_private_data = (void *) &amd_irongate_private;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = amd_irongate_configure;
-	agp_bridge.fetch_size = amd_irongate_fetch_size;
-	agp_bridge.cleanup = amd_irongate_cleanup;
-	agp_bridge.tlb_flush = amd_irongate_tlbflush;
-	agp_bridge.mask_memory = amd_irongate_mask_memory;
-	agp_bridge.agp_enable = agp_generic_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = amd_create_gatt_table;
-	agp_bridge.free_gatt_table = amd_free_gatt_table;
-	agp_bridge.insert_memory = amd_insert_memory;
-	agp_bridge.remove_memory = amd_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
-
-	return 0;
-	
-	(void) pdev; /* unused */
-}
-
diff -Nru a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/agp/amd-k7-agp.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,505 @@
+/*
+ * AMD K7 AGPGART routines.
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/agp_backend.h>
+#include "agp.h"
+
+static int agp_try_unsupported __initdata = 0;
+
+struct amd_page_map {
+	unsigned long *real;
+	unsigned long *remapped;
+};
+
+static struct _amd_irongate_private {
+	volatile u8 *registers;
+	struct amd_page_map **gatt_pages;
+	int num_tables;
+} amd_irongate_private;
+
+static int amd_create_page_map(struct amd_page_map *page_map)
+{
+	int i;
+
+	page_map->real = (unsigned long *) __get_free_page(GFP_KERNEL);
+	if (page_map->real == NULL) {
+		return -ENOMEM;
+	}
+	SetPageReserved(virt_to_page(page_map->real));
+	CACHE_FLUSH();
+	page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), 
+					    PAGE_SIZE);
+	if (page_map->remapped == NULL) {
+		ClearPageReserved(virt_to_page(page_map->real));
+		free_page((unsigned long) page_map->real);
+		page_map->real = NULL;
+		return -ENOMEM;
+	}
+	CACHE_FLUSH();
+
+	for(i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) {
+		page_map->remapped[i] = agp_bridge.scratch_page;
+	}
+
+	return 0;
+}
+
+static void amd_free_page_map(struct amd_page_map *page_map)
+{
+	iounmap(page_map->remapped);
+	ClearPageReserved(virt_to_page(page_map->real));
+	free_page((unsigned long) page_map->real);
+}
+
+static void amd_free_gatt_pages(void)
+{
+	int i;
+	struct amd_page_map **tables;
+	struct amd_page_map *entry;
+
+	tables = amd_irongate_private.gatt_pages;
+	for(i = 0; i < amd_irongate_private.num_tables; i++) {
+		entry = tables[i];
+		if (entry != NULL) {
+			if (entry->real != NULL) {
+				amd_free_page_map(entry);
+			}
+			kfree(entry);
+		}
+	}
+	kfree(tables);
+}
+
+static int amd_create_gatt_pages(int nr_tables)
+{
+	struct amd_page_map **tables;
+	struct amd_page_map *entry;
+	int retval = 0;
+	int i;
+
+	tables = kmalloc((nr_tables + 1) * sizeof(struct amd_page_map *), 
+			 GFP_KERNEL);
+	if (tables == NULL) {
+		return -ENOMEM;
+	}
+	memset(tables, 0, sizeof(struct amd_page_map *) * (nr_tables + 1));
+	for (i = 0; i < nr_tables; i++) {
+		entry = kmalloc(sizeof(struct amd_page_map), GFP_KERNEL);
+		if (entry == NULL) {
+			retval = -ENOMEM;
+			break;
+		}
+		memset(entry, 0, sizeof(struct amd_page_map));
+		tables[i] = entry;
+		retval = amd_create_page_map(entry);
+		if (retval != 0) break;
+	}
+	amd_irongate_private.num_tables = nr_tables;
+	amd_irongate_private.gatt_pages = tables;
+
+	if (retval != 0) amd_free_gatt_pages();
+
+	return retval;
+}
+
+/* Since we don't need contigious memory we just try
+ * to get the gatt table once
+ */
+
+#define GET_PAGE_DIR_OFF(addr) (addr >> 22)
+#define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr) - \
+	GET_PAGE_DIR_OFF(agp_bridge.gart_bus_addr))
+#define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12) 
+#define GET_GATT(addr) (amd_irongate_private.gatt_pages[\
+	GET_PAGE_DIR_IDX(addr)]->remapped)
+
+static int amd_create_gatt_table(void)
+{
+	struct aper_size_info_lvl2 *value;
+	struct amd_page_map page_dir;
+	unsigned long addr;
+	int retval;
+	u32 temp;
+	int i;
+
+	value = A_SIZE_LVL2(agp_bridge.current_size);
+	retval = amd_create_page_map(&page_dir);
+	if (retval != 0) {
+		return retval;
+	}
+
+	retval = amd_create_gatt_pages(value->num_entries / 1024);
+	if (retval != 0) {
+		amd_free_page_map(&page_dir);
+		return retval;
+	}
+
+	agp_bridge.gatt_table_real = (u32 *)page_dir.real;
+	agp_bridge.gatt_table = (u32 *)page_dir.remapped;
+	agp_bridge.gatt_bus_addr = virt_to_phys(page_dir.real);
+
+	/* Get the address for the gart region.
+	 * This is a bus address even on the alpha, b/c its
+	 * used to program the agp master not the cpu
+	 */
+
+	pci_read_config_dword(agp_bridge.dev, AMD_APBASE, &temp);
+	addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+	agp_bridge.gart_bus_addr = addr;
+
+	/* Calculate the agp offset */
+	for(i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) {
+		page_dir.remapped[GET_PAGE_DIR_OFF(addr)] =
+			virt_to_phys(amd_irongate_private.gatt_pages[i]->real);
+		page_dir.remapped[GET_PAGE_DIR_OFF(addr)] |= 0x00000001;
+	}
+
+	return 0;
+}
+
+static int amd_free_gatt_table(void)
+{
+	struct amd_page_map page_dir;
+   
+	page_dir.real = (u32 *)agp_bridge.gatt_table_real;
+	page_dir.remapped = (u32 *)agp_bridge.gatt_table;
+
+	amd_free_gatt_pages();
+	amd_free_page_map(&page_dir);
+	return 0;
+}
+
+static int amd_irongate_fetch_size(void)
+{
+	int i;
+	u32 temp;
+	struct aper_size_info_lvl2 *values;
+
+	pci_read_config_dword(agp_bridge.dev, AMD_APSIZE, &temp);
+	temp = (temp & 0x0000000e);
+	values = A_SIZE_LVL2(agp_bridge.aperture_sizes);
+	for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+		if (temp == values[i].size_value) {
+			agp_bridge.previous_size =
+			    agp_bridge.current_size = (void *) (values + i);
+
+			agp_bridge.aperture_size_idx = i;
+			return values[i].size;
+		}
+	}
+
+	return 0;
+}
+
+static int amd_irongate_configure(void)
+{
+	struct aper_size_info_lvl2 *current_size;
+	u32 temp;
+	u16 enable_reg;
+
+	current_size = A_SIZE_LVL2(agp_bridge.current_size);
+
+	/* Get the memory mapped registers */
+	pci_read_config_dword(agp_bridge.dev, AMD_MMBASE, &temp);
+	temp = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+	amd_irongate_private.registers = (volatile u8 *) ioremap(temp, 4096);
+
+	/* Write out the address of the gatt table */
+	OUTREG32(amd_irongate_private.registers, AMD_ATTBASE,
+		 agp_bridge.gatt_bus_addr);
+
+	/* Write the Sync register */
+	pci_write_config_byte(agp_bridge.dev, AMD_MODECNTL, 0x80);
+   
+   	/* Set indexing mode */
+   	pci_write_config_byte(agp_bridge.dev, AMD_MODECNTL2, 0x00);
+
+	/* Write the enable register */
+	enable_reg = INREG16(amd_irongate_private.registers, AMD_GARTENABLE);
+	enable_reg = (enable_reg | 0x0004);
+	OUTREG16(amd_irongate_private.registers, AMD_GARTENABLE, enable_reg);
+
+	/* Write out the size register */
+	pci_read_config_dword(agp_bridge.dev, AMD_APSIZE, &temp);
+	temp = (((temp & ~(0x0000000e)) | current_size->size_value)
+		| 0x00000001);
+	pci_write_config_dword(agp_bridge.dev, AMD_APSIZE, temp);
+
+	/* Flush the tlb */
+	OUTREG32(amd_irongate_private.registers, AMD_TLBFLUSH, 0x00000001);
+
+	return 0;
+}
+
+static void amd_irongate_cleanup(void)
+{
+	struct aper_size_info_lvl2 *previous_size;
+	u32 temp;
+	u16 enable_reg;
+
+	previous_size = A_SIZE_LVL2(agp_bridge.previous_size);
+
+	enable_reg = INREG16(amd_irongate_private.registers, AMD_GARTENABLE);
+	enable_reg = (enable_reg & ~(0x0004));
+	OUTREG16(amd_irongate_private.registers, AMD_GARTENABLE, enable_reg);
+
+	/* Write back the previous size and disable gart translation */
+	pci_read_config_dword(agp_bridge.dev, AMD_APSIZE, &temp);
+	temp = ((temp & ~(0x0000000f)) | previous_size->size_value);
+	pci_write_config_dword(agp_bridge.dev, AMD_APSIZE, temp);
+	iounmap((void *) amd_irongate_private.registers);
+}
+
+/*
+ * This routine could be implemented by taking the addresses
+ * written to the GATT, and flushing them individually.  However
+ * currently it just flushes the whole table.  Which is probably
+ * more efficent, since agp_memory blocks can be a large number of
+ * entries.
+ */
+
+static void amd_irongate_tlbflush(agp_memory * temp)
+{
+	OUTREG32(amd_irongate_private.registers, AMD_TLBFLUSH, 0x00000001);
+}
+
+static unsigned long amd_irongate_mask_memory(unsigned long addr, int type)
+{
+	/* Only type 0 is supported by the irongate */
+
+	return addr | agp_bridge.masks[0].mask;
+}
+
+static int amd_insert_memory(agp_memory * mem,
+			     off_t pg_start, int type)
+{
+	int i, j, num_entries;
+	unsigned long *cur_gatt;
+	unsigned long addr;
+
+	num_entries = A_SIZE_LVL2(agp_bridge.current_size)->num_entries;
+
+	if (type != 0 || mem->type != 0) {
+		return -EINVAL;
+	}
+	if ((pg_start + mem->page_count) > num_entries) {
+		return -EINVAL;
+	}
+
+	j = pg_start;
+	while (j < (pg_start + mem->page_count)) {
+		addr = (j * PAGE_SIZE) + agp_bridge.gart_bus_addr;
+		cur_gatt = GET_GATT(addr);
+		if (!PGE_EMPTY(cur_gatt[GET_GATT_OFF(addr)])) {
+			return -EBUSY;
+		}
+		j++;
+	}
+
+	if (mem->is_flushed == FALSE) {
+		CACHE_FLUSH();
+		mem->is_flushed = TRUE;
+	}
+
+	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
+		addr = (j * PAGE_SIZE) + agp_bridge.gart_bus_addr;
+		cur_gatt = GET_GATT(addr);
+		cur_gatt[GET_GATT_OFF(addr)] = mem->memory[i];
+	}
+	agp_bridge.tlb_flush(mem);
+	return 0;
+}
+
+static int amd_remove_memory(agp_memory * mem, off_t pg_start,
+			     int type)
+{
+	int i;
+	unsigned long *cur_gatt;
+	unsigned long addr;
+
+	if (type != 0 || mem->type != 0) {
+		return -EINVAL;
+	}
+	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
+		addr = (i * PAGE_SIZE) + agp_bridge.gart_bus_addr;
+		cur_gatt = GET_GATT(addr);
+		cur_gatt[GET_GATT_OFF(addr)] = 
+			(unsigned long) agp_bridge.scratch_page;
+	}
+
+	agp_bridge.tlb_flush(mem);
+	return 0;
+}
+
+static struct aper_size_info_lvl2 amd_irongate_sizes[7] =
+{
+	{2048, 524288, 0x0000000c},
+	{1024, 262144, 0x0000000a},
+	{512, 131072, 0x00000008},
+	{256, 65536, 0x00000006},
+	{128, 32768, 0x00000004},
+	{64, 16384, 0x00000002},
+	{32, 8192, 0x00000000}
+};
+
+static struct gatt_mask amd_irongate_masks[] =
+{
+	{.mask = 0x00000001, .type = 0}
+};
+
+int __init amd_irongate_setup (struct pci_dev *pdev)
+{
+	agp_bridge.masks = amd_irongate_masks;
+	agp_bridge.num_of_masks = 1;
+	agp_bridge.aperture_sizes = (void *) amd_irongate_sizes;
+	agp_bridge.size_type = LVL2_APER_SIZE;
+	agp_bridge.num_aperture_sizes = 7;
+	agp_bridge.dev_private_data = (void *) &amd_irongate_private;
+	agp_bridge.needs_scratch_page = FALSE;
+	agp_bridge.configure = amd_irongate_configure;
+	agp_bridge.fetch_size = amd_irongate_fetch_size;
+	agp_bridge.cleanup = amd_irongate_cleanup;
+	agp_bridge.tlb_flush = amd_irongate_tlbflush;
+	agp_bridge.mask_memory = amd_irongate_mask_memory;
+	agp_bridge.agp_enable = agp_generic_agp_enable;
+	agp_bridge.cache_flush = global_cache_flush;
+	agp_bridge.create_gatt_table = amd_create_gatt_table;
+	agp_bridge.free_gatt_table = amd_free_gatt_table;
+	agp_bridge.insert_memory = amd_insert_memory;
+	agp_bridge.remove_memory = amd_remove_memory;
+	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge.free_by_type = agp_generic_free_by_type;
+	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.suspend = agp_generic_suspend;
+	agp_bridge.resume = agp_generic_resume;
+	agp_bridge.cant_use_aperture = 0;
+	return 0;
+}
+
+struct agp_device_ids amd_agp_device_ids[] __initdata =
+{
+	{
+		.device_id	= PCI_DEVICE_ID_AMD_FE_GATE_7006,
+		.chipset	= AMD_IRONGATE,
+		.chipset_name	= "Irongate",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_AMD_FE_GATE_700E,
+		.chipset	= AMD_761,
+		.chipset_name	= "761",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_AMD_FE_GATE_700C,
+		.chipset	= AMD_762,
+		.chipset_name	= "760MP",
+	},
+	{ }, /* dummy final entry, always present */
+};
+
+
+/* scan table above for supported devices */
+static int __init agp_lookup_host_bridge (struct pci_dev *pdev)
+{
+	int j=0;
+	struct agp_device_ids *devs;
+	
+	devs = amd_agp_device_ids;
+
+	while (devs[j].chipset_name != NULL) {
+		if (pdev->device == devs[j].device_id) {
+			printk (KERN_INFO PFX "Detected AMD %s chipset\n", devs[j].chipset_name);
+			agp_bridge.type = devs[j].chipset;
+
+			if (devs[j].chipset_setup != NULL)
+				return devs[j].chipset_setup(pdev);
+			else
+				return amd_irongate_setup(pdev);
+		}
+		j++;
+	}
+
+	/* try init anyway, if user requests it */
+	if (agp_try_unsupported) {
+		printk(KERN_WARNING PFX "Trying generic AMD routines"
+		       " for device id: %04x\n", pdev->device);
+		agp_bridge.type = AMD_GENERIC;
+		return amd_irongate_setup(pdev);
+	}
+
+	printk(KERN_ERR PFX "Unsupported AMD chipset (device id: %04x),"
+		" you might want to try agp_try_unsupported=1.\n", pdev->device);
+	return -ENODEV;
+}
+
+
+/* Supported Device Scanning routine */
+
+static int __init agp_find_supported_device(struct pci_dev *dev)
+{
+	agp_bridge.dev = dev;
+
+	if (pci_find_capability(dev, PCI_CAP_ID_AGP)==0)
+		return -ENODEV;
+
+	/* probe for known chipsets */
+	return agp_lookup_host_bridge (dev);
+}
+
+
+static int agp_amdk7_probe (struct pci_dev *dev, const struct pci_device_id *ent)
+{
+	if (agp_find_supported_device(dev) == 0) {
+		agp_register_driver(dev);
+		return 0;
+	}
+	return -ENODEV;	
+}
+
+static struct pci_device_id agp_amdk7_pci_table[] __initdata = {
+	{
+	.class		= (PCI_CLASS_BRIDGE_HOST << 8),
+	.class_mask	= ~0,
+	.vendor		= PCI_VENDOR_ID_AMD,
+	.device		= PCI_ANY_ID,
+	.subvendor	= PCI_ANY_ID,
+	.subdevice	= PCI_ANY_ID,
+	},
+	{ }
+};
+
+MODULE_DEVICE_TABLE(pci, agp_amdk7_pci_table);
+
+static struct pci_driver agp_amdk7_pci_driver = {
+	.name		= "agpgart-amdk7",
+	.id_table	= agp_amdk7_pci_table,
+	.probe		= agp_amdk7_probe,
+};
+
+static int __init agp_amdk7_init(void)
+{
+	int ret_val;
+
+	ret_val = pci_module_init(&agp_amdk7_pci_driver);
+	if (ret_val)
+		agp_bridge.type = NOT_SUPPORTED;
+
+	return ret_val;
+}
+
+static void __exit agp_amdk7_cleanup(void)
+{
+	agp_unregister_driver();
+	pci_unregister_driver(&agp_amdk7_pci_driver);
+}
+
+module_init(agp_amdk7_init);
+module_exit(agp_amdk7_cleanup);
+
+MODULE_PARM(agp_try_unsupported, "1i");
+MODULE_LICENSE("GPL and additional rights");
+
diff -Nru a/drivers/char/agp/amd-k8-agp.c b/drivers/char/agp/amd-k8-agp.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/agp/amd-k8-agp.c	Mon Dec  9 18:46:50 2002
@@ -0,0 +1,530 @@
+/* 
+ * Copyright 2001,2002 SuSE Labs
+ * Distributed under the GNU public license, v2.
+ * 
+ * This is a GART driver for the AMD K8 northbridge and the AMD 8151 
+ * AGP bridge. The main work is done in the northbridge. The configuration
+ * is only mirrored in the 8151 for compatibility (could be likely
+ * removed now).
+ */ 
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/agp_backend.h>
+#include "agp.h"
+
+extern int agp_memory_reserved;
+extern __u32 *agp_gatt_table; 
+
+static u_int64_t pci_read64 (struct pci_dev *dev, int reg)
+{
+	union {
+		u64 full;
+		struct {
+			u32 high;
+			u32 low;
+		} split;
+	} tmp;
+	pci_read_config_dword(dev, reg, &tmp.split.high);
+	pci_read_config_dword(dev, reg+4, &tmp.split.low);
+	return tmp.full;
+}
+
+static void pci_write64 (struct pci_dev *dev, int reg, u64 value)
+{
+	union {
+		u64 full;
+		struct {
+			u32 high;
+			u32 low;
+		} split;
+	} tmp;
+	tmp.full = value;
+	pci_write_config_dword(dev, reg, tmp.split.high);
+	pci_write_config_dword(dev, reg+4, tmp.split.low);
+}
+
+
+static int x86_64_insert_memory(agp_memory * mem, off_t pg_start, int type)
+{
+	int i, j, num_entries;
+	void *temp;
+	long tmp;
+	u32 pte;
+	u64 addr;
+
+	temp = agp_bridge.current_size;
+
+	num_entries = A_SIZE_32(temp)->num_entries;
+
+	num_entries -= agp_memory_reserved>>PAGE_SHIFT;
+
+	if (type != 0 || mem->type != 0)
+		return -EINVAL;
+
+	/* Make sure we can fit the range in the gatt table. */
+	if ((pg_start + mem->page_count) > num_entries)
+		return -EINVAL;
+
+	j = pg_start;
+
+	/* gatt table should be empty. */
+	while (j < (pg_start + mem->page_count)) {
+		if (!PGE_EMPTY(agp_bridge.gatt_table[j]))
+			return -EBUSY;
+		j++;
+	}
+
+	if (mem->is_flushed == FALSE) {
+		CACHE_FLUSH();
+		mem->is_flushed = TRUE;
+	}
+
+	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
+		addr = mem->memory[i];
+
+		tmp = addr;
+		BUG_ON(tmp & 0xffffff0000000ffc);
+		pte = (tmp & 0x000000ff00000000) >> 28;
+		pte |=(tmp & 0x00000000fffff000);
+		pte |= 1<<1|1<<0;
+
+		agp_bridge.gatt_table[j] = pte;
+	}
+	agp_bridge.tlb_flush(mem);
+	return 0;
+}
+
+/*
+ * This hack alters the order element according
+ * to the size of a long. It sucks. I totally disown this, even
+ * though it does appear to work for the most part.
+ */
+static struct aper_size_info_32 x86_64_aperture_sizes[7] =
+{
+	{32,   8192,   3+(sizeof(long)/8), 0 },
+	{64,   16384,  4+(sizeof(long)/8), 1<<1 },
+	{128,  32768,  5+(sizeof(long)/8), 1<<2 },
+	{256,  65536,  6+(sizeof(long)/8), 1<<1 | 1<<2 },
+	{512,  131072, 7+(sizeof(long)/8), 1<<3 },
+	{1024, 262144, 8+(sizeof(long)/8), 1<<1 | 1<<3},
+	{2048, 524288, 9+(sizeof(long)/8), 1<<2 | 1<<3}
+};
+
+
+/*
+ * Get the current Aperture size from the x86-64.
+ * Note, that there may be multiple x86-64's, but we just return
+ * the value from the first one we find. The set_size functions
+ * keep the rest coherent anyway. Or at least should do.
+ */
+static int amd_x86_64_fetch_size(void)
+{
+	struct pci_dev *dev;
+	int i;
+	u32 temp;
+	struct aper_size_info_32 *values;
+
+	pci_for_each_dev(dev) {
+		if (dev->bus->number==0 &&
+			PCI_FUNC(dev->devfn)==3 &&
+			PCI_SLOT(dev->devfn)>=24 && PCI_SLOT(dev->devfn)<=31) {
+
+			pci_read_config_dword(dev, AMD_X86_64_GARTAPERTURECTL, &temp);
+			temp = (temp & 0xe);
+			values = A_SIZE_32(x86_64_aperture_sizes);
+
+			for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+				if (temp == values[i].size_value) {
+					agp_bridge.previous_size =
+					    agp_bridge.current_size = (void *) (values + i);
+
+					agp_bridge.aperture_size_idx = i;
+					return values[i].size;
+				}
+			}
+		}
+	}
+	/* erk, couldn't find an x86-64 ? */
+	return 0;
+}
+
+
+static void inline flush_x86_64_tlb(struct pci_dev *dev)
+{
+	u32 tmp;
+
+	pci_read_config_dword (dev, AMD_X86_64_GARTCACHECTL, &tmp);
+	tmp |= 1<<0;
+	pci_write_config_dword (dev, AMD_X86_64_GARTCACHECTL, tmp);
+}
+
+
+static void amd_x86_64_tlbflush(agp_memory * temp)
+{
+	struct pci_dev *dev;
+
+	pci_for_each_dev(dev) {
+		if (dev->bus->number==0 && PCI_FUNC(dev->devfn)==3 &&
+		    PCI_SLOT(dev->devfn) >=24 && PCI_SLOT(dev->devfn) <=31) {
+			flush_x86_64_tlb (dev);
+		}
+	}
+}
+
+
+/*
+ * In a multiprocessor x86-64 system, this function gets
+ * called once for each CPU.
+ */
+static u64 amd_x86_64_configure (struct pci_dev *hammer, u64 gatt_table)
+{
+	u64 aperturebase;
+	u32 tmp;
+	u64 addr, aper_base;
+
+	/* Address to map to */
+	pci_read_config_dword (hammer, AMD_X86_64_GARTAPERTUREBASE, &tmp);
+	aperturebase = tmp << 25;
+	aper_base = (aperturebase & PCI_BASE_ADDRESS_MEM_MASK);
+
+	/* address of the mappings table */
+	addr = (u64) gatt_table;
+	addr >>= 12;
+	tmp = (u32) addr<<4;
+	tmp &= ~0xf;
+	pci_write_config_dword (hammer, AMD_X86_64_GARTTABLEBASE, tmp);
+
+	/* Enable GART translation for this hammer. */
+	pci_read_config_dword(hammer, AMD_X86_64_GARTAPERTURECTL, &tmp);
+	tmp &= 0x3f;
+	tmp |= 1<<0;
+	pci_write_config_dword(hammer, AMD_X86_64_GARTAPERTURECTL, tmp);
+
+	/* keep CPU's coherent. */
+	flush_x86_64_tlb (hammer);
+	
+	return aper_base;
+}
+
+
+static struct aper_size_info_32 amd_8151_sizes[7] =
+{
+	{2048, 524288, 9, 0x00000000 },	/* 0 0 0 0 0 0 */
+	{1024, 262144, 8, 0x00000400 },	/* 1 0 0 0 0 0 */
+	{512,  131072, 7, 0x00000600 },	/* 1 1 0 0 0 0 */
+	{256,  65536,  6, 0x00000700 },	/* 1 1 1 0 0 0 */
+	{128,  32768,  5, 0x00000720 },	/* 1 1 1 1 0 0 */
+	{64,   16384,  4, 0x00000730 },	/* 1 1 1 1 1 0 */
+	{32,   8192,   3, 0x00000738 } 	/* 1 1 1 1 1 1 */
+};
+
+static int amd_8151_configure(void)
+{
+	struct pci_dev *dev, *hammer=NULL;
+	int current_size;
+	int tmp, tmp2, i;
+	u64 aperbar;
+	unsigned long gatt_bus = virt_to_phys(agp_bridge.gatt_table_real);
+
+	/* Configure AGP regs in each x86-64 host bridge. */
+	pci_for_each_dev(dev) {
+		if (dev->bus->number==0 &&
+			PCI_FUNC(dev->devfn)==3 &&
+			PCI_SLOT(dev->devfn)>=24 && PCI_SLOT(dev->devfn)<=31) {
+			agp_bridge.gart_bus_addr = amd_x86_64_configure(dev,gatt_bus);
+			hammer = dev;
+
+			/*
+			 * TODO: Cache pci_dev's of x86-64's in private struct to save us
+			 * having to scan the pci list each time.
+			 */
+		}
+	}
+
+	if (hammer == NULL) {
+		return -ENODEV;
+	}
+
+	/* Shadow x86-64 registers into 8151 registers. */
+
+	dev = agp_bridge.dev;
+	if (!dev) 
+		return -ENODEV;
+
+	current_size = amd_x86_64_fetch_size();
+
+	pci_read_config_dword(dev, AMD_8151_APERTURESIZE, &tmp);
+	tmp &= ~(0xfff);
+
+	/* translate x86-64 size bits to 8151 size bits*/
+	for (i=0 ; i<7; i++) {
+		if (amd_8151_sizes[i].size == current_size)
+			tmp |= (amd_8151_sizes[i].size_value) << 3;
+	}
+	pci_write_config_dword(dev, AMD_8151_APERTURESIZE, tmp);
+
+	pci_read_config_dword (hammer, AMD_X86_64_GARTAPERTUREBASE, &tmp);
+	aperbar = pci_read64 (dev, AMD_8151_VMAPERTURE);
+	aperbar |= (tmp & 0x7fff) <<25;
+	aperbar &= 0x000000ffffffffff;
+	aperbar |= 1<<2;	/* This address is a 64bit ptr FIXME: Make conditional in 32bit mode */
+	pci_write64 (dev, AMD_8151_VMAPERTURE, aperbar);
+
+	pci_read_config_dword(dev, AMD_8151_AGP_CTL , &tmp);
+	tmp &= ~(AMD_8151_GTLBEN | AMD_8151_APEREN);
+	
+	pci_read_config_dword(hammer, AMD_X86_64_GARTAPERTURECTL, &tmp2);
+	if (tmp2 & AMD_X86_64_GARTEN)
+		tmp |= AMD_8151_APEREN;
+	// FIXME: bit 7 of AMD_8151_AGP_CTL (GTLBEN) must be copied if set.
+	// But where is it set ?
+	pci_write_config_dword(dev, AMD_8151_AGP_CTL, tmp);
+
+	return 0;
+}
+
+
+static void amd_8151_cleanup(void)
+{
+	struct pci_dev *dev;
+	u32 tmp;
+
+	pci_for_each_dev(dev) {
+		/* disable gart translation */
+		if (dev->bus->number==0 && PCI_FUNC(dev->devfn)==3 &&
+		    (PCI_SLOT(dev->devfn) >=24) && (PCI_SLOT(dev->devfn) <=31)) {
+
+			pci_read_config_dword (dev, AMD_X86_64_GARTAPERTURECTL, &tmp);
+			tmp &= ~(AMD_X86_64_GARTEN);
+			pci_write_config_dword (dev, AMD_X86_64_GARTAPERTURECTL, tmp);
+		}
+
+		/* Now shadow the disable in the 8151 */
+		if (dev->vendor == PCI_VENDOR_ID_AMD &&
+			dev->device == PCI_DEVICE_ID_AMD_8151_0) {
+
+			pci_read_config_dword (dev, AMD_8151_AGP_CTL, &tmp);
+			tmp &= ~(AMD_8151_APEREN);	
+			pci_write_config_dword (dev, AMD_8151_AGP_CTL, tmp);
+		}
+	}
+}
+
+
+
+static unsigned long amd_8151_mask_memory(unsigned long addr, int type)
+{
+	return addr | agp_bridge.masks[0].mask;
+}
+
+
+static struct gatt_mask amd_8151_masks[] =
+{
+	{0x00000001, 0}
+};
+
+
+/*
+ * Try to configure an AGP v3 capable setup.
+ * If we fail (typically because we don't have an AGP v3
+ * card in the system) we fall back to the generic AGP v2
+ * routines.
+ */
+static void agp_x86_64_agp_enable(u32 mode)
+{
+	struct pci_dev *device = NULL;
+	u32 command, scratch; 
+	u8 cap_ptr;
+	u8 agp_v3;
+	u8 v3_devs=0;
+
+	/* FIXME: If 'mode' is x1/x2/x4 should we call the AGPv2 routines directly ?
+	 * Messy, as some AGPv3 cards can only do x4 as a minimum.
+	 */
+
+	/* PASS1: Count # of devs capable of AGPv3 mode. */
+	pci_for_each_dev(device) {
+		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
+		if (cap_ptr != 0x00) {
+			pci_read_config_dword(device, cap_ptr, &scratch);
+			scratch &= (1<<20|1<<21|1<<22|1<<23);
+			scratch = scratch>>20;
+			/* AGP v3 capable ? */
+			if (scratch>=3) {
+				v3_devs++;
+				printk (KERN_INFO "AGP: Found AGPv3 capable device at %d:%d:%d\n",
+					device->bus->number, PCI_FUNC(device->devfn), PCI_SLOT(device->devfn));
+			} else {
+				printk (KERN_INFO "AGP: Meh. version %x AGP device found.\n", scratch);
+			}
+		}
+	}
+	/* If not enough, go to AGP v2 setup */
+	if (v3_devs<2) {
+		printk (KERN_INFO "AGP: Only %d devices found, not enough, trying AGPv2\n", v3_devs);
+		return agp_generic_agp_enable(mode);
+	} else {
+		printk (KERN_INFO "AGP: Enough AGPv3 devices found, setting up...\n");
+	}
+
+
+	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx + 4, &command);
+
+	/*
+	 * PASS2: go through all devices that claim to be
+	 *        AGP devices and collect their data.
+	 */
+
+	pci_for_each_dev(device) {
+		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
+		if (cap_ptr != 0x00) {
+			/*
+			 * Ok, here we have a AGP device. Disable impossible 
+			 * settings, and adjust the readqueue to the minimum.
+			 */
+
+			printk (KERN_INFO "AGP: Setting up AGPv3 capable device at %d:%d:%d\n",
+					device->bus->number, PCI_FUNC(device->devfn), PCI_SLOT(device->devfn));
+			pci_read_config_dword(device, cap_ptr + 4, &scratch);
+			agp_v3 = (scratch & (1<<3) ) >>3;
+
+			/* adjust RQ depth */
+			command =
+			    ((command & ~0xff000000) |
+			     min_t(u32, (mode & 0xff000000),
+				 min_t(u32, (command & 0xff000000),
+				     (scratch & 0xff000000))));
+
+			/* disable SBA if it's not supported */
+			if (!((command & 0x200) && (scratch & 0x200) && (mode & 0x200)))
+				command &= ~0x200;
+
+			/* disable FW if it's not supported */
+			if (!((command & 0x10) && (scratch & 0x10) && (mode & 0x10)))
+				command &= ~0x10;
+
+			if (!((command & 2) && (scratch & 2) && (mode & 2))) {
+				command &= ~2;		/* 8x */
+				printk (KERN_INFO "AGP: Putting device into 8x mode\n");
+			}
+
+			if (!((command & 1) && (scratch & 1) && (mode & 1))) {
+				command &= ~1;		/* 4x */
+				printk (KERN_INFO "AGP: Putting device into 4x mode\n");
+			}
+		}
+	}
+	/*
+	 * PASS3: Figure out the 8X/4X setting and enable the
+	 *        target (our motherboard chipset).
+	 */
+
+	if (command & 2)
+		command &= ~5;	/* 8X */
+
+	if (command & 1)
+		command &= ~6;	/* 4X */
+
+	command |= 0x100;
+
+	pci_write_config_dword(agp_bridge.dev, agp_bridge.capndx + 8, command);
+
+	/*
+	 * PASS4: Go through all AGP devices and update the
+	 *        command registers.
+	 */
+
+	pci_for_each_dev(device) {
+		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
+		if (cap_ptr != 0x00)
+			pci_write_config_dword(device, cap_ptr + 8, command);
+	}
+}
+
+
+static int __init amd_8151_setup (struct pci_dev *pdev)
+{
+	agp_bridge.masks = amd_8151_masks;
+	agp_bridge.num_of_masks = 1;
+	agp_bridge.aperture_sizes = (void *) amd_8151_sizes;
+	agp_bridge.size_type = U32_APER_SIZE;
+	agp_bridge.num_aperture_sizes = 7;
+	agp_bridge.dev_private_data = NULL;
+	agp_bridge.needs_scratch_page = FALSE;
+	agp_bridge.configure = amd_8151_configure;
+	agp_bridge.fetch_size = amd_x86_64_fetch_size;
+	agp_bridge.cleanup = amd_8151_cleanup;
+	agp_bridge.tlb_flush = amd_x86_64_tlbflush;
+	agp_bridge.mask_memory = amd_8151_mask_memory;
+	agp_bridge.agp_enable = agp_x86_64_agp_enable;
+	agp_bridge.cache_flush = global_cache_flush;
+	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge.insert_memory = x86_64_insert_memory;
+	agp_bridge.remove_memory = agp_generic_remove_memory;
+	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge.free_by_type = agp_generic_free_by_type;
+	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.suspend = agp_generic_suspend;
+	agp_bridge.resume = agp_generic_resume;
+	agp_bridge.cant_use_aperture = 0;
+	return 0;
+}
+
+
+static int agp_amdk8_probe (struct pci_dev *dev, const struct pci_device_id *ent)
+{
+	if (pci_find_capability(dev, PCI_CAP_ID_AGP)==0)
+		return -ENODEV;
+
+	amd_8151_setup(dev);
+	agp_register_driver(dev);
+	return 0;
+}
+
+static struct pci_device_id agp_amdk8_pci_table[] __initdata = {
+	{
+	.class		= (PCI_CLASS_BRIDGE_HOST << 8),
+	.class_mask	= ~0,
+	.vendor		= PCI_VENDOR_ID_AMD,
+	.device		= PCI_DEVICE_ID_AMD_8151_0,
+	.subvendor	= PCI_ANY_ID,
+	.subdevice	= PCI_ANY_ID,
+	},
+	{ }
+};
+
+MODULE_DEVICE_TABLE(pci, agp_amdk8_pci_table);
+
+static struct pci_driver agp_amdk8_pci_driver = {
+	.name		= "agpgart-amd-k8",
+	.id_table	= agp_amdk8_pci_table,
+	.probe		= agp_amdk8_probe,
+};
+
+static int __init agp_amdk8_init(void)
+{
+	int ret_val;
+
+	ret_val = pci_module_init(&agp_amdk8_pci_driver);
+	if (ret_val)
+		agp_bridge.type = NOT_SUPPORTED;
+
+	return ret_val;
+}
+
+static void __exit agp_amdk8_cleanup(void)
+{
+	agp_unregister_driver();
+	pci_unregister_driver(&agp_amdk8_pci_driver);
+}
+
+module_init(agp_amdk8_init);
+module_exit(agp_amdk8_cleanup);
+
+MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
+MODULE_LICENSE("GPL and additional rights");
+
diff -Nru a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/agp/backend.c	Mon Dec  9 18:46:50 2002
@@ -0,0 +1,291 @@
+/*
+ * AGPGART module version 1.0
+ * Copyright (C) 2002 Dave Jones.
+ * Copyright (C) 1999 Jeff Hartmann.
+ * Copyright (C) 1999 Precision Insight, Inc.
+ * Copyright (C) 1999 Xi Graphics, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * JEFF HARTMANN, DAVE JONES, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * TODO: 
+ * - Allocate more than order 0 pages to avoid too much linear map splitting.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/pagemap.h>
+#include <linux/miscdevice.h>
+#include <linux/pm.h>
+#include <linux/agp_backend.h>
+#include "agp.h"
+
+#define AGPGART_VERSION_MAJOR 1
+#define AGPGART_VERSION_MINOR 0
+
+struct agp_bridge_data agp_bridge = { .type = NOT_SUPPORTED };
+
+int agp_backend_acquire(void)
+{
+	if (agp_bridge.type == NOT_SUPPORTED)
+		return -EINVAL;
+
+	atomic_inc(&agp_bridge.agp_in_use);
+
+	if (atomic_read(&agp_bridge.agp_in_use) != 1) {
+		atomic_dec(&agp_bridge.agp_in_use);
+		return -EBUSY;
+	}
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+void agp_backend_release(void)
+{
+	if (agp_bridge.type == NOT_SUPPORTED)
+		return;
+
+	atomic_dec(&agp_bridge.agp_in_use);
+	MOD_DEC_USE_COUNT;
+}
+
+struct agp_max_table {
+	int mem;
+	int agp;
+};
+
+static struct agp_max_table maxes_table[9] __initdata =
+{
+	{0, 0},
+	{32, 4},
+	{64, 28},
+	{128, 96},
+	{256, 204},
+	{512, 440},
+	{1024, 942},
+	{2048, 1920},
+	{4096, 3932}
+};
+
+static int __init agp_find_max (void)
+{
+	long memory, index, result;
+
+	memory = virt_to_phys(high_memory) >> 20;
+	index = 1;
+
+	while ((memory > maxes_table[index].mem) && (index < 8))
+		index++;
+
+	result = maxes_table[index - 1].agp +
+	   ( (memory - maxes_table[index - 1].mem)  *
+	     (maxes_table[index].agp - maxes_table[index - 1].agp)) /
+	   (maxes_table[index].mem - maxes_table[index - 1].mem);
+
+	printk(KERN_INFO PFX "Maximum main memory to use for agp memory: %ldM\n", result);
+	result = result << (20 - PAGE_SHIFT);
+	return result;
+}
+
+static struct agp_version agp_current_version =
+{
+	.major = AGPGART_VERSION_MAJOR,
+	.minor = AGPGART_VERSION_MINOR,
+};
+
+static int __init agp_backend_initialize(struct pci_dev *dev)
+{
+	int size_value, rc, got_gatt=0, got_keylist=0;
+	u8 cap_ptr = 0;
+
+	agp_bridge.max_memory_agp = agp_find_max();
+	agp_bridge.version = &agp_current_version;
+
+	cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP);
+	if (cap_ptr == 0)
+		return -ENODEV;
+	agp_bridge.capndx = cap_ptr;
+
+	/* Fill in the mode register */
+	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx + 4, &agp_bridge.mode);
+
+
+	if (agp_bridge.needs_scratch_page == TRUE) {
+		void *addr;
+		addr = agp_bridge.agp_alloc_page();
+
+		if (addr == NULL) {
+			printk(KERN_ERR PFX "unable to get memory for scratch page.\n");
+			return -ENOMEM;
+		}
+		agp_bridge.scratch_page = virt_to_phys(addr);
+		agp_bridge.scratch_page = agp_bridge.mask_memory(agp_bridge.scratch_page, 0);
+	}
+
+	size_value = agp_bridge.fetch_size();
+
+	if (size_value == 0) {
+		printk(KERN_ERR PFX "unable to determine aperture size.\n");
+		rc = -EINVAL;
+		goto err_out;
+	}
+	if (agp_bridge.create_gatt_table()) {
+		printk(KERN_ERR PFX "unable to get memory for graphics translation table.\n");
+		rc = -ENOMEM;
+		goto err_out;
+	}
+	got_gatt = 1;
+	
+	agp_bridge.key_list = vmalloc(PAGE_SIZE * 4);
+	if (agp_bridge.key_list == NULL) {
+		printk(KERN_ERR PFX "error allocating memory for key lists.\n");
+		rc = -ENOMEM;
+		goto err_out;
+	}
+	got_keylist = 1;
+	
+	/* FIXME vmalloc'd memory not guaranteed contiguous */
+	memset(agp_bridge.key_list, 0, PAGE_SIZE * 4);
+
+	if (agp_bridge.configure()) {
+		printk(KERN_ERR PFX "error configuring host chipset.\n");
+		rc = -EINVAL;
+		goto err_out;
+	}
+
+	printk(KERN_INFO PFX "AGP aperture is %dM @ 0x%lx\n",
+	       size_value, agp_bridge.gart_bus_addr);
+
+	return 0;
+
+err_out:
+	if (agp_bridge.needs_scratch_page == TRUE) {
+		agp_bridge.scratch_page &= ~(0x00000fff);
+		agp_bridge.agp_destroy_page(phys_to_virt(agp_bridge.scratch_page));
+	}
+	if (got_gatt)
+		agp_bridge.free_gatt_table();
+	if (got_keylist)
+		vfree(agp_bridge.key_list);
+	return rc;
+}
+
+
+/* cannot be __exit b/c as it could be called from __init code */
+static void agp_backend_cleanup(void)
+{
+	agp_bridge.cleanup();
+	agp_bridge.free_gatt_table();
+	vfree(agp_bridge.key_list);
+
+	if (agp_bridge.needs_scratch_page == TRUE) {
+		agp_bridge.scratch_page &= ~(0x00000fff);
+		agp_bridge.agp_destroy_page(phys_to_virt(agp_bridge.scratch_page));
+	}
+}
+
+static int agp_power(struct pm_dev *dev, pm_request_t rq, void *data)
+{
+	switch(rq)
+	{
+		case PM_SUSPEND:
+			return agp_bridge.suspend();
+		case PM_RESUME:
+			agp_bridge.resume();
+			return 0;
+	}		
+	return 0;
+}
+
+extern int agp_frontend_initialize(void);
+extern void agp_frontend_cleanup(void);
+
+static const drm_agp_t drm_agp = {
+	&agp_free_memory,
+	&agp_allocate_memory,
+	&agp_bind_memory,
+	&agp_unbind_memory,
+	&agp_enable,
+	&agp_backend_acquire,
+	&agp_backend_release,
+	&agp_copy_info
+};
+
+static int agp_count=0;
+
+int agp_register_driver (struct pci_dev *dev)
+{
+	int ret_val;
+
+	if (agp_count==1) {
+		printk (KERN_DEBUG PFX "Only one agpgart device currently supported.\n");
+		return -ENODEV;
+	}
+
+	ret_val = agp_backend_initialize(dev);
+	if (ret_val) {
+		agp_bridge.type = NOT_SUPPORTED;
+		return ret_val;
+	}
+	ret_val = agp_frontend_initialize();
+	if (ret_val) {
+		agp_bridge.type = NOT_SUPPORTED;
+		agp_backend_cleanup();
+		return ret_val;
+	}
+
+	inter_module_register("drm_agp", THIS_MODULE, &drm_agp);
+	
+	pm_register(PM_PCI_DEV, PM_PCI_ID(agp_bridge.dev), agp_power);
+
+	agp_count++;
+	return 0;
+}
+
+int __exit agp_unregister_driver(void)
+{
+	agp_bridge.type = NOT_SUPPORTED;
+	pm_unregister_all(agp_power);
+	agp_frontend_cleanup();
+	agp_backend_cleanup();
+	inter_module_unregister("drm_agp");
+	agp_count--;
+	return 0;
+}
+
+int __init agp_init(void)
+{
+	memset(&agp_bridge, 0, sizeof(struct agp_bridge_data));
+	agp_bridge.type = NOT_SUPPORTED;
+
+	printk(KERN_INFO "Linux agpgart interface v%d.%d (c) Dave Jones\n",
+	       AGPGART_VERSION_MAJOR, AGPGART_VERSION_MINOR);
+	return 0;
+}
+
+#ifndef CONFIG_GART_IOMMU
+module_init(agp_init);
+#endif
+
+EXPORT_SYMBOL(agp_backend_acquire);
+EXPORT_SYMBOL(agp_backend_release);
+EXPORT_SYMBOL_GPL(agp_register_driver);
+
+MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
+MODULE_LICENSE("GPL and additional rights");
diff -Nru a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
--- a/drivers/char/agp/frontend.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/char/agp/frontend.c	Mon Dec  9 18:46:35 2002
@@ -1063,7 +1063,7 @@
 static struct miscdevice agp_miscdev =
 {
 	AGPGART_MINOR,
-	AGPGART_MODULE_NAME,
+	"agpgart",
 	&agp_fops
 };
 
diff -Nru a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/agp/generic.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,699 @@
+/*
+ * AGPGART module version 1.0
+ * Copyright (C) 2002 Dave Jones.
+ * Copyright (C) 1999 Jeff Hartmann.
+ * Copyright (C) 1999 Precision Insight, Inc.
+ * Copyright (C) 1999 Xi Graphics, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * TODO: 
+ * - Allocate more than order 0 pages to avoid too much linear map splitting.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/pagemap.h>
+#include <linux/miscdevice.h>
+#include <linux/pm.h>
+#include <linux/agp_backend.h>
+#include "agp.h"
+
+__u32 *agp_gatt_table; 
+int agp_memory_reserved;
+
+/* 
+ * Generic routines for handling agp_memory structures -
+ * They use the basic page allocation routines to do the
+ * brunt of the work.
+ */
+
+void agp_free_key(int key)
+{
+
+	if (key < 0)
+		return;
+
+	if (key < MAXKEY)
+		clear_bit(key, agp_bridge.key_list);
+}
+
+static int agp_get_key(void)
+{
+	int bit;
+
+	bit = find_first_zero_bit(agp_bridge.key_list, MAXKEY);
+	if (bit < MAXKEY) {
+		set_bit(bit, agp_bridge.key_list);
+		return bit;
+	}
+	return -1;
+}
+
+agp_memory *agp_create_memory(int scratch_pages)
+{
+	agp_memory *new;
+
+	new = kmalloc(sizeof(agp_memory), GFP_KERNEL);
+
+	if (new == NULL)
+		return NULL;
+
+	memset(new, 0, sizeof(agp_memory));
+	new->key = agp_get_key();
+
+	if (new->key < 0) {
+		kfree(new);
+		return NULL;
+	}
+	new->memory = vmalloc(PAGE_SIZE * scratch_pages);
+
+	if (new->memory == NULL) {
+		agp_free_key(new->key);
+		kfree(new);
+		return NULL;
+	}
+	new->num_scratch_pages = scratch_pages;
+	return new;
+}
+
+void agp_free_memory(agp_memory * curr)
+{
+	int i;
+
+	if ((agp_bridge.type == NOT_SUPPORTED) || (curr == NULL))
+		return;
+
+	if (curr->is_bound == TRUE)
+		agp_unbind_memory(curr);
+
+	if (curr->type != 0) {
+		agp_bridge.free_by_type(curr);
+		return;
+	}
+	if (curr->page_count != 0) {
+		for (i = 0; i < curr->page_count; i++) {
+			curr->memory[i] &= ~(0x00000fff);
+			agp_bridge.agp_destroy_page(phys_to_virt(curr->memory[i]));
+		}
+	}
+	agp_free_key(curr->key);
+	vfree(curr->memory);
+	kfree(curr);
+	MOD_DEC_USE_COUNT;
+}
+
+#define ENTRIES_PER_PAGE		(PAGE_SIZE / sizeof(unsigned long))
+
+agp_memory *agp_allocate_memory(size_t page_count, u32 type)
+{
+	int scratch_pages;
+	agp_memory *new;
+	int i;
+
+	if (agp_bridge.type == NOT_SUPPORTED)
+		return NULL;
+
+	if ((atomic_read(&agp_bridge.current_memory_agp) + page_count) > agp_bridge.max_memory_agp)
+		return NULL;
+
+	if (type != 0) {
+		new = agp_bridge.alloc_by_type(page_count, type);
+		return new;
+	}
+
+	/* We always increase the module count, since free auto-decrements it */
+	MOD_INC_USE_COUNT;
+
+	scratch_pages = (page_count + ENTRIES_PER_PAGE - 1) / ENTRIES_PER_PAGE;
+
+	new = agp_create_memory(scratch_pages);
+
+	if (new == NULL) {
+		MOD_DEC_USE_COUNT;
+		return NULL;
+	}
+
+	for (i = 0; i < page_count; i++) {
+		void *addr = agp_bridge.agp_alloc_page();
+
+		if (addr == NULL) {
+			agp_free_memory(new);
+			return NULL;
+		}
+		new->memory[i] = agp_bridge.mask_memory(virt_to_phys(addr), type);
+		new->page_count++;
+	}
+
+	flush_agp_mappings();
+
+	return new;
+}
+
+/* End - Generic routines for handling agp_memory structures */
+
+static int agp_return_size(void)
+{
+	int current_size;
+	void *temp;
+
+	temp = agp_bridge.current_size;
+
+	switch (agp_bridge.size_type) {
+	case U8_APER_SIZE:
+		current_size = A_SIZE_8(temp)->size;
+		break;
+	case U16_APER_SIZE:
+		current_size = A_SIZE_16(temp)->size;
+		break;
+	case U32_APER_SIZE:
+		current_size = A_SIZE_32(temp)->size;
+		break;
+	case LVL2_APER_SIZE:
+		current_size = A_SIZE_LVL2(temp)->size;
+		break;
+	case FIXED_APER_SIZE:
+		current_size = A_SIZE_FIX(temp)->size;
+		break;
+	default:
+		current_size = 0;
+		break;
+	}
+
+	current_size -= (agp_memory_reserved / (1024*1024));
+	if (current_size <0)
+		current_size = 0;
+	return current_size;
+}
+
+/* Routine to copy over information structure */
+
+int agp_copy_info(agp_kern_info * info)
+{
+	unsigned long page_mask = 0;
+	int i;
+
+	memset(info, 0, sizeof(agp_kern_info));
+	if (agp_bridge.type == NOT_SUPPORTED) {
+		info->chipset = agp_bridge.type;
+		return -EIO;
+	}
+	info->version.major = agp_bridge.version->major;
+	info->version.minor = agp_bridge.version->minor;
+	info->device = agp_bridge.dev;
+	info->chipset = agp_bridge.type;
+	info->mode = agp_bridge.mode;
+	info->aper_base = agp_bridge.gart_bus_addr;
+	info->aper_size = agp_return_size();
+	info->max_memory = agp_bridge.max_memory_agp;
+	info->current_memory = atomic_read(&agp_bridge.current_memory_agp);
+	info->cant_use_aperture = agp_bridge.cant_use_aperture;
+
+	for(i = 0; i < agp_bridge.num_of_masks; i++)
+		page_mask |= agp_bridge.mask_memory(page_mask, i);
+
+	info->page_mask = ~page_mask;
+	return 0;
+}
+
+/* End - Routine to copy over information structure */
+
+/*
+ * Routines for handling swapping of agp_memory into the GATT -
+ * These routines take agp_memory and insert them into the GATT.
+ * They call device specific routines to actually write to the GATT.
+ */
+
+int agp_bind_memory(agp_memory * curr, off_t pg_start)
+{
+	int ret_val;
+
+	if ((agp_bridge.type == NOT_SUPPORTED) ||
+	    (curr == NULL) || (curr->is_bound == TRUE)) {
+		return -EINVAL;
+	}
+	if (curr->is_flushed == FALSE) {
+		CACHE_FLUSH();
+		curr->is_flushed = TRUE;
+	}
+	ret_val = agp_bridge.insert_memory(curr, pg_start, curr->type);
+
+	if (ret_val != 0)
+		return ret_val;
+
+	curr->is_bound = TRUE;
+	curr->pg_start = pg_start;
+	return 0;
+}
+
+int agp_unbind_memory(agp_memory * curr)
+{
+	int ret_val;
+
+	if ((agp_bridge.type == NOT_SUPPORTED) || (curr == NULL))
+		return -EINVAL;
+
+	if (curr->is_bound != TRUE)
+		return -EINVAL;
+
+	ret_val = agp_bridge.remove_memory(curr, curr->pg_start, curr->type);
+
+	if (ret_val != 0)
+		return ret_val;
+
+	curr->is_bound = FALSE;
+	curr->pg_start = 0;
+	return 0;
+}
+
+/* End - Routines for handling swapping of agp_memory into the GATT */
+
+
+/* Generic Agp routines - Start */
+void agp_generic_agp_enable(u32 mode)
+{
+	struct pci_dev *device = NULL;
+	u32 command, scratch; 
+	u8 cap_ptr;
+
+	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx + 4, &command);
+
+	/*
+	 * PASS1: go through all devices that claim to be
+	 *        AGP devices and collect their data.
+	 */
+
+	pci_for_each_dev(device) {
+		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
+		if (cap_ptr != 0x00) {
+			/*
+			 * Ok, here we have a AGP device. Disable impossible 
+			 * settings, and adjust the readqueue to the minimum.
+			 */
+
+			pci_read_config_dword(device, cap_ptr + 4, &scratch);
+
+			/* adjust RQ depth */
+			command = ((command & ~0xff000000) |
+			     min_t(u32, (mode & 0xff000000),
+				 min_t(u32, (command & 0xff000000),
+				     (scratch & 0xff000000))));
+
+			/* disable SBA if it's not supported */
+			if (!((command & 0x00000200) &&
+			      (scratch & 0x00000200) &&
+			      (mode & 0x00000200)))
+				command &= ~0x00000200;
+
+			/* disable FW if it's not supported */
+			if (!((command & 0x00000010) &&
+			      (scratch & 0x00000010) &&
+			      (mode & 0x00000010)))
+				command &= ~0x00000010;
+
+			if (!((command & 4) &&
+			      (scratch & 4) &&
+			      (mode & 4)))
+				command &= ~0x00000004;
+
+			if (!((command & 2) &&
+			      (scratch & 2) &&
+			      (mode & 2)))
+				command &= ~0x00000002;
+
+			if (!((command & 1) &&
+			      (scratch & 1) &&
+			      (mode & 1)))
+				command &= ~0x00000001;
+		}
+	}
+	/*
+	 * PASS2: Figure out the 4X/2X/1X setting and enable the
+	 *        target (our motherboard chipset).
+	 */
+
+	if (command & 4)
+		command &= ~3;	/* 4X */
+
+	if (command & 2)
+		command &= ~5;	/* 2X */
+
+	if (command & 1)
+		command &= ~6;	/* 1X */
+
+	command |= 0x00000100;
+
+	pci_write_config_dword(agp_bridge.dev,
+			       agp_bridge.capndx + 8,
+			       command);
+
+	/*
+	 * PASS3: Go throu all AGP devices and update the
+	 *        command registers.
+	 */
+
+	pci_for_each_dev(device) {
+		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
+		if (cap_ptr != 0x00)
+			pci_write_config_dword(device, cap_ptr + 8, command);
+	}
+}
+
+int agp_generic_create_gatt_table(void)
+{
+	char *table;
+	char *table_end;
+	int size;
+	int page_order;
+	int num_entries;
+	int i;
+	void *temp;
+	struct page *page;
+
+	/* The generic routines can't handle 2 level gatt's */
+	if (agp_bridge.size_type == LVL2_APER_SIZE)
+		return -EINVAL;
+
+	table = NULL;
+	i = agp_bridge.aperture_size_idx;
+	temp = agp_bridge.current_size;
+	size = page_order = num_entries = 0;
+
+	if (agp_bridge.size_type != FIXED_APER_SIZE) {
+		do {
+			switch (agp_bridge.size_type) {
+			case U8_APER_SIZE:
+				size = A_SIZE_8(temp)->size;
+				page_order =
+				    A_SIZE_8(temp)->page_order;
+				num_entries =
+				    A_SIZE_8(temp)->num_entries;
+				break;
+			case U16_APER_SIZE:
+				size = A_SIZE_16(temp)->size;
+				page_order = A_SIZE_16(temp)->page_order;
+				num_entries = A_SIZE_16(temp)->num_entries;
+				break;
+			case U32_APER_SIZE:
+				size = A_SIZE_32(temp)->size;
+				page_order = A_SIZE_32(temp)->page_order;
+				num_entries = A_SIZE_32(temp)->num_entries;
+				break;
+				/* This case will never really happen. */
+			case FIXED_APER_SIZE:
+			case LVL2_APER_SIZE:
+			default:
+				size = page_order = num_entries = 0;
+				break;
+			}
+
+			table = (char *) __get_free_pages(GFP_KERNEL,
+							  page_order);
+
+			if (table == NULL) {
+				i++;
+				switch (agp_bridge.size_type) {
+				case U8_APER_SIZE:
+					agp_bridge.current_size = A_IDX8();
+					break;
+				case U16_APER_SIZE:
+					agp_bridge.current_size = A_IDX16();
+					break;
+				case U32_APER_SIZE:
+					agp_bridge.current_size = A_IDX32();
+					break;
+					/* This case will never really 
+					 * happen. 
+					 */
+				case FIXED_APER_SIZE:
+				case LVL2_APER_SIZE:
+				default:
+					agp_bridge.current_size =
+					    agp_bridge.current_size;
+					break;
+				}
+				temp = agp_bridge.current_size;	
+			} else {
+				agp_bridge.aperture_size_idx = i;
+			}
+		} while ((table == NULL) && (i < agp_bridge.num_aperture_sizes));
+	} else {
+		size = ((struct aper_size_info_fixed *) temp)->size;
+		page_order = ((struct aper_size_info_fixed *) temp)->page_order;
+		num_entries = ((struct aper_size_info_fixed *) temp)->num_entries;
+		table = (char *) __get_free_pages(GFP_KERNEL, page_order);
+	}
+
+	if (table == NULL)
+		return -ENOMEM;
+
+	table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
+
+	for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
+		SetPageReserved(page);
+
+	agp_bridge.gatt_table_real = (u32 *) table;
+	agp_gatt_table = (void *)table; 
+	CACHE_FLUSH();
+	agp_bridge.gatt_table = ioremap_nocache(virt_to_phys(table),
+					(PAGE_SIZE * (1 << page_order)));
+	CACHE_FLUSH();
+
+	if (agp_bridge.gatt_table == NULL) {
+		for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
+			ClearPageReserved(page);
+
+		free_pages((unsigned long) table, page_order);
+
+		return -ENOMEM;
+	}
+	agp_bridge.gatt_bus_addr = virt_to_phys(agp_bridge.gatt_table_real);
+
+	for (i = 0; i < num_entries; i++)
+		agp_bridge.gatt_table[i] = (unsigned long) agp_bridge.scratch_page;
+
+	return 0;
+}
+
+int agp_generic_suspend(void)
+{
+	return 0;
+}
+
+void agp_generic_resume(void)
+{
+	return;
+}
+
+int agp_generic_free_gatt_table(void)
+{
+	int page_order;
+	char *table, *table_end;
+	void *temp;
+	struct page *page;
+
+	temp = agp_bridge.current_size;
+
+	switch (agp_bridge.size_type) {
+	case U8_APER_SIZE:
+		page_order = A_SIZE_8(temp)->page_order;
+		break;
+	case U16_APER_SIZE:
+		page_order = A_SIZE_16(temp)->page_order;
+		break;
+	case U32_APER_SIZE:
+		page_order = A_SIZE_32(temp)->page_order;
+		break;
+	case FIXED_APER_SIZE:
+		page_order = A_SIZE_FIX(temp)->page_order;
+		break;
+	case LVL2_APER_SIZE:
+		/* The generic routines can't deal with 2 level gatt's */
+		return -EINVAL;
+		break;
+	default:
+		page_order = 0;
+		break;
+	}
+
+	/* Do not worry about freeing memory, because if this is
+	 * called, then all agp memory is deallocated and removed
+	 * from the table.
+	 */
+
+	iounmap(agp_bridge.gatt_table);
+	table = (char *) agp_bridge.gatt_table_real;
+	table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
+
+	for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
+		ClearPageReserved(page);
+
+	free_pages((unsigned long) agp_bridge.gatt_table_real, page_order);
+	return 0;
+}
+
+int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type)
+{
+	int i, j, num_entries;
+	void *temp;
+
+	temp = agp_bridge.current_size;
+
+	switch (agp_bridge.size_type) {
+	case U8_APER_SIZE:
+		num_entries = A_SIZE_8(temp)->num_entries;
+		break;
+	case U16_APER_SIZE:
+		num_entries = A_SIZE_16(temp)->num_entries;
+		break;
+	case U32_APER_SIZE:
+		num_entries = A_SIZE_32(temp)->num_entries;
+		break;
+	case FIXED_APER_SIZE:
+		num_entries = A_SIZE_FIX(temp)->num_entries;
+		break;
+	case LVL2_APER_SIZE:
+		/* The generic routines can't deal with 2 level gatt's */
+		return -EINVAL;
+		break;
+	default:
+		num_entries = 0;
+		break;
+	}
+
+	num_entries -= agp_memory_reserved/PAGE_SIZE;
+	if (num_entries < 0) num_entries = 0;
+
+	if (type != 0 || mem->type != 0) {
+		/* The generic routines know nothing of memory types */
+		return -EINVAL;
+	}
+
+	if ((pg_start + mem->page_count) > num_entries)
+		return -EINVAL;
+
+	j = pg_start;
+
+	while (j < (pg_start + mem->page_count)) {
+		if (!PGE_EMPTY(agp_bridge.gatt_table[j])) {
+			return -EBUSY;
+		}
+		j++;
+	}
+
+	if (mem->is_flushed == FALSE) {
+		CACHE_FLUSH();
+		mem->is_flushed = TRUE;
+	}
+
+	for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
+		agp_bridge.gatt_table[j] = mem->memory[i];
+
+	agp_bridge.tlb_flush(mem);
+	return 0;
+}
+
+int agp_generic_remove_memory(agp_memory * mem, off_t pg_start, int type)
+{
+	int i;
+
+	if (type != 0 || mem->type != 0) {
+		/* The generic routines know nothing of memory types */
+		return -EINVAL;
+	}
+	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
+		agp_bridge.gatt_table[i] =
+		    (unsigned long) agp_bridge.scratch_page;
+	}
+
+	agp_bridge.tlb_flush(mem);
+	return 0;
+}
+
+agp_memory *agp_generic_alloc_by_type(size_t page_count, int type)
+{
+	return NULL;
+}
+
+void agp_generic_free_by_type(agp_memory * curr)
+{
+	if (curr->memory != NULL)
+		vfree(curr->memory);
+
+	agp_free_key(curr->key);
+	kfree(curr);
+}
+
+/* 
+ * Basic Page Allocation Routines -
+ * These routines handle page allocation
+ * and by default they reserve the allocated 
+ * memory.  They also handle incrementing the
+ * current_memory_agp value, Which is checked
+ * against a maximum value.
+ */
+
+void *agp_generic_alloc_page(void)
+{
+	struct page * page;
+	
+	page = alloc_page(GFP_KERNEL);
+	if (page == NULL)
+		return 0;
+
+	map_page_into_agp(page);
+
+	get_page(page);
+	SetPageLocked(page);
+	atomic_inc(&agp_bridge.current_memory_agp);
+	return page_address(page);
+}
+
+void agp_generic_destroy_page(void *addr)
+{
+	struct page *page;
+
+	if (addr == NULL)
+		return;
+
+	page = virt_to_page(addr);
+	unmap_page_from_agp(page);
+	put_page(page);
+	unlock_page(page);
+	free_page((unsigned long)addr);
+	atomic_dec(&agp_bridge.current_memory_agp);
+}
+
+/* End Basic Page Allocation Routines */
+
+void agp_enable(u32 mode)
+{
+	if (agp_bridge.type == NOT_SUPPORTED)
+		return;
+	agp_bridge.agp_enable(mode);
+}
+
+EXPORT_SYMBOL(agp_free_memory);
+EXPORT_SYMBOL(agp_allocate_memory);
+EXPORT_SYMBOL(agp_copy_info);
+EXPORT_SYMBOL(agp_bind_memory);
+EXPORT_SYMBOL(agp_unbind_memory);
+EXPORT_SYMBOL(agp_enable);
+
diff -Nru a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c
--- a/drivers/char/agp/hp-agp.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/char/agp/hp-agp.c	Mon Dec  9 18:46:50 2002
@@ -1,29 +1,5 @@
 /*
- * AGPGART module version 0.99
- * Copyright (C) 1999 Jeff Hartmann
- * Copyright (C) 1999 Precision Insight, Inc.
- * Copyright (C) 1999 Xi Graphics, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
- * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * TODO: 
- * - Allocate more than order 0 pages to avoid too much linear map splitting.
+ * HP AGPGART routines. 
  */
 
 #include <linux/module.h>
@@ -32,7 +8,6 @@
 #include <linux/agp_backend.h>
 #include "agp.h"
 
-
 #ifndef log2
 #define log2(x)		ffz(~(x))
 #endif
@@ -174,15 +149,13 @@
 
 	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
 		if (pci_resource_flags(ioc, i) == IORESOURCE_MEM) {
-			hp->registers = (u8 *) ioremap(pci_resource_start(ioc,
-									    i),
+			hp->registers = (u8 *) ioremap(pci_resource_start(ioc, i),
 						    pci_resource_len(ioc, i));
 			break;
 		}
 	}
 	if (!hp->registers) {
 		printk(KERN_ERR PFX "Detected HP ZX1 AGP bridge but no CSRs\n");
-
 		return -ENODEV;
 	}
 
@@ -386,9 +359,72 @@
 	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
 	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
 	agp_bridge.cant_use_aperture = 1;
-
 	return hp_zx1_ioc_init();
+}
+
+static int __init agp_find_supported_device(struct pci_dev *dev)
+{
+	agp_bridge.dev = dev;
+
+	/* ZX1 LBAs can be either PCI or AGP bridges */
+	if (pci_find_capability(dev, PCI_CAP_ID_AGP)) {
+		printk(KERN_INFO PFX "Detected HP ZX1 AGP chipset at %s\n",
+			dev->slot_name);
+		agp_bridge.type = HP_ZX1;
+		agp_bridge.dev = dev;
+		return hp_zx1_setup(dev);
+	}
+	return -ENODEV;
+}
+
+
+static int agp_hp_probe (struct pci_dev *dev, const struct pci_device_id *ent)
+{
+	if (agp_find_supported_device(dev) == 0) {
+		agp_register_driver(dev);
+		return 0;
+	}
+	return -ENODEV;	
+}
+
+static struct pci_device_id agp_hp_pci_table[] __initdata = {
+	{
+	.class		= (PCI_CLASS_BRIDGE_HOST << 8),
+	.class_mask	= ~0,
+	.vendor_id	= PCI_VENDOR_ID_HP,
+	.device		= PCI_DEVICE_ID_HP_ZX1_LBA,
+	.subvendor	= PCI_ANY_ID,
+	.subdevice	= PCI_ANY_ID,
+	},
+	{ }
+};
+
+MODULE_DEVICE_TABLE(pci, agp_pci_table);
 
-	(void) pdev; /* unused */
+static struct pci_driver agp_hp_pci_driver = {
+	.name		= "agpgart-hp",
+	.id_table	= agp_hp_pci_table,
+	.probe		= agp_hp_probe,
+};
+
+static int __init agp_hp_init(void)
+{
+	int ret_val;
+
+	ret_val = pci_module_init(&agp_hp_pci_driver);
+	if (ret_val)
+		agp_bridge.type = NOT_SUPPORTED;
+
+	return ret_val;
+}
+
+static void __exit agp_hp_cleanup(void)
+{
+	agp_unregister_driver();
+	pci_unregister_driver(&agp_pci_driver);
 }
 
+module_init(agp_hp_init);
+module_exit(agp_hp_cleanup);
+
+MODULE_LICENSE("GPL and additional rights");
diff -Nru a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
--- a/drivers/char/agp/i460-agp.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/char/agp/i460-agp.c	Mon Dec  9 18:46:38 2002
@@ -1,29 +1,5 @@
 /*
- * AGPGART module version 0.99
- * Copyright (C) 1999 Jeff Hartmann
- * Copyright (C) 1999 Precision Insight, Inc.
- * Copyright (C) 1999 Xi Graphics, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
- * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * TODO: 
- * - Allocate more than order 0 pages to avoid too much linear map splitting.
+ * FIXME: Nothing ever calls this stuff!
  */
 
 #include <linux/module.h>
@@ -592,4 +568,57 @@
 	agp_bridge.cant_use_aperture = 1;
 	return 0;
 }
+
+static int agp_intel_i460_probe (struct pci_dev *dev, const struct pci_device_id *ent)
+{
+	if (pci_find_capability(dev, PCI_CAP_ID_AGP)==0)
+		return -ENODEV;
+
+	intel_i460_setup(dev);
+	agp_register_driver(dev);
+	return 0;
+}
+
+static struct pci_device_id agp_i460_pci_table[] __initdata = {
+	{
+	.class		= (PCI_CLASS_BRIDGE_HOST << 8),
+	.class_mask	= ~0,
+	.vendor		= PCI_VENDOR_ID_INTEL,
+	.device		= PCI_DEVICE_ID_INTEL_460GX,
+	.subvendor	= PCI_ANY_ID,
+	.subdevice	= PCI_ANY_ID,
+	},
+	{ }
+};
+
+MODULE_DEVICE_TABLE(pci, agp_i460_pci_table);
+
+static struct pci_driver agp_i460_pci_driver = {
+	.name		= "agpgart-intel-i460",
+	.id_table	= agp_i460_pci_table,
+	.probe		= agp_i460_probe,
+};
+
+static int __init agp_i460_init(void)
+{
+	int ret_val;
+
+	ret_val = pci_module_init(&agp_i460_pci_driver);
+	if (ret_val)
+		agp_bridge.type = NOT_SUPPORTED;
+
+	return ret_val;
+}
+
+static void __exit agp_i460_cleanup(void)
+{
+	agp_unregister_driver();
+	pci_unregister_driver(&agp_i460_pci_driver);
+}
+
+module_init(agp_i460_init);
+module_exit(agp_i460_cleanup);
+
+MODULE_AUTHOR("Bjorn Helgaas <helgaas@fc.hp.com>");
+MODULE_LICENSE("GPL and additional rights");
 
diff -Nru a/drivers/char/agp/i810-agp.c b/drivers/char/agp/i810-agp.c
--- a/drivers/char/agp/i810-agp.c	Mon Dec  9 18:46:37 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,594 +0,0 @@
-/*
- * AGPGART module version 0.99
- * Copyright (C) 1999 Jeff Hartmann
- * Copyright (C) 1999 Precision Insight, Inc.
- * Copyright (C) 1999 Xi Graphics, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
- * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * TODO: 
- * - Allocate more than order 0 pages to avoid too much linear map splitting.
- */
-
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/agp_backend.h>
-#include "agp.h"
-
-static struct aper_size_info_fixed intel_i810_sizes[] =
-{
-	{64, 16384, 4},
-     /* The 32M mode still requires a 64k gatt */
-	{32, 8192, 4}
-};
-
-#define AGP_DCACHE_MEMORY 1
-#define AGP_PHYS_MEMORY   2
-
-static struct gatt_mask intel_i810_masks[] =
-{
-	{.mask = I810_PTE_VALID, .type = 0},
-	{.mask = (I810_PTE_VALID | I810_PTE_LOCAL), .type = AGP_DCACHE_MEMORY},
-	{.mask = I810_PTE_VALID, .type = 0}
-};
-
-static struct _intel_i810_private {
-	struct pci_dev *i810_dev;	/* device one */
-	volatile u8 *registers;
-	int num_dcache_entries;
-} intel_i810_private;
-
-static int intel_i810_fetch_size(void)
-{
-	u32 smram_miscc;
-	struct aper_size_info_fixed *values;
-
-	pci_read_config_dword(agp_bridge.dev, I810_SMRAM_MISCC, &smram_miscc);
-	values = A_SIZE_FIX(agp_bridge.aperture_sizes);
-
-	if ((smram_miscc & I810_GMS) == I810_GMS_DISABLE) {
-		printk(KERN_WARNING PFX "i810 is disabled\n");
-		return 0;
-	}
-	if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) == I810_GFX_MEM_WIN_32M) {
-		agp_bridge.previous_size =
-		    agp_bridge.current_size = (void *) (values + 1);
-		agp_bridge.aperture_size_idx = 1;
-		return values[1].size;
-	} else {
-		agp_bridge.previous_size =
-		    agp_bridge.current_size = (void *) (values);
-		agp_bridge.aperture_size_idx = 0;
-		return values[0].size;
-	}
-
-	return 0;
-}
-
-static int intel_i810_configure(void)
-{
-	struct aper_size_info_fixed *current_size;
-	u32 temp;
-	int i;
-
-	current_size = A_SIZE_FIX(agp_bridge.current_size);
-
-	pci_read_config_dword(intel_i810_private.i810_dev, I810_MMADDR, &temp);
-	temp &= 0xfff80000;
-
-	intel_i810_private.registers =
-	    (volatile u8 *) ioremap(temp, 128 * 4096);
-
-	if ((INREG32(intel_i810_private.registers, I810_DRAM_CTL)
-	     & I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) {
-		/* This will need to be dynamically assigned */
-		printk(KERN_INFO PFX "detected 4MB dedicated video ram.\n");
-		intel_i810_private.num_dcache_entries = 1024;
-	}
-	pci_read_config_dword(intel_i810_private.i810_dev, I810_GMADDR, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
-	OUTREG32(intel_i810_private.registers, I810_PGETBL_CTL,
-		 agp_bridge.gatt_bus_addr | I810_PGETBL_ENABLED);
-	CACHE_FLUSH();
-
-	if (agp_bridge.needs_scratch_page == TRUE) {
-		for (i = 0; i < current_size->num_entries; i++) {
-			OUTREG32(intel_i810_private.registers,
-				 I810_PTE_BASE + (i * 4),
-				 agp_bridge.scratch_page);
-		}
-	}
-	return 0;
-}
-
-static void intel_i810_cleanup(void)
-{
-	OUTREG32(intel_i810_private.registers, I810_PGETBL_CTL, 0);
-	iounmap((void *) intel_i810_private.registers);
-}
-
-static void intel_i810_tlbflush(agp_memory * mem)
-{
-	return;
-}
-
-static void intel_i810_agp_enable(u32 mode)
-{
-	return;
-}
-
-static int intel_i810_insert_entries(agp_memory * mem, off_t pg_start,
-				     int type)
-{
-	int i, j, num_entries;
-	void *temp;
-
-	temp = agp_bridge.current_size;
-	num_entries = A_SIZE_FIX(temp)->num_entries;
-
-	if ((pg_start + mem->page_count) > num_entries) {
-		return -EINVAL;
-	}
-	for (j = pg_start; j < (pg_start + mem->page_count); j++) {
-		if (!PGE_EMPTY(agp_bridge.gatt_table[j])) {
-			return -EBUSY;
-		}
-	}
-
-	if (type != 0 || mem->type != 0) {
-		if ((type == AGP_DCACHE_MEMORY) &&
-		    (mem->type == AGP_DCACHE_MEMORY)) {
-			/* special insert */
-			CACHE_FLUSH();
-			for (i = pg_start;
-			     i < (pg_start + mem->page_count); i++) {
-				OUTREG32(intel_i810_private.registers,
-					 I810_PTE_BASE + (i * 4),
-					 (i * 4096) | I810_PTE_LOCAL |
-					 I810_PTE_VALID);
-			}
-			CACHE_FLUSH();
-			agp_bridge.tlb_flush(mem);
-			return 0;
-		}
-	        if((type == AGP_PHYS_MEMORY) &&
-		   (mem->type == AGP_PHYS_MEMORY)) {
-		   goto insert;
-		}
-		return -EINVAL;
-	}
-
-insert:
-   	CACHE_FLUSH();
-	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
-		OUTREG32(intel_i810_private.registers,
-			 I810_PTE_BASE + (j * 4), mem->memory[i]);
-	}
-	CACHE_FLUSH();
-
-	agp_bridge.tlb_flush(mem);
-	return 0;
-}
-
-static int intel_i810_remove_entries(agp_memory * mem, off_t pg_start,
-				     int type)
-{
-	int i;
-
-	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
-		OUTREG32(intel_i810_private.registers,
-			 I810_PTE_BASE + (i * 4),
-			 agp_bridge.scratch_page);
-	}
-
-	CACHE_FLUSH();
-	agp_bridge.tlb_flush(mem);
-	return 0;
-}
-
-static agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type)
-{
-	agp_memory *new;
-
-	if (type == AGP_DCACHE_MEMORY) {
-		if (pg_count != intel_i810_private.num_dcache_entries) {
-			return NULL;
-		}
-		new = agp_create_memory(1);
-
-		if (new == NULL) {
-			return NULL;
-		}
-		new->type = AGP_DCACHE_MEMORY;
-		new->page_count = pg_count;
-		new->num_scratch_pages = 0;
-		vfree(new->memory);
-	   	MOD_INC_USE_COUNT;
-		return new;
-	}
-	if(type == AGP_PHYS_MEMORY) {
-		void *addr;
-		/* The I810 requires a physical address to program
-		 * it's mouse pointer into hardware.  However the
-		 * Xserver still writes to it through the agp
-		 * aperture
-		 */
-	   	if (pg_count != 1) {
-		   	return NULL;
-		}
-	   	new = agp_create_memory(1);
-
-		if (new == NULL) {
-			return NULL;
-		}
-	   	MOD_INC_USE_COUNT;
-		addr = agp_bridge.agp_alloc_page();
-
-		if (addr == NULL) {
-			/* Free this structure */
-			agp_free_memory(new);
-			return NULL;
-		}
-		new->memory[0] = agp_bridge.mask_memory(virt_to_phys(addr), type);
-		new->page_count = 1;
-	   	new->num_scratch_pages = 1;
-	   	new->type = AGP_PHYS_MEMORY;
-	        new->physical = virt_to_phys((void *) new->memory[0]);
-	   	return new;
-	}
-   
-	return NULL;
-}
-
-static void intel_i810_free_by_type(agp_memory * curr)
-{
-	agp_free_key(curr->key);
-   	if(curr->type == AGP_PHYS_MEMORY) {
-	   	agp_bridge.agp_destroy_page(
-				 phys_to_virt(curr->memory[0]));
-		vfree(curr->memory);
-	}
-	kfree(curr);
-   	MOD_DEC_USE_COUNT;
-}
-
-static unsigned long intel_i810_mask_memory(unsigned long addr, int type)
-{
-	/* Type checking must be done elsewhere */
-	return addr | agp_bridge.masks[type].mask;
-}
-
-int __init intel_i810_setup(struct pci_dev *i810_dev)
-{
-	intel_i810_private.i810_dev = i810_dev;
-
-	agp_bridge.masks = intel_i810_masks;
-	agp_bridge.num_of_masks = 2;
-	agp_bridge.aperture_sizes = (void *) intel_i810_sizes;
-	agp_bridge.size_type = FIXED_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 2;
-	agp_bridge.dev_private_data = (void *) &intel_i810_private;
-	agp_bridge.needs_scratch_page = TRUE;
-	agp_bridge.configure = intel_i810_configure;
-	agp_bridge.fetch_size = intel_i810_fetch_size;
-	agp_bridge.cleanup = intel_i810_cleanup;
-	agp_bridge.tlb_flush = intel_i810_tlbflush;
-	agp_bridge.mask_memory = intel_i810_mask_memory;
-	agp_bridge.agp_enable = intel_i810_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-	agp_bridge.insert_memory = intel_i810_insert_entries;
-	agp_bridge.remove_memory = intel_i810_remove_entries;
-	agp_bridge.alloc_by_type = intel_i810_alloc_by_type;
-	agp_bridge.free_by_type = intel_i810_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
-
-	return 0;
-}
-
-static struct aper_size_info_fixed intel_i830_sizes[] =
-{
-	{128, 32768, 5},
-	/* The 64M mode still requires a 128k gatt */
-	{64, 16384, 5}
-};
-
-static struct _intel_i830_private {
-	struct pci_dev *i830_dev;   /* device one */
-	volatile u8 *registers;
-	int gtt_entries;
-} intel_i830_private;
-
-static void intel_i830_init_gtt_entries(void)
-{
-	u16 gmch_ctrl;
-	int gtt_entries;
-	u8 rdct;
-	static const int ddt[4] = { 0, 16, 32, 64 };
-
-	pci_read_config_word(agp_bridge.dev,I830_GMCH_CTRL,&gmch_ctrl);
-
-	switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
-	case I830_GMCH_GMS_STOLEN_512:
-		gtt_entries = KB(512) - KB(132);
-		printk(KERN_INFO PFX "detected %dK stolen memory.\n",gtt_entries / KB(1));
-		break;
-	case I830_GMCH_GMS_STOLEN_1024:
-		gtt_entries = MB(1) - KB(132);
-		printk(KERN_INFO PFX "detected %dK stolen memory.\n",gtt_entries / KB(1));
-		break;
-	case I830_GMCH_GMS_STOLEN_8192:
-		gtt_entries = MB(8) - KB(132);
-		printk(KERN_INFO PFX "detected %dK stolen memory.\n",gtt_entries / KB(1));
-		break;
-	case I830_GMCH_GMS_LOCAL:
-		rdct = INREG8(intel_i830_private.registers,I830_RDRAM_CHANNEL_TYPE);
-		gtt_entries = (I830_RDRAM_ND(rdct) + 1) * MB(ddt[I830_RDRAM_DDT(rdct)]);
-		printk(KERN_INFO PFX "detected %dK local memory.\n",gtt_entries / KB(1));
-		break;
-	default:
-		printk(KERN_INFO PFX "no video memory detected.\n");
-		gtt_entries = 0;
-		break;
-	}
-
-	gtt_entries /= KB(4);
-
-	intel_i830_private.gtt_entries = gtt_entries;
-}
-
-/* The intel i830 automatically initializes the agp aperture during POST.
- * Use the memory already set aside for in the GTT.
- */
-static int intel_i830_create_gatt_table(void)
-{
-	int page_order;
-	struct aper_size_info_fixed *size;
-	int num_entries;
-	u32 temp;
-
-	size = agp_bridge.current_size;
-	page_order = size->page_order;
-	num_entries = size->num_entries;
-	agp_bridge.gatt_table_real = 0;
-
-	pci_read_config_dword(intel_i830_private.i830_dev,I810_MMADDR,&temp);
-	temp &= 0xfff80000;
-
-	intel_i830_private.registers = (volatile u8 *) ioremap(temp,128 * 4096);
-	if (!intel_i830_private.registers) return (-ENOMEM);
-
-	temp = INREG32(intel_i830_private.registers,I810_PGETBL_CTL) & 0xfffff000;
-	CACHE_FLUSH();
-
-	/* we have to call this as early as possible after the MMIO base address is known */
-	intel_i830_init_gtt_entries();
-
-	agp_bridge.gatt_table = NULL;
-
-	agp_bridge.gatt_bus_addr = temp;
-
-	return(0);
-}
-
-/* Return the gatt table to a sane state. Use the top of stolen
- * memory for the GTT.
- */
-static int intel_i830_free_gatt_table(void)
-{
-	return(0);
-}
-
-static int intel_i830_fetch_size(void)
-{
-	u16 gmch_ctrl;
-	struct aper_size_info_fixed *values;
-
-	pci_read_config_word(agp_bridge.dev,I830_GMCH_CTRL,&gmch_ctrl);
-	values = A_SIZE_FIX(agp_bridge.aperture_sizes);
-
-	if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
-		agp_bridge.previous_size = agp_bridge.current_size = (void *) values;
-		agp_bridge.aperture_size_idx = 0;
-		return(values[0].size);
-	} else {
-		agp_bridge.previous_size = agp_bridge.current_size = (void *) values;
-		agp_bridge.aperture_size_idx = 1;
-		return(values[1].size);
-	}
-
-	return(0);
-}
-
-static int intel_i830_configure(void)
-{
-	struct aper_size_info_fixed *current_size;
-	u32 temp;
-	u16 gmch_ctrl;
-	int i;
-
-	current_size = A_SIZE_FIX(agp_bridge.current_size);
-
-	pci_read_config_dword(intel_i830_private.i830_dev,I810_GMADDR,&temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
-
-	pci_read_config_word(agp_bridge.dev,I830_GMCH_CTRL,&gmch_ctrl);
-	gmch_ctrl |= I830_GMCH_ENABLED;
-	pci_write_config_word(agp_bridge.dev,I830_GMCH_CTRL,gmch_ctrl);
-
-	OUTREG32(intel_i830_private.registers,I810_PGETBL_CTL,agp_bridge.gatt_bus_addr | I810_PGETBL_ENABLED);
-	CACHE_FLUSH();
-
-	if (agp_bridge.needs_scratch_page == TRUE)
-		for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++)
-			OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge.scratch_page);
-
-	return (0);
-}
-
-static void intel_i830_cleanup(void)
-{
-	iounmap((void *) intel_i830_private.registers);
-}
-
-static int intel_i830_insert_entries(agp_memory *mem,off_t pg_start,int type)
-{
-	int i,j,num_entries;
-	void *temp;
-
-	temp = agp_bridge.current_size;
-	num_entries = A_SIZE_FIX(temp)->num_entries;
-
-	if (pg_start < intel_i830_private.gtt_entries) {
-		printk (KERN_DEBUG "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
-				pg_start,intel_i830_private.gtt_entries);
-
-		printk ("Trying to insert into local/stolen memory\n");
-		return (-EINVAL);
-	}
-
-	if ((pg_start + mem->page_count) > num_entries)
-		return (-EINVAL);
-
-	/* The i830 can't check the GTT for entries since its read only,
-	 * depend on the caller to make the correct offset decisions.
-	 */
-
-	if ((type != 0 && type != AGP_PHYS_MEMORY) ||
-		(mem->type != 0 && mem->type != AGP_PHYS_MEMORY))
-		return (-EINVAL);
-
-	CACHE_FLUSH();
-
-	for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
-		OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (j * 4),mem->memory[i]);
-
-	CACHE_FLUSH();
-
-	agp_bridge.tlb_flush(mem);
-
-	return(0);
-}
-
-static int intel_i830_remove_entries(agp_memory *mem,off_t pg_start,int type)
-{
-	int i;
-
-	CACHE_FLUSH ();
-
-	if (pg_start < intel_i830_private.gtt_entries) {
-		printk ("Trying to disable local/stolen memory\n");
-		return (-EINVAL);
-	}
-
-	for (i = pg_start; i < (mem->page_count + pg_start); i++)
-		OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge.scratch_page);
-
-	CACHE_FLUSH();
-
-	agp_bridge.tlb_flush(mem);
-
-	return (0);
-}
-
-static agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type)
-{
-	agp_memory *nw;
-
-	/* always return NULL for now */
-	if (type == AGP_DCACHE_MEMORY) return(NULL);
-
-	if (type == AGP_PHYS_MEMORY) {
-		void *addr;
-
-		/* The i830 requires a physical address to program
-		 * it's mouse pointer into hardware. However the
-		 * Xserver still writes to it through the agp
-		 * aperture
-		 */
-
-		if (pg_count != 1) return(NULL);
-
-		nw = agp_create_memory(1);
-
-		if (nw == NULL) return(NULL);
-
-		MOD_INC_USE_COUNT;
-		addr = agp_bridge.agp_alloc_page();
-		if (addr == NULL) {
-			/* free this structure */
-			agp_free_memory(nw);
-			return(NULL);
-		}
-
-		nw->memory[0] = agp_bridge.mask_memory(virt_to_phys(addr),type);
-		nw->page_count = 1;
-		nw->num_scratch_pages = 1;
-		nw->type = AGP_PHYS_MEMORY;
-		nw->physical = virt_to_phys(addr);
-		return(nw);
-	}
-
-	return(NULL);
-}
-
-int __init intel_i830_setup(struct pci_dev *i830_dev)
-{
-	intel_i830_private.i830_dev = i830_dev;
-
-	agp_bridge.masks = intel_i810_masks;
-	agp_bridge.num_of_masks = 3;
-	agp_bridge.aperture_sizes = (void *) intel_i830_sizes;
-	agp_bridge.size_type = FIXED_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 2;
-
-	agp_bridge.dev_private_data = (void *) &intel_i830_private;
-	agp_bridge.needs_scratch_page = TRUE;
-
-	agp_bridge.configure = intel_i830_configure;
-	agp_bridge.fetch_size = intel_i830_fetch_size;
-	agp_bridge.cleanup = intel_i830_cleanup;
-	agp_bridge.tlb_flush = intel_i810_tlbflush;
-	agp_bridge.mask_memory = intel_i810_mask_memory;
-	agp_bridge.agp_enable = intel_i810_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-
-	agp_bridge.create_gatt_table = intel_i830_create_gatt_table;
-	agp_bridge.free_gatt_table = intel_i830_free_gatt_table;
-
-	agp_bridge.insert_memory = intel_i830_insert_entries;
-	agp_bridge.remove_memory = intel_i830_remove_entries;
-	agp_bridge.alloc_by_type = intel_i830_alloc_by_type;
-	agp_bridge.free_by_type = intel_i810_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
-
-	return(0);
-}
-
diff -Nru a/drivers/char/agp/i8x0-agp.c b/drivers/char/agp/i8x0-agp.c
--- a/drivers/char/agp/i8x0-agp.c	Mon Dec  9 18:46:37 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,731 +0,0 @@
-/*
- * AGPGART module version 0.99
- * Copyright (C) 1999 Jeff Hartmann
- * Copyright (C) 1999 Precision Insight, Inc.
- * Copyright (C) 1999 Xi Graphics, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
- * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * TODO: 
- * - Allocate more than order 0 pages to avoid too much linear map splitting.
- */
-
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/agp_backend.h>
-#include "agp.h"
-
-
-static int intel_fetch_size(void)
-{
-	int i;
-	u16 temp;
-	struct aper_size_info_16 *values;
-
-	pci_read_config_word(agp_bridge.dev, INTEL_APSIZE, &temp);
-	values = A_SIZE_16(agp_bridge.aperture_sizes);
-
-	for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
-		if (temp == values[i].size_value) {
-			agp_bridge.previous_size =
-			    agp_bridge.current_size = (void *) (values + i);
-			agp_bridge.aperture_size_idx = i;
-			return values[i].size;
-		}
-	}
-
-	return 0;
-}
-
-static int intel_8xx_fetch_size(void)
-{
-	int i;
-	u8 temp;
-	struct aper_size_info_8 *values;
-
-	pci_read_config_byte(agp_bridge.dev, INTEL_APSIZE, &temp);
-
-	/* Intel 815 chipsets have a _weird_ APSIZE register with only
-	 * one non-reserved bit, so mask the others out ... */
-	if (agp_bridge.type == INTEL_I815)
-		temp &= (1 << 3);
-
-	values = A_SIZE_8(agp_bridge.aperture_sizes);
-
-	for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
-		if (temp == values[i].size_value) {
-			agp_bridge.previous_size =
-				agp_bridge.current_size = (void *) (values + i);
-			agp_bridge.aperture_size_idx = i;
-			return values[i].size;
-		}
-	}
-	return 0;
-}
-
-
-static void intel_tlbflush(agp_memory * mem)
-{
-	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2200);
-	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2280);
-}
-
-
-static void intel_8xx_tlbflush(agp_memory * mem)
-{
-  u32 temp;
-  pci_read_config_dword(agp_bridge.dev, INTEL_AGPCTRL, &temp);
-  pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, temp & ~(1 << 7));
-  pci_read_config_dword(agp_bridge.dev, INTEL_AGPCTRL, &temp);
-  pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, temp | (1 << 7));
-}
-
-
-static void intel_cleanup(void)
-{
-	u16 temp;
-	struct aper_size_info_16 *previous_size;
-
-	previous_size = A_SIZE_16(agp_bridge.previous_size);
-	pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp);
-	pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, temp & ~(1 << 9));
-	pci_write_config_word(agp_bridge.dev, INTEL_APSIZE,
-			      previous_size->size_value);
-}
-
-
-static void intel_8xx_cleanup(void)
-{
-	u16 temp;
-	struct aper_size_info_8 *previous_size;
-
-	previous_size = A_SIZE_8(agp_bridge.previous_size);
-	pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp);
-	pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, temp & ~(1 << 9));
-	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
-			      previous_size->size_value);
-}
-
-
-static int intel_configure(void)
-{
-	u32 temp;
-	u16 temp2;
-	struct aper_size_info_16 *current_size;
-
-	current_size = A_SIZE_16(agp_bridge.current_size);
-
-	/* aperture size */
-	pci_write_config_word(agp_bridge.dev, INTEL_APSIZE,
-			      current_size->size_value);
-
-	/* address to map to */
-	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
-
-	/* attbase - aperture base */
-	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE,
-			       agp_bridge.gatt_bus_addr);
-
-	/* agpctrl */
-	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2280);
-
-	/* paccfg/nbxcfg */
-	pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp2);
-	pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG,
-			      (temp2 & ~(1 << 10)) | (1 << 9));
-	/* clear any possible error conditions */
-	pci_write_config_byte(agp_bridge.dev, INTEL_ERRSTS + 1, 7);
-	return 0;
-}
-
-static int intel_815_configure(void)
-{
-	u32 temp, addr;
-	u8 temp2;
-	struct aper_size_info_8 *current_size;
-
-	current_size = A_SIZE_8(agp_bridge.current_size);
-
-	/* aperture size */
-	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
-			current_size->size_value); 
-
-	/* address to map to */
-	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
-
-	/* attbase - aperture base */
-	/* the Intel 815 chipset spec. says that bits 29-31 in the
-	* ATTBASE register are reserved -> try not to write them */
-	if (agp_bridge.gatt_bus_addr &  INTEL_815_ATTBASE_MASK)
-		panic("gatt bus addr too high");
-	pci_read_config_dword(agp_bridge.dev, INTEL_ATTBASE, &addr);
-	addr &= INTEL_815_ATTBASE_MASK;
-	addr |= agp_bridge.gatt_bus_addr;
-	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, addr);
-
-	/* agpctrl */
-	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); 
-
-	/* apcont */
-	pci_read_config_byte(agp_bridge.dev, INTEL_815_APCONT, &temp2);
-	pci_write_config_byte(agp_bridge.dev, INTEL_815_APCONT, temp2 | (1 << 1));
-
-	/* clear any possible error conditions */
-	/* Oddness : this chipset seems to have no ERRSTS register ! */
-	return 0;
-}
-
-static void intel_820_tlbflush(agp_memory * mem)
-{
-  return;
-}
-
-static void intel_820_cleanup(void)
-{
-	u8 temp;
-	struct aper_size_info_8 *previous_size;
-
-	previous_size = A_SIZE_8(agp_bridge.previous_size);
-	pci_read_config_byte(agp_bridge.dev, INTEL_I820_RDCR, &temp);
-	pci_write_config_byte(agp_bridge.dev, INTEL_I820_RDCR, 
-			      temp & ~(1 << 1));
-	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
-			      previous_size->size_value);
-}
-
-
-static int intel_820_configure(void)
-{
-	u32 temp;
- 	u8 temp2; 
-	struct aper_size_info_8 *current_size;
-
-	current_size = A_SIZE_8(agp_bridge.current_size);
-
-	/* aperture size */
-	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
-			      current_size->size_value); 
-
-	/* address to map to */
-	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
-
-	/* attbase - aperture base */
-	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE,
-			       agp_bridge.gatt_bus_addr); 
-
-	/* agpctrl */
-	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); 
-
-	/* global enable aperture access */
-	/* This flag is not accessed through MCHCFG register as in */
-	/* i850 chipset. */
-	pci_read_config_byte(agp_bridge.dev, INTEL_I820_RDCR, &temp2);
-	pci_write_config_byte(agp_bridge.dev, INTEL_I820_RDCR, 
-			      temp2 | (1 << 1));
-	/* clear any possible AGP-related error conditions */
-	pci_write_config_word(agp_bridge.dev, INTEL_I820_ERRSTS, 0x001c); 
-	return 0;
-}
-
-static int intel_840_configure(void)
-{
-	u32 temp;
-	u16 temp2;
-	struct aper_size_info_8 *current_size;
-
-	current_size = A_SIZE_8(agp_bridge.current_size);
-
-	/* aperture size */
-	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
-			      current_size->size_value); 
-
-	/* address to map to */
-	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
-
-	/* attbase - aperture base */
-	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE,
-			       agp_bridge.gatt_bus_addr); 
-
-	/* agpctrl */
-	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); 
-
-	/* mcgcfg */
-	pci_read_config_word(agp_bridge.dev, INTEL_I840_MCHCFG, &temp2);
-	pci_write_config_word(agp_bridge.dev, INTEL_I840_MCHCFG,
-			      temp2 | (1 << 9));
-	/* clear any possible error conditions */
-	pci_write_config_word(agp_bridge.dev, INTEL_I840_ERRSTS, 0xc000); 
-	return 0;
-}
-
-static int intel_845_configure(void)
-{
-	u32 temp;
-	u8 temp2;
-	struct aper_size_info_8 *current_size;
-
-	current_size = A_SIZE_8(agp_bridge.current_size);
-
-	/* aperture size */
-	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
-			      current_size->size_value); 
-
-	/* address to map to */
-	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
-
-	/* attbase - aperture base */
-	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE,
-			       agp_bridge.gatt_bus_addr); 
-
-	/* agpctrl */
-	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); 
-
-	/* agpm */
-	pci_read_config_byte(agp_bridge.dev, INTEL_I845_AGPM, &temp2);
-	pci_write_config_byte(agp_bridge.dev, INTEL_I845_AGPM,
-			      temp2 | (1 << 1));
-	/* clear any possible error conditions */
-	pci_write_config_word(agp_bridge.dev, INTEL_I845_ERRSTS, 0x001c); 
-	return 0;
-}
-
-static void intel_845_resume(void)
-{
-	intel_845_configure();
-}
-
-static int intel_850_configure(void)
-{
-	u32 temp;
-	u16 temp2;
-	struct aper_size_info_8 *current_size;
-
-	current_size = A_SIZE_8(agp_bridge.current_size);
-
-	/* aperture size */
-	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
-			      current_size->size_value); 
-
-	/* address to map to */
-	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
-
-	/* attbase - aperture base */
-	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE,
-			       agp_bridge.gatt_bus_addr); 
-
-	/* agpctrl */
-	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); 
-
-	/* mcgcfg */
-	pci_read_config_word(agp_bridge.dev, INTEL_I850_MCHCFG, &temp2);
-	pci_write_config_word(agp_bridge.dev, INTEL_I850_MCHCFG,
-			      temp2 | (1 << 9));
-	/* clear any possible AGP-related error conditions */
-	pci_write_config_word(agp_bridge.dev, INTEL_I850_ERRSTS, 0x001c); 
-	return 0;
-}
-
-static int intel_860_configure(void)
-{
-	u32 temp;
-	u16 temp2;
-	struct aper_size_info_8 *current_size;
-
-	current_size = A_SIZE_8(agp_bridge.current_size);
-
-	/* aperture size */
-	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
-			      current_size->size_value);
-
-	/* address to map to */
-	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
-
-	/* attbase - aperture base */
-	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE,
-			       agp_bridge.gatt_bus_addr);
-
-	/* agpctrl */
-	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000);
-
-	/* mcgcfg */
-	pci_read_config_word(agp_bridge.dev, INTEL_I860_MCHCFG, &temp2);
-	pci_write_config_word(agp_bridge.dev, INTEL_I860_MCHCFG,
-			      temp2 | (1 << 9));
-	/* clear any possible AGP-related error conditions */
-	pci_write_config_word(agp_bridge.dev, INTEL_I860_ERRSTS, 0xf700);
-	return 0;
-}
-
-static int intel_830mp_configure(void)
-{
-	u32 temp;
-	u16 temp2;
-	struct aper_size_info_8 *current_size;
-
-	current_size = A_SIZE_8(agp_bridge.current_size);
-
-	/* aperture size */
-	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
-			      current_size->size_value);
-
-	/* address to map to */
-	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
-
-	/* attbase - aperture base */
-	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE,
-			       agp_bridge.gatt_bus_addr);
-
-	/* agpctrl */
-	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000);
-
-	/* gmch */
-	pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp2);
-	pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG,
-			      temp2 | (1 << 9));
-	/* clear any possible AGP-related error conditions */
-	pci_write_config_word(agp_bridge.dev, INTEL_I830_ERRSTS, 0x1c);
-	return 0;
-}
-
-static unsigned long intel_mask_memory(unsigned long addr, int type)
-{
-	/* Memory type is ignored */
-
-	return addr | agp_bridge.masks[0].mask;
-}
-
-static void intel_resume(void)
-{
-	intel_configure();
-}
-
-/* Setup function */
-static struct gatt_mask intel_generic_masks[] =
-{
-	{.mask = 0x00000017, .type = 0}
-};
-
-static struct aper_size_info_8 intel_815_sizes[2] =
-{
-	{64, 16384, 4, 0},
-	{32, 8192, 3, 8},
-};
-	
-static struct aper_size_info_8 intel_8xx_sizes[7] =
-{
-	{256, 65536, 6, 0},
-	{128, 32768, 5, 32},
-	{64, 16384, 4, 48},
-	{32, 8192, 3, 56},
-	{16, 4096, 2, 60},
-	{8, 2048, 1, 62},
-	{4, 1024, 0, 63}
-};
-
-static struct aper_size_info_16 intel_generic_sizes[7] =
-{
-	{256, 65536, 6, 0},
-	{128, 32768, 5, 32},
-	{64, 16384, 4, 48},
-	{32, 8192, 3, 56},
-	{16, 4096, 2, 60},
-	{8, 2048, 1, 62},
-	{4, 1024, 0, 63}
-};
-
-static struct aper_size_info_8 intel_830mp_sizes[4] = 
-{
-  {256, 65536, 6, 0},
-  {128, 32768, 5, 32},
-  {64, 16384, 4, 48},
-  {32, 8192, 3, 56}
-};
-
-int __init intel_generic_setup (struct pci_dev *pdev)
-{
-	agp_bridge.masks = intel_generic_masks;
-	agp_bridge.num_of_masks = 1;
-	agp_bridge.aperture_sizes = (void *) intel_generic_sizes;
-	agp_bridge.size_type = U16_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 7;
-	agp_bridge.dev_private_data = NULL;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = intel_configure;
-	agp_bridge.fetch_size = intel_fetch_size;
-	agp_bridge.cleanup = intel_cleanup;
-	agp_bridge.tlb_flush = intel_tlbflush;
-	agp_bridge.mask_memory = intel_mask_memory;
-	agp_bridge.agp_enable = agp_generic_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-	agp_bridge.insert_memory = agp_generic_insert_memory;
-	agp_bridge.remove_memory = agp_generic_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = intel_resume;
-	agp_bridge.cant_use_aperture = 0;
-
-	return 0;
-	
-	(void) pdev; /* unused */
-}
-
-int __init intel_815_setup (struct pci_dev *pdev)
-{
-	agp_bridge.masks = intel_generic_masks;
-	agp_bridge.num_of_masks = 1;
-	agp_bridge.aperture_sizes = (void *) intel_815_sizes;
-	agp_bridge.size_type = U8_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 2;
-	agp_bridge.dev_private_data = NULL;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = intel_815_configure;
-	agp_bridge.fetch_size = intel_8xx_fetch_size;
-	agp_bridge.cleanup = intel_8xx_cleanup;
-	agp_bridge.tlb_flush = intel_8xx_tlbflush;
-	agp_bridge.mask_memory = intel_mask_memory;
-	agp_bridge.agp_enable = agp_generic_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-	agp_bridge.insert_memory = agp_generic_insert_memory;
-	agp_bridge.remove_memory = agp_generic_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
-
-	return 0;
-}
-
-
-int __init intel_820_setup (struct pci_dev *pdev)
-{
-       agp_bridge.masks = intel_generic_masks;
-       agp_bridge.num_of_masks = 1;
-       agp_bridge.aperture_sizes = (void *) intel_8xx_sizes;
-       agp_bridge.size_type = U8_APER_SIZE;
-       agp_bridge.num_aperture_sizes = 7;
-       agp_bridge.dev_private_data = NULL;
-       agp_bridge.needs_scratch_page = FALSE;
-       agp_bridge.configure = intel_820_configure;
-       agp_bridge.fetch_size = intel_8xx_fetch_size;
-       agp_bridge.cleanup = intel_820_cleanup;
-       agp_bridge.tlb_flush = intel_820_tlbflush;
-       agp_bridge.mask_memory = intel_mask_memory;
-       agp_bridge.agp_enable = agp_generic_agp_enable;
-       agp_bridge.cache_flush = global_cache_flush;
-       agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-       agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-       agp_bridge.insert_memory = agp_generic_insert_memory;
-       agp_bridge.remove_memory = agp_generic_remove_memory;
-       agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-       agp_bridge.free_by_type = agp_generic_free_by_type;
-       agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-       agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-       agp_bridge.suspend = agp_generic_suspend;
-       agp_bridge.resume = agp_generic_resume;
-       agp_bridge.cant_use_aperture = 0;
-
-       return 0;
-
-       (void) pdev; /* unused */
-}
-
-int __init intel_830mp_setup (struct pci_dev *pdev)
-{
-       agp_bridge.masks = intel_generic_masks;
-       agp_bridge.num_of_masks = 1;
-       agp_bridge.aperture_sizes = (void *) intel_830mp_sizes;
-       agp_bridge.size_type = U8_APER_SIZE;
-       agp_bridge.num_aperture_sizes = 4;
-       agp_bridge.dev_private_data = NULL;
-       agp_bridge.needs_scratch_page = FALSE;
-       agp_bridge.configure = intel_830mp_configure;
-       agp_bridge.fetch_size = intel_8xx_fetch_size;
-       agp_bridge.cleanup = intel_8xx_cleanup;
-       agp_bridge.tlb_flush = intel_8xx_tlbflush;
-       agp_bridge.mask_memory = intel_mask_memory;
-       agp_bridge.agp_enable = agp_generic_agp_enable;
-       agp_bridge.cache_flush = global_cache_flush;
-       agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-       agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-       agp_bridge.insert_memory = agp_generic_insert_memory;
-       agp_bridge.remove_memory = agp_generic_remove_memory;
-       agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-       agp_bridge.free_by_type = agp_generic_free_by_type;
-       agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-       agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-       agp_bridge.suspend = agp_generic_suspend;
-       agp_bridge.resume = agp_generic_resume;
-       agp_bridge.cant_use_aperture = 0;
-
-       return 0;
-
-       (void) pdev; /* unused */
-}
-
-int __init intel_840_setup (struct pci_dev *pdev)
-{
-	agp_bridge.masks = intel_generic_masks;
-	agp_bridge.num_of_masks = 1;
-	agp_bridge.aperture_sizes = (void *) intel_8xx_sizes;
-	agp_bridge.size_type = U8_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 7;
-	agp_bridge.dev_private_data = NULL;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = intel_840_configure;
-	agp_bridge.fetch_size = intel_8xx_fetch_size;
-	agp_bridge.cleanup = intel_8xx_cleanup;
-	agp_bridge.tlb_flush = intel_8xx_tlbflush;
-	agp_bridge.mask_memory = intel_mask_memory;
-	agp_bridge.agp_enable = agp_generic_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-	agp_bridge.insert_memory = agp_generic_insert_memory;
-	agp_bridge.remove_memory = agp_generic_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
-
-	return 0;
-	
-	(void) pdev; /* unused */
-}
-
-int __init intel_845_setup (struct pci_dev *pdev)
-{
-	agp_bridge.masks = intel_generic_masks;
-	agp_bridge.num_of_masks = 1;
-	agp_bridge.aperture_sizes = (void *) intel_8xx_sizes;
-	agp_bridge.size_type = U8_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 7;
-	agp_bridge.dev_private_data = NULL;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = intel_845_configure;
-	agp_bridge.fetch_size = intel_8xx_fetch_size;
-	agp_bridge.cleanup = intel_8xx_cleanup;
-	agp_bridge.tlb_flush = intel_8xx_tlbflush;
-	agp_bridge.mask_memory = intel_mask_memory;
-	agp_bridge.agp_enable = agp_generic_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-	agp_bridge.insert_memory = agp_generic_insert_memory;
-	agp_bridge.remove_memory = agp_generic_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = intel_845_resume;
-	agp_bridge.cant_use_aperture = 0;
-
-	return 0;
-	
-	(void) pdev; /* unused */
-}
-
-int __init intel_850_setup (struct pci_dev *pdev)
-{
-	agp_bridge.masks = intel_generic_masks;
-	agp_bridge.num_of_masks = 1;
-	agp_bridge.aperture_sizes = (void *) intel_8xx_sizes;
-	agp_bridge.size_type = U8_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 7;
-	agp_bridge.dev_private_data = NULL;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = intel_850_configure;
-	agp_bridge.fetch_size = intel_8xx_fetch_size;
-	agp_bridge.cleanup = intel_8xx_cleanup;
-	agp_bridge.tlb_flush = intel_8xx_tlbflush;
-	agp_bridge.mask_memory = intel_mask_memory;
-	agp_bridge.agp_enable = agp_generic_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-	agp_bridge.insert_memory = agp_generic_insert_memory;
-	agp_bridge.remove_memory = agp_generic_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
-
-	return 0;
-	
-	(void) pdev; /* unused */
-}
-
-int __init intel_860_setup (struct pci_dev *pdev)
-{
-	agp_bridge.masks = intel_generic_masks;
-	agp_bridge.num_of_masks = 1;
-	agp_bridge.aperture_sizes = (void *) intel_8xx_sizes;
-	agp_bridge.size_type = U8_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 7;
-	agp_bridge.dev_private_data = NULL;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = intel_860_configure;
-	agp_bridge.fetch_size = intel_8xx_fetch_size;
-	agp_bridge.cleanup = intel_8xx_cleanup;
-	agp_bridge.tlb_flush = intel_8xx_tlbflush;
-	agp_bridge.mask_memory = intel_mask_memory;
-	agp_bridge.agp_enable = agp_generic_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-	agp_bridge.insert_memory = agp_generic_insert_memory;
-	agp_bridge.remove_memory = agp_generic_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
-
-	return 0;
-
-	(void) pdev; /* unused */
-}
-
diff -Nru a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/agp/intel-agp.c	Mon Dec  9 18:46:37 2002
@@ -0,0 +1,1496 @@
+/*
+ * Intel AGPGART routines.
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/agp_backend.h>
+#include "agp.h"
+
+static int agp_try_unsupported __initdata = 0;
+
+
+static struct aper_size_info_fixed intel_i810_sizes[] =
+{
+	{64, 16384, 4},
+     /* The 32M mode still requires a 64k gatt */
+	{32, 8192, 4}
+};
+
+#define AGP_DCACHE_MEMORY 1
+#define AGP_PHYS_MEMORY   2
+
+static struct gatt_mask intel_i810_masks[] =
+{
+	{.mask = I810_PTE_VALID, .type = 0},
+	{.mask = (I810_PTE_VALID | I810_PTE_LOCAL), .type = AGP_DCACHE_MEMORY},
+	{.mask = I810_PTE_VALID, .type = 0}
+};
+
+static struct _intel_i810_private {
+	struct pci_dev *i810_dev;	/* device one */
+	volatile u8 *registers;
+	int num_dcache_entries;
+} intel_i810_private;
+
+static int intel_i810_fetch_size(void)
+{
+	u32 smram_miscc;
+	struct aper_size_info_fixed *values;
+
+	pci_read_config_dword(agp_bridge.dev, I810_SMRAM_MISCC, &smram_miscc);
+	values = A_SIZE_FIX(agp_bridge.aperture_sizes);
+
+	if ((smram_miscc & I810_GMS) == I810_GMS_DISABLE) {
+		printk(KERN_WARNING PFX "i810 is disabled\n");
+		return 0;
+	}
+	if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) == I810_GFX_MEM_WIN_32M) {
+		agp_bridge.previous_size =
+		    agp_bridge.current_size = (void *) (values + 1);
+		agp_bridge.aperture_size_idx = 1;
+		return values[1].size;
+	} else {
+		agp_bridge.previous_size =
+		    agp_bridge.current_size = (void *) (values);
+		agp_bridge.aperture_size_idx = 0;
+		return values[0].size;
+	}
+
+	return 0;
+}
+
+static int intel_i810_configure(void)
+{
+	struct aper_size_info_fixed *current_size;
+	u32 temp;
+	int i;
+
+	current_size = A_SIZE_FIX(agp_bridge.current_size);
+
+	pci_read_config_dword(intel_i810_private.i810_dev, I810_MMADDR, &temp);
+	temp &= 0xfff80000;
+
+	intel_i810_private.registers =
+	    (volatile u8 *) ioremap(temp, 128 * 4096);
+
+	if ((INREG32(intel_i810_private.registers, I810_DRAM_CTL)
+	     & I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) {
+		/* This will need to be dynamically assigned */
+		printk(KERN_INFO PFX "detected 4MB dedicated video ram.\n");
+		intel_i810_private.num_dcache_entries = 1024;
+	}
+	pci_read_config_dword(intel_i810_private.i810_dev, I810_GMADDR, &temp);
+	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+	OUTREG32(intel_i810_private.registers, I810_PGETBL_CTL,
+		 agp_bridge.gatt_bus_addr | I810_PGETBL_ENABLED);
+	CACHE_FLUSH();
+
+	if (agp_bridge.needs_scratch_page == TRUE) {
+		for (i = 0; i < current_size->num_entries; i++) {
+			OUTREG32(intel_i810_private.registers,
+				 I810_PTE_BASE + (i * 4),
+				 agp_bridge.scratch_page);
+		}
+	}
+	return 0;
+}
+
+static void intel_i810_cleanup(void)
+{
+	OUTREG32(intel_i810_private.registers, I810_PGETBL_CTL, 0);
+	iounmap((void *) intel_i810_private.registers);
+}
+
+static void intel_i810_tlbflush(agp_memory * mem)
+{
+	return;
+}
+
+static void intel_i810_agp_enable(u32 mode)
+{
+	return;
+}
+
+static int intel_i810_insert_entries(agp_memory * mem, off_t pg_start,
+				     int type)
+{
+	int i, j, num_entries;
+	void *temp;
+
+	temp = agp_bridge.current_size;
+	num_entries = A_SIZE_FIX(temp)->num_entries;
+
+	if ((pg_start + mem->page_count) > num_entries) {
+		return -EINVAL;
+	}
+	for (j = pg_start; j < (pg_start + mem->page_count); j++) {
+		if (!PGE_EMPTY(agp_bridge.gatt_table[j])) {
+			return -EBUSY;
+		}
+	}
+
+	if (type != 0 || mem->type != 0) {
+		if ((type == AGP_DCACHE_MEMORY) &&
+		    (mem->type == AGP_DCACHE_MEMORY)) {
+			/* special insert */
+			CACHE_FLUSH();
+			for (i = pg_start;
+			     i < (pg_start + mem->page_count); i++) {
+				OUTREG32(intel_i810_private.registers,
+					 I810_PTE_BASE + (i * 4),
+					 (i * 4096) | I810_PTE_LOCAL |
+					 I810_PTE_VALID);
+			}
+			CACHE_FLUSH();
+			agp_bridge.tlb_flush(mem);
+			return 0;
+		}
+	        if((type == AGP_PHYS_MEMORY) &&
+		   (mem->type == AGP_PHYS_MEMORY)) {
+		   goto insert;
+		}
+		return -EINVAL;
+	}
+
+insert:
+   	CACHE_FLUSH();
+	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
+		OUTREG32(intel_i810_private.registers,
+			 I810_PTE_BASE + (j * 4), mem->memory[i]);
+	}
+	CACHE_FLUSH();
+
+	agp_bridge.tlb_flush(mem);
+	return 0;
+}
+
+static int intel_i810_remove_entries(agp_memory * mem, off_t pg_start,
+				     int type)
+{
+	int i;
+
+	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
+		OUTREG32(intel_i810_private.registers,
+			 I810_PTE_BASE + (i * 4),
+			 agp_bridge.scratch_page);
+	}
+
+	CACHE_FLUSH();
+	agp_bridge.tlb_flush(mem);
+	return 0;
+}
+
+static agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type)
+{
+	agp_memory *new;
+
+	if (type == AGP_DCACHE_MEMORY) {
+		if (pg_count != intel_i810_private.num_dcache_entries) {
+			return NULL;
+		}
+		new = agp_create_memory(1);
+
+		if (new == NULL) {
+			return NULL;
+		}
+		new->type = AGP_DCACHE_MEMORY;
+		new->page_count = pg_count;
+		new->num_scratch_pages = 0;
+		vfree(new->memory);
+	   	MOD_INC_USE_COUNT;
+		return new;
+	}
+	if(type == AGP_PHYS_MEMORY) {
+		void *addr;
+		/* The I810 requires a physical address to program
+		 * it's mouse pointer into hardware.  However the
+		 * Xserver still writes to it through the agp
+		 * aperture
+		 */
+	   	if (pg_count != 1) {
+		   	return NULL;
+		}
+	   	new = agp_create_memory(1);
+
+		if (new == NULL) {
+			return NULL;
+		}
+	   	MOD_INC_USE_COUNT;
+		addr = agp_bridge.agp_alloc_page();
+
+		if (addr == NULL) {
+			/* Free this structure */
+			agp_free_memory(new);
+			return NULL;
+		}
+		new->memory[0] = agp_bridge.mask_memory(virt_to_phys(addr), type);
+		new->page_count = 1;
+	   	new->num_scratch_pages = 1;
+	   	new->type = AGP_PHYS_MEMORY;
+	        new->physical = virt_to_phys((void *) new->memory[0]);
+	   	return new;
+	}
+   
+	return NULL;
+}
+
+static void intel_i810_free_by_type(agp_memory * curr)
+{
+	agp_free_key(curr->key);
+   	if(curr->type == AGP_PHYS_MEMORY) {
+	   	agp_bridge.agp_destroy_page(
+				 phys_to_virt(curr->memory[0]));
+		vfree(curr->memory);
+	}
+	kfree(curr);
+   	MOD_DEC_USE_COUNT;
+}
+
+static unsigned long intel_i810_mask_memory(unsigned long addr, int type)
+{
+	/* Type checking must be done elsewhere */
+	return addr | agp_bridge.masks[type].mask;
+}
+
+int __init intel_i810_setup(struct pci_dev *i810_dev)
+{
+	intel_i810_private.i810_dev = i810_dev;
+
+	agp_bridge.masks = intel_i810_masks;
+	agp_bridge.num_of_masks = 2;
+	agp_bridge.aperture_sizes = (void *) intel_i810_sizes;
+	agp_bridge.size_type = FIXED_APER_SIZE;
+	agp_bridge.num_aperture_sizes = 2;
+	agp_bridge.dev_private_data = (void *) &intel_i810_private;
+	agp_bridge.needs_scratch_page = TRUE;
+	agp_bridge.configure = intel_i810_configure;
+	agp_bridge.fetch_size = intel_i810_fetch_size;
+	agp_bridge.cleanup = intel_i810_cleanup;
+	agp_bridge.tlb_flush = intel_i810_tlbflush;
+	agp_bridge.mask_memory = intel_i810_mask_memory;
+	agp_bridge.agp_enable = intel_i810_agp_enable;
+	agp_bridge.cache_flush = global_cache_flush;
+	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge.insert_memory = intel_i810_insert_entries;
+	agp_bridge.remove_memory = intel_i810_remove_entries;
+	agp_bridge.alloc_by_type = intel_i810_alloc_by_type;
+	agp_bridge.free_by_type = intel_i810_free_by_type;
+	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.suspend = agp_generic_suspend;
+	agp_bridge.resume = agp_generic_resume;
+	agp_bridge.cant_use_aperture = 0;
+
+	return 0;
+}
+
+static struct aper_size_info_fixed intel_i830_sizes[] =
+{
+	{128, 32768, 5},
+	/* The 64M mode still requires a 128k gatt */
+	{64, 16384, 5}
+};
+
+static struct _intel_i830_private {
+	struct pci_dev *i830_dev;   /* device one */
+	volatile u8 *registers;
+	int gtt_entries;
+} intel_i830_private;
+
+static void intel_i830_init_gtt_entries(void)
+{
+	u16 gmch_ctrl;
+	int gtt_entries;
+	u8 rdct;
+	static const int ddt[4] = { 0, 16, 32, 64 };
+
+	pci_read_config_word(agp_bridge.dev,I830_GMCH_CTRL,&gmch_ctrl);
+
+	switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
+	case I830_GMCH_GMS_STOLEN_512:
+		gtt_entries = KB(512) - KB(132);
+		printk(KERN_INFO PFX "detected %dK stolen memory.\n",gtt_entries / KB(1));
+		break;
+	case I830_GMCH_GMS_STOLEN_1024:
+		gtt_entries = MB(1) - KB(132);
+		printk(KERN_INFO PFX "detected %dK stolen memory.\n",gtt_entries / KB(1));
+		break;
+	case I830_GMCH_GMS_STOLEN_8192:
+		gtt_entries = MB(8) - KB(132);
+		printk(KERN_INFO PFX "detected %dK stolen memory.\n",gtt_entries / KB(1));
+		break;
+	case I830_GMCH_GMS_LOCAL:
+		rdct = INREG8(intel_i830_private.registers,I830_RDRAM_CHANNEL_TYPE);
+		gtt_entries = (I830_RDRAM_ND(rdct) + 1) * MB(ddt[I830_RDRAM_DDT(rdct)]);
+		printk(KERN_INFO PFX "detected %dK local memory.\n",gtt_entries / KB(1));
+		break;
+	default:
+		printk(KERN_INFO PFX "no video memory detected.\n");
+		gtt_entries = 0;
+		break;
+	}
+
+	gtt_entries /= KB(4);
+
+	intel_i830_private.gtt_entries = gtt_entries;
+}
+
+/* The intel i830 automatically initializes the agp aperture during POST.
+ * Use the memory already set aside for in the GTT.
+ */
+static int intel_i830_create_gatt_table(void)
+{
+	int page_order;
+	struct aper_size_info_fixed *size;
+	int num_entries;
+	u32 temp;
+
+	size = agp_bridge.current_size;
+	page_order = size->page_order;
+	num_entries = size->num_entries;
+	agp_bridge.gatt_table_real = 0;
+
+	pci_read_config_dword(intel_i830_private.i830_dev,I810_MMADDR,&temp);
+	temp &= 0xfff80000;
+
+	intel_i830_private.registers = (volatile u8 *) ioremap(temp,128 * 4096);
+	if (!intel_i830_private.registers) return (-ENOMEM);
+
+	temp = INREG32(intel_i830_private.registers,I810_PGETBL_CTL) & 0xfffff000;
+	CACHE_FLUSH();
+
+	/* we have to call this as early as possible after the MMIO base address is known */
+	intel_i830_init_gtt_entries();
+
+	agp_bridge.gatt_table = NULL;
+
+	agp_bridge.gatt_bus_addr = temp;
+
+	return(0);
+}
+
+/* Return the gatt table to a sane state. Use the top of stolen
+ * memory for the GTT.
+ */
+static int intel_i830_free_gatt_table(void)
+{
+	return(0);
+}
+
+static int intel_i830_fetch_size(void)
+{
+	u16 gmch_ctrl;
+	struct aper_size_info_fixed *values;
+
+	pci_read_config_word(agp_bridge.dev,I830_GMCH_CTRL,&gmch_ctrl);
+	values = A_SIZE_FIX(agp_bridge.aperture_sizes);
+
+	if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
+		agp_bridge.previous_size = agp_bridge.current_size = (void *) values;
+		agp_bridge.aperture_size_idx = 0;
+		return(values[0].size);
+	} else {
+		agp_bridge.previous_size = agp_bridge.current_size = (void *) values;
+		agp_bridge.aperture_size_idx = 1;
+		return(values[1].size);
+	}
+
+	return(0);
+}
+
+static int intel_i830_configure(void)
+{
+	struct aper_size_info_fixed *current_size;
+	u32 temp;
+	u16 gmch_ctrl;
+	int i;
+
+	current_size = A_SIZE_FIX(agp_bridge.current_size);
+
+	pci_read_config_dword(intel_i830_private.i830_dev,I810_GMADDR,&temp);
+	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+
+	pci_read_config_word(agp_bridge.dev,I830_GMCH_CTRL,&gmch_ctrl);
+	gmch_ctrl |= I830_GMCH_ENABLED;
+	pci_write_config_word(agp_bridge.dev,I830_GMCH_CTRL,gmch_ctrl);
+
+	OUTREG32(intel_i830_private.registers,I810_PGETBL_CTL,agp_bridge.gatt_bus_addr | I810_PGETBL_ENABLED);
+	CACHE_FLUSH();
+
+	if (agp_bridge.needs_scratch_page == TRUE)
+		for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++)
+			OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge.scratch_page);
+
+	return (0);
+}
+
+static void intel_i830_cleanup(void)
+{
+	iounmap((void *) intel_i830_private.registers);
+}
+
+static int intel_i830_insert_entries(agp_memory *mem,off_t pg_start,int type)
+{
+	int i,j,num_entries;
+	void *temp;
+
+	temp = agp_bridge.current_size;
+	num_entries = A_SIZE_FIX(temp)->num_entries;
+
+	if (pg_start < intel_i830_private.gtt_entries) {
+		printk (KERN_DEBUG "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
+				pg_start,intel_i830_private.gtt_entries);
+
+		printk ("Trying to insert into local/stolen memory\n");
+		return (-EINVAL);
+	}
+
+	if ((pg_start + mem->page_count) > num_entries)
+		return (-EINVAL);
+
+	/* The i830 can't check the GTT for entries since its read only,
+	 * depend on the caller to make the correct offset decisions.
+	 */
+
+	if ((type != 0 && type != AGP_PHYS_MEMORY) ||
+		(mem->type != 0 && mem->type != AGP_PHYS_MEMORY))
+		return (-EINVAL);
+
+	CACHE_FLUSH();
+
+	for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
+		OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (j * 4),mem->memory[i]);
+
+	CACHE_FLUSH();
+
+	agp_bridge.tlb_flush(mem);
+
+	return(0);
+}
+
+static int intel_i830_remove_entries(agp_memory *mem,off_t pg_start,int type)
+{
+	int i;
+
+	CACHE_FLUSH ();
+
+	if (pg_start < intel_i830_private.gtt_entries) {
+		printk ("Trying to disable local/stolen memory\n");
+		return (-EINVAL);
+	}
+
+	for (i = pg_start; i < (mem->page_count + pg_start); i++)
+		OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge.scratch_page);
+
+	CACHE_FLUSH();
+
+	agp_bridge.tlb_flush(mem);
+
+	return (0);
+}
+
+static agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type)
+{
+	agp_memory *nw;
+
+	/* always return NULL for now */
+	if (type == AGP_DCACHE_MEMORY) return(NULL);
+
+	if (type == AGP_PHYS_MEMORY) {
+		void *addr;
+
+		/* The i830 requires a physical address to program
+		 * it's mouse pointer into hardware. However the
+		 * Xserver still writes to it through the agp
+		 * aperture
+		 */
+
+		if (pg_count != 1) return(NULL);
+
+		nw = agp_create_memory(1);
+
+		if (nw == NULL) return(NULL);
+
+		MOD_INC_USE_COUNT;
+		addr = agp_bridge.agp_alloc_page();
+		if (addr == NULL) {
+			/* free this structure */
+			agp_free_memory(nw);
+			return(NULL);
+		}
+
+		nw->memory[0] = agp_bridge.mask_memory(virt_to_phys(addr),type);
+		nw->page_count = 1;
+		nw->num_scratch_pages = 1;
+		nw->type = AGP_PHYS_MEMORY;
+		nw->physical = virt_to_phys(addr);
+		return(nw);
+	}
+
+	return(NULL);
+}
+
+int __init intel_i830_setup(struct pci_dev *i830_dev)
+{
+	intel_i830_private.i830_dev = i830_dev;
+
+	agp_bridge.masks = intel_i810_masks;
+	agp_bridge.num_of_masks = 3;
+	agp_bridge.aperture_sizes = (void *) intel_i830_sizes;
+	agp_bridge.size_type = FIXED_APER_SIZE;
+	agp_bridge.num_aperture_sizes = 2;
+
+	agp_bridge.dev_private_data = (void *) &intel_i830_private;
+	agp_bridge.needs_scratch_page = TRUE;
+
+	agp_bridge.configure = intel_i830_configure;
+	agp_bridge.fetch_size = intel_i830_fetch_size;
+	agp_bridge.cleanup = intel_i830_cleanup;
+	agp_bridge.tlb_flush = intel_i810_tlbflush;
+	agp_bridge.mask_memory = intel_i810_mask_memory;
+	agp_bridge.agp_enable = intel_i810_agp_enable;
+	agp_bridge.cache_flush = global_cache_flush;
+
+	agp_bridge.create_gatt_table = intel_i830_create_gatt_table;
+	agp_bridge.free_gatt_table = intel_i830_free_gatt_table;
+
+	agp_bridge.insert_memory = intel_i830_insert_entries;
+	agp_bridge.remove_memory = intel_i830_remove_entries;
+	agp_bridge.alloc_by_type = intel_i830_alloc_by_type;
+	agp_bridge.free_by_type = intel_i810_free_by_type;
+	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+
+	agp_bridge.suspend = agp_generic_suspend;
+	agp_bridge.resume = agp_generic_resume;
+	agp_bridge.cant_use_aperture = 0;
+
+	return(0);
+}
+static int intel_fetch_size(void)
+{
+	int i;
+	u16 temp;
+	struct aper_size_info_16 *values;
+
+	pci_read_config_word(agp_bridge.dev, INTEL_APSIZE, &temp);
+	values = A_SIZE_16(agp_bridge.aperture_sizes);
+
+	for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+		if (temp == values[i].size_value) {
+			agp_bridge.previous_size =
+			    agp_bridge.current_size = (void *) (values + i);
+			agp_bridge.aperture_size_idx = i;
+			return values[i].size;
+		}
+	}
+
+	return 0;
+}
+
+static int intel_8xx_fetch_size(void)
+{
+	int i;
+	u8 temp;
+	struct aper_size_info_8 *values;
+
+	pci_read_config_byte(agp_bridge.dev, INTEL_APSIZE, &temp);
+
+	/* Intel 815 chipsets have a _weird_ APSIZE register with only
+	 * one non-reserved bit, so mask the others out ... */
+	if (agp_bridge.type == INTEL_I815)
+		temp &= (1 << 3);
+
+	values = A_SIZE_8(agp_bridge.aperture_sizes);
+
+	for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+		if (temp == values[i].size_value) {
+			agp_bridge.previous_size =
+				agp_bridge.current_size = (void *) (values + i);
+			agp_bridge.aperture_size_idx = i;
+			return values[i].size;
+		}
+	}
+	return 0;
+}
+
+
+static void intel_tlbflush(agp_memory * mem)
+{
+	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2200);
+	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2280);
+}
+
+
+static void intel_8xx_tlbflush(agp_memory * mem)
+{
+  u32 temp;
+  pci_read_config_dword(agp_bridge.dev, INTEL_AGPCTRL, &temp);
+  pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, temp & ~(1 << 7));
+  pci_read_config_dword(agp_bridge.dev, INTEL_AGPCTRL, &temp);
+  pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, temp | (1 << 7));
+}
+
+
+static void intel_cleanup(void)
+{
+	u16 temp;
+	struct aper_size_info_16 *previous_size;
+
+	previous_size = A_SIZE_16(agp_bridge.previous_size);
+	pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp);
+	pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, temp & ~(1 << 9));
+	pci_write_config_word(agp_bridge.dev, INTEL_APSIZE, previous_size->size_value);
+}
+
+
+static void intel_8xx_cleanup(void)
+{
+	u16 temp;
+	struct aper_size_info_8 *previous_size;
+
+	previous_size = A_SIZE_8(agp_bridge.previous_size);
+	pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp);
+	pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, temp & ~(1 << 9));
+	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, previous_size->size_value);
+}
+
+
+static int intel_configure(void)
+{
+	u32 temp;
+	u16 temp2;
+	struct aper_size_info_16 *current_size;
+
+	current_size = A_SIZE_16(agp_bridge.current_size);
+
+	/* aperture size */
+	pci_write_config_word(agp_bridge.dev, INTEL_APSIZE, current_size->size_value);
+
+	/* address to map to */
+	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
+	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+
+	/* attbase - aperture base */
+	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr);
+
+	/* agpctrl */
+	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2280);
+
+	/* paccfg/nbxcfg */
+	pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp2);
+	pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG,
+			      (temp2 & ~(1 << 10)) | (1 << 9));
+	/* clear any possible error conditions */
+	pci_write_config_byte(agp_bridge.dev, INTEL_ERRSTS + 1, 7);
+	return 0;
+}
+
+static int intel_815_configure(void)
+{
+	u32 temp, addr;
+	u8 temp2;
+	struct aper_size_info_8 *current_size;
+
+	current_size = A_SIZE_8(agp_bridge.current_size);
+
+	/* aperture size */
+	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
+			current_size->size_value); 
+
+	/* address to map to */
+	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
+	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+
+	/* attbase - aperture base */
+	/* the Intel 815 chipset spec. says that bits 29-31 in the
+	* ATTBASE register are reserved -> try not to write them */
+	if (agp_bridge.gatt_bus_addr &  INTEL_815_ATTBASE_MASK)
+		panic("gatt bus addr too high");
+	pci_read_config_dword(agp_bridge.dev, INTEL_ATTBASE, &addr);
+	addr &= INTEL_815_ATTBASE_MASK;
+	addr |= agp_bridge.gatt_bus_addr;
+	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, addr);
+
+	/* agpctrl */
+	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); 
+
+	/* apcont */
+	pci_read_config_byte(agp_bridge.dev, INTEL_815_APCONT, &temp2);
+	pci_write_config_byte(agp_bridge.dev, INTEL_815_APCONT, temp2 | (1 << 1));
+
+	/* clear any possible error conditions */
+	/* Oddness : this chipset seems to have no ERRSTS register ! */
+	return 0;
+}
+
+static void intel_820_tlbflush(agp_memory * mem)
+{
+  return;
+}
+
+static void intel_820_cleanup(void)
+{
+	u8 temp;
+	struct aper_size_info_8 *previous_size;
+
+	previous_size = A_SIZE_8(agp_bridge.previous_size);
+	pci_read_config_byte(agp_bridge.dev, INTEL_I820_RDCR, &temp);
+	pci_write_config_byte(agp_bridge.dev, INTEL_I820_RDCR, 
+			      temp & ~(1 << 1));
+	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
+			      previous_size->size_value);
+}
+
+
+static int intel_820_configure(void)
+{
+	u32 temp;
+ 	u8 temp2; 
+	struct aper_size_info_8 *current_size;
+
+	current_size = A_SIZE_8(agp_bridge.current_size);
+
+	/* aperture size */
+	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, current_size->size_value); 
+
+	/* address to map to */
+	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
+	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+
+	/* attbase - aperture base */
+	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr); 
+
+	/* agpctrl */
+	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); 
+
+	/* global enable aperture access */
+	/* This flag is not accessed through MCHCFG register as in */
+	/* i850 chipset. */
+	pci_read_config_byte(agp_bridge.dev, INTEL_I820_RDCR, &temp2);
+	pci_write_config_byte(agp_bridge.dev, INTEL_I820_RDCR, temp2 | (1 << 1));
+	/* clear any possible AGP-related error conditions */
+	pci_write_config_word(agp_bridge.dev, INTEL_I820_ERRSTS, 0x001c); 
+	return 0;
+}
+
+static int intel_840_configure(void)
+{
+	u32 temp;
+	u16 temp2;
+	struct aper_size_info_8 *current_size;
+
+	current_size = A_SIZE_8(agp_bridge.current_size);
+
+	/* aperture size */
+	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, current_size->size_value); 
+
+	/* address to map to */
+	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
+	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+
+	/* attbase - aperture base */
+	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr); 
+
+	/* agpctrl */
+	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); 
+
+	/* mcgcfg */
+	pci_read_config_word(agp_bridge.dev, INTEL_I840_MCHCFG, &temp2);
+	pci_write_config_word(agp_bridge.dev, INTEL_I840_MCHCFG, temp2 | (1 << 9));
+	/* clear any possible error conditions */
+	pci_write_config_word(agp_bridge.dev, INTEL_I840_ERRSTS, 0xc000); 
+	return 0;
+}
+
+static int intel_845_configure(void)
+{
+	u32 temp;
+	u8 temp2;
+	struct aper_size_info_8 *current_size;
+
+	current_size = A_SIZE_8(agp_bridge.current_size);
+
+	/* aperture size */
+	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, current_size->size_value); 
+
+	/* address to map to */
+	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
+	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+
+	/* attbase - aperture base */
+	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr); 
+
+	/* agpctrl */
+	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); 
+
+	/* agpm */
+	pci_read_config_byte(agp_bridge.dev, INTEL_I845_AGPM, &temp2);
+	pci_write_config_byte(agp_bridge.dev, INTEL_I845_AGPM, temp2 | (1 << 1));
+	/* clear any possible error conditions */
+	pci_write_config_word(agp_bridge.dev, INTEL_I845_ERRSTS, 0x001c); 
+	return 0;
+}
+
+static void intel_845_resume(void)
+{
+	intel_845_configure();
+}
+
+static int intel_850_configure(void)
+{
+	u32 temp;
+	u16 temp2;
+	struct aper_size_info_8 *current_size;
+
+	current_size = A_SIZE_8(agp_bridge.current_size);
+
+	/* aperture size */
+	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, current_size->size_value); 
+
+	/* address to map to */
+	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
+	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+
+	/* attbase - aperture base */
+	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr); 
+
+	/* agpctrl */
+	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); 
+
+	/* mcgcfg */
+	pci_read_config_word(agp_bridge.dev, INTEL_I850_MCHCFG, &temp2);
+	pci_write_config_word(agp_bridge.dev, INTEL_I850_MCHCFG, temp2 | (1 << 9));
+	/* clear any possible AGP-related error conditions */
+	pci_write_config_word(agp_bridge.dev, INTEL_I850_ERRSTS, 0x001c); 
+	return 0;
+}
+
+static int intel_860_configure(void)
+{
+	u32 temp;
+	u16 temp2;
+	struct aper_size_info_8 *current_size;
+
+	current_size = A_SIZE_8(agp_bridge.current_size);
+
+	/* aperture size */
+	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, current_size->size_value);
+
+	/* address to map to */
+	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
+	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+
+	/* attbase - aperture base */
+	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr);
+
+	/* agpctrl */
+	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000);
+
+	/* mcgcfg */
+	pci_read_config_word(agp_bridge.dev, INTEL_I860_MCHCFG, &temp2);
+	pci_write_config_word(agp_bridge.dev, INTEL_I860_MCHCFG, temp2 | (1 << 9));
+	/* clear any possible AGP-related error conditions */
+	pci_write_config_word(agp_bridge.dev, INTEL_I860_ERRSTS, 0xf700);
+	return 0;
+}
+
+static int intel_830mp_configure(void)
+{
+	u32 temp;
+	u16 temp2;
+	struct aper_size_info_8 *current_size;
+
+	current_size = A_SIZE_8(agp_bridge.current_size);
+
+	/* aperture size */
+	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, current_size->size_value);
+
+	/* address to map to */
+	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
+	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+
+	/* attbase - aperture base */
+	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr);
+
+	/* agpctrl */
+	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000);
+
+	/* gmch */
+	pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp2);
+	pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, temp2 | (1 << 9));
+	/* clear any possible AGP-related error conditions */
+	pci_write_config_word(agp_bridge.dev, INTEL_I830_ERRSTS, 0x1c);
+	return 0;
+}
+
+static unsigned long intel_mask_memory(unsigned long addr, int type)
+{
+	/* Memory type is ignored */
+	return addr | agp_bridge.masks[0].mask;
+}
+
+static void intel_resume(void)
+{
+	intel_configure();
+}
+
+/* Setup function */
+static struct gatt_mask intel_generic_masks[] =
+{
+	{.mask = 0x00000017, .type = 0}
+};
+
+static struct aper_size_info_8 intel_815_sizes[2] =
+{
+	{64, 16384, 4, 0},
+	{32, 8192, 3, 8},
+};
+	
+static struct aper_size_info_8 intel_8xx_sizes[7] =
+{
+	{256, 65536, 6, 0},
+	{128, 32768, 5, 32},
+	{64, 16384, 4, 48},
+	{32, 8192, 3, 56},
+	{16, 4096, 2, 60},
+	{8, 2048, 1, 62},
+	{4, 1024, 0, 63}
+};
+
+static struct aper_size_info_16 intel_generic_sizes[7] =
+{
+	{256, 65536, 6, 0},
+	{128, 32768, 5, 32},
+	{64, 16384, 4, 48},
+	{32, 8192, 3, 56},
+	{16, 4096, 2, 60},
+	{8, 2048, 1, 62},
+	{4, 1024, 0, 63}
+};
+
+static struct aper_size_info_8 intel_830mp_sizes[4] = 
+{
+  {256, 65536, 6, 0},
+  {128, 32768, 5, 32},
+  {64, 16384, 4, 48},
+  {32, 8192, 3, 56}
+};
+
+static int __init intel_generic_setup (struct pci_dev *pdev)
+{
+	agp_bridge.masks = intel_generic_masks;
+	agp_bridge.num_of_masks = 1;
+	agp_bridge.aperture_sizes = (void *) intel_generic_sizes;
+	agp_bridge.size_type = U16_APER_SIZE;
+	agp_bridge.num_aperture_sizes = 7;
+	agp_bridge.dev_private_data = NULL;
+	agp_bridge.needs_scratch_page = FALSE;
+	agp_bridge.configure = intel_configure;
+	agp_bridge.fetch_size = intel_fetch_size;
+	agp_bridge.cleanup = intel_cleanup;
+	agp_bridge.tlb_flush = intel_tlbflush;
+	agp_bridge.mask_memory = intel_mask_memory;
+	agp_bridge.agp_enable = agp_generic_agp_enable;
+	agp_bridge.cache_flush = global_cache_flush;
+	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge.insert_memory = agp_generic_insert_memory;
+	agp_bridge.remove_memory = agp_generic_remove_memory;
+	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge.free_by_type = agp_generic_free_by_type;
+	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.suspend = agp_generic_suspend;
+	agp_bridge.resume = intel_resume;
+	agp_bridge.cant_use_aperture = 0;
+	return 0;
+}
+
+static int __init intel_815_setup (struct pci_dev *pdev)
+{
+	agp_bridge.masks = intel_generic_masks;
+	agp_bridge.num_of_masks = 1;
+	agp_bridge.aperture_sizes = (void *) intel_815_sizes;
+	agp_bridge.size_type = U8_APER_SIZE;
+	agp_bridge.num_aperture_sizes = 2;
+	agp_bridge.dev_private_data = NULL;
+	agp_bridge.needs_scratch_page = FALSE;
+	agp_bridge.configure = intel_815_configure;
+	agp_bridge.fetch_size = intel_8xx_fetch_size;
+	agp_bridge.cleanup = intel_8xx_cleanup;
+	agp_bridge.tlb_flush = intel_8xx_tlbflush;
+	agp_bridge.mask_memory = intel_mask_memory;
+	agp_bridge.agp_enable = agp_generic_agp_enable;
+	agp_bridge.cache_flush = global_cache_flush;
+	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge.insert_memory = agp_generic_insert_memory;
+	agp_bridge.remove_memory = agp_generic_remove_memory;
+	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge.free_by_type = agp_generic_free_by_type;
+	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.suspend = agp_generic_suspend;
+	agp_bridge.resume = agp_generic_resume;
+	agp_bridge.cant_use_aperture = 0;
+	return 0;
+}
+
+
+static int __init intel_820_setup (struct pci_dev *pdev)
+{
+	agp_bridge.masks = intel_generic_masks;
+	agp_bridge.num_of_masks = 1;
+	agp_bridge.aperture_sizes = (void *) intel_8xx_sizes;
+	agp_bridge.size_type = U8_APER_SIZE;
+	agp_bridge.num_aperture_sizes = 7;
+	agp_bridge.dev_private_data = NULL;
+	agp_bridge.needs_scratch_page = FALSE;
+	agp_bridge.configure = intel_820_configure;
+	agp_bridge.fetch_size = intel_8xx_fetch_size;
+	agp_bridge.cleanup = intel_820_cleanup;
+	agp_bridge.tlb_flush = intel_820_tlbflush;
+	agp_bridge.mask_memory = intel_mask_memory;
+	agp_bridge.agp_enable = agp_generic_agp_enable;
+	agp_bridge.cache_flush = global_cache_flush;
+	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge.insert_memory = agp_generic_insert_memory;
+	agp_bridge.remove_memory = agp_generic_remove_memory;
+	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge.free_by_type = agp_generic_free_by_type;
+	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.suspend = agp_generic_suspend;
+	agp_bridge.resume = agp_generic_resume;
+	agp_bridge.cant_use_aperture = 0;
+	return 0;
+}
+
+static int __init intel_830mp_setup (struct pci_dev *pdev)
+{
+	agp_bridge.masks = intel_generic_masks;
+	agp_bridge.num_of_masks = 1;
+	agp_bridge.aperture_sizes = (void *) intel_830mp_sizes;
+	agp_bridge.size_type = U8_APER_SIZE;
+	agp_bridge.num_aperture_sizes = 4;
+	agp_bridge.dev_private_data = NULL;
+	agp_bridge.needs_scratch_page = FALSE;
+	agp_bridge.configure = intel_830mp_configure;
+	agp_bridge.fetch_size = intel_8xx_fetch_size;
+	agp_bridge.cleanup = intel_8xx_cleanup;
+	agp_bridge.tlb_flush = intel_8xx_tlbflush;
+	agp_bridge.mask_memory = intel_mask_memory;
+	agp_bridge.agp_enable = agp_generic_agp_enable;
+	agp_bridge.cache_flush = global_cache_flush;
+	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge.insert_memory = agp_generic_insert_memory;
+	agp_bridge.remove_memory = agp_generic_remove_memory;
+	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge.free_by_type = agp_generic_free_by_type;
+	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.suspend = agp_generic_suspend;
+	agp_bridge.resume = agp_generic_resume;
+	agp_bridge.cant_use_aperture = 0;
+	return 0;
+}
+
+static int __init intel_840_setup (struct pci_dev *pdev)
+{
+	agp_bridge.masks = intel_generic_masks;
+	agp_bridge.num_of_masks = 1;
+	agp_bridge.aperture_sizes = (void *) intel_8xx_sizes;
+	agp_bridge.size_type = U8_APER_SIZE;
+	agp_bridge.num_aperture_sizes = 7;
+	agp_bridge.dev_private_data = NULL;
+	agp_bridge.needs_scratch_page = FALSE;
+	agp_bridge.configure = intel_840_configure;
+	agp_bridge.fetch_size = intel_8xx_fetch_size;
+	agp_bridge.cleanup = intel_8xx_cleanup;
+	agp_bridge.tlb_flush = intel_8xx_tlbflush;
+	agp_bridge.mask_memory = intel_mask_memory;
+	agp_bridge.agp_enable = agp_generic_agp_enable;
+	agp_bridge.cache_flush = global_cache_flush;
+	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge.insert_memory = agp_generic_insert_memory;
+	agp_bridge.remove_memory = agp_generic_remove_memory;
+	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge.free_by_type = agp_generic_free_by_type;
+	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.suspend = agp_generic_suspend;
+	agp_bridge.resume = agp_generic_resume;
+	agp_bridge.cant_use_aperture = 0;
+	return 0;
+}
+
+static int __init intel_845_setup (struct pci_dev *pdev)
+{
+	agp_bridge.masks = intel_generic_masks;
+	agp_bridge.num_of_masks = 1;
+	agp_bridge.aperture_sizes = (void *) intel_8xx_sizes;
+	agp_bridge.size_type = U8_APER_SIZE;
+	agp_bridge.num_aperture_sizes = 7;
+	agp_bridge.dev_private_data = NULL;
+	agp_bridge.needs_scratch_page = FALSE;
+	agp_bridge.configure = intel_845_configure;
+	agp_bridge.fetch_size = intel_8xx_fetch_size;
+	agp_bridge.cleanup = intel_8xx_cleanup;
+	agp_bridge.tlb_flush = intel_8xx_tlbflush;
+	agp_bridge.mask_memory = intel_mask_memory;
+	agp_bridge.agp_enable = agp_generic_agp_enable;
+	agp_bridge.cache_flush = global_cache_flush;
+	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge.insert_memory = agp_generic_insert_memory;
+	agp_bridge.remove_memory = agp_generic_remove_memory;
+	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge.free_by_type = agp_generic_free_by_type;
+	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.suspend = agp_generic_suspend;
+	agp_bridge.resume = intel_845_resume;
+	agp_bridge.cant_use_aperture = 0;
+	return 0;
+}
+
+static int __init intel_850_setup (struct pci_dev *pdev)
+{
+	agp_bridge.masks = intel_generic_masks;
+	agp_bridge.num_of_masks = 1;
+	agp_bridge.aperture_sizes = (void *) intel_8xx_sizes;
+	agp_bridge.size_type = U8_APER_SIZE;
+	agp_bridge.num_aperture_sizes = 7;
+	agp_bridge.dev_private_data = NULL;
+	agp_bridge.needs_scratch_page = FALSE;
+	agp_bridge.configure = intel_850_configure;
+	agp_bridge.fetch_size = intel_8xx_fetch_size;
+	agp_bridge.cleanup = intel_8xx_cleanup;
+	agp_bridge.tlb_flush = intel_8xx_tlbflush;
+	agp_bridge.mask_memory = intel_mask_memory;
+	agp_bridge.agp_enable = agp_generic_agp_enable;
+	agp_bridge.cache_flush = global_cache_flush;
+	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge.insert_memory = agp_generic_insert_memory;
+	agp_bridge.remove_memory = agp_generic_remove_memory;
+	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge.free_by_type = agp_generic_free_by_type;
+	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.suspend = agp_generic_suspend;
+	agp_bridge.resume = agp_generic_resume;
+	agp_bridge.cant_use_aperture = 0;
+	return 0;
+}
+
+static int __init intel_860_setup (struct pci_dev *pdev)
+{
+	agp_bridge.masks = intel_generic_masks;
+	agp_bridge.num_of_masks = 1;
+	agp_bridge.aperture_sizes = (void *) intel_8xx_sizes;
+	agp_bridge.size_type = U8_APER_SIZE;
+	agp_bridge.num_aperture_sizes = 7;
+	agp_bridge.dev_private_data = NULL;
+	agp_bridge.needs_scratch_page = FALSE;
+	agp_bridge.configure = intel_860_configure;
+	agp_bridge.fetch_size = intel_8xx_fetch_size;
+	agp_bridge.cleanup = intel_8xx_cleanup;
+	agp_bridge.tlb_flush = intel_8xx_tlbflush;
+	agp_bridge.mask_memory = intel_mask_memory;
+	agp_bridge.agp_enable = agp_generic_agp_enable;
+	agp_bridge.cache_flush = global_cache_flush;
+	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge.insert_memory = agp_generic_insert_memory;
+	agp_bridge.remove_memory = agp_generic_remove_memory;
+	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge.free_by_type = agp_generic_free_by_type;
+	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.suspend = agp_generic_suspend;
+	agp_bridge.resume = agp_generic_resume;
+	agp_bridge.cant_use_aperture = 0;
+	return 0;
+}
+
+struct agp_device_ids intel_agp_device_ids[] __initdata =
+{
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_82443LX_0,
+		.chipset	= INTEL_LX,
+		.chipset_name	= "440LX",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_82443BX_0,
+		.chipset	= INTEL_BX,
+		.chipset_name	= "440BX",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_82443GX_0,
+		.chipset	= INTEL_GX,
+		.chipset_name	= "440GX",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_82815_MC,
+		.chipset	= INTEL_I815,
+		.chipset_name	= "i815",
+		.chipset_setup	= intel_815_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_82820_HB,
+		.chipset	= INTEL_I820,
+		.chipset_name	= "i820",
+		.chipset_setup	= intel_820_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_82820_UP_HB,
+		.chipset	= INTEL_I820,
+		.chipset_name	= "i820",
+		.chipset_setup	= intel_820_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_82830_HB,
+		.chipset	= INTEL_I830_M,
+		.chipset_name	= "i830M",
+		.chipset_setup	= intel_830mp_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_82845G_HB,
+		.chipset	= INTEL_I845_G,
+		.chipset_name	= "i845G",
+		.chipset_setup	= intel_830mp_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_82840_HB,
+		.chipset	= INTEL_I840,
+		.chipset_name	= "i840",
+		.chipset_setup	= intel_840_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_82845_HB,
+		.chipset	= INTEL_I845,
+		.chipset_name	= "i845",
+		.chipset_setup	= intel_845_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_82850_HB,
+		.chipset	= INTEL_I850,
+		.chipset_name	= "i850",
+		.chipset_setup	= intel_850_setup
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_INTEL_82860_HB,
+		.chipset	= INTEL_I860,
+		.chipset_name	= "i860",
+		.chipset_setup	= intel_860_setup
+	},
+	{ }, /* dummy final entry, always present */
+};
+
+
+/* scan table above for supported devices */
+static int __init agp_lookup_host_bridge (struct pci_dev *pdev)
+{
+	int j=0;
+	struct agp_device_ids *devs;
+	
+	devs = intel_agp_device_ids;
+
+	while (devs[j].chipset_name != NULL) {
+		if (pdev->device == devs[j].device_id) {
+			printk (KERN_INFO PFX "Detected Intel %s chipset\n",
+				devs[j].chipset_name);
+			agp_bridge.type = devs[j].chipset;
+
+			if (devs[j].chipset_setup != NULL)
+				return devs[j].chipset_setup(pdev);
+			else
+				return intel_generic_setup(pdev);
+		}
+		j++;
+	}
+	j--;
+
+	/* try init anyway, if user requests it */
+	if (agp_try_unsupported) {
+		printk(KERN_WARNING PFX "Trying generic Intel routines"
+		       " for device id: %04x\n", pdev->device);
+		agp_bridge.type = INTEL_GENERIC;
+		return intel_generic_setup(pdev);
+	}
+
+	printk(KERN_ERR PFX "Unsupported Intel chipset (device id: %04x),"
+		" you might want to try agp_try_unsupported=1.\n", pdev->device);
+	return -ENODEV;
+}
+
+
+/* Supported Device Scanning routine */
+
+static int __init agp_find_supported_device(struct pci_dev *dev)
+{
+	struct pci_dev *i810_dev;
+
+	agp_bridge.dev = dev;
+
+	/* This shit needs moving into tables/init-routines. */
+	switch (dev->device) {
+	case PCI_DEVICE_ID_INTEL_82810_MC1:
+		i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG1, NULL);
+		if (i810_dev == NULL) {
+			printk(KERN_ERR PFX "Detected an Intel i810,"
+			       " but could not find the secondary device.\n");
+			return -ENODEV;
+		}
+		printk(KERN_INFO PFX "Detected an Intel i810 Chipset.\n");
+		agp_bridge.type = INTEL_I810;
+		return intel_i810_setup (i810_dev);
+
+	case PCI_DEVICE_ID_INTEL_82810_MC3:
+		i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3, NULL);
+		if (i810_dev == NULL) {
+			printk(KERN_ERR PFX "Detected an Intel i810 DC100, but could not find the "
+			       "secondary device.\n");
+			return -ENODEV;
+		}
+		printk(KERN_INFO PFX "Detected an Intel i810 DC100 Chipset.\n");
+		agp_bridge.type = INTEL_I810;
+		return intel_i810_setup(i810_dev);
+
+	case PCI_DEVICE_ID_INTEL_82810E_MC:
+		i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG, NULL);
+		if (i810_dev == NULL) {
+			printk(KERN_ERR PFX "Detected an Intel i810 E"
+			    ", but could not find the secondary device.\n");
+			return -ENODEV;
+		}
+		printk(KERN_INFO PFX "Detected an Intel i810 E Chipset.\n");
+		agp_bridge.type = INTEL_I810;
+		return intel_i810_setup(i810_dev);
+
+	 case PCI_DEVICE_ID_INTEL_82815_MC:
+	   /* The i815 can operate either as an i810 style
+	    * integrated device, or as an AGP4X motherboard.
+	    *
+	    * This only addresses the first mode:
+	    */
+		i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC, NULL);
+		if (i810_dev == NULL) {
+			printk(KERN_ERR PFX "agpgart: Detected an "
+				"Intel i815, but could not find the"
+				" secondary device. Assuming a "
+				"non-integrated video card.\n");
+			break;
+		}
+		printk(KERN_INFO PFX "agpgart: Detected an Intel i815 Chipset.\n");
+		agp_bridge.type = INTEL_I810;
+		return intel_i810_setup(i810_dev);
+
+	case PCI_DEVICE_ID_INTEL_82845G_HB:
+		i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
+				PCI_DEVICE_ID_INTEL_82845G_IG, NULL);
+		if (i810_dev && PCI_FUNC(i810_dev->devfn) != 0) {
+			i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
+				PCI_DEVICE_ID_INTEL_82845G_IG, i810_dev);
+		}
+
+		if (i810_dev == NULL) {
+			/* 
+			 * We probably have a I845MP chipset with an external graphics
+			 * card. It will be initialized later 
+			 */
+			agp_bridge.type = INTEL_I845_G;
+			break;
+		}
+		printk(KERN_INFO PFX "Detected an Intel 845G Chipset.\n");
+		agp_bridge.type = INTEL_I810;
+		return intel_i830_setup(i810_dev);
+		   
+	case PCI_DEVICE_ID_INTEL_82830_HB:
+		i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82830_CGC, NULL);
+		if(i810_dev && PCI_FUNC(i810_dev->devfn) != 0)
+			i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82830_CGC, i810_dev);
+
+		if (i810_dev == NULL) {
+			/* Intel 830MP with external graphic card */
+			/* It will be initialized later */
+			agp_bridge.type = INTEL_I830_M;
+			break;
+		}
+		printk(KERN_INFO PFX "Detected an Intel 830M Chipset.\n");
+		agp_bridge.type = INTEL_I810;
+		return intel_i830_setup(i810_dev);
+
+	default:
+		break;
+	}
+
+	if (pci_find_capability(dev, PCI_CAP_ID_AGP)==0)
+		return -ENODEV;
+
+	/* probe for known chipsets */
+	return agp_lookup_host_bridge(dev);
+}
+
+
+static int agp_intel_probe (struct pci_dev *dev, const struct pci_device_id *ent)
+{
+	if (agp_find_supported_device(dev) == 0) {
+		agp_register_driver(dev);
+		return 0;
+	}
+	return -ENODEV;	
+}
+
+static struct pci_device_id agp_intel_pci_table[] __initdata = {
+	{
+	.class		= (PCI_CLASS_BRIDGE_HOST << 8),
+	.class_mask	= ~0,
+	.vendor		= PCI_VENDOR_ID_INTEL,
+	.device		= PCI_ANY_ID,
+	.subvendor	= PCI_ANY_ID,
+	.subdevice	= PCI_ANY_ID,
+	},
+	{ }
+};
+
+MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
+
+static struct pci_driver agp_intel_pci_driver = {
+	.name		= "agpgart-intel",
+	.id_table	= agp_intel_pci_table,
+	.probe		= agp_intel_probe,
+};
+
+static int __init agp_intel_init(void)
+{
+	int ret_val;
+
+	ret_val = pci_module_init(&agp_intel_pci_driver);
+	if (ret_val)
+		agp_bridge.type = NOT_SUPPORTED;
+
+	return ret_val;
+}
+
+static void __exit agp_intel_cleanup(void)
+{
+	agp_unregister_driver();
+	pci_unregister_driver(&agp_intel_pci_driver);
+}
+
+module_init(agp_intel_init);
+module_exit(agp_intel_cleanup);
+
+MODULE_PARM(agp_try_unsupported, "1i");
+MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
+MODULE_LICENSE("GPL and additional rights");
+
diff -Nru a/drivers/char/agp/k8-agp.c b/drivers/char/agp/k8-agp.c
--- a/drivers/char/agp/k8-agp.c	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,476 +0,0 @@
-/* 
- * Copyright 2001,2002 SuSE Labs
- * Distributed under the GNU public license, v2.
- * 
- * This is a GART driver for the AMD K8 northbridge and the AMD 8151 
- * AGP bridge. The main work is done in the northbridge. The configuration
- * is only mirrored in the 8151 for compatibility (could be likely
- * removed now).
- */ 
-
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/agp_backend.h>
-#include "agp.h"
-
-extern int agp_memory_reserved;
-extern __u32 *agp_gatt_table; 
-
-static u_int64_t pci_read64 (struct pci_dev *dev, int reg)
-{
-	union {
-		u64 full;
-		struct {
-			u32 high;
-			u32 low;
-		} split;
-	} tmp;
-	pci_read_config_dword(dev, reg, &tmp.split.high);
-	pci_read_config_dword(dev, reg+4, &tmp.split.low);
-	return tmp.full;
-}
-
-static void pci_write64 (struct pci_dev *dev, int reg, u64 value)
-{
-	union {
-		u64 full;
-		struct {
-			u32 high;
-			u32 low;
-		} split;
-	} tmp;
-	tmp.full = value;
-	pci_write_config_dword(dev, reg, tmp.split.high);
-	pci_write_config_dword(dev, reg+4, tmp.split.low);
-}
-
-
-static int x86_64_insert_memory(agp_memory * mem, off_t pg_start, int type)
-{
-	int i, j, num_entries;
-	void *temp;
-	long tmp;
-	u32 pte;
-	u64 addr;
-
-	temp = agp_bridge.current_size;
-
-	num_entries = A_SIZE_32(temp)->num_entries;
-
-	num_entries -= agp_memory_reserved>>PAGE_SHIFT;
-
-	if (type != 0 || mem->type != 0)
-		return -EINVAL;
-
-	/* Make sure we can fit the range in the gatt table. */
-	if ((pg_start + mem->page_count) > num_entries)
-		return -EINVAL;
-
-	j = pg_start;
-
-	/* gatt table should be empty. */
-	while (j < (pg_start + mem->page_count)) {
-		if (!PGE_EMPTY(agp_bridge.gatt_table[j]))
-			return -EBUSY;
-		j++;
-	}
-
-	if (mem->is_flushed == FALSE) {
-		CACHE_FLUSH();
-		mem->is_flushed = TRUE;
-	}
-
-	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
-		addr = mem->memory[i];
-
-		tmp = addr;
-		BUG_ON(tmp & 0xffffff0000000ffc);
-		pte = (tmp & 0x000000ff00000000) >> 28;
-		pte |=(tmp & 0x00000000fffff000);
-		pte |= 1<<1|1<<0;
-
-		agp_bridge.gatt_table[j] = pte;
-	}
-	agp_bridge.tlb_flush(mem);
-	return 0;
-}
-
-/*
- * This hack alters the order element according
- * to the size of a long. It sucks. I totally disown this, even
- * though it does appear to work for the most part.
- */
-static struct aper_size_info_32 x86_64_aperture_sizes[7] =
-{
-	{32,   8192,   3+(sizeof(long)/8), 0 },
-	{64,   16384,  4+(sizeof(long)/8), 1<<1 },
-	{128,  32768,  5+(sizeof(long)/8), 1<<2 },
-	{256,  65536,  6+(sizeof(long)/8), 1<<1 | 1<<2 },
-	{512,  131072, 7+(sizeof(long)/8), 1<<3 },
-	{1024, 262144, 8+(sizeof(long)/8), 1<<1 | 1<<3},
-	{2048, 524288, 9+(sizeof(long)/8), 1<<2 | 1<<3}
-};
-
-
-/*
- * Get the current Aperture size from the x86-64.
- * Note, that there may be multiple x86-64's, but we just return
- * the value from the first one we find. The set_size functions
- * keep the rest coherent anyway. Or at least should do.
- */
-static int amd_x86_64_fetch_size(void)
-{
-	struct pci_dev *dev;
-	int i;
-	u32 temp;
-	struct aper_size_info_32 *values;
-
-	pci_for_each_dev(dev) {
-		if (dev->bus->number==0 &&
-			PCI_FUNC(dev->devfn)==3 &&
-			PCI_SLOT(dev->devfn)>=24 && PCI_SLOT(dev->devfn)<=31) {
-
-			pci_read_config_dword(dev, AMD_X86_64_GARTAPERTURECTL, &temp);
-			temp = (temp & 0xe);
-			values = A_SIZE_32(x86_64_aperture_sizes);
-
-			for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
-				if (temp == values[i].size_value) {
-					agp_bridge.previous_size =
-					    agp_bridge.current_size = (void *) (values + i);
-
-					agp_bridge.aperture_size_idx = i;
-					return values[i].size;
-				}
-			}
-		}
-	}
-	/* erk, couldn't find an x86-64 ? */
-	return 0;
-}
-
-
-static void inline flush_x86_64_tlb(struct pci_dev *dev)
-{
-	u32 tmp;
-
-	pci_read_config_dword (dev, AMD_X86_64_GARTCACHECTL, &tmp);
-	tmp |= 1<<0;
-	pci_write_config_dword (dev, AMD_X86_64_GARTCACHECTL, tmp);
-}
-
-
-void amd_x86_64_tlbflush(agp_memory * temp)
-{
-	struct pci_dev *dev;
-
-	pci_for_each_dev(dev) {
-		if (dev->bus->number==0 && PCI_FUNC(dev->devfn)==3 &&
-		    PCI_SLOT(dev->devfn) >=24 && PCI_SLOT(dev->devfn) <=31) {
-			flush_x86_64_tlb (dev);
-		}
-	}
-}
-
-
-/*
- * In a multiprocessor x86-64 system, this function gets
- * called once for each CPU.
- */
-u64 amd_x86_64_configure (struct pci_dev *hammer, u64 gatt_table)
-{
-	u64 aperturebase;
-	u32 tmp;
-	u64 addr, aper_base;
-
-	/* Address to map to */
-	pci_read_config_dword (hammer, AMD_X86_64_GARTAPERTUREBASE, &tmp);
-	aperturebase = tmp << 25;
-	aper_base = (aperturebase & PCI_BASE_ADDRESS_MEM_MASK);
-
-	/* address of the mappings table */
-	addr = (u64) gatt_table;
-	addr >>= 12;
-	tmp = (u32) addr<<4;
-	tmp &= ~0xf;
-	pci_write_config_dword (hammer, AMD_X86_64_GARTTABLEBASE, tmp);
-
-	/* Enable GART translation for this hammer. */
-	pci_read_config_dword(hammer, AMD_X86_64_GARTAPERTURECTL, &tmp);
-	tmp &= 0x3f;
-	tmp |= 1<<0;
-	pci_write_config_dword(hammer, AMD_X86_64_GARTAPERTURECTL, tmp);
-
-	/* keep CPU's coherent. */
-	flush_x86_64_tlb (hammer);
-	
-	return aper_base;
-}
-
-
-static struct aper_size_info_32 amd_8151_sizes[7] =
-{
-	{2048, 524288, 9, 0x00000000 },	/* 0 0 0 0 0 0 */
-	{1024, 262144, 8, 0x00000400 },	/* 1 0 0 0 0 0 */
-	{512,  131072, 7, 0x00000600 },	/* 1 1 0 0 0 0 */
-	{256,  65536,  6, 0x00000700 },	/* 1 1 1 0 0 0 */
-	{128,  32768,  5, 0x00000720 },	/* 1 1 1 1 0 0 */
-	{64,   16384,  4, 0x00000730 },	/* 1 1 1 1 1 0 */
-	{32,   8192,   3, 0x00000738 } 	/* 1 1 1 1 1 1 */
-};
-
-static int amd_8151_configure(void)
-{
-	struct pci_dev *dev, *hammer=NULL;
-	int current_size;
-	int tmp, tmp2, i;
-	u64 aperbar;
-	unsigned long gatt_bus = virt_to_phys(agp_bridge.gatt_table_real);
-
-	/* Configure AGP regs in each x86-64 host bridge. */
-	pci_for_each_dev(dev) {
-		if (dev->bus->number==0 &&
-			PCI_FUNC(dev->devfn)==3 &&
-			PCI_SLOT(dev->devfn)>=24 && PCI_SLOT(dev->devfn)<=31) {
-			agp_bridge.gart_bus_addr = amd_x86_64_configure(dev,gatt_bus);
-			hammer = dev;
-
-			/*
-			 * TODO: Cache pci_dev's of x86-64's in private struct to save us
-			 * having to scan the pci list each time.
-			 */
-		}
-	}
-
-	if (hammer == NULL) {
-		return -ENODEV;
-	}
-
-	/* Shadow x86-64 registers into 8151 registers. */
-
-	dev = agp_bridge.dev;
-	if (!dev) 
-		return -ENODEV;
-
-	current_size = amd_x86_64_fetch_size();
-
-	pci_read_config_dword(dev, AMD_8151_APERTURESIZE, &tmp);
-	tmp &= ~(0xfff);
-
-	/* translate x86-64 size bits to 8151 size bits*/
-	for (i=0 ; i<7; i++) {
-		if (amd_8151_sizes[i].size == current_size)
-			tmp |= (amd_8151_sizes[i].size_value) << 3;
-	}
-	pci_write_config_dword(dev, AMD_8151_APERTURESIZE, tmp);
-
-	pci_read_config_dword (hammer, AMD_X86_64_GARTAPERTUREBASE, &tmp);
-	aperbar = pci_read64 (dev, AMD_8151_VMAPERTURE);
-	aperbar |= (tmp & 0x7fff) <<25;
-	aperbar &= 0x000000ffffffffff;
-	aperbar |= 1<<2;	/* This address is a 64bit ptr FIXME: Make conditional in 32bit mode */
-	pci_write64 (dev, AMD_8151_VMAPERTURE, aperbar);
-
-	pci_read_config_dword(dev, AMD_8151_AGP_CTL , &tmp);
-	tmp &= ~(AMD_8151_GTLBEN | AMD_8151_APEREN);
-	
-	pci_read_config_dword(hammer, AMD_X86_64_GARTAPERTURECTL, &tmp2);
-	if (tmp2 & AMD_X86_64_GARTEN)
-		tmp |= AMD_8151_APEREN;
-	// FIXME: bit 7 of AMD_8151_AGP_CTL (GTLBEN) must be copied if set.
-	// But where is it set ?
-	pci_write_config_dword(dev, AMD_8151_AGP_CTL, tmp);
-
-	return 0;
-}
-
-
-static void amd_8151_cleanup(void)
-{
-	struct pci_dev *dev;
-	u32 tmp;
-
-	pci_for_each_dev(dev) {
-		/* disable gart translation */
-		if (dev->bus->number==0 && PCI_FUNC(dev->devfn)==3 &&
-		    (PCI_SLOT(dev->devfn) >=24) && (PCI_SLOT(dev->devfn) <=31)) {
-
-			pci_read_config_dword (dev, AMD_X86_64_GARTAPERTURECTL, &tmp);
-			tmp &= ~(AMD_X86_64_GARTEN);
-			pci_write_config_dword (dev, AMD_X86_64_GARTAPERTURECTL, tmp);
-		}
-
-		/* Now shadow the disable in the 8151 */
-		if (dev->vendor == PCI_VENDOR_ID_AMD &&
-			dev->device == PCI_DEVICE_ID_AMD_8151_0) {
-
-			pci_read_config_dword (dev, AMD_8151_AGP_CTL, &tmp);
-			tmp &= ~(AMD_8151_APEREN);	
-			pci_write_config_dword (dev, AMD_8151_AGP_CTL, tmp);
-		}
-	}
-}
-
-
-
-static unsigned long amd_8151_mask_memory(unsigned long addr, int type)
-{
-	return addr | agp_bridge.masks[0].mask;
-}
-
-
-static struct gatt_mask amd_8151_masks[] =
-{
-	{0x00000001, 0}
-};
-
-
-/*
- * Try to configure an AGP v3 capable setup.
- * If we fail (typically because we don't have an AGP v3
- * card in the system) we fall back to the generic AGP v2
- * routines.
- */
-static void agp_x86_64_agp_enable(u32 mode)
-{
-	struct pci_dev *device = NULL;
-	u32 command, scratch; 
-	u8 cap_ptr;
-	u8 agp_v3;
-	u8 v3_devs=0;
-
-	/* FIXME: If 'mode' is x1/x2/x4 should we call the AGPv2 routines directly ?
-	 * Messy, as some AGPv3 cards can only do x4 as a minimum.
-	 */
-
-	/* PASS1: Count # of devs capable of AGPv3 mode. */
-	pci_for_each_dev(device) {
-		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (cap_ptr != 0x00) {
-			pci_read_config_dword(device, cap_ptr, &scratch);
-			scratch &= (1<<20|1<<21|1<<22|1<<23);
-			scratch = scratch>>20;
-			/* AGP v3 capable ? */
-			if (scratch>=3) {
-				v3_devs++;
-				printk (KERN_INFO "AGP: Found AGPv3 capable device at %d:%d:%d\n",
-					device->bus->number, PCI_FUNC(device->devfn), PCI_SLOT(device->devfn));
-			} else {
-				printk (KERN_INFO "AGP: Meh. version %x AGP device found.\n", scratch);
-			}
-		}
-	}
-	/* If not enough, go to AGP v2 setup */
-	if (v3_devs<2) {
-		printk (KERN_INFO "AGP: Only %d devices found, not enough, trying AGPv2\n", v3_devs);
-		return agp_generic_agp_enable(mode);
-	} else {
-		printk (KERN_INFO "AGP: Enough AGPv3 devices found, setting up...\n");
-	}
-
-
-	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx + 4, &command);
-
-	/*
-	 * PASS2: go through all devices that claim to be
-	 *        AGP devices and collect their data.
-	 */
-
-	pci_for_each_dev(device) {
-		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (cap_ptr != 0x00) {
-			/*
-			 * Ok, here we have a AGP device. Disable impossible 
-			 * settings, and adjust the readqueue to the minimum.
-			 */
-
-			printk (KERN_INFO "AGP: Setting up AGPv3 capable device at %d:%d:%d\n",
-					device->bus->number, PCI_FUNC(device->devfn), PCI_SLOT(device->devfn));
-			pci_read_config_dword(device, cap_ptr + 4, &scratch);
-			agp_v3 = (scratch & (1<<3) ) >>3;
-
-			/* adjust RQ depth */
-			command =
-			    ((command & ~0xff000000) |
-			     min_t(u32, (mode & 0xff000000),
-				 min_t(u32, (command & 0xff000000),
-				     (scratch & 0xff000000))));
-
-			/* disable SBA if it's not supported */
-			if (!((command & 0x200) && (scratch & 0x200) && (mode & 0x200)))
-				command &= ~0x200;
-
-			/* disable FW if it's not supported */
-			if (!((command & 0x10) && (scratch & 0x10) && (mode & 0x10)))
-				command &= ~0x10;
-
-			if (!((command & 2) && (scratch & 2) && (mode & 2))) {
-				command &= ~2;		/* 8x */
-				printk (KERN_INFO "AGP: Putting device into 8x mode\n");
-			}
-
-			if (!((command & 1) && (scratch & 1) && (mode & 1))) {
-				command &= ~1;		/* 4x */
-				printk (KERN_INFO "AGP: Putting device into 4x mode\n");
-			}
-		}
-	}
-	/*
-	 * PASS3: Figure out the 8X/4X setting and enable the
-	 *        target (our motherboard chipset).
-	 */
-
-	if (command & 2)
-		command &= ~5;	/* 8X */
-
-	if (command & 1)
-		command &= ~6;	/* 4X */
-
-	command |= 0x100;
-
-	pci_write_config_dword(agp_bridge.dev, agp_bridge.capndx + 8, command);
-
-	/*
-	 * PASS4: Go through all AGP devices and update the
-	 *        command registers.
-	 */
-
-	pci_for_each_dev(device) {
-		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (cap_ptr != 0x00)
-			pci_write_config_dword(device, cap_ptr + 8, command);
-	}
-}
-
-
-int __init amd_8151_setup (struct pci_dev *pdev)
-{
-	agp_bridge.masks = amd_8151_masks;
-	agp_bridge.num_of_masks = 1;
-	agp_bridge.aperture_sizes = (void *) amd_8151_sizes;
-	agp_bridge.size_type = U32_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 7;
-	agp_bridge.dev_private_data = NULL;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = amd_8151_configure;
-	agp_bridge.fetch_size = amd_x86_64_fetch_size;
-	agp_bridge.cleanup = amd_8151_cleanup;
-	agp_bridge.tlb_flush = amd_x86_64_tlbflush;
-	agp_bridge.mask_memory = amd_8151_mask_memory;
-	agp_bridge.agp_enable = agp_x86_64_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-	agp_bridge.insert_memory = x86_64_insert_memory;
-	agp_bridge.remove_memory = agp_generic_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
-
-	return 0;
-}
diff -Nru a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
--- a/drivers/char/agp/sis-agp.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/char/agp/sis-agp.c	Mon Dec  9 18:46:34 2002
@@ -1,29 +1,5 @@
 /*
- * AGPGART module version 0.99
- * Copyright (C) 1999 Jeff Hartmann
- * Copyright (C) 1999 Precision Insight, Inc.
- * Copyright (C) 1999 Xi Graphics, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
- * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * TODO: 
- * - Allocate more than order 0 pages to avoid too much linear map splitting.
+ * SiS AGPGART routines. 
  */
 
 #include <linux/module.h>
@@ -32,6 +8,8 @@
 #include <linux/agp_backend.h>
 #include "agp.h"
 
+static int agp_try_unsupported __initdata = 0;
+
 static int sis_fetch_size(void)
 {
 	u8 temp_size;
@@ -55,7 +33,6 @@
 	return 0;
 }
 
-
 static void sis_tlbflush(agp_memory * mem)
 {
 	pci_write_config_byte(agp_bridge.dev, SIS_TLBFLUSH, 0x02);
@@ -140,3 +117,172 @@
 	return 0;
 }
 
+struct agp_device_ids sis_agp_device_ids[] __initdata =
+{
+	{
+		.device_id	= PCI_DEVICE_ID_SI_740,
+		.chipset	= SIS_GENERIC,
+		.chipset_name	= "740",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_SI_650,
+		.chipset	= SIS_GENERIC,
+		.chipset_name	= "650",
+	},
+	{
+		.device_id  = PCI_DEVICE_ID_SI_651,
+		.chipset    = SIS_GENERIC,
+		.chipset_name   = "651",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_SI_645,
+		.chipset	= SIS_GENERIC,
+		.chipset_name	= "645",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_SI_646,
+		.chipset	= SIS_GENERIC,
+		.chipset_name	= "646",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_SI_735,
+		.chipset	= SIS_GENERIC,
+		.chipset_name	= "735",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_SI_745,
+		.chipset	= SIS_GENERIC,
+		.chipset_name	= "745",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_SI_730,
+		.chipset	= SIS_GENERIC,
+		.chipset_name	= "730",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_SI_630,
+		.chipset	= SIS_GENERIC,
+		.chipset_name	= "630",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_SI_540,
+		.chipset	= SIS_GENERIC,
+		.chipset_name	= "540",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_SI_620,
+		.chipset	= SIS_GENERIC,
+		.chipset_name	= "620",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_SI_530,
+		.chipset	= SIS_GENERIC,
+		.chipset_name	= "530",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_SI_550,
+		.chipset	= SIS_GENERIC,
+		.chipset_name	= "550",
+	},
+	{ }, /* dummy final entry, always present */
+};
+
+/* scan table above for supported devices */
+static int __init agp_lookup_host_bridge (struct pci_dev *pdev)
+{
+	int j=0;
+	struct agp_device_ids *devs;
+	
+	devs = sis_agp_device_ids;
+
+	while (devs[j].chipset_name != NULL) {
+		if (pdev->device == devs[j].device_id) {
+			printk (KERN_INFO PFX "Detected SiS %s chipset\n",
+				devs[j].chipset_name);
+			agp_bridge.type = devs[j].chipset;
+
+			if (devs[j].chipset_setup != NULL)
+				return devs[j].chipset_setup(pdev);
+			else
+				return sis_generic_setup(pdev);
+		}
+		j++;
+	}
+
+	/* try init anyway, if user requests it */
+	if (agp_try_unsupported) {
+		printk(KERN_WARNING PFX "Trying generic SiS routines"
+		       " for device id: %04x\n", pdev->device);
+		agp_bridge.type = SIS_GENERIC;
+		return sis_generic_setup(pdev);
+	}
+
+	printk(KERN_ERR PFX "Unsupported SiS chipset (device id: %04x),"
+		" you might want to try agp_try_unsupported=1.\n", pdev->device);
+	return -ENODEV;
+}
+
+
+static int __init agp_find_supported_device(struct pci_dev *dev)
+{
+	agp_bridge.dev = dev;
+
+	if (pci_find_capability(dev, PCI_CAP_ID_AGP)==0)
+		return -ENODEV;
+
+	/* probe for known chipsets */
+	return agp_lookup_host_bridge (dev);
+}
+
+
+static int agp_sis_probe (struct pci_dev *dev, const struct pci_device_id *ent)
+{
+	if (agp_find_supported_device(dev) == 0) {
+		agp_register_driver(dev);
+		return 0;
+	}
+	return -ENODEV;	
+}
+
+static struct pci_device_id agp_sis_pci_table[] __initdata = {
+	{
+	.class		= (PCI_CLASS_BRIDGE_HOST << 8),
+	.class_mask	= ~0,
+	.vendor		= PCI_VENDOR_ID_SI,
+	.device		= PCI_ANY_ID,
+	.subvendor	= PCI_ANY_ID,
+	.subdevice	= PCI_ANY_ID,
+	},
+	{ }
+};
+
+MODULE_DEVICE_TABLE(pci, agp_sis_pci_table);
+
+static struct pci_driver agp_sis_pci_driver = {
+	.name		= "agpgart-sis",
+	.id_table	= agp_sis_pci_table,
+	.probe		= agp_sis_probe,
+};
+
+int __init agp_sis_init(void)
+{
+	int ret_val;
+
+	ret_val = pci_module_init(&agp_sis_pci_driver);
+	if (ret_val)
+		agp_bridge.type = NOT_SUPPORTED;
+
+	return ret_val;
+}
+
+static void __exit agp_sis_cleanup(void)
+{
+	agp_unregister_driver();
+	pci_unregister_driver(&agp_sis_pci_driver);
+}
+
+module_init(agp_sis_init);
+module_exit(agp_sis_cleanup);
+
+MODULE_PARM(agp_try_unsupported, "1i");
+MODULE_LICENSE("GPL and additional rights");
diff -Nru a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
--- a/drivers/char/agp/sworks-agp.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/char/agp/sworks-agp.c	Mon Dec  9 18:46:36 2002
@@ -1,29 +1,5 @@
 /*
- * AGPGART module version 0.99
- * Copyright (C) 1999 Jeff Hartmann
- * Copyright (C) 1999 Precision Insight, Inc.
- * Copyright (C) 1999 Xi Graphics, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
- * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * TODO: 
- * - Allocate more than order 0 pages to avoid too much linear map splitting.
+ * Serverworks AGPGART routines.
  */
 
 #include <linux/module.h>
@@ -32,6 +8,8 @@
 #include <linux/agp_backend.h>
 #include "agp.h"
 
+static int agp_try_unsupported __initdata = 0;
+
 struct serverworks_page_map {
 	unsigned long *real;
 	unsigned long *remapped;
@@ -182,8 +160,8 @@
 		return retval;
 	}
 
-	agp_bridge.gatt_table_real = page_dir.real;
-	agp_bridge.gatt_table = page_dir.remapped;
+	agp_bridge.gatt_table_real = (unsigned long *)page_dir.real;
+	agp_bridge.gatt_table = (unsigned long *)page_dir.remapped;
 	agp_bridge.gatt_bus_addr = virt_to_phys(page_dir.real);
 
 	/* Get the address for the gart region.
@@ -211,8 +189,8 @@
 {
 	struct serverworks_page_map page_dir;
    
-	page_dir.real = agp_bridge.gatt_table_real;
-	page_dir.remapped = agp_bridge.gatt_table;
+	page_dir.real = (unsigned long *)agp_bridge.gatt_table_real;
+	page_dir.remapped = (unsigned long *)agp_bridge.gatt_table;
 
 	serverworks_free_gatt_pages();
 	serverworks_free_page_map(&page_dir);
@@ -623,4 +601,92 @@
 
 	return 0;
 }
+
+
+static int __init agp_find_supported_device(struct pci_dev *dev)
+{
+	struct pci_dev *bridge_dev;
+	agp_bridge.dev = dev;
+
+	/* Everything is on func 1 here so we are hardcoding function one */
+	bridge_dev = pci_find_slot ((unsigned int)dev->bus->number, PCI_DEVFN(0, 1));
+	if(bridge_dev == NULL) {
+		printk(KERN_INFO PFX "agpgart: Detected a Serverworks "
+		       "Chipset, but could not find the secondary "
+		       "device.\n");
+		return -ENODEV;
+	}
+
+	switch (dev->device) {
+	case PCI_DEVICE_ID_SERVERWORKS_HE:
+		agp_bridge.type = SVWRKS_HE;
+		return serverworks_setup(bridge_dev);
+
+	case PCI_DEVICE_ID_SERVERWORKS_LE:
+	case 0x0007:
+		agp_bridge.type = SVWRKS_LE;
+		return serverworks_setup(bridge_dev);
+
+	default:
+		if(agp_try_unsupported) {
+			agp_bridge.type = SVWRKS_GENERIC;
+			return serverworks_setup(bridge_dev);
+		}
+		break;
+	}
+	return -ENODEV;
+}
+
+
+static int agp_serverworks_probe (struct pci_dev *dev, const struct pci_device_id *ent)
+{
+	if (agp_find_supported_device(dev) == 0) {
+		agp_register_driver(dev);
+		return 0;
+	}
+	return -ENODEV;	
+}
+
+static struct pci_device_id agp_serverworks_pci_table[] __initdata = {
+	{
+	.class		= (PCI_CLASS_BRIDGE_HOST << 8),
+	.class_mask	= ~0,
+	.vendor		= PCI_VENDOR_ID_SERVERWORKS,
+	.device		= PCI_ANY_ID,
+	.subvendor	= PCI_ANY_ID,
+	.subdevice	= PCI_ANY_ID,
+	},
+	{ }
+};
+
+MODULE_DEVICE_TABLE(pci, agp_serverworks_pci_table);
+
+static struct pci_driver agp_serverworks_pci_driver = {
+	.name		= "agpgart-serverworks",
+	.id_table	= agp_serverworks_pci_table,
+	.probe		= agp_serverworks_probe,
+};
+
+static int __init agp_serverworks_init(void)
+{
+	int ret_val;
+
+	ret_val = pci_module_init(&agp_serverworks_pci_driver);
+	if (ret_val)
+		agp_bridge.type = NOT_SUPPORTED;
+
+	return ret_val;
+}
+
+static void __exit agp_serverworks_cleanup(void)
+{
+	agp_unregister_driver();
+	pci_unregister_driver(&agp_serverworks_pci_driver);
+}
+
+module_init(agp_serverworks_init);
+module_exit(agp_serverworks_cleanup);
+
+MODULE_PARM(agp_try_unsupported, "1i");
+MODULE_LICENSE("GPL and additional rights");
 
diff -Nru a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c
--- a/drivers/char/agp/via-agp.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/char/agp/via-agp.c	Mon Dec  9 18:46:50 2002
@@ -1,38 +1,15 @@
 /*
- * AGPGART module version 0.99
- * Copyright (C) 1999 Jeff Hartmann
- * Copyright (C) 1999 Precision Insight, Inc.
- * Copyright (C) 1999 Xi Graphics, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
- * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * TODO: 
- * - Allocate more than order 0 pages to avoid too much linear map splitting.
+ * VIA AGPGART routines. 
  */
-#include <linux/config.h>
+
 #include <linux/types.h>
-#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/agp_backend.h>
 #include "agp.h"
 
+static int agp_try_unsupported __initdata = 0;
 
 static int via_fetch_size(void)
 {
@@ -144,8 +121,159 @@
 	agp_bridge.suspend = agp_generic_suspend;
 	agp_bridge.resume = agp_generic_resume;
 	agp_bridge.cant_use_aperture = 0;
-
 	return 0;
+}
+
+struct agp_device_ids via_agp_device_ids[] __initdata =
+{
+	{
+		.device_id	= PCI_DEVICE_ID_VIA_8501_0,
+		.chipset	= VIA_MVP4,
+		.chipset_name	= "MVP4",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_VIA_82C597_0,
+		.chipset	= VIA_VP3,
+		.chipset_name	= "VP3",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_VIA_82C598_0,
+		.chipset	= VIA_MVP3,
+		.chipset_name	= "MVP3",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_VIA_82C691,
+		.chipset	= VIA_APOLLO_PRO,
+		.chipset_name	= "Apollo Pro",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_VIA_8371_0,
+		.chipset	= VIA_APOLLO_KX133,
+		.chipset_name	= "Apollo Pro KX133",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_VIA_8633_0,
+		.chipset	= VIA_APOLLO_PRO_266,
+		.chipset_name	= "Apollo Pro 266",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_VIA_8363_0,
+		.chipset	= VIA_APOLLO_KT133,
+		.chipset_name	= "Apollo Pro KT133",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_VIA_8367_0,
+		.chipset	= VIA_APOLLO_KT133,
+		.chipset_name	= "Apollo Pro KT266",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_VIA_8377_0,
+		.chipset	= VIA_APOLLO_KT400,
+		.chipset_name	= "Apollo Pro KT400",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_VIA_8653_0,
+		.chipset	= VIA_APOLLO_PRO,
+		.chipset_name	= "Apollo Pro266T",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_VIA_82C694X_0,
+		.chipset	= VIA_VT8605,
+		.chipset_name	= "PM133"
+	},
+	{ }, /* dummy final entry, always present */
+};
+
+
+/* scan table above for supported devices */
+static int __init agp_lookup_host_bridge (struct pci_dev *pdev)
+{
+	int j=0;
+	struct agp_device_ids *devs;
 	
-	(void) pdev; /* unused */
+	devs = via_agp_device_ids;
+
+	while (devs[j].chipset_name != NULL) {
+		if (pdev->device == devs[j].device_id) {
+			printk (KERN_INFO PFX "Detected VIA %s chipset\n", devs[j].chipset_name);
+			agp_bridge.type = devs[j].chipset;
+
+			if (devs[j].chipset_setup != NULL)
+				return devs[j].chipset_setup(pdev);
+			else
+				return via_generic_setup(pdev);
+		}
+		j++;
+	}
+
+	/* try init anyway, if user requests it */
+	if (agp_try_unsupported) {
+		printk(KERN_WARNING PFX "Trying generic VIA routines"
+		       " for device id: %04x\n", pdev->device);
+		agp_bridge.type = VIA_GENERIC;
+		return via_generic_setup(pdev);
+	}
+
+	printk(KERN_ERR PFX "Unsupported VIA chipset (device id: %04x),"
+		" you might want to try agp_try_unsupported=1.\n", pdev->device);
+	return -ENODEV;
 }
+
+
+static int agp_via_probe (struct pci_dev *dev, const struct pci_device_id *ent)
+{
+	if (pci_find_capability(dev, PCI_CAP_ID_AGP)==0)
+		return -ENODEV;
+
+	agp_bridge.dev = dev;
+
+	/* probe for known chipsets */
+	if (agp_lookup_host_bridge (dev) != -ENODEV) {
+		agp_register_driver(dev);
+		return 0;
+	}
+	return -ENODEV;	
+}
+
+static struct pci_device_id agp_via_pci_table[] __initdata = {
+	{
+	.class		= (PCI_CLASS_BRIDGE_HOST << 8),
+	.class_mask	= ~0,
+	.vendor		= PCI_VENDOR_ID_VIA,
+	.device		= PCI_ANY_ID,
+	.subvendor	= PCI_ANY_ID,
+	.subdevice	= PCI_ANY_ID,
+	},
+	{ }
+};
+
+MODULE_DEVICE_TABLE(pci, agp_via_pci_table);
+
+static struct pci_driver agp_via_pci_driver = {
+	.name		= "agpgart-via",
+	.id_table	= agp_via_pci_table,
+	.probe		= agp_via_probe,
+};
+
+static int __init agp_via_init(void)
+{
+	int ret_val;
+
+	ret_val = pci_module_init(&agp_via_pci_driver);
+	if (ret_val)
+		agp_bridge.type = NOT_SUPPORTED;
+
+	return ret_val;
+}
+
+static void __exit agp_via_cleanup(void)
+{
+	agp_unregister_driver();
+	pci_unregister_driver(&agp_via_pci_driver);
+}
+
+module_init(agp_via_init);
+module_exit(agp_via_cleanup);
+
+MODULE_PARM(agp_try_unsupported, "1i");
+MODULE_LICENSE("GPL and additional rights");
diff -Nru a/drivers/char/consolemap.c b/drivers/char/consolemap.c
--- a/drivers/char/consolemap.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/char/consolemap.c	Mon Dec  9 18:46:50 2002
@@ -11,6 +11,8 @@
  * Fix bug in inverse translation. Stanislav Voronyi <stas@cnti.uanet.kharkov.ua>, Dec 1998
  */
 
+#include <linux/config.h>
+#include <linux/module.h>
 #include <linux/kd.h>
 #include <linux/errno.h>
 #include <linux/mm.h>
@@ -19,7 +21,6 @@
 #include <linux/tty.h>
 #include <asm/uaccess.h>
 #include <linux/consolemap.h>
-#include <linux/console_struct.h>
 #include <linux/vt_kern.h>
 
 static unsigned short translations[][256] = {
@@ -681,3 +682,5 @@
 		if (vc_cons_allocated(i) && !*vc_cons[i].d->vc_uni_pagedir_loc)
 			con_set_default_unimap(i);
 }
+
+EXPORT_SYMBOL(con_copy_unimap);
diff -Nru a/drivers/char/cyclades.c b/drivers/char/cyclades.c
--- a/drivers/char/cyclades.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/char/cyclades.c	Mon Dec  9 18:46:35 2002
@@ -12,7 +12,7 @@
  *
  * Initially written by Randolph Bentson <bentson@grieg.seaslug.org>.
  * Modified and maintained by Marcio Saito <marcio@cyclades.com>.
- * Currently maintained by Ivan Passos <ivan@cyclades.com>.
+ * Currently maintained by Henrique Gobbi <henrique.gobbi@cyclades.com>.
  *
  * For Technical support and installation problems, please send e-mail
  * to support@cyclades.com.
@@ -884,7 +884,7 @@
 
 static int cyz_timeron = 0;
 static struct timer_list cyz_timerlist = TIMER_INITIALIZER(cyz_poll, 0, 0);
-};
+
 #else /* CONFIG_CYZ_INTR */
 static void cyz_rx_restart(unsigned long);
 static struct timer_list cyz_rx_full_timer[NR_PORTS];
diff -Nru a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
--- a/drivers/char/dsp56k.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/char/dsp56k.c	Mon Dec  9 18:46:37 2002
@@ -499,8 +499,6 @@
 
 /****** Init and module functions ******/
 
-static devfs_handle_t devfs_handle;
-
 static char banner[] __initdata = KERN_INFO "DSP56k driver installed\n";
 
 static int __init dsp56k_init_driver(void)
@@ -514,10 +512,10 @@
 		printk("DSP56k driver: Unable to register driver\n");
 		return -ENODEV;
 	}
-	devfs_handle = devfs_register(NULL, "dsp56k", DEVFS_FL_DEFAULT,
-				      DSP56K_MAJOR, 0,
-				      S_IFCHR | S_IRUSR | S_IWUSR,
-				      &dsp56k_fops, NULL);
+	devfs_register(NULL, "dsp56k", DEVFS_FL_DEFAULT,
+		      DSP56K_MAJOR, 0,
+		      S_IFCHR | S_IRUSR | S_IWUSR,
+		      &dsp56k_fops, NULL);
 
 	printk(banner);
 	return 0;
@@ -527,7 +525,7 @@
 static void __exit dsp56k_cleanup_driver(void)
 {
 	unregister_chrdev(DSP56K_MAJOR, "dsp56k");
-	devfs_unregister(devfs_handle);
+	devfs_remove("dsp56k");
 }
 module_exit(dsp56k_cleanup_driver);
 
diff -Nru a/drivers/char/dtlk.c b/drivers/char/dtlk.c
--- a/drivers/char/dtlk.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/char/dtlk.c	Mon Dec  9 18:46:36 2002
@@ -333,8 +333,6 @@
 	return 0;
 }
 
-static devfs_handle_t devfs_handle;
-
 static int __init dtlk_init(void)
 {
 	dtlk_port_lpc = 0;
@@ -347,10 +345,10 @@
 	}
 	if (dtlk_dev_probe() == 0)
 		printk(", MAJOR %d\n", dtlk_major);
-	devfs_handle = devfs_register (NULL, "dtlk", DEVFS_FL_DEFAULT,
-				       dtlk_major, DTLK_MINOR,
-				       S_IFCHR | S_IRUSR | S_IWUSR,
-				       &dtlk_fops, NULL);
+	devfs_register(NULL, "dtlk", DEVFS_FL_DEFAULT,
+		       dtlk_major, DTLK_MINOR,
+		       S_IFCHR | S_IRUSR | S_IWUSR,
+		       &dtlk_fops, NULL);
 
 	init_timer(&dtlk_timer);
 	dtlk_timer.function = dtlk_timer_tick;
@@ -370,7 +368,7 @@
 
 	dtlk_write_tts(DTLK_CLEAR);
 	unregister_chrdev(dtlk_major, "dtlk");
-	devfs_unregister(devfs_handle);
+	devfs_remove("dtlk");
 	release_region(dtlk_port_lpc, DTLK_IO_EXTENT);
 }
 
diff -Nru a/drivers/char/epca.c b/drivers/char/epca.c
--- a/drivers/char/epca.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/char/epca.c	Mon Dec  9 18:46:38 2002
@@ -141,12 +141,6 @@
 	configured.
 ----------------------------------------------------------------------- */
 	
-
-#ifdef MODULE
-int                init_module(void);
-void               cleanup_module(void);
-#endif /* MODULE */
-
 static inline void memwinon(struct board_info *b, unsigned int win);
 static inline void memwinoff(struct board_info *b, unsigned int win);
 static inline void globalwinon(struct channel *ch);
@@ -1534,8 +1528,7 @@
 } /* End pc_open */
 
 #ifdef MODULE
-/* -------------------- Begin init_module ---------------------- */
-int __init init_module()
+static int __init epca_module_init(void)
 { /* Begin init_module */
 
 	unsigned long	flags;
@@ -1548,8 +1541,9 @@
 	restore_flags(flags);
 
 	return(0);
-} /* End init_module */
+}
 
+module_init(epca_module_init);
 #endif
 
 #ifdef ENABLE_PCI
@@ -1559,8 +1553,8 @@
 #ifdef MODULE
 /* -------------------- Begin cleanup_module  ---------------------- */
 
-void cleanup_module()
-{ /* Begin cleanup_module */
+static void __exit epca_module_exit(void)
+{
 
 	int               count, crd;
 	struct board_info *bd;
@@ -1613,7 +1607,8 @@
 
 	restore_flags(flags);
 
-} /* End cleanup_module */
+}
+module_exit(epca_module_exit);
 #endif /* MODULE */
 
 /* ------------------ Begin pc_init  ---------------------- */
diff -Nru a/drivers/char/ftape/zftape/zftape-init.c b/drivers/char/ftape/zftape/zftape-init.c
--- a/drivers/char/ftape/zftape/zftape-init.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/char/ftape/zftape/zftape-init.c	Mon Dec  9 18:46:36 2002
@@ -314,7 +314,7 @@
 /*  Called by modules package when installing the driver or by kernel
  *  during the initialization phase
  */
-static int __init zft_init(void)
+int __init zft_init(void)
 {
 	int i;
 	TRACE_FUN(ft_t_flow);
diff -Nru a/drivers/char/hp_keyb.c b/drivers/char/hp_keyb.c
--- a/drivers/char/hp_keyb.c	Mon Dec  9 18:46:36 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,519 +0,0 @@
-/*
- * linux/drivers/char/hp_keyb.c
- * helper-functions for the keyboard/psaux driver for HP-PARISC workstations
- *
- * based on pc_keyb.c by Geert Uytterhoeven & Martin Mares
- *
- * 2000/10/26	Debacker Xavier <debackex@esiee.fr>
- *		Marteau Thomas <marteaut@esiee.fr>
- *		Djoudi Malek <djoudim@esiee.fr>
- * - fixed some keysym defines 
- *
- * 2001/04/28	Debacker Xavier <debackex@esiee.fr>
- * - scancode translation rewritten in handle_at_scancode()
- */  
-
-#include <linux/config.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/ptrace.h>
-#include <linux/signal.h>
-#include <linux/timer.h>
-#include <linux/random.h>
-#include <linux/ctype.h>
-#include <linux/kbd_ll.h>
-#include <linux/init.h>
-
-#include <asm/bitops.h>
-#include <asm/irq.h>
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/system.h>
-
-#define KBD_REPORT_ERR
-#define KBD_REPORT_UNKN
-
-#define KBD_ESCAPEE0	0xe0		/* in */
-#define KBD_ESCAPEE1	0xe1		/* in */
-
-#define ESCE0(x)	(0xe000|(x))
-#define ESCE1(x)	(0xe100|(x))
-
-#define KBD_BAT		0xaa		/* in */
-#define KBD_SETLEDS	0xed		/* out */
-#define KBD_ECHO	0xee		/* in/out */
-#define KBD_BREAK	0xf0		/* in */
-#define KBD_TYPRATEDLY	0xf3		/* out */
-#define KBD_SCANENABLE	0xf4		/* out */
-#define KBD_DEFDISABLE	0xf5		/* out */
-#define KBD_DEFAULT	0xf6		/* out */
-#define KBD_ACK		0xfa		/* in */
-#define KBD_DIAGFAIL	0xfd		/* in */
-#define KBD_RESEND	0xfe		/* in/out */
-#define KBD_RESET	0xff		/* out */
-
-#define CODE_BREAK	1
-#define CODE_ESCAPEE0	2
-#define CODE_ESCAPEE1	4
-#define CODE_ESCAPE12	8
-
-#define K_NONE		0x7f
-#define K_ESC		0x01
-#define K_F1		0x3b
-#define K_F2		0x3c
-#define K_F3		0x3d
-#define K_F4		0x3e
-#define K_F5		0x3f
-#define K_F6		0x40
-#define K_F7		0x41
-#define K_F8		0x42
-#define K_F9		0x43
-#define K_F10		0x44
-#define K_F11		0x57
-#define K_F12		0x58
-#define K_PRNT		0x54
-#define K_SCRL		0x46
-#define K_BRK		0x77
-#define K_AGR		0x29
-#define K_1		0x02
-#define K_2		0x03
-#define K_3		0x04
-#define K_4		0x05
-#define K_5		0x06
-#define K_6		0x07
-#define K_7		0x08
-#define K_8		0x09
-#define K_9		0x0a
-#define K_0		0x0b
-#define K_MINS		0x0c
-#define K_EQLS		0x0d
-#define K_BKSP		0x0e
-#define K_INS		0x6e
-#define K_HOME		0x66
-#define K_PGUP		0x68
-#define K_NUML		0x45
-#define KP_SLH		0x62
-#define KP_STR		0x37
-#define KP_MNS		0x4a
-#define K_TAB		0x0f
-#define K_Q		0x10
-#define K_W		0x11
-#define K_E		0x12
-#define K_R		0x13
-#define K_T		0x14
-#define K_Y		0x15
-#define K_U		0x16
-#define K_I		0x17
-#define K_O		0x18
-#define K_P		0x19
-#define K_LSBK		0x1a
-#define K_RSBK		0x1b
-#define K_ENTR		0x1c
-#define K_DEL		111
-#define K_END		0x6b
-#define K_PGDN		0x6d
-#define KP_7		0x47
-#define KP_8		0x48
-#define KP_9		0x49
-#define KP_PLS		0x4e
-#define K_CAPS		0x3a
-#define K_A		0x1e
-#define K_S		0x1f
-#define K_D		0x20
-#define K_F		0x21
-#define K_G		0x22
-#define K_H		0x23
-#define K_J		0x24
-#define K_K		0x25
-#define K_L		0x26
-#define K_SEMI		0x27
-#define K_SQOT		0x28
-#define K_HASH		K_NONE
-#define KP_4		0x4b
-#define KP_5		0x4c
-#define KP_6		0x4d
-#define K_LSFT		0x2a
-#define K_BSLH		0x2b
-#define K_Z		0x2c
-#define K_X		0x2d
-#define K_C		0x2e
-#define K_V		0x2f
-#define K_B		0x30
-#define K_N		0x31
-#define K_M		0x32
-#define K_COMA		0x33
-#define K_DOT		0x34
-#define K_FSLH		0x35
-#define K_RSFT		0x36
-#define K_UP		0x67
-#define KP_1		0x4f
-#define KP_2		0x50
-#define KP_3		0x51
-#define KP_ENT		0x60
-#define K_LCTL		0x1d
-#define K_LALT		0x38
-#define K_SPCE		0x39
-#define K_RALT		0x64
-#define K_RCTL		0x61
-#define K_LEFT		0x69
-#define K_DOWN		0x6c
-#define K_RGHT		0x6a
-#define KP_0		0x52
-#define KP_DOT		0x53
-
-static unsigned char keycode_translate[256] =
-{
-/* 00 */  K_NONE, K_F9  , K_NONE, K_F5  , K_F3  , K_F1  , K_F2  , K_F12 ,
-/* 08 */  K_NONE, K_F10 , K_F8  , K_F6  , K_F4  , K_TAB , K_AGR , K_NONE,
-/* 10 */  K_NONE, K_LALT, K_LSFT, K_NONE, K_LCTL, K_Q   , K_1   , K_NONE,
-/* 18 */  K_NONE, K_NONE, K_Z   , K_S   , K_A   , K_W   , K_2   , K_NONE,
-/* 20 */  K_NONE, K_C   , K_X   , K_D   , K_E   , K_4   , K_3   , K_NONE,
-/* 28 */  K_NONE, K_SPCE, K_V   , K_F   , K_T   , K_R   , K_5   , K_NONE,
-/* 30 */  K_NONE, K_N   , K_B   , K_H   , K_G   , K_Y   , K_6   , K_NONE,
-/* 38 */  K_NONE, K_NONE, K_M   , K_J   , K_U   , K_7   , K_8   , K_NONE,
-/* 40 */  K_NONE, K_COMA, K_K   , K_I   , K_O   , K_0   , K_9   , K_NONE,
-/* 48 */  K_NONE, K_DOT , K_FSLH, K_L   , K_SEMI, K_P   , K_MINS, K_NONE,
-/* 50 */  K_NONE, K_NONE, K_SQOT, K_NONE, K_LSBK, K_EQLS, K_NONE, K_NONE,
-/* 58 */  K_CAPS, K_RSFT, K_ENTR, K_RSBK, K_NONE, K_BSLH, K_NONE, K_NONE,
-/* 60 */  K_NONE, K_HASH, K_NONE, K_NONE, K_NONE, K_NONE, K_BKSP, K_NONE,
-/* 68 */  K_NONE, KP_1  , K_NONE, KP_4  , KP_7  , K_NONE, K_NONE, K_NONE,
-/* 70 */  KP_0  , KP_DOT, KP_2  , KP_5  , KP_6  , KP_8  , K_ESC , K_NUML,
-/* 78 */  K_F11 , KP_PLS, KP_3  , KP_MNS, KP_STR, KP_9  , K_SCRL, K_PRNT,
-/* 80 */  K_NONE, K_NONE, K_NONE, K_F7  , K_NONE, K_NONE, K_NONE, K_NONE,
-/* 88 */  K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
-/* 90 */  K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
-/* 98 */  K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
-/* a0 */  K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
-/* a8 */  K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
-/* b0 */  K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
-/* b8 */  K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
-/* c0 */  K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
-/* c8 */  K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
-/* d0 */  K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
-/* d8 */  K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
-/* e0 */  K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
-/* e8 */  K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
-/* f0 */  K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
-/* f8 */  K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, KBD_RESEND, K_NONE
-};
-
-/* ----- the following code stolen from pc_keyb.c */
-
-
-#ifdef CONFIG_MAGIC_SYSRQ
-unsigned char hp_ps2kbd_sysrq_xlate[128] =
-	"\000\0331234567890-=\177\t"			/* 0x00 - 0x0f */
-	"qwertyuiop[]\r\000as"				/* 0x10 - 0x1f */
-	"dfghjkl;'`\000\\zxcv"				/* 0x20 - 0x2f */
-	"bnm,./\000*\000 \000\201\202\203\204\205"	/* 0x30 - 0x3f */
-	"\206\207\210\211\212\000\000789-456+1"		/* 0x40 - 0x4f */
-	"230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
-	"\r\000/";					/* 0x60 - 0x6f */
-#endif
-
-/*
- * Translation of escaped scancodes to keycodes.
- * This is now user-settable.
- * The keycodes 1-88,96-111,119 are fairly standard, and
- * should probably not be changed - changing might confuse X.
- * X also interprets scancode 0x5d (KEY_Begin).
- *
- * For 1-88 keycode equals scancode.
- */
-
-#define E0_KPENTER 96
-#define E0_RCTRL   97
-#define E0_KPSLASH 98
-#define E0_PRSCR   99
-#define E0_RALT    100
-#define E0_BREAK   101	/* (control-pause) */
-#define E0_HOME    102
-#define E0_UP      103
-#define E0_PGUP    104
-#define E0_LEFT    105
-#define E0_RIGHT   106
-#define E0_END     107
-#define E0_DOWN    108
-#define E0_PGDN    109
-#define E0_INS     110
-#define E0_DEL     111
-
-#define E1_PAUSE   119
-
-/*
- * The keycodes below are randomly located in 89-95,112-118,120-127.
- * They could be thrown away (and all occurrences below replaced by 0),
- * but that would force many users to use the `setkeycodes' utility, where
- * they needed not before. It does not matter that there are duplicates, as
- * long as no duplication occurs for any single keyboard.
- */
-#define SC_LIM 89		/* 0x59 == 89 */
-
-#define FOCUS_PF1 85		/* actual code! */
-#define FOCUS_PF2 89
-#define FOCUS_PF3 90
-#define FOCUS_PF4 91
-#define FOCUS_PF5 92
-#define FOCUS_PF6 93
-#define FOCUS_PF7 94
-#define FOCUS_PF8 95
-#define FOCUS_PF9 120
-#define FOCUS_PF10 121
-#define FOCUS_PF11 122
-#define FOCUS_PF12 123
-
-#define JAP_86     124
-/* tfj@olivia.ping.dk:
- * The four keys are located over the numeric keypad, and are
- * labelled A1-A4. It's an rc930 keyboard, from
- * Regnecentralen/RC International, Now ICL.
- * Scancodes: 59, 5a, 5b, 5c.
- */
-#define RGN1 124
-#define RGN2 125
-#define RGN3 126
-#define RGN4 127
-
-static unsigned char high_keys[128 - SC_LIM] = {
-  RGN1, RGN2, RGN3, RGN4, 0, 0, 0,                   /* 0x59-0x5f */
-  0, 0, 0, 0, 0, 0, 0, 0,                            /* 0x60-0x67 */
-  0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12,          /* 0x68-0x6f */
-  0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3,    /* 0x70-0x77 */
-  FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7,        /* 0x78-0x7b */
-  FOCUS_PF8, JAP_86, FOCUS_PF10, 0                   /* 0x7c-0x7f */
-};
-
-/* BTC */
-#define E0_MACRO   112
-/* LK450 */
-#define E0_F13     113
-#define E0_F14     114
-#define E0_HELP    115
-#define E0_DO      116
-#define E0_F17     117
-#define E0_KPMINPLUS 118
-/*
- * My OmniKey generates e0 4c for  the "OMNI" key and the
- * right alt key does nada. [kkoller@nyx10.cs.du.edu]
- */
-#define E0_OK	124
-/*
- * New microsoft keyboard is rumoured to have
- * e0 5b (left window button), e0 5c (right window button),
- * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
- * [or: Windows_L, Windows_R, TaskMan]
- */
-#define E0_MSLW	125
-#define E0_MSRW	126
-#define E0_MSTM	127
-
-static unsigned char e0_keys[128] = {
-  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x00-0x07 */
-  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x08-0x0f */
-  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x10-0x17 */
-  0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0,	      /* 0x18-0x1f */
-  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x20-0x27 */
-  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x28-0x2f */
-  0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR,	      /* 0x30-0x37 */
-  E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP,	      /* 0x38-0x3f */
-  E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME,	      /* 0x40-0x47 */
-  E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */
-  E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0,	      /* 0x50-0x57 */
-  0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0,	      /* 0x58-0x5f */
-  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x60-0x67 */
-  0, 0, 0, 0, 0, 0, 0, E0_MACRO,		      /* 0x68-0x6f */
-  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x70-0x77 */
-  0, 0, 0, 0, 0, 0, 0, 0			      /* 0x78-0x7f */
-};
-
-int pckbd_setkeycode(unsigned int scancode, unsigned int keycode)
-{
-	if (scancode < SC_LIM || scancode > 255 || keycode > 127)
-	  return -EINVAL;
-	if (scancode < 128)
-	  high_keys[scancode - SC_LIM] = keycode;
-	else
-	  e0_keys[scancode - 128] = keycode;
-	return 0;
-}
-
-int pckbd_getkeycode(unsigned int scancode)
-{
-	return
-	  (scancode < SC_LIM || scancode > 255) ? -EINVAL :
-	  (scancode < 128) ? high_keys[scancode - SC_LIM] :
-	    e0_keys[scancode - 128];
-}
-
-int pckbd_translate(unsigned char scancode, unsigned char *keycode,
-		    char raw_mode)
-{
-	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) {
-	  /*
-	   * usually it will be 0xe0, but a Pause key generates
-	   * e1 1d 45 e1 9d c5 when pressed, and nothing when released
-	   */
-	  if (prev_scancode != 0xe0) {
-	      if (prev_scancode == 0xe1 && scancode == 0x1d) {
-		  prev_scancode = 0x100;
-		  return 0;
-	      } else if (prev_scancode == 0x100 && scancode == 0x45) {
-		  *keycode = E1_PAUSE;
-		  prev_scancode = 0;
-	      } else {
-#ifdef KBD_REPORT_UNKN
-		  if (!raw_mode)
-		    printk(KERN_INFO "keyboard: unknown e1 escape sequence\n");
-#endif
-		  prev_scancode = 0;
-		  return 0;
-	      }
-	  } else {
-	      prev_scancode = 0;
-	      /*
-	       *  The keyboard maintains its own internal caps lock and
-	       *  num lock statuses. In caps lock mode E0 AA precedes make
-	       *  code and E0 2A follows break code. In num lock mode,
-	       *  E0 2A precedes make code and E0 AA follows break code.
-	       *  We do our own book-keeping, so we will just ignore these.
-	       */
-	      /*
-	       *  For my keyboard there is no caps lock mode, but there are
-	       *  both Shift-L and Shift-R modes. The former mode generates
-	       *  E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs.
-	       *  So, we should also ignore the latter. - aeb@cwi.nl
-	       */
-	      if (scancode == 0x2a || scancode == 0x36)
-		return 0;
-
-	      if (e0_keys[scancode])
-		*keycode = e0_keys[scancode];
-	      else {
-#ifdef KBD_REPORT_UNKN
-		  if (!raw_mode)
-		    printk(KERN_INFO "keyboard: unknown scancode e0 %02x\n",
-			   scancode);
-#endif
-		  return 0;
-	      }
-	  }
-	} else if (scancode >= SC_LIM) {
-	    /* This happens with the FOCUS 9000 keyboard
-	       Its keys PF1..PF12 are reported to generate
-	       55 73 77 78 79 7a 7b 7c 74 7e 6d 6f
-	       Moreover, unless repeated, they do not generate
-	       key-down events, so we have to zero up_flag below */
-	    /* Also, Japanese 86/106 keyboards are reported to
-	       generate 0x73 and 0x7d for \ - and \ | respectively. */
-	    /* Also, some Brazilian keyboard is reported to produce
-	       0x73 and 0x7e for \ ? and KP-dot, respectively. */
-
-	  *keycode = high_keys[scancode - SC_LIM];
-
-	  if (!*keycode) {
-	      if (!raw_mode) {
-#ifdef KBD_REPORT_UNKN
-		  printk(KERN_INFO "keyboard: unrecognized scancode (%02x)"
-			 " - ignored\n", scancode);
-#endif
-	      }
-	      return 0;
-	  }
- 	} else
-	  *keycode = scancode;
-	
- 	return 1;
-}
-
-/* ----- end of stolen part ------ */
-
-
-void kbd_reset_setup(void) 
-{ 
-}
-
-void handle_at_scancode(int keyval)
-{
-	static int brk;
-	static int esc0;
-	static int esc1;
-	int scancode = 0;
-	
-	switch (keyval) {
-		case KBD_BREAK :  
-			/* sets the "release_key" bit when a key is 
-			   released. HP keyboard send f0 followed by 
-			   the keycode while AT keyboard send the keycode
-			   with this bit set. */
-			brk = 0x80;
-			return;
-		case KBD_ESCAPEE0 :
-			/* 2chars sequence, commonly used to differenciate 
-			   the two ALT keys and the two ENTER keys and so 
-			   on... */
-			esc0 = 2;	/* e0-xx are 2 chars */
-			scancode = keyval;
-			break;
-		case KBD_ESCAPEE1 :  
-			/* 3chars sequence, only used by the Pause key. */
-			esc1 = 3;	/* e1-xx-xx are 3 chars */
-			scancode = keyval;
-			break;
-#if 0
-		case KBD_RESEND :
-			/* dunno what to do when it happens. RFC */
-			printk(KERN_INFO "keyboard: KBD_RESEND received.\n");
-			return;
-#endif
-		case 0x14 : 
-			/* translate e1-14-77-e1-f0-14-f0-77 to 
-			   e1-1d-45-e1-9d-c5 (the Pause key) */
-			if (esc1==2) scancode = brk | 0x1d;
-			break;
-		case 0x77 :
-			if (esc1==1) scancode = brk | 0x45;
-			break;
-		case 0x12 :
-			/* an extended key is e0-12-e0-xx e0-f0-xx-e0-f0-12
-			   on HP, while it is e0-2a-e0-xx e0-(xx|80)-f0-aa 
-			   on AT. */
-			if (esc0==1) scancode = brk | 0x2a;
-			break;
-	}
-	
-
-	/* translates HP scancodes to AT scancodes */
-	if (!scancode) scancode = brk | keycode_translate[keyval];
-
-
-	if (!scancode) printk(KERN_INFO "keyboard: unexpected key code %02x\n",keyval);
-
-	/* now behave like an AT keyboard */
-	handle_scancode(scancode,!(scancode&0x80));
-
-	if (esc0) esc0--;
-	if (esc1) esc1--;
-
-	/* release key bit must be unset for the next key */
-	brk = 0;
-}
-
diff -Nru a/drivers/char/hp_psaux.c b/drivers/char/hp_psaux.c
--- a/drivers/char/hp_psaux.c	Mon Dec  9 18:46:51 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,551 +0,0 @@
-/*
- *      LASI PS/2 keyboard/psaux driver for HP-PARISC workstations
- *      
- *      (c) Copyright 1999 The Puffin Group Inc.
- *      by Alex deVries <adevries@thepuffingroup.com>
- *	Copyright 1999, 2000 Philipp Rumpf <prumpf@tux.org>
- *
- *	2000/10/26	Debacker Xavier (debackex@esiee.fr)
- *			Marteau Thomas (marteaut@esiee.fr)
- * 			Djoudi Malek (djoudim@esiee.fr)
- *	fixed leds control
- *	implemented the psaux and controlled the mouse scancode based on pc_keyb.c
- */
-
-#include <linux/config.h>
-
-#include <asm/hardware.h>
-#include <asm/keyboard.h>
-#include <asm/gsc.h>
-
-#include <linux/types.h>
-#include <linux/ptrace.h>	/* interrupt.h wants struct pt_regs defined */
-#include <linux/interrupt.h>
-#include <linux/sched.h>	/* for request_irq/free_irq */
-#include <linux/ioport.h>
-#include <linux/kernel.h>
-#include <linux/wait.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/pc_keyb.h>
-#include <linux/kbd_kern.h>
-
-/* mouse includes */
-#include <linux/miscdevice.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <asm/uaccess.h>
-#include <linux/poll.h>
-
-/* HP specific LASI PS/2 keyboard and psaux constants */
-#define	AUX_REPLY_ACK	0xFA	/* Command byte ACK. */
-#define	AUX_RECONNECT	0xAA	/* scancode when ps2 device is plugged (back) in */
-
-#define	LASI_PSAUX_OFFSET 0x0100 /* offset from keyboard to psaux port */
-
-#define	LASI_ID		0x00	/* ID and reset port offsets */
-#define	LASI_RESET	0x00
-#define	LASI_RCVDATA	0x04	/* receive and transmit port offsets */
-#define	LASI_XMTDATA	0x04
-#define	LASI_CONTROL	0x08	/* see: control register bits */
-#define	LASI_STATUS	0x0C	/* see: status register bits */
-
-/* control register bits */
-#define LASI_CTRL_ENBL	0x01	/* enable interface */
-#define LASI_CTRL_LPBXR	0x02	/* loopback operation */
-#define LASI_CTRL_DIAG	0x20	/* directly control clock/data line */
-#define LASI_CTRL_DATDIR 0x40	/* data line direct control */
-#define LASI_CTRL_CLKDIR 0x80	/* clock line direct control */
-
-/* status register bits */
-#define LASI_STAT_RBNE	0x01
-#define LASI_STAT_TBNE	0x02
-#define LASI_STAT_TERR	0x04
-#define LASI_STAT_PERR	0x08
-#define LASI_STAT_CMPINTR 0x10
-#define LASI_STAT_DATSHD 0x40
-#define LASI_STAT_CLKSHD 0x80
-
-static void *lasikbd_hpa;
-static void *lasips2_hpa;
-
-
-static inline u8 read_input(void *hpa)
-{
-	return gsc_readb(hpa+LASI_RCVDATA);
-}
-
-static inline u8 read_control(void *hpa)
-{
-        return gsc_readb(hpa+LASI_CONTROL);
-}
-
-static inline void write_control(u8 val, void *hpa)
-{
-	gsc_writeb(val, hpa+LASI_CONTROL);
-}
-
-static inline u8 read_status(void *hpa)
-{
-        return gsc_readb(hpa+LASI_STATUS);
-}
-
-static int write_output(u8 val, void *hpa)
-{
-	int wait = 0;
-
-	while (read_status(hpa) & LASI_STAT_TBNE) {
-		wait++;
-		if (wait>10000) {
-			/* printk(KERN_WARNING "Lasi PS/2 transmit buffer timeout\n"); */
-			return 0;
-		}
-	}
-
-	if (wait)
-		printk(KERN_DEBUG "Lasi PS/2 wait %d\n", wait);
-	
-	gsc_writeb(val, hpa+LASI_XMTDATA);
-
-	return 1;
-}
-
-/* This function is the PA-RISC adaptation of i386 source */
-
-static inline int aux_write_ack(u8 val)
-{
-      return write_output(val, lasikbd_hpa+LASI_PSAUX_OFFSET);
-}
-
-static void lasikbd_leds(unsigned char leds)
-{
-	write_output(KBD_CMD_SET_LEDS, lasikbd_hpa);
-	write_output(leds, lasikbd_hpa);
-	write_output(KBD_CMD_ENABLE, lasikbd_hpa);
-}
-
-#if 0
-/* this might become useful again at some point.  not now  -prumpf */
-int lasi_ps2_test(void *hpa)
-{
-	u8 control,c;
-	int i, ret = 0;
-
-	control = read_control(hpa);
-	write_control(control | LASI_CTRL_LPBXR | LASI_CTRL_ENBL, hpa);
-
-	for (i=0; i<256; i++) {
-		write_output(i, hpa);
-
-		while (!(read_status(hpa) & LASI_STAT_RBNE))
-		    /* just wait */;
-		    
-		c = read_input(hpa);
-		if (c != i)
-			ret--;
-	}
-
-	write_control(control, hpa);
-
-	return ret;
-}
-#endif 
-
-static int __init lasi_ps2_reset(void *hpa, int id)
-{
-	u8 control;
-	int ret = 1;
-
-	/* reset the interface */
-	gsc_writeb(0xff, hpa+LASI_RESET);
-	gsc_writeb(0x0 , hpa+LASI_RESET);		
-
-	/* enable it */
-	control = read_control(hpa);
-	write_control(control | LASI_CTRL_ENBL, hpa);
-
-        /* initializes the leds at the default state */
-        if (id==0) {
-           write_output(KBD_CMD_SET_LEDS, hpa);
-	   write_output(0, hpa);
-	   ret = write_output(KBD_CMD_ENABLE, hpa);
-	}
-
-	return ret;
-}
-
-static int inited;
-
-static void lasi_ps2_init_hw(void)
-{
-	++inited;
-}
-
-
-/* Greatly inspired by pc_keyb.c */
-
-/*
- * Wait for keyboard controller input buffer to drain.
- *
- * Don't use 'jiffies' so that we don't depend on
- * interrupts..
- *
- * Quote from PS/2 System Reference Manual:
- *
- * "Address hex 0060 and address hex 0064 should be written only when
- * the input-buffer-full bit and output-buffer-full bit in the
- * Controller Status register are set 0."
- */
-#ifdef CONFIG_PSMOUSE
-
-static struct aux_queue	*queue;
-static spinlock_t	kbd_controller_lock = SPIN_LOCK_UNLOCKED;
-static unsigned char	mouse_reply_expected;
-static int 		aux_count;
-
-static int fasync_aux(int fd, struct file *filp, int on)
-{
-	int retval;
-	
-	retval = fasync_helper(fd, filp, on, &queue->fasync);
-	if (retval < 0)
-		return retval;
-	
-	return 0;
-}
-
-
-
-static inline void handle_mouse_scancode(unsigned char scancode)
-{
-	if (mouse_reply_expected) {
-		if (scancode == AUX_REPLY_ACK) {
-			mouse_reply_expected--;
-			return;
-		}
-		mouse_reply_expected = 0;
-	}
-	else if (scancode == AUX_RECONNECT) {
-		queue->head = queue->tail = 0;  /* Flush input queue */
-		return;
-	}
-
-	add_mouse_randomness(scancode);
-	if (aux_count) {
-		int head = queue->head;
-				
-		queue->buf[head] = scancode;
-		head = (head + 1) & (AUX_BUF_SIZE-1);
-		
-		if (head != queue->tail) {
-			queue->head = head;
-			kill_fasync(&queue->fasync, SIGIO, POLL_IN);
-			wake_up_interruptible(&queue->proc_list);
-		}
-	}
-}
-
-static inline int queue_empty(void)
-{
-	return queue->head == queue->tail;
-}
-
-static unsigned char get_from_queue(void)
-{
-	unsigned char result;
-	unsigned long flags;
-
-	spin_lock_irqsave(&kbd_controller_lock, flags);
-	result = queue->buf[queue->tail];
-	queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
-	spin_unlock_irqrestore(&kbd_controller_lock, flags);
-
-	return result;
-}
-
-
-/*
- * Write to the aux device.
- */
-
-static ssize_t write_aux(struct file * file, const char * buffer,
-			 size_t count, loff_t *ppos)
-{
-	ssize_t retval = 0;
-
-	if (count) {
-		ssize_t written = 0;
-
-		if (count > 32)
-			count = 32; /* Limit to 32 bytes. */
-		do {
-			char c;
-			get_user(c, buffer++);
-			written++;
-		} while (--count);
-		retval = -EIO;
-		if (written) {
-			retval = written;
-			file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
-		}
-	}
-
-	return retval;
-}
-
-
-
-static ssize_t read_aux(struct file * file, char * buffer,
-			size_t count, loff_t *ppos)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t i = count;
-	unsigned char c;
-
-	if (queue_empty()) {
-		if (file->f_flags & O_NONBLOCK)
-			return -EAGAIN;
-		add_wait_queue(&queue->proc_list, &wait);
-repeat:
-		set_current_state(TASK_INTERRUPTIBLE);
-		if (queue_empty() && !signal_pending(current)) {
-			schedule();
-			goto repeat;
-		}
-		set_current_state(TASK_RUNNING);
-		remove_wait_queue(&queue->proc_list, &wait);
-	}
-	while (i > 0 && !queue_empty()) {
-		c = get_from_queue();
-		put_user(c, buffer++);
-		i--;
-	}
-	if (count-i) {
-		file->f_dentry->d_inode->i_atime = CURRENT_TIME;
-		return count-i;
-	}
-	if (signal_pending(current))
-		return -ERESTARTSYS;
-	return 0;
-}
-
-
-static int open_aux(struct inode * inode, struct file * file)
-{
-	if (aux_count++) 
-		return 0;
-
-	queue->head = queue->tail = 0;	/* Flush input queue */
-	aux_count = 1;
-	aux_write_ack(AUX_ENABLE_DEV);	/* Enable aux device */
-	
-	return 0;
-}
-
-
-/* No kernel lock held - fine */
-static unsigned int aux_poll(struct file *file, poll_table * wait)
-{
-
-	poll_wait(file, &queue->proc_list, wait);
-	if (!queue_empty())
-		return POLLIN | POLLRDNORM;
-	return 0;
-}
-
-
-static int release_aux(struct inode * inode, struct file * file)
-{
-	lock_kernel();
-	fasync_aux(-1, file, 0);
-	if (--aux_count) {
-	   unlock_kernel();
-		return 0;
-	}
-	unlock_kernel();
-	return 0;
-}
-
-static struct file_operations psaux_fops = {
-	.read		= read_aux,
-	.write		= write_aux,
-	.poll		= aux_poll,
-	.open		= open_aux,
-	.release	= release_aux,
-	.fasync		= fasync_aux,
-};
-
-static struct miscdevice psaux_mouse = {
-	.minor		= PSMOUSE_MINOR,
-	.name		= "psaux",
-	.fops		= &psaux_fops,
-};
-
-#endif /* CONFIG_PSMOUSE */
-
-
-/* This function is looking at the PS2 controller and empty the two buffers */
-
-static u8 handle_lasikbd_event(void *hpa)
-{
-        u8 status_keyb,status_mouse,scancode,id;
-        extern void handle_at_scancode(int); /* in drivers/char/keyb_at.c */
-        
-        /* Mask to get the base address of the PS/2 controller */
-        id = gsc_readb(hpa+LASI_ID) & 0x0f;
-        
-        if (id==1) 
-           hpa -= LASI_PSAUX_OFFSET; 
-        lasikbd_hpa = hpa;
-        
-
-        status_keyb = read_status(hpa);
-        status_mouse = read_status(hpa+LASI_PSAUX_OFFSET);
-
-        while ((status_keyb|status_mouse) & LASI_STAT_RBNE){
-           
-           while (status_keyb & LASI_STAT_RBNE) {
-	      
-              scancode = read_input(hpa);
-
-	      /* XXX don't know if this is a valid fix, but filtering
-	       * 0xfa avoids 'unknown scancode' errors on, eg, capslock
-	       * on some keyboards.
-	       */
-	      if (inited && scancode != 0xfa)
-		 handle_at_scancode(scancode); 
-	      
-	      status_keyb =read_status(hpa);
-           }
-	   
-#ifdef CONFIG_PSMOUSE
-           while (status_mouse & LASI_STAT_RBNE) {
-	      scancode = read_input(hpa+LASI_PSAUX_OFFSET);
-	      handle_mouse_scancode(scancode);
-              status_mouse = read_status(hpa+LASI_PSAUX_OFFSET);
-	   }
-           status_mouse = read_status(hpa+LASI_PSAUX_OFFSET);
-#endif /* CONFIG_PSMOUSE */
-           status_keyb = read_status(hpa);
-        }
-
-        tasklet_schedule(&keyboard_tasklet);
-        return (status_keyb|status_mouse);
-}
-
-
-
-	
-extern struct pt_regs *kbd_pt_regs;
-
-static void lasikbd_interrupt(int irq, void *dev, struct pt_regs *regs)
-{
-	lasips2_hpa = dev; /* save "hpa" for lasikbd_leds() */
-	kbd_pt_regs = regs;
-	handle_lasikbd_event(lasips2_hpa);
-}
-
-
-extern int pckbd_translate(unsigned char, unsigned char *, char);
-
-static struct kbd_ops gsc_ps2_kbd_ops = {
-	.translate	= pckbd_translate,
-	.init_hw	= lasi_ps2_init_hw,
-	.leds		= lasikbd_leds,
-#ifdef CONFIG_MAGIC_SYSRQ
-	.sysrq_key	= 0x54,
-	.sysrq_xlate	= hp_ps2kbd_sysrq_xlate,
-#endif
-};
-
-static int __init
-lasi_ps2_register(struct hp_device *d, struct pa_iodc_driver *dri)
-{
-	void *hpa = (void *) d->hpa;
-	unsigned int irq;
-	char *name;
-	int device_found;
-	u8 id;
-
-	id = gsc_readb(hpa+LASI_ID) & 0x0f;
-
-	switch (id) {
-	case 0:
-		name = "keyboard";
-		lasikbd_hpa = hpa;
-		break;
-	case 1:
-		name = "psaux";
-		break;
-	default:
-		printk(KERN_WARNING "%s: Unknown PS/2 port (id=%d) - ignored.\n",
-			__FUNCTION__, id );
-		return 0;
-	}
-	
-	/* reset the PS/2 port */
-	device_found = lasi_ps2_reset(hpa,id);
-
-	/* allocate the irq and memory region for that device */
-	if (!(irq = busdevice_alloc_irq(d)))
-		return -ENODEV;
-		    
-	if (request_irq(irq, lasikbd_interrupt, 0, name, hpa))
-		return -ENODEV;
-	
-	if (!request_mem_region((unsigned long)hpa, LASI_STATUS + 4, name))
-		return -ENODEV;
-
-	switch (id) {
-	case 0:	
-		register_kbd_ops(&gsc_ps2_kbd_ops);
-		break;
-	case 1:
-#ifdef CONFIG_PSMOUSE
-		queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
-		if (!queue)
-			return -ENOMEM;
-
-		memset(queue, 0, sizeof(*queue));
-		queue->head = queue->tail = 0;
-		init_waitqueue_head(&queue->proc_list);
-		
-		misc_register(&psaux_mouse);
-
-		aux_write_ack(AUX_ENABLE_DEV);
-		/* try it a second time, this will give status if the device is
-		 * available */
-		device_found = aux_write_ack(AUX_ENABLE_DEV);
-		break;
-#else
-		/* return without printing any unnecessary and misleading info */
-		return 0;	
-#endif
-	} /* of case */
-	
-	printk(KERN_INFO "PS/2 %s controller at 0x%08lx (irq %d) found, "
-			 "%sdevice attached.\n",
-			name, (unsigned long)hpa, irq,
-			device_found ? "":"no ");
-
-	return 0;
-}
-
-
-static struct pa_iodc_driver lasi_psaux_drivers_for[] __initdata = {
-	{HPHW_FIO, 0x0, 0,0x00084, 0, 0,
-		DRIVER_CHECK_HWTYPE + DRIVER_CHECK_SVERSION,
-		"Lasi psaux", "generic", (void *) lasi_ps2_register},
-	{ 0, }
-};
-
-static int __init gsc_ps2_init(void) 
-{
-	return pdc_register_driver(lasi_psaux_drivers_for);
-}
-
-module_init(gsc_ps2_init);
-
diff -Nru a/drivers/char/ip2/i2ellis.h b/drivers/char/ip2/i2ellis.h
--- a/drivers/char/ip2/i2ellis.h	Mon Dec  9 18:46:34 2002
+++ b/drivers/char/ip2/i2ellis.h	Mon Dec  9 18:46:34 2002
@@ -405,12 +405,6 @@
 
 	struct timer_list  SendPendingTimer;   // Used by iiSendPending
 	unsigned int	SendPendingRetry;
-
-#ifdef	CONFIG_DEVFS_FS
-	/* Device handles into devfs */
-	devfs_handle_t	devfs_ipl_handle;
-	devfs_handle_t	devfs_stat_handle;
-#endif
 } i2eBordStr, *i2eBordStrPtr;
 
 //-------------------------------------------------------------------
diff -Nru a/drivers/char/ip2main.c b/drivers/char/ip2main.c
--- a/drivers/char/ip2main.c	Mon Dec  9 18:46:52 2002
+++ b/drivers/char/ip2main.c	Mon Dec  9 18:46:52 2002
@@ -510,10 +510,8 @@
 			iiResetDelay( i2BoardPtrTable[i] );
 			/* free io addresses and Tibet */
 			release_region( ip2config.addr[i], 8 );
-#ifdef	CONFIG_DEVFS_FS
-			devfs_unregister (i2BoardPtrTable[i]->devfs_ipl_handle);
-			devfs_unregister (i2BoardPtrTable[i]->devfs_stat_handle);
-#endif
+			devfs_remove("ip2/ipl%d", i);
+			devfs_remove("ip2/stat%d", i);
 		}
 		/* Disable and remove interrupt handler. */
 		if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) {	
@@ -521,6 +519,7 @@
 			clear_requested_irq( ip2config.irq[i]);
 		}
 	}
+	devfs_remove("ip2");
 	if ( ( err = tty_unregister_driver ( &ip2_tty_driver ) ) ) {
 		printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err);
 	}
@@ -574,7 +573,6 @@
 ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) 
 {
 #ifdef	CONFIG_DEVFS_FS
-	static devfs_handle_t devfs_handle;
 	int j, box;
 #endif
 	int i;
@@ -869,10 +867,6 @@
 		/* Register the interrupt handler or poll handler, depending upon the
 		 * specified interrupt.
 		 */
-#ifdef	CONFIG_DEVFS_FS
-		if (!devfs_handle)
-			devfs_handle = devfs_mk_dir (NULL, "ip2", NULL);
-#endif
 
 		for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
 #ifdef	CONFIG_DEVFS_FS
@@ -885,17 +879,15 @@
 
 #ifdef	CONFIG_DEVFS_FS
 			if ( NULL != ( pB = i2BoardPtrTable[i] ) ) {
-				sprintf( name, "ipl%d", i );
-				pB->devfs_ipl_handle =
-					devfs_register (devfs_handle, name,
+				sprintf( name, "ip2/ipl%d", i );
+				devfs_register(NULL, name,
 						DEVFS_FL_DEFAULT,
 						IP2_IPL_MAJOR, 4 * i,
 						S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
 						&ip2_ipl, NULL);
 
-				sprintf( name, "stat%d", i );
-				pB->devfs_stat_handle =
-					devfs_register (devfs_handle, name,
+				sprintf( name, "ip2/stat%d", i );
+				devfs_register(NULL, name,
 						DEVFS_FL_DEFAULT,
 						IP2_IPL_MAJOR, 4 * i + 1,
 						S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
@@ -975,7 +967,7 @@
 static void __init
 ip2_init_board( int boardnum )
 {
-	int i,rc;
+	int i;
 	int nports = 0, nboxes = 0;
 	i2ChanStrPtr pCh;
 	i2eBordStrPtr pB = i2BoardPtrTable[boardnum];
diff -Nru a/drivers/char/isicom.c b/drivers/char/isicom.c
--- a/drivers/char/isicom.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/char/isicom.c	Mon Dec  9 18:46:34 2002
@@ -2008,11 +2008,12 @@
 	if (!(isi_card[0].base || isi_card[1].base || isi_card[2].base || isi_card[3].base)) {
 		printk(KERN_ERR "ISICOM: No valid card configuration. Driver cannot be initialized...\n"); 
 		return -EIO;
-	}		
-	retval=misc_register(&isiloader_device);
-	if (retval<0) {
+	}	
+
+	retval = misc_register(&isiloader_device);
+	if (retval < 0) {
 		printk(KERN_ERR "ISICOM: Unable to register firmware loader driver.\n");
-		return -EIO;
+		return retval;
 	}
 	
 	if (!isicom_init()) {
diff -Nru a/drivers/char/istallion.c b/drivers/char/istallion.c
--- a/drivers/char/istallion.c	Mon Dec  9 18:46:49 2002
+++ b/drivers/char/istallion.c	Mon Dec  9 18:46:49 2002
@@ -143,8 +143,6 @@
  */
 #define	STLI_EISAPROBE	0
 
-static devfs_handle_t devfs_handle;
-
 /*****************************************************************************/
 
 /*
@@ -798,7 +796,6 @@
  *	not increase character latency by much either...
  */
 static struct timer_list stli_timerlist = TIMER_INITIALIZER(stli_poll, 0, 0);
-};
 
 static int	stli_timeron;
 
@@ -815,7 +812,7 @@
  *	Loadable module initialization stuff.
  */
 
-int init_module()
+static int __init istallion_module_init(void)
 {
 	unsigned long	flags;
 
@@ -833,7 +830,7 @@
 
 /*****************************************************************************/
 
-void cleanup_module()
+static void __exit istallion_module_exit(void)
 {
 	stlibrd_t	*brdp;
 	stliport_t	*portp;
@@ -867,7 +864,9 @@
 		restore_flags(flags);
 		return;
 	}
-	devfs_unregister (devfs_handle);
+	for (i = 0; i < 4; i++)
+		devfs_remove("staliomem/%d", i);
+	devfs_remove("staliomem");
 	if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
 		printk("STALLION: failed to un-register serial memory device, "
 			"errno=%d\n", -i);
@@ -898,6 +897,9 @@
 	restore_flags(flags);
 }
 
+module_init(istallion_module_init);
+module_exit(istallion_module_exit);
+
 /*****************************************************************************/
 
 /*
@@ -5307,6 +5309,7 @@
 
 int __init stli_init(void)
 {
+	int i;
 	printk(KERN_INFO "%s: version %s\n", stli_drvtitle, stli_drvversion);
 
 	stli_initbrds();
@@ -5331,11 +5334,15 @@
 		printk(KERN_ERR "STALLION: failed to register serial memory "
 				"device\n");
 
-	devfs_handle = devfs_mk_dir (NULL, "staliomem", NULL);
-	devfs_register_series (devfs_handle, "%u", 4, DEVFS_FL_DEFAULT,
-			       STL_SIOMEMMAJOR, 0,
+	devfs_mk_dir (NULL, "staliomem", NULL);
+	for (i = 0; i < 4; i++) {
+		char name[16];
+		sprintf(name, "staliomem/%d", i);
+		devfs_register(NULL, name, DEVFS_FL_DEFAULT,
+			       STL_SIOMEMMAJOR, i,
 			       S_IFCHR | S_IRUSR | S_IWUSR,
 			       &stli_fsiomem, NULL);
+	}
 
 /*
  *	Set up the tty driver structure and register us as a driver.
diff -Nru a/drivers/char/keyboard.c b/drivers/char/keyboard.c
--- a/drivers/char/keyboard.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/char/keyboard.c	Mon Dec  9 18:46:36 2002
@@ -35,7 +35,6 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 
-#include <linux/console_struct.h>
 #include <linux/kbd_kern.h>
 #include <linux/kbd_diacr.h>
 #include <linux/vt_kern.h>
diff -Nru a/drivers/char/lp.c b/drivers/char/lp.c
--- a/drivers/char/lp.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/char/lp.c	Mon Dec  9 18:46:34 2002
@@ -141,8 +141,6 @@
 /* ROUND_UP macro from fs/select.c */
 #define ROUND_UP(x,y) (((x)+(y)-1)/(y))
 
-static devfs_handle_t devfs_handle = NULL;
-
 struct lp_struct lp_table[LP_NO];
 
 static unsigned int lp_count = 0;
@@ -792,7 +790,7 @@
 
 static int lp_register(int nr, struct parport *port)
 {
-	char name[8];
+	char name[16];
 
 	lp_table[nr].dev = parport_register_device(port, "lp", 
 						   lp_preempt, NULL, NULL, 0,
@@ -804,8 +802,8 @@
 	if (reset)
 		lp_reset(nr);
 
-	sprintf (name, "%d", nr);
-	devfs_register (devfs_handle, name,
+	sprintf (name, "printers/%d", nr);
+	devfs_register (NULL, name,
 			DEVFS_FL_DEFAULT, LP_MAJOR, nr,
 			S_IFCHR | S_IRUGO | S_IWUGO,
 			&lp_fops, NULL);
@@ -908,7 +906,7 @@
 		return -EIO;
 	}
 
-	devfs_handle = devfs_mk_dir (NULL, "printers", NULL);
+	devfs_mk_dir (NULL, "printers", NULL);
 
 	if (parport_register_driver (&lp_driver)) {
 		printk (KERN_ERR "lp: unable to register with parport\n");
@@ -964,13 +962,14 @@
 	unregister_console (&lpcons);
 #endif
 
-	devfs_unregister (devfs_handle);
 	unregister_chrdev(LP_MAJOR, "lp");
 	for (offset = 0; offset < LP_NO; offset++) {
 		if (lp_table[offset].dev == NULL)
 			continue;
 		parport_unregister_device(lp_table[offset].dev);
+		devfs_remove("printers/%d", offset);
 	}
+	devfs_remove("printers");
 }
 
 __setup("lp=", lp_setup);
diff -Nru a/drivers/char/mem.c b/drivers/char/mem.c
--- a/drivers/char/mem.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/char/mem.c	Mon Dec  9 18:46:37 2002
@@ -33,12 +33,6 @@
 #ifdef CONFIG_FB
 extern void fbmem_init(void);
 #endif
-#ifdef CONFIG_PROM_CONSOLE
-extern void prom_con_init(void);
-#endif
-#ifdef CONFIG_MDA_CONSOLE
-extern void mda_console_init(void);
-#endif
 #if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR)
 extern void tapechar_init(void);
 #endif
@@ -685,12 +679,6 @@
 #endif
 #if defined (CONFIG_FB)
 	fbmem_init();
-#endif
-#if defined (CONFIG_PROM_CONSOLE)
-	prom_con_init();
-#endif
-#if defined (CONFIG_MDA_CONSOLE)
-	mda_console_init();
 #endif
 	tty_init();
 #ifdef CONFIG_M68K_PRINTER
diff -Nru a/drivers/char/mxser.c b/drivers/char/mxser.c
--- a/drivers/char/mxser.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/char/mxser.c	Mon Dec  9 18:46:50 2002
@@ -328,13 +328,7 @@
  * static functions:
  */
 
-#ifdef MODULE
-int init_module(void);
-void cleanup_module(void);
-#endif
-
 static void mxser_getcfg(int board, struct mxser_hwconf *hwconf);
-int mxser_init(void);
 static int mxser_get_ISA_conf(int, struct mxser_hwconf *);
 static int mxser_get_PCI_conf(struct pci_dev *, int, struct mxser_hwconf *);
 static void mxser_do_softint(void *);
@@ -373,21 +367,7 @@
  * The MOXA C168/C104 serial driver boot-time initialization code!
  */
 
-
-#ifdef MODULE
-int init_module(void)
-{
-	int ret;
-
-	if (verbose)
-		printk("Loading module mxser ...\n");
-	ret = mxser_init();
-	if (verbose)
-		printk("Done.\n");
-	return (ret);
-}
-
-void cleanup_module(void)
+static void __exit mxser_module_exit(void)
 {
 	int i, err = 0;
 
@@ -411,8 +391,6 @@
 		printk("Done.\n");
 
 }
-#endif
-
 
 int mxser_initbrd(int board, struct mxser_hwconf *hwconf)
 {
@@ -510,7 +488,7 @@
 	return (0);
 }
 
-int mxser_init(void)
+static int __init mxser_module_init(void)
 {
 	int i, m, retval, b;
 	int n, index;
@@ -2493,3 +2471,6 @@
 	}
 	outb(0x00, port + 4);
 }
+
+module_init(mxser_module_init);
+module_exit(mxser_module_exit);
diff -Nru a/drivers/char/ppdev.c b/drivers/char/ppdev.c
--- a/drivers/char/ppdev.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/char/ppdev.c	Mon Dec  9 18:46:51 2002
@@ -749,20 +749,22 @@
 	.release	= pp_release,
 };
 
-static devfs_handle_t devfs_handle;
-
 static int __init ppdev_init (void)
 {
+	int i;
+
 	if (register_chrdev (PP_MAJOR, CHRDEV, &pp_fops)) {
 		printk (KERN_WARNING CHRDEV ": unable to get major %d\n",
 			PP_MAJOR);
 		return -EIO;
 	}
-	devfs_handle = devfs_mk_dir (NULL, "parports", NULL);
-	devfs_register_series (devfs_handle, "%u", PARPORT_MAX,
-			       DEVFS_FL_DEFAULT, PP_MAJOR, 0,
-			       S_IFCHR | S_IRUGO | S_IWUGO,
-			       &pp_fops, NULL);
+	devfs_mk_dir (NULL, "parports", NULL);
+	for (i = 0; i < PARPORT_MAX; i++) {
+		char name[16];
+		sprintf(name, "parports/%d", i);
+		devfs_register(NULL, name, DEVFS_FL_DEFAULT, PP_MAJOR, i,
+			       S_IFCHR | S_IRUGO | S_IWUGO, &pp_fops, NULL);
+	}
 
 	printk (KERN_INFO PP_VERSION "\n");
 	return 0;
@@ -770,8 +772,11 @@
 
 static void __exit ppdev_cleanup (void)
 {
+	int i;
 	/* Clean up all parport stuff */
-	devfs_unregister (devfs_handle);
+	for (i = 0; i < PARPORT_MAX; i++)
+		devfs_remove("parports/%d", i);
+	devfs_remove("parports");
 	unregister_chrdev (PP_MAJOR, CHRDEV);
 }
 
diff -Nru a/drivers/char/qtronix.c b/drivers/char/qtronix.c
--- a/drivers/char/qtronix.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/char/qtronix.c	Mon Dec  9 18:46:36 2002
@@ -585,7 +585,12 @@
 
 static int __init psaux_init(void)
 {
-	misc_register(&psaux_mouse);
+	int retval;
+
+	retval = misc_register(&psaux_mouse);
+	if(retval < 0)
+		return retval;
+
 	queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
 	memset(queue, 0, sizeof(*queue));
 	queue->head = queue->tail = 0;
diff -Nru a/drivers/char/random.c b/drivers/char/random.c
--- a/drivers/char/random.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/char/random.c	Mon Dec  9 18:46:34 2002
@@ -128,7 +128,6 @@
  * 	void add_keyboard_randomness(unsigned char scancode);
  * 	void add_mouse_randomness(__u32 mouse_data);
  * 	void add_interrupt_randomness(int irq);
- * 	void add_blkdev_randomness(int irq);
  * 
  * add_keyboard_randomness() uses the inter-keypress timing, as well as the
  * scancode as random inputs into the "entropy pool".
@@ -143,8 +142,6 @@
  * regular, and hence predictable to an attacker.  Disk interrupts are
  * a better measure, since the timing of the disk interrupts are more
  * unpredictable.
- * 
- * add_blkdev_randomness() times the finishing time of block requests.
  * 
  * All of these routines try to estimate how many bits of randomness a
  * particular randomness source.  They do this by keeping track of the
diff -Nru a/drivers/char/raw.c b/drivers/char/raw.c
--- a/drivers/char/raw.c	Mon Dec  9 18:46:39 2002
+++ b/drivers/char/raw.c	Mon Dec  9 18:46:39 2002
@@ -104,7 +104,7 @@
 {
 	struct block_device *bdev = filp->private_data;
 
-	return blkdev_ioctl(bdev->bd_inode, NULL, command, arg);
+	return ioctl_by_bdev(bdev, command, arg);
 }
 
 /*
@@ -242,3 +242,4 @@
 
 module_init(raw_init);
 module_exit(raw_exit);
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c
--- a/drivers/char/scx200_gpio.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/char/scx200_gpio.c	Mon Dec  9 18:46:34 2002
@@ -6,6 +6,7 @@
    Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> */
 
 #include <linux/config.h>
+#include <linux/fs.h>
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
diff -Nru a/drivers/char/selection.c b/drivers/char/selection.c
--- a/drivers/char/selection.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/char/selection.c	Mon Dec  9 18:46:51 2002
@@ -22,7 +22,6 @@
 
 #include <linux/vt_kern.h>
 #include <linux/consolemap.h>
-#include <linux/console_struct.h>
 #include <linux/selection.h>
 
 #ifndef MIN
diff -Nru a/drivers/char/sonypi.h b/drivers/char/sonypi.h
--- a/drivers/char/sonypi.h	Mon Dec  9 18:46:38 2002
+++ b/drivers/char/sonypi.h	Mon Dec  9 18:46:38 2002
@@ -37,7 +37,7 @@
 #ifdef __KERNEL__
 
 #define SONYPI_DRIVER_MAJORVERSION	 1
-#define SONYPI_DRIVER_MINORVERSION	15
+#define SONYPI_DRIVER_MINORVERSION	16
 
 #define SONYPI_DEVICE_MODEL_TYPE1	1
 #define SONYPI_DEVICE_MODEL_TYPE2	2
@@ -165,6 +165,7 @@
 #define SONYPI_ZOOM_MASK			0x00000100
 #define SONYPI_THUMBPHRASE_MASK			0x00000200
 #define SONYPI_MEYE_MASK			0x00000400
+#define SONYPI_MEMORYSTICK_MASK			0x00000800
 
 struct sonypi_event {
 	u8	data;
@@ -262,7 +263,7 @@
 
 /* The set of possible zoom events */
 static struct sonypi_event sonypi_zoomev[] = {
-	{ 0x3a, SONYPI_EVENT_ZOOM_PRESSED },
+	{ 0x39, SONYPI_EVENT_ZOOM_PRESSED },
 	{ 0, 0 }
 };
 
@@ -279,6 +280,13 @@
 	{ 0, 0 }
 };
 
+/* The set of possible memorystick events */
+static struct sonypi_event sonypi_memorystickev[] = {
+	{ 0x53, SONYPI_EVENT_MEMORYSTICK_INSERT },
+	{ 0x54, SONYPI_EVENT_MEMORYSTICK_EJECT },
+	{ 0, 0 }
+};
+
 struct sonypi_eventtypes {
 	int			model;
 	u8			data;
@@ -303,6 +311,7 @@
 	{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_HELP_MASK, sonypi_helpev },
 	{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_ZOOM_MASK, sonypi_zoomev },
 	{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev },
+	{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
 
 	{ 0, 0, 0, 0 }
 };
diff -Nru a/drivers/char/stallion.c b/drivers/char/stallion.c
--- a/drivers/char/stallion.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/char/stallion.c	Mon Dec  9 18:46:50 2002
@@ -751,15 +751,13 @@
 
 /*****************************************************************************/
 
-static devfs_handle_t devfs_handle;
-
 #ifdef MODULE
 
 /*
  *	Loadable module initialization stuff.
  */
 
-int init_module()
+static int __init stallion_module_init(void)
 {
 	unsigned long	flags;
 
@@ -777,7 +775,7 @@
 
 /*****************************************************************************/
 
-void cleanup_module()
+static void __exit stallion_module_exit(void)
 {
 	stlbrd_t	*brdp;
 	stlpanel_t	*panelp;
@@ -809,7 +807,9 @@
 		restore_flags(flags);
 		return;
 	}
-	devfs_unregister (devfs_handle);
+	for (i = 0; i < 4; i++)
+		devfs_remove("staliomem/%d", i);
+	devfs_remove("staliomem");
 	if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
 		printk("STALLION: failed to un-register serial memory device, "
 			"errno=%d\n", -i);
@@ -851,6 +851,9 @@
 	restore_flags(flags);
 }
 
+module_init(stallion_module_init);
+module_exit(stallion_module_exit);
+
 /*****************************************************************************/
 
 /*
@@ -3191,6 +3194,7 @@
 
 int __init stl_init(void)
 {
+	int i;
 	printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion);
 
 	stl_initbrds();
@@ -3209,11 +3213,15 @@
  */
 	if (register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stl_fsiomem))
 		printk("STALLION: failed to register serial board device\n");
-	devfs_handle = devfs_mk_dir (NULL, "staliomem", NULL);
-	devfs_register_series (devfs_handle, "%u", 4, DEVFS_FL_DEFAULT,
-			       STL_SIOMEMMAJOR, 0,
+	devfs_mk_dir (NULL, "staliomem", NULL);
+	for (i = 0; i < 4; i++) {
+		char name[16];
+		sprintf(name, "staliomem/%d", i);
+		devfs_register(NULL, name, DEVFS_FL_DEFAULT,
+			       STL_SIOMEMMAJOR, i,
 			       S_IFCHR | S_IRUSR | S_IWUSR,
 			       &stl_fsiomem, NULL);
+	}
 
 /*
  *	Set up the tty driver structure and register us as a driver.
diff -Nru a/drivers/char/sx.h b/drivers/char/sx.h
--- a/drivers/char/sx.h	Mon Dec  9 18:46:35 2002
+++ b/drivers/char/sx.h	Mon Dec  9 18:46:35 2002
@@ -44,7 +44,7 @@
   int poll;
   int ta_type;
   struct timer_list       timer;
-  int                     locks;
+  long                    locks;
 };
 
 struct vpd_prom {
diff -Nru a/drivers/char/tipar.c b/drivers/char/tipar.c
--- a/drivers/char/tipar.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/char/tipar.c	Mon Dec  9 18:46:50 2002
@@ -90,7 +90,6 @@
 static int delay = IO_DELAY;	/* inter-bit delay in microseconds */
 static int timeout = TIMAXTIME;	/* timeout in tenth of seconds     */
 
-static devfs_handle_t devfs_handle;
 static unsigned int tp_count;	/* tipar count */
 static unsigned long opened;	/* opened devices */
 
@@ -422,7 +421,7 @@
 static int
 tipar_register(int nr, struct parport *port)
 {
-	char name[8];
+	char name[32];
 
 	/* Register our module into parport */
 	table[nr].dev = parport_register_device(port, "tipar",
@@ -433,11 +432,11 @@
 		return 1;
 
 	/* Use devfs, tree: /dev/ticables/par/[0..2] */
-	sprintf(name, "%d", nr);
+	sprintf(name, "ticables/par/%d", nr);
 	printk
 	    ("tipar: registering to devfs : major = %d, minor = %d, node = %s\n",
 	     TISER_MAJOR, (TIPAR_MINOR + nr), name);
-	devfs_register(devfs_handle, name, DEVFS_FL_DEFAULT, TIPAR_MAJOR,
+	devfs_register(NULL, name, DEVFS_FL_DEFAULT, TIPAR_MAJOR,
 		       TIPAR_MINOR + nr, S_IFCHR | S_IRUGO | S_IWUGO,
 		       &tipar_fops, NULL);
 
@@ -491,7 +490,7 @@
 	}
 
 	/* Use devfs with tree: /dev/ticables/par/[0..2] */
-	devfs_handle = devfs_mk_dir(NULL, "ticables/par", NULL);
+	devfs_mk_dir(NULL, "ticables/par", NULL);
 
 	if (parport_register_driver(&tipar_driver)) {
 		printk("tipar: unable to register with parport\n");
@@ -509,14 +508,15 @@
 	/* Unregistering module */
 	parport_unregister_driver(&tipar_driver);
 
-	devfs_unregister(devfs_handle);
 	unregister_chrdev(TIPAR_MAJOR, "tipar");
 
 	for (i = 0; i < PP_NO; i++) {
 		if (table[i].dev == NULL)
 			continue;
 		parport_unregister_device(table[i].dev);
+		devfs_remove("ticables/par/%d", i);
 	}
+	devfs_remove("ticables/par");
 
 	printk("tipar: module unloaded !\n");
 }
diff -Nru a/drivers/char/toshiba.c b/drivers/char/toshiba.c
--- a/drivers/char/toshiba.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/char/toshiba.c	Mon Dec  9 18:46:51 2002
@@ -210,7 +210,7 @@
 /*
  * Put the laptop into System Management Mode
  */
-static int tosh_smm(SMMRegisters *regs)
+int tosh_smm(SMMRegisters *regs)
 {
 	int eax;
 
diff -Nru a/drivers/char/tty_io.c b/drivers/char/tty_io.c
--- a/drivers/char/tty_io.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/char/tty_io.c	Mon Dec  9 18:46:38 2002
@@ -372,6 +372,8 @@
 	return -ERESTARTSYS;
 }
 
+EXPORT_SYMBOL(tty_check_change);
+
 static ssize_t hung_up_tty_read(struct file * file, char * buf,
 				size_t count, loff_t *ppos)
 {
@@ -540,6 +542,8 @@
 	schedule_work(&tty->hangup_work);
 }
 
+EXPORT_SYMBOL(tty_hangup);
+
 void tty_vhangup(struct tty_struct * tty)
 {
 #ifdef TTY_DEBUG_HANGUP
@@ -556,6 +560,8 @@
 	return (filp->f_op == &hung_up_tty_fops);
 }
 
+EXPORT_SYMBOL(tty_hung_up_p);
+
 /*
  * This function is typically called only by the session leader, when
  * it wants to disassociate itself from its controlling tty.
@@ -1503,6 +1509,13 @@
 		return -EFAULT;
 	if (!memcmp(&tmp_ws, &tty->winsize, sizeof(*arg)))
 		return 0;
+#ifdef CONFIG_VT
+	if (tty->driver.type == TTY_DRIVER_TYPE_CONSOLE) {
+		unsigned int currcons = minor(tty->device) - tty->driver.minor_start;
+		if (vc_resize(currcons, tmp_ws.ws_col, tmp_ws.ws_row))
+			return -ENXIO;
+	}
+#endif
 	if (tty->pgrp > 0)
 		kill_pg(tty->pgrp, SIGWINCH, 1);
 	if ((real_tty->pgrp != tty->pgrp) && (real_tty->pgrp > 0))
@@ -1886,6 +1899,8 @@
 	schedule_work(&tty->SAK_work);
 }
 
+EXPORT_SYMBOL(do_SAK);
+
 /*
  * This routine is called out of the software interrupt to flush data
  * from the flip buffer to the line discipline.
@@ -1946,34 +1961,44 @@
 #endif
 };
 
-static int n_baud_table = sizeof(baud_table)/sizeof(int);
+static int n_baud_table = ARRAY_SIZE(baud_table);
 
-int tty_get_baud_rate(struct tty_struct *tty)
+int tty_termios_baud_rate(struct termios *termios)
 {
-	unsigned int cflag, i;
+	unsigned int cbaud = termios->c_cflag & CBAUD;
 
-	cflag = tty->termios->c_cflag;
+	if (cbaud & CBAUDEX) {
+		cbaud &= ~CBAUDEX;
 
-	i = cflag & CBAUD;
-	if (i & CBAUDEX) {
-		i &= ~CBAUDEX;
-		if (i < 1 || i+15 >= n_baud_table) 
-			tty->termios->c_cflag &= ~CBAUDEX;
+		if (cbaud < 1 || cbaud + 15 > n_baud_table)
+			termios->c_cflag &= ~CBAUDEX;
 		else
-			i += 15;
+			cbaud += 15;
 	}
-	if (i==15 && tty->alt_speed) {
+
+	return baud_table[cbaud];
+}
+
+EXPORT_SYMBOL(tty_termios_baud_rate);
+
+int tty_get_baud_rate(struct tty_struct *tty)
+{
+	int baud = tty_termios_baud_rate(tty->termios);
+
+	if (baud == 38400 && tty->alt_speed) {
 		if (!tty->warned) {
 			printk(KERN_WARNING "Use of setserial/setrocket to "
 					    "set SPD_* flags is deprecated\n");
 			tty->warned = 1;
 		}
-		return(tty->alt_speed);
+		baud = tty->alt_speed;
 	}
 	
-	return baud_table[i];
+	return baud;
 }
 
+EXPORT_SYMBOL(tty_get_baud_rate);
+
 void tty_flip_buffer_push(struct tty_struct *tty)
 {
 	if (tty->low_latency)
@@ -2204,7 +2229,7 @@
 #ifdef CONFIG_TN3270_CONSOLE
 	tub3270_con_init();
 #endif
-#ifdef CONFIG_TN3215
+#ifdef CONFIG_TN3215_CONSOLE
 	con3215_init();
 #endif
 #ifdef CONFIG_SCLP_CONSOLE
@@ -2345,10 +2370,7 @@
 #ifdef CONFIG_TN3270
 	tub3270_init();
 #endif
-#ifdef CONFIG_TN3215
-	tty3215_init();
-#endif
-#ifdef CONFIG_SCLP
+#ifdef CONFIG_SCLP_TTY
 	sclp_tty_init();
 #endif
 #ifdef CONFIG_A2232
diff -Nru a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
--- a/drivers/char/vc_screen.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/char/vc_screen.c	Mon Dec  9 18:46:35 2002
@@ -32,7 +32,6 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/vt_kern.h>
-#include <linux/console_struct.h>
 #include <linux/selection.h>
 #include <linux/kbd_kern.h>
 #include <linux/console.h>
diff -Nru a/drivers/char/vt.c b/drivers/char/vt.c
--- a/drivers/char/vt.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/char/vt.c	Mon Dec  9 18:46:51 2002
@@ -90,7 +90,6 @@
 #include <linux/devfs_fs_kernel.h>
 #include <linux/vt_kern.h>
 #include <linux/selection.h>
-#include <linux/console_struct.h>
 #include <linux/kbd_kern.h>
 #include <linux/consolemap.h>
 #include <linux/timer.h>
@@ -127,6 +126,15 @@
 
 extern void vcs_make_devfs (unsigned int index, int unregister);
 extern void console_map_init(void);
+#ifdef CONFIG_PROM_CONSOLE
+extern void prom_con_init(void);
+#endif
+#ifdef CONFIG_MDA_CONSOLE
+extern void mda_console_init(void);
+#endif
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE
+extern int fb_console_init(void);
+#endif
 
 static struct tty_struct *console_table[MAX_NR_CONSOLES];
 static struct termios *console_termios[MAX_NR_CONSOLES];
@@ -691,106 +699,106 @@
 	return 0;
 }
 
+inline int resize_screen(int currcons, int width, int height)
+{
+	/* Resizes the resolution of the display adapater */
+	int err = 0;
+
+	if (vcmode != KD_GRAPHICS && sw->con_resize)
+		err = sw->con_resize(vc_cons[currcons].d, width, height);
+	return err;
+}
+
 /*
  * Change # of rows and columns (0 means unchanged/the size of fg_console)
  * [this is to be used together with some user program
  * like resize that changes the hardware videomode]
  */
-int vc_resize(unsigned int lines, unsigned int cols,
-	      unsigned int first, unsigned int last)
+int vc_resize(int currcons, unsigned int cols, unsigned int lines)
 {
-	unsigned int cc, ll, ss, sr, todo = 0;
-	unsigned int currcons = fg_console, i;
-	unsigned short *newscreens[MAX_NR_CONSOLES];
-
-	cc = (cols ? cols : video_num_columns);
-	ll = (lines ? lines : video_num_lines);
-	sr = cc << 1;
-	ss = sr * ll;
-
- 	for (currcons = first; currcons <= last; currcons++) {
-		if (!vc_cons_allocated(currcons) ||
-		    (cc == video_num_columns && ll == video_num_lines))
-			newscreens[currcons] = NULL;
-		else {
-			unsigned short *p = (unsigned short *) kmalloc(ss, GFP_USER);
-			if (!p) {
-				for (i = first; i < currcons; i++)
-					if (newscreens[i])
-						kfree(newscreens[i]);
-				return -ENOMEM;
-			}
-			newscreens[currcons] = p;
-			todo++;
-		}
-	}
-	if (!todo)
+	unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0;
+	unsigned int old_cols, old_rows, old_row_size, old_screen_size;
+	unsigned int new_cols, new_rows, new_row_size, new_screen_size;
+	unsigned short *newscreen;
+
+	if (!vc_cons_allocated(currcons))
+		return -ENXIO;
+
+	new_cols = (cols ? cols : video_num_columns);
+	new_rows = (lines ? lines : video_num_lines);
+	new_row_size = new_cols << 1;
+	new_screen_size = new_row_size * new_rows;
+
+	if (new_cols == video_num_columns && new_rows == video_num_lines)
 		return 0;
 
-	for (currcons = first; currcons <= last; currcons++) {
-		unsigned int occ, oll, oss, osr;
-		unsigned long ol, nl, nlend, rlth, rrem;
-		if (!newscreens[currcons] || !vc_cons_allocated(currcons))
-			continue;
+	newscreen = (unsigned short *) kmalloc(new_screen_size, GFP_USER);
+	if (!newscreen)
+		return -ENOMEM;
 
-		oll = video_num_lines;
-		occ = video_num_columns;
-		osr = video_size_row;
-		oss = screenbuf_size;
-
-		video_num_lines = ll;
-		video_num_columns = cc;
-		video_size_row = sr;
-		screenbuf_size = ss;
-
-		rlth = min(osr, sr);
-		rrem = sr - rlth;
-		ol = origin;
-		nl = (long) newscreens[currcons];
-		nlend = nl + ss;
-		if (ll < oll)
-			ol += (oll - ll) * osr;
-
-		update_attr(currcons);
-
-		while (ol < scr_end) {
-			scr_memcpyw((unsigned short *) nl, (unsigned short *) ol, rlth);
-			if (rrem)
-				scr_memsetw((void *)(nl + rlth), video_erase_char, rrem);
-			ol += osr;
-			nl += sr;
-		}
-		if (nlend > nl)
-			scr_memsetw((void *) nl, video_erase_char, nlend - nl);
-		if (kmalloced)
-			kfree(screenbuf);
-		screenbuf = newscreens[currcons];
-		kmalloced = 1;
-		screenbuf_size = ss;
-		set_origin(currcons);
+	old_rows = video_num_lines;
+	old_cols = video_num_columns;
+	old_row_size = video_size_row;
+	old_screen_size = screenbuf_size;
+
+	video_num_lines = new_rows;
+	video_num_columns = new_cols;
+	video_size_row = new_row_size;
+	screenbuf_size = new_screen_size;
+
+	err = resize_screen(currcons, new_cols, new_rows);
+	if (err)
+		return err;
+
+	rlth = min(old_row_size, new_row_size);
+	rrem = new_row_size - rlth;
+	old_origin = origin;
+	new_origin = (long) newscreen;
+	new_scr_end = new_origin + new_screen_size;
+	if (new_rows < old_rows)
+		old_origin += (old_rows - new_rows) * old_row_size;
 
-		/* do part of a reset_terminal() */
-		top = 0;
-		bottom = video_num_lines;
-		gotoxy(currcons, x, y);
-		save_cur(currcons);
-
-		if (console_table[currcons]) {
-			struct winsize ws, *cws = &console_table[currcons]->winsize;
-			memset(&ws, 0, sizeof(ws));
-			ws.ws_row = video_num_lines;
-			ws.ws_col = video_num_columns;
-			if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col) &&
-			    console_table[currcons]->pgrp > 0)
-				kill_pg(console_table[currcons]->pgrp, SIGWINCH, 1);
-			*cws = ws;
-		}
+	update_attr(currcons);
 
-		if (IS_VISIBLE)
-			update_screen(currcons);
+	while (old_origin < scr_end) {
+		scr_memcpyw((unsigned short *) new_origin, (unsigned short *) old_origin, rlth);
+		if (rrem)
+			scr_memsetw((void *)(new_origin + rlth), video_erase_char, rrem);
+		old_origin += old_row_size;
+		new_origin += new_row_size;
+	}
+	if (new_scr_end > new_origin)
+		scr_memsetw((void *) new_origin, video_erase_char, new_scr_end - new_origin);
+	if (kmalloced)
+		kfree(screenbuf);
+	screenbuf = newscreen;
+	kmalloced = 1;
+	screenbuf_size = new_screen_size;
+	if (IS_VISIBLE)
+		err = resize_screen(currcons, new_cols, new_rows);
+	set_origin(currcons);
+
+	/* do part of a reset_terminal() */
+	top = 0;
+	bottom = video_num_lines;
+	gotoxy(currcons, x, y);
+	save_cur(currcons);
+
+	if (vc_cons[currcons].d->vc_tty) {
+		struct winsize ws, *cws = &vc_cons[currcons].d->vc_tty->winsize;
+
+		memset(&ws, 0, sizeof(ws));
+		ws.ws_row = video_num_lines;
+		ws.ws_col = video_num_columns;
+		if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col) &&
+		    vc_cons[currcons].d->vc_tty->pgrp > 0)
+			kill_pg(vc_cons[currcons].d->vc_tty->pgrp, SIGWINCH, 1);
+		*cws = ws;
 	}
 
-	return 0;
+	if (IS_VISIBLE)
+		update_screen(currcons);
+	return err;
 }
 
 
@@ -1200,7 +1208,7 @@
 			case 3:	/* 80/132 mode switch unimplemented */
 				deccolm = on_off;
 #if 0
-				(void) vc_resize(video_num_lines, deccolm ? 132 : 80);
+				(void) vc_resize(deccolm ? 132 : 80, video_num_lines);
 				/* this alone does not suffice; some user mode
 				   utility has to change the hardware regs */
 #endif
@@ -2525,6 +2533,15 @@
 
 	kbd_init();
 	console_map_init();
+#ifdef CONFIG_PROM_CONSOLE
+	prom_con_init();
+#endif
+#ifdef CONFIG_MDA_CONSOLE
+	mda_console_init();
+#endif
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE
+	fb_console_init();
+#endif	
 	con_init_devfs();
 	vcs_init();
 	return 0;
@@ -2629,7 +2646,7 @@
 	int i;
 
 	for (i = 0; i < console_driver.num; i++)
-		tty_register_devfs (&console_driver, DEVFS_FL_AOPEN_NOTIFY,
+		tty_register_devfs (&console_driver, DEVFS_FL_DEFAULT,
 				    console_driver.minor_start + i);
 }
 
@@ -3021,10 +3038,15 @@
 EXPORT_SYMBOL(default_blu);
 EXPORT_SYMBOL(video_font_height);
 EXPORT_SYMBOL(video_scan_lines);
+EXPORT_SYMBOL(vc_cons_allocated);
+EXPORT_SYMBOL(update_region);
+EXPORT_SYMBOL(redraw_screen);
 EXPORT_SYMBOL(vc_resize);
 EXPORT_SYMBOL(fg_console);
 EXPORT_SYMBOL(console_blank_hook);
+EXPORT_SYMBOL(console_blanked);
 EXPORT_SYMBOL(vt_cons);
+EXPORT_SYMBOL(vc_cons);
 #ifndef VT_SINGLE_DRIVER
 EXPORT_SYMBOL(take_over_console);
 EXPORT_SYMBOL(give_up_console);
diff -Nru a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
--- a/drivers/char/vt_ioctl.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/char/vt_ioctl.c	Mon Dec  9 18:46:50 2002
@@ -810,7 +810,9 @@
 		if (get_user(ll, &vtsizes->v_rows) ||
 		    get_user(cc, &vtsizes->v_cols))
 			return -EFAULT;
-		return vc_resize_all(ll, cc);
+		for (i = 0; i < MAX_NR_CONSOLES; i++)
+                        vc_resize(i, cc, ll);
+		return 0;
 	}
 
 	case VT_RESIZEX:
@@ -829,37 +831,33 @@
 		__get_user(vcol, &vtconsize->v_vcol);
 		__get_user(ccol, &vtconsize->v_ccol);
 		vlin = vlin ? vlin : video_scan_lines;
-		if ( clin )
-		  {
-		    if ( ll )
-		      {
-			if ( ll != vlin/clin )
-			  return -EINVAL; /* Parameters don't add up */
-		      }
-		    else 
-		      ll = vlin/clin;
-		  }
-		if ( vcol && ccol )
-		  {
-		    if ( cc )
-		      {
-			if ( cc != vcol/ccol )
-			  return -EINVAL;
-		      }
-		    else
-		      cc = vcol/ccol;
-		  }
+		if (clin) {
+			if (ll) {
+				if (ll != vlin/clin)
+					return -EINVAL; /* Parameters don't add up */
+			} else 
+				ll = vlin/clin;
+		}
+		if (vcol && ccol) {
+			if (cc) {
+				if (cc != vcol/ccol)
+					return -EINVAL;
+			} else
+				cc = vcol/ccol;
+		}
 
-		if ( clin > 32 )
-		  return -EINVAL;
+		if (clin > 32)
+			return -EINVAL;
 		    
-		if ( vlin )
-		  video_scan_lines = vlin;
-		if ( clin )
-		  video_font_height = clin;
-		
-		return vc_resize_all(ll, cc);
-  	}
+		if (vlin)
+			video_scan_lines = vlin;
+		if (clin)
+			video_font_height = clin;
+	
+		for (i = 0; i < MAX_NR_CONSOLES; i++)
+			vc_resize(i, cc, ll);
+  		return 0;
+	}
 
 	case PIO_FONT: {
 		struct console_font_op op;
diff -Nru a/drivers/char/watchdog/sbc60xxwdt.c b/drivers/char/watchdog/sbc60xxwdt.c
--- a/drivers/char/watchdog/sbc60xxwdt.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/char/watchdog/sbc60xxwdt.c	Mon Dec  9 18:46:50 2002
@@ -345,7 +345,7 @@
 	release_region(WDT_START,1);
 err_out_region1:
 	release_region(WDT_STOP,1);
-err_out:
+/* err_out: */
 	return rc;
 }
 
diff -Nru a/drivers/hotplug/Makefile b/drivers/hotplug/Makefile
--- a/drivers/hotplug/Makefile	Mon Dec  9 18:46:50 2002
+++ b/drivers/hotplug/Makefile	Mon Dec  9 18:46:50 2002
@@ -8,13 +8,17 @@
 obj-$(CONFIG_HOTPLUG_PCI_COMPAQ)	+= cpqphp.o
 obj-$(CONFIG_HOTPLUG_PCI_IBM)		+= ibmphp.o
 obj-$(CONFIG_HOTPLUG_PCI_ACPI)		+= acpiphp.o
-obj-$(CONFIG_HOTPLUG_PCI_CPCI)		+= cpci_hotplug.o
 obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550)	+= cpcihp_zt5550.o
 obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC)	+= cpcihp_generic.o
 
 pci_hotplug-objs	:=	pci_hotplug_core.o	\
 				pci_hotplug_util.o
 
+ifdef CONFIG_HOTPLUG_PCI_CPCI
+pci_hotplug-objs	+=	cpci_hotplug_core.o	\
+				cpci_hotplug_pci.o
+endif
+
 cpqphp-objs		:=	cpqphp_core.o	\
 				cpqphp_ctrl.o	\
 				cpqphp_proc.o	\
@@ -30,9 +34,6 @@
 				acpiphp_glue.o	\
 				acpiphp_pci.o	\
 				acpiphp_res.o
-
-cpci_hotplug-objs	:=	cpci_hotplug_core.o	\
-				cpci_hotplug_pci.o
 
 ifdef CONFIG_HOTPLUG_PCI_ACPI
   EXTRA_CFLAGS  += -D_LINUX -I$(TOPDIR)/drivers/acpi
diff -Nru a/drivers/hotplug/cpci_hotplug_core.c b/drivers/hotplug/cpci_hotplug_core.c
--- a/drivers/hotplug/cpci_hotplug_core.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/hotplug/cpci_hotplug_core.c	Mon Dec  9 18:46:36 2002
@@ -891,16 +891,17 @@
 	return;
 }
 
-static int __init
-cpci_hotplug_init(void)
+int __init
+cpci_hotplug_init(int debug)
 {
 	spin_lock_init(&list_lock);
+	cpci_debug = debug;
 
 	info(DRIVER_DESC " version: " DRIVER_VERSION);
 	return 0;
 }
 
-static void __exit
+void __exit
 cpci_hotplug_exit(void)
 {
 	/*
@@ -909,14 +910,6 @@
 	cleanup_slots();
 }
 
-module_init(cpci_hotplug_init);
-module_exit(cpci_hotplug_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-MODULE_PARM(cpci_debug, "i");
-MODULE_PARM_DESC(cpci_debug, "Debugging mode");
 
 EXPORT_SYMBOL_GPL(cpci_hp_register_controller);
 EXPORT_SYMBOL_GPL(cpci_hp_unregister_controller);
diff -Nru a/drivers/hotplug/cpci_hotplug_pci.c b/drivers/hotplug/cpci_hotplug_pci.c
--- a/drivers/hotplug/cpci_hotplug_pci.c	Mon Dec  9 18:46:49 2002
+++ b/drivers/hotplug/cpci_hotplug_pci.c	Mon Dec  9 18:46:49 2002
@@ -572,16 +572,16 @@
 }
 
 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_ebda.c b/drivers/hotplug/ibmphp_ebda.c
--- a/drivers/hotplug/ibmphp_ebda.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/hotplug/ibmphp_ebda.c	Mon Dec  9 18:46:35 2002
@@ -1240,11 +1240,11 @@
 
 static struct pci_device_id id_table[] __devinitdata = {
 	{
-		vendor:		PCI_VENDOR_ID_IBM,
-		device:		HPC_DEVICE_ID,
-		subvendor:	PCI_VENDOR_ID_IBM,
-		subdevice:	HPC_SUBSYSTEM_ID,
-		class:		((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),
+		.vendor		= PCI_VENDOR_ID_IBM,
+		.device		= HPC_DEVICE_ID,
+		.subvendor	= PCI_VENDOR_ID_IBM,
+		.subdevice	= HPC_SUBSYSTEM_ID,
+		.class		= ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),
 	}, {}
 };		
 
@@ -1252,9 +1252,9 @@
 
 static int ibmphp_probe (struct pci_dev *, const struct pci_device_id *);
 static struct pci_driver ibmphp_driver = {
-	name:		"ibmphp",
-	id_table:	id_table,
-	probe:		ibmphp_probe,
+	.name		= "ibmphp",
+	.id_table	= id_table,
+	.probe		= ibmphp_probe,
 };
 
 int ibmphp_register_pci (void)
diff -Nru a/drivers/hotplug/pci_hotplug_core.c b/drivers/hotplug/pci_hotplug_core.c
--- a/drivers/hotplug/pci_hotplug_core.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/hotplug/pci_hotplug_core.c	Mon Dec  9 18:46:50 2002
@@ -60,8 +60,8 @@
 /* local variables */
 static int debug;
 
-#define DRIVER_VERSION	"0.4"
-#define DRIVER_AUTHOR	"Greg Kroah-Hartman <greg@kroah.com>"
+#define DRIVER_VERSION	"0.5"
+#define DRIVER_AUTHOR	"Greg Kroah-Hartman <greg@kroah.com>, Scott Murray <scottm@somanetworks.com>"
 #define DRIVER_DESC	"PCI Hot Plug PCI Core"
 
 
@@ -89,7 +89,7 @@
 static spinlock_t mount_lock;		/* protects our mount_count */
 static spinlock_t list_lock;
 
-LIST_HEAD(pci_hotplug_slot_list);
+static LIST_HEAD(pci_hotplug_slot_list);
 
 /* these strings match up with the values in pci_bus_speed */
 static char *pci_bus_speed_strings[] = {
@@ -121,6 +121,14 @@
 static const char *slotdir_name = "slots";
 #endif
 
+#ifdef CONFIG_HOTPLUG_PCI_CPCI
+extern int cpci_hotplug_init(int debug);
+extern void cpci_hotplug_exit(void);
+#else
+static inline int cpci_hotplug_init(int debug) { return 0; }
+static inline void cpci_hotplug_exit(void) { }
+#endif
+
 static struct inode *pcihpfs_get_inode (struct super_block *sb, int mode, dev_t dev)
 {
 	struct inode *inode = new_inode(sb);
@@ -311,19 +319,19 @@
 /* file ops for the "max bus speed" files */
 static ssize_t max_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
 static struct file_operations max_bus_speed_file_operations = {
-	read:		max_bus_speed_read_file,
-	write:		default_write_file,
-	open:		default_open,
-	llseek:		default_file_lseek,
+	.read		= max_bus_speed_read_file,
+	.write		= default_write_file,
+	.open		= default_open,
+	.llseek		= default_file_lseek,
 };
 
 /* file ops for the "current bus speed" files */
 static ssize_t cur_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
 static struct file_operations cur_bus_speed_file_operations = {
-	read:		cur_bus_speed_read_file,
-	write:		default_write_file,
-	open:		default_open,
-	llseek:		default_file_lseek,
+	.read		= cur_bus_speed_read_file,
+	.write		= default_write_file,
+	.open		= default_open,
+	.llseek		= default_file_lseek,
 };
 
 /* file ops for the "test" files */
@@ -1273,19 +1281,30 @@
 		goto exit;
 	}
 
+	result = cpci_hotplug_init(debug);
+	if (result) {
+		err ("cpci_hotplug_init with error %d\n", result);
+		goto error_fs;
+	}
+
 #ifdef CONFIG_PROC_FS
 	/* create mount point for pcihpfs */
 	slotdir = proc_mkdir(slotdir_name, proc_bus_pci_dir);
 #endif
 
 	info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
-
+	goto exit;
+	
+error_fs:
+	unregister_filesystem(&pcihpfs_type);
 exit:
 	return result;
 }
 
 static void __exit pci_hotplug_exit (void)
 {
+	cpci_hotplug_exit();
+
 	unregister_filesystem(&pcihpfs_type);
 
 #ifdef CONFIG_PROC_FS
diff -Nru a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
--- a/drivers/i2c/i2c-dev.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/i2c/i2c-dev.c	Mon Dec  9 18:46:50 2002
@@ -37,9 +37,7 @@
 #include <linux/slab.h>
 #include <linux/version.h>
 #include <linux/smp_lock.h>
-#ifdef CONFIG_DEVFS_FS
 #include <linux/devfs_fs_kernel.h>
-#endif
 
 
 /* If you want debugging uncomment: */
@@ -80,10 +78,6 @@
 
 #define I2CDEV_ADAPS_MAX I2C_ADAP_MAX
 static struct i2c_adapter *i2cdev_adaps[I2CDEV_ADAPS_MAX];
-#ifdef CONFIG_DEVFS_FS
-static devfs_handle_t devfs_i2c[I2CDEV_ADAPS_MAX];
-static devfs_handle_t devfs_handle = NULL;
-#endif
 
 static struct i2c_driver i2cdev_driver = {
 	.name		= "i2c-dev dummy driver",
@@ -101,8 +95,6 @@
 	.driver		= &i2cdev_driver,
 };
 
-static int i2cdev_initialized;
-
 static ssize_t i2cdev_read (struct file *file, char *buf, size_t count,
                             loff_t *offset)
 {
@@ -399,7 +391,7 @@
 int i2cdev_attach_adapter(struct i2c_adapter *adap)
 {
 	int i;
-	char name[8];
+	char name[12];
 
 	if ((i = i2c_adapter_id(adap)) < 0) {
 		printk(KERN_DEBUG "i2c-dev.o: Unknown adapter ?!?\n");
@@ -410,21 +402,17 @@
 		return -ENODEV;
 	}
 
-	sprintf (name, "%d", i);
+	sprintf (name, "i2c/%d", i);
 	if (! i2cdev_adaps[i]) {
 		i2cdev_adaps[i] = adap;
-#ifdef CONFIG_DEVFS_FS
-		devfs_i2c[i] = devfs_register (devfs_handle, name,
+		devfs_register (NULL, name,
 			DEVFS_FL_DEFAULT, I2C_MAJOR, i,
 			S_IFCHR | S_IRUSR | S_IWUSR,
 			&i2cdev_fops, NULL);
-#endif
 		printk(KERN_DEBUG "i2c-dev.o: Registered '%s' as minor %d\n",adap->name,i);
 	} else {
 		/* This is actually a detach_adapter call! */
-#ifdef CONFIG_DEVFS_FS
-		devfs_unregister(devfs_i2c[i]);
-#endif
+		devfs_remove("i2c/%d", i);
 		i2cdev_adaps[i] = NULL;
 #ifdef DEBUG
 		printk(KERN_DEBUG "i2c-dev.o: Adapter unregistered: %s\n",adap->name);
@@ -449,24 +437,13 @@
 {
 	int res;
 
-	if (i2cdev_initialized >= 2) {
-		if ((res = i2c_del_driver(&i2cdev_driver))) {
-			printk(KERN_ERR "i2c-dev.o: Driver deregistration failed, "
-			       "module not removed.\n");
-		}
-	i2cdev_initialized --;
+	if ((res = i2c_del_driver(&i2cdev_driver))) {
+		printk(KERN_ERR "i2c-dev.o: Driver deregistration failed, "
+		       "module not removed.\n");
 	}
 
-	if (i2cdev_initialized >= 1) {
-#ifdef CONFIG_DEVFS_FS
-		devfs_unregister(devfs_handle);
-#endif
-		if ((res = unregister_chrdev(I2C_MAJOR,"i2c"))) {
-			printk(KERN_ERR "i2c-dev.o: unable to release major %d for i2c bus\n",
-			       I2C_MAJOR);
-		}
-		i2cdev_initialized --;
-	}
+	devfs_remove("i2c");
+	unregister_chrdev(I2C_MAJOR,"i2c");
 }
 
 int __init i2c_dev_init(void)
@@ -475,23 +452,18 @@
 
 	printk(KERN_INFO "i2c-dev.o: i2c /dev entries driver module version %s (%s)\n", I2C_VERSION, I2C_DATE);
 
-	i2cdev_initialized = 0;
 	if (register_chrdev(I2C_MAJOR,"i2c",&i2cdev_fops)) {
 		printk(KERN_ERR "i2c-dev.o: unable to get major %d for i2c bus\n",
 		       I2C_MAJOR);
 		return -EIO;
 	}
-#ifdef CONFIG_DEVFS_FS
-	devfs_handle = devfs_mk_dir(NULL, "i2c", NULL);
-#endif
-	i2cdev_initialized ++;
-
+	devfs_mk_dir(NULL, "i2c", NULL);
 	if ((res = i2c_add_driver(&i2cdev_driver))) {
 		printk(KERN_ERR "i2c-dev.o: Driver registration failed, module not inserted.\n");
-		i2cdev_cleanup();
+		devfs_remove("i2c");
+		unregister_chrdev(I2C_MAJOR,"i2c");
 		return res;
 	}
-	i2cdev_initialized ++;
 	return 0;
 }
 
diff -Nru a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
--- a/drivers/ide/ide-floppy.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/ide/ide-floppy.c	Mon Dec  9 18:46:37 2002
@@ -115,10 +115,10 @@
 /* #define IDEFLOPPY_DEBUG(fmt, args...) printk(KERN_INFO fmt, ## args) */
 #define IDEFLOPPY_DEBUG( fmt, args... )
 
-#ifndef IDEFLOPPY_DEBUG_LOG
-#define debug_log(fmt, args... ) do {} while(0)
-#else
+#if IDEFLOPPY_DEBUG_LOG
 #define debug_log printk
+#else
+#define debug_log(fmt, args... ) do {} while(0)
 #endif
 
 
diff -Nru a/drivers/ide/ide-geometry.c b/drivers/ide/ide-geometry.c
--- a/drivers/ide/ide-geometry.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/ide/ide-geometry.c	Mon Dec  9 18:46:50 2002
@@ -6,83 +6,6 @@
 #include <linux/mc146818rtc.h>
 #include <asm/io.h>
 
-/*
- * We query CMOS about hard disks : it could be that we have a SCSI/ESDI/etc
- * controller that is BIOS compatible with ST-506, and thus showing up in our
- * BIOS table, but not register compatible, and therefore not present in CMOS.
- *
- * Furthermore, we will assume that our ST-506 drives <if any> are the primary
- * drives in the system -- the ones reflected as drive 1 or 2.  The first
- * drive is stored in the high nibble of CMOS byte 0x12, the second in the low
- * nibble.  This will be either a 4 bit drive type or 0xf indicating use byte
- * 0x19 for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.  A non-zero value
- * means we have an AT controller hard disk for that drive.
- *
- * Of course, there is no guarantee that either drive is actually on the
- * "primary" IDE interface, but we don't bother trying to sort that out here.
- * If a drive is not actually on the primary interface, then these parameters
- * will be ignored.  This results in the user having to supply the logical
- * drive geometry as a boot parameter for each drive not on the primary i/f.
- *
- * The only "perfect" way to handle this would be to modify the setup.[cS] code
- * to do BIOS calls Int13h/Fn08h and Int13h/Fn48h to get all of the drive info
- * for us during initialization.  I have the necessary docs -- any takers?  -ml
- *
- * I did this, but it doesn't work - there is no reasonable way to find the
- * correspondence between the BIOS numbering of the disks and the Linux
- * numbering. -aeb
- *
- * The code below is bad. One of the problems is that drives 1 and 2
- * may be SCSI disks (even when IDE disks are present), so that
- * the geometry we read here from BIOS is attributed to the wrong disks.
- * Consequently, also the former "drive->present = 1" below was a mistake.
- *
- * Eventually the entire routine below should be removed.
- *
- * 17-OCT-2000 rjohnson@analogic.com Added spin-locks for reading CMOS
- * chip.
- */
-
-void probe_cmos_for_drives (ide_hwif_t *hwif)
-{
-#ifdef __i386__
-	extern struct drive_info_struct drive_info;
-	u8 cmos_disks, *BIOS = (u8 *) &drive_info;
-	int unit;
-	unsigned long flags;
-
-	if (hwif->chipset == ide_pdc4030 && hwif->channel != 0)
-		return;
-
-	spin_lock_irqsave(&rtc_lock, flags);
-	cmos_disks = CMOS_READ(0x12);
-	spin_unlock_irqrestore(&rtc_lock, flags);
-	/* Extract drive geometry from CMOS+BIOS if not already setup */
-	for (unit = 0; unit < MAX_DRIVES; ++unit) {
-		ide_drive_t *drive = &hwif->drives[unit];
-
-		if ((cmos_disks & (0xf0 >> (unit*4)))
-		   && !drive->present && !drive->nobios) {
-			u16 cyl = *(u16 *)BIOS;
-			unsigned char head = *(BIOS+2);
-			unsigned char sect = *(BIOS+14);
-			if (cyl > 0 && head > 0 && sect > 0 && sect < 64) {
-				drive->cyl   = drive->bios_cyl  = cyl;
-				drive->head  = drive->bios_head = head;
-				drive->sect  = drive->bios_sect = sect;
-				drive->ctl   = *(BIOS+8);
-			} else {
-				printk("hd%c: C/H/S=%d/%d/%d from BIOS ignored\n",
-				       unit+'a', cyl, head, sect);
-			}
-		}
-
-		BIOS += 16;
-	}
-#endif
-}
-
-
 extern unsigned long current_capacity (ide_drive_t *);
 
 /*
diff -Nru a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
--- a/drivers/ide/ide-probe.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/ide/ide-probe.c	Mon Dec  9 18:46:38 2002
@@ -639,12 +639,6 @@
 
 	if (hwif->noprobe)
 		return;
-#ifdef CONFIG_BLK_DEV_IDE
-	if (hwif->io_ports[IDE_DATA_OFFSET] == HD_DATA) {
-		extern void probe_cmos_for_drives(ide_hwif_t *);
-		probe_cmos_for_drives(hwif);
-	}
-#endif
 
 	if ((hwif->chipset != ide_4drives || !hwif->mate || !hwif->mate->present) &&
 #if CONFIG_BLK_DEV_PDC4030
diff -Nru a/drivers/ide/ide.c b/drivers/ide/ide.c
--- a/drivers/ide/ide.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/ide/ide.c	Mon Dec  9 18:46:35 2002
@@ -2346,11 +2346,9 @@
 /*
  * Probe module
  */
-devfs_handle_t ide_devfs_handle;
 
 EXPORT_SYMBOL(ide_lock);
 EXPORT_SYMBOL(ide_probe);
-EXPORT_SYMBOL(ide_devfs_handle);
 
 struct bus_type ide_bus_type = {
 	.name		= "ide",
@@ -2364,7 +2362,7 @@
 	static char banner_printed;
 	if (!banner_printed) {
 		printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n");
-		ide_devfs_handle = devfs_mk_dir(NULL, "ide", NULL);
+		devfs_mk_dir(NULL, "ide", NULL);
 		system_bus_speed = ide_system_bus_speed();
 		banner_printed = 1;
 	}
@@ -2420,7 +2418,7 @@
 #ifdef CONFIG_PROC_FS
 	proc_ide_destroy();
 #endif
-	devfs_unregister (ide_devfs_handle);
+	devfs_remove("ide");
 
 	bus_unregister(&ide_bus_type);
 }
diff -Nru a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
--- a/drivers/ieee1394/sbp2.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/ieee1394/sbp2.c	Mon Dec  9 18:46:35 2002
@@ -320,7 +320,6 @@
 #include <linux/blk.h>
 #include <linux/smp_lock.h>
 #include <linux/init.h>
-#include <linux/blk.h>
 #include <asm/current.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
diff -Nru a/drivers/input/gameport/ns558.c b/drivers/input/gameport/ns558.c
--- a/drivers/input/gameport/ns558.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/input/gameport/ns558.c	Mon Dec  9 18:46:50 2002
@@ -37,7 +37,7 @@
 #include <linux/init.h>
 #include <linux/gameport.h>
 #include <linux/slab.h>
-#include <linux/isapnp.h>
+#include <linux/pnp.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 MODULE_DESCRIPTION("Classic gameport (ISA/PnP) driver");
@@ -52,7 +52,7 @@
 struct ns558 {
 	int type;
 	int size;
-	struct pci_dev *dev;
+	struct pnp_dev *dev;
 	struct list_head node;
 	struct gameport gameport;
 	char phys[32];
@@ -159,67 +159,55 @@
 	list_add(&port->node, &ns558_list);
 }
 
-#ifdef __ISAPNP__
+#ifdef CONFIG_PNP
 
-#define NS558_DEVICE(a,b,c,d)\
-	.card_vendor = ISAPNP_ANY_ID, card_device: ISAPNP_ANY_ID,\
-	.vendor = ISAPNP_VENDOR(a,b,c), function: ISAPNP_DEVICE(d)
-
-static struct isapnp_device_id pnp_devids[] = {
-	{ NS558_DEVICE('@','P','@',0x0001) }, /* ALS 100 */
-	{ NS558_DEVICE('@','P','@',0x0020) }, /* ALS 200 */
-	{ NS558_DEVICE('@','P','@',0x1001) }, /* ALS 100+ */
-	{ NS558_DEVICE('@','P','@',0x2001) }, /* ALS 120 */
-	{ NS558_DEVICE('A','S','B',0x16fd) }, /* AdLib NSC16 */
-	{ NS558_DEVICE('A','Z','T',0x3001) }, /* AZT1008 */
-	{ NS558_DEVICE('C','D','C',0x0001) }, /* Opl3-SAx */
-	{ NS558_DEVICE('C','S','C',0x0001) }, /* CS4232 */
-	{ NS558_DEVICE('C','S','C',0x000f) }, /* CS4236 */
-	{ NS558_DEVICE('C','S','C',0x0101) }, /* CS4327 */
-	{ NS558_DEVICE('C','T','L',0x7001) }, /* SB16 */
-	{ NS558_DEVICE('C','T','L',0x7002) }, /* AWE64 */
-	{ NS558_DEVICE('C','T','L',0x7005) }, /* Vibra16 */
-	{ NS558_DEVICE('E','N','S',0x2020) }, /* SoundscapeVIVO */
-	{ NS558_DEVICE('E','S','S',0x0001) }, /* ES1869 */
-	{ NS558_DEVICE('E','S','S',0x0005) }, /* ES1878 */
-	{ NS558_DEVICE('E','S','S',0x6880) }, /* ES688 */
-	{ NS558_DEVICE('I','B','M',0x0012) }, /* CS4232 */
-	{ NS558_DEVICE('O','P','T',0x0001) }, /* OPTi Audio16 */
-	{ NS558_DEVICE('Y','M','H',0x0006) }, /* Opl3-SA */
-	{ NS558_DEVICE('Y','M','H',0x0022) }, /* Opl3-SAx */
-	{ NS558_DEVICE('P','N','P',0xb02f) }, /* Generic */
-	{ 0, },
+static struct pnp_device_id pnp_devids[] = {
+	{ .id = "@P@0001", .driver_data = 0 }, /* ALS 100 */
+	{ .id = "@P@0020", .driver_data = 0 }, /* ALS 200 */
+	{ .id = "@P@1001", .driver_data = 0 }, /* ALS 100+ */
+	{ .id = "@P@2001", .driver_data = 0 }, /* ALS 120 */
+	{ .id = "ASB16fd", .driver_data = 0 }, /* AdLib NSC16 */
+	{ .id = "AZT3001", .driver_data = 0 }, /* AZT1008 */
+	{ .id = "CDC0001", .driver_data = 0 }, /* Opl3-SAx */
+	{ .id = "CSC0001", .driver_data = 0 }, /* CS4232 */
+	{ .id = "CSC000f", .driver_data = 0 }, /* CS4236 */
+	{ .id = "CSC0101", .driver_data = 0 }, /* CS4327 */
+	{ .id = "CTL7001", .driver_data = 0 }, /* SB16 */
+	{ .id = "CTL7002", .driver_data = 0 }, /* AWE64 */
+	{ .id = "CTL7005", .driver_data = 0 }, /* Vibra16 */
+	{ .id = "ENS2020", .driver_data = 0 }, /* SoundscapeVIVO */
+	{ .id = "ESS0001", .driver_data = 0 }, /* ES1869 */
+	{ .id = "ESS0005", .driver_data = 0 }, /* ES1878 */
+	{ .id = "ESS6880", .driver_data = 0 }, /* ES688 */
+	{ .id = "IBM0012", .driver_data = 0 }, /* CS4232 */
+	{ .id = "OPT0001", .driver_data = 0 }, /* OPTi Audio16 */
+	{ .id = "YMH0006", .driver_data = 0 }, /* Opl3-SA */
+	{ .id = "YMH0022", .driver_data = 0 }, /* Opl3-SAx */
+	{ .id = "PNPb02f", .driver_data = 0 }, /* Generic */
+	{ .id = "", },
 };
 
-MODULE_DEVICE_TABLE(isapnp, pnp_devids);
+MODULE_DEVICE_TABLE(pnp, pnp_devids);
 
-static void ns558_pnp_probe(struct pci_dev *dev)
+static int ns558_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *did)
 {
 	int ioport, iolen;
 	struct ns558 *port;
 
-	if (dev->prepare && dev->prepare(dev) < 0)
-		return;
-
 	if (!(dev->resource[0].flags & IORESOURCE_IO)) {
 		printk(KERN_WARNING "ns558: No i/o ports on a gameport? Weird\n");
-		return;
+		return -ENODEV;
 	}
 
-	if (dev->activate && dev->activate(dev) < 0) {
-		printk(KERN_ERR "ns558: PnP resource allocation failed\n");
-		return;
-	}
-	
-	ioport = pci_resource_start(dev, 0);
-	iolen = pci_resource_len(dev, 0);
+	ioport = pnp_port_start(dev,0);
+	iolen = pnp_port_len(dev,0);
 
 	if (!request_region(ioport, iolen, "ns558-pnp"))
-		goto deactivate;
+		return -EBUSY;
 
 	if (!(port = kmalloc(sizeof(struct ns558), GFP_KERNEL))) {
 		printk(KERN_ERR "ns558: Memory allocation failed.\n");
-		goto deactivate;
+		return -ENOMEM;
 	}
 	memset(port, 0, sizeof(struct ns558));
 
@@ -231,54 +219,46 @@
 	port->gameport.phys = port->phys;
 	port->gameport.name = port->name;
 	port->gameport.id.bustype = BUS_ISAPNP;
-	port->gameport.id.vendor = dev->vendor;
-	port->gameport.id.product = dev->device;
 	port->gameport.id.version = 0x100;
 
-	sprintf(port->phys, "isapnp%d.%d/gameport0", PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+	sprintf(port->phys, "pnp%s/gameport0", dev->dev.bus_id);
 	sprintf(port->name, "%s", dev->dev.name[0] ? dev->dev.name : "NS558 PnP Gameport");
 
 	gameport_register_port(&port->gameport);
 
-	printk(KERN_INFO "gameport: NS558 PnP at isapnp%d.%d io %#x",
-		PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), port->gameport.io);
+	printk(KERN_INFO "gameport: NS558 PnP at pnp%s io %#x",
+		dev->dev.bus_id, port->gameport.io);
 	if (iolen > 1) printk(" size %d", iolen);
 	printk(" speed %d kHz\n", port->gameport.speed);
 
 	list_add_tail(&port->node, &ns558_list);
-	return;
-
-deactivate:
-	if (dev->deactivate)
-		dev->deactivate(dev);
+	return 0;
 }
+
+static struct pnp_driver ns558_pnp_driver = {
+	.name		= "ns558",
+	.id_table	= pnp_devids,
+	.probe		= ns558_pnp_probe,
+};
+
+#else
+
+static const struct pnp_driver ns558_pnp_driver;
+
 #endif
 
 int __init ns558_init(void)
 {
 	int i = 0;
-#ifdef __ISAPNP__
-	struct isapnp_device_id *devid;
-	struct pci_dev *dev = NULL;
-#endif
 
 /*
  * Probe for ISA ports.
  */
 
-	while (ns558_isa_portlist[i]) 
+	while (ns558_isa_portlist[i])
 		ns558_isa_probe(ns558_isa_portlist[i++]);
 
-/*
- * Probe for PnP ports.
- */
-
-#ifdef __ISAPNP__
-	for (devid = pnp_devids; devid->vendor; devid++)
-		while ((dev = isapnp_find_dev(NULL, devid->vendor, devid->function, dev)))
-			ns558_pnp_probe(dev);
-#endif
-
+	pnp_register_driver(&ns558_pnp_driver);
 	return list_empty(&ns558_list) ? -ENODEV : 0;
 }
 
@@ -290,13 +270,10 @@
 		gameport_unregister_port(&port->gameport);
 		switch (port->type) {
 
-#ifdef __ISAPNP__
+#ifdef CONFIG_PNP
 			case NS558_PNP:
-				if (port->dev->deactivate)
-					port->dev->deactivate(port->dev);
 				/* fall through */
 #endif
-
 			case NS558_ISA:
 				release_region(port->gameport.io, port->size);
 				break;
@@ -305,6 +282,7 @@
 				break;
 		}
 	}
+	pnp_unregister_driver(&ns558_pnp_driver);
 }
 
 module_init(ns558_init);
diff -Nru a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
--- a/drivers/input/misc/Kconfig	Mon Dec  9 18:46:36 2002
+++ b/drivers/input/misc/Kconfig	Mon Dec  9 18:46:36 2002
@@ -56,3 +56,12 @@
 	  The module will be called uinput.o.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.	    
 
+config INPUT_GSC
+	tristate "PA-RISC GSC PS/2 keyboard/mouse support"
+	depends on GSC && INPUT && INPUT_MISC
+	help
+	  Say Y here if you have a PS/2 keyboard and/or mouse attached
+	  to your PA-RISC box.	HP run the keyboard in AT mode rather than
+	  XT mode like everyone else, so we need our own driver.
+	  Furthermore, the GSC PS/2 controller shares IRQ between mouse and
+	  keyboard.
diff -Nru a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
--- a/drivers/input/misc/Makefile	Mon Dec  9 18:46:38 2002
+++ b/drivers/input/misc/Makefile	Mon Dec  9 18:46:38 2002
@@ -8,7 +8,4 @@
 obj-$(CONFIG_INPUT_PCSPKR)		+= pcspkr.o
 obj-$(CONFIG_INPUT_M68K_BEEP)		+= m68kspkr.o
 obj-$(CONFIG_INPUT_UINPUT)		+= uinput.o
-
-# The global Rules.make.
-
-include $(TOPDIR)/Rules.make
+obj-$(CONFIG_INPUT_GSC)			+= gsc_ps2.o
diff -Nru a/drivers/input/misc/gsc_ps2.c b/drivers/input/misc/gsc_ps2.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/input/misc/gsc_ps2.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,699 @@
+/*
+ * drivers/input/misc/gsc_ps2.c
+ *
+ * Copyright (c) 2002 Laurent Canet <canetl@esiee.fr>
+ * Copyright (c) 2002 Thibaut Varene <varenet@esiee.fr>
+ *
+ * Pieces of code based on linux-2.4's hp_mouse.c & hp_keyb.c
+ * 	Copyright (c) 1999 Alex deVries <adevries@thepuffingroup.com>
+ *	Copyright (c) 1999-2000 Philipp Rumpf <prumpf@tux.org>
+ *	Copyright (c) 2000 Xavier Debacker <debackex@esiee.fr>
+ *	Copyright (c) 2000-2001 Thomas Marteau <marteaut@esiee.fr>
+ *
+ * HP PS/2 Keyboard, found in PA/RISC Workstations
+ * very similar to AT keyboards, but without i8042
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 
+ * STATUS:
+ * 11/09: lc: Only basic keyboard is supported, mouse still needs to be done.
+ * 11/12: tv: switching iomapping; cleaning code; improving module stuff.
+ * 11/13: lc & tv: leds aren't working. auto_repeat/meta are. Generaly good behavior.
+ * 11/15: tv: 2AM: leds ARE working !
+ * 11/16: tv: 3AM: escaped keycodes emulation *handled*, some keycodes are
+ *	  still deliberately ignored (18), what are they used for ?
+ * 11/21: lc: mouse is now working
+ * 11/29: tv: first try for error handling in init sequence
+ *
+ * TODO:
+ * Error handling in init sequence
+ * SysRq handling
+ * Pause key handling
+ * Intellimouse & other rodents handling (at least send an error when
+ * such a mouse is plugged : it will totally fault)
+ * Mouse: set scaling / Dino testing
+ * Bug chasing...
+ *
+ */
+
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/ptrace.h>       /* interrupt.h wants struct pt_regs defined */
+#include <linux/interrupt.h>
+#include <linux/sched.h>        /* for request_irq/free_irq */        
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/pc_keyb.h>
+#include <linux/ioport.h>
+#include <linux/kd.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+
+/* Debugging stuff */
+#undef KBD_DEBUG
+#ifdef KBD_DEBUG
+	#define DPRINTK(fmt,args...) printk(KERN_DEBUG __FILE__ ":" fmt, ##args)
+#else 
+	#define DPRINTK(x,...)
+#endif
+
+
+/* 
+ * Driver constants
+ */
+
+/* PS/2 keyboard and mouse constants */
+#define AUX_RECONNECT		0xAA	/* PS/2 Mouse end of test successful */
+#define AUX_REPLY_ACK		0xFA
+
+/* Order of the mouse bytes coming to the host */
+#define PACKET_X		1
+#define PACKET_Y		2
+#define PACKET_CTRL		0
+
+#define GSC_MOUSE_OFFSET	0x0100	/* offset from keyboard to mouse port */
+#define GSC_DINO_OFFSET		0x800	/* offset for DINO controller versus LASI one */
+
+#define GSC_ID			0x00	/* ID and reset port offsets */
+#define GSC_RESET		0x00
+#define GSC_RCVDATA		0x04	/* receive and transmit port offsets */
+#define GSC_XMTDATA		0x04
+#define GSC_CONTROL		0x08	/* see: control register bits */
+#define GSC_STATUS		0x0C	/* see: status register bits */
+
+/* Control register bits */
+#define GSC_CTRL_ENBL		0x01	/* enable interface */
+#define GSC_CTRL_LPBXR		0x02	/* loopback operation */
+#define GSC_CTRL_DIAG		0x20	/* directly control clock/data line */
+#define GSC_CTRL_DATDIR		0x40	/* data line direct control */
+#define GSC_CTRL_CLKDIR		0x80	/* clock line direct control */
+
+/* Status register bits */
+#define GSC_STAT_RBNE		0x01	/* Receive Buffer Not Empty */
+#define GSC_STAT_TBNE		0x02	/* Transmit Buffer Not Empty */
+#define GSC_STAT_TERR		0x04	/* Timeout Error */
+#define GSC_STAT_PERR		0x08	/* Parity Error */
+#define GSC_STAT_CMPINTR	0x10	/* Composite Interrupt */
+#define GSC_STAT_DATSHD		0x40	/* Data Line Shadow */
+#define GSC_STAT_CLKSHD		0x80	/* Clock Line Shadow */
+
+/* Keycode map */
+#define KBD_ESCAPE0		0xe0
+#define KBD_ESCAPE1		0xe1
+#define KBD_RELEASE		0xf0
+#define KBD_ACK			0xfa
+#define KBD_RESEND		0xfe
+#define KBD_UNKNOWN		0
+
+#define KBD_TBLSIZE		512
+
+/* Mouse */
+#define MOUSE_LEFTBTN		0x1
+#define MOUSE_MIDBTN		0x4
+#define MOUSE_RIGHTBTN		0x2
+#define MOUSE_ALWAYS1		0x8
+#define MOUSE_XSIGN		0x10
+#define MOUSE_YSIGN		0x20
+#define MOUSE_XOVFLOW		0x40
+#define MOUSE_YOVFLOW		0x80
+
+
+static unsigned char hpkeyb_keycode[KBD_TBLSIZE] =
+{
+	/* 00 */  KBD_UNKNOWN,  KEY_F9,        KBD_UNKNOWN,   KEY_F5,        KEY_F3,        KEY_F1,       KEY_F2,        KEY_F12,
+	/* 08 */  KBD_UNKNOWN,  KEY_F10,       KEY_F8,        KEY_F6,        KEY_F4,        KEY_TAB,      KEY_GRAVE,     KBD_UNKNOWN,
+	/* 10 */  KBD_UNKNOWN,  KEY_LEFTALT,   KEY_LEFTSHIFT, KBD_UNKNOWN,   KEY_LEFTCTRL,  KEY_Q,        KEY_1,         KBD_UNKNOWN,
+	/* 18 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KEY_Z,         KEY_S,         KEY_A,         KEY_W,        KEY_2,         KBD_UNKNOWN,
+	/* 20 */  KBD_UNKNOWN,  KEY_C,         KEY_X,         KEY_D,         KEY_E,         KEY_4,        KEY_3,         KBD_UNKNOWN,
+	/* 28 */  KBD_UNKNOWN,  KEY_SPACE,     KEY_V,         KEY_F,         KEY_T,         KEY_R,        KEY_5,         KBD_UNKNOWN,
+	/* 30 */  KBD_UNKNOWN,  KEY_N,         KEY_B,         KEY_H,         KEY_G,         KEY_Y,        KEY_6,         KBD_UNKNOWN,
+	/* 38 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KEY_M,         KEY_J,         KEY_U,         KEY_7,        KEY_8,         KBD_UNKNOWN,
+	/* 40 */  KBD_UNKNOWN,  KEY_COMMA,     KEY_K,         KEY_I,         KEY_O,         KEY_0,        KEY_9,         KBD_UNKNOWN,
+	/* 48 */  KBD_UNKNOWN,  KEY_DOT,       KEY_SLASH,     KEY_L,         KEY_SEMICOLON, KEY_P,        KEY_MINUS,     KBD_UNKNOWN,
+	/* 50 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KEY_APOSTROPHE,KBD_UNKNOWN,   KEY_LEFTBRACE, KEY_EQUAL,    KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 58 */  KEY_CAPSLOCK, KEY_RIGHTSHIFT,KEY_ENTER,     KEY_RIGHTBRACE,KBD_UNKNOWN,   KEY_BACKSLASH,KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 60 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KEY_BACKSPACE, KBD_UNKNOWN,
+	/* 68 */  KBD_UNKNOWN,  KEY_KP1,       KBD_UNKNOWN,   KEY_KP4,       KEY_KP7,       KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 70 */  KEY_KP0,      KEY_KPDOT,     KEY_KP2,       KEY_KP5,       KEY_KP6,       KEY_KP8,      KEY_ESC,       KEY_NUMLOCK,
+	/* 78 */  KEY_F11,      KEY_KPPLUS,    KEY_KP3,       KEY_KPMINUS,   KEY_KPASTERISK,KEY_KP9,      KEY_SCROLLLOCK,KEY_103RD,
+	/* 80 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KEY_F7,        KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 88 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 90 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 98 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* a0 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* a8 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* b0 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* b8 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* c0 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* c8 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* d0 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* d8 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* e0 */  KBD_ESCAPE0,  KBD_ESCAPE1,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* e8 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* f0 */  KBD_RELEASE,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* f8 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_ACK,       KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_RESEND,    KBD_UNKNOWN,
+/* These are offset for escaped keycodes */
+	/* 00 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 08 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 10 */  KBD_UNKNOWN,  KEY_RIGHTALT,  KBD_UNKNOWN,   KBD_UNKNOWN,   KEY_RIGHTCTRL, KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 18 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 20 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 28 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 30 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 38 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 40 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 48 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KEY_KPSLASH,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 50 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 58 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KEY_KPENTER,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 60 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 68 */  KBD_UNKNOWN,  KEY_END,       KBD_UNKNOWN,   KEY_LEFT,      KEY_HOME,      KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 70 */  KEY_INSERT,   KEY_DELETE,    KEY_DOWN,      KBD_UNKNOWN,   KEY_RIGHT,     KEY_UP,       KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 78 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KEY_PAGEDOWN,  KBD_UNKNOWN,   KEY_SYSRQ,     KEY_PAGEUP,   KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 80 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 88 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 90 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* 98 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* a0 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* a8 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* b0 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* b8 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* c0 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* c8 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* d0 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* d8 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* e0 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* e8 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* f0 */  KBD_RELEASE,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,
+	/* f8 */  KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,   KBD_UNKNOWN,  KBD_UNKNOWN,   KBD_UNKNOWN
+};
+
+
+/* Keyboard struct */
+static struct {
+	struct input_dev dev;
+	char * addr;
+	unsigned int irq;
+	unsigned int scancode;
+	unsigned int escaped;
+	unsigned int released;
+	unsigned int initialized;
+}
+hpkeyb = {
+	.escaped = 0,
+	.released = 0,
+	.initialized = 0
+};
+
+/* Mouse struct */
+static struct {
+   	struct input_dev dev;
+	char * addr;
+	unsigned long irq;
+	unsigned long initialized;
+	int nbread;
+	unsigned char bytes[3];
+	unsigned long last;
+}
+hpmouse = {
+	.initialized = 0,
+	.nbread = 0
+};
+
+static spinlock_t gscps2_lock = SPIN_LOCK_UNLOCKED;
+
+
+/*
+ * Various HW level routines
+ */
+
+#define gscps2_readb_input(x)		readb(x+GSC_RCVDATA)
+#define gscps2_readb_control(x)		readb(x+GSC_CONTROL)
+#define gscps2_readb_status(x)		readb(x+GSC_STATUS)
+#define gscps2_writeb_control(x, y)	writeb(x, y+GSC_CONTROL)
+
+static inline void gscps2_writeb_output(u8 val, char * addr)
+{
+	int wait = 250;			/* Keyboard is expected to react within 250ms */
+
+	while (gscps2_readb_status(addr) & GSC_STAT_TBNE) {
+		if (!--wait)
+			return;		/* This should not happen */
+		mdelay(1);
+	}
+	writeb(val, addr+GSC_XMTDATA);
+}
+
+static inline unsigned char gscps2_wait_input(char * addr)
+{
+	int wait = 250;			/* Keyboard is expected to react within 250ms */
+
+	while (!(gscps2_readb_status(addr) & GSC_STAT_RBNE)) {
+		if (!--wait)
+			return 0;	/* This should not happen */
+		mdelay(1);
+	}
+	return gscps2_readb_input(addr);
+}
+
+static int gscps2_writeb_safe_output(u8 val)
+{
+	/* This function waits for keyboard's ACK */
+	u8 scanread = KBD_UNKNOWN;
+	int loop = 5;
+	
+	while (hpkeyb_keycode[scanread]!=KBD_ACK && --loop > 0) {	
+		gscps2_writeb_output(val, hpkeyb.addr);
+		mdelay(5);
+		scanread = gscps2_wait_input(hpkeyb.addr);
+	}
+	
+	if (loop <= 0)
+		return -1;
+	
+	return 0;
+}
+
+/* Reset the PS2 port */
+static void __init gscps2_reset(char * addr)
+{
+	/* reset the interface */
+	writeb(0xff, addr+GSC_RESET);
+	writeb(0x0 , addr+GSC_RESET);
+
+	/* enable it */
+	gscps2_writeb_control(gscps2_readb_control(addr) | GSC_CTRL_ENBL, addr);
+}
+
+
+/**
+ * gscps2_kbd_docode() - PS2 Keyboard basic handler
+ *
+ * Receives a keyboard scancode, analyses it and sends it to the input layer.
+ */
+
+static void gscps2_kbd_docode(void)
+{
+	int scancode = gscps2_readb_input(hpkeyb.addr);
+	DPRINTK("rel=%d scancode=%d, esc=%d ", hpkeyb.released, scancode, hpkeyb.escaped);
+
+	/* Handle previously escaped scancodes */
+	if (hpkeyb.escaped == KBD_ESCAPE0)
+		scancode |= 0x100;	/* jump to the next 256 chars of the table */
+		
+	switch (hpkeyb_keycode[scancode]) {
+		case KBD_RELEASE:
+			DPRINTK("release\n");
+			hpkeyb.released = 1;
+			break;
+		case KBD_RESEND:
+			DPRINTK("resend request\n");
+			break;
+		case KBD_ACK:
+			DPRINTK("ACK\n");
+			break;
+		case KBD_ESCAPE0:
+		case KBD_ESCAPE1:
+			DPRINTK("escape code %d\n", hpkeyb_keycode[scancode]);
+			hpkeyb.escaped = hpkeyb_keycode[scancode];
+			break;
+		case KBD_UNKNOWN:
+			DPRINTK("received unknown scancode %d, escape %d.\n",
+				scancode, hpkeyb.escaped);	/* This is a DPRINTK atm since we do not handle escaped scancodes cleanly */
+			if (hpkeyb.escaped)
+			hpkeyb.escaped = 0;
+			if (hpkeyb.released)
+				hpkeyb.released = 0;
+			return;
+		default:
+			hpkeyb.scancode = scancode;
+			DPRINTK("sent=%d, rel=%d\n",hpkeyb.scancode, hpkeyb.released);
+			input_report_key(&hpkeyb.dev, hpkeyb_keycode[hpkeyb.scancode], !hpkeyb.released);
+			input_sync(&hpkeyb.dev);
+			if (hpkeyb.escaped)
+				hpkeyb.escaped = 0;
+			if (hpkeyb.released) 
+				hpkeyb.released = 0;
+			break;	
+	}
+}
+
+
+/**
+ * gscps2_mouse_docode() - PS2 Mouse basic handler
+ *
+ * Receives mouse codes, processes them by packets of three, and sends
+ * correct events to the input layer.
+ */
+
+static void gscps2_mouse_docode(void)
+{
+	int xrel, yrel;
+
+	/* process BAT (end of basic tests) command */
+	if ((hpmouse.nbread == 1) && (hpmouse.bytes[0] == AUX_RECONNECT))
+		hpmouse.nbread--;
+
+	/* stolen from psmouse.c */
+	if (hpmouse.nbread && time_after(jiffies, hpmouse.last + HZ/20)) {
+		printk(KERN_DEBUG "%s:%d : Lost mouse synchronization, throwing %d bytes away.\n", __FILE__, __LINE__,
+				hpmouse.nbread);
+		hpmouse.nbread = 0;
+	}
+
+	hpmouse.last = jiffies;
+	hpmouse.bytes[hpmouse.nbread++] = gscps2_readb_input(hpmouse.addr);
+	
+	/* process packet */
+	if (hpmouse.nbread == 3) {
+		
+		if (!(hpmouse.bytes[PACKET_CTRL] & MOUSE_ALWAYS1))
+			DPRINTK("Mouse: error on packet always1 bit checking\n");
+			/* XXX should exit now, bad data on the line! */
+		
+		if ((hpmouse.bytes[PACKET_CTRL] & (MOUSE_XOVFLOW | MOUSE_YOVFLOW)))
+			DPRINTK("Mouse: position overflow\n");
+		
+		input_report_key(&hpmouse.dev, BTN_LEFT, hpmouse.bytes[PACKET_CTRL] & MOUSE_LEFTBTN);
+		input_report_key(&hpmouse.dev, BTN_MIDDLE, hpmouse.bytes[PACKET_CTRL] & MOUSE_MIDBTN);
+		input_report_key(&hpmouse.dev, BTN_RIGHT, hpmouse.bytes[PACKET_CTRL] & MOUSE_RIGHTBTN);
+		
+		xrel = hpmouse.bytes[PACKET_X];
+		yrel = hpmouse.bytes[PACKET_Y];
+		
+		/* Data sent by mouse are 9-bit signed, the sign bit is in the control packet */
+		if (xrel && (hpmouse.bytes[PACKET_CTRL] & MOUSE_XSIGN))
+			xrel = xrel - 0x100;
+		if (yrel && (hpmouse.bytes[PACKET_CTRL] & MOUSE_YSIGN))
+			yrel = yrel - 0x100;
+		
+		input_report_rel(&hpmouse.dev, REL_X, xrel);
+		input_report_rel(&hpmouse.dev, REL_Y, -yrel);	/* Y axis is received upside-down */
+		
+		input_sync(&hpmouse.dev);
+		
+		hpmouse.nbread = 0;
+	}
+}
+
+
+/**
+ * gscps2_interrupt() - Interruption service routine
+ *
+ * This processes the list of scancodes queued and sends appropriate
+ * key value to the system.
+ */
+
+static void gscps2_interrupt(int irq, void *dev, struct pt_regs *reg)
+{
+	/* process mouse actions */
+	while (gscps2_readb_status(hpmouse.addr) & GSC_STAT_RBNE)
+		gscps2_mouse_docode();
+	
+	/* process keyboard scancode */
+	while (gscps2_readb_status(hpkeyb.addr) & GSC_STAT_RBNE)
+		gscps2_kbd_docode();
+}
+
+
+/**
+ * gscps2_hpkeyb_event() - Event handler
+ * @return: success/error report
+ *
+ * Currently only updates leds on keyboard
+ */
+
+int gscps2_hpkeyb_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+{
+	DPRINTK("Calling %s, type=%d, code=%d, value=%d\n",
+			__FUNCTION__, type, code, value);
+
+	if (!hpkeyb.initialized)
+		return -1;
+
+	if (type == EV_LED) {
+		u8 leds[2];
+
+		if (gscps2_writeb_safe_output(KBD_CMD_SET_LEDS)) {
+			printk(KERN_ERR "gsckbd_leds: timeout\n");
+			return -1;
+		}
+		DPRINTK("KBD_CMD_SET_LEDS\n");
+
+		*leds = (test_bit(LED_SCROLLL, dev->led) ? LED_SCR : 0)
+			| (test_bit(LED_NUML,    dev->led) ? LED_NUM : 0)
+			| (test_bit(LED_CAPSL,   dev->led) ? LED_CAP : 0);
+		DPRINTK("Sending leds=%x\n", *leds);
+		
+		if (gscps2_writeb_safe_output(*leds)) {
+			printk(KERN_ERR "gsckbd_leds: timeout\n");
+			return -1;
+		}
+		DPRINTK("leds sent\n");
+		
+		if (gscps2_writeb_safe_output(KBD_CMD_ENABLE)) {
+			printk(KERN_ERR "gsckbd_leds: timeout\n");
+			return -1;
+		}
+		DPRINTK("End\n");
+
+		return 0;
+
+	}
+	return -1;
+}
+
+
+/**
+ * gscps2_kbd_probe() - Probes keyboard device and init input_dev structure
+ * @return: number of device initialized (1, 0 on error)
+ */
+
+static int __init gscps2_kbd_probe(void)
+{
+	int i, res = 0;
+	unsigned long flags;
+
+	if (hpkeyb.initialized) {
+		printk(KERN_ERR "GSC PS/2 keyboard driver already registered\n");
+		return 0;
+	}
+	
+	spin_lock_irqsave(&gscps2_lock, flags);
+ 
+	if (!gscps2_writeb_safe_output(KBD_CMD_SET_LEDS)	&&
+	    !gscps2_writeb_safe_output(0)			&&
+	    !gscps2_writeb_safe_output(KBD_CMD_ENABLE))
+		res = 1;
+ 
+	spin_unlock_irqrestore(&gscps2_lock, flags);
+
+	if (!res)
+		printk(KERN_ERR "Keyboard initialization sequence failled\n");
+	
+	init_input_dev(&hpkeyb.dev);
+	
+	for (i = 0; i < KBD_TBLSIZE; i++)
+		if (hpkeyb_keycode[i] != KBD_UNKNOWN)
+			set_bit(hpkeyb_keycode[i], hpkeyb.dev.keybit);
+		
+	hpkeyb.dev.evbit[0]	= BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
+	hpkeyb.dev.ledbit[0]	= BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
+	hpkeyb.dev.keycode	= hpkeyb_keycode;
+	hpkeyb.dev.keycodesize	= sizeof(unsigned char);
+	hpkeyb.dev.keycodemax	= KBD_TBLSIZE;
+	hpkeyb.dev.name		= "GSC Keyboard";
+	hpkeyb.dev.phys		= "hpkbd/input0";
+
+	hpkeyb.dev.event	= gscps2_hpkeyb_event;
+	
+	/* TODO These need some adjustement, are they really useful ? */
+	hpkeyb.dev.id.bustype	= BUS_GSC;
+	hpkeyb.dev.id.vendor	= 0x0001;
+	hpkeyb.dev.id.product	= 0x0001;
+	hpkeyb.dev.id.version	= 0x0010;
+	hpkeyb.initialized	= 1;
+
+	return 1;
+}
+
+
+/**
+ * gscps2_mouse_probe() - Probes mouse device and init input_dev structure
+ * @return: number of device initialized (1, 0 on error)
+ *
+ * Currently no check on initialization is performed
+ */
+
+static int __init gscps2_mouse_probe(void)
+{
+	if (hpmouse.initialized) {
+		printk(KERN_ERR "GSC PS/2 Mouse driver already registered\n");
+		return 0;
+	}
+	
+	init_input_dev(&hpmouse.dev);
+	
+	hpmouse.dev.name	= "GSC Mouse";
+	hpmouse.dev.phys	= "hpmouse/input0";
+   	hpmouse.dev.evbit[0] 	= BIT(EV_KEY) | BIT(EV_REL);
+	hpmouse.dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+	hpmouse.dev.relbit[0] 	= BIT(REL_X) | BIT(REL_Y);
+	hpmouse.last 		= 0;
+
+	gscps2_writeb_output(AUX_ENABLE_DEV, hpmouse.addr);
+	/* Try it a second time, this will give status if the device is available */
+	gscps2_writeb_output(AUX_ENABLE_DEV, hpmouse.addr);
+	
+	/* TODO These need some adjustement, are they really useful ? */
+	hpmouse.dev.id.bustype	= BUS_GSC;
+	hpmouse.dev.id.vendor	= 0x0001;
+	hpmouse.dev.id.product	= 0x0001;
+	hpmouse.dev.id.version	= 0x0010;
+	hpmouse.initialized = 1;
+	return 1;	/* XXX: we don't check if initialization failed */
+}
+
+
+/**
+ * gscps2_probe() - Probes PS2 devices
+ * @return: success/error report
+ */
+
+static int __init gscps2_probe(struct parisc_device *dev)
+{
+	u8 id;
+	char *addr, *name;
+	int ret, device_found = 0;
+	unsigned long hpa = dev->hpa;
+
+	if (!dev->irq)
+		goto fail_pitifully;
+	
+	/* Offset for DINO PS/2. Works with LASI even */
+	if (dev->id.sversion == 0x96)
+		hpa += GSC_DINO_OFFSET;
+
+	addr = ioremap(hpa, 256);
+	
+	if (!hpmouse.initialized || !hpkeyb.initialized)
+		gscps2_reset(addr);
+
+	ret = -EINVAL;
+	id = readb(addr+GSC_ID) & 0x0f;
+	switch (id) {
+		case 0:				/* keyboard */
+			hpkeyb.addr = addr;
+			name = "keyboard";
+			device_found = gscps2_kbd_probe();
+			break;
+		case 1:				/* mouse */
+			hpmouse.addr = addr;
+			name = "mouse";
+			device_found = gscps2_mouse_probe();
+			break;
+		default:
+			printk(KERN_WARNING "%s: Unsupported PS/2 port (id=%d) ignored\n",
+		    		__FUNCTION__, id);
+			goto fail_miserably;
+	}
+
+	/* No valid device found */
+	ret = -ENODEV;
+	if (!device_found)
+		goto fail_miserably;
+
+	/* Here we claim only if we have a device attached */
+	/* Allocate the irq and memory region for that device */
+	ret = -EBUSY;
+	if (request_irq(dev->irq, gscps2_interrupt, 0, name, NULL))
+		goto fail_miserably;
+
+	if (!request_mem_region(hpa, GSC_STATUS + 4, name))
+		goto fail_request_mem;
+	
+	/* Finalize input struct and register it */
+	switch (id) {
+		case 0:				/* keyboard */
+			hpkeyb.irq = dev->irq;
+			input_register_device(&hpkeyb.dev);	
+			break;
+		case 1:				/* mouse */
+			hpmouse.irq = dev->irq;
+			input_register_device(&hpmouse.dev);
+			break;
+		default:
+			break;
+	}
+
+	printk(KERN_INFO "input: PS/2 %s port at 0x%08lx (irq %d) found and attached\n",
+			name, hpa, dev->irq);
+
+	return 0;
+	
+fail_request_mem: free_irq(dev->irq, NULL);
+fail_miserably: iounmap(addr);
+fail_pitifully:	return ret;
+}
+
+
+
+static struct parisc_device_id gscps2_device_tbl[] = {
+	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00084 }, /* LASI PS/2 */
+/*	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00096 },  DINO PS/2 (XXX Not yet tested) */
+	{ 0, }	/* 0 terminated list */
+};
+
+static struct parisc_driver gscps2_driver = {
+	.name		= "GSC PS2",
+	.id_table	= gscps2_device_tbl,
+	.probe		= gscps2_probe,
+};
+
+static int __init gscps2_init(void)
+{
+	if (register_parisc_driver(&gscps2_driver))
+		return -EBUSY;
+	return 0;
+}
+
+static void __exit gscps2_exit(void)
+{
+	/* TODO this is probably not very good and needs to be checked */
+	if (hpkeyb.initialized) {
+		free_irq(hpkeyb.irq, gscps2_interrupt);
+		iounmap(hpkeyb.addr);
+		hpkeyb.initialized = 0;
+		input_unregister_device(&hpkeyb.dev);
+	}
+	if (hpmouse.initialized) {
+		free_irq(hpmouse.irq, gscps2_interrupt);
+		iounmap(hpmouse.addr);
+		hpmouse.initialized = 0;
+		input_unregister_device(&hpmouse.dev);
+	}
+	unregister_parisc_driver(&gscps2_driver);
+}
+
+
+MODULE_AUTHOR("Laurent Canet <canetl@esiee.fr>, Thibaut Varene <varenet@esiee.fr>");
+MODULE_DESCRIPTION("GSC PS/2 keyboard/mouse driver");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(parisc, gscps2_device_tbl);
+
+
+module_init(gscps2_init);
+module_exit(gscps2_exit);
diff -Nru a/drivers/input/tsdev.c b/drivers/input/tsdev.c
--- a/drivers/input/tsdev.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/input/tsdev.c	Mon Dec  9 18:46:51 2002
@@ -385,7 +385,12 @@
 
 static int __init tsdev_init(void)
 {
-	interface_register(&tsdev_intf);
+	int retval;
+
+	retval = interface_register(&tsdev_intf);
+	if(retval < 0)
+		return retval;
+
 	input_register_handler(&tsdev_handler);
 	printk(KERN_INFO "ts: Compaq touchscreen protocol output\n");
 	return 0;
diff -Nru a/drivers/isdn/hardware/eicon/divamnt.c b/drivers/isdn/hardware/eicon/divamnt.c
--- a/drivers/isdn/hardware/eicon/divamnt.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/isdn/hardware/eicon/divamnt.c	Mon Dec  9 18:46:37 2002
@@ -51,8 +51,6 @@
 static char *DRIVERLNAME = "diva_mnt";
 char *DRIVERRELEASE = "2.0";
 
-static devfs_handle_t devfs_handle;
-
 static wait_queue_head_t msgwaitq;
 static DECLARE_MUTEX(opened_sem);
 static int opened;
@@ -412,8 +410,7 @@
 
 static void divas_maint_unregister_chrdev(void)
 {
-	if (devfs_handle)
-		devfs_unregister(devfs_handle);
+	devfs_remove("DivasMAINT");
 	unregister_chrdev(major, "DivasMAINT");
 }
 
@@ -425,10 +422,9 @@
 		       DRIVERLNAME);
 		return (0);
 	}
-	devfs_handle =
-	    devfs_register(NULL, "DivasMAINT", DEVFS_FL_DEFAULT, major, 0,
-			   S_IFCHR | S_IRUSR | S_IWUSR, &divas_maint_fops,
-			   NULL);
+	devfs_register(NULL, "DivasMAINT", DEVFS_FL_DEFAULT, major, 0,
+		       S_IFCHR | S_IRUSR | S_IWUSR, &divas_maint_fops,
+		       NULL);
 
 	return (1);
 }
diff -Nru a/drivers/isdn/hardware/eicon/divasi.c b/drivers/isdn/hardware/eicon/divasi.c
--- a/drivers/isdn/hardware/eicon/divasi.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/isdn/hardware/eicon/divasi.c	Mon Dec  9 18:46:36 2002
@@ -52,8 +52,6 @@
 static char *DRIVERLNAME = "diva_idi";
 char *DRIVERRELEASE = "2.0";
 
-static devfs_handle_t devfs_handle;
-
 extern int idifunc_init(void);
 extern void idifunc_finit(void);
 
@@ -171,8 +169,7 @@
 
 static void divas_idi_unregister_chrdev(void)
 {
-	if (devfs_handle)
-		devfs_unregister(devfs_handle);
+	devfs_remove("DivasIDI");
 	unregister_chrdev(major, "DivasIDI");
 }
 
@@ -184,10 +181,9 @@
 		       DRIVERLNAME);
 		return (0);
 	}
-	devfs_handle =
-	    devfs_register(NULL, "DivasIDI", DEVFS_FL_DEFAULT, major, 0,
-			   S_IFCHR | S_IRUSR | S_IWUSR, &divas_idi_fops,
-			   NULL);
+	devfs_register(NULL, "DivasIDI", DEVFS_FL_DEFAULT, major, 0,
+		       S_IFCHR | S_IRUSR | S_IWUSR, &divas_idi_fops,
+		       NULL);
 
 	return (1);
 }
diff -Nru a/drivers/isdn/hardware/eicon/divasmain.c b/drivers/isdn/hardware/eicon/divasmain.c
--- a/drivers/isdn/hardware/eicon/divasmain.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/isdn/hardware/eicon/divasmain.c	Mon Dec  9 18:46:35 2002
@@ -70,8 +70,6 @@
 extern int divasfunc_init(void);
 extern void divasfunc_exit(void);
 
-static devfs_handle_t devfs_handle;
-
 typedef struct _diva_os_thread_dpc {
 	struct tasklet_struct divas_task;
 	struct work_struct trap_script_task;
@@ -779,8 +777,7 @@
 
 static void divas_unregister_chrdev(void)
 {
-	if (devfs_handle)
-		devfs_unregister(devfs_handle);
+	devfs_remove("Divas");
 	unregister_chrdev(major, "Divas");
 }
 
@@ -792,9 +789,8 @@
 		       DRIVERLNAME);
 		return (0);
 	}
-	devfs_handle =
-	    devfs_register(NULL, "Divas", DEVFS_FL_DEFAULT, major, 0,
-			   S_IFCHR | S_IRUSR | S_IWUSR, &divas_fops, NULL);
+	devfs_register(NULL, "Divas", DEVFS_FL_DEFAULT, major, 0,
+		       S_IFCHR | S_IRUSR | S_IWUSR, &divas_fops, NULL);
 
 	return (1);
 }
diff -Nru a/drivers/isdn/hisax/isurf.c b/drivers/isdn/hisax/isurf.c
--- a/drivers/isdn/hisax/isurf.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/isdn/hisax/isurf.c	Mon Dec  9 18:46:38 2002
@@ -242,14 +242,12 @@
 		return (0);
 #endif
 	}
-	if (check_region(cs->hw.isurf.reset, 1)) {
+	if (!request_region(cs->hw.isurf.reset, 1, "isurf isdn")) {
 		printk(KERN_WARNING
 			"HiSax: %s config port %x already in use\n",
 			CardType[card->typ],
 			cs->hw.isurf.reset);
 			return (0);
-	} else {
-		request_region(cs->hw.isurf.reset, 1, "isurf isdn");
 	}
 	if (check_mem_region(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE)) {
 		printk(KERN_WARNING
diff -Nru a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c
--- a/drivers/isdn/hisax/st5481_usb.c	Mon Dec  9 18:46:49 2002
+++ b/drivers/isdn/hisax/st5481_usb.c	Mon Dec  9 18:46:49 2002
@@ -123,7 +123,7 @@
  * Call the user provided completion routine and try
  * to send the next request.
  */
-static void usb_ctrl_complete(struct urb *urb)
+static void usb_ctrl_complete(struct urb *urb, struct pt_regs *regs)
 {
 	struct st5481_adapter *adapter = urb->context;
 	struct st5481_ctrl *ctrl = &adapter->ctrl;
@@ -176,7 +176,7 @@
  * Decode the register values and schedule a private event.
  * Called at interrupt.
  */
-static void usb_int_complete(struct urb *urb)
+static void usb_int_complete(struct urb *urb, struct pt_regs *regs)
 {
 	u_char *data = urb->transfer_buffer;
 	u_char irqbyte;
diff -Nru a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
--- a/drivers/isdn/i4l/isdn_common.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/isdn/i4l/isdn_common.c	Mon Dec  9 18:46:36 2002
@@ -2165,22 +2165,19 @@
 
 #ifdef CONFIG_DEVFS_FS
 
-static devfs_handle_t devfs_handle;
-
 static void isdn_register_devfs(int k)
 {
-	char buf[11];
+	char buf[16];
 
-	sprintf (buf, "isdnctrl%d", k);
-	dev->devfs_handle_isdnctrlX[k] =
-	    devfs_register (devfs_handle, buf, DEVFS_FL_DEFAULT,
-			    ISDN_MAJOR, ISDN_MINOR_CTRL + k, 0600 | S_IFCHR,
-			    &isdn_fops, NULL);
+	sprintf (buf, "isdn/isdnctrl%d", k);
+	devfs_register(NULL, buf, DEVFS_FL_DEFAULT,
+		       ISDN_MAJOR, ISDN_MINOR_CTRL + k, 0600 | S_IFCHR,
+		       &isdn_fops, NULL);
 }
 
 static void isdn_unregister_devfs(int k)
 {
-	devfs_unregister (dev->devfs_handle_isdnctrlX[k]);
+	devfs_remove("isdn/isdnctrl%d", k);
 }
 
 static void isdn_init_devfs(void)
@@ -2189,27 +2186,24 @@
 	int i;
 #  endif
 
-	devfs_handle = devfs_mk_dir (NULL, "isdn", NULL);
+	devfs_mk_dir (NULL, "isdn", NULL);
 #  ifdef CONFIG_ISDN_PPP
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
-		char buf[8];
+		char buf[16];
 
-		sprintf (buf, "ippp%d", i);
-		dev->devfs_handle_ipppX[i] =
-		    devfs_register (devfs_handle, buf, DEVFS_FL_DEFAULT,
-				    ISDN_MAJOR, ISDN_MINOR_PPP + i,
-				    0600 | S_IFCHR, &isdn_fops, NULL);
+		sprintf (buf, "isdn/ippp%d", i);
+		devfs_register(NULL, buf, DEVFS_FL_DEFAULT,
+			       ISDN_MAJOR, ISDN_MINOR_PPP + i,
+			       0600 | S_IFCHR, &isdn_fops, NULL);
 	}
 #  endif
 
-	dev->devfs_handle_isdninfo =
-	    devfs_register (devfs_handle, "isdninfo", DEVFS_FL_DEFAULT,
-			    ISDN_MAJOR, ISDN_MINOR_STATUS, 0600 | S_IFCHR,
-			    &isdn_fops, NULL);
-	dev->devfs_handle_isdnctrl =
-	    devfs_register (devfs_handle, "isdnctrl", DEVFS_FL_DEFAULT,
-			    ISDN_MAJOR, ISDN_MINOR_CTRL, 0600 | S_IFCHR, 
-			    &isdn_fops, NULL);
+	devfs_register(NULL, "isdn/isdninfo", DEVFS_FL_DEFAULT,
+		       ISDN_MAJOR, ISDN_MINOR_STATUS, 0600 | S_IFCHR,
+		       &isdn_fops, NULL);
+	devfs_register(NULL, "isdn/isdnctrl", DEVFS_FL_DEFAULT,
+		       ISDN_MAJOR, ISDN_MINOR_CTRL, 0600 | S_IFCHR, 
+		       &isdn_fops, NULL);
 }
 
 static void isdn_cleanup_devfs(void)
@@ -2217,11 +2211,11 @@
 #  ifdef CONFIG_ISDN_PPP
 	int i;
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) 
-		devfs_unregister (dev->devfs_handle_ipppX[i]);
+		devfs_remove("isdn/ippp%d", i);
 #  endif
-	devfs_unregister (dev->devfs_handle_isdninfo);
-	devfs_unregister (dev->devfs_handle_isdnctrl);
-	devfs_unregister (devfs_handle);
+	devfs_remove("isdn/isdninfo");
+	devfs_remove("isdn/isdnctrl");
+	devfs_remove("isdn");
 }
 
 #else   /* CONFIG_DEVFS_FS */
diff -Nru a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
--- a/drivers/macintosh/adbhid.c	Mon Dec  9 18:46:52 2002
+++ b/drivers/macintosh/adbhid.c	Mon Dec  9 18:46:52 2002
@@ -3,8 +3,9 @@
  *
  * ADB HID driver for Power Macintosh computers.
  *
- * Adapted from drivers/macintosh/mac_keyb.c by Franz Sirl
- * (see that file for its authors and contributors).
+ * Adapted from drivers/macintosh/mac_keyb.c by Franz Sirl.
+ * drivers/macintosh/mac_keyb.c was Copyright (C) 1996 Paul Mackerras
+ * with considerable contributions from Ben Herrenschmidt and others.
  *
  * Copyright (C) 2000 Franz Sirl.
  *
@@ -433,22 +434,17 @@
 static int
 adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
 {
-	unsigned long flags;
-
 	switch (code) {
 	case ADB_MSG_PRE_RESET:
 	case ADB_MSG_POWERDOWN:
 	    	/* Stop the repeat timer. Autopoll is already off at this point */
-		save_flags(flags);
-		cli();
 		{
 			int i;
 			for (i = 1; i < 16; i++) {
 				if (adbhid[i])
-					del_timer(&adbhid[i]->input.timer);
+					del_timer_sync(&adbhid[i]->input.timer);
 			}
 		}
-		restore_flags(flags);
 
 		/* Stop pending led requests */
 		while(!led_request.complete)
@@ -479,7 +475,7 @@
 	memset(adbhid[id], 0, sizeof(struct adbhid));
 	sprintf(adbhid[id]->phys, "adb%d:%d.%02x/input", id, default_id, original_handler_id);
 
-	init_input_dev(&adbhid[id]);
+	init_input_dev(&adbhid[id]->input);
 
 	adbhid[id]->id = default_id;
 	adbhid[id]->original_handler_id = original_handler_id;
@@ -508,21 +504,21 @@
 		switch (original_handler_id) {
 		default:
 			printk("<unknown>.\n");
-			adbhid[id]->input.idversion = ADB_KEYBOARD_UNKNOWN;
+			adbhid[id]->input.id.version = ADB_KEYBOARD_UNKNOWN;
 			break;
 
 		case 0x01: case 0x02: case 0x03: case 0x06: case 0x08:
 		case 0x0C: case 0x10: case 0x18: case 0x1B: case 0x1C:
 		case 0xC0: case 0xC3: case 0xC6:
 			printk("ANSI.\n");
-			adbhid[id]->input.idversion = ADB_KEYBOARD_ANSI;
+			adbhid[id]->input.id.version = ADB_KEYBOARD_ANSI;
 			break;
 
 		case 0x04: case 0x05: case 0x07: case 0x09: case 0x0D:
 		case 0x11: case 0x14: case 0x19: case 0x1D: case 0xC1:
 		case 0xC4: case 0xC7:
 			printk("ISO, swapping keys.\n");
-			adbhid[id]->input.idversion = ADB_KEYBOARD_ISO;
+			adbhid[id]->input.id.version = ADB_KEYBOARD_ISO;
 			i = adbhid[id]->keycode[10];
 			adbhid[id]->keycode[10] = adbhid[id]->keycode[50];
 			adbhid[id]->keycode[50] = i;
@@ -531,7 +527,7 @@
 		case 0x12: case 0x15: case 0x16: case 0x17: case 0x1A:
 		case 0x1E: case 0xC2: case 0xC5: case 0xC8: case 0xC9:
 			printk("JIS.\n");
-			adbhid[id]->input.idversion = ADB_KEYBOARD_JIS;
+			adbhid[id]->input.id.version = ADB_KEYBOARD_JIS;
 			break;
 		}
 
diff -Nru a/drivers/macintosh/nvram.c b/drivers/macintosh/nvram.c
--- a/drivers/macintosh/nvram.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/macintosh/nvram.c	Mon Dec  9 18:46:34 2002
@@ -118,8 +118,7 @@
 {
 	printk(KERN_INFO "Macintosh non-volatile memory driver v%s\n",
 		NVRAM_VERSION);
-	misc_register(&nvram_dev);
-	return 0;
+	return misc_register(&nvram_dev);
 }
 
 void __exit nvram_cleanup(void)
diff -Nru a/drivers/mca/Kconfig b/drivers/mca/Kconfig
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/mca/Kconfig	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,17 @@
+comment "Micro Channel Architecture Bus support"
+	depends on MCA
+
+config MCA_LEGACY
+	bool "Legacy MCA API Support"
+	depends on MCA
+	help
+	  This compiles in support for the old slot based MCA API.  If you
+	  have an unconverted MCA driver, you will need to say Y here.  It
+	  is safe to say Y anyway.
+
+config MCA_PROC_FS
+	bool "Support for the mca entry in /proc"
+	depends on MCA_LEGACY && PROC_FS
+	help
+	  If you want the old style /proc/mca directory in addition to the
+	  new style sysfs say Y here.
diff -Nru a/drivers/mca/Makefile b/drivers/mca/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/mca/Makefile	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,10 @@
+# Makefile for the Linux MCA bus support
+
+obj-y	:= mca-bus.o mca-device.o mca-driver.o
+
+obj-$(CONFIG_MCA_PROC_FS)	+= mca-proc.o
+obj-$(CONFIG_MCA_LEGACY)	+= mca-legacy.o
+
+export-objs	:= mca-bus.o mca-legacy.o mca-proc.o mca-driver.o
+
+include $(TOPDIR)/Rules.make
diff -Nru a/drivers/mca/mca-bus.c b/drivers/mca/mca-bus.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/mca/mca-bus.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,167 @@
+/* -*- mode: c; c-basic-offset: 8 -*- */
+
+/*
+ * MCA bus support functions for sysfs.
+ *
+ * (C) 2002 James Bottomley <James.Bottomley@HansenPartnership.com>
+ *
+**-----------------------------------------------------------------------------
+**  
+**  This program is free software; you can redistribute it and/or modify
+**  it under the terms of the GNU General Public License as published by
+**  the Free Software Foundation; either version 2 of the License, or
+**  (at your option) any later version.
+**
+**  This program is distributed in the hope that it will be useful,
+**  but WITHOUT ANY WARRANTY; without even the implied warranty of
+**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+**  GNU General Public License for more details.
+**
+**  You should have received a copy of the GNU General Public License
+**  along with this program; if not, write to the Free Software
+**  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+**-----------------------------------------------------------------------------
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/mca.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+
+/* Very few machines have more than one MCA bus.  However, there are
+ * those that do (Voyager 35xx/5xxx), so we do it this way for future
+ * expansion.  None that I know have more than 2 */
+struct mca_bus *mca_root_busses[MAX_MCA_BUSSES];
+
+#define MCA_DEVINFO(i,s) { .pos = i, .name = s }
+
+struct mca_device_info {
+	short pos_id;		/* the 2 byte pos id for this card */
+	char name[DEVICE_NAME_SIZE];
+};
+
+static int mca_bus_match (struct device *dev, struct device_driver *drv)
+{
+	struct mca_device *mca_dev = to_mca_device (dev);
+	struct mca_driver *mca_drv = to_mca_driver (drv);
+	const short *mca_ids = mca_drv->id_table;
+	int i;
+
+	if (!mca_ids)
+		return 0;
+
+	for(i = 0; mca_ids[i]; i++) {
+		if (mca_ids[i] == mca_dev->pos_id) {
+			mca_dev->index = i;
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+struct bus_type mca_bus_type = {
+	.name  = "MCA",
+	.match = mca_bus_match,
+};
+EXPORT_SYMBOL (mca_bus_type);
+
+static ssize_t mca_show_pos_id(struct device *dev, char *buf, size_t count,
+			       loff_t off)
+{
+	/* four digits, \n and trailing \0 */
+	char mybuf[6];
+	struct mca_device *mca_dev = to_mca_device(dev);
+	int len;
+
+	if(mca_dev->pos_id < MCA_DUMMY_POS_START)
+		len = sprintf(mybuf, "%04x\n", mca_dev->pos_id);
+	else
+		len = sprintf(mybuf, "none\n");
+
+	len++;
+	if(len > off) {
+		len = min((size_t)(len - off), count);
+		memcpy(buf + off, mybuf + off, len);
+	} else {
+		len = 0;
+	}
+	return len;
+}
+static ssize_t mca_show_pos(struct device *dev, char *buf, size_t count,
+			    loff_t off)
+{
+	/* enough for 8 two byte hex chars plus space and new line */
+	char mybuf[26];
+	int j, len=0;
+	struct mca_device *mca_dev = to_mca_device(dev);
+
+	for(j=0; j<8; j++)
+		len += sprintf(mybuf+len, "%02x ", mca_dev->pos[j]);
+	/* change last trailing space to new line */
+	mybuf[len-1] = '\n';
+	len++;
+	if(len > off) {
+		len = min((size_t)(len - off), count);
+		memcpy(buf + off, mybuf + off, len);
+	} else {
+		len = 0;
+	}
+	return len;
+}
+
+static DEVICE_ATTR(id, S_IRUGO, mca_show_pos_id, NULL);
+static DEVICE_ATTR(pos, S_IRUGO, mca_show_pos, NULL);
+
+int __init mca_register_device(int bus, struct mca_device *mca_dev)
+{
+	struct mca_bus *mca_bus = mca_root_busses[bus];
+
+	mca_dev->dev.parent = &mca_bus->dev;
+	mca_dev->dev.bus = &mca_bus_type;
+	sprintf (mca_dev->dev.bus_id, "%02d:%02X", bus, mca_dev->slot);
+	mca_dev->dma_mask = mca_bus->default_dma_mask;
+	mca_dev->dev.dma_mask = &mca_dev->dma_mask;
+
+	if (device_register(&mca_dev->dev))
+		return 0;
+
+	device_create_file(&mca_dev->dev, &dev_attr_id);
+	device_create_file(&mca_dev->dev, &dev_attr_pos);
+
+	return 1;
+}
+
+/* */
+struct mca_bus * __devinit mca_attach_bus(int bus)
+{
+	struct mca_bus *mca_bus;
+
+	if (unlikely(mca_root_busses[bus] != NULL)) {
+		/* This should never happen, but just in case */
+		printk(KERN_EMERG "MCA tried to add already existing bus %d\n",
+		       bus);
+		dump_stack();
+		return NULL;
+	}
+
+	mca_bus = kmalloc(sizeof(struct mca_bus), GFP_KERNEL);
+	if (!mca_bus)
+		return NULL;
+	memset(mca_bus, 0, sizeof(struct mca_bus));
+	sprintf(mca_bus->dev.bus_id,"mca%d",bus);
+	sprintf(mca_bus->dev.name,"Host %s MCA Bridge", bus ? "Secondary" : "Primary");
+	device_register(&mca_bus->dev);
+
+	mca_root_busses[bus] = mca_bus;
+
+	return mca_bus;
+}
+
+int __init mca_system_init (void)
+{
+	return bus_register(&mca_bus_type);
+}
diff -Nru a/drivers/mca/mca-device.c b/drivers/mca/mca-device.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/mca/mca-device.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,202 @@
+/* -*- mode: c; c-basic-offset: 8 -*- */
+
+/*
+ * MCA device support functions
+ *
+ * These functions support the ongoing device access API.
+ *
+ * (C) 2002 James Bottomley <James.Bottomley@HansenPartnership.com>
+ *
+**-----------------------------------------------------------------------------
+**  
+**  This program is free software; you can redistribute it and/or modify
+**  it under the terms of the GNU General Public License as published by
+**  the Free Software Foundation; either version 2 of the License, or
+**  (at your option) any later version.
+**
+**  This program is distributed in the hope that it will be useful,
+**  but WITHOUT ANY WARRANTY; without even the implied warranty of
+**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+**  GNU General Public License for more details.
+**
+**  You should have received a copy of the GNU General Public License
+**  along with this program; if not, write to the Free Software
+**  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+**-----------------------------------------------------------------------------
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/mca.h>
+
+/**
+ *	mca_device_read_stored_pos - read POS register from stored data
+ *	@mca_dev: device to read from
+ *	@reg:  register to read from
+ *
+ *	Fetch a POS value that was stored at boot time by the kernel
+ *	when it scanned the MCA space. The register value is returned.
+ *	Missing or invalid registers report 0.
+ */
+unsigned char mca_device_read_stored_pos(struct mca_device *mca_dev, int reg)
+{
+	if(reg < 0 || reg >= 8)
+		return 0;
+
+	return mca_dev->pos[reg];
+}
+EXPORT_SYMBOL(mca_device_read_stored_pos);
+
+/**
+ *	mca_device_read_pos - read POS register from card
+ *	@mca_dev: device to read from
+ *	@reg:  register to read from
+ *
+ *	Fetch a POS value directly from the hardware to obtain the
+ *	current value. This is much slower than
+ *	mca_device_read_stored_pos and may not be invoked from
+ *	interrupt context. It handles the deep magic required for
+ *	onboard devices transparently.
+ */
+unsigned char mca_device_read_pos(struct mca_device *mca_dev, int reg)
+{
+	struct mca_bus *mca_bus = to_mca_bus(mca_dev->dev.parent);
+
+	return mca_bus->f.mca_read_pos(mca_dev, reg);
+
+	return 	mca_dev->pos[reg];
+}
+EXPORT_SYMBOL(mca_device_read_pos);
+
+
+/**
+ *	mca_device_write_pos - read POS register from card
+ *	@mca_dev: device to write pos register to
+ *	@reg:  register to write to
+ *	@byte: byte to write to the POS registers
+ *
+ *	Store a POS value directly to the hardware. You should not
+ *	normally need to use this function and should have a very good
+ *	knowledge of MCA bus before you do so. Doing this wrongly can
+ *	damage the hardware.
+ *
+ *	This function may not be used from interrupt context.
+ *
+ */
+void mca_device_write_pos(struct mca_device *mca_dev, int reg,
+			  unsigned char byte)
+{
+	struct mca_bus *mca_bus = to_mca_bus(mca_dev->dev.parent);
+
+	mca_bus->f.mca_write_pos(mca_dev, reg, byte);
+}
+EXPORT_SYMBOL(mca_device_write_pos);
+
+/**
+ *	mca_device_transform_irq - transform the ADF obtained IRQ
+ *	@mca_device: device whose irq needs transforming
+ *	@irq: input irq from ADF
+ *
+ *	MCA Adapter Definition Files (ADF) contain irq, ioport, memory
+ *	etc. definitions.  In systems with more than one bus, these need
+ *	to be transformed through bus mapping functions to get the real
+ *	system global quantities.
+ *
+ *	This function transforms the interrupt number and returns the
+ *	transformed system global interrupt
+ */
+int mca_device_transform_irq(struct mca_device *mca_dev, int irq)
+{
+	struct mca_bus *mca_bus = to_mca_bus(mca_dev->dev.parent);
+
+	return mca_bus->f.mca_transform_irq(mca_dev, irq);
+}
+EXPORT_SYMBOL(mca_device_transform_irq);
+
+/**
+ *	mca_device_transform_ioport - transform the ADF obtained I/O port
+ *	@mca_device: device whose port needs transforming
+ *	@ioport: input I/O port from ADF
+ *
+ *	MCA Adapter Definition Files (ADF) contain irq, ioport, memory
+ *	etc. definitions.  In systems with more than one bus, these need
+ *	to be transformed through bus mapping functions to get the real
+ *	system global quantities.
+ *
+ *	This function transforms the I/O port number and returns the
+ *	transformed system global port number.
+ *
+ *	This transformation can be assumed to be linear for port ranges.
+ */
+int mca_device_transform_ioport(struct mca_device *mca_dev, int port)
+{
+	struct mca_bus *mca_bus = to_mca_bus(mca_dev->dev.parent);
+
+	return mca_bus->f.mca_transform_ioport(mca_dev, port);
+}
+EXPORT_SYMBOL(mca_device_transform_ioport);
+
+/**
+ *	mca_device_transform_memory - transform the ADF obtained memory
+ *	@mca_device: device whose memory region needs transforming
+ *	@mem: memory region start from ADF
+ *
+ *	MCA Adapter Definition Files (ADF) contain irq, ioport, memory
+ *	etc. definitions.  In systems with more than one bus, these need
+ *	to be transformed through bus mapping functions to get the real
+ *	system global quantities.
+ *
+ *	This function transforms the memory region start and returns the
+ *	transformed system global memory region (physical).
+ *
+ *	This transformation can be assumed to be linear for region ranges.
+ */
+void *mca_device_transform_memory(struct mca_device *mca_dev, void *mem)
+{
+	struct mca_bus *mca_bus = to_mca_bus(mca_dev->dev.parent);
+
+	return mca_bus->f.mca_transform_memory(mca_dev, mem);
+}
+EXPORT_SYMBOL(mca_device_transform_memory);
+
+
+/**
+ *	mca_device_claimed - check if claimed by driver
+ *	@mca_dev:	device to check
+ *
+ *	Returns 1 if the slot has been claimed by a driver
+ */
+
+int mca_device_claimed(struct mca_device *mca_dev)
+{
+	return mca_dev->driver_loaded;
+}
+EXPORT_SYMBOL(mca_device_claimed);
+
+/**
+ *	mca_device_set_claim - set the claim value of the driver
+ *	@mca_dev:	device to set value for
+ *	@val:		claim value to set (1 claimed, 0 unclaimed)
+ */
+void mca_device_set_claim(struct mca_device *mca_dev, int val)
+{
+	mca_dev->driver_loaded = val;
+}
+EXPORT_SYMBOL(mca_device_set_claim);
+
+/**
+ *	mca_device_status - get the status of the device
+ *	@mca_device:	device to get
+ *
+ *	returns an enumeration of the device status:
+ *
+ *	MCA_ADAPTER_NORMAL	adapter is OK.
+ *	MCA_ADAPTER_NONE	no adapter at device (should never happen).
+ *	MCA_ADAPTER_DISABLED	adapter is disabled.
+ *	MCA_ADAPTER_ERROR	adapter cannot be initialised.
+ */
+enum MCA_AdapterStatus mca_device_status(struct mca_device *mca_dev)
+{
+	return mca_dev->status;
+}
diff -Nru a/drivers/mca/mca-driver.c b/drivers/mca/mca-driver.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/mca/mca-driver.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,47 @@
+/* -*- mode: c; c-basic-offset: 8 -*- */
+
+/*
+ * MCA driver support functions for sysfs.
+ *
+ * (C) 2002 James Bottomley <James.Bottomley@HansenPartnership.com>
+ *
+**-----------------------------------------------------------------------------
+**  
+**  This program is free software; you can redistribute it and/or modify
+**  it under the terms of the GNU General Public License as published by
+**  the Free Software Foundation; either version 2 of the License, or
+**  (at your option) any later version.
+**
+**  This program is distributed in the hope that it will be useful,
+**  but WITHOUT ANY WARRANTY; without even the implied warranty of
+**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+**  GNU General Public License for more details.
+**
+**  You should have received a copy of the GNU General Public License
+**  along with this program; if not, write to the Free Software
+**  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+**-----------------------------------------------------------------------------
+ */
+
+#include <linux/device.h>
+#include <linux/mca.h>
+#include <linux/module.h>
+
+int mca_register_driver(struct mca_driver *mca_drv)
+{
+	int r;
+
+	mca_drv->driver.bus = &mca_bus_type;
+	if ((r = driver_register(&mca_drv->driver)) < 0)
+		return r;
+
+	return 0;
+}
+EXPORT_SYMBOL(mca_register_driver);
+
+void mca_unregister_driver(struct mca_driver *mca_drv)
+{
+	driver_unregister(&mca_drv->driver);
+}
+EXPORT_SYMBOL(mca_unregister_driver);
diff -Nru a/drivers/mca/mca-legacy.c b/drivers/mca/mca-legacy.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/mca/mca-legacy.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,408 @@
+/* -*- mode: c; c-basic-offset: 8 -*- */
+
+/*
+ * MCA bus support functions for legacy (2.4) API.
+ *
+ * Legacy API means the API that operates in terms of MCA slot number
+ *
+ * (C) 2002 James Bottomley <James.Bottomley@HansenPartnership.com>
+ *
+**-----------------------------------------------------------------------------
+**  
+**  This program is free software; you can redistribute it and/or modify
+**  it under the terms of the GNU General Public License as published by
+**  the Free Software Foundation; either version 2 of the License, or
+**  (at your option) any later version.
+**
+**  This program is distributed in the hope that it will be useful,
+**  but WITHOUT ANY WARRANTY; without even the implied warranty of
+**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+**  GNU General Public License for more details.
+**
+**  You should have received a copy of the GNU General Public License
+**  along with this program; if not, write to the Free Software
+**  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+**-----------------------------------------------------------------------------
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/mca.h>
+#include <asm/io.h>
+
+/* NOTE: This structure is stack allocated */
+struct mca_find_adapter_info {
+	int			id;
+	int			slot;
+	struct mca_device	*mca_dev;
+};
+
+/* The purpose of this iterator is to loop over all the devices and
+ * find the one with the smallest slot number that's just greater than
+ * or equal to the required slot with a matching id */
+static int mca_find_adapter_callback(struct device *dev, void *data)
+{
+	struct mca_find_adapter_info *info = data;
+	struct mca_device *mca_dev = to_mca_device(dev);
+
+	if(mca_dev->pos_id != info->id)
+		return 0;
+
+	if(mca_dev->slot < info->slot)
+		return 0;
+
+	if(!info->mca_dev || info->mca_dev->slot >= mca_dev->slot)
+		info->mca_dev = mca_dev;
+
+	return 0;
+}
+
+/**
+ *	mca_find_adapter - scan for adapters
+ *	@id:	MCA identification to search for
+ *	@start:	starting slot
+ *
+ *	Search the MCA configuration for adapters matching the 16bit
+ *	ID given. The first time it should be called with start as zero
+ *	and then further calls made passing the return value of the
+ *	previous call until %MCA_NOTFOUND is returned.
+ *
+ *	Disabled adapters are not reported.
+ */
+
+int mca_find_adapter(int id, int start)
+{
+	struct mca_find_adapter_info info;
+
+	if(id == 0xffff)
+		return MCA_NOTFOUND;
+
+	info.slot = start;
+	info.id = id;
+	info.mca_dev = NULL;
+
+	for(;;) {
+		bus_for_each_dev(&mca_bus_type, NULL, &info, mca_find_adapter_callback);
+
+		if(info.mca_dev == NULL)
+			return MCA_NOTFOUND;
+
+		if(info.mca_dev->status != MCA_ADAPTER_DISABLED)
+			break;
+
+		/* OK, found adapter but it was disabled.  Go around
+		 * again, excluding the slot we just found */
+
+		info.slot = info.mca_dev->slot + 1;
+		info.mca_dev = NULL;
+	}
+		
+	return info.mca_dev->slot;
+}
+EXPORT_SYMBOL(mca_find_adapter);
+
+/*--------------------------------------------------------------------*/
+
+/**
+ *	mca_find_unused_adapter - scan for unused adapters
+ *	@id:	MCA identification to search for
+ *	@start:	starting slot
+ *
+ *	Search the MCA configuration for adapters matching the 16bit
+ *	ID given. The first time it should be called with start as zero
+ *	and then further calls made passing the return value of the
+ *	previous call until %MCA_NOTFOUND is returned.
+ *
+ *	Adapters that have been claimed by drivers and those that
+ *	are disabled are not reported. This function thus allows a driver
+ *	to scan for further cards when some may already be driven.
+ */
+
+int mca_find_unused_adapter(int id, int start)
+{
+	struct mca_find_adapter_info info = { 0 };
+
+	if(id == 0xffff)
+		return MCA_NOTFOUND;
+
+	info.slot = start;
+	info.id = id;
+	info.mca_dev = NULL;
+
+	for(;;) {
+		bus_for_each_dev(&mca_bus_type, NULL, &info, mca_find_adapter_callback);
+
+		if(info.mca_dev == NULL)
+			return MCA_NOTFOUND;
+
+		if(info.mca_dev->status != MCA_ADAPTER_DISABLED
+		   && !info.mca_dev->driver_loaded)
+			break;
+
+		/* OK, found adapter but it was disabled or already in
+		 * use.  Go around again, excluding the slot we just
+		 * found */
+
+		info.slot = info.mca_dev->slot + 1;
+		info.mca_dev = NULL;
+	}
+		
+	return info.mca_dev->slot;
+}
+EXPORT_SYMBOL(mca_find_unused_adapter);
+
+/* NOTE: stack allocated structure */
+struct mca_find_device_by_slot_info {
+	int			slot;
+	struct mca_device 	*mca_dev;
+};
+
+static int mca_find_device_by_slot_callback(struct device *dev, void *data)
+{
+	struct mca_find_device_by_slot_info *info = data;
+	struct mca_device *mca_dev = to_mca_device(dev);
+
+	if(mca_dev->slot == info->slot)
+		info->mca_dev = mca_dev;
+
+	return 0;
+}
+
+struct mca_device *mca_find_device_by_slot(int slot)
+{
+	struct mca_find_device_by_slot_info info;
+
+	info.slot = slot;
+	info.mca_dev = NULL;
+
+	bus_for_each_dev(&mca_bus_type, NULL, &info, mca_find_device_by_slot_callback);
+
+	return info.mca_dev;
+}
+EXPORT_SYMBOL(mca_find_device_by_slot);
+
+/**
+ *	mca_read_stored_pos - read POS register from boot data
+ *	@slot: slot number to read from
+ *	@reg:  register to read from
+ *
+ *	Fetch a POS value that was stored at boot time by the kernel
+ *	when it scanned the MCA space. The register value is returned.
+ *	Missing or invalid registers report 0.
+ */
+unsigned char mca_read_stored_pos(int slot, int reg)
+{
+	struct mca_device *mca_dev = mca_find_device_by_slot(slot);
+
+	if(!mca_dev)
+		return 0;
+
+	return mca_device_read_stored_pos(mca_dev, reg);
+}
+EXPORT_SYMBOL(mca_read_stored_pos);
+
+
+/**
+ *	mca_read_pos - read POS register from card
+ *	@slot: slot number to read from
+ *	@reg:  register to read from
+ *
+ *	Fetch a POS value directly from the hardware to obtain the
+ *	current value. This is much slower than mca_read_stored_pos and
+ *	may not be invoked from interrupt context. It handles the
+ *	deep magic required for onboard devices transparently.
+ */
+
+unsigned char mca_read_pos(int slot, int reg)
+{
+	struct mca_device *mca_dev = mca_find_device_by_slot(slot);
+
+	if(!mca_dev)
+		return 0;
+
+	return mca_device_read_pos(mca_dev, reg);
+}
+EXPORT_SYMBOL(mca_read_pos);
+
+		
+/**
+ *	mca_write_pos - read POS register from card
+ *	@slot: slot number to read from
+ *	@reg:  register to read from
+ *	@byte: byte to write to the POS registers
+ *
+ *	Store a POS value directly from the hardware. You should not
+ *	normally need to use this function and should have a very good
+ *	knowledge of MCA bus before you do so. Doing this wrongly can
+ *	damage the hardware.
+ *
+ *	This function may not be used from interrupt context.
+ *
+ *	Note that this a technically a Bad Thing, as IBM tech stuff says
+ *	you should only set POS values through their utilities.
+ *	However, some devices such as the 3c523 recommend that you write
+ *	back some data to make sure the configuration is consistent.
+ *	I'd say that IBM is right, but I like my drivers to work.
+ *
+ *	This function can't do checks to see if multiple devices end up
+ *	with the same resources, so you might see magic smoke if someone
+ *	screws up.
+ */
+
+void mca_write_pos(int slot, int reg, unsigned char byte)
+{
+	struct mca_device *mca_dev = mca_find_device_by_slot(slot);
+
+	if(!mca_dev)
+		return;
+
+	mca_device_write_pos(mca_dev, reg, byte);
+}
+EXPORT_SYMBOL(mca_write_pos);
+
+/**
+ *	mca_set_adapter_name - Set the description of the card
+ *	@slot: slot to name
+ *	@name: text string for the namen
+ *
+ *	This function sets the name reported via /proc for this
+ *	adapter slot. This is for user information only. Setting a
+ *	name deletes any previous name.
+ */
+
+void mca_set_adapter_name(int slot, char* name)
+{
+	struct mca_device *mca_dev = mca_find_device_by_slot(slot);
+
+	if(!mca_dev)
+		return;
+
+	strncpy(mca_dev->dev.name, name, sizeof(mca_dev->dev.name));
+	mca_dev->dev.name[sizeof(mca_dev->dev.name) - 1] = '\0';
+}
+EXPORT_SYMBOL(mca_set_adapter_name);
+
+/**
+ *	mca_get_adapter_name - get the adapter description
+ *	@slot:	slot to query
+ *
+ *	Return the adapter description if set. If it has not been
+ *	set or the slot is out range then return NULL.
+ */
+
+char *mca_get_adapter_name(int slot)
+{
+	struct mca_device *mca_dev = mca_find_device_by_slot(slot);
+
+	if(!mca_dev)
+		return NULL;
+
+	return mca_dev->dev.name;
+}
+EXPORT_SYMBOL(mca_get_adapter_name);
+
+/**
+ *	mca_is_adapter_used - check if claimed by driver
+ *	@slot:	slot to check
+ *
+ *	Returns 1 if the slot has been claimed by a driver
+ */
+
+int mca_is_adapter_used(int slot)
+{
+	struct mca_device *mca_dev = mca_find_device_by_slot(slot);
+
+	if(!mca_dev)
+		return 0;
+
+	return mca_device_claimed(mca_dev);
+}
+EXPORT_SYMBOL(mca_is_adapter_used);
+
+/**
+ *	mca_mark_as_used - claim an MCA device
+ *	@slot:	slot to claim
+ *	FIXME:  should we make this threadsafe
+ *
+ *	Claim an MCA slot for a device driver. If the
+ *	slot is already taken the function returns 1,
+ *	if it is not taken it is claimed and 0 is
+ *	returned.
+ */
+
+int mca_mark_as_used(int slot)
+{
+	struct mca_device *mca_dev = mca_find_device_by_slot(slot);
+
+	if(!mca_dev)
+		/* FIXME: this is actually a severe error */
+		return 1;
+
+	if(mca_device_claimed(mca_dev))
+		return 1;
+
+	mca_device_set_claim(mca_dev, 1);
+
+	return 0;
+}
+EXPORT_SYMBOL(mca_mark_as_used);
+
+/**
+ *	mca_mark_as_unused - release an MCA device
+ *	@slot:	slot to claim
+ *
+ *	Release the slot for other drives to use.
+ */
+
+void mca_mark_as_unused(int slot)
+{
+	struct mca_device *mca_dev = mca_find_device_by_slot(slot);
+
+	if(!mca_dev)
+		return;
+
+	mca_device_set_claim(mca_dev, 0);
+}
+EXPORT_SYMBOL(mca_mark_as_unused);
+
+/**
+ *	mca_isadapter - check if the slot holds an adapter
+ *	@slot:	slot to query
+ *
+ *	Returns zero if the slot does not hold an adapter, non zero if
+ *	it does.
+ */
+
+int mca_isadapter(int slot)
+{
+	struct mca_device *mca_dev = mca_find_device_by_slot(slot);
+	enum MCA_AdapterStatus status;
+
+	if(!mca_dev)
+		return 0;
+
+	status = mca_device_status(mca_dev);
+
+	return status == MCA_ADAPTER_NORMAL
+		|| status == MCA_ADAPTER_DISABLED;
+}
+EXPORT_SYMBOL(mca_isadapter);
+
+/**
+ *	mca_isenabled - check if the slot holds an enabled adapter
+ *	@slot:	slot to query
+ *
+ *	Returns a non zero value if the slot holds an enabled adapter
+ *	and zero for any other case.
+ */
+
+int mca_isenabled(int slot)
+{
+	struct mca_device *mca_dev = mca_find_device_by_slot(slot);
+
+	if(!mca_dev)
+		return 0;
+
+	return mca_device_status(mca_dev) == MCA_ADAPTER_NORMAL;
+}
diff -Nru a/drivers/mca/mca-proc.c b/drivers/mca/mca-proc.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/mca/mca-proc.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,244 @@
+/* -*- mode: c; c-basic-offset: 8 -*- */
+
+/*
+ * MCA bus support functions for the proc fs.
+ *
+ * NOTE: this code *requires* the legacy MCA api.
+ *
+ * Legacy API means the API that operates in terms of MCA slot number
+ *
+ * (C) 2002 James Bottomley <James.Bottomley@HansenPartnership.com>
+ *
+**-----------------------------------------------------------------------------
+**  
+**  This program is free software; you can redistribute it and/or modify
+**  it under the terms of the GNU General Public License as published by
+**  the Free Software Foundation; either version 2 of the License, or
+**  (at your option) any later version.
+**
+**  This program is distributed in the hope that it will be useful,
+**  but WITHOUT ANY WARRANTY; without even the implied warranty of
+**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+**  GNU General Public License for more details.
+**
+**  You should have received a copy of the GNU General Public License
+**  along with this program; if not, write to the Free Software
+**  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+**-----------------------------------------------------------------------------
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/mca.h>
+
+static int get_mca_info_helper(struct mca_device *mca_dev, char *page, int len)
+{
+	int j;
+
+	for(j=0; j<8; j++)
+		len += sprintf(page+len, "%02x ",
+			       mca_dev ? mca_dev->pos[j] : 0xff);
+	len += sprintf(page+len, " %s\n", mca_dev ? mca_dev->dev.name : "");
+	return len;
+}
+
+int get_mca_info(char *page, char **start, off_t off,
+		 int count, int *eof, void *data)
+{
+	int i, len = 0;
+
+	if(MCA_bus) {
+		struct mca_device *mca_dev;
+		/* Format POS registers of eight MCA slots */
+
+		for(i=0; i<MCA_MAX_SLOT_NR; i++) {
+			mca_dev = mca_find_device_by_slot(i);
+
+			len += sprintf(page+len, "Slot %d: ", i+1);
+			len = get_mca_info_helper(mca_dev, page, len);
+		}
+
+		/* Format POS registers of integrated video subsystem */
+
+		mca_dev = mca_find_device_by_slot(MCA_INTEGVIDEO);
+		len += sprintf(page+len, "Video : ");
+		len = get_mca_info_helper(mca_dev, page, len);
+
+		/* Format POS registers of integrated SCSI subsystem */
+
+		mca_dev = mca_find_device_by_slot(MCA_INTEGSCSI);
+		len += sprintf(page+len, "SCSI  : ");
+		len = get_mca_info_helper(mca_dev, page, len);
+
+		/* Format POS registers of motherboard */
+
+		mca_dev = mca_find_device_by_slot(MCA_MOTHERBOARD);
+		len += sprintf(page+len, "Planar: ");
+		len = get_mca_info_helper(mca_dev, page, len);
+	} else {
+		/* Leave it empty if MCA not detected - this should *never*
+		 * happen!
+		 */
+	}
+
+	if (len <= off+count) *eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len>count) len = count;
+	if (len<0) len = 0;
+	return len;
+}
+
+/*--------------------------------------------------------------------*/
+
+static int mca_default_procfn(char* buf, struct mca_device *mca_dev)
+{
+	int len = 0, i;
+	int slot = mca_dev->slot;
+
+	/* Print out the basic information */
+
+	if(slot < MCA_MAX_SLOT_NR) {
+		len += sprintf(buf+len, "Slot: %d\n", slot+1);
+	} else if(slot == MCA_INTEGSCSI) {
+		len += sprintf(buf+len, "Integrated SCSI Adapter\n");
+	} else if(slot == MCA_INTEGVIDEO) {
+		len += sprintf(buf+len, "Integrated Video Adapter\n");
+	} else if(slot == MCA_MOTHERBOARD) {
+		len += sprintf(buf+len, "Motherboard\n");
+	}
+	if(mca_dev->dev.name[0]) {
+
+		/* Drivers might register a name without /proc handler... */
+
+		len += sprintf(buf+len, "Adapter Name: %s\n",
+			       mca_dev->dev.name);
+	} else {
+		len += sprintf(buf+len, "Adapter Name: Unknown\n");
+	}
+	len += sprintf(buf+len, "Id: %02x%02x\n",
+		mca_dev->pos[1], mca_dev->pos[0]);
+	len += sprintf(buf+len, "Enabled: %s\nPOS: ",
+		mca_isenabled(slot) ? "Yes" : "No");
+	for(i=0; i<8; i++) {
+		len += sprintf(buf+len, "%02x ", mca_dev->pos[i]);
+	}
+	len += sprintf(buf+len, "\nDriver Installed: %s",
+		mca_is_adapter_used(slot) ? "Yes" : "No");
+	buf[len++] = '\n';
+	buf[len] = 0;
+
+	return len;
+} /* mca_default_procfn() */
+
+static int get_mca_machine_info(char* page, char **start, off_t off,
+				 int count, int *eof, void *data)
+{
+	int len = 0;
+
+	len += sprintf(page+len, "Model Id: 0x%x\n", machine_id);
+	len += sprintf(page+len, "Submodel Id: 0x%x\n", machine_submodel_id);
+	len += sprintf(page+len, "BIOS Revision: 0x%x\n", BIOS_revision);
+
+	if (len <= off+count) *eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len>count) len = count;
+	if (len<0) len = 0;
+	return len;
+}
+
+static int mca_read_proc(char *page, char **start, off_t off,
+				 int count, int *eof, void *data)
+{
+	struct mca_device *mca_dev = (struct mca_device *)data;
+	int len = 0;
+
+	/* Get the standard info */
+
+	len = mca_default_procfn(page, mca_dev);
+
+	/* Do any device-specific processing, if there is any */
+
+	if(mca_dev->procfn) {
+		len += mca_dev->procfn(page+len, mca_dev->slot,
+				       mca_dev->proc_dev);
+	}
+	if (len <= off+count) *eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len>count) len = count;
+	if (len<0) len = 0;
+	return len;
+} /* mca_read_proc() */
+
+/*--------------------------------------------------------------------*/
+
+void __init mca_do_proc_init(void)
+{
+	int i;
+	struct proc_dir_entry *proc_mca;
+	struct proc_dir_entry* node = NULL;
+	struct mca_device *mca_dev;
+
+	proc_mca = proc_mkdir("mca", &proc_root);
+	create_proc_read_entry("pos",0,proc_mca,get_mca_info,NULL);
+	create_proc_read_entry("machine",0,proc_mca,get_mca_machine_info,NULL);
+
+	/* Initialize /proc/mca entries for existing adapters */
+
+	for(i = 0; i < MCA_NUMADAPTERS; i++) {
+		mca_dev = mca_find_device_by_slot(i);
+		if(!mca_dev)
+			continue;
+
+		mca_dev->procfn = NULL;
+
+		if(i < MCA_MAX_SLOT_NR) sprintf(mca_dev->procname,"slot%d", i+1);
+		else if(i == MCA_INTEGVIDEO) sprintf(mca_dev->procname,"video");
+		else if(i == MCA_INTEGSCSI) sprintf(mca_dev->procname,"scsi");
+		else if(i == MCA_MOTHERBOARD) sprintf(mca_dev->procname,"planar");
+
+		if(!mca_isadapter(i)) continue;
+
+		node = create_proc_read_entry(mca_dev->procname, 0, proc_mca,
+					      mca_read_proc, (void *)mca_dev);
+
+		if(node == NULL) {
+			printk("Failed to allocate memory for MCA proc-entries!");
+			return;
+		}
+	}
+
+} /* mca_do_proc_init() */
+
+/**
+ *	mca_set_adapter_procfn - Set the /proc callback
+ *	@slot: slot to configure
+ *	@procfn: callback function to call for /proc
+ *	@dev: device information passed to the callback
+ *
+ *	This sets up an information callback for /proc/mca/slot?.  The
+ *	function is called with the buffer, slot, and device pointer (or
+ *	some equally informative context information, or nothing, if you
+ *	prefer), and is expected to put useful information into the
+ *	buffer.  The adapter name, ID, and POS registers get printed
+ *	before this is called though, so don't do it again.
+ *
+ *	This should be called with a %NULL @procfn when a module
+ *	unregisters, thus preventing kernel crashes and other such
+ *	nastiness.
+ */
+
+void mca_set_adapter_procfn(int slot, MCA_ProcFn procfn, void* proc_dev)
+{
+	struct mca_device *mca_dev = mca_find_device_by_slot(slot);
+
+	if(!mca_dev)
+		return;
+
+	mca_dev->procfn = procfn;
+	mca_dev->proc_dev = proc_dev;
+}
+EXPORT_SYMBOL(mca_set_adapter_procfn);
diff -Nru a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
--- a/drivers/md/dm-ioctl.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/md/dm-ioctl.c	Mon Dec  9 18:46:35 2002
@@ -30,9 +30,6 @@
 	char *name;
 	char *uuid;
 	struct mapped_device *md;
-
-	/* I hate devfs */
-	devfs_handle_t devfs_entry;
 };
 
 #define NUM_BUCKETS 64
@@ -40,7 +37,6 @@
 static struct list_head _name_buckets[NUM_BUCKETS];
 static struct list_head _uuid_buckets[NUM_BUCKETS];
 
-static devfs_handle_t _dev_dir;
 void dm_hash_remove_all(void);
 
 /*
@@ -60,14 +56,14 @@
 {
 	init_buckets(_name_buckets);
 	init_buckets(_uuid_buckets);
-	_dev_dir = devfs_mk_dir(0, DM_DIR, NULL);
+	devfs_mk_dir(NULL, DM_DIR, NULL);
 	return 0;
 }
 
 void dm_hash_exit(void)
 {
 	dm_hash_remove_all();
-	devfs_unregister(_dev_dir);
+	devfs_remove(DM_DIR);
 }
 
 /*-----------------------------------------------------------------
@@ -177,20 +173,20 @@
  */
 static int register_with_devfs(struct hash_cell *hc)
 {
+	char name[32];
 	struct gendisk *disk = dm_disk(hc->md);
 
-	hc->devfs_entry =
-	    devfs_register(_dev_dir, hc->name, DEVFS_FL_CURRENT_OWNER,
-			   disk->major, disk->first_minor,
-			   S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP,
-			   &dm_blk_dops, NULL);
-
+	sprintf(name, DM_DIR "/%s", hc->name);
+	devfs_register(NULL, name, DEVFS_FL_CURRENT_OWNER,
+		       disk->major, disk->first_minor,
+		       S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP,
+		       &dm_blk_dops, NULL);
 	return 0;
 }
 
 static int unregister_with_devfs(struct hash_cell *hc)
 {
-	devfs_unregister(hc->devfs_entry);
+	devfs_remove(DM_DIR"/%s", hc->name);
 	return 0;
 }
 
diff -Nru a/drivers/md/md.c b/drivers/md/md.c
--- a/drivers/md/md.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/md/md.c	Mon Dec  9 18:46:35 2002
@@ -36,6 +36,7 @@
 #include <linux/bio.h>
 #include <linux/devfs_fs_kernel.h>
 #include <linux/buffer_head.h> /* for invalidate_bdev */
+#include <linux/suspend.h>
 
 #include <linux/init.h>
 
@@ -105,7 +106,6 @@
 sector_t md_size[MAX_MD_DEVS];
 
 static struct block_device_operations md_fops;
-static devfs_handle_t devfs_handle;
 
 static struct gendisk *disks[MAX_MD_DEVS];
 
@@ -2466,6 +2466,8 @@
 
 		wait_event_interruptible(thread->wqueue,
 					 test_bit(THREAD_WAKEUP, &thread->flags));
+		if (current->flags & PF_FREEZE)
+			refrigerator(PF_IOTHREAD);
 
 		clear_bit(THREAD_WAKEUP, &thread->flags);
 
@@ -3102,15 +3104,14 @@
 		printk(KERN_ALERT "md: Unable to get major %d for md\n", MAJOR_NR);
 		return (-1);
 	}
-	devfs_handle = devfs_mk_dir (NULL, "md", NULL);
+	devfs_mk_dir (NULL, "md", NULL);
 	blk_register_region(MKDEV(MAJOR_NR, 0), MAX_MD_DEVS, THIS_MODULE,
 				md_probe, NULL, NULL);
 	for (minor=0; minor < MAX_MD_DEVS; ++minor) {
-		char devname[128];
-		sprintf (devname, "%u", minor);
-		devfs_register (devfs_handle,
-			devname, DEVFS_FL_DEFAULT, MAJOR_NR, minor,
-			S_IFBLK | S_IRUSR | S_IWUSR, &md_fops, NULL);
+		char name[16];
+		sprintf(name, "md/%d", minor);
+		devfs_register(NULL, name, DEVFS_FL_DEFAULT, MAJOR_NR, minor,
+			       S_IFBLK | S_IRUSR | S_IWUSR, &md_fops, NULL);
 	}
 
 	md_recovery_thread = md_register_thread(md_do_recovery, NULL, name);
@@ -3176,7 +3177,9 @@
 	int i;
 	blk_unregister_region(MKDEV(MAJOR_NR,0), MAX_MD_DEVS);
 	md_unregister_thread(md_recovery_thread);
-	devfs_unregister(devfs_handle);
+	for (i=0; i < MAX_MD_DEVS; i++)
+		devfs_remove("md/%d", i);
+	devfs_remove("md");
 
 	unregister_blkdev(MAJOR_NR,"md");
 	unregister_reboot_notifier(&md_notifier);
diff -Nru a/drivers/md/raid0.c b/drivers/md/raid0.c
--- a/drivers/md/raid0.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/md/raid0.c	Mon Dec  9 18:46:38 2002
@@ -214,7 +214,7 @@
 	printk("raid0 : nb_zone is %d.\n", nb_zone);
 	conf->nr_zones = nb_zone;
 
-	printk("raid0 : Allocating %d bytes for hash.\n",
+	printk("raid0 : Allocating %Zd bytes for hash.\n",
 				nb_zone*sizeof(struct raid0_hash));
 	conf->hash_table = vmalloc (sizeof (struct raid0_hash)*nb_zone);
 	if (!conf->hash_table)
diff -Nru a/drivers/media/dvb/av7110/av7110_ir.c b/drivers/media/dvb/av7110/av7110_ir.c
--- a/drivers/media/dvb/av7110/av7110_ir.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/media/dvb/av7110/av7110_ir.c	Mon Dec  9 18:46:51 2002
@@ -54,7 +54,7 @@
 
 
 static
-struct timer_list keyup_timer = { function: av7110_emit_keyup };
+struct timer_list keyup_timer = { .function = av7110_emit_keyup };
 
 
 static
diff -Nru a/drivers/media/dvb/av7110/saa7146_core.c b/drivers/media/dvb/av7110/saa7146_core.c
--- a/drivers/media/dvb/av7110/saa7146_core.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/media/dvb/av7110/saa7146_core.c	Mon Dec  9 18:46:50 2002
@@ -45,14 +45,14 @@
 
 /* insmod parameter: some programs (e.g. ´vic´) do not allow to
    specify the used video-mode, so you have to tell this to the
-   modules by hand, 0 = PAL, 1 = NTSC  */
-static int mode = 0;
+   modules by hand, 0 = PAL (default), 1 = NTSC  */
+static int mode;
 
-/* debug levels: 0 -- no debugging outputs
+/* debug levels: 0 -- no debugging outputs: default
 		 1 -- prints out entering (and exiting if useful) of functions
 		 2 -- prints out very, very detailed informations of what is going on
 		 3 -- both of the above */
-int saa7146_debug = 0;	/* insmod parameter */
+int saa7146_debug;	/* insmod parameter */
 
 #define dprintk		if (saa7146_debug & 1) printk
 #define hprintk		if (saa7146_debug & 2) printk
@@ -796,7 +796,7 @@
 static int saa7146_suspend(struct pci_dev *pdev, u32 state)
 {
         printk("saa7146_suspend()\n");
-	saa7146_core_command(((struct saa7146 *) pdev->driver_data)->i2c_bus,
+	saa7146_core_command(((struct saa7146 *)pci_get_drvdata(pdev))->i2c_bus,
 			     SAA7146_SUSPEND, 0);
 	return 0;
 }
@@ -805,7 +805,7 @@
 saa7146_resume(struct pci_dev *pdev)
 {
         printk("saa7146_resume()\n");
-	saa7146_core_command(((struct saa7146 *) pdev->driver_data)->i2c_bus,
+	saa7146_core_command(((struct saa7146 *)pci_get_drvdata(pdev))->i2c_bus,
 			     SAA7146_RESUME, 0);
 	return 0;
 }
@@ -839,7 +839,7 @@
 	memset (saa, 0, sizeof (struct saa7146));
 
 	saa->device = pdev;
-	saa->device->driver_data = saa;
+	pci_set_drvdata(pdev, saa);
 	saa->card_type = card_type;
 	saa->dvb_adapter = adap;
 
@@ -855,7 +855,7 @@
 static
 void __devexit saa7146_remove_one (struct pci_dev *pdev)
 {
-	struct saa7146 *saa = pdev->driver_data;
+	struct saa7146 *saa = pci_get_drvdata(pdev);
 
 	dprintk("saa7146_remove_one()\n");
 
@@ -905,12 +905,12 @@
 MODULE_DEVICE_TABLE(pci, saa7146_pci_tbl);
 	
 static struct pci_driver saa7146_driver = {
-	name:		"saa7146",
-	id_table:	saa7146_pci_tbl,
-	probe:		saa7146_init_one,
-	remove:		saa7146_remove_one,
-	suspend:	saa7146_suspend,
-	resume:		saa7146_resume,
+	.name		= "saa7146",
+	.id_table	= saa7146_pci_tbl,
+	.probe		= saa7146_init_one,
+	.remove		= saa7146_remove_one,
+	.suspend	= saa7146_suspend,
+	.resume		= saa7146_resume,
 };
 
 
diff -Nru a/drivers/media/dvb/frontends/alps_bsru6.c b/drivers/media/dvb/frontends/alps_bsru6.c
--- a/drivers/media/dvb/frontends/alps_bsru6.c	Mon Dec  9 18:46:52 2002
+++ b/drivers/media/dvb/frontends/alps_bsru6.c	Mon Dec  9 18:46:52 2002
@@ -39,22 +39,22 @@
 static
 struct dvb_frontend_info bsru6_info = {
 #ifdef CONFIG_ALPS_BSRU6_IS_LG_TDQBS00X
-	name: "LG TDQB-S00x",
+	.name			= "LG TDQB-S00x",
 #else
-	name: "Alps BSRU6",
+	.name			= "Alps BSRU6",
 #endif
-	type: FE_QPSK,
-	frequency_min: 950000,
-	frequency_max: 2150000,
-	frequency_stepsize: 125,   /* kHz for QPSK frontends */
-	frequency_tolerance: M_CLK/2000,
-	symbol_rate_min: 1000000,
-	symbol_rate_max: 45000000,
-	symbol_rate_tolerance: 500,  /* ppm */
-	notifier_delay: 0,
-	caps: FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-	      FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-	      FE_CAN_QPSK
+	.type			= FE_QPSK,
+	.frequency_min		= 950000,
+	.frequency_max		= 2150000,
+	.frequency_stepsize	= 125,   /* kHz for QPSK frontends */
+	.frequency_tolerance	= M_CLK/2000,
+	.symbol_rate_min	= 1000000,
+	.symbol_rate_max	= 45000000,
+	.symbol_rate_tolerance	= 500,  /* ppm */
+	.caps 			= FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
+				  FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
+				  FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+				  FE_CAN_QPSK
 };
 
 
@@ -158,7 +158,7 @@
 {
 	int ret;
 	u8 buf [] = { reg, data };
-	struct i2c_msg msg = { addr: 0x68, flags: 0, buf: buf, len: 2 };
+	struct i2c_msg msg = { .addr = 0x68, .flags = 0, .buf = buf, .len = 2 };
 
 	dprintk ("%s\n", __FUNCTION__);
 
@@ -178,8 +178,8 @@
 	int ret;
 	u8 b0 [] = { reg };
 	u8 b1 [] = { 0 };
-	struct i2c_msg msg [] = { { addr: 0x68, flags: 0, buf: b0, len: 1 },
-			   { addr: 0x68, flags: I2C_M_RD, buf: b1, len: 1 } };
+	struct i2c_msg msg [] = { { .addr = 0x68, .flags = 0, .buf = b0, .len = 1 },
+			   { .addr = 0x68, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
         
 	dprintk ("%s\n", __FUNCTION__);
 
@@ -196,8 +196,8 @@
 int stv0299_readregs (struct dvb_i2c_bus *i2c, u8 reg1, u8 *b, u8 len)
 {
         int ret;
-        struct i2c_msg msg [] = { { addr: 0x68, flags: 0, buf: &reg1, len: 1 },
-                           { addr: 0x68, flags: I2C_M_RD, buf: b, len: len } };
+        struct i2c_msg msg [] = { { .addr = 0x68, .flags = 0, .buf = &reg1, .len = 1 },
+                           { .addr = 0x68, .flags = I2C_M_RD, .buf = b, .len = len } };
 
 	dprintk ("%s\n", __FUNCTION__);
 
@@ -216,8 +216,8 @@
 {
 	int ret;
 	u8 rpt1 [] = { 0x05, 0xb5 };  /*  enable i2c repeater on stv0299  */
-	struct i2c_msg msg [] = {{ addr: 0x68, flags: 0, buf: rpt1, len: 2 },
-				 { addr: 0x61, flags: 0, buf: data, len: 4 }};
+	struct i2c_msg msg [] = {{ .addr = 0x68, .flags = 0, .buf = rpt1, .len = 2 },
+				 { .addr = 0x61, .flags = 0, .buf = data, .len = 4 }};
 
 	dprintk ("%s\n", __FUNCTION__);
 
diff -Nru a/drivers/media/dvb/frontends/alps_bsrv2.c b/drivers/media/dvb/frontends/alps_bsrv2.c
--- a/drivers/media/dvb/frontends/alps_bsrv2.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/media/dvb/frontends/alps_bsrv2.c	Mon Dec  9 18:46:34 2002
@@ -32,20 +32,20 @@
 
 static
 struct dvb_frontend_info bsrv2_info = {
-	name: "Alps BSRV2",
-	type: FE_QPSK,
-	frequency_min: 950000,
-	frequency_max: 2150000,
-	frequency_stepsize: 250,           /* kHz for QPSK frontends */
-	frequency_tolerance: 29500,
-	symbol_rate_min: 1000000,
-	symbol_rate_max: 45000000,
-/*      symbol_rate_tolerance: ???,*/
-	notifier_delay: 50,                /* 1/20 s */
-	caps:   FE_CAN_INVERSION_AUTO |
-		FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-		FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-		FE_CAN_QPSK
+	.name			= "Alps BSRV2",
+	.type			= FE_QPSK,
+	.frequency_min		= 950000,
+	.frequency_max		= 2150000,
+	.frequency_stepsize	= 250,           /* kHz for QPSK frontends */
+	.frequency_tolerance	= 29500,
+	.symbol_rate_min	= 1000000,
+	.symbol_rate_max	= 45000000,
+	.notifier_delay		= 50,                /* 1/20 s */
+	.caps			= FE_CAN_INVERSION_AUTO |
+				  FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
+				  FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
+				  FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+				  FE_CAN_QPSK
 };
 
 
@@ -76,7 +76,7 @@
 int ves1893_writereg (struct dvb_i2c_bus *i2c, int reg, int data)
 {
         u8 buf [] = { 0x00, reg, data };
-	struct i2c_msg msg = { addr: 0x08, flags: 0, buf: buf, len: 3 };
+	struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 3 };
 	int err;
 
         if ((err = i2c->xfer (i2c, &msg, 1)) != 1) {
@@ -94,8 +94,8 @@
 	int ret;
 	u8 b0 [] = { 0x00, reg };
 	u8 b1 [] = { 0 };
-	struct i2c_msg msg [] = { { addr: 0x08, flags: 0, buf: b0, len: 2 },
-			   { addr: 0x08, flags: I2C_M_RD, buf: b1, len: 1 } };
+	struct i2c_msg msg [] = { { .addr = 0x08, .flags = 0, .buf = b0, .len = 2 },
+			   { .addr = 0x08, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
 
 	ret = i2c->xfer (i2c, msg, 2);
 
@@ -110,7 +110,7 @@
 int sp5659_write (struct dvb_i2c_bus *i2c, u8 data [4])
 {
         int ret;
-        struct i2c_msg msg = { addr: 0x61, flags: 0, buf: data, len: 4 };
+        struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = 4 };
 
         ret = i2c->xfer (i2c, &msg, 1);
 
diff -Nru a/drivers/media/dvb/frontends/alps_tdlb7.c b/drivers/media/dvb/frontends/alps_tdlb7.c
--- a/drivers/media/dvb/frontends/alps_tdlb7.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/media/dvb/frontends/alps_tdlb7.c	Mon Dec  9 18:46:35 2002
@@ -73,21 +73,15 @@
 
 static
 struct dvb_frontend_info tdlb7_info = {
-	name: "Alps TDLB7",
-	type: FE_OFDM,
-	frequency_min: 470000000,
-	frequency_max: 860000000,
-	frequency_stepsize: 166666,
-#if 0
-    	frequency_tolerance: ???,
-	symbol_rate_min: ???,
-	symbol_rate_max: ???,
-	symbol_rate_tolerance: ???,
-	notifier_delay: 0,
-#endif
-	caps: FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-	      FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-	      FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64
+	.name			= "Alps TDLB7",
+	.type			= FE_OFDM,
+	.frequency_min		= 470000000,
+	.frequency_max		= 860000000,
+	.frequency_stepsize	= 166666,
+	.caps			= FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
+				  FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
+				  FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+				  FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64
 };
 
 
@@ -95,7 +89,7 @@
 int sp8870_writereg (struct dvb_i2c_bus *i2c, u16 reg, u16 data)
 {
         u8 buf [] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff };
-	struct i2c_msg msg = { addr: 0x71, flags: 0, buf: buf, len: 4 };
+	struct i2c_msg msg = { .addr = 0x71, .flags = 0, .buf = buf, .len = 4 };
 	int err;
 
         if ((err = i2c->xfer (i2c, &msg, 1)) != 1) {
@@ -113,8 +107,8 @@
 	int ret;
 	u8 b0 [] = { reg >> 8 , reg & 0xff };
 	u8 b1 [] = { 0, 0 };
-	struct i2c_msg msg [] = { { addr: 0x71, flags: 0, buf: b0, len: 2 },
-			   { addr: 0x71, flags: I2C_M_RD, buf: b1, len: 2 } };
+	struct i2c_msg msg [] = { { .addr = 0x71, .flags = 0, .buf = b0, .len = 2 },
+			   { .addr = 0x71, .flags = I2C_M_RD, .buf = b1, .len = 2 } };
 
 	ret = i2c->xfer (i2c, msg, 2);
 
@@ -129,7 +123,7 @@
 int sp5659_write (struct dvb_i2c_bus *i2c, u8 data [4])
 {
         int ret;
-        struct i2c_msg msg = { addr: 0x60, flags: 0, buf: data, len: 4 };
+        struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = 4 };
 
         ret = i2c->xfer (i2c, &msg, 1);
 
@@ -377,7 +371,7 @@
 int tdlb7_attach (struct dvb_i2c_bus *i2c)
 {
 
-	struct i2c_msg msg = { addr: 0x71, flags: 0, buf: NULL, len: 0 };
+	struct i2c_msg msg = { .addr = 0x71, .flags = 0, .buf = NULL, .len = 0 };
 
 	dprintk ("%s\n", __FUNCTION__);
 
diff -Nru a/drivers/media/dvb/frontends/alps_tdmb7.c b/drivers/media/dvb/frontends/alps_tdmb7.c
--- a/drivers/media/dvb/frontends/alps_tdmb7.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/media/dvb/frontends/alps_tdmb7.c	Mon Dec  9 18:46:35 2002
@@ -33,21 +33,15 @@
 
 static
 struct dvb_frontend_info tdmb7_info = {
-	name: "Alps TDMB7",
-	type: FE_OFDM,
-	frequency_min: 470000000,
-	frequency_max: 860000000,
-	frequency_stepsize: 166667,
-#if 0
-    	frequency_tolerance: ???,
-	symbol_rate_min: ???,
-	symbol_rate_max: ???,
-	symbol_rate_tolerance: 500,  /* ppm */
-	notifier_delay: 0,
-#endif
-	caps: FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-	      FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-	      FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64
+	.name			= "Alps TDMB7",
+	.type			= FE_OFDM,
+	.frequency_min		= 470000000,
+	.frequency_max		= 860000000,
+	.frequency_stepsize	= 166667,
+	.caps			= FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
+				  FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
+				  FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+				  FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64
 };
 
 
@@ -87,7 +81,7 @@
 {
 	int ret;
 	u8 buf [] = { reg, data };
-	struct i2c_msg msg = { addr: 0x43, flags: 0, buf: buf, len: 2 };
+	struct i2c_msg msg = { .addr = 0x43, .flags = 0, .buf = buf, .len = 2 };
 
 	dprintk ("%s\n", __FUNCTION__);
 
@@ -107,8 +101,8 @@
 	int ret;
 	u8 b0 [] = { reg };
 	u8 b1 [] = { 0 };
-	struct i2c_msg msg [] = { { addr: 0x43, flags: 0, buf: b0, len: 1 },
-			   { addr: 0x43, flags: I2C_M_RD, buf: b1, len: 1 } };
+	struct i2c_msg msg [] = { { .addr = 0x43, .flags = 0, .buf = b0, .len = 1 },
+			   { .addr = 0x43, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
         
 	dprintk ("%s\n", __FUNCTION__);
 
@@ -124,7 +118,7 @@
 static
 int pll_write (struct dvb_i2c_bus *i2c, u8 data [4])
 {
-	struct i2c_msg msg = { addr: 0x61, flags: 0, buf: data, len: 4 };
+	struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = 4 };
 	int ret;
 
 	cx22700_writereg (i2c, 0x0a, 0x00);  /* open i2c bus switch */
@@ -418,7 +412,7 @@
 static
 int tdmb7_attach (struct dvb_i2c_bus *i2c)
 {
-	struct i2c_msg msg = { addr: 0x43, flags: 0, buf: NULL, len: 0 };
+	struct i2c_msg msg = { .addr = 0x43, .flags = 0, .buf = NULL, .len = 0 };
 
 	dprintk ("%s\n", __FUNCTION__);
 
diff -Nru a/drivers/media/dvb/frontends/grundig_29504-401.c b/drivers/media/dvb/frontends/grundig_29504-401.c
--- a/drivers/media/dvb/frontends/grundig_29504-401.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/media/dvb/frontends/grundig_29504-401.c	Mon Dec  9 18:46:35 2002
@@ -34,18 +34,14 @@
 
 
 struct dvb_frontend_info grundig_29504_401_info = {
-	name: "Grundig 29504-401",
-	type: FE_OFDM,
-/*	frequency_min: ???,*/
-/*	frequency_max: ???,*/
-	frequency_stepsize: 166666,
-/*      frequency_tolerance: ???,*/
-/*      symbol_rate_tolerance: ???,*/
-	notifier_delay: 0,
-	caps: FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 
-	      FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
-	      FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
-	      FE_CAN_MUTE_TS
+	.name			= "Grundig 29504-401",
+	.type			= FE_OFDM,
+	.frequency_stepsize	= 166666,
+	.caps 			= FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
+				  FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
+				  FE_CAN_FEC_7_8 | FE_CAN_QPSK |
+				  FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+				  FE_CAN_MUTE_TS
 };
 
 
@@ -54,7 +50,7 @@
 {
 	int ret;
 	u8 buf [] = { reg, data };
-	struct i2c_msg msg = { addr: 0x55, flags: 0, buf: buf, len: 2 };
+	struct i2c_msg msg = { .addr = 0x55, .flags = 0, .buf = buf, .len = 2 };
 
 	if ((ret = i2c->xfer (i2c, &msg, 1)) != 1)
 		dprintk ("%s: write_reg error (reg == %02x) = %02x!\n",
@@ -70,8 +66,8 @@
 	int ret;
 	u8 b0 [] = { reg };
 	u8 b1 [] = { 0 };
-	struct i2c_msg msg [] = { { addr: 0x55, flags: 0, buf: b0, len: 1 },
-			   { addr: 0x55, flags: I2C_M_RD, buf: b1, len: 1 } };
+	struct i2c_msg msg [] = { { .addr = 0x55, .flags = 0, .buf = b0, .len = 1 },
+			   { .addr = 0x55, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
 
 	ret = i2c->xfer (i2c, msg, 2);
 
@@ -86,7 +82,7 @@
 int tsa5060_write (struct dvb_i2c_bus *i2c, u8 data [4])
 {
 	int ret;
-	struct i2c_msg msg = { addr: 0x61, flags: 0, buf: data, len: 4 };
+	struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = 4 };
 
 	if ((ret = i2c->xfer (i2c, &msg, 1)) != 1)
 		dprintk ("%s: write_reg error == %02x!\n", __FUNCTION__, ret);
@@ -273,7 +269,7 @@
 void reset_and_configure (struct dvb_i2c_bus *i2c)
 {
 	u8 buf [] = { 0x06 };
-	struct i2c_msg msg = { addr: 0x00, flags: 0, buf: buf, len: 1 };
+	struct i2c_msg msg = { .addr = 0x00, .flags = 0, .buf = buf, .len = 1 };
 
 	i2c->xfer (i2c, &msg, 1);
 }
@@ -432,8 +428,8 @@
 {
 	u8 b0 [] = { 0x1a };
 	u8 b1 [] = { 0x00 };
-	struct i2c_msg msg [] = { { addr: 0x55, flags: 0, buf: b0, len: 1 },
-			   { addr: 0x55, flags: I2C_M_RD, buf: b1, len: 1 } };
+	struct i2c_msg msg [] = { { .addr = 0x55, .flags = 0, .buf = b0, .len = 1 },
+			   { .addr = 0x55, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
 
 	if (i2c->xfer (i2c, msg, 2) == 2)   /*  probably an EEPROM... */
 		return -ENODEV;
diff -Nru a/drivers/media/dvb/frontends/grundig_29504-491.c b/drivers/media/dvb/frontends/grundig_29504-491.c
--- a/drivers/media/dvb/frontends/grundig_29504-491.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/media/dvb/frontends/grundig_29504-491.c	Mon Dec  9 18:46:50 2002
@@ -36,22 +36,20 @@
 
 static
 struct dvb_frontend_info grundig_29504_491_info = {
-	name: "Grundig 29504-491, (TDA8083 based)",
-	type: FE_QPSK,
-	frequency_min: 950000,     /* FIXME: guessed! */
-	frequency_max: 1400000,    /* FIXME: guessed! */
-	frequency_stepsize: 125,   /* kHz for QPSK frontends */
-/*      frequency_tolerance: ???,*/
-	symbol_rate_min: 1000000,   /* FIXME: guessed! */
-	symbol_rate_max: 45000000,  /* FIXME: guessed! */
-/*      symbol_rate_tolerance: ???,*/
-	notifier_delay: 0,
-	caps:	FE_CAN_INVERSION_AUTO |
-		FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-		FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
-		FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
-		FE_CAN_QPSK |
-		FE_CAN_MUTE_TS
+	.name			= "Grundig 29504-491, (TDA8083 based)",
+	.type			= FE_QPSK,
+	.frequency_min		= 950000,     /* FIXME: guessed! */
+	.frequency_max		= 1400000,    /* FIXME: guessed! */
+	.frequency_stepsize	= 125,   /* kHz for QPSK frontends */
+	.symbol_rate_min	= 1000000,   /* FIXME: guessed! */
+	.symbol_rate_max	= 45000000,  /* FIXME: guessed! */
+	.caps			= FE_CAN_INVERSION_AUTO |
+				  FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
+				  FE_CAN_FEC_3_4 | FE_CAN_FEC_4_5 |
+				  FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
+				  FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 |
+				  FE_CAN_FEC_AUTO | FE_CAN_QPSK |
+				  FE_CAN_MUTE_TS
 };
 
 
@@ -73,7 +71,7 @@
 {
 	int ret;
 	u8 buf [] = { reg, data };
-	struct i2c_msg msg = { addr: 0x68, flags: 0, buf: buf, len: 2 };
+	struct i2c_msg msg = { .addr = 0x68, .flags = 0, .buf = buf, .len = 2 };
 
         ret = i2c->xfer (i2c, &msg, 1);
 
@@ -89,8 +87,8 @@
 int tda8083_readregs (struct dvb_i2c_bus *i2c, u8 reg1, u8 *b, u8 len)
 {
 	int ret;
-	struct i2c_msg msg [] = { { addr: 0x68, flags: 0, buf: &reg1, len: 1 },
-			   { addr: 0x68, flags: I2C_M_RD, buf: b, len: len } };
+	struct i2c_msg msg [] = { { .addr = 0x68, .flags = 0, .buf = &reg1, .len = 1 },
+			   { .addr = 0x68, .flags = I2C_M_RD, .buf = b, .len = len } };
 
 	ret = i2c->xfer (i2c, msg, 2);
 
@@ -117,7 +115,7 @@
 int tsa5522_write (struct dvb_i2c_bus *i2c, u8 data [4])
 {
 	int ret;
-	struct i2c_msg msg = { addr: 0x61, flags: 0, buf: data, len: 4 };
+	struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = 4 };
 
 	ret = i2c->xfer (i2c, &msg, 1);
 
diff -Nru a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c
--- a/drivers/media/dvb/frontends/ves1820.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/media/dvb/frontends/ves1820.c	Mon Dec  9 18:46:37 2002
@@ -59,20 +59,13 @@
 
 static
 struct dvb_frontend_info ves1820_info = {
-	name: "VES1820/Grundig tuner as used on the Siemens DVB-C card",
-	type: FE_QAM,
-	frequency_stepsize: 62500,
-	frequency_min: 51000000,
-	frequency_max: 858000000,
-#if 0
-	frequency_tolerance: ???,
-	symbol_rate_min: ???,
-	symbol_rate_max: ???,
-	symbol_rate_tolerance: ???,  /* ppm */  /* == 8% (spec p. 5) */
-	notifier_delay: ?,
-#endif
-	caps: FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
-		FE_CAN_QAM_128 | FE_CAN_QAM_256
+	.name	= "VES1820/Grundig tuner as used on the Siemens DVB-C card",
+	.type	= FE_QAM,
+	.frequency_stepsize	= 62500,
+	.frequency_min		= 51000000,
+	.frequency_max		= 858000000,
+	.caps	= FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
+		  FE_CAN_QAM_128 | FE_CAN_QAM_256
 };
 
 
@@ -95,7 +88,7 @@
 {
         int ret;
         u8 buf[] = { 0x00, reg, data };
-	struct i2c_msg msg = { addr: 0x09, flags: 0, buf: buf, len: 3 };
+	struct i2c_msg msg = { .addr = 0x09, .flags = 0, .buf = buf, .len = 3 };
 
 	ret = i2c->xfer (i2c, &msg, 1);
 
@@ -115,8 +108,8 @@
 	int ret;
 	u8 b0 [] = { 0x00, reg };
 	u8 b1 [] = { 0 };
-	struct i2c_msg msg [] = { { addr: 0x09, flags: 0, buf: b0, len: 2 },
-	                   { addr: 0x09, flags: I2C_M_RD, buf: b1, len: 1 } };
+	struct i2c_msg msg [] = { { .addr = 0x09, .flags = 0, .buf = b0, .len = 2 },
+	                   { .addr = 0x09, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
 
 
 	ret = i2c->xfer (i2c, msg, 2);
@@ -132,7 +125,7 @@
 int tuner_write (struct dvb_i2c_bus *i2c, u8 addr, u8 data [4])
 {
         int ret;
-        struct i2c_msg msg = { addr: addr, flags: 0, buf: data, len: 4 };
+        struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 };
 
         ret = i2c->xfer (i2c, &msg, 1);
 
@@ -178,7 +171,7 @@
 int probe_tuner (struct dvb_frontend *frontend)
 {
 	struct dvb_i2c_bus *i2c = frontend->i2c;
-	struct i2c_msg msg = { addr: 0x61, flags: 0, buf: NULL, len: 0 };
+	struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = NULL, .len = 0 };
 
 	if (i2c->xfer(i2c, &msg, 1) == 1) {
 		SET_TUNER(frontend,0);
@@ -199,8 +192,8 @@
 	u8 b0 [] = { 0xff };
 	u8 pwm;
 	int i;
-	struct i2c_msg msg [] = { { addr: 0x50, flags: 0, buf: b0, len: 1 },
-	                   { addr: 0x50, flags: I2C_M_RD, buf: &pwm, len: 1 } };
+	struct i2c_msg msg [] = { { .addr = 0x50, .flags = 0, .buf = b0, .len = 1 },
+	                   { .addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1 } };
         
         dprintk("VES1820: init chip\n");
 
diff -Nru a/drivers/media/radio/miropcm20-radio.c b/drivers/media/radio/miropcm20-radio.c
--- a/drivers/media/radio/miropcm20-radio.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/media/radio/miropcm20-radio.c	Mon Dec  9 18:46:35 2002
@@ -217,26 +217,25 @@
 }
 
 static struct pcm20_device pcm20_unit = {
-	freq:   87*16000,
-	muted:  1,
-	stereo: 0
+	.freq   = 87*16000,
+	.muted  = 1,
 };
 
 static struct file_operations pcm20_fops = {
-	owner:		THIS_MODULE,
-	open:           video_exclusive_open,
-	release:        video_exclusive_release,
-	ioctl:		pcm20_ioctl,
-	llseek:         no_llseek,
+	.owner		= THIS_MODULE,
+	.open           = video_exclusive_open,
+	.release        = video_exclusive_release,
+	.ioctl		= pcm20_ioctl,
+	.llseek         = no_llseek,
 };
 
 static struct video_device pcm20_radio = {
-	owner:		THIS_MODULE,
-	name:		"Miro PCM 20 radio",
-	type:		VID_TYPE_TUNER,
-	hardware:	VID_HARDWARE_RTRACK,
-	fops:           &pcm20_fops,
-	priv:		&pcm20_unit
+	.owner		= THIS_MODULE,
+	.name		= "Miro PCM 20 radio",
+	.type		= VID_TYPE_TUNER,
+	.hardware	= VID_HARDWARE_RTRACK,
+	.fops           = &pcm20_fops,
+	.priv		= &pcm20_unit
 };
 
 static int __init pcm20_init(void)
diff -Nru a/drivers/media/radio/miropcm20-rds.c b/drivers/media/radio/miropcm20-rds.c
--- a/drivers/media/radio/miropcm20-rds.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/media/radio/miropcm20-rds.c	Mon Dec  9 18:46:34 2002
@@ -16,8 +16,7 @@
 #include <linux/devfs_fs_kernel.h>
 #include "miropcm20-rds-core.h"
 
-devfs_handle_t dfsh;
-char * text_buffer;
+static char * text_buffer;
 static int rds_users = 0;
 
 
@@ -105,35 +104,30 @@
 }
 
 static struct file_operations rds_f_ops = {
-	owner:	THIS_MODULE,
-	read:    rds_f_read,
-	open:    rds_f_open,
-	release: rds_f_release
+	.owner		= THIS_MODULE,
+	.read		= rds_f_read,
+	.open		= rds_f_open,
+	.release	= rds_f_release
 };
 
 
 static int __init miropcm20_rds_init(void)
 {
-	if ((dfsh = devfs_register(NULL, "v4l/rds/radiotext", 
+	if (!devfs_register(NULL, "v4l/rds/radiotext", 
 				   DEVFS_FL_DEFAULT | DEVFS_FL_AUTO_DEVNUM,
 				   0, 0, S_IRUGO | S_IFCHR, &rds_f_ops, NULL))
-	    == NULL)
-		goto devfs_register;
+		return -EINVAL;
 
 	printk("miropcm20-rds: userinterface driver loaded.\n");
 #if DEBUG
 	printk("v4l-name: %s\n", devfs_get_name(pcm20_radio.devfs_handle, 0));
 #endif
-
 	return 0;
-
- devfs_register:
-	return -EINVAL;
 }
 
 static void __exit miropcm20_rds_cleanup(void)
 {
-	devfs_unregister(dfsh);
+	devfs_remove("v4l/rds/radiotext");
 }
 
 module_init(miropcm20_rds_init);
diff -Nru a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
--- a/drivers/media/radio/radio-aimslab.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/media/radio/radio-aimslab.c	Mon Dec  9 18:46:35 2002
@@ -300,20 +300,20 @@
 static struct rt_device rtrack_unit;
 
 static struct file_operations rtrack_fops = {
-	owner:		THIS_MODULE,
-	open:           video_exclusive_open,
-	release:        video_exclusive_release,
-	ioctl:	        rt_ioctl,
-	llseek:         no_llseek,
+	.owner		= THIS_MODULE,
+	.open           = video_exclusive_open,
+	.release        = video_exclusive_release,
+	.ioctl	        = rt_ioctl,
+	.llseek         = no_llseek,
 };
 
 static struct video_device rtrack_radio=
 {
-	owner:		THIS_MODULE,
-	name:		"RadioTrack radio",
-	type:		VID_TYPE_TUNER,
-	hardware:	VID_HARDWARE_RTRACK,
-	fops:           &rtrack_fops,
+	.owner		= THIS_MODULE,
+	.name		= "RadioTrack radio",
+	.type		= VID_TYPE_TUNER,
+	.hardware	= VID_HARDWARE_RTRACK,
+	.fops           = &rtrack_fops,
 };
 
 static int __init rtrack_init(void)
diff -Nru a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
--- a/drivers/media/radio/radio-aztech.c	Mon Dec  9 18:46:52 2002
+++ b/drivers/media/radio/radio-aztech.c	Mon Dec  9 18:46:52 2002
@@ -252,20 +252,20 @@
 static struct az_device aztech_unit;
 
 static struct file_operations aztech_fops = {
-	owner:		THIS_MODULE,
-	open:           video_exclusive_open,
-	release:        video_exclusive_release,
-	ioctl:		az_ioctl,
-	llseek:         no_llseek,
+	.owner		= THIS_MODULE,
+	.open           = video_exclusive_open,
+	.release        = video_exclusive_release,
+	.ioctl		= az_ioctl,
+	.llseek         = no_llseek,
 };
 
 static struct video_device aztech_radio=
 {
-	owner:		THIS_MODULE,
-	name:		"Aztech radio",
-	type:		VID_TYPE_TUNER,
-	hardware:	VID_HARDWARE_AZTECH,
-	fops:           &aztech_fops,
+	.owner		= THIS_MODULE,
+	.name		= "Aztech radio",
+	.type		= VID_TYPE_TUNER,
+	.hardware	= VID_HARDWARE_AZTECH,
+	.fops           = &aztech_fops,
 };
 
 static int __init aztech_init(void)
diff -Nru a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
--- a/drivers/media/radio/radio-cadet.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/media/radio/radio-cadet.c	Mon Dec  9 18:46:36 2002
@@ -524,21 +524,21 @@
 
 
 static struct file_operations cadet_fops = {
-	owner:		THIS_MODULE,
-	open:		cadet_open,
-	release:       	cadet_release,
-	read:		cadet_read,
-	ioctl:		cadet_ioctl,
-	llseek:         no_llseek,
+	.owner		= THIS_MODULE,
+	.open		= cadet_open,
+	.release       	= cadet_release,
+	.read		= cadet_read,
+	.ioctl		= cadet_ioctl,
+	.llseek         = no_llseek,
 };
 
 static struct video_device cadet_radio=
 {
-	owner:		THIS_MODULE,
-	name:		"Cadet radio",
-	type:		VID_TYPE_TUNER,
-	hardware:	VID_HARDWARE_CADET,
-	fops:           &cadet_fops,
+	.owner		= THIS_MODULE,
+	.name		= "Cadet radio",
+	.type		= VID_TYPE_TUNER,
+	.hardware	= VID_HARDWARE_CADET,
+	.fops           = &cadet_fops,
 };
 
 static int isapnp_cadet_probe(void)
diff -Nru a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
--- a/drivers/media/radio/radio-gemtek-pci.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/media/radio/radio-gemtek-pci.c	Mon Dec  9 18:46:34 2002
@@ -298,19 +298,19 @@
 static u8 mx = 1;
 
 static struct file_operations gemtek_pci_fops = {
-	owner:		THIS_MODULE,
-	open:           video_exclusive_open,
-	release:        video_exclusive_release,
-	ioctl:		gemtek_pci_ioctl,
-	llseek:         no_llseek,
+	.owner		= THIS_MODULE,
+	.open           = video_exclusive_open,
+	.release        = video_exclusive_release,
+	.ioctl		= gemtek_pci_ioctl,
+	.llseek         = no_llseek,
 };
 
 static struct video_device vdev_template = {
-	owner:         THIS_MODULE,
-	name:          "Gemtek PCI Radio",
-	type:          VID_TYPE_TUNER,
-	hardware:      VID_HARDWARE_GEMTEK,
-	fops:          &gemtek_pci_fops,
+	.owner         = THIS_MODULE,
+	.name          = "Gemtek PCI Radio",
+	.type          = VID_TYPE_TUNER,
+	.hardware      = VID_HARDWARE_GEMTEK,
+	.fops          = &gemtek_pci_fops,
 };
 
 static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci_device_id *pci_id )
@@ -387,10 +387,10 @@
 
 static struct pci_driver gemtek_pci_driver =
 {
-    name:	"gemtek_pci",
-id_table:	gemtek_pci_id,
-   probe:	gemtek_pci_probe,
-  remove:	__devexit_p(gemtek_pci_remove),
+	.name		= "gemtek_pci",
+	.id_table	= gemtek_pci_id,
+	.probe		= gemtek_pci_probe,
+	.remove		= __devexit_p(gemtek_pci_remove),
 };
 
 static int __init gemtek_pci_init_module( void )
diff -Nru a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
--- a/drivers/media/radio/radio-gemtek.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/media/radio/radio-gemtek.c	Mon Dec  9 18:46:34 2002
@@ -229,20 +229,20 @@
 static struct gemtek_device gemtek_unit;
 
 static struct file_operations gemtek_fops = {
-	owner:		THIS_MODULE,
-	open:           video_exclusive_open,
-	release:        video_exclusive_release,
-	ioctl:		gemtek_ioctl,
-	llseek:         no_llseek,
+	.owner		= THIS_MODULE,
+	.open           = video_exclusive_open,
+	.release        = video_exclusive_release,
+	.ioctl		= gemtek_ioctl,
+	.llseek         = no_llseek,
 };
 
 static struct video_device gemtek_radio=
 {
-	owner:		THIS_MODULE,
-	name:		"GemTek radio",
-	type:		VID_TYPE_TUNER,
-	hardware:	VID_HARDWARE_GEMTEK,
-	fops:           &gemtek_fops,
+	.owner		= THIS_MODULE,
+	.name		= "GemTek radio",
+	.type		= VID_TYPE_TUNER,
+	.hardware	= VID_HARDWARE_GEMTEK,
+	.fops           = &gemtek_fops,
 };
 
 static int __init gemtek_init(void)
@@ -269,13 +269,13 @@
 	printk(KERN_INFO "GemTek Radio Card driver.\n");
 
 	spin_lock_init(&lock);
- 	/* mute card - prevents noisy bootups */
-	outb(0x10, io);
-	udelay(5);
-	gemtek_unit.muted = 1;
 
 	/* this is _maybe_ unnecessary */
 	outb(0x01, io);
+
+ 	/* mute card - prevents noisy bootups */
+	gemtek_unit.muted = 0;
+	gemtek_mute(&gemtek_unit);
 
 	return 0;
 }
diff -Nru a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
--- a/drivers/media/radio/radio-maestro.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/media/radio/radio-maestro.c	Mon Dec  9 18:46:38 2002
@@ -68,20 +68,20 @@
 		       unsigned int cmd, unsigned long arg);
 
 static struct file_operations maestro_fops = {
-	owner:		THIS_MODULE,
-	open:           video_exclusive_open,
-	release:        video_exclusive_release,
-	ioctl:		radio_ioctl,
-	llseek:         no_llseek,
+	.owner		= THIS_MODULE,
+	.open           = video_exclusive_open,
+	.release        = video_exclusive_release,
+	.ioctl		= radio_ioctl,
+	.llseek         = no_llseek,
 };
 
 static struct video_device maestro_radio=
 {
-	owner:		THIS_MODULE,
-	name:		"Maestro radio",
-	type:		VID_TYPE_TUNER,
-	hardware:	VID_HARDWARE_SF16MI,
-	fops:           &maestro_fops,
+	.owner		= THIS_MODULE,
+	.name		= "Maestro radio",
+	.type		= VID_TYPE_TUNER,
+	.hardware	= VID_HARDWARE_SF16MI,
+	.fops           = &maestro_fops,
 };
 
 static struct radio_device
diff -Nru a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
--- a/drivers/media/radio/radio-maxiradio.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/media/radio/radio-maxiradio.c	Mon Dec  9 18:46:51 2002
@@ -76,19 +76,19 @@
 		       unsigned int cmd, unsigned long arg);
 
 static struct file_operations maxiradio_fops = {
-	owner:		THIS_MODULE,
-	open:           video_exclusive_open,
-	release:        video_exclusive_release,
-	ioctl:	        radio_ioctl,
-	llseek:         no_llseek,
+	.owner		= THIS_MODULE,
+	.open           = video_exclusive_open,
+	.release        = video_exclusive_release,
+	.ioctl	        = radio_ioctl,
+	.llseek         = no_llseek,
 };
 static struct video_device maxiradio_radio =
 {
-	owner:		THIS_MODULE,
-	name:		"Maxi Radio FM2000 radio",
-	type:		VID_TYPE_TUNER,
-	hardware:	VID_HARDWARE_SF16MI,
-	fops:           &maxiradio_fops,
+	.owner		= THIS_MODULE,
+	.name		= "Maxi Radio FM2000 radio",
+	.type		= VID_TYPE_TUNER,
+	.hardware	= VID_HARDWARE_SF16MI,
+	.fops           = &maxiradio_fops,
 };
 
 static struct radio_device
@@ -336,10 +336,10 @@
 MODULE_DEVICE_TABLE(pci, maxiradio_pci_tbl);
 
 static struct pci_driver maxiradio_driver = {
-	name:		"radio-maxiradio",
-	id_table:	maxiradio_pci_tbl,
-	probe:		maxiradio_init_one,
-	remove:		__devexit_p(maxiradio_remove_one),
+	.name		= "radio-maxiradio",
+	.id_table	= maxiradio_pci_tbl,
+	.probe		= maxiradio_init_one,
+	.remove		= __devexit_p(maxiradio_remove_one),
 };
 
 int __init maxiradio_radio_init(void)
diff -Nru a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
--- a/drivers/media/radio/radio-rtrack2.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/media/radio/radio-rtrack2.c	Mon Dec  9 18:46:50 2002
@@ -195,20 +195,20 @@
 static struct rt_device rtrack2_unit;
 
 static struct file_operations rtrack2_fops = {
-	owner:		THIS_MODULE,
-	open:           video_exclusive_open,
-	release:        video_exclusive_release,
-	ioctl:		rt_ioctl,
-	llseek:         no_llseek,
+	.owner		= THIS_MODULE,
+	.open           = video_exclusive_open,
+	.release        = video_exclusive_release,
+	.ioctl		= rt_ioctl,
+	.llseek         = no_llseek,
 };
 
 static struct video_device rtrack2_radio=
 {
-	owner:		THIS_MODULE,
-	name:		"RadioTrack II radio",
-	type:		VID_TYPE_TUNER,
-	hardware:	VID_HARDWARE_RTRACK2,
-	fops:           &rtrack2_fops,
+	.owner		= THIS_MODULE,
+	.name		= "RadioTrack II radio",
+	.type		= VID_TYPE_TUNER,
+	.hardware	= VID_HARDWARE_RTRACK2,
+	.fops           = &rtrack2_fops,
 };
 
 static int __init rtrack2_init(void)
diff -Nru a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
--- a/drivers/media/radio/radio-sf16fmi.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/media/radio/radio-sf16fmi.c	Mon Dec  9 18:46:51 2002
@@ -223,20 +223,20 @@
 static struct fmi_device fmi_unit;
 
 static struct file_operations fmi_fops = {
-	owner:		THIS_MODULE,
-	open:           video_exclusive_open,
-	release:        video_exclusive_release,
-	ioctl:		fmi_ioctl,
-	llseek:         no_llseek,
+	.owner		= THIS_MODULE,
+	.open           = video_exclusive_open,
+	.release        = video_exclusive_release,
+	.ioctl		= fmi_ioctl,
+	.llseek         = no_llseek,
 };
 
 static struct video_device fmi_radio=
 {
-	owner:		THIS_MODULE,
-	name:		"SF16FMx radio",
-	type:		VID_TYPE_TUNER,
-	hardware:	VID_HARDWARE_SF16MI,
-	fops:           &fmi_fops,
+	.owner		= THIS_MODULE,
+	.name		= "SF16FMx radio",
+	.type		= VID_TYPE_TUNER,
+	.hardware	= VID_HARDWARE_SF16MI,
+	.fops           = &fmi_fops,
 };
 
 /* ladis: this is my card. does any other types exist? */
diff -Nru a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
--- a/drivers/media/radio/radio-terratec.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/media/radio/radio-terratec.c	Mon Dec  9 18:46:36 2002
@@ -272,20 +272,20 @@
 static struct tt_device terratec_unit;
 
 static struct file_operations terratec_fops = {
-	owner:		THIS_MODULE,
-	open:           video_exclusive_open,
-	release:        video_exclusive_release,
-	ioctl:		tt_ioctl,
-	llseek:         no_llseek,
+	.owner		= THIS_MODULE,
+	.open           = video_exclusive_open,
+	.release        = video_exclusive_release,
+	.ioctl		= tt_ioctl,
+	.llseek         = no_llseek,
 };
 
 static struct video_device terratec_radio=
 {
-	owner:		THIS_MODULE,
-	name:		"TerraTec ActiveRadio",
-	type:		VID_TYPE_TUNER,
-	hardware:	VID_HARDWARE_TERRATEC,
-	fops:           &terratec_fops,
+	.owner		= THIS_MODULE,
+	.name		= "TerraTec ActiveRadio",
+	.type		= VID_TYPE_TUNER,
+	.hardware	= VID_HARDWARE_TERRATEC,
+	.fops           = &terratec_fops,
 };
 
 static int __init terratec_init(void)
diff -Nru a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c
--- a/drivers/media/radio/radio-trust.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/media/radio/radio-trust.c	Mon Dec  9 18:46:37 2002
@@ -251,20 +251,20 @@
 }
 
 static struct file_operations trust_fops = {
-	owner:		THIS_MODULE,
-	open:           video_exclusive_open,
-	release:        video_exclusive_release,
-	ioctl:		tr_ioctl,
-	llseek:         no_llseek,
+	.owner		= THIS_MODULE,
+	.open           = video_exclusive_open,
+	.release        = video_exclusive_release,
+	.ioctl		= tr_ioctl,
+	.llseek         = no_llseek,
 };
 
 static struct video_device trust_radio=
 {
-	owner:		THIS_MODULE,
-	name:		"Trust FM Radio",
-	type:		VID_TYPE_TUNER,
-	hardware:	VID_HARDWARE_TRUST,
-	fops:           &trust_fops,
+	.owner		= THIS_MODULE,
+	.name		= "Trust FM Radio",
+	.type		= VID_TYPE_TUNER,
+	.hardware	= VID_HARDWARE_TRUST,
+	.fops           = &trust_fops,
 };
 
 static int __init trust_init(void)
diff -Nru a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c
--- a/drivers/media/radio/radio-typhoon.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/media/radio/radio-typhoon.c	Mon Dec  9 18:46:36 2002
@@ -251,26 +251,26 @@
 
 static struct typhoon_device typhoon_unit =
 {
-	iobase:		CONFIG_RADIO_TYPHOON_PORT,
-	curfreq:	CONFIG_RADIO_TYPHOON_MUTEFREQ,
-	mutefreq:	CONFIG_RADIO_TYPHOON_MUTEFREQ,
+	.iobase		= CONFIG_RADIO_TYPHOON_PORT,
+	.curfreq	= CONFIG_RADIO_TYPHOON_MUTEFREQ,
+	.mutefreq	= CONFIG_RADIO_TYPHOON_MUTEFREQ,
 };
 
 static struct file_operations typhoon_fops = {
-	owner:		THIS_MODULE,
-	open:           video_exclusive_open,
-	release:        video_exclusive_release,
-	ioctl:		typhoon_ioctl,
-	llseek:         no_llseek,
+	.owner		= THIS_MODULE,
+	.open           = video_exclusive_open,
+	.release        = video_exclusive_release,
+	.ioctl		= typhoon_ioctl,
+	.llseek         = no_llseek,
 };
 
 static struct video_device typhoon_radio =
 {
-	owner:		THIS_MODULE,
-	name:		"Typhoon Radio",
-	type:		VID_TYPE_TUNER,
-	hardware:	VID_HARDWARE_TYPHOON,
-	fops:           &typhoon_fops,
+	.owner		= THIS_MODULE,
+	.name		= "Typhoon Radio",
+	.type		= VID_TYPE_TUNER,
+	.hardware	= VID_HARDWARE_TYPHOON,
+	.fops           = &typhoon_fops,
 };
 
 #ifdef CONFIG_RADIO_TYPHOON_PROC_FS
diff -Nru a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
--- a/drivers/media/radio/radio-zoltrix.c	Mon Dec  9 18:46:52 2002
+++ b/drivers/media/radio/radio-zoltrix.c	Mon Dec  9 18:46:52 2002
@@ -320,20 +320,20 @@
 
 static struct file_operations zoltrix_fops =
 {
-	owner:		THIS_MODULE,
-	open:           video_exclusive_open,
-	release:        video_exclusive_release,
-	ioctl:		zol_ioctl,
-	llseek:         no_llseek,
+	.owner		= THIS_MODULE,
+	.open           = video_exclusive_open,
+	.release        = video_exclusive_release,
+	.ioctl		= zol_ioctl,
+	.llseek         = no_llseek,
 };
 
 static struct video_device zoltrix_radio =
 {
-	owner:		THIS_MODULE,
-	name:		"Zoltrix Radio Plus",
-	type:		VID_TYPE_TUNER,
-	hardware:	VID_HARDWARE_ZOLTRIX,
-	fops:           &zoltrix_fops,
+	.owner		= THIS_MODULE,
+	.name		= "Zoltrix Radio Plus",
+	.type		= VID_TYPE_TUNER,
+	.hardware	= VID_HARDWARE_ZOLTRIX,
+	.fops           = &zoltrix_fops,
 };
 
 static int __init zoltrix_init(void)
diff -Nru a/drivers/media/video/Makefile b/drivers/media/video/Makefile
--- a/drivers/media/video/Makefile	Mon Dec  9 18:46:36 2002
+++ b/drivers/media/video/Makefile	Mon Dec  9 18:46:36 2002
@@ -35,7 +35,7 @@
 obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o
 obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o
 obj-$(CONFIG_VIDEO_MEYE) += meye.o
-obj-$(CONFIG_VIDEO_SAA7134) += saa7134/ tuner.o tda9887.o
+obj-$(CONFIG_VIDEO_SAA7134) += saa7134/ tuner.o tda9887.o video-buf.o
 obj-$(CONFIG_TUNER_3036) += tuner-3036.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c
--- a/drivers/media/video/adv7175.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/media/video/adv7175.c	Mon Dec  9 18:46:51 2002
@@ -410,30 +410,30 @@
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver i2c_driver_adv7175 = {
-	name:		"adv7175",		/* name */
-	id:		I2C_DRIVERID_ADV717x,	/* ID */
-	flags:		I2C_DF_NOTIFY, //I2C_ADV7175, I2C_ADV7175 + 3,
-	attach_adapter:	adv717x_probe,
-	detach_client:	adv717x_detach,
-	command:	adv717x_command,
-	inc_use:	&adv717x_inc_use,
-	dec_use:	&adv717x_dec_use
+	.name		= "adv7175",		/* name */
+	.id		= I2C_DRIVERID_ADV717x,	/* ID */
+	.flags		= I2C_DF_NOTIFY, //I2C_ADV7175, I2C_ADV7175 + 3,
+	.attach_adapter	= adv717x_probe,
+	.detach_client	= adv717x_detach,
+	.command	= adv717x_command,
+	.inc_use	= &adv717x_inc_use,
+	.dec_use	= &adv717x_dec_use
 };
 
 static struct i2c_driver i2c_driver_adv7176 = {
-	name:		"adv7176",		/* name */
-	id:		I2C_DRIVERID_ADV717x,	/* ID */
-	flags:		I2C_DF_NOTIFY, //I2C_ADV7176, I2C_ADV7176 + 3,
-	attach_adapter:	adv717x_probe,
-	detach_client:	adv717x_detach,
-	command:	adv717x_command,
-	inc_use:	&adv717x_inc_use,
-	dec_use:	&adv717x_dec_use
+	.name		= "adv7176",		/* name */
+	.id		= I2C_DRIVERID_ADV717x,	/* ID */
+	.flags		= I2C_DF_NOTIFY, //I2C_ADV7176, I2C_ADV7176 + 3,
+	.attach_adapter	= adv717x_probe,
+	.detach_client	= adv717x_detach,
+	.command	= adv717x_command,
+	.inc_use	= &adv717x_inc_use,
+	.dec_use	= &adv717x_dec_use
 };
 
 static struct i2c_client client_template = {
-	name:		"adv7175_client",
-	driver:		&i2c_driver_adv7175
+	.name		= "adv7175_client",
+	.driver		= &i2c_driver_adv7175
 };
 
 static int adv717x_init(void)
diff -Nru a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
--- a/drivers/media/video/bttv-cards.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/media/video/bttv-cards.c	Mon Dec  9 18:46:37 2002
@@ -208,350 +208,350 @@
 struct tvcard bttv_tvcards[] = {
 {
 /* ---- card 0x00 ---------------------------------- */
-	name:		" *** UNKNOWN/GENERIC *** ",
-	video_inputs:	4,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	muxsel:		{ 2, 3, 1, 0},
-	tuner_type:	-1,
-},{
-	name:		"MIRO PCTV",
-	video_inputs:	4,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	15,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 2, 0, 0, 0, 10},
-	needs_tvaudio:	1,
-	tuner_type:	-1,
-},{
-	name:		"Hauppauge (bt848)",
-	video_inputs:	4,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	7,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 0, 1, 2, 3, 4},
-	needs_tvaudio:	1,
-	tuner_type:	-1,
-},{
-	name:		"STB, Gateway P/N 6000699 (bt848)",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	7,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 4, 0, 2, 3, 1},
-	no_msp34xx:	1,
-	needs_tvaudio:	1,
-	tuner_type:     TUNER_PHILIPS_NTSC,
-	pll:            PLL_28,
-	has_radio:      1,
+	.name		= " *** UNKNOWN/GENERIC *** ",
+	.video_inputs	= 4,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.muxsel		= { 2, 3, 1, 0},
+	.tuner_type	= -1,
+},{
+	.name		= "MIRO PCTV",
+	.video_inputs	= 4,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 15,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 2, 0, 0, 0, 10},
+	.needs_tvaudio	= 1,
+	.tuner_type	= -1,
+},{
+	.name		= "Hauppauge (bt848)",
+	.video_inputs	= 4,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 7,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 0, 1, 2, 3, 4},
+	.needs_tvaudio	= 1,
+	.tuner_type	= -1,
+},{
+	.name		= "STB, Gateway P/N 6000699 (bt848)",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 7,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 4, 0, 2, 3, 1},
+	.no_msp34xx	= 1,
+	.needs_tvaudio	= 1,
+	.tuner_type     = TUNER_PHILIPS_NTSC,
+	.pll            = PLL_28,
+	.has_radio      = 1,
 },{
 
 /* ---- card 0x04 ---------------------------------- */
-	name:		"Intel Create and Share PCI/ Smart Video Recorder III",
-	video_inputs:	4,
-	audio_inputs:	0,
-	tuner:		-1,
-	svhs:		2,
-	gpiomask:	0,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 0 },
-	needs_tvaudio:	0,
-	tuner_type:	4,
-},{
-	name:		"Diamond DTV2000",
-	video_inputs:	4,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	3,
-	muxsel:		{ 2, 3, 1, 0},
-	audiomux:	{ 0, 1, 0, 1, 3},
-	needs_tvaudio:	1,
-	tuner_type:	-1,
-},{
-	name:		"AVerMedia TVPhone",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		3,
-	muxsel:		{ 2, 3, 1, 1},
-	gpiomask:	0x0f,
-	audiomux:	{ 0x0c, 0x04, 0x08, 0x04, 0},
+	.name		= "Intel Create and Share PCI/ Smart Video Recorder III",
+	.video_inputs	= 4,
+	.audio_inputs	= 0,
+	.tuner		= -1,
+	.svhs		= 2,
+	.gpiomask	= 0,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 0 },
+	.needs_tvaudio	= 0,
+	.tuner_type	= 4,
+},{
+	.name		= "Diamond DTV2000",
+	.video_inputs	= 4,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 3,
+	.muxsel		= { 2, 3, 1, 0},
+	.audiomux	= { 0, 1, 0, 1, 3},
+	.needs_tvaudio	= 1,
+	.tuner_type	= -1,
+},{
+	.name		= "AVerMedia TVPhone",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 3,
+	.muxsel		= { 2, 3, 1, 1},
+	.gpiomask	= 0x0f,
+	.audiomux	= { 0x0c, 0x04, 0x08, 0x04, 0},
 	/*                0x04 for some cards ?? */
-	needs_tvaudio:	1,
-	tuner_type:	-1,
-	audio_hook:	avermedia_tvphone_audio,
-},{
-	name:		"MATRIX-Vision MV-Delta",
-	video_inputs:	5,
-	audio_inputs:	1,
-	tuner:		-1,
-	svhs:		3,
-	gpiomask:	0,
-	muxsel:		{ 2, 3, 1, 0, 0},
-	audiomux:	{0 },
-	needs_tvaudio:	1,
-	tuner_type:	-1,
+	.needs_tvaudio	= 1,
+	.tuner_type	= -1,
+	.audio_hook	= avermedia_tvphone_audio,
+},{
+	.name		= "MATRIX-Vision MV-Delta",
+	.video_inputs	= 5,
+	.audio_inputs	= 1,
+	.tuner		= -1,
+	.svhs		= 3,
+	.gpiomask	= 0,
+	.muxsel		= { 2, 3, 1, 0, 0},
+	.audiomux	= {0 },
+	.needs_tvaudio	= 1,
+	.tuner_type	= -1,
 },{
 
 /* ---- card 0x08 ---------------------------------- */
-	name:		"Lifeview FlyVideo II (Bt848) LR26",
-	video_inputs:	4,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0xc00,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 0, 0xc00, 0x800, 0x400, 0xc00, 0},
-	needs_tvaudio:	1,
-	pll:		PLL_28,
-	tuner_type:	-1,
-},{
-	name:		"IMS/IXmicro TurboTV",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	3,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 1, 1, 2, 3, 0},
-	needs_tvaudio:	0,
-	pll:		PLL_28,
-	tuner_type:	TUNER_TEMIC_PAL,
-},{
-	name:		"Hauppauge (bt878)",
-	video_inputs:	4,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0x0f, /* old: 7 */
-	muxsel:		{ 2, 0, 1, 1},
-	audiomux:	{ 0, 1, 2, 3, 4},
-	needs_tvaudio:	1,
-	pll:		PLL_28,
-	tuner_type:	-1,
-},{
-	name:		"MIRO PCTV pro",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0x3014f,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 0x20001,0x10001, 0, 0,10},
-	needs_tvaudio:	1,
-	tuner_type:	-1,
+	.name		= "Lifeview FlyVideo II (Bt848) LR26",
+	.video_inputs	= 4,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0xc00,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 0, 0xc00, 0x800, 0x400, 0xc00, 0},
+	.needs_tvaudio	= 1,
+	.pll		= PLL_28,
+	.tuner_type	= -1,
+},{
+	.name		= "IMS/IXmicro TurboTV",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 3,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 1, 1, 2, 3, 0},
+	.needs_tvaudio	= 0,
+	.pll		= PLL_28,
+	.tuner_type	= TUNER_TEMIC_PAL,
+},{
+	.name		= "Hauppauge (bt878)",
+	.video_inputs	= 4,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0x0f, /* old: 7 */
+	.muxsel		= { 2, 0, 1, 1},
+	.audiomux	= { 0, 1, 2, 3, 4},
+	.needs_tvaudio	= 1,
+	.pll		= PLL_28,
+	.tuner_type	= -1,
+},{
+	.name		= "MIRO PCTV pro",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0x3014f,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 0x20001,0x10001, 0, 0,10},
+	.needs_tvaudio	= 1,
+	.tuner_type	= -1,
 },{
 
 /* ---- card 0x0c ---------------------------------- */
-	name:		"ADS Technologies Channel Surfer TV (bt848)",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	15,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 13, 14, 11, 7, 0, 0},
-	needs_tvaudio:	1,
-	tuner_type:	-1,
-},{
-	name:		"AVerMedia TVCapture 98",
-	video_inputs:	3,
-	audio_inputs:	4,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	15,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 13, 14, 11, 7, 0, 0},
-	needs_tvaudio:	1,
-	pll:		PLL_28,
-	tuner_type:	TUNER_PHILIPS_PAL,
-},{
-	name:		"Aimslab Video Highway Xtreme (VHX)",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	7,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 0, 2, 1, 3, 4}, /* old: { 0, 1, 2, 3, 4} */
-	needs_tvaudio:	1,
-	pll:		PLL_28,
-	tuner_type:	-1,
-},{
-	name:		"Zoltrix TV-Max",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	15,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{0 , 0, 1 , 0, 10},
-	needs_tvaudio:	1,
-	tuner_type:	-1,
+	.name		= "ADS Technologies Channel Surfer TV (bt848)",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 15,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 13, 14, 11, 7, 0, 0},
+	.needs_tvaudio	= 1,
+	.tuner_type	= -1,
+},{
+	.name		= "AVerMedia TVCapture 98",
+	.video_inputs	= 3,
+	.audio_inputs	= 4,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 15,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 13, 14, 11, 7, 0, 0},
+	.needs_tvaudio	= 1,
+	.pll		= PLL_28,
+	.tuner_type	= TUNER_PHILIPS_PAL,
+},{
+	.name		= "Aimslab Video Highway Xtreme (VHX)",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 7,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 0, 2, 1, 3, 4}, /* old: { 0, 1, 2, 3, 4} */
+	.needs_tvaudio	= 1,
+	.pll		= PLL_28,
+	.tuner_type	= -1,
+},{
+	.name		= "Zoltrix TV-Max",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 15,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= {0 , 0, 1 , 0, 10},
+	.needs_tvaudio	= 1,
+	.tuner_type	= -1,
 },{
 
 /* ---- card 0x10 ---------------------------------- */
-	name:		"Prolink Pixelview PlayTV (bt878)",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0x01fe00,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 },
-	needs_tvaudio:	1,
-	pll:		PLL_28,
-	tuner_type:	-1,
-},{
-	name:		"Leadtek WinView 601",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0x8300f8,
-	muxsel:		{ 2, 3, 1, 1,0},
-	audiomux:	{ 0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007},
-	needs_tvaudio:	1,
-	tuner_type:	-1,
-	audio_hook:	winview_audio,
-	has_radio:	1,
-},{
-	name:		"AVEC Intercapture",
-	video_inputs:	3,
-	audio_inputs:	2,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0,
-	muxsel:		{2, 3, 1, 1},
-	audiomux:	{1, 0, 0, 0, 0},
-	needs_tvaudio:	1,
-	tuner_type:	-1,
-},{
-	name:		"Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)",
-	video_inputs:	4,
-	audio_inputs:	1,
-	tuner:		-1,
-	svhs:		-1,
-	gpiomask:	0x8dff00,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 0 },
-	no_msp34xx:	1,
-	tuner_type:	-1,
+	.name		= "Prolink Pixelview PlayTV (bt878)",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0x01fe00,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 },
+	.needs_tvaudio	= 1,
+	.pll		= PLL_28,
+	.tuner_type	= -1,
+},{
+	.name		= "Leadtek WinView 601",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0x8300f8,
+	.muxsel		= { 2, 3, 1, 1,0},
+	.audiomux	= { 0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007},
+	.needs_tvaudio	= 1,
+	.tuner_type	= -1,
+	.audio_hook	= winview_audio,
+	.has_radio	= 1,
+},{
+	.name		= "AVEC Intercapture",
+	.video_inputs	= 3,
+	.audio_inputs	= 2,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0,
+	.muxsel		= {2, 3, 1, 1},
+	.audiomux	= {1, 0, 0, 0, 0},
+	.needs_tvaudio	= 1,
+	.tuner_type	= -1,
+},{
+	.name		= "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)",
+	.video_inputs	= 4,
+	.audio_inputs	= 1,
+	.tuner		= -1,
+	.svhs		= -1,
+	.gpiomask	= 0x8dff00,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 0 },
+	.no_msp34xx	= 1,
+	.tuner_type	= -1,
 },{
 
 /* ---- card 0x14 ---------------------------------- */
-	name:		"CEI Raffles Card",
-	video_inputs:	3,
-	audio_inputs:	3,
-	tuner:		0,
-	svhs:		2,
-	muxsel:		{2, 3, 1, 1},
-	tuner_type:	-1,
-},{
-	name:		"Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50",
-	video_inputs:	4,
-	audio_inputs:	2,  // tuner, line in
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0x1800,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 0, 0x800, 0x1000, 0x1000, 0x1800},
-	pll:		PLL_28,
-	tuner_type:	TUNER_PHILIPS_PAL_I,
-},{
-	name:		"Askey CPH050/ Phoebe Tv Master + FM",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0xc00,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{0, 1, 0x800, 0x400, 0xc00, 0},
-	needs_tvaudio:	1,
-	pll:		PLL_28,
-	tuner_type:	-1,
-},{
-	name:		"Modular Technology MM205 PCTV, bt878",
-	video_inputs:	2,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		-1,
-	gpiomask:	7,
-	muxsel:		{ 2, 3 },
-	audiomux:	{ 0, 0, 0, 0, 0 },
-	no_msp34xx:	1,
-	pll:            PLL_28,
-	tuner_type:     TUNER_ALPS_TSBB5_PAL_I,
+	.name		= "CEI Raffles Card",
+	.video_inputs	= 3,
+	.audio_inputs	= 3,
+	.tuner		= 0,
+	.svhs		= 2,
+	.muxsel		= {2, 3, 1, 1},
+	.tuner_type	= -1,
+},{
+	.name		= "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50",
+	.video_inputs	= 4,
+	.audio_inputs	= 2,  // tuner, line in
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0x1800,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 0, 0x800, 0x1000, 0x1000, 0x1800},
+	.pll		= PLL_28,
+	.tuner_type	= TUNER_PHILIPS_PAL_I,
+},{
+	.name		= "Askey CPH050/ Phoebe Tv Master + FM",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0xc00,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= {0, 1, 0x800, 0x400, 0xc00, 0},
+	.needs_tvaudio	= 1,
+	.pll		= PLL_28,
+	.tuner_type	= -1,
+},{
+	.name		= "Modular Technology MM205 PCTV, bt878",
+	.video_inputs	= 2,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= -1,
+	.gpiomask	= 7,
+	.muxsel		= { 2, 3 },
+	.audiomux	= { 0, 0, 0, 0, 0 },
+	.no_msp34xx	= 1,
+	.pll            = PLL_28,
+	.tuner_type     = TUNER_ALPS_TSBB5_PAL_I,
 },{
 
 /* ---- card 0x18 ---------------------------------- */
-	name:		"Askey CPH05X/06X (bt878) [many vendors]",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0xe00,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{0x400, 0x400, 0x400, 0x400, 0xc00},
-	needs_tvaudio:	1,
-	pll:		PLL_28,
-	tuner_type:	-1,
-},{
-	name:           "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:       0x1f0fff,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:       { 0x20000, 0x30000, 0x10000, 0, 0x40000},
-	needs_tvaudio:	0,
-	tuner_type:	TUNER_PHILIPS_PAL,
-	audio_hook:     terratv_audio,
-},{
-	name:		"Hauppauge WinCam newer (bt878)",
-	video_inputs:	4,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		3,
-	gpiomask:	7,
-	muxsel:		{ 2, 0, 1, 1},
-	audiomux:	{ 0, 1, 2, 3, 4},
-	needs_tvaudio:	1,
-	tuner_type:	-1,
-},{
-	name:		"Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50",
-	video_inputs:	4,
-	audio_inputs:	2,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0x1800,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 0, 0x800, 0x1000, 0x1000, 0x1800},
-	pll:            PLL_28,
-	tuner_type:	TUNER_PHILIPS_SECAM,
+	.name		= "Askey CPH05X/06X (bt878) [many vendors]",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0xe00,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= {0x400, 0x400, 0x400, 0x400, 0xc00},
+	.needs_tvaudio	= 1,
+	.pll		= PLL_28,
+	.tuner_type	= -1,
+},{
+	.name           = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask       = 0x1f0fff,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux       = { 0x20000, 0x30000, 0x10000, 0, 0x40000},
+	.needs_tvaudio	= 0,
+	.tuner_type	= TUNER_PHILIPS_PAL,
+	.audio_hook     = terratv_audio,
+},{
+	.name		= "Hauppauge WinCam newer (bt878)",
+	.video_inputs	= 4,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 3,
+	.gpiomask	= 7,
+	.muxsel		= { 2, 0, 1, 1},
+	.audiomux	= { 0, 1, 2, 3, 4},
+	.needs_tvaudio	= 1,
+	.tuner_type	= -1,
+},{
+	.name		= "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50",
+	.video_inputs	= 4,
+	.audio_inputs	= 2,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0x1800,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 0, 0x800, 0x1000, 0x1000, 0x1800},
+	.pll            = PLL_28,
+	.tuner_type	= TUNER_PHILIPS_SECAM,
 },{
 
 /* ---- card 0x1c ---------------------------------- */
-	name:           "Terratec TerraTV+ Version 1.1 (bt878)",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0x1f0fff,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 0x20000, 0x30000, 0x10000, 0x00000, 0x40000},
-	needs_tvaudio:	0,
-	tuner_type:	TUNER_PHILIPS_PAL,
-	audio_hook:	terratv_audio,
+	.name           = "Terratec TerraTV+ Version 1.1 (bt878)",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0x1f0fff,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 0x20000, 0x30000, 0x10000, 0x00000, 0x40000},
+	.needs_tvaudio	= 0,
+	.tuner_type	= TUNER_PHILIPS_PAL,
+	.audio_hook	= terratv_audio,
 	/* GPIO wiring:
                External 20 pin connector (for Active Radio Upgrade board)
                gpio00: i2c-sda
@@ -585,71 +585,71 @@
 
 },{
 	/* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */
-	name:		"Imagenation PXC200",
-	video_inputs:	5,
-	audio_inputs:	1,
-	tuner:		-1,
-	svhs:		1, /* was: 4 */
-	gpiomask:	0,
-	muxsel:		{ 2, 3, 1, 0, 0},
-	audiomux:	{ 0 },
-	needs_tvaudio:	1,
-	tuner_type:	-1,
-},{
-	name:		"Lifeview FlyVideo 98 LR50",
-	video_inputs:	4,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0x1800,  //0x8dfe00
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 },
-	pll:            PLL_28,
-	tuner_type:	-1,
-},{
-	name:		"Formac iProTV",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	1,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 1, 0, 0, 0, 0 },
-	tuner_type:	-1,
+	.name		= "Imagenation PXC200",
+	.video_inputs	= 5,
+	.audio_inputs	= 1,
+	.tuner		= -1,
+	.svhs		= 1, /* was: 4 */
+	.gpiomask	= 0,
+	.muxsel		= { 2, 3, 1, 0, 0},
+	.audiomux	= { 0 },
+	.needs_tvaudio	= 1,
+	.tuner_type	= -1,
+},{
+	.name		= "Lifeview FlyVideo 98 LR50",
+	.video_inputs	= 4,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0x1800,  //0x8dfe00
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 },
+	.pll            = PLL_28,
+	.tuner_type	= -1,
+},{
+	.name		= "Formac iProTV",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 1,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 1, 0, 0, 0, 0 },
+	.tuner_type	= -1,
 },{
 
 /* ---- card 0x20 ---------------------------------- */
-	name:		"Intel Create and Share PCI/ Smart Video Recorder III",
-	video_inputs:	4,
-	audio_inputs:	0,
-	tuner:		-1,
-	svhs:		2,
-	gpiomask:	0,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 0 },
-	needs_tvaudio:	0,
-	tuner_type:	4,
-},{
-	name:           "Terratec TerraTValue Version Bt878",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0xffff00,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 0x500, 0, 0x300, 0x900, 0x900},
-	needs_tvaudio:	1,
-	pll:		PLL_28,
-	tuner_type:	TUNER_PHILIPS_PAL,
-},{
-	name:		"Leadtek WinFast 2000/ WinFast 2000 XP",
-	video_inputs:	4,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0xc33000,
-	muxsel:		{ 2, 3, 1, 1, 0}, // TV, CVid, SVid, CVid over SVid connector
-	audiomux:	{ 0x422000,0x1000,0x0000,0x620000,0x800000},
+	.name		= "Intel Create and Share PCI/ Smart Video Recorder III",
+	.video_inputs	= 4,
+	.audio_inputs	= 0,
+	.tuner		= -1,
+	.svhs		= 2,
+	.gpiomask	= 0,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 0 },
+	.needs_tvaudio	= 0,
+	.tuner_type	= 4,
+},{
+	.name           = "Terratec TerraTValue Version Bt878",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0xffff00,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 0x500, 0, 0x300, 0x900, 0x900},
+	.needs_tvaudio	= 1,
+	.pll		= PLL_28,
+	.tuner_type	= TUNER_PHILIPS_PAL,
+},{
+	.name		= "Leadtek WinFast 2000/ WinFast 2000 XP",
+	.video_inputs	= 4,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0xc33000,
+	.muxsel		= { 2, 3, 1, 1, 0}, // TV, CVid, SVid, CVid over SVid connector
+	.audiomux	= { 0x422000,0x1000,0x0000,0x620000,0x800000},
 	/* Audio Routing for "WinFast 2000 XP" (no tv stereo !)
 		gpio23 -- hef4052:nEnable (0x800000)
 		gpio12 -- hef4052:A1
@@ -661,216 +661,216 @@
           Note: There exists another variant "Winfast 2000" with tv stereo !?
 	  Note: eeprom only contains FF and pci subsystem id 107d:6606
 	 */
-	needs_tvaudio:	0,
-	pll:		PLL_28,
-	has_radio:	1,
-	tuner_type:	5, // default for now, gpio reads BFFF06 for Pal bg+dk
-	audio_hook:	winfast2000_audio,
-},{
-	name:		"Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II",
-	video_inputs:	4,
-	audio_inputs:	3,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0x1800,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 0, 0x800, 0x1000, 0x1000, 0x1800},
-	pll:		PLL_28,
-	tuner_type:	-1,
+	.needs_tvaudio	= 0,
+	.pll		= PLL_28,
+	.has_radio	= 1,
+	.tuner_type	= 5, // default for now, gpio reads BFFF06 for Pal bg+dk
+	.audio_hook	= winfast2000_audio,
+},{
+	.name		= "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II",
+	.video_inputs	= 4,
+	.audio_inputs	= 3,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0x1800,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 0, 0x800, 0x1000, 0x1000, 0x1800},
+	.pll		= PLL_28,
+	.tuner_type	= -1,
 },{
 
 /* ---- card 0x24 ---------------------------------- */
-	name:		"Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner",
-	video_inputs:	4,
-	audio_inputs:	3,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0x1800,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
-	pll:		PLL_28,
-	tuner_type:	-1,
-	has_radio:	1,
-},{
-	name:		"Prolink PixelView PlayTV pro",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0xff,
-	muxsel:		{ 2, 3, 1, 1 },
-	audiomux:	{ 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 },
-	no_msp34xx:	1,
-	pll:		PLL_28,
-	tuner_type:	-1,
-},{
-	name:		"Askey CPH06X TView99",
-	video_inputs:	4,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0x551e00,
-	muxsel:		{ 2, 3, 1, 0},
-	audiomux:	{ 0x551400, 0x551200, 0, 0, 0x551c00, 0x551200 },
-	needs_tvaudio:	1,
-	pll:		PLL_28,
-	tuner_type:	-1,
-},{
-	name:		"Pinnacle PCTV Studio/Rave",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0x03000F,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 2, 0, 0, 0, 1},
-	needs_tvaudio:	1,
-	pll:		PLL_28,
-	tuner_type:	-1,
+	.name		= "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner",
+	.video_inputs	= 4,
+	.audio_inputs	= 3,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0x1800,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
+	.pll		= PLL_28,
+	.tuner_type	= -1,
+	.has_radio	= 1,
+},{
+	.name		= "Prolink PixelView PlayTV pro",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0xff,
+	.muxsel		= { 2, 3, 1, 1 },
+	.audiomux	= { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 },
+	.no_msp34xx	= 1,
+	.pll		= PLL_28,
+	.tuner_type	= -1,
+},{
+	.name		= "Askey CPH06X TView99",
+	.video_inputs	= 4,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0x551e00,
+	.muxsel		= { 2, 3, 1, 0},
+	.audiomux	= { 0x551400, 0x551200, 0, 0, 0x551c00, 0x551200 },
+	.needs_tvaudio	= 1,
+	.pll		= PLL_28,
+	.tuner_type	= -1,
+},{
+	.name		= "Pinnacle PCTV Studio/Rave",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0x03000F,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 2, 0, 0, 0, 1},
+	.needs_tvaudio	= 1,
+	.pll		= PLL_28,
+	.tuner_type	= -1,
 },{
 
 /* ---- card 0x28 ---------------------------------- */
-	name:		"STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	7,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 4, 0, 2, 3, 1},
-	no_msp34xx:	1,
-	needs_tvaudio:	1,
-	tuner_type:     TUNER_PHILIPS_NTSC,
-	pll:            PLL_28,
-	has_radio:      1,
-},{
-	name:		"AVerMedia TVPhone 98",
-	video_inputs:	3,
-	audio_inputs:	4,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	15,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 13, 4, 11, 7, 0, 0},
-	needs_tvaudio:	1,
-	pll:		PLL_28,
-	tuner_type:	-1,
-	has_radio:	1,
-},{
-	name:		"ProVideo PV951", /* pic16c54 */
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 0, 0, 0, 0, 0},
-	needs_tvaudio:	1,
-	no_msp34xx:	1,
-	pll:		PLL_28,
-	tuner_type:	1,
-},{
-	name:		"Little OnAir TV",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0xe00b,
-	muxsel:		{2, 3, 1, 1},
-	audiomux:	{0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc},
-	no_msp34xx:	1,
-	tuner_type:	-1,
+	.name		= "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 7,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 4, 0, 2, 3, 1},
+	.no_msp34xx	= 1,
+	.needs_tvaudio	= 1,
+	.tuner_type     = TUNER_PHILIPS_NTSC,
+	.pll            = PLL_28,
+	.has_radio      = 1,
+},{
+	.name		= "AVerMedia TVPhone 98",
+	.video_inputs	= 3,
+	.audio_inputs	= 4,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 15,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 13, 4, 11, 7, 0, 0},
+	.needs_tvaudio	= 1,
+	.pll		= PLL_28,
+	.tuner_type	= -1,
+	.has_radio	= 1,
+},{
+	.name		= "ProVideo PV951", /* pic16c54 */
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 0, 0, 0, 0, 0},
+	.needs_tvaudio	= 1,
+	.no_msp34xx	= 1,
+	.pll		= PLL_28,
+	.tuner_type	= 1,
+},{
+	.name		= "Little OnAir TV",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0xe00b,
+	.muxsel		= {2, 3, 1, 1},
+	.audiomux	= {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc},
+	.no_msp34xx	= 1,
+	.tuner_type	= -1,
 },{
 
 /* ---- card 0x2c ---------------------------------- */
-	name:		"Sigma TVII-FM",
-	video_inputs:	2,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		-1,
-	gpiomask:	3,
-	muxsel:		{2, 3, 1, 1},
-	audiomux:	{1, 1, 0, 2, 3},
-	no_msp34xx:	1,
-	pll:		PLL_NONE,
-	tuner_type:	-1,
-},{
-	name:		"MATRIX-Vision MV-Delta 2",
-	video_inputs:	5,
-	audio_inputs:	1,
-	tuner:		-1,
-	svhs:		3,
-	gpiomask:	0,
-	muxsel:		{ 2, 3, 1, 0, 0},
-	audiomux:	{0 },
-	no_msp34xx:	1,
-	pll:		PLL_28,
-	tuner_type:	-1,
-},{
-	name:		"Zoltrix Genie TV/FM",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0xbcf03f,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 0xbc803f, 0xbc903f, 0xbcb03f, 0, 0xbcb03f},
-	no_msp34xx:	1,
-	pll:		PLL_28,
-	tuner_type:	21,
-},{
-	name:		"Terratec TV/Radio+",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0x70000,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 0x20000, 0x30000, 0x10000, 0, 0x40000, 0x20000 },
-	needs_tvaudio:	1,
-	no_msp34xx:	1,
-	pll:		PLL_35,
-	tuner_type:	1,
-	has_radio:	1,
+	.name		= "Sigma TVII-FM",
+	.video_inputs	= 2,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= -1,
+	.gpiomask	= 3,
+	.muxsel		= {2, 3, 1, 1},
+	.audiomux	= {1, 1, 0, 2, 3},
+	.no_msp34xx	= 1,
+	.pll		= PLL_NONE,
+	.tuner_type	= -1,
+},{
+	.name		= "MATRIX-Vision MV-Delta 2",
+	.video_inputs	= 5,
+	.audio_inputs	= 1,
+	.tuner		= -1,
+	.svhs		= 3,
+	.gpiomask	= 0,
+	.muxsel		= { 2, 3, 1, 0, 0},
+	.audiomux	= {0 },
+	.no_msp34xx	= 1,
+	.pll		= PLL_28,
+	.tuner_type	= -1,
+},{
+	.name		= "Zoltrix Genie TV/FM",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0xbcf03f,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 0xbc803f, 0xbc903f, 0xbcb03f, 0, 0xbcb03f},
+	.no_msp34xx	= 1,
+	.pll		= PLL_28,
+	.tuner_type	= 21,
+},{
+	.name		= "Terratec TV/Radio+",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0x70000,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 0x20000, 0x30000, 0x10000, 0, 0x40000, 0x20000 },
+	.needs_tvaudio	= 1,
+	.no_msp34xx	= 1,
+	.pll		= PLL_35,
+	.tuner_type	= 1,
+	.has_radio	= 1,
 },{
 
 /* ---- card 0x30 ---------------------------------- */
-	name:		"Askey CPH03x/ Dynalink Magic TView",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	15,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{2,0,0,0,1},
-	needs_tvaudio:	1,
-	pll:		PLL_28,
-	tuner_type:	-1,
-},{
-	name:		"IODATA GV-BCTV3/PCI",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0x010f00,
-	muxsel:		{2, 3, 0, 0},
-	audiomux:	{0x10000, 0, 0x10000, 0, 0, 0},
-	no_msp34xx:	1,
-	pll:		PLL_28,
-	tuner_type:	TUNER_ALPS_TSHC6_NTSC,
-	audio_hook:	gvbctv3pci_audio,
-},{
-	name:		"Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
-	video_inputs:	4,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		3,
-	gpiomask:	0xAA0000,
-	muxsel:		{ 2,3,1,1 },
-	audiomux:	{ 0x20000, 0, 0x80000, 0x80000, 0xa8000, 0x46000  },
-	no_msp34xx:	1,
-	pll:		PLL_28,
-	tuner_type:	TUNER_PHILIPS_PAL_I,
+	.name		= "Askey CPH03x/ Dynalink Magic TView",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 15,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= {2,0,0,0,1},
+	.needs_tvaudio	= 1,
+	.pll		= PLL_28,
+	.tuner_type	= -1,
+},{
+	.name		= "IODATA GV-BCTV3/PCI",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0x010f00,
+	.muxsel		= {2, 3, 0, 0},
+	.audiomux	= {0x10000, 0, 0x10000, 0, 0, 0},
+	.no_msp34xx	= 1,
+	.pll		= PLL_28,
+	.tuner_type	= TUNER_ALPS_TSHC6_NTSC,
+	.audio_hook	= gvbctv3pci_audio,
+},{
+	.name		= "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
+	.video_inputs	= 4,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 3,
+	.gpiomask	= 0xAA0000,
+	.muxsel		= { 2,3,1,1 },
+	.audiomux	= { 0x20000, 0, 0x80000, 0x80000, 0xa8000, 0x46000  },
+	.no_msp34xx	= 1,
+	.pll		= PLL_28,
+	.tuner_type	= TUNER_PHILIPS_PAL_I,
 	/* GPIO wiring: (different from Rev.4C !)
 		GPIO17: U4.A0 (first hef4052bt)
 		GPIO19: U4.A1
@@ -881,28 +881,28 @@
 	   Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22
 	 */
 },{
-	name:           "Eagle Wireless Capricorn2 (bt878A)",
-	video_inputs:   4,
-	audio_inputs:   1,
-	tuner:          0,
-	svhs:           2,
-	gpiomask:       7,
-	muxsel:         { 2, 0, 1, 1},
-	audiomux:       { 0, 1, 2, 3, 4},
-	pll:            PLL_28,
-	tuner_type:     -1 /* TUNER_ALPS_TMDH2_NTSC */,
+	.name           = "Eagle Wireless Capricorn2 (bt878A)",
+	.video_inputs   = 4,
+	.audio_inputs   = 1,
+	.tuner          = 0,
+	.svhs           = 2,
+	.gpiomask       = 7,
+	.muxsel         = { 2, 0, 1, 1},
+	.audiomux       = { 0, 1, 2, 3, 4},
+	.pll            = PLL_28,
+	.tuner_type     = -1 /* TUNER_ALPS_TMDH2_NTSC */,
 },{
 
 /* ---- card 0x34 ---------------------------------- */
 	/* David Härdeman <david@2gen.com> */
-	name:           "Pinnacle PCTV Studio Pro",
-	video_inputs:   3,
-	audio_inputs:   1,
-	tuner:          0,
-	svhs:           2,
-	gpiomask:       0x03000F,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 1, 0x10001, 0, 0, 10},
+	.name           = "Pinnacle PCTV Studio Pro",
+	.video_inputs   = 3,
+	.audio_inputs   = 1,
+	.tuner          = 0,
+	.svhs           = 2,
+	.gpiomask       = 0x03000F,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 1, 0x10001, 0, 0, 10},
 			/* sound path (5 sources):
 			   MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable)
 				0= ext. Audio IN
@@ -912,273 +912,273 @@
 			   MUX2 (mask 0x30000):
 				0,2,3= from MSP34xx
 				1= FM stereo Radio from Tuner */
-	needs_tvaudio:  1,
-	pll:            PLL_28,
-	tuner_type:     -1,
+	.needs_tvaudio  = 1,
+	.pll            = PLL_28,
+	.tuner_type     = -1,
 },{
 	/* Claas Langbehn <claas@bigfoot.com>,
 	   Sven Grothklags <sven@upb.de> */
-	name:		"Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
-	video_inputs:	3,
-	audio_inputs:	3,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0x1c,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 0, 0, 0x10, 8, 4 },
-	needs_tvaudio:	1,
-	pll:		PLL_28,
-	tuner_type:	TUNER_PHILIPS_PAL_I,
-	has_radio:	1,
+	.name		= "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
+	.video_inputs	= 3,
+	.audio_inputs	= 3,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0x1c,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 0, 0, 0x10, 8, 4 },
+	.needs_tvaudio	= 1,
+	.pll		= PLL_28,
+	.tuner_type	= TUNER_PHILIPS_PAL_I,
+	.has_radio	= 1,
 },{
 	/* Tim Röstermundt <rosterm@uni-muenster.de>
 	   in de.comp.os.unix.linux.hardware:
 		options bttv card=0 pll=1 radio=1 gpiomask=0x18e0
 		audiomux=0x44c71f,0x44d71f,0,0x44d71f,0x44dfff
 		options tuner type=5 */
-	name:		"Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]",
-	video_inputs:	4,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0x18e0,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 0x0000,0x0800,0x1000,0x1000,0x18e0 },
+	.name		= "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]",
+	.video_inputs	= 4,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0x18e0,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 0x0000,0x0800,0x1000,0x1000,0x18e0 },
 		       /* For cards with tda9820/tda9821:
 			  0x0000: Tuner normal stereo
 			  0x0080: Tuner A2 SAP (second audio program = Zweikanalton)
 			  0x0880: Tuner A2 stereo */
-	pll:		PLL_28,
-	tuner_type:	-1,
+	.pll		= PLL_28,
+	.tuner_type	= -1,
 },{
 	/* Miguel Angel Alvarez <maacruz@navegalia.com>
 	   old Easy TV BT848 version (model CPH031) */
-	name:           "Askey CPH031/ BESTBUY Easy TV",
-	video_inputs:	4,
-	audio_inputs:   1,
-	tuner:          0,
-	svhs:           2,
-	gpiomask:       0xF,
-	muxsel:         { 2, 3, 1, 0},
-	audiomux:       { 2, 0, 0, 0, 10},
-	needs_tvaudio:  0,
-	pll:		PLL_28,
-	tuner_type:	TUNER_TEMIC_PAL,
+	.name           = "Askey CPH031/ BESTBUY Easy TV",
+	.video_inputs	= 4,
+	.audio_inputs   = 1,
+	.tuner          = 0,
+	.svhs           = 2,
+	.gpiomask       = 0xF,
+	.muxsel         = { 2, 3, 1, 0},
+	.audiomux       = { 2, 0, 0, 0, 10},
+	.needs_tvaudio  = 0,
+	.pll		= PLL_28,
+	.tuner_type	= TUNER_TEMIC_PAL,
 },{
 
 /* ---- card 0x38 ---------------------------------- */
 	/* Gordon Heydon <gjheydon@bigfoot.com ('98) */
-	name:           "Lifeview FlyVideo 98FM LR50",
-	video_inputs:   4,
-	audio_inputs:   3,
-	tuner:          0,
-	svhs:           2,
-	gpiomask:       0x1800,
-	muxsel:         { 2, 3, 1, 1},
-	audiomux:       { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
-	pll:            PLL_28,
-	tuner_type:     5,
+	.name           = "Lifeview FlyVideo 98FM LR50",
+	.video_inputs   = 4,
+	.audio_inputs   = 3,
+	.tuner          = 0,
+	.svhs           = 2,
+	.gpiomask       = 0x1800,
+	.muxsel         = { 2, 3, 1, 1},
+	.audiomux       = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
+	.pll            = PLL_28,
+	.tuner_type     = 5,
 },{
 	/* This is the ultimate cheapo capture card 
 	 * just a BT848A on a small PCB!
 	 * Steve Hosgood <steve@equiinet.com> */
-	name:           "GrandTec 'Grand Video Capture' (Bt848)",
-	video_inputs:   2,
-	audio_inputs:   0,
-	tuner:          -1,
-	svhs:           1,
-	gpiomask:       0,
-	muxsel:         { 3, 1 },
-	audiomux:       { 0 },
-	needs_tvaudio:  0,
-	no_msp34xx:     1,
-	pll:            PLL_35,
-	tuner_type:     -1,
+	.name           = "GrandTec 'Grand Video Capture' (Bt848)",
+	.video_inputs   = 2,
+	.audio_inputs   = 0,
+	.tuner          = -1,
+	.svhs           = 1,
+	.gpiomask       = 0,
+	.muxsel         = { 3, 1 },
+	.audiomux       = { 0 },
+	.needs_tvaudio  = 0,
+	.no_msp34xx     = 1,
+	.pll            = PLL_35,
+	.tuner_type     = -1,
 },{
         /* Daniel Herrington <daniel.herrington@home.com> */
-        name:           "Askey CPH060/ Phoebe TV Master Only (No FM)",
-        video_inputs:   3,
-        audio_inputs:   1,
-        tuner:          0,
-        svhs:           2,
-        gpiomask:       0xe00,
-        muxsel:         { 2, 3, 1, 1},
-        audiomux:       { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 },
-        needs_tvaudio:  1,
-        pll:            PLL_28,
-        tuner_type:     TUNER_TEMIC_4036FY5_NTSC,
+        .name           = "Askey CPH060/ Phoebe TV Master Only (No FM)",
+        .video_inputs   = 3,
+        .audio_inputs   = 1,
+        .tuner          = 0,
+        .svhs           = 2,
+        .gpiomask       = 0xe00,
+        .muxsel         = { 2, 3, 1, 1},
+        .audiomux       = { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 },
+        .needs_tvaudio  = 1,
+        .pll            = PLL_28,
+        .tuner_type     = TUNER_TEMIC_4036FY5_NTSC,
 },{
 	/* Matti Mottus <mottus@physic.ut.ee> */
-	name:		"Askey CPH03x TV Capturer",
-	video_inputs:	4,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-        gpiomask:       0x03000F,
-	muxsel:		{ 2, 3, 1, 0},
-        audiomux:       { 2,0,0,0,1 },
-	pll:            PLL_28,
-	tuner_type:	0,
+	.name		= "Askey CPH03x TV Capturer",
+	.video_inputs	= 4,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+        .gpiomask       = 0x03000F,
+	.muxsel		= { 2, 3, 1, 0},
+        .audiomux       = { 2,0,0,0,1 },
+	.pll            = PLL_28,
+	.tuner_type	= 0,
 },{
 
 /* ---- card 0x3c ---------------------------------- */
 	/* Philip Blundell <philb@gnu.org> */
-	name:           "Modular Technology MM100PCTV",
-	video_inputs:   2,
-	audio_inputs:   2,
-	tuner:		0,
-	svhs:		-1,
-	gpiomask:       11,
-	muxsel:         { 2, 3, 1, 1},
-	audiomux:       { 2, 0, 0, 1, 8},
-	pll:            PLL_35,
-	tuner_type:     TUNER_TEMIC_PAL,
+	.name           = "Modular Technology MM100PCTV",
+	.video_inputs   = 2,
+	.audio_inputs   = 2,
+	.tuner		= 0,
+	.svhs		= -1,
+	.gpiomask       = 11,
+	.muxsel         = { 2, 3, 1, 1},
+	.audiomux       = { 2, 0, 0, 1, 8},
+	.pll            = PLL_35,
+	.tuner_type     = TUNER_TEMIC_PAL,
 
 },{
 	/* Adrian Cox <adrian@humboldt.co.uk */
-	name:	        "AG Electronics GMV1",
-	video_inputs:   2,
-	audio_inputs:   0,
-	tuner:	        -1,
-	svhs:	        1,
-	gpiomask:       0xF,
-	muxsel:	        { 2, 2},
-	audiomux:       { },
-	no_msp34xx:     1,
-	needs_tvaudio:  0,
-	pll:	        PLL_28,
-	tuner_type:     -1,
+	.name	        = "AG Electronics GMV1",
+	.video_inputs   = 2,
+	.audio_inputs   = 0,
+	.tuner	        = -1,
+	.svhs	        = 1,
+	.gpiomask       = 0xF,
+	.muxsel	        = { 2, 2},
+	.audiomux       = { },
+	.no_msp34xx     = 1,
+	.needs_tvaudio  = 0,
+	.pll	        = PLL_28,
+	.tuner_type     = -1,
 },{
 	/* Miguel Angel Alvarez <maacruz@navegalia.com>
 	   new Easy TV BT878 version (model CPH061) 
 	   special thanks to Informatica Mieres for providing the card */
-	name:           "Askey CPH061/ BESTBUY Easy TV (bt878)",
-	video_inputs:	3,
-	audio_inputs:   2,
-	tuner:          0,
-	svhs:           2,
-	gpiomask:       0xFF,
-	muxsel:         { 2, 3, 1, 0},
-	audiomux:       { 1, 0, 4, 4, 9},
-	needs_tvaudio:  0,
-	pll:		PLL_28,
-	tuner_type:	TUNER_PHILIPS_PAL,
+	.name           = "Askey CPH061/ BESTBUY Easy TV (bt878)",
+	.video_inputs	= 3,
+	.audio_inputs   = 2,
+	.tuner          = 0,
+	.svhs           = 2,
+	.gpiomask       = 0xFF,
+	.muxsel         = { 2, 3, 1, 0},
+	.audiomux       = { 1, 0, 4, 4, 9},
+	.needs_tvaudio  = 0,
+	.pll		= PLL_28,
+	.tuner_type	= TUNER_PHILIPS_PAL,
 },{
 	/* Lukas Gebauer <geby@volny.cz> */
-	name:		"ATI TV-Wonder",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0xf03f,
-	muxsel:		{ 2, 3, 1, 0 },
-	audiomux:	{ 0xbffe, 0, 0xbfff, 0, 0xbffe},
-	pll:		PLL_28,
-	tuner_type:	TUNER_TEMIC_4006FN5_MULTI_PAL,
+	.name		= "ATI TV-Wonder",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0xf03f,
+	.muxsel		= { 2, 3, 1, 0 },
+	.audiomux	= { 0xbffe, 0, 0xbfff, 0, 0xbffe},
+	.pll		= PLL_28,
+	.tuner_type	= TUNER_TEMIC_4006FN5_MULTI_PAL,
 },{
 
 /* ---- card 0x40 ---------------------------------- */
 	/* Lukas Gebauer <geby@volny.cz> */
-	name:		"ATI TV-Wonder VE",
-	video_inputs:	2,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		-1,
-	gpiomask:	1,
-	muxsel:		{ 2, 3, 0, 1},
-	audiomux:	{ 0, 0, 1, 0, 0},
-	no_msp34xx:	1,
-	pll:		PLL_28,
-	tuner_type:	TUNER_TEMIC_4006FN5_MULTI_PAL,
+	.name		= "ATI TV-Wonder VE",
+	.video_inputs	= 2,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= -1,
+	.gpiomask	= 1,
+	.muxsel		= { 2, 3, 0, 1},
+	.audiomux	= { 0, 0, 1, 0, 0},
+	.no_msp34xx	= 1,
+	.pll		= PLL_28,
+	.tuner_type	= TUNER_TEMIC_4006FN5_MULTI_PAL,
 },{
 	/* DeeJay <deejay@westel900.net (2000S) */
-	name:           "Lifeview FlyVideo 2000S LR90",
-	video_inputs:   3,
-	audio_inputs:   3,
-	tuner:          0,
-	svhs:           2,
-	gpiomask:	0x18e0,
-	muxsel:		{ 2, 3, 0, 1},
+	.name           = "Lifeview FlyVideo 2000S LR90",
+	.video_inputs   = 3,
+	.audio_inputs   = 3,
+	.tuner          = 0,
+	.svhs           = 2,
+	.gpiomask	= 0x18e0,
+	.muxsel		= { 2, 3, 0, 1},
 			/* Radio changed from 1e80 to 0x800 to make
 			   FlyVideo2000S in .hu happy (gm)*/
 			/* -dk-???: set mute=0x1800 for tda9874h daughterboard */
-	audiomux:	{ 0x0000,0x0800,0x1000,0x1000,0x1800, 0x1080 },
-	audio_hook:	fv2000s_audio,
-	no_msp34xx:	1,
-	no_tda9875:	1,
-	needs_tvaudio:  1,
-	pll:            PLL_28,
-	tuner_type:     5,
-},{
-	name:		"Terratec TValueRadio",
-	video_inputs:	3,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0xffff00,
-	muxsel:		{ 2, 3, 1, 1},
-	audiomux:	{ 0x500, 0x500, 0x300, 0x900, 0x900},
-	needs_tvaudio:	1,
-	pll:		PLL_28,
-	tuner_type:	TUNER_PHILIPS_PAL,
-	has_radio:	1,
+	.audiomux	= { 0x0000,0x0800,0x1000,0x1000,0x1800, 0x1080 },
+	.audio_hook	= fv2000s_audio,
+	.no_msp34xx	= 1,
+	.no_tda9875	= 1,
+	.needs_tvaudio  = 1,
+	.pll            = PLL_28,
+	.tuner_type     = 5,
+},{
+	.name		= "Terratec TValueRadio",
+	.video_inputs	= 3,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0xffff00,
+	.muxsel		= { 2, 3, 1, 1},
+	.audiomux	= { 0x500, 0x500, 0x300, 0x900, 0x900},
+	.needs_tvaudio	= 1,
+	.pll		= PLL_28,
+	.tuner_type	= TUNER_PHILIPS_PAL,
+	.has_radio	= 1,
 },{
 	/* TANAKA Kei <peg00625@nifty.com> */
-	name:           "IODATA GV-BCTV4/PCI",
-	video_inputs:   3,
-	audio_inputs:   1,
-	tuner:          0,
-	svhs:           2,
-	gpiomask:       0x010f00,
-	muxsel:         {2, 3, 0, 0},
-	audiomux:       {0x10000, 0, 0x10000, 0, 0, 0},
-	no_msp34xx:     1,
-	pll:            PLL_28,
-	tuner_type:     TUNER_SHARP_2U5JF5540_NTSC,
-	audio_hook:     gvbctv3pci_audio,
+	.name           = "IODATA GV-BCTV4/PCI",
+	.video_inputs   = 3,
+	.audio_inputs   = 1,
+	.tuner          = 0,
+	.svhs           = 2,
+	.gpiomask       = 0x010f00,
+	.muxsel         = {2, 3, 0, 0},
+	.audiomux       = {0x10000, 0, 0x10000, 0, 0, 0},
+	.no_msp34xx     = 1,
+	.pll            = PLL_28,
+	.tuner_type     = TUNER_SHARP_2U5JF5540_NTSC,
+	.audio_hook     = gvbctv3pci_audio,
 },{
 
 /* ---- card 0x44 ---------------------------------- */
-        name:           "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)",
+        .name           = "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)",
 	// try "insmod msp3400 simple=0" if you have
 	// sound problems with this card.
-        video_inputs:   4,
-        audio_inputs:   1,
-        tuner:          0,
-        svhs:           -1,
-        gpiomask:       0x4f8a00,
+        .video_inputs   = 4,
+        .audio_inputs   = 1,
+        .tuner          = 0,
+        .svhs           = -1,
+        .gpiomask       = 0x4f8a00,
 	// 0x100000: 1=MSP enabled (0=disable again)
 	// 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC)
-        audiomux:       {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff},
+        .audiomux       = {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff},
 	// tvtuner, radio,   external,internal, mute,  stereo
 	/* tuner, Composit, SVid, Composit-on-Svid-adapter*/
-        muxsel:         { 2, 3 ,0 ,1},
-        tuner_type:     TUNER_MT2032,
-	pll:		PLL_28,
-	has_radio:	1,
+        .muxsel         = { 2, 3 ,0 ,1},
+        .tuner_type     = TUNER_MT2032,
+	.pll		= PLL_28,
+	.has_radio	= 1,
 },{
 	/* Philip Blundell <pb@nexus.co.uk> */
-	name:           "Active Imaging AIMMS",
-	video_inputs:   1,
-	audio_inputs:   0,
-	tuner:          -1,
-	tuner_type:     -1,
-	pll:            PLL_28,
-	muxsel:         { 2 },
-	gpiomask:       0
+	.name           = "Active Imaging AIMMS",
+	.video_inputs   = 1,
+	.audio_inputs   = 0,
+	.tuner          = -1,
+	.tuner_type     = -1,
+	.pll            = PLL_28,
+	.muxsel         = { 2 },
+	.gpiomask       = 0
 },{
         /* Tomasz Pyra <hellfire@sedez.iq.pl> */
-        name:           "Prolink Pixelview PV-BT878P+ (Rev.4C)",
-        video_inputs:   3,
-        audio_inputs:   4,
-        tuner:          0,
-        svhs:           2,
-        gpiomask:       15,
-        muxsel:         { 2, 3, 1, 1},
-        audiomux:       { 0, 0, 11, 7, 13, 0}, // TV and Radio with same GPIO !
-        needs_tvaudio:  1,
-        pll:            PLL_28,
-        tuner_type:     25,
+        .name           = "Prolink Pixelview PV-BT878P+ (Rev.4C)",
+        .video_inputs   = 3,
+        .audio_inputs   = 4,
+        .tuner          = 0,
+        .svhs           = 2,
+        .gpiomask       = 15,
+        .muxsel         = { 2, 3, 1, 1},
+        .audiomux       = { 0, 0, 11, 7, 13, 0}, // TV and Radio with same GPIO !
+        .needs_tvaudio  = 1,
+        .pll            = PLL_28,
+        .tuner_type     = 25,
 	/* GPIO wiring:
 		GPIO0: U4.A0 (hef4052bt)
 		GPIO1: U4.A1
@@ -1187,33 +1187,33 @@
 		GPIO8-15: vrd866b ?
 	 */
 },{
-	name:		"Lifeview FlyVideo 98EZ (capture only) LR51",
-	video_inputs:	4,
-	audio_inputs:   0,
-	tuner:		-1,
-	svhs:		2,
-	muxsel:		{ 2, 3, 1, 1}, // AV1, AV2, SVHS, CVid adapter on SVHS
-	pll:		PLL_28,
-	no_msp34xx:	1,
+	.name		= "Lifeview FlyVideo 98EZ (capture only) LR51",
+	.video_inputs	= 4,
+	.audio_inputs   = 0,
+	.tuner		= -1,
+	.svhs		= 2,
+	.muxsel		= { 2, 3, 1, 1}, // AV1, AV2, SVHS, CVid adapter on SVHS
+	.pll		= PLL_28,
+	.no_msp34xx	= 1,
 },{
 
 /* ---- card 0x48 ---------------------------------- */
 	/* Dariusz Kowalewski <darekk@automex.pl> */
-	name:		"Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)",
-	video_inputs:	4,
-	audio_inputs:	1,
-	tuner:		0,
-	svhs:		2,
-	gpiomask:	0x3f,
-	muxsel:		{ 2, 3, 1, 1 },
-	audiomux:	{ 0x01, 0x00, 0x03, 0x03, 0x09, 0x02 },
-	needs_tvaudio:  1,
-	no_msp34xx:	1,
-	no_tda9875:	1,
-	pll:		PLL_28,
-	tuner_type:	5,
-	audio_hook:	pvbt878p9b_audio, // Note: not all cards have stereo
-	has_radio:	1,  // Note: not all cards have radio
+	.name		= "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)",
+	.video_inputs	= 4,
+	.audio_inputs	= 1,
+	.tuner		= 0,
+	.svhs		= 2,
+	.gpiomask	= 0x3f,
+	.muxsel		= { 2, 3, 1, 1 },
+	.audiomux	= { 0x01, 0x00, 0x03, 0x03, 0x09, 0x02 },
+	.needs_tvaudio  = 1,
+	.no_msp34xx	= 1,
+	.no_tda9875	= 1,
+	.pll		= PLL_28,
+	.tuner_type	= 5,
+	.audio_hook	= pvbt878p9b_audio, // Note: not all cards have stereo
+	.has_radio	= 1,  // Note: not all cards have radio
 	/* GPIO wiring:
 		GPIO0: A0 hef4052
 		GPIO1: A1 hef4052
@@ -1224,91 +1224,91 @@
 },{
 	/* Clay Kunz <ckunz@mail.arc.nasa.gov> */
 	/* you must jumper JP5 for the card to work */
-	name:           "Sensoray 311",
-	video_inputs:   5,
-	audio_inputs:   0,
-	tuner:          -1,
-	svhs:           4,
-	gpiomask:       0,
-	muxsel:         { 2, 3, 1, 0, 0},
-	audiomux:       { 0 },
-	needs_tvaudio:  0,
-	tuner_type:     -1,
+	.name           = "Sensoray 311",
+	.video_inputs   = 5,
+	.audio_inputs   = 0,
+	.tuner          = -1,
+	.svhs           = 4,
+	.gpiomask       = 0,
+	.muxsel         = { 2, 3, 1, 0, 0},
+	.audiomux       = { 0 },
+	.needs_tvaudio  = 0,
+	.tuner_type     = -1,
 },{
 	/* Miguel Freitas <miguel@cetuc.puc-rio.br> */
-	name:           "RemoteVision MX (RV605)",
-	video_inputs:   16,
-	audio_inputs:   0,
-	tuner:          -1,
-	svhs:           -1,
-	gpiomask:       0x00,
-	gpiomask2:      0x07ff,
-	muxsel:         { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03,
+	.name           = "RemoteVision MX (RV605)",
+	.video_inputs   = 16,
+	.audio_inputs   = 0,
+	.tuner          = -1,
+	.svhs           = -1,
+	.gpiomask       = 0x00,
+	.gpiomask2      = 0x07ff,
+	.muxsel         = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03,
 			  0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 },
-	no_msp34xx:     1,
-	no_tda9875:     1,
-	tuner_type:     -1,
-	muxsel_hook:    rv605_muxsel,
-},{
-        name:           "Powercolor MTV878/ MTV878R/ MTV878F",
-        video_inputs:   3,
-        audio_inputs:   2, 
-	tuner:		0,
-        svhs:           2,
-        gpiomask:       0x1C800F,  // Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset
-        muxsel:         { 2, 1, 1, },
-        audiomux:       { 0, 1, 2, 2, 4 },
-        needs_tvaudio:  0,
-        tuner_type:     TUNER_PHILIPS_PAL,
-	pll:		PLL_28,
-	has_radio:	1,
+	.no_msp34xx     = 1,
+	.no_tda9875     = 1,
+	.tuner_type     = -1,
+	.muxsel_hook    = rv605_muxsel,
+},{
+        .name           = "Powercolor MTV878/ MTV878R/ MTV878F",
+        .video_inputs   = 3,
+        .audio_inputs   = 2, 
+	.tuner		= 0,
+        .svhs           = 2,
+        .gpiomask       = 0x1C800F,  // Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset
+        .muxsel         = { 2, 1, 1, },
+        .audiomux       = { 0, 1, 2, 2, 4 },
+        .needs_tvaudio  = 0,
+        .tuner_type     = TUNER_PHILIPS_PAL,
+	.pll		= PLL_28,
+	.has_radio	= 1,
 },{
 
 /* ---- card 0x4c ---------------------------------- */
         /* Masaki Suzuki <masaki@btree.org> */
-        name:           "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)",
-        video_inputs:   3,
-        audio_inputs:   1,
-        tuner:          0,
-        svhs:           2,
-        gpiomask:       0x140007,
-        muxsel:         { 2, 3, 1, 1 },
-        audiomux:       { 0, 1, 2, 3, 4, 0 },
-        tuner_type:     TUNER_PHILIPS_NTSC,
-        audio_hook:     windvr_audio,
-},{
-        name:           "GrandTec Multi Capture Card (Bt878)",
-        video_inputs:   4,
-        audio_inputs:   0,
-        tuner:          -1,
-        svhs:           -1,
-        gpiomask:       0,
-        muxsel:         { 2, 3, 1, 0 },
-        audiomux:       { 0 },
-        needs_tvaudio:  0,
-        no_msp34xx:     1,
-        pll:            PLL_28,
-        tuner_type:     -1,
-},{
-        name:           "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF",
-        video_inputs:   4,
-        audio_inputs:   3, 
-        tuner:          0,
-        svhs:           2,
-        gpiomask:       7,
-        muxsel:         { 2, 3, 1, 1 },   // Tuner, SVid, SVHS, SVid to SVHS connector
-        audiomux:       { 0 ,0 ,4, 4,4,4},// Yes, this tuner uses the same audio output for TV and FM radio!
+        .name           = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)",
+        .video_inputs   = 3,
+        .audio_inputs   = 1,
+        .tuner          = 0,
+        .svhs           = 2,
+        .gpiomask       = 0x140007,
+        .muxsel         = { 2, 3, 1, 1 },
+        .audiomux       = { 0, 1, 2, 3, 4, 0 },
+        .tuner_type     = TUNER_PHILIPS_NTSC,
+        .audio_hook     = windvr_audio,
+},{
+        .name           = "GrandTec Multi Capture Card (Bt878)",
+        .video_inputs   = 4,
+        .audio_inputs   = 0,
+        .tuner          = -1,
+        .svhs           = -1,
+        .gpiomask       = 0,
+        .muxsel         = { 2, 3, 1, 0 },
+        .audiomux       = { 0 },
+        .needs_tvaudio  = 0,
+        .no_msp34xx     = 1,
+        .pll            = PLL_28,
+        .tuner_type     = -1,
+},{
+        .name           = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF",
+        .video_inputs   = 4,
+        .audio_inputs   = 3, 
+        .tuner          = 0,
+        .svhs           = 2,
+        .gpiomask       = 7,
+        .muxsel         = { 2, 3, 1, 1 },   // Tuner, SVid, SVHS, SVid to SVHS connector
+        .audiomux       = { 0 ,0 ,4, 4,4,4},// Yes, this tuner uses the same audio output for TV and FM radio!
 					  // This card lacks external Audio In, so we mute it on Ext. & Int.
 					  // The PCB can take a sbx1637/sbx1673, wiring unknown.
 					  // This card lacks PCI subsystem ID, sigh.
 					  // audiomux=1: lower volume, 2+3: mute
 					  // btwincap uses 0x80000/0x80003
-        needs_tvaudio:  0,
-        no_msp34xx:     1,
-        pll:            PLL_28,
-        tuner_type:     5, // Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and
+        .needs_tvaudio  = 0,
+        .no_msp34xx     = 1,
+        .pll            = PLL_28,
+        .tuner_type     = 5, // Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and
 			   // radio signal strength indicators work fine.
-	has_radio:		1,
+	.has_radio		= 1,
 	/* GPIO Info:
 		GPIO0,1:   HEF4052 A0,A1
 		GPIO2:     HEF4052 nENABLE
@@ -1320,199 +1320,199 @@
 		??       : mtu8b56ep microcontroller for IR (GPIO wiring unknown)*/
 },{
         /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */
-        name:           "DSP Design TCVIDEO",
-        video_inputs:   4,
-        svhs:           -1,
-        muxsel:         { 2, 3, 1, 0},
-        pll:            PLL_28,
-        tuner_type:     -1,
+        .name           = "DSP Design TCVIDEO",
+        .video_inputs   = 4,
+        .svhs           = -1,
+        .muxsel         = { 2, 3, 1, 0},
+        .pll            = PLL_28,
+        .tuner_type     = -1,
 },{
 
         /* ---- card 0x50 ---------------------------------- */
-	name:           "Hauppauge WinTV PVR",
-        video_inputs:   4,
-        audio_inputs:   1,
-        tuner:          0,
-        svhs:           2,
-        muxsel:         { 2, 0, 1, 1},
-        needs_tvaudio:  1,
-        pll:            PLL_28,
-        tuner_type:     -1,
-
-	gpiomask:       7,
-	audiomux:       {7},
-},{
-	name:           "GV-BCTV5/PCI",
-	video_inputs:   3,
-	audio_inputs:   1,
-	tuner:          0,
-	svhs:           2,
-	gpiomask:       0x010f00,
-	muxsel:         {2, 3, 1, 0},
-	audiomux:       {0x10000, 0, 0x10000, 0, 0, 0},
-	no_msp34xx:     1,
-	pll:            PLL_28,
-	tuner_type:     TUNER_PHILIPS_NTSC_M,
-	audio_hook:     gvbctv3pci_audio,
-},{
-	name:           "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */
-	video_inputs:   4,                  /* id-inputs-clock */
-	audio_inputs:   0,
-	tuner:          -1,
-	svhs:           3,
-	muxsel:         { 3, 2, 0, 1 },
-	pll:            PLL_28,
-	tuner_type:     -1,
-        no_msp34xx:     1,
-        no_tda9875:     1,
-        no_tda7432:     1,
-},{
-	name:           "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */
-	video_inputs:   3,
-	audio_inputs:   0,
-	tuner:          -1,
-	svhs:           2,
-	muxsel:         { 2, 3, 1 },
-	pll:            PLL_28,
-	tuner_type:     -1,
-        no_msp34xx:     1,
-        no_tda9875:     1,
-        no_tda7432:     1,
+	.name           = "Hauppauge WinTV PVR",
+        .video_inputs   = 4,
+        .audio_inputs   = 1,
+        .tuner          = 0,
+        .svhs           = 2,
+        .muxsel         = { 2, 0, 1, 1},
+        .needs_tvaudio  = 1,
+        .pll            = PLL_28,
+        .tuner_type     = -1,
+
+	.gpiomask       = 7,
+	.audiomux       = {7},
+},{
+	.name           = "GV-BCTV5/PCI",
+	.video_inputs   = 3,
+	.audio_inputs   = 1,
+	.tuner          = 0,
+	.svhs           = 2,
+	.gpiomask       = 0x010f00,
+	.muxsel         = {2, 3, 1, 0},
+	.audiomux       = {0x10000, 0, 0x10000, 0, 0, 0},
+	.no_msp34xx     = 1,
+	.pll            = PLL_28,
+	.tuner_type     = TUNER_PHILIPS_NTSC_M,
+	.audio_hook     = gvbctv3pci_audio,
+},{
+	.name           = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */
+	.video_inputs   = 4,                  /* id-inputs-clock */
+	.audio_inputs   = 0,
+	.tuner          = -1,
+	.svhs           = 3,
+	.muxsel         = { 3, 2, 0, 1 },
+	.pll            = PLL_28,
+	.tuner_type     = -1,
+        .no_msp34xx     = 1,
+        .no_tda9875     = 1,
+        .no_tda7432     = 1,
+},{
+	.name           = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */
+	.video_inputs   = 3,
+	.audio_inputs   = 0,
+	.tuner          = -1,
+	.svhs           = 2,
+	.muxsel         = { 2, 3, 1 },
+	.pll            = PLL_28,
+	.tuner_type     = -1,
+        .no_msp34xx     = 1,
+        .no_tda9875     = 1,
+        .no_tda7432     = 1,
 },{
 
 	/* ---- card 0x54 ---------------------------------- */
-	name:           "Osprey 101 (848)", /* 0x05-40C0-C1 */
-	video_inputs:   2,
-	audio_inputs:   0,
-	tuner:          -1,
-	svhs:           1,
-	muxsel:         { 3, 1 },
-	pll:            PLL_28,
-	tuner_type:     -1,
-        no_msp34xx:     1,
-        no_tda9875:     1,
-        no_tda7432:     1,
-},{
-	name:           "Osprey 101/151",       /* 0x1(4|5)-0004-C4 */
-	video_inputs:   1,
-	audio_inputs:   0,
-	tuner:          -1,
-	svhs:           -1,
-	muxsel:         { 0 },
-	pll:            PLL_28,
-	tuner_type:     -1,
-        no_msp34xx:     1,
-        no_tda9875:     1,
-        no_tda7432:     1,
-},{
-	name:           "Osprey 101/151 w/ svid",  /* 0x(16|17|20)-00C4-C1 */
-	video_inputs:   2,
-	audio_inputs:   0,
-	tuner:          -1,
-	svhs:           1,
-	muxsel:         { 0, 1 },
-	pll:            PLL_28,
-	tuner_type:     -1,
-        no_msp34xx:     1,
-        no_tda9875:     1,
-        no_tda7432:     1,
-},{
-	name:           "Osprey 200/201/250/251",  /* 0x1(8|9|E|F)-0004-C4 */
-	video_inputs:   1,
-	audio_inputs:   1,
-	tuner:          -1,
-	svhs:           -1,
-	muxsel:         { 0 },
-	pll:            PLL_28,
-	tuner_type:     -1,
-        no_msp34xx:     1,
-        no_tda9875:     1,
-        no_tda7432:     1,
+	.name           = "Osprey 101 (848)", /* 0x05-40C0-C1 */
+	.video_inputs   = 2,
+	.audio_inputs   = 0,
+	.tuner          = -1,
+	.svhs           = 1,
+	.muxsel         = { 3, 1 },
+	.pll            = PLL_28,
+	.tuner_type     = -1,
+        .no_msp34xx     = 1,
+        .no_tda9875     = 1,
+        .no_tda7432     = 1,
+},{
+	.name           = "Osprey 101/151",       /* 0x1(4|5)-0004-C4 */
+	.video_inputs   = 1,
+	.audio_inputs   = 0,
+	.tuner          = -1,
+	.svhs           = -1,
+	.muxsel         = { 0 },
+	.pll            = PLL_28,
+	.tuner_type     = -1,
+        .no_msp34xx     = 1,
+        .no_tda9875     = 1,
+        .no_tda7432     = 1,
+},{
+	.name           = "Osprey 101/151 w/ svid",  /* 0x(16|17|20)-00C4-C1 */
+	.video_inputs   = 2,
+	.audio_inputs   = 0,
+	.tuner          = -1,
+	.svhs           = 1,
+	.muxsel         = { 0, 1 },
+	.pll            = PLL_28,
+	.tuner_type     = -1,
+        .no_msp34xx     = 1,
+        .no_tda9875     = 1,
+        .no_tda7432     = 1,
+},{
+	.name           = "Osprey 200/201/250/251",  /* 0x1(8|9|E|F)-0004-C4 */
+	.video_inputs   = 1,
+	.audio_inputs   = 1,
+	.tuner          = -1,
+	.svhs           = -1,
+	.muxsel         = { 0 },
+	.pll            = PLL_28,
+	.tuner_type     = -1,
+        .no_msp34xx     = 1,
+        .no_tda9875     = 1,
+        .no_tda7432     = 1,
 },{
 	
 	/* ---- card 0x58 ---------------------------------- */
-	name:           "Osprey 200/250",   /* 0x1(A|B)-00C4-C1 */
-	video_inputs:   2,
-	audio_inputs:   1,
-	tuner:          -1,
-	svhs:           1,
-	muxsel:         { 0, 1 },
-	pll:            PLL_28,
-	tuner_type:     -1,
-        no_msp34xx:     1,
-        no_tda9875:     1,
-        no_tda7432:     1,
-},{
-	name:           "Osprey 210/220",   /* 0x1(A|B)-04C0-C1 */
-	video_inputs:   2,
-	audio_inputs:   1,
-	tuner:          -1,
-	svhs:           1,
-	muxsel:         { 2, 3 },
-	pll:            PLL_28,
-	tuner_type:     -1,
-        no_msp34xx:     1,
-        no_tda9875:     1,
-        no_tda7432:     1,
-},{
-	name:           "Osprey 500",   /* 500 */
-	video_inputs:   2,
-	audio_inputs:   1,
-	tuner:          -1,
-	svhs:           1,
-	muxsel:         { 2, 3 },
-	pll:            PLL_28,
-	tuner_type:     -1,
-        no_msp34xx:     1,
-        no_tda9875:     1,
-        no_tda7432:     1,
-},{
-       name:           "Osprey 540",   /* 540 */
-       video_inputs:   4,
-       audio_inputs:   1,
-       tuner:          -1,
+	.name           = "Osprey 200/250",   /* 0x1(A|B)-00C4-C1 */
+	.video_inputs   = 2,
+	.audio_inputs   = 1,
+	.tuner          = -1,
+	.svhs           = 1,
+	.muxsel         = { 0, 1 },
+	.pll            = PLL_28,
+	.tuner_type     = -1,
+        .no_msp34xx     = 1,
+        .no_tda9875     = 1,
+        .no_tda7432     = 1,
+},{
+	.name           = "Osprey 210/220",   /* 0x1(A|B)-04C0-C1 */
+	.video_inputs   = 2,
+	.audio_inputs   = 1,
+	.tuner          = -1,
+	.svhs           = 1,
+	.muxsel         = { 2, 3 },
+	.pll            = PLL_28,
+	.tuner_type     = -1,
+        .no_msp34xx     = 1,
+        .no_tda9875     = 1,
+        .no_tda7432     = 1,
+},{
+	.name           = "Osprey 500",   /* 500 */
+	.video_inputs   = 2,
+	.audio_inputs   = 1,
+	.tuner          = -1,
+	.svhs           = 1,
+	.muxsel         = { 2, 3 },
+	.pll            = PLL_28,
+	.tuner_type     = -1,
+        .no_msp34xx     = 1,
+        .no_tda9875     = 1,
+        .no_tda7432     = 1,
+},{
+       .name           = "Osprey 540",   /* 540 */
+       .video_inputs   = 4,
+       .audio_inputs   = 1,
+       .tuner          = -1,
 #if 0 /* TODO ... */
-       svhs:           OSPREY540_SVID_ANALOG,
-       muxsel:         {       [OSPREY540_COMP_ANALOG] = 2,
+       .svhs           = OSPREY540_SVID_ANALOG,
+       .muxsel         = {       [OSPREY540_COMP_ANALOG] = 2,
                                [OSPREY540_SVID_ANALOG] = 3, },
 #endif
-       pll:            PLL_28,
-       tuner_type:     -1,
-       no_msp34xx:     1,
-       no_tda9875:     1,
-       no_tda7432:     1,
+       .pll            = PLL_28,
+       .tuner_type     = -1,
+       .no_msp34xx     = 1,
+       .no_tda9875     = 1,
+       .no_tda7432     = 1,
 #if 0 /* TODO ... */
-       muxsel_hook:    osprey_540_muxsel,
-       picture_hook:   osprey_540_set_picture,
+       .muxsel_hook    = osprey_540_muxsel,
+       .picture_hook   = osprey_540_set_picture,
 #endif
 },{
 
 	/* ---- card 0x5C ---------------------------------- */
-	name:           "Osprey 2000",  /* 2000 */
-	video_inputs:   2,
-	audio_inputs:   1,
-	tuner:          -1,
-	svhs:           1,
-	muxsel:         { 2, 3 },
-	pll:            PLL_28,
-	tuner_type:     -1,
-        no_msp34xx:     1,
-        no_tda9875:     1,
-        no_tda7432:     1,      /* must avoid, conflicts with the bt860 */
+	.name           = "Osprey 2000",  /* 2000 */
+	.video_inputs   = 2,
+	.audio_inputs   = 1,
+	.tuner          = -1,
+	.svhs           = 1,
+	.muxsel         = { 2, 3 },
+	.pll            = PLL_28,
+	.tuner_type     = -1,
+        .no_msp34xx     = 1,
+        .no_tda9875     = 1,
+        .no_tda7432     = 1,      /* must avoid, conflicts with the bt860 */
 },{
 	/* M G Berberich <berberic@forwiss.uni-passau.de> */
-	name:           "IDS Eagle",
-	video_inputs:   4,
-	audio_inputs:   0,
-	tuner:          -1,
-	tuner_type:     -1,
-	svhs:           -1,
-	gpiomask:       0,
-	muxsel:         { 0, 1, 2, 3 },
-	muxsel_hook:    eagle_muxsel,
-	no_msp34xx:     1,
-	no_tda9875:     1,
-	pll:            PLL_28,
+	.name           = "IDS Eagle",
+	.video_inputs   = 4,
+	.audio_inputs   = 0,
+	.tuner          = -1,
+	.tuner_type     = -1,
+	.svhs           = -1,
+	.gpiomask       = 0,
+	.muxsel         = { 0, 1, 2, 3 },
+	.muxsel_hook    = eagle_muxsel,
+	.no_msp34xx     = 1,
+	.no_tda9875     = 1,
+	.pll            = PLL_28,
 }};
 
 const int bttv_num_tvcards = (sizeof(bttv_tvcards)/sizeof(struct tvcard));
diff -Nru a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
--- a/drivers/media/video/bttv-driver.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/media/video/bttv-driver.c	Mon Dec  9 18:46:50 2002
@@ -274,154 +274,154 @@
    packed pixel formats must come first */
 const struct bttv_format bttv_formats[] = {
 	{
-		name:     "8 bpp, gray",
-		palette:  VIDEO_PALETTE_GREY,
-		fourcc:   V4L2_PIX_FMT_GREY,
-		btformat: BT848_COLOR_FMT_Y8,
-		depth:    8,
-		flags:    FORMAT_FLAGS_PACKED,
-	},{
-		name:     "8 bpp, dithered color",
-		palette:  VIDEO_PALETTE_HI240,
-		fourcc:   V4L2_PIX_FMT_HI240,
-		btformat: BT848_COLOR_FMT_RGB8,
-		depth:    8,
-		flags:    FORMAT_FLAGS_PACKED | FORMAT_FLAGS_DITHER,
-	},{
-		name:     "15 bpp RGB, le",
-		palette:  VIDEO_PALETTE_RGB555,
-		fourcc:   V4L2_PIX_FMT_RGB555,
-		btformat: BT848_COLOR_FMT_RGB15,
-		depth:    16,
-		flags:    FORMAT_FLAGS_PACKED,
-	},{
-		name:     "15 bpp RGB, be",
-		palette:  -1,
-		fourcc:   V4L2_PIX_FMT_RGB555X,
-		btformat: BT848_COLOR_FMT_RGB15,
-		btswap:   0x03, /* byteswap */
-		depth:    16,
-		flags:    FORMAT_FLAGS_PACKED,
-	},{
-		name:     "16 bpp RGB, le",
-		palette:  VIDEO_PALETTE_RGB565,
-		fourcc:   V4L2_PIX_FMT_RGB565,
-		btformat: BT848_COLOR_FMT_RGB16,
-		depth:    16,
-		flags:    FORMAT_FLAGS_PACKED,
-	},{
-		name:     "16 bpp RGB, be",
-		palette:  -1,
-		fourcc:   V4L2_PIX_FMT_RGB565X,
-		btformat: BT848_COLOR_FMT_RGB16,
-		btswap:   0x03, /* byteswap */
-		depth:    16,
-		flags:    FORMAT_FLAGS_PACKED,
-	},{
-		name:     "24 bpp RGB, le",
-		palette:  VIDEO_PALETTE_RGB24,
-		fourcc:   V4L2_PIX_FMT_BGR24,
-		btformat: BT848_COLOR_FMT_RGB24,
-		depth:    24,
-		flags:    FORMAT_FLAGS_PACKED,
-	},{
-		name:     "32 bpp RGB, le",
-		palette:  VIDEO_PALETTE_RGB32,
-		fourcc:   V4L2_PIX_FMT_BGR32,
-		btformat: BT848_COLOR_FMT_RGB32,
-		depth:    32,
-		flags:    FORMAT_FLAGS_PACKED,
-	},{
-		name:     "32 bpp RGB, be",
-		palette:  -1,
-		fourcc:   V4L2_PIX_FMT_RGB32,
-		btformat: BT848_COLOR_FMT_RGB32,
-		btswap:   0x0f, /* byte+word swap */
-		depth:    32,
-		flags:    FORMAT_FLAGS_PACKED,
-	},{
-		name:     "4:2:2, packed, YUYV",
-		palette:  VIDEO_PALETTE_YUV422,
-		fourcc:   V4L2_PIX_FMT_YUYV,
-		btformat: BT848_COLOR_FMT_YUY2,
-		depth:    16,
-		flags:    FORMAT_FLAGS_PACKED,
-	},{
-		name:     "4:2:2, packed, YUYV",
-		palette:  VIDEO_PALETTE_YUYV,
-		fourcc:   V4L2_PIX_FMT_YUYV,
-		btformat: BT848_COLOR_FMT_YUY2,
-		depth:    16,
-		flags:    FORMAT_FLAGS_PACKED,
-	},{
-		name:     "4:2:2, packed, UYVY",
-		palette:  VIDEO_PALETTE_UYVY,
-		fourcc:   V4L2_PIX_FMT_UYVY,
-		btformat: BT848_COLOR_FMT_YUY2,
-		btswap:   0x03, /* byteswap */
-		depth:    16,
-		flags:    FORMAT_FLAGS_PACKED,
-	},{
-		name:     "4:2:2, planar, Y-Cb-Cr",
-		palette:  VIDEO_PALETTE_YUV422P,
-		fourcc:   V4L2_PIX_FMT_YUV422P,
-		btformat: BT848_COLOR_FMT_YCrCb422,
-		depth:    16,
-		flags:    FORMAT_FLAGS_PLANAR,
-		hshift:   1,
-		vshift:   0,
-	},{
-		name:     "4:2:0, planar, Y-Cb-Cr",
-		palette:  VIDEO_PALETTE_YUV420P,
-		fourcc:   V4L2_PIX_FMT_YUV420,
-		btformat: BT848_COLOR_FMT_YCrCb422,
-		depth:    12,
-		flags:    FORMAT_FLAGS_PLANAR,
-		hshift:   1,
-		vshift:   1,
-	},{
-		name:     "4:2:0, planar, Y-Cr-Cb",
-		palette:  -1,
-		fourcc:   V4L2_PIX_FMT_YVU420,
-		btformat: BT848_COLOR_FMT_YCrCb422,
-		depth:    12,
-		flags:    FORMAT_FLAGS_PLANAR | FORMAT_FLAGS_CrCb,
-		hshift:   1,
-		vshift:   1,
-	},{
-		name:     "4:1:1, planar, Y-Cb-Cr",
-		palette:  VIDEO_PALETTE_YUV411P,
-		fourcc:   V4L2_PIX_FMT_YUV411P,
-		btformat: BT848_COLOR_FMT_YCrCb411,
-		depth:    12,
-		flags:    FORMAT_FLAGS_PLANAR,
-		hshift:   2,
-		vshift:   0,
-	},{
-		name:     "4:1:0, planar, Y-Cb-Cr",
-		palette:  VIDEO_PALETTE_YUV410P,
-		fourcc:   V4L2_PIX_FMT_YUV410,
-		btformat: BT848_COLOR_FMT_YCrCb411,
-		depth:    9,
-		flags:    FORMAT_FLAGS_PLANAR,
-		hshift:   2,
-		vshift:   2,
-	},{
-		name:     "4:1:0, planar, Y-Cr-Cb",
-		palette:  -1,
-		fourcc:   V4L2_PIX_FMT_YVU410,
-		btformat: BT848_COLOR_FMT_YCrCb411,
-		depth:    9,
-		flags:    FORMAT_FLAGS_PLANAR | FORMAT_FLAGS_CrCb,
-		hshift:   2,
-		vshift:   2,
-	},{
-		name:     "raw scanlines",
-		palette:  VIDEO_PALETTE_RAW,
-		fourcc:   -1,
-		btformat: BT848_COLOR_FMT_RAW,
-		depth:    8,
-		flags:    FORMAT_FLAGS_RAW,
+		.name     = "8 bpp, gray",
+		.palette  = VIDEO_PALETTE_GREY,
+		.fourcc   = V4L2_PIX_FMT_GREY,
+		.btformat = BT848_COLOR_FMT_Y8,
+		.depth    = 8,
+		.flags    = FORMAT_FLAGS_PACKED,
+	},{
+		.name     = "8 bpp, dithered color",
+		.palette  = VIDEO_PALETTE_HI240,
+		.fourcc   = V4L2_PIX_FMT_HI240,
+		.btformat = BT848_COLOR_FMT_RGB8,
+		.depth    = 8,
+		.flags    = FORMAT_FLAGS_PACKED | FORMAT_FLAGS_DITHER,
+	},{
+		.name     = "15 bpp RGB, le",
+		.palette  = VIDEO_PALETTE_RGB555,
+		.fourcc   = V4L2_PIX_FMT_RGB555,
+		.btformat = BT848_COLOR_FMT_RGB15,
+		.depth    = 16,
+		.flags    = FORMAT_FLAGS_PACKED,
+	},{
+		.name     = "15 bpp RGB, be",
+		.palette  = -1,
+		.fourcc   = V4L2_PIX_FMT_RGB555X,
+		.btformat = BT848_COLOR_FMT_RGB15,
+		.btswap   = 0x03, /* byteswap */
+		.depth    = 16,
+		.flags    = FORMAT_FLAGS_PACKED,
+	},{
+		.name     = "16 bpp RGB, le",
+		.palette  = VIDEO_PALETTE_RGB565,
+		.fourcc   = V4L2_PIX_FMT_RGB565,
+		.btformat = BT848_COLOR_FMT_RGB16,
+		.depth    = 16,
+		.flags    = FORMAT_FLAGS_PACKED,
+	},{
+		.name     = "16 bpp RGB, be",
+		.palette  = -1,
+		.fourcc   = V4L2_PIX_FMT_RGB565X,
+		.btformat = BT848_COLOR_FMT_RGB16,
+		.btswap   = 0x03, /* byteswap */
+		.depth    = 16,
+		.flags    = FORMAT_FLAGS_PACKED,
+	},{
+		.name     = "24 bpp RGB, le",
+		.palette  = VIDEO_PALETTE_RGB24,
+		.fourcc   = V4L2_PIX_FMT_BGR24,
+		.btformat = BT848_COLOR_FMT_RGB24,
+		.depth    = 24,
+		.flags    = FORMAT_FLAGS_PACKED,
+	},{
+		.name     = "32 bpp RGB, le",
+		.palette  = VIDEO_PALETTE_RGB32,
+		.fourcc   = V4L2_PIX_FMT_BGR32,
+		.btformat = BT848_COLOR_FMT_RGB32,
+		.depth    = 32,
+		.flags    = FORMAT_FLAGS_PACKED,
+	},{
+		.name     = "32 bpp RGB, be",
+		.palette  = -1,
+		.fourcc   = V4L2_PIX_FMT_RGB32,
+		.btformat = BT848_COLOR_FMT_RGB32,
+		.btswap   = 0x0f, /* byte+word swap */
+		.depth    = 32,
+		.flags    = FORMAT_FLAGS_PACKED,
+	},{
+		.name     = "4:2:2, packed, YUYV",
+		.palette  = VIDEO_PALETTE_YUV422,
+		.fourcc   = V4L2_PIX_FMT_YUYV,
+		.btformat = BT848_COLOR_FMT_YUY2,
+		.depth    = 16,
+		.flags    = FORMAT_FLAGS_PACKED,
+	},{
+		.name     = "4:2:2, packed, YUYV",
+		.palette  = VIDEO_PALETTE_YUYV,
+		.fourcc   = V4L2_PIX_FMT_YUYV,
+		.btformat = BT848_COLOR_FMT_YUY2,
+		.depth    = 16,
+		.flags    = FORMAT_FLAGS_PACKED,
+	},{
+		.name     = "4:2:2, packed, UYVY",
+		.palette  = VIDEO_PALETTE_UYVY,
+		.fourcc   = V4L2_PIX_FMT_UYVY,
+		.btformat = BT848_COLOR_FMT_YUY2,
+		.btswap   = 0x03, /* byteswap */
+		.depth    = 16,
+		.flags    = FORMAT_FLAGS_PACKED,
+	},{
+		.name     = "4:2:2, planar, Y-Cb-Cr",
+		.palette  = VIDEO_PALETTE_YUV422P,
+		.fourcc   = V4L2_PIX_FMT_YUV422P,
+		.btformat = BT848_COLOR_FMT_YCrCb422,
+		.depth    = 16,
+		.flags    = FORMAT_FLAGS_PLANAR,
+		.hshift   = 1,
+		.vshift   = 0,
+	},{
+		.name     = "4:2:0, planar, Y-Cb-Cr",
+		.palette  = VIDEO_PALETTE_YUV420P,
+		.fourcc   = V4L2_PIX_FMT_YUV420,
+		.btformat = BT848_COLOR_FMT_YCrCb422,
+		.depth    = 12,
+		.flags    = FORMAT_FLAGS_PLANAR,
+		.hshift   = 1,
+		.vshift   = 1,
+	},{
+		.name     = "4:2:0, planar, Y-Cr-Cb",
+		.palette  = -1,
+		.fourcc   = V4L2_PIX_FMT_YVU420,
+		.btformat = BT848_COLOR_FMT_YCrCb422,
+		.depth    = 12,
+		.flags    = FORMAT_FLAGS_PLANAR | FORMAT_FLAGS_CrCb,
+		.hshift   = 1,
+		.vshift   = 1,
+	},{
+		.name     = "4:1:1, planar, Y-Cb-Cr",
+		.palette  = VIDEO_PALETTE_YUV411P,
+		.fourcc   = V4L2_PIX_FMT_YUV411P,
+		.btformat = BT848_COLOR_FMT_YCrCb411,
+		.depth    = 12,
+		.flags    = FORMAT_FLAGS_PLANAR,
+		.hshift   = 2,
+		.vshift   = 0,
+	},{
+		.name     = "4:1:0, planar, Y-Cb-Cr",
+		.palette  = VIDEO_PALETTE_YUV410P,
+		.fourcc   = V4L2_PIX_FMT_YUV410,
+		.btformat = BT848_COLOR_FMT_YCrCb411,
+		.depth    = 9,
+		.flags    = FORMAT_FLAGS_PLANAR,
+		.hshift   = 2,
+		.vshift   = 2,
+	},{
+		.name     = "4:1:0, planar, Y-Cr-Cb",
+		.palette  = -1,
+		.fourcc   = V4L2_PIX_FMT_YVU410,
+		.btformat = BT848_COLOR_FMT_YCrCb411,
+		.depth    = 9,
+		.flags    = FORMAT_FLAGS_PLANAR | FORMAT_FLAGS_CrCb,
+		.hshift   = 2,
+		.vshift   = 2,
+	},{
+		.name     = "raw scanlines",
+		.palette  = VIDEO_PALETTE_RAW,
+		.fourcc   = -1,
+		.btformat = BT848_COLOR_FMT_RAW,
+		.depth    = 8,
+		.flags    = FORMAT_FLAGS_RAW,
 	}
 };
 const int BTTV_FORMATS = (sizeof(bttv_formats)/sizeof(struct bttv_format));
@@ -436,115 +436,115 @@
 #define V4L2_CID_PRIVATE_LASTP1      (V4L2_CID_PRIVATE_BASE + 5)
 
 static const struct v4l2_queryctrl no_ctl = {
-	name:  "42",
-	flags: V4L2_CTRL_FLAG_DISABLED,
+	.name  = "42",
+	.flags = V4L2_CTRL_FLAG_DISABLED,
 };
 static const struct v4l2_queryctrl bttv_ctls[] = {
 	/* --- video --- */
 	{
-		id:            V4L2_CID_BRIGHTNESS,
-		name:          "Brightness",
-		minimum:       0,
-		maximum:       65535,
-		step:          256,
-		default_value: 32768,
-		type:          V4L2_CTRL_TYPE_INTEGER,
-	},{
-		id:            V4L2_CID_CONTRAST,
-		name:          "Contrast",
-		minimum:       0,
-		maximum:       65535,
-		step:          128,
-		default_value: 32768,
-		type:          V4L2_CTRL_TYPE_INTEGER,
-	},{
-		id:            V4L2_CID_SATURATION,
-		name:          "Saturation",
-		minimum:       0,
-		maximum:       65535,
-		step:          128,
-		default_value: 32768,
-		type:          V4L2_CTRL_TYPE_INTEGER,
-	},{
-		id:            V4L2_CID_HUE,
-		name:          "Hue",
-		minimum:       0,
-		maximum:       65535,
-		step:          256,
-		default_value: 32768,
-		type:          V4L2_CTRL_TYPE_INTEGER,
+		.id            = V4L2_CID_BRIGHTNESS,
+		.name          = "Brightness",
+		.minimum       = 0,
+		.maximum       = 65535,
+		.step          = 256,
+		.default_value = 32768,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+	},{
+		.id            = V4L2_CID_CONTRAST,
+		.name          = "Contrast",
+		.minimum       = 0,
+		.maximum       = 65535,
+		.step          = 128,
+		.default_value = 32768,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+	},{
+		.id            = V4L2_CID_SATURATION,
+		.name          = "Saturation",
+		.minimum       = 0,
+		.maximum       = 65535,
+		.step          = 128,
+		.default_value = 32768,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+	},{
+		.id            = V4L2_CID_HUE,
+		.name          = "Hue",
+		.minimum       = 0,
+		.maximum       = 65535,
+		.step          = 256,
+		.default_value = 32768,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
 	},
 	/* --- audio --- */
 	{
-		id:            V4L2_CID_AUDIO_MUTE,
-		name:          "Mute",
-		minimum:       0,
-		maximum:       1,
-		type:          V4L2_CTRL_TYPE_BOOLEAN,
-	},{
-		id:            V4L2_CID_AUDIO_VOLUME,
-		name:          "Volume",
-		minimum:       0,
-		maximum:       65535,
-		step:          65535/100,
-		default_value: 65535,
-		type:          V4L2_CTRL_TYPE_INTEGER,
-	},{
-		id:            V4L2_CID_AUDIO_BALANCE,
-		name:          "Balance",
-		minimum:       0,
-		maximum:       65535,
-		step:          65535/100,
-		default_value: 32768,
-		type:          V4L2_CTRL_TYPE_INTEGER,
-	},{
-		id:            V4L2_CID_AUDIO_BASS,
-		name:          "Bass",
-		minimum:       0,
-		maximum:       65535,
-		step:          65535/100,
-		default_value: 32768,
-		type:          V4L2_CTRL_TYPE_INTEGER,
-	},{
-		id:            V4L2_CID_AUDIO_TREBLE,
-		name:          "Treble",
-		minimum:       0,
-		maximum:       65535,
-		step:          65535/100,
-		default_value: 32768,
-		type:          V4L2_CTRL_TYPE_INTEGER,
+		.id            = V4L2_CID_AUDIO_MUTE,
+		.name          = "Mute",
+		.minimum       = 0,
+		.maximum       = 1,
+		.type          = V4L2_CTRL_TYPE_BOOLEAN,
+	},{
+		.id            = V4L2_CID_AUDIO_VOLUME,
+		.name          = "Volume",
+		.minimum       = 0,
+		.maximum       = 65535,
+		.step          = 65535/100,
+		.default_value = 65535,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+	},{
+		.id            = V4L2_CID_AUDIO_BALANCE,
+		.name          = "Balance",
+		.minimum       = 0,
+		.maximum       = 65535,
+		.step          = 65535/100,
+		.default_value = 32768,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+	},{
+		.id            = V4L2_CID_AUDIO_BASS,
+		.name          = "Bass",
+		.minimum       = 0,
+		.maximum       = 65535,
+		.step          = 65535/100,
+		.default_value = 32768,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+	},{
+		.id            = V4L2_CID_AUDIO_TREBLE,
+		.name          = "Treble",
+		.minimum       = 0,
+		.maximum       = 65535,
+		.step          = 65535/100,
+		.default_value = 32768,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
 	},
 	/* --- private --- */
 	{
-		id:            V4L2_CID_PRIVATE_CHROMA_AGC,
-		name:          "chroma agc",
-		minimum:       0,
-		maximum:       1,
-		type:          V4L2_CTRL_TYPE_BOOLEAN,
-	},{
-		id:            V4L2_CID_PRIVATE_COMBFILTER,
-		name:          "combfilter",
-		minimum:       0,
-		maximum:       1,
-		type:          V4L2_CTRL_TYPE_BOOLEAN,
-	},{
-		id:            V4L2_CID_PRIVATE_AUTOMUTE,
-		name:          "automute",
-		minimum:       0,
-		maximum:       1,
-		type:          V4L2_CTRL_TYPE_BOOLEAN,
-	},{
-		id:            V4L2_CID_PRIVATE_LUMAFILTER,
-		name:          "luma decimation filter",
-		minimum:       0,
-		maximum:       1,
-		type:          V4L2_CTRL_TYPE_BOOLEAN,
-	},{
-		id:            V4L2_CID_PRIVATE_AGC_CRUSH,
-		name:          "agc crush",
-		minimum:       0,
-		maximum:       1,
-		type:          V4L2_CTRL_TYPE_BOOLEAN,
+		.id            = V4L2_CID_PRIVATE_CHROMA_AGC,
+		.name          = "chroma agc",
+		.minimum       = 0,
+		.maximum       = 1,
+		.type          = V4L2_CTRL_TYPE_BOOLEAN,
+	},{
+		.id            = V4L2_CID_PRIVATE_COMBFILTER,
+		.name          = "combfilter",
+		.minimum       = 0,
+		.maximum       = 1,
+		.type          = V4L2_CTRL_TYPE_BOOLEAN,
+	},{
+		.id            = V4L2_CID_PRIVATE_AUTOMUTE,
+		.name          = "automute",
+		.minimum       = 0,
+		.maximum       = 1,
+		.type          = V4L2_CTRL_TYPE_BOOLEAN,
+	},{
+		.id            = V4L2_CID_PRIVATE_LUMAFILTER,
+		.name          = "luma decimation filter",
+		.minimum       = 0,
+		.maximum       = 1,
+		.type          = V4L2_CTRL_TYPE_BOOLEAN,
+	},{
+		.id            = V4L2_CID_PRIVATE_AGC_CRUSH,
+		.name          = "agc crush",
+		.minimum       = 0,
+		.maximum       = 1,
+		.type          = V4L2_CTRL_TYPE_BOOLEAN,
 	}
 };
 const int BTTV_CTLS = (sizeof(bttv_ctls)/sizeof(struct v4l2_queryctrl));
@@ -1314,10 +1314,10 @@
 }
 
 static struct videobuf_queue_ops bttv_video_qops = {
-	buf_setup:    buffer_setup,
-	buf_prepare:  buffer_prepare,
-	buf_queue:    buffer_queue,
-	buf_release:  buffer_release,
+	.buf_setup    = buffer_setup,
+	.buf_prepare  = buffer_prepare,
+	.buf_queue    = buffer_queue,
+	.buf_release  = buffer_release,
 };
 
 static const char *v4l1_ioctls[] = {
@@ -2706,33 +2706,33 @@
 
 static struct file_operations bttv_fops =
 {
-	owner:	  THIS_MODULE,
-	open:	  bttv_open,
-	release:  bttv_release,
-	ioctl:	  bttv_ioctl,
-	llseek:	  no_llseek,
-	read:	  bttv_read,
-	mmap:	  bttv_mmap,
-	poll:     bttv_poll,
+	.owner	  = THIS_MODULE,
+	.open	  = bttv_open,
+	.release  = bttv_release,
+	.ioctl	  = bttv_ioctl,
+	.llseek	  = no_llseek,
+	.read	  = bttv_read,
+	.mmap	  = bttv_mmap,
+	.poll     = bttv_poll,
 };
 
 static struct video_device bttv_video_template =
 {
-	name:     "UNSET",
-	type:     VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
+	.name     = "UNSET",
+	.type     = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
 	          VID_TYPE_CLIPPING|VID_TYPE_SCALES,
-	hardware: VID_HARDWARE_BT848,
-	fops:     &bttv_fops,
-	minor:    -1,
+	.hardware = VID_HARDWARE_BT848,
+	.fops     = &bttv_fops,
+	.minor    = -1,
 };
 
 struct video_device bttv_vbi_template =
 {
-	name:     "bt848/878 vbi",
-	type:     VID_TYPE_TUNER|VID_TYPE_TELETEXT,
-	hardware: VID_HARDWARE_BT848,
-	fops:     &bttv_fops,
-	minor:    -1,
+	.name     = "bt848/878 vbi",
+	.type     = VID_TYPE_TUNER|VID_TYPE_TELETEXT,
+	.hardware = VID_HARDWARE_BT848,
+	.fops     = &bttv_fops,
+	.minor    = -1,
 };
 
 /* ----------------------------------------------------------------------- */
@@ -2841,20 +2841,20 @@
 
 static struct file_operations radio_fops =
 {
-	owner:	  THIS_MODULE,
-	open:	  radio_open,
-	release:  radio_release,
-	ioctl:	  radio_ioctl,
-	llseek:	  no_llseek,
+	.owner	  = THIS_MODULE,
+	.open	  = radio_open,
+	.release  = radio_release,
+	.ioctl	  = radio_ioctl,
+	.llseek	  = no_llseek,
 };
 
 static struct video_device radio_template =
 {
-	name:     "bt848/878 radio",
-	type:     VID_TYPE_TUNER,
-	hardware: VID_HARDWARE_BT848,
-	fops:     &radio_fops,
-	minor:    -1,
+	.name     = "bt848/878 radio",
+	.type     = VID_TYPE_TUNER,
+	.hardware = VID_HARDWARE_BT848,
+	.fops     = &radio_fops,
+	.minor    = -1,
 };
 
 /* ----------------------------------------------------------------------- */
@@ -3439,10 +3439,10 @@
 MODULE_DEVICE_TABLE(pci, bttv_pci_tbl);
 
 static struct pci_driver bttv_pci_driver = {
-        name:     "bttv",
-        id_table: bttv_pci_tbl,
-        probe:    bttv_probe,
-        remove:   __devexit_p(bttv_remove),
+        .name     = "bttv",
+        .id_table = bttv_pci_tbl,
+        .probe    = bttv_probe,
+        .remove   = __devexit_p(bttv_remove),
 };
 
 static int bttv_init_module(void)
diff -Nru a/drivers/media/video/bttv-if.c b/drivers/media/video/bttv-if.c
--- a/drivers/media/video/bttv-if.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/media/video/bttv-if.c	Mon Dec  9 18:46:34 2002
@@ -262,27 +262,27 @@
 }
 
 static struct i2c_algo_bit_data bttv_i2c_algo_template = {
-	setsda:  bttv_bit_setsda,
-	setscl:  bttv_bit_setscl,
-	getsda:  bttv_bit_getsda,
-	getscl:  bttv_bit_getscl,
-	udelay:  16,
-	mdelay:  10,
-	timeout: 200,
+	.setsda  = bttv_bit_setsda,
+	.setscl  = bttv_bit_setscl,
+	.getsda  = bttv_bit_getsda,
+	.getscl  = bttv_bit_getscl,
+	.udelay  = 16,
+	.mdelay  = 10,
+	.timeout = 200,
 };
 
 static struct i2c_adapter bttv_i2c_adap_template = {
-	name:              "bt848",
-	id:                I2C_HW_B_BT848,
-	inc_use:           bttv_inc_use,
-	dec_use:           bttv_dec_use,
-	client_register:   attach_inform,
-	client_unregister: detach_inform,
+	.name              = "bt848",
+	.id                = I2C_HW_B_BT848,
+	.inc_use           = bttv_inc_use,
+	.dec_use           = bttv_dec_use,
+	.client_register   = attach_inform,
+	.client_unregister = detach_inform,
 };
 
 static struct i2c_client bttv_i2c_client_template = {
-        name: "bttv internal use only",
-        id:   -1,
+        .name = "bttv internal use only",
+        .id   = -1,
 };
 
 
diff -Nru a/drivers/media/video/bttv-vbi.c b/drivers/media/video/bttv-vbi.c
--- a/drivers/media/video/bttv-vbi.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/media/video/bttv-vbi.c	Mon Dec  9 18:46:50 2002
@@ -123,10 +123,10 @@
 }
 
 struct videobuf_queue_ops bttv_vbi_qops = {
-	buf_setup:    vbi_buffer_setup,
-	buf_prepare:  vbi_buffer_prepare,
-	buf_queue:    vbi_buffer_queue,
-	buf_release:  vbi_buffer_release,
+	.buf_setup    = vbi_buffer_setup,
+	.buf_prepare  = vbi_buffer_prepare,
+	.buf_queue    = vbi_buffer_queue,
+	.buf_release  = vbi_buffer_release,
 };
 
 /* ----------------------------------------------------------------------- */
diff -Nru a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
--- a/drivers/media/video/bw-qcam.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/media/video/bw-qcam.c	Mon Dec  9 18:46:35 2002
@@ -885,20 +885,20 @@
 }
  
 static struct file_operations qcam_fops = {
-	owner:		THIS_MODULE,
-	open:           video_exclusive_open,
-	release:        video_exclusive_release,
-	ioctl:          qcam_ioctl,
-	read:		qcam_read,
-	llseek:         no_llseek,
+	.owner		= THIS_MODULE,
+	.open           = video_exclusive_open,
+	.release        = video_exclusive_release,
+	.ioctl          = qcam_ioctl,
+	.read		= qcam_read,
+	.llseek         = no_llseek,
 };
 static struct video_device qcam_template=
 {
-	owner:		THIS_MODULE,
-	name:		"Connectix Quickcam",
-	type:		VID_TYPE_CAPTURE,
-	hardware:	VID_HARDWARE_QCAM_BW,
-	fops:           &qcam_fops,
+	.owner		= THIS_MODULE,
+	.name		= "Connectix Quickcam",
+	.type		= VID_TYPE_CAPTURE,
+	.hardware	= VID_HARDWARE_QCAM_BW,
+	.fops           = &qcam_fops,
 };
 
 #define MAX_CAMS 4
diff -Nru a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
--- a/drivers/media/video/c-qcam.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/media/video/c-qcam.c	Mon Dec  9 18:46:36 2002
@@ -686,21 +686,21 @@
 
 /* video device template */
 static struct file_operations qcam_fops = {
-	owner:		THIS_MODULE,
-	open:           video_exclusive_open,
-	release:        video_exclusive_release,
-	ioctl:          qcam_ioctl,
-	read:		qcam_read,
-	llseek:         no_llseek,
+	.owner		= THIS_MODULE,
+	.open           = video_exclusive_open,
+	.release        = video_exclusive_release,
+	.ioctl          = qcam_ioctl,
+	.read		= qcam_read,
+	.llseek         = no_llseek,
 };
 
 static struct video_device qcam_template=
 {
-	owner:		THIS_MODULE,
-	name:		"Colour QuickCam",
-	type:		VID_TYPE_CAPTURE,
-	hardware:	VID_HARDWARE_QCAM_C,
-	fops:           &qcam_fops,
+	.owner		= THIS_MODULE,
+	.name		= "Colour QuickCam",
+	.type		= VID_TYPE_CAPTURE,
+	.hardware	= VID_HARDWARE_QCAM_C,
+	.fops           = &qcam_fops,
 };
 
 /* Initialize the QuickCam driver control structure. */
diff -Nru a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
--- a/drivers/media/video/cpia.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/media/video/cpia.c	Mon Dec  9 18:46:50 2002
@@ -3783,21 +3783,21 @@
 }
 
 static struct file_operations cpia_fops = {
-	owner:		THIS_MODULE,
-	open:		cpia_open,
-	release:       	cpia_close,
-	read:		cpia_read,
-	mmap:		cpia_mmap,
-	ioctl:          cpia_ioctl,
-	llseek:         no_llseek,
+	.owner		= THIS_MODULE,
+	.open		= cpia_open,
+	.release       	= cpia_close,
+	.read		= cpia_read,
+	.mmap		= cpia_mmap,
+	.ioctl          = cpia_ioctl,
+	.llseek         = no_llseek,
 };
 
 static struct video_device cpia_template = {
-	owner:		THIS_MODULE,
-	name:		"CPiA Camera",
-	type:		VID_TYPE_CAPTURE,
-	hardware:	VID_HARDWARE_CPIA,
-	fops:           &cpia_fops,
+	.owner		= THIS_MODULE,
+	.name		= "CPiA Camera",
+	.type		= VID_TYPE_CAPTURE,
+	.hardware	= VID_HARDWARE_CPIA,
+	.fops           = &cpia_fops,
 };
 
 /* initialise cam_data structure  */
diff -Nru a/drivers/media/video/cpia_usb.c b/drivers/media/video/cpia_usb.c
--- a/drivers/media/video/cpia_usb.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/media/video/cpia_usb.c	Mon Dec  9 18:46:34 2002
@@ -107,7 +107,7 @@
 static struct cam_data *cam_list;
 static spinlock_t cam_list_lock_usb;
 
-static void cpia_usb_complete(struct urb *urb)
+static void cpia_usb_complete(struct urb *urb, struct pt_regs *regs)
 {
 	int i;
 	char *cdata;
@@ -582,10 +582,10 @@
 
 
 static struct usb_driver cpia_driver = {
-	name:		"cpia",
-	probe:		cpia_probe,
-	disconnect:	cpia_disconnect,
-	id_table:	cpia_id_table,
+	.name		= "cpia",
+	.probe		= cpia_probe,
+	.disconnect	= cpia_disconnect,
+	.id_table	= cpia_id_table,
 };
 
 /* don't use dev, it may be NULL! (see usb_cpia_cleanup) */
diff -Nru a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
--- a/drivers/media/video/msp3400.c	Mon Dec  9 18:46:49 2002
+++ b/drivers/media/video/msp3400.c	Mon Dec  9 18:46:49 2002
@@ -1213,19 +1213,19 @@
 static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg);
 
 static struct i2c_driver driver = {
-        name:           "i2c msp3400 driver",
-        id:             I2C_DRIVERID_MSP3400,
-        flags:          I2C_DF_NOTIFY,
-        attach_adapter: msp_probe,
-        detach_client:  msp_detach,
-        command:        msp_command,
+	.name		= "i2cmsp3400driver",
+	.id		= I2C_DRIVERID_MSP3400,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= msp_probe,
+	.detach_client	= msp_detach,
+	.command	= msp_command,
 };
 
 static struct i2c_client client_template = 
 {
-	name:   "(unset)",
-	flags:  I2C_CLIENT_ALLOW_USE,
-        driver: &driver,
+	.name	= "(unset)",
+	.flags	= I2C_CLIENT_ALLOW_USE,
+	.driver	= &driver,
 };
 
 static int msp_attach(struct i2c_adapter *adap, int addr,
diff -Nru a/drivers/media/video/planb.c b/drivers/media/video/planb.c
--- a/drivers/media/video/planb.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/media/video/planb.c	Mon Dec  9 18:46:50 2002
@@ -2020,16 +2020,16 @@
 
 static struct video_device planb_template=
 {
-	owner:		THIS_MODULE,
-	name:		PLANB_DEVICE_NAME,
-	type:		VID_TYPE_OVERLAY,
-	hardware:	VID_HARDWARE_PLANB,
-	open:		planb_open,
-	close:		planb_close,
-	read:		planb_read,
-	write:		planb_write,
-	ioctl:		planb_ioctl,
-	mmap:		planb_mmap,	/* mmap? */
+	.owner		= THIS_MODULE,
+	.name		= PLANB_DEVICE_NAME,
+	.type		= VID_TYPE_OVERLAY,
+	.hardware	= VID_HARDWARE_PLANB,
+	.open		= planb_open,
+	.close		= planb_close,
+	.read		= planb_read,
+	.write		= planb_write,
+	.ioctl		= planb_ioctl,
+	.mmap		= planb_mmap,	/* mmap? */
 };
 
 static int init_planb(struct planb *pb)
diff -Nru a/drivers/media/video/pms.c b/drivers/media/video/pms.c
--- a/drivers/media/video/pms.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/media/video/pms.c	Mon Dec  9 18:46:50 2002
@@ -875,21 +875,21 @@
 }
 
 static struct file_operations pms_fops = {
-	owner:		THIS_MODULE,
-	open:           video_exclusive_open,
-	release:        video_exclusive_release,
-	ioctl:          pms_ioctl,
-	read:           pms_read,
-	llseek:         no_llseek,
+	.owner		= THIS_MODULE,
+	.open           = video_exclusive_open,
+	.release        = video_exclusive_release,
+	.ioctl          = pms_ioctl,
+	.read           = pms_read,
+	.llseek         = no_llseek,
 };
 
 static struct video_device pms_template=
 {
-	owner:		THIS_MODULE,
-	name:		"Mediavision PMS",
-	type:		VID_TYPE_CAPTURE,
-	hardware:	VID_HARDWARE_PMS,
-	fops:           &pms_fops,
+	.owner		= THIS_MODULE,
+	.name		= "Mediavision PMS",
+	.type		= VID_TYPE_CAPTURE,
+	.hardware	= VID_HARDWARE_PMS,
+	.fops           = &pms_fops,
 };
 
 struct pms_device pms_device;
diff -Nru a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
--- a/drivers/media/video/saa5249.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/media/video/saa5249.c	Mon Dec  9 18:46:50 2002
@@ -678,20 +678,20 @@
 module_exit(cleanup_saa_5249);
 
 static struct file_operations saa_fops = {
-	owner:		THIS_MODULE,
-	open:		saa5249_open,
-	release:       	saa5249_release,
-	ioctl:          saa5249_ioctl,
-	llseek:         no_llseek,
+	.owner		= THIS_MODULE,
+	.open		= saa5249_open,
+	.release       	= saa5249_release,
+	.ioctl          = saa5249_ioctl,
+	.llseek         = no_llseek,
 };
 
 static struct video_device saa_template =
 {
-	owner:		THIS_MODULE,
-	name:		IF_NAME,
-	type:		VID_TYPE_TELETEXT,	/*| VID_TYPE_TUNER ?? */
-	hardware:	VID_HARDWARE_SAA5249,
-	fops:           &saa_fops,
+	.owner		= THIS_MODULE,
+	.name		= IF_NAME,
+	.type		= VID_TYPE_TELETEXT,	/*| VID_TYPE_TUNER ?? */
+	.hardware	= VID_HARDWARE_SAA5249,
+	.fops           = &saa_fops,
 };
 
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
--- a/drivers/media/video/saa7134/saa7134-cards.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/media/video/saa7134/saa7134-cards.c	Mon Dec  9 18:46:50 2002
@@ -39,253 +39,253 @@
 
 struct saa7134_board saa7134_boards[] = {
 	[SAA7134_BOARD_UNKNOWN] = {
-		name:		"UNKNOWN/GENERIC",
-		audio_clock:	0x00187de7,
-		tuner_type:	TUNER_ABSENT,
-		inputs: {{
-			name: "default",
-			vmux: 0,
-			amux: LINE1,
+		.name		= "UNKNOWN/GENERIC",
+		.audio_clock	= 0x00187de7,
+		.tuner_type	= TUNER_ABSENT,
+		.inputs         = {{
+			.name = "default",
+			.vmux = 0,
+			.amux = LINE1,
 		}},
 	},
 	[SAA7134_BOARD_PROTEUS_PRO] = {
 		/* /me */
-		name:		"Proteus Pro [philips reference design]",
-		audio_clock:	0x00187de7,
-		tuner_type:	TUNER_PHILIPS_PAL,
-		inputs: {{
-			name: name_comp1,
-			vmux: 0,
-			amux: LINE1,
-		},{
-			name: name_tv,
-			vmux: 1,
-			amux: TV,
-			tv:   1,
+		.name		= "Proteus Pro [philips reference design]",
+		.audio_clock	= 0x00187de7,
+		.tuner_type	= TUNER_PHILIPS_PAL,
+		.inputs         = {{
+			.name = name_comp1,
+			.vmux = 0,
+			.amux = LINE1,
+		},{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
 		}},
 	},
 	[SAA7134_BOARD_FLYVIDEO3000] = {
 		/* "Marco d'Itri" <md@Linux.IT> */
-		name:		"LifeView FlyVIDEO3000",
-		audio_clock:	0x00200000,
-		tuner_type:	TUNER_PHILIPS_PAL,
-		inputs: {{
-			name: name_tv,
-			vmux: 1,
-			amux: TV,
-			tv:   1,
-		},{
-			name: name_comp1,
-			vmux: 0,
-			amux: LINE1,
-		},{
-			name: name_comp2,
-			vmux: 3,
-			amux: LINE1,
-		},{
-			name: name_svideo,
-			vmux: 8,
-			amux: LINE1,
+		.name		= "LifeView FlyVIDEO3000",
+		.audio_clock	= 0x00200000,
+		.tuner_type	= TUNER_PHILIPS_PAL,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
+		},{
+			.name = name_comp1,
+			.vmux = 0,
+			.amux = LINE1,
+		},{
+			.name = name_comp2,
+			.vmux = 3,
+			.amux = LINE1,
+		},{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
 		}},
-		radio: {
-			name: name_radio,
-			amux: LINE2,
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
 		},
 	},
 	[SAA7134_BOARD_FLYVIDEO2000] = {
 		/* "TC Wan" <tcwan@cs.usm.my> */
-		name:           "LifeView FlyVIDEO2000",
-		audio_clock:    0x00200000,
-		tuner_type:     TUNER_LG_PAL_NEW_TAPC,
-		gpiomask:       0x6000,
-		inputs: {{
-			name: name_tv,
-			vmux: 1,
-			amux: LINE2,
-			gpio: 0x0000,
-			tv:   1,
-		},{
-			name: name_comp1,
-			vmux: 0,
-			amux: LINE2,
-			gpio: 0x4000,
-		},{
-			name: name_comp2,
-			vmux: 3,
-			amux: LINE2,
-			gpio: 0x4000,
-		},{
-			name: name_svideo,
-			vmux: 8,
-			amux: LINE2,
-			gpio: 0x4000,
+		.name           = "LifeView FlyVIDEO2000",
+		.audio_clock    = 0x00200000,
+		.tuner_type     = TUNER_LG_PAL_NEW_TAPC,
+		.gpiomask       = 0x6000,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = LINE2,
+			.gpio = 0x0000,
+			.tv   = 1,
+		},{
+			.name = name_comp1,
+			.vmux = 0,
+			.amux = LINE2,
+			.gpio = 0x4000,
+		},{
+			.name = name_comp2,
+			.vmux = 3,
+			.amux = LINE2,
+			.gpio = 0x4000,
+		},{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE2,
+			.gpio = 0x4000,
 		}},
-                radio: {
-                        name: name_radio,
-                        amux: LINE2,
+                .radio = {
+                        .name = name_radio,
+                        .amux = LINE2,
                 },
-		mute: {
-			name: name_mute,
-			amux: LINE1,
+		.mute = {
+			.name = name_mute,
+			.amux = LINE1,
 		},
 	},
 	[SAA7134_BOARD_EMPRESS] = {
 		/* "Gert Vervoort" <gert.vervoort@philips.com> */
-		name:		"EMPRESS",
-		audio_clock:	0x00187de7,
-		tuner_type:	TUNER_PHILIPS_PAL,
-		inputs: {{
-			name: name_comp1,
-			vmux: 0,
-			amux: LINE1,
-		},{
-			name: name_svideo,
-			vmux: 8,
-			amux: LINE1,
-		},{
-			name: name_tv,
-			vmux: 1,
-			amux: LINE2,
-			tv:   1,
+		.name		= "EMPRESS",
+		.audio_clock	= 0x00187de7,
+		.tuner_type	= TUNER_PHILIPS_PAL,
+		.inputs         = {{
+			.name = name_comp1,
+			.vmux = 0,
+			.amux = LINE1,
+		},{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		},{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = LINE2,
+			.tv   = 1,
 		}},
-		radio: {
-			name: name_radio,
-			amux: LINE2,
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
 		},
-		i2s_rate:  48000,
-		has_ts:    1,
-		video_out: CCIR656,
+		.i2s_rate  = 48000,
+		.has_ts    = 1,
+		.video_out = CCIR656,
 	},
 	[SAA7134_BOARD_MONSTERTV] = {
                /* "K.Ohta" <alpha292@bremen.or.jp> */
-               name:           "SKNet Monster TV",
-               audio_clock:    0x00187de7,
-               tuner_type:     TUNER_PHILIPS_NTSC_M,
-               inputs: {{
-                       name: name_tv,
-                       vmux: 1,
-                       amux: TV,
-                       tv:   1,
+               .name           = "SKNet Monster TV",
+               .audio_clock    = 0x00187de7,
+               .tuner_type     = TUNER_PHILIPS_NTSC_M,
+               .inputs         = {{
+                       .name = name_tv,
+                       .vmux = 1,
+                       .amux = TV,
+                       .tv   = 1,
                },{
-                       name: name_comp1,
-                       vmux: 0,
-                       amux: LINE1,
+                       .name = name_comp1,
+                       .vmux = 0,
+                       .amux = LINE1,
                },{
-                       name: name_svideo,
-                       vmux: 8,
-                       amux: LINE1,
+                       .name = name_svideo,
+                       .vmux = 8,
+                       .amux = LINE1,
                }},
-               radio: {
-                       name: name_radio,
-                       amux: LINE2,
+               .radio = {
+                       .name = name_radio,
+                       .amux = LINE2,
                },
 	},
 	[SAA7134_BOARD_MD9717] = {
-		name:		"Tevion MD 9717",
-		audio_clock:	0x00200000,
-		tuner_type:	TUNER_PHILIPS_PAL,
-		inputs: {{
-			name: name_tv,
-			vmux: 1,
-			amux: TV,
-			tv:   1,
+		.name		= "Tevion MD 9717",
+		.audio_clock	= 0x00200000,
+		.tuner_type	= TUNER_PHILIPS_PAL,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
 		},{
 			/* workaround for problems with normal TV sound */
-			name: "TV (mono only)",
-			vmux: 1,
-			amux: LINE2,
-			tv:   1,
-		},{
-			name: name_comp1,
-			vmux: 2,
-			amux: LINE1,
-		},{
-			name: name_comp2,
-			vmux: 3,
-			amux: LINE1,
-		},{
-			name: name_svideo,
-			vmux: 8,
-			amux: LINE1,
+			.name = "TV (mono only)",
+			.vmux = 1,
+			.amux = LINE2,
+			.tv   = 1,
+		},{
+			.name = name_comp1,
+			.vmux = 2,
+			.amux = LINE1,
+		},{
+			.name = name_comp2,
+			.vmux = 3,
+			.amux = LINE1,
+		},{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
 		}},
-		radio: {
-			name: name_radio,
-			amux: LINE2,
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
 		},
 	},
 	[SAA7134_BOARD_TVSTATION_RDS] = {
-		name:		"KNC One TV-Station RDS",
-		audio_clock:	0x00200000,
-		tuner_type:	TUNER_PHILIPS_FM1216ME_MK3,
-		need_tda9887:   1,
-		inputs: {{
-			name: name_tv,
-			vmux: 1,
-			amux: TV,
-			tv:   1,
-		},{
-			name: name_comp1,
-			vmux: 2,
-			amux: LINE1,
-		},{
-			name: name_comp2,
-			vmux: 3,
-			amux: LINE1,
+		.name		= "KNC One TV-Station RDS",
+		.audio_clock	= 0x00200000,
+		.tuner_type	= TUNER_PHILIPS_FM1216ME_MK3,
+		.need_tda9887   = 1,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
+		},{
+			.name = name_comp1,
+			.vmux = 2,
+			.amux = LINE1,
+		},{
+			.name = name_comp2,
+			.vmux = 3,
+			.amux = LINE1,
 		}},
-		radio: {
-			name: name_radio,
-			amux: LINE2,
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
 		},
 	},
 	[SAA7134_BOARD_CINERGY400] = {
-                name:           "Terratec Cinergy 400 TV",
-                audio_clock:    0x00200000,
-                tuner_type:     TUNER_PHILIPS_PAL,
-                inputs: {{
-                        name: name_tv,
-                        vmux: 1,
-                        amux: TV,
-                        tv:   1,
+                .name           = "Terratec Cinergy 400 TV",
+                .audio_clock    = 0x00200000,
+                .tuner_type     = TUNER_PHILIPS_PAL,
+                .inputs         = {{
+                        .name = name_tv,
+                        .vmux = 1,
+                        .amux = TV,
+                        .tv   = 1,
                 },{
-                        name: name_comp1,
-                        vmux: 4,
-                        amux: LINE1,
+                        .name = name_comp1,
+                        .vmux = 4,
+                        .amux = LINE1,
                 },{
-                        name: name_svideo,
-                        vmux: 8,
-                        amux: LINE1,
+                        .name = name_svideo,
+                        .vmux = 8,
+                        .amux = LINE1,
                 },{
-                        name: name_comp2, // CVideo over SVideo Connector
-                        vmux: 0,
-                        amux: LINE1,
+                        .name = name_comp2, // CVideo over SVideo Connector
+                        .vmux = 0,
+                        .amux = LINE1,
                 }}
         },
 	[SAA7134_BOARD_MD5044] = {
-		name:           "Medion 5044",
-		audio_clock:    0x00200000,
-		tuner_type:     TUNER_PHILIPS_FM1216ME_MK3,
-		need_tda9887:   1,
-		inputs: {{
-			name: name_tv,
-			vmux: 1,
-			amux: TV,
-			tv:   1,
-		},{
-			name: name_comp1,
-			vmux: 0,
-			amux: LINE2,
-		},{
-			name: name_comp2,
-			vmux: 3,
-			amux: LINE2,
-		},{
-			name: name_svideo,
-			vmux: 8,
-			amux: LINE2,
+		.name           = "Medion 5044",
+		.audio_clock    = 0x00200000,
+		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
+		.need_tda9887   = 1,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
+		},{
+			.name = name_comp1,
+			.vmux = 0,
+			.amux = LINE2,
+		},{
+			.name = name_comp2,
+			.vmux = 3,
+			.amux = LINE2,
+		},{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE2,
 		}},
-		radio: {
-			name: name_radio,
-			amux: LINE2,
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
 		},
 	},
 };
@@ -296,57 +296,57 @@
 
 struct pci_device_id __devinitdata saa7134_pci_tbl[] = {
 	{
-		vendor:       PCI_VENDOR_ID_PHILIPS,
-		device:       PCI_DEVICE_ID_PHILIPS_SAA7134,
-		subvendor:    PCI_VENDOR_ID_PHILIPS,
-		subdevice:    0x2001,
-		driver_data:  SAA7134_BOARD_PROTEUS_PRO,
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+		.subvendor    = PCI_VENDOR_ID_PHILIPS,
+		.subdevice    = 0x2001,
+		.driver_data  = SAA7134_BOARD_PROTEUS_PRO,
         },{
-		vendor:       PCI_VENDOR_ID_PHILIPS,
-		device:       PCI_DEVICE_ID_PHILIPS_SAA7134,
-		subvendor:    PCI_VENDOR_ID_PHILIPS,
-		subdevice:    0x6752,
-		driver_data:  SAA7134_BOARD_EMPRESS,
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+		.subvendor    = PCI_VENDOR_ID_PHILIPS,
+		.subdevice    = 0x6752,
+		.driver_data  = SAA7134_BOARD_EMPRESS,
 	},{
-		vendor:       PCI_VENDOR_ID_PHILIPS,
-		device:       PCI_DEVICE_ID_PHILIPS_SAA7134,
-                subvendor:    0x1131,
-                subdevice:    0x4e85,
-		driver_data:  SAA7134_BOARD_MONSTERTV,
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+                .subvendor    = 0x1131,
+                .subdevice    = 0x4e85,
+		.driver_data  = SAA7134_BOARD_MONSTERTV,
         },{
-                vendor:       PCI_VENDOR_ID_PHILIPS,
-                device:       PCI_DEVICE_ID_PHILIPS_SAA7134,
-                subvendor:    0x153B,
-                subdevice:    0x1142,
-                driver_data:  SAA7134_BOARD_CINERGY400,
+                .vendor       = PCI_VENDOR_ID_PHILIPS,
+                .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+                .subvendor    = 0x153B,
+                .subdevice    = 0x1142,
+                .driver_data  = SAA7134_BOARD_CINERGY400,
         },{
 
 		/* --- boards without eeprom + subsystem ID --- */
-                vendor:       PCI_VENDOR_ID_PHILIPS,
-                device:       PCI_DEVICE_ID_PHILIPS_SAA7134,
-                subvendor:    PCI_VENDOR_ID_PHILIPS,
-		subdevice:    0,
-		driver_data:  SAA7134_BOARD_NOAUTO,
+                .vendor       = PCI_VENDOR_ID_PHILIPS,
+                .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+                .subvendor    = PCI_VENDOR_ID_PHILIPS,
+		.subdevice    = 0,
+		.driver_data  = SAA7134_BOARD_NOAUTO,
         },{
-                vendor:       PCI_VENDOR_ID_PHILIPS,
-                device:       PCI_DEVICE_ID_PHILIPS_SAA7130,
-                subvendor:    PCI_VENDOR_ID_PHILIPS,
-		subdevice:    0,
-		driver_data:  SAA7134_BOARD_NOAUTO,
+                .vendor       = PCI_VENDOR_ID_PHILIPS,
+                .device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
+                .subvendor    = PCI_VENDOR_ID_PHILIPS,
+		.subdevice    = 0,
+		.driver_data  = SAA7134_BOARD_NOAUTO,
 	},{
 		
 		/* --- default catch --- */
-		vendor:       PCI_VENDOR_ID_PHILIPS,
-		device:       PCI_DEVICE_ID_PHILIPS_SAA7130,
-                subvendor:    PCI_ANY_ID,
-                subdevice:    PCI_ANY_ID,
-		driver_data:  SAA7134_BOARD_UNKNOWN,
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
+                .subvendor    = PCI_ANY_ID,
+                .subdevice    = PCI_ANY_ID,
+		.driver_data  = SAA7134_BOARD_UNKNOWN,
         },{
-		vendor:       PCI_VENDOR_ID_PHILIPS,
-		device:       PCI_DEVICE_ID_PHILIPS_SAA7134,
-                subvendor:    PCI_ANY_ID,
-                subdevice:    PCI_ANY_ID,
-		driver_data:  SAA7134_BOARD_UNKNOWN,
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+                .subvendor    = PCI_ANY_ID,
+                .subdevice    = PCI_ANY_ID,
+		.driver_data  = SAA7134_BOARD_UNKNOWN,
 	},{
 		/* --- end of list --- */
 	}
diff -Nru a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
--- a/drivers/media/video/saa7134/saa7134-core.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/media/video/saa7134/saa7134-core.c	Mon Dec  9 18:46:35 2002
@@ -896,10 +896,10 @@
 }
 
 static struct pci_driver saa7134_pci_driver = {
-        name:     "saa7134",
-        id_table: saa7134_pci_tbl,
-        probe:    saa7134_initdev,
-        remove:   saa7134_finidev,
+        .name     = "saa7134",
+        .id_table = saa7134_pci_tbl,
+        .probe    = saa7134_initdev,
+        .remove   = saa7134_finidev,
 };
 
 static int saa7134_init(void)
diff -Nru a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
--- a/drivers/media/video/saa7134/saa7134-i2c.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/media/video/saa7134/saa7134-i2c.c	Mon Dec  9 18:46:35 2002
@@ -338,25 +338,25 @@
 }
 
 static struct i2c_algorithm saa7134_algo = {
-	name:          "saa7134",
-	id:            I2C_ALGO_SAA7134,
-	master_xfer:   saa7134_i2c_xfer,
-	algo_control:  algo_control,
-	functionality: functionality,
+	.name          = "saa7134",
+	.id            = I2C_ALGO_SAA7134,
+	.master_xfer   = saa7134_i2c_xfer,
+	.algo_control  = algo_control,
+	.functionality = functionality,
 };
 
 static struct i2c_adapter saa7134_adap_template = {
-	name:	       "saa7134",
-	id:            I2C_ALGO_SAA7134,
-	algo:          &saa7134_algo,
-	inc_use:       inc_use,
-	dec_use:       dec_use,
-	client_register: attach_inform,
+	.name	       = "saa7134",
+	.id            = I2C_ALGO_SAA7134,
+	.algo          = &saa7134_algo,
+	.inc_use       = inc_use,
+	.dec_use       = dec_use,
+	.client_register = attach_inform,
 };
 
 static struct i2c_client saa7134_client_template = {
-        name: "saa7134 internal",
-        id:   -1,
+        .name = "saa7134 internal",
+        .id   = -1,
 };
 
 /* ----------------------------------------------------------- */
diff -Nru a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
--- a/drivers/media/video/saa7134/saa7134-oss.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/media/video/saa7134/saa7134-oss.c	Mon Dec  9 18:46:37 2002
@@ -486,14 +486,14 @@
 }
 
 struct file_operations saa7134_dsp_fops = {
-	owner:   THIS_MODULE,
-	open:    dsp_open,
-	release: dsp_release,
-	read:    dsp_read,
-	write:   dsp_write,
-	ioctl:   dsp_ioctl,
-	poll:    dsp_poll,
-	llseek:  no_llseek,
+	.owner   = THIS_MODULE,
+	.open    = dsp_open,
+	.release = dsp_release,
+	.read    = dsp_read,
+	.write   = dsp_write,
+	.ioctl   = dsp_ioctl,
+	.poll    = dsp_poll,
+	.llseek  = no_llseek,
 };
 
 /* ------------------------------------------------------------------ */
@@ -670,11 +670,11 @@
 }
 
 struct file_operations saa7134_mixer_fops = {
-	owner:   THIS_MODULE,
-	open:    mixer_open,
-	release: mixer_release,
-	ioctl:   mixer_ioctl,
-	llseek:  no_llseek,
+	.owner   = THIS_MODULE,
+	.open    = mixer_open,
+	.release = mixer_release,
+	.ioctl   = mixer_ioctl,
+	.llseek  = no_llseek,
 };
 
 /* ------------------------------------------------------------------ */
diff -Nru a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
--- a/drivers/media/video/saa7134/saa7134-ts.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/media/video/saa7134/saa7134-ts.c	Mon Dec  9 18:46:34 2002
@@ -151,10 +151,10 @@
 }
 
 static struct videobuf_queue_ops ts_qops = {
-	buf_setup:    buffer_setup,
-	buf_prepare:  buffer_prepare,
-	buf_queue:    buffer_queue,
-	buf_release:  buffer_release,
+	.buf_setup    = buffer_setup,
+	.buf_prepare  = buffer_prepare,
+	.buf_queue    = buffer_queue,
+	.buf_release  = buffer_release,
 };
 
 /* ------------------------------------------------------------------ */
@@ -375,14 +375,14 @@
 
 static struct file_operations ts_fops =
 {
-	owner:	  THIS_MODULE,
-	open:	  ts_open,
-	release:  ts_release,
-	read:	  ts_read,
-	poll:	  ts_poll,
-	mmap:	  ts_mmap,
-	ioctl:	  ts_ioctl,
-	llseek:   no_llseek,
+	.owner	  = THIS_MODULE,
+	.open	  = ts_open,
+	.release  = ts_release,
+	.read	  = ts_read,
+	.poll	  = ts_poll,
+	.mmap	  = ts_mmap,
+	.ioctl	  = ts_ioctl,
+	.llseek   = no_llseek,
 };
 
 
@@ -391,12 +391,12 @@
 
 struct video_device saa7134_ts_template =
 {
-	name:          "saa7134-ts",
-	type:          0 /* FIXME */,
-	type2:         0 /* FIXME */,
-	hardware:      0,
-	fops:          &ts_fops,
-	minor:	       -1,
+	.name          = "saa7134-ts",
+	.type          = 0 /* FIXME */,
+	.type2         = 0 /* FIXME */,
+	.hardware      = 0,
+	.fops          = &ts_fops,
+	.minor	       = -1,
 };
 
 int saa7134_ts_init(struct saa7134_dev *dev)
diff -Nru a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c	Mon Dec  9 18:46:34 2002
@@ -48,65 +48,65 @@
 
 static struct saa7134_tvaudio tvaudio[] = {
 	{
-		name:          "PAL-B/G FM-stereo",
-		std:           V4L2_STD_PAL,
-		mode:          TVAUDIO_FM_BG_STEREO,
-		carr1:         5500,
-		carr2:         5742,
-	},{
-		name:          "PAL-D/K1 FM-stereo",
-		std:           V4L2_STD_PAL,
-		carr1:         6500,
-		carr2:         6258,
-		mode:          TVAUDIO_FM_BG_STEREO,
-	},{
-		name:          "PAL-D/K2 FM-stereo",
-		std:           V4L2_STD_PAL,
-		carr1:         6500,
-		carr2:         6742,
-		mode:          TVAUDIO_FM_BG_STEREO,
-	},{
-		name:          "PAL-D/K3 FM-stereo",
-		std:           V4L2_STD_PAL,
-		carr1:         6500,
-		carr2:         5742,
-		mode:          TVAUDIO_FM_BG_STEREO,
-	},{
-		name:          "PAL-B/G NICAM",
-		std:           V4L2_STD_PAL,
-		carr1:         5500,
-		carr2:         5850,
-		mode:          TVAUDIO_NICAM_FM,
-	},{
-		name:          "PAL-I NICAM",
-		std:           V4L2_STD_PAL,
-		carr1:         6000,
-		carr2:         6552,
-		mode:          TVAUDIO_NICAM_FM,
-	},{
-		name:          "PAL-D/K NICAM",
-		std:           V4L2_STD_PAL,
-		carr1:         6500,
-		carr2:         5850,
-		mode:          TVAUDIO_NICAM_FM,
-	},{
-		name:          "SECAM-L NICAM",
-		std:           V4L2_STD_SECAM,
-		carr1:         6500,
-		carr2:         5850,
-		mode:          TVAUDIO_NICAM_AM,
-	},{
-		name:          "NTSC-M",
-		std:           V4L2_STD_NTSC,
-		carr1:         4500,
-		carr2:         -1,
-		mode:          TVAUDIO_FM_MONO,
-	},{
-		name:          "NTSC-A2 FM-stereo",
-		std:           V4L2_STD_NTSC,
-		carr1:         4500,
-		carr2:         4724,
-		mode:          TVAUDIO_FM_K_STEREO,
+		.name          = "PAL-B/G FM-stereo",
+		.std           = V4L2_STD_PAL,
+		.mode          = TVAUDIO_FM_BG_STEREO,
+		.carr1         = 5500,
+		.carr2         = 5742,
+	},{
+		.name          = "PAL-D/K1 FM-stereo",
+		.std           = V4L2_STD_PAL,
+		.carr1         = 6500,
+		.carr2         = 6258,
+		.mode          = TVAUDIO_FM_BG_STEREO,
+	},{
+		.name          = "PAL-D/K2 FM-stereo",
+		.std           = V4L2_STD_PAL,
+		.carr1         = 6500,
+		.carr2         = 6742,
+		.mode          = TVAUDIO_FM_BG_STEREO,
+	},{
+		.name          = "PAL-D/K3 FM-stereo",
+		.std           = V4L2_STD_PAL,
+		.carr1         = 6500,
+		.carr2         = 5742,
+		.mode          = TVAUDIO_FM_BG_STEREO,
+	},{
+		.name          = "PAL-B/G NICAM",
+		.std           = V4L2_STD_PAL,
+		.carr1         = 5500,
+		.carr2         = 5850,
+		.mode          = TVAUDIO_NICAM_FM,
+	},{
+		.name          = "PAL-I NICAM",
+		.std           = V4L2_STD_PAL,
+		.carr1         = 6000,
+		.carr2         = 6552,
+		.mode          = TVAUDIO_NICAM_FM,
+	},{
+		.name          = "PAL-D/K NICAM",
+		.std           = V4L2_STD_PAL,
+		.carr1         = 6500,
+		.carr2         = 5850,
+		.mode          = TVAUDIO_NICAM_FM,
+	},{
+		.name          = "SECAM-L NICAM",
+		.std           = V4L2_STD_SECAM,
+		.carr1         = 6500,
+		.carr2         = 5850,
+		.mode          = TVAUDIO_NICAM_AM,
+	},{
+		.name          = "NTSC-M",
+		.std           = V4L2_STD_NTSC,
+		.carr1         = 4500,
+		.carr2         = -1,
+		.mode          = TVAUDIO_FM_MONO,
+	},{
+		.name          = "NTSC-A2 FM-stereo",
+		.std           = V4L2_STD_NTSC,
+		.carr1         = 4500,
+		.carr2         = 4724,
+		.mode          = TVAUDIO_FM_K_STEREO,
 	}
 };
 #define TVAUDIO (sizeof(tvaudio)/sizeof(struct saa7134_tvaudio))
diff -Nru a/drivers/media/video/saa7134/saa7134-vbi.c b/drivers/media/video/saa7134/saa7134-vbi.c
--- a/drivers/media/video/saa7134/saa7134-vbi.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/media/video/saa7134/saa7134-vbi.c	Mon Dec  9 18:46:51 2002
@@ -207,10 +207,10 @@
 }
 
 struct videobuf_queue_ops saa7134_vbi_qops = {
-	buf_setup:    buffer_setup,
-	buf_prepare:  buffer_prepare,
-	buf_queue:    buffer_queue,
-	buf_release:  buffer_release,
+	.buf_setup    = buffer_setup,
+	.buf_prepare  = buffer_prepare,
+	.buf_queue    = buffer_queue,
+	.buf_release  = buffer_release,
 };
 
 /* ------------------------------------------------------------------ */
diff -Nru a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
--- a/drivers/media/video/saa7134/saa7134-video.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/media/video/saa7134/saa7134-video.c	Mon Dec  9 18:46:35 2002
@@ -55,80 +55,80 @@
 		
 static struct saa7134_format formats[] = {
 	{
-		name:     "8 bpp gray",
-		fourcc:   V4L2_PIX_FMT_GREY,
-		depth:    8,
-		pm:       0x06,
-	},{
-		name:     "15 bpp RGB, le",
-		fourcc:   V4L2_PIX_FMT_RGB555,
-		depth:    16,
-		pm:       0x13 | 0x80,
-	},{
-		name:     "15 bpp RGB, be",
-		fourcc:   V4L2_PIX_FMT_RGB555X,
-		depth:    16,
-		pm:       0x13 | 0x80,
-		bswap:    1,
-	},{
-		name:     "16 bpp RGB, le",
-		fourcc:   V4L2_PIX_FMT_RGB565,
-		depth:    16,
-		pm:       0x10 | 0x80,
-	},{
-		name:     "16 bpp RGB, be",
-		fourcc:   V4L2_PIX_FMT_RGB565X,
-		depth:    16,
-		pm:       0x10 | 0x80,
-		bswap:    1,
-	},{
-		name:     "24 bpp RGB, le",
-		fourcc:   V4L2_PIX_FMT_BGR24,
-		depth:    24,
-		pm:       0x11,
-	},{
-		name:     "32 bpp RGB, le",
-		fourcc:   V4L2_PIX_FMT_BGR32,
-		depth:    32,
-		pm:       0x12,
-	},{
-		name:     "32 bpp RGB, be",
-		fourcc:   V4L2_PIX_FMT_RGB32,
-		depth:    32,
-		pm:       0x12,
-		bswap:    1,
-		wswap:    1,
-	},{
-		name:     "4:2:2 packed, YUYV",
-		fourcc:   V4L2_PIX_FMT_YUYV,
-		depth:    16,
-		pm:       0x00,
-		bswap:    1,
-		yuv:      1,
-	},{
-		name:     "4:2:2 packed, UYVY",
-		fourcc:   V4L2_PIX_FMT_UYVY,
-		depth:    16,
-		pm:       0x00,
-		yuv:      1,
-	},{
-		name:     "4:2:2 planar, Y-Cb-Cr",
-		fourcc:   V4L2_PIX_FMT_YUV422P,
-		depth:    16,
-		pm:       0x09,
-		yuv:      1,
-		planar:   1,
-		hshift:   1,
-		vshift:   0,
-	},{
-		name:     "4:2:0 planar, Y-Cb-Cr",
-		fourcc:   V4L2_PIX_FMT_YUV420,
-		depth:    12,
-		pm:       0x0a,
-		yuv:      1,
-		planar:   1,
-		hshift:   1,
-		vshift:   1,
+		.name     = "8 bpp gray",
+		.fourcc   = V4L2_PIX_FMT_GREY,
+		.depth    = 8,
+		.pm       = 0x06,
+	},{
+		.name     = "15 bpp RGB, le",
+		.fourcc   = V4L2_PIX_FMT_RGB555,
+		.depth    = 16,
+		.pm       = 0x13 | 0x80,
+	},{
+		.name     = "15 bpp RGB, be",
+		.fourcc   = V4L2_PIX_FMT_RGB555X,
+		.depth    = 16,
+		.pm       = 0x13 | 0x80,
+		.bswap    = 1,
+	},{
+		.name     = "16 bpp RGB, le",
+		.fourcc   = V4L2_PIX_FMT_RGB565,
+		.depth    = 16,
+		.pm       = 0x10 | 0x80,
+	},{
+		.name     = "16 bpp RGB, be",
+		.fourcc   = V4L2_PIX_FMT_RGB565X,
+		.depth    = 16,
+		.pm       = 0x10 | 0x80,
+		.bswap    = 1,
+	},{
+		.name     = "24 bpp RGB, le",
+		.fourcc   = V4L2_PIX_FMT_BGR24,
+		.depth    = 24,
+		.pm       = 0x11,
+	},{
+		.name     = "32 bpp RGB, le",
+		.fourcc   = V4L2_PIX_FMT_BGR32,
+		.depth    = 32,
+		.pm       = 0x12,
+	},{
+		.name     = "32 bpp RGB, be",
+		.fourcc   = V4L2_PIX_FMT_RGB32,
+		.depth    = 32,
+		.pm       = 0x12,
+		.bswap    = 1,
+		.wswap    = 1,
+	},{
+		.name     = "4:2:2 packed, YUYV",
+		.fourcc   = V4L2_PIX_FMT_YUYV,
+		.depth    = 16,
+		.pm       = 0x00,
+		.bswap    = 1,
+		.yuv      = 1,
+	},{
+		.name     = "4:2:2 packed, UYVY",
+		.fourcc   = V4L2_PIX_FMT_UYVY,
+		.depth    = 16,
+		.pm       = 0x00,
+		.yuv      = 1,
+	},{
+		.name     = "4:2:2 planar, Y-Cb-Cr",
+		.fourcc   = V4L2_PIX_FMT_YUV422P,
+		.depth    = 16,
+		.pm       = 0x09,
+		.yuv      = 1,
+		.planar   = 1,
+		.hshift   = 1,
+		.vshift   = 0,
+	},{
+		.name     = "4:2:0 planar, Y-Cb-Cr",
+		.fourcc   = V4L2_PIX_FMT_YUV420,
+		.depth    = 12,
+		.pm       = 0x0a,
+		.yuv      = 1,
+		.planar   = 1,
+		.hshift   = 1,
+		.vshift   = 1,
 	}
 };
 #define FORMATS (sizeof(formats)/sizeof(struct saa7134_format))
@@ -136,77 +136,77 @@
 
 static struct saa7134_tvnorm tvnorms[] = {
 	{
-		name:          "PAL-BGHI",
-		id:            V4L2_STD_PAL,
-		width:         720,
-		height:        576,
-
-		sync_control:  0x18,
-		luma_control:  0x40,
-		chroma_ctrl1:  0x81,
-		chroma_gain:   0x2a,
-		chroma_ctrl2:  0x06,
-
-		h_start:       0,
-		h_stop:        719,
-		video_v_start: 24,
-		video_v_stop:  311,
-		vbi_v_start:   7-3,  /* FIXME */
-		vbi_v_stop:    22-3,
-	},{
-		name:          "NTSC-M",
-		id:            V4L2_STD_NTSC,
-		width:         720,
-		height:        480,
-
-		sync_control:  0x59,
-		luma_control:  0x40,
-		chroma_ctrl1:  0x89,
-		chroma_gain:   0x2a,
-		chroma_ctrl2:  0x0e,
-
-		h_start:       0,
-		h_stop:        719,
-		video_v_start: 22,
-		video_v_stop:  22+240,
-		vbi_v_start:   10, /* FIXME */
-		vbi_v_stop:    21, /* FIXME */
-	},{
-		name:          "SECAM",
-		id:            V4L2_STD_SECAM,
-		width:         720,
-		height:        576,
-
-		sync_control:  0x58,
-		luma_control:  0x1b,
-		chroma_ctrl1:  0xd1,
-		chroma_gain:   0x80,
-		chroma_ctrl2:  0x00,
-
-		h_start:       0,
-		h_stop:        719,
-		video_v_start: 24,
-		video_v_stop:  311,
-		vbi_v_start:   7,
-		vbi_v_stop:    22,
-	},{
-		name:          "AUTO",
-		id:            -1,
-		width:         768,
-		height:        576,
-
-		sync_control:  0x98,
-		luma_control:  0x40,
-		chroma_ctrl1:  0x8b,
-		chroma_gain:   0x00,
-		chroma_ctrl2:  0x00,
-
-		h_start:       0,
-		h_stop:        719,
-		video_v_start: 24,
-		video_v_stop:  311,
-		vbi_v_start:   7,
-		vbi_v_stop:    22,
+		.name          = "PAL-BGHI",
+		.id            = V4L2_STD_PAL,
+		.width         = 720,
+		.height        = 576,
+
+		.sync_control  = 0x18,
+		.luma_control  = 0x40,
+		.chroma_ctrl1  = 0x81,
+		.chroma_gain   = 0x2a,
+		.chroma_ctrl2  = 0x06,
+
+		.h_start       = 0,
+		.h_stop        = 719,
+		.video_v_start = 24,
+		.video_v_stop  = 311,
+		.vbi_v_start   = 7-3,  /* FIXME */
+		.vbi_v_stop    = 22-3,
+	},{
+		.name          = "NTSC-M",
+		.id            = V4L2_STD_NTSC,
+		.width         = 720,
+		.height        = 480,
+
+		.sync_control  = 0x59,
+		.luma_control  = 0x40,
+		.chroma_ctrl1  = 0x89,
+		.chroma_gain   = 0x2a,
+		.chroma_ctrl2  = 0x0e,
+
+		.h_start       = 0,
+		.h_stop        = 719,
+		.video_v_start = 22,
+		.video_v_stop  = 22+240,
+		.vbi_v_start   = 10, /* FIXME */
+		.vbi_v_stop    = 21, /* FIXME */
+	},{
+		.name          = "SECAM",
+		.id            = V4L2_STD_SECAM,
+		.width         = 720,
+		.height        = 576,
+
+		.sync_control  = 0x58,
+		.luma_control  = 0x1b,
+		.chroma_ctrl1  = 0xd1,
+		.chroma_gain   = 0x80,
+		.chroma_ctrl2  = 0x00,
+
+		.h_start       = 0,
+		.h_stop        = 719,
+		.video_v_start = 24,
+		.video_v_stop  = 311,
+		.vbi_v_start   = 7,
+		.vbi_v_stop    = 22,
+	},{
+		.name          = "AUTO",
+		.id            = -1,
+		.width         = 768,
+		.height        = 576,
+
+		.sync_control  = 0x98,
+		.luma_control  = 0x40,
+		.chroma_ctrl1  = 0x8b,
+		.chroma_gain   = 0x00,
+		.chroma_ctrl2  = 0x00,
+
+		.h_start       = 0,
+		.h_stop        = 719,
+		.video_v_start = 24,
+		.video_v_stop  = 311,
+		.vbi_v_start   = 7,
+		.vbi_v_stop    = 22,
 	}
 };
 #define TVNORMS (sizeof(tvnorms)/sizeof(struct saa7134_tvnorm))
@@ -218,87 +218,87 @@
 #define V4L2_CID_PRIVATE_LASTP1      (V4L2_CID_PRIVATE_BASE + 3)
 
 static const struct v4l2_queryctrl no_ctrl = {
-	name:  "42",
-	flags: V4L2_CTRL_FLAG_DISABLED,
+	.name  = "42",
+	.flags = V4L2_CTRL_FLAG_DISABLED,
 };
 static const struct v4l2_queryctrl video_ctrls[] = {
 	/* --- video --- */
 	{
-		id:            V4L2_CID_BRIGHTNESS,
-		name:          "Brightness",
-		minimum:       0,
-		maximum:       255,
-		step:          1,
-		default_value: 128,
-		type:          V4L2_CTRL_TYPE_INTEGER,
-	},{
-		id:            V4L2_CID_CONTRAST,
-		name:          "Contrast",
-		minimum:       0,
-		maximum:       127,
-		step:          1,
-		default_value: 68,
-		type:          V4L2_CTRL_TYPE_INTEGER,
-	},{
-		id:            V4L2_CID_SATURATION,
-		name:          "Saturation",
-		minimum:       0,
-		maximum:       127,
-		step:          1,
-		default_value: 64,
-		type:          V4L2_CTRL_TYPE_INTEGER,
-	},{
-		id:            V4L2_CID_HUE,
-		name:          "Hue",
-		minimum:       -128,
-		maximum:       127,
-		step:          1,
-		default_value: 0,
-		type:          V4L2_CTRL_TYPE_INTEGER,
-	},{
-		id:            V4L2_CID_VFLIP,
-		name:          "vertical flip",
-		minimum:       0,
-		maximum:       1,
-		type:          V4L2_CTRL_TYPE_BOOLEAN,
+		.id            = V4L2_CID_BRIGHTNESS,
+		.name          = "Brightness",
+		.minimum       = 0,
+		.maximum       = 255,
+		.step          = 1,
+		.default_value = 128,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+	},{
+		.id            = V4L2_CID_CONTRAST,
+		.name          = "Contrast",
+		.minimum       = 0,
+		.maximum       = 127,
+		.step          = 1,
+		.default_value = 68,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+	},{
+		.id            = V4L2_CID_SATURATION,
+		.name          = "Saturation",
+		.minimum       = 0,
+		.maximum       = 127,
+		.step          = 1,
+		.default_value = 64,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+	},{
+		.id            = V4L2_CID_HUE,
+		.name          = "Hue",
+		.minimum       = -128,
+		.maximum       = 127,
+		.step          = 1,
+		.default_value = 0,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+	},{
+		.id            = V4L2_CID_VFLIP,
+		.name          = "vertical flip",
+		.minimum       = 0,
+		.maximum       = 1,
+		.type          = V4L2_CTRL_TYPE_BOOLEAN,
 	},
 	/* --- audio --- */
 	{
-		id:            V4L2_CID_AUDIO_MUTE,
-		name:          "Mute",
-		minimum:       0,
-		maximum:       1,
-		type:          V4L2_CTRL_TYPE_BOOLEAN,
-	},{
-		id:            V4L2_CID_AUDIO_VOLUME,
-		name:          "Volume",
-		minimum:       -15,
-		maximum:       15,
-		step:          1,
-		default_value: 0,
-		type:          V4L2_CTRL_TYPE_INTEGER,
+		.id            = V4L2_CID_AUDIO_MUTE,
+		.name          = "Mute",
+		.minimum       = 0,
+		.maximum       = 1,
+		.type          = V4L2_CTRL_TYPE_BOOLEAN,
+	},{
+		.id            = V4L2_CID_AUDIO_VOLUME,
+		.name          = "Volume",
+		.minimum       = -15,
+		.maximum       = 15,
+		.step          = 1,
+		.default_value = 0,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
 	},
 	/* --- private --- */
 	{
-		id:            V4L2_CID_PRIVATE_INVERT,
-		name:          "Invert",
-		minimum:       0,
-		maximum:       1,
-		type:          V4L2_CTRL_TYPE_BOOLEAN,
-	},{
-		id:            V4L2_CID_PRIVATE_Y_ODD,
-		name:          "y offset odd field",
-		minimum:       0,
-		maximum:       128,
-		default_value: 0,
-		type:          V4L2_CTRL_TYPE_INTEGER,
-	},{
-		id:            V4L2_CID_PRIVATE_Y_EVEN,
-		name:          "y offset even field",
-		minimum:       0,
-		maximum:       128,
-		default_value: 0,
-		type:          V4L2_CTRL_TYPE_INTEGER,
+		.id            = V4L2_CID_PRIVATE_INVERT,
+		.name          = "Invert",
+		.minimum       = 0,
+		.maximum       = 1,
+		.type          = V4L2_CTRL_TYPE_BOOLEAN,
+	},{
+		.id            = V4L2_CID_PRIVATE_Y_ODD,
+		.name          = "y offset odd field",
+		.minimum       = 0,
+		.maximum       = 128,
+		.default_value = 0,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+	},{
+		.id            = V4L2_CID_PRIVATE_Y_EVEN,
+		.name          = "y offset even field",
+		.minimum       = 0,
+		.maximum       = 128,
+		.default_value = 0,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
 	}
 };
 const int CTRLS = (sizeof(video_ctrls)/sizeof(struct v4l2_queryctrl));
@@ -912,10 +912,10 @@
 }
 
 static struct videobuf_queue_ops video_qops = {
-	buf_setup:    buffer_setup,
-	buf_prepare:  buffer_prepare,
-	buf_queue:    buffer_queue,
-	buf_release:  buffer_release,
+	.buf_setup    = buffer_setup,
+	.buf_prepare  = buffer_prepare,
+	.buf_queue    = buffer_queue,
+	.buf_release  = buffer_release,
 };
 
 /* ------------------------------------------------------------------ */
@@ -1873,23 +1873,23 @@
 
 static struct file_operations video_fops =
 {
-	owner:	  THIS_MODULE,
-	open:	  video_open,
-	release:  video_release,
-	read:	  video_read,
-	poll:     video_poll,
-	mmap:	  video_mmap,
-	ioctl:	  video_ioctl,
-	llseek:   no_llseek,
+	.owner	  = THIS_MODULE,
+	.open	  = video_open,
+	.release  = video_release,
+	.read	  = video_read,
+	.poll     = video_poll,
+	.mmap	  = video_mmap,
+	.ioctl	  = video_ioctl,
+	.llseek   = no_llseek,
 };
 
 static struct file_operations radio_fops =
 {
-	owner:	  THIS_MODULE,
-	open:	  video_open,
-	release:  video_release,
-	ioctl:	  radio_ioctl,
-	llseek:   no_llseek,
+	.owner	  = THIS_MODULE,
+	.open	  = video_open,
+	.release  = video_release,
+	.ioctl	  = radio_ioctl,
+	.llseek   = no_llseek,
 };
 
 /* ----------------------------------------------------------- */
@@ -1897,30 +1897,30 @@
 
 struct video_device saa7134_video_template =
 {
-	name:          "saa7134-video",
+	.name          = "saa7134-video",
 	type:          VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
 	               VID_TYPE_CLIPPING|VID_TYPE_SCALES,
-	hardware:      0,
-	fops:          &video_fops,
-	minor:         -1,
+	.hardware      = 0,
+	.fops          = &video_fops,
+	.minor         = -1,
 };
 
 struct video_device saa7134_vbi_template =
 {
-	name:          "saa7134-vbi",
-	type:          VID_TYPE_TUNER|VID_TYPE_TELETEXT,
-	hardware:      0,
-	fops:          &video_fops,
-	minor:         -1,
+	.name          = "saa7134-vbi",
+	.type          = VID_TYPE_TUNER|VID_TYPE_TELETEXT,
+	.hardware      = 0,
+	.fops          = &video_fops,
+	.minor         = -1,
 };
 
 struct video_device saa7134_radio_template =
 {
-	name:          "saa7134-radio",
-	type:          VID_TYPE_TUNER,
-	hardware:      0,
-	fops:          &radio_fops,
-	minor:         -1,
+	.name          = "saa7134-radio",
+	.type          = VID_TYPE_TUNER,
+	.hardware      = 0,
+	.fops          = &radio_fops,
+	.minor         = -1,
 };
 
 int saa7134_video_init(struct saa7134_dev *dev)
diff -Nru a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
--- a/drivers/media/video/saa7134/saa7134.h	Mon Dec  9 18:46:50 2002
+++ b/drivers/media/video/saa7134/saa7134.h	Mon Dec  9 18:46:50 2002
@@ -24,7 +24,7 @@
 #include <linux/kdev_t.h>
 #include "video-buf.h"
 
-#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,1)
+#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,2)
 
 #ifndef TRUE
 # define TRUE (1==1)
diff -Nru a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c
--- a/drivers/media/video/stradis.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/media/video/stradis.c	Mon Dec  9 18:46:51 2002
@@ -1970,16 +1970,16 @@
 /* template for video_device-structure */
 static struct video_device saa_template =
 {
-	owner:		THIS_MODULE,
-	name:		"SAA7146A",
-	type:		VID_TYPE_CAPTURE | VID_TYPE_OVERLAY,
-	hardware:	VID_HARDWARE_SAA7146,
-	open:		saa_open,
-	close:		saa_close,
-	read:		saa_read,
-	write:		saa_write,
-	ioctl:		saa_ioctl,
-	mmap:		saa_mmap,
+	.owner		= THIS_MODULE,
+	.name		= "SAA7146A",
+	.type		= VID_TYPE_CAPTURE | VID_TYPE_OVERLAY,
+	.hardware	= VID_HARDWARE_SAA7146,
+	.open		= saa_open,
+	.close		= saa_close,
+	.read		= saa_read,
+	.write		= saa_write,
+	.ioctl		= saa_ioctl,
+	.mmap		= saa_mmap,
 };
 
 static int configure_saa7146(struct pci_dev *dev, int num)
diff -Nru a/drivers/media/video/tuner.c b/drivers/media/video/tuner.c
--- a/drivers/media/video/tuner.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/media/video/tuner.c	Mon Dec  9 18:46:50 2002
@@ -975,18 +975,18 @@
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver driver = {
-        name:           "i2c TV tuner driver",
-        id:             I2C_DRIVERID_TUNER,
-        flags:          I2C_DF_NOTIFY,
-        attach_adapter: tuner_probe,
-        detach_client:  tuner_detach,
-        command:        tuner_command,
+	.name		= "i2cTVtunerdriver",
+	.id		= I2C_DRIVERID_TUNER,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= tuner_probe,
+	.detach_client	= tuner_detach,
+	.command	= tuner_command,
 };
-static struct i2c_client client_template =
+static struct i2c_client client_template = 
 {
-        name:   "(tuner unset)",
-	flags:  I2C_CLIENT_ALLOW_USE,
-        driver: &driver,
+	.name	= "(tunerunset)",
+	.flags	= I2C_CLIENT_ALLOW_USE,
+	.driver	= &driver,
 };
 
 static int tuner_init_module(void)
diff -Nru a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
--- a/drivers/media/video/tvaudio.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/media/video/tvaudio.c	Mon Dec  9 18:46:35 2002
@@ -1156,167 +1156,167 @@
 
 static struct CHIPDESC chiplist[] = {
 	{
-		name:       "tda9840",
-		id:         I2C_DRIVERID_TDA9840,
-		insmodopt:  &tda9840,
-		addr_lo:    I2C_TDA9840 >> 1,
-		addr_hi:    I2C_TDA9840 >> 1,
-		registers:  5,
-
-		getmode:    tda9840_getmode,
-		setmode:    tda9840_setmode,
-		checkmode:  generic_checkmode,
+		.name       = "tda9840",
+		.id         = I2C_DRIVERID_TDA9840,
+		.insmodopt  = &tda9840,
+		.addr_lo    = I2C_TDA9840 >> 1,
+		.addr_hi    = I2C_TDA9840 >> 1,
+		.registers  = 5,
+
+		.getmode    = tda9840_getmode,
+		.setmode    = tda9840_setmode,
+		.checkmode  = generic_checkmode,
 
-	        init:       { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN
+	        .init       = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN
 				/* ,TDA9840_SW, TDA9840_MONO */} }
 	},
 	{
-		name:       "tda9873h",
-		id:         I2C_DRIVERID_TDA9873,
-		checkit:    tda9873_checkit,
-		insmodopt:  &tda9873,
-		addr_lo:    I2C_TDA985x_L >> 1,
-		addr_hi:    I2C_TDA985x_H >> 1,
-		registers:  3,
-		flags:      CHIP_HAS_INPUTSEL,
-
-		getmode:    tda9873_getmode,
-		setmode:    tda9873_setmode,
-		checkmode:  generic_checkmode,
-
-		init:       { 4, { TDA9873_SW, 0xa4, 0x06, 0x03 } },
-		inputreg:   TDA9873_SW,
-		inputmute:  TDA9873_MUTE | TDA9873_AUTOMUTE,
-		inputmap:   {0xa0, 0xa2, 0xa0, 0xa0, 0xc0},
-		inputmask:  TDA9873_INP_MASK | TDA9873_MUTE | TDA9873_AUTOMUTE
+		.name       = "tda9873h",
+		.id         = I2C_DRIVERID_TDA9873,
+		.checkit    = tda9873_checkit,
+		.insmodopt  = &tda9873,
+		.addr_lo    = I2C_TDA985x_L >> 1,
+		.addr_hi    = I2C_TDA985x_H >> 1,
+		.registers  = 3,
+		.flags      = CHIP_HAS_INPUTSEL,
+
+		.getmode    = tda9873_getmode,
+		.setmode    = tda9873_setmode,
+		.checkmode  = generic_checkmode,
+
+		.init       = { 4, { TDA9873_SW, 0xa4, 0x06, 0x03 } },
+		.inputreg   = TDA9873_SW,
+		.inputmute  = TDA9873_MUTE | TDA9873_AUTOMUTE,
+		.inputmap   = {0xa0, 0xa2, 0xa0, 0xa0, 0xc0},
+		.inputmask  = TDA9873_INP_MASK | TDA9873_MUTE | TDA9873_AUTOMUTE
 		
 	},
 	{
-		name:       "tda9874h/a",
-		id:         I2C_DRIVERID_TDA9874,
-		checkit:    tda9874a_checkit,
-		initialize: tda9874a_initialize,
-		insmodopt:  &tda9874a,
-		addr_lo:    I2C_TDA9874 >> 1,
-		addr_hi:    I2C_TDA9874 >> 1,
-
-		getmode:    tda9874a_getmode,
-		setmode:    tda9874a_setmode,
-		checkmode:  generic_checkmode,
+		.name       = "tda9874h/a",
+		.id         = I2C_DRIVERID_TDA9874,
+		.checkit    = tda9874a_checkit,
+		.initialize = tda9874a_initialize,
+		.insmodopt  = &tda9874a,
+		.addr_lo    = I2C_TDA9874 >> 1,
+		.addr_hi    = I2C_TDA9874 >> 1,
+
+		.getmode    = tda9874a_getmode,
+		.setmode    = tda9874a_setmode,
+		.checkmode  = generic_checkmode,
 	},
 	{
-		name:       "tda9850",
-		id:         I2C_DRIVERID_TDA9850,
-		insmodopt:  &tda9850,
-		addr_lo:    I2C_TDA985x_L >> 1,
-		addr_hi:    I2C_TDA985x_H >> 1,
-		registers:  11,
+		.name       = "tda9850",
+		.id         = I2C_DRIVERID_TDA9850,
+		.insmodopt  = &tda9850,
+		.addr_lo    = I2C_TDA985x_L >> 1,
+		.addr_hi    = I2C_TDA985x_H >> 1,
+		.registers  = 11,
 
-		getmode:    tda985x_getmode,
-		setmode:    tda985x_setmode,
+		.getmode    = tda985x_getmode,
+		.setmode    = tda985x_setmode,
 
-		init:       { 8, { TDA9850_C4, 0x08, 0x08, TDA985x_STEREO, 0x07, 0x10, 0x10, 0x03 } }
+		.init       = { 8, { TDA9850_C4, 0x08, 0x08, TDA985x_STEREO, 0x07, 0x10, 0x10, 0x03 } }
 	},
 	{
-		name:       "tda9855",
-		id:         I2C_DRIVERID_TDA9855,
-		insmodopt:  &tda9855,
-		addr_lo:    I2C_TDA985x_L >> 1,
-		addr_hi:    I2C_TDA985x_H >> 1,
-		registers:  11,
-		flags:      CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE,
-
-		leftreg:    TDA9855_VL,
-		rightreg:   TDA9855_VR,
-		bassreg:    TDA9855_BA,
-		treblereg:  TDA9855_TR,
-		volfunc:    tda9855_volume,
-		bassfunc:   tda9855_bass,
-		treblefunc: tda9855_treble,
+		.name       = "tda9855",
+		.id         = I2C_DRIVERID_TDA9855,
+		.insmodopt  = &tda9855,
+		.addr_lo    = I2C_TDA985x_L >> 1,
+		.addr_hi    = I2C_TDA985x_H >> 1,
+		.registers  = 11,
+		.flags      = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE,
+
+		.leftreg    = TDA9855_VL,
+		.rightreg   = TDA9855_VR,
+		.bassreg    = TDA9855_BA,
+		.treblereg  = TDA9855_TR,
+		.volfunc    = tda9855_volume,
+		.bassfunc   = tda9855_bass,
+		.treblefunc = tda9855_treble,
 
-		getmode:    tda985x_getmode,
-		setmode:    tda985x_setmode,
+		.getmode    = tda985x_getmode,
+		.setmode    = tda985x_setmode,
 
-		init:       { 12, { 0, 0x6f, 0x6f, 0x0e, 0x07<<1, 0x8<<2,
+		.init       = { 12, { 0, 0x6f, 0x6f, 0x0e, 0x07<<1, 0x8<<2,
 				    TDA9855_MUTE | TDA9855_AVL | TDA9855_LOUD | TDA9855_INT,
 				    TDA985x_STEREO | TDA9855_LINEAR | TDA9855_TZCM | TDA9855_VZCM,
 				    0x07, 0x10, 0x10, 0x03 }}
 	},
 	{
-		name:       "tea6300",
-		id:         I2C_DRIVERID_TEA6300,
-		insmodopt:  &tea6300,
-		addr_lo:    I2C_TEA6300 >> 1,
-		addr_hi:    I2C_TEA6300 >> 1,
-		registers:  6,
-		flags:      CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL,
-
-		leftreg:    TEA6300_VR,
-		rightreg:   TEA6300_VL,
-		bassreg:    TEA6300_BA,
-		treblereg:  TEA6300_TR,
-		volfunc:    tea6300_shift10,
-		bassfunc:   tea6300_shift12,
-		treblefunc: tea6300_shift12,
-
-		inputreg:   TEA6300_S,
-		inputmap:   { TEA6300_S_SA, TEA6300_S_SB, TEA6300_S_SC },
-		inputmute:  TEA6300_S_GMU,
+		.name       = "tea6300",
+		.id         = I2C_DRIVERID_TEA6300,
+		.insmodopt  = &tea6300,
+		.addr_lo    = I2C_TEA6300 >> 1,
+		.addr_hi    = I2C_TEA6300 >> 1,
+		.registers  = 6,
+		.flags      = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL,
+
+		.leftreg    = TEA6300_VR,
+		.rightreg   = TEA6300_VL,
+		.bassreg    = TEA6300_BA,
+		.treblereg  = TEA6300_TR,
+		.volfunc    = tea6300_shift10,
+		.bassfunc   = tea6300_shift12,
+		.treblefunc = tea6300_shift12,
+
+		.inputreg   = TEA6300_S,
+		.inputmap   = { TEA6300_S_SA, TEA6300_S_SB, TEA6300_S_SC },
+		.inputmute  = TEA6300_S_GMU,
 	},
 	{
-		name:       "tea6420",
-		id:         I2C_DRIVERID_TEA6420,
-		insmodopt:  &tea6420,
-		addr_lo:    I2C_TEA6420 >> 1,
-		addr_hi:    I2C_TEA6420 >> 1,
-		registers:  1,
-		flags:      CHIP_HAS_INPUTSEL,
-
-		inputreg:   -1,
-		inputmap:   { TEA6420_S_SA, TEA6420_S_SB, TEA6420_S_SC },
-		inputmute:  TEA6300_S_GMU,
+		.name       = "tea6420",
+		.id         = I2C_DRIVERID_TEA6420,
+		.insmodopt  = &tea6420,
+		.addr_lo    = I2C_TEA6420 >> 1,
+		.addr_hi    = I2C_TEA6420 >> 1,
+		.registers  = 1,
+		.flags      = CHIP_HAS_INPUTSEL,
+
+		.inputreg   = -1,
+		.inputmap   = { TEA6420_S_SA, TEA6420_S_SB, TEA6420_S_SC },
+		.inputmute  = TEA6300_S_GMU,
 	},
 	{
-		name:       "tda8425",
-		id:         I2C_DRIVERID_TDA8425,
-		insmodopt:  &tda8425,
-		addr_lo:    I2C_TDA8425 >> 1,
-		addr_hi:    I2C_TDA8425 >> 1,
-		registers:  9,
-		flags:      CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL,
-
-		leftreg:    TDA8425_VR,
-		rightreg:   TDA8425_VL,
-		bassreg:    TDA8425_BA,
-		treblereg:  TDA8425_TR,
-		volfunc:    tda8425_shift10,
-		bassfunc:   tda8425_shift12,
-		treblefunc: tda8425_shift12,
-
-		inputreg:   TDA8425_S1,
-		inputmap:   { TDA8425_S1_CH1, TDA8425_S1_CH1, TDA8425_S1_CH1 },
-		inputmute:  TDA8425_S1_OFF,
+		.name       = "tda8425",
+		.id         = I2C_DRIVERID_TDA8425,
+		.insmodopt  = &tda8425,
+		.addr_lo    = I2C_TDA8425 >> 1,
+		.addr_hi    = I2C_TDA8425 >> 1,
+		.registers  = 9,
+		.flags      = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL,
+
+		.leftreg    = TDA8425_VR,
+		.rightreg   = TDA8425_VL,
+		.bassreg    = TDA8425_BA,
+		.treblereg  = TDA8425_TR,
+		.volfunc    = tda8425_shift10,
+		.bassfunc   = tda8425_shift12,
+		.treblefunc = tda8425_shift12,
+
+		.inputreg   = TDA8425_S1,
+		.inputmap   = { TDA8425_S1_CH1, TDA8425_S1_CH1, TDA8425_S1_CH1 },
+		.inputmute  = TDA8425_S1_OFF,
 
-		setmode:    tda8425_setmode,
+		.setmode    = tda8425_setmode,
 	},
 	{
-		name:       "pic16c54 (PV951)",
-		id:         I2C_DRIVERID_PIC16C54_PV951,
-		insmodopt:  &pic16c54,
-		addr_lo:    I2C_PIC16C54 >> 1,
-		addr_hi:    I2C_PIC16C54>> 1,
-		registers:  2,
-		flags:      CHIP_HAS_INPUTSEL,
+		.name       = "pic16c54 (PV951)",
+		.id         = I2C_DRIVERID_PIC16C54_PV951,
+		.insmodopt  = &pic16c54,
+		.addr_lo    = I2C_PIC16C54 >> 1,
+		.addr_hi    = I2C_PIC16C54>> 1,
+		.registers  = 2,
+		.flags      = CHIP_HAS_INPUTSEL,
 
-		inputreg:   PIC16C54_REG_MISC,
-		inputmap:   {PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_TUNER,
+		.inputreg   = PIC16C54_REG_MISC,
+		.inputmap   = {PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_TUNER,
 			     PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_LINE,
 			     PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_LINE,
 			     PIC16C54_MISC_SND_MUTE,PIC16C54_MISC_SND_MUTE,
 			     PIC16C54_MISC_SND_NOTMUTE},
-		inputmute:  PIC16C54_MISC_SND_MUTE,
+		.inputmute  = PIC16C54_MISC_SND_MUTE,
 	},
-	{ name: NULL } /* EOF */
+	{ .name = NULL } /* EOF */
 };
 
 
@@ -1544,19 +1544,19 @@
 
 
 static struct i2c_driver driver = {
-        name:            "generic i2c audio driver",
-        id:              I2C_DRIVERID_TVAUDIO,
-        flags:           I2C_DF_NOTIFY,
-        attach_adapter:  chip_probe,
-        detach_client:   chip_detach,
-        command:         chip_command,
+	.name		= "generic i2c audio driver",
+	.id		= I2C_DRIVERID_TVAUDIO,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= chip_probe,
+	.detach_client	= chip_detach,
+	.command	= chip_command,
 };
 
 static struct i2c_client client_template =
 {
-        name:   "(unset)",
-	flags:  I2C_CLIENT_ALLOW_USE,
-        driver: &driver,
+	.name		= "(unset)",
+	.flags		= I2C_CLIENT_ALLOW_USE,
+	.driver		= &driver,
 };
 
 static int audiochip_init_module(void)
diff -Nru a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c
--- a/drivers/media/video/tvmixer.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/media/video/tvmixer.c	Mon Dec  9 18:46:51 2002
@@ -217,19 +217,19 @@
 
 
 static struct i2c_driver driver = {
-	name:            "tv card mixer driver",
-        id:              I2C_DRIVERID_TVMIXER,
-	flags:           I2C_DF_DUMMY,
-        attach_adapter:  tvmixer_adapters,
-        detach_client:   tvmixer_clients,
+	.name		= "tv card mixer driver",
+	.id		= I2C_DRIVERID_TVMIXER,
+	.flags		= I2C_DF_DUMMY,
+	.attach_adapter	= tvmixer_adapters,
+	.detach_client	= tvmixer_clients,
 };
 
 static struct file_operations tvmixer_fops = {
-	owner:		THIS_MODULE,
-	llseek:         no_llseek,
-	ioctl:          tvmixer_ioctl,
-	open:           tvmixer_open,
-	release:        tvmixer_release,
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.ioctl		= tvmixer_ioctl,
+	.open		= tvmixer_open,
+	.release	= tvmixer_release,
 };
 
 /* ----------------------------------------------------------------------- */
diff -Nru a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c
--- a/drivers/media/video/video-buf.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/media/video/video-buf.c	Mon Dec  9 18:46:37 2002
@@ -926,9 +926,9 @@
 
 static struct vm_operations_struct videobuf_vm_ops =
 {
-	open:     videobuf_vm_open,
-	close:    videobuf_vm_close,
-	nopage:   videobuf_vm_nopage,
+	.open     = videobuf_vm_open,
+	.close    = videobuf_vm_close,
+	.nopage   = videobuf_vm_nopage,
 };
 
 int videobuf_mmap_setup(struct file *file, struct videobuf_queue *q,
diff -Nru a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
--- a/drivers/media/video/videodev.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/media/video/videodev.c	Mon Dec  9 18:46:34 2002
@@ -288,8 +288,6 @@
 	video_dev_proc_entry->owner = THIS_MODULE;
 }
 
-#ifdef MODULE
-#ifdef CONFIG_VIDEO_PROC_FS
 static void videodev_proc_destroy(void)
 {
 	if (video_dev_proc_entry != NULL)
@@ -298,8 +296,6 @@
 	if (video_proc_entry != NULL)
 		remove_proc_entry("video", &proc_root);
 }
-#endif
-#endif
 
 static void videodev_proc_create_dev (struct video_device *vfd, char *name)
 {
@@ -472,9 +468,9 @@
 
 static struct file_operations video_fops=
 {
-	owner:		THIS_MODULE,
-	llseek:		no_llseek,
-	open:		video_open,
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.open		= video_open,
 };
 
 /*
diff -Nru a/drivers/media/video/vino.c b/drivers/media/video/vino.c
--- a/drivers/media/video/vino.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/media/video/vino.c	Mon Dec  9 18:46:35 2002
@@ -222,14 +222,14 @@
 }
 
 static struct video_device vino_dev = {
-	owner:		THIS_MODULE,
-	name:		"Vino IndyCam/TV",
-	type:		VID_TYPE_CAPTURE,
-	hardware:	VID_HARDWARE_VINO,
-	open:		vino_open,
-	close:		vino_close,
-	ioctl:		vino_ioctl,
-	mmap:		vino_mmap,
+	.owner		= THIS_MODULE,
+	.name		= "Vino IndyCam/TV",
+	.type		= VID_TYPE_CAPTURE,
+	.hardware	= VID_HARDWARE_VINO,
+	.open		= vino_open,
+	.close		= vino_close,
+	.ioctl		= vino_ioctl,
+	.mmap		= vino_mmap,
 };
 
 int __init init_vino(struct video_device *dev)
diff -Nru a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
--- a/drivers/media/video/w9966.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/media/video/w9966.c	Mon Dec  9 18:46:35 2002
@@ -179,19 +179,19 @@
 			  size_t count, loff_t *ppos);
 
 static struct file_operations w9966_fops = {
-	owner:		THIS_MODULE,
-	open:           video_exclusive_open,
-	release:        video_exclusive_release,
-	ioctl:          w9966_v4l_ioctl,
-	read:           w9966_v4l_read,
-	llseek:         no_llseek,
+	.owner		= THIS_MODULE,
+	.open           = video_exclusive_open,
+	.release        = video_exclusive_release,
+	.ioctl          = w9966_v4l_ioctl,
+	.read           = w9966_v4l_read,
+	.llseek         = no_llseek,
 };
 static struct video_device w9966_template = {
-	owner:		THIS_MODULE,
-	name:           W9966_DRIVERNAME,
-	type:           VID_TYPE_CAPTURE | VID_TYPE_SCALES,
-	hardware:       VID_HARDWARE_W9966,
-	fops:           &w9966_fops,
+	.owner		= THIS_MODULE,
+	.name           = W9966_DRIVERNAME,
+	.type           = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
+	.hardware       = VID_HARDWARE_W9966,
+	.fops           = &w9966_fops,
 };
 
 /*
@@ -710,14 +710,13 @@
 	case VIDIOCGCAP:
 	{
 		static struct video_capability vcap = {
-			name:      W9966_DRIVERNAME,
-			type:      VID_TYPE_CAPTURE | VID_TYPE_SCALES,
-			channels:  1,
-			audios:    0,
-			maxwidth:  W9966_WND_MAX_W,
-			maxheight: W9966_WND_MAX_H,
-			minwidth:  2,
-			minheight: 1,
+			.name      = W9966_DRIVERNAME,
+			.type      = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
+			.channels  = 1,
+			.maxwidth  = W9966_WND_MAX_W,
+			.maxheight = W9966_WND_MAX_H,
+			.minwidth  = 2,
+			.minheight = 1,
 		};
 		struct video_capability *cap = arg;
 		*cap = vcap;
diff -Nru a/drivers/media/video/zr36067.c b/drivers/media/video/zr36067.c
--- a/drivers/media/video/zr36067.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/media/video/zr36067.c	Mon Dec  9 18:46:51 2002
@@ -4396,18 +4396,18 @@
 }
 
 static struct video_device zoran_template = {
-	owner:		THIS_MODULE,
-	name:		ZORAN_NAME,
-	type:		VID_TYPE_CAPTURE | VID_TYPE_OVERLAY | VID_TYPE_CLIPPING |
+	.owner		= THIS_MODULE,
+	.name		= ZORAN_NAME,
+	.type		= VID_TYPE_CAPTURE | VID_TYPE_OVERLAY | VID_TYPE_CLIPPING |
 	    VID_TYPE_FRAMERAM | VID_TYPE_SCALES | VID_TYPE_SUBCAPTURE,
-	hardware:	ZORAN_HARDWARE,
-	open:		zoran_open,
-	close:		zoran_close,
-	read:		zoran_read,
-	write:		zoran_write,
-	ioctl:		zoran_ioctl,
-	mmap:		zoran_mmap,
-	initialize:	zoran_init_done,
+	.hardware	= ZORAN_HARDWARE,
+	.open		= zoran_open,
+	.close		= zoran_close,
+	.read		= zoran_read,
+	.write		= zoran_write,
+	.ioctl		= zoran_ioctl,
+	.mmap		= zoran_mmap,
+	.initialize	= zoran_init_done,
 };
 
 /*
diff -Nru a/drivers/media/video/zr36120.c b/drivers/media/video/zr36120.c
--- a/drivers/media/video/zr36120.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/media/video/zr36120.c	Mon Dec  9 18:46:37 2002
@@ -1490,18 +1490,18 @@
 
 static struct video_device zr36120_template=
 {
-	owner:		THIS_MODULE,
-	name:		"UNSET",
-	type:		VID_TYPE_TUNER|VID_TYPE_CAPTURE|VID_TYPE_OVERLAY,
-	hardware:	VID_HARDWARE_ZR36120,
-	open:		zoran_open,
-	close:		zoran_close,
-	read:		zoran_read,
-	write:		zoran_write,
-	poll:		zoran_poll,
-	ioctl:		zoran_ioctl,
-	mmap:		zoran_mmap,
-	minor:		-1,
+	.owner		= THIS_MODULE,
+	.name		= "UNSET",
+	.type		= VID_TYPE_TUNER|VID_TYPE_CAPTURE|VID_TYPE_OVERLAY,
+	.hardware	= VID_HARDWARE_ZR36120,
+	.open		= zoran_open,
+	.close		= zoran_close,
+	.read		= zoran_read,
+	.write		= zoran_write,
+	.poll		= zoran_poll,
+	.ioctl		= zoran_ioctl,
+	.mmap		= zoran_mmap,
+	.minor		= -1,
 };
 
 static
@@ -1826,17 +1826,17 @@
 
 static struct video_device vbi_template=
 {
-	owner:		THIS_MODULE,
-	name:		"UNSET",
-	type:		VID_TYPE_CAPTURE|VID_TYPE_TELETEXT,
-	hardware:	VID_HARDWARE_ZR36120,
-	open:		vbi_open,
-	close:		vbi_close,
-	read:		vbi_read,
-	write:		zoran_write,
-	poll:		vbi_poll,
-	ioctl:		vbi_ioctl,
-	minor:		-1,
+	.owner		= THIS_MODULE,
+	.name		= "UNSET",
+	.type		= VID_TYPE_CAPTURE|VID_TYPE_TELETEXT,
+	.hardware	= VID_HARDWARE_ZR36120,
+	.open		= vbi_open,
+	.close		= vbi_close,
+	.read		= vbi_read,
+	.write		= zoran_write,
+	.poll		= vbi_poll,
+	.ioctl		= vbi_ioctl,
+	.minor		= -1,
 };
 
 /*
diff -Nru a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
--- a/drivers/message/i2o/i2o_config.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/message/i2o/i2o_config.c	Mon Dec  9 18:46:51 2002
@@ -930,7 +930,7 @@
 		printk(KERN_ERR "i2o_config: no memory for page buffer.\n");
 		return -ENOBUFS;
 	}
-	if(misc_register(&i2o_miscdev)==-1)
+	if(misc_register(&i2o_miscdev) < 0)
 	{
 		printk(KERN_ERR "i2o_config: can't register device.\n");
 		kfree(page_buf);
diff -Nru a/drivers/misc/Makefile b/drivers/misc/Makefile
--- a/drivers/misc/Makefile	Mon Dec  9 18:46:51 2002
+++ b/drivers/misc/Makefile	Mon Dec  9 18:46:51 2002
@@ -1,5 +1,5 @@
 #
 # Makefile for misc devices that really don't fit anywhere else.
 #
-
+obj- := misc.o	# Dummy rule to force built-in.o to be made
 include $(TOPDIR)/Rules.make
diff -Nru a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
--- a/drivers/mtd/mtdblock.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/mtd/mtdblock.c	Mon Dec  9 18:46:36 2002
@@ -21,12 +21,7 @@
 #define DEVICE_NR(device) (device)
 #define LOCAL_END_REQUEST
 #include <linux/blk.h>
-
-#ifdef CONFIG_DEVFS_FS
 #include <linux/devfs_fs_kernel.h>
-static devfs_handle_t devfs_dir_handle = NULL;
-static devfs_handle_t devfs_rw_handle[MAX_MTD_DEVICES];
-#endif
 
 static void mtd_notify_add(struct mtd_info* mtd);
 static void mtd_notify_remove(struct mtd_info* mtd);
@@ -533,15 +528,15 @@
 static void mtd_notify_add(struct mtd_info* mtd)
 {
 	struct gendisk *disk;
-        char name[8];
+        char name[16];
 
         if (!mtd || mtd->type == MTD_ABSENT)
                 return;
 
 #ifdef CONFIG_DEVFS_FS
-        sprintf(name, "%d", mtd->index);
-        devfs_rw_handle[mtd->index] = devfs_register(devfs_dir_handle, name,
-                        DEVFS_FL_DEFAULT, MTD_BLOCK_MAJOR, mtd->index,
+        sprintf(name, DEVICE_NAME"/%d", mtd->index);
+        devfs_register(NULL, name, DEVFS_FL_DEFAULT,
+			MTD_BLOCK_MAJOR, mtd->index,
                         S_IFBLK | S_IRUGO | S_IWUGO,
                         &mtd_fops, NULL);
 #endif
@@ -566,9 +561,7 @@
         if (!mtd || mtd->type == MTD_ABSENT)
                 return;
 
-#ifdef CONFIG_DEVFS_FS
-        devfs_unregister(devfs_rw_handle[mtd->index]);
-#endif
+        devfs_remove(DEVICE_NAME"/%d", mtd->index);
 
         if (mtddisk[mtd->index]) {
 		del_gendisk(mtddisk[mtd->index]);
@@ -588,7 +581,7 @@
 		return -EAGAIN;
 	}
 #ifdef CONFIG_DEVFS_FS
-	devfs_dir_handle = devfs_mk_dir(NULL, DEVICE_NAME, NULL);
+	devfs_mk_dir(NULL, DEVICE_NAME, NULL);
 #endif
 	register_mtd_user(&notifier);
 	
@@ -605,7 +598,7 @@
 	down(&thread_sem);
 	unregister_mtd_user(&notifier);
 #ifdef CONFIG_DEVFS_FS
-	devfs_unregister(devfs_dir_handle);
+	devfs_remove(DEVICE_NAME);
 #endif
 	unregister_blkdev(MAJOR_NR,DEVICE_NAME);
 	blk_cleanup_queue(&mtd_queue);
diff -Nru a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
--- a/drivers/mtd/mtdchar.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/mtd/mtdchar.c	Mon Dec  9 18:46:50 2002
@@ -23,9 +23,6 @@
 	remove:	mtd_notify_remove,
 };
 
-static devfs_handle_t devfs_dir_handle;
-static devfs_handle_t devfs_rw_handle[MAX_MTD_DEVICES];
-static devfs_handle_t devfs_ro_handle[MAX_MTD_DEVICES];
 #endif
 
 static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
@@ -464,19 +461,19 @@
 
 static void mtd_notify_add(struct mtd_info* mtd)
 {
-	char name[8];
+	char name[16];
 
 	if (!mtd)
 		return;
 
-	sprintf(name, "%d", mtd->index);
-	devfs_rw_handle[mtd->index] = devfs_register(devfs_dir_handle, name,
+	sprintf(name, "mtd/%d", mtd->index);
+	devfs_register(NULL, name,
 			DEVFS_FL_DEFAULT, MTD_CHAR_MAJOR, mtd->index*2,
 			S_IFCHR | S_IRUGO | S_IWUGO,
 			&mtd_fops, NULL);
 
-	sprintf(name, "%dro", mtd->index);
-	devfs_ro_handle[mtd->index] = devfs_register(devfs_dir_handle, name,
+	sprintf(name, "mtd/%dro", mtd->index);
+	devfs_register(NULL, name,
 			DEVFS_FL_DEFAULT, MTD_CHAR_MAJOR, mtd->index*2+1,
 			S_IFCHR | S_IRUGO | S_IWUGO,
 			&mtd_fops, NULL);
@@ -486,9 +483,8 @@
 {
 	if (!mtd)
 		return;
-
-	devfs_unregister(devfs_rw_handle[mtd->index]);
-	devfs_unregister(devfs_ro_handle[mtd->index]);
+	devfs_remove("mtd/%d", mtd->index);
+	devfs_remove("mtd/%dro", mtd->index);
 }
 #endif
 
@@ -501,7 +497,7 @@
 	}
 
 #ifdef CONFIG_DEVFS_FS
-	devfs_dir_handle = devfs_mk_dir(NULL, "mtd", NULL);
+	devfs_mk_dir(NULL, "mtd", NULL);
 
 	register_mtd_user(&notifier);
 #endif
@@ -512,7 +508,7 @@
 {
 #ifdef CONFIG_DEVFS_FS
 	unregister_mtd_user(&notifier);
-	devfs_unregister(devfs_dir_handle);
+	devfs_remove("mtd");
 #endif
 	unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
 }
diff -Nru a/drivers/net/3c515.c b/drivers/net/3c515.c
--- a/drivers/net/3c515.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/net/3c515.c	Mon Dec  9 18:46:35 2002
@@ -83,12 +83,14 @@
 #define NEW_MULTICAST
 #include <linux/delay.h>
 
+#define MAX_UNITS 8
+
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("3Com 3c515 Corkscrew driver");
 MODULE_LICENSE("GPL");
 
 MODULE_PARM(debug, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(8) "i");
+MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM(rx_copybreak, "i");
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM_DESC(debug, "3c515 debug level (0-6)");
@@ -408,7 +410,7 @@
 */
 /* This driver uses 'options' to pass the media type, full-duplex flag, etc. */
 /* Note: this is the only limit on the number of cards supported!! */
-static int options[8] = { -1, -1, -1, -1, -1, -1, -1, -1, };
+static int options[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1, };
 
 #ifdef MODULE
 static int debug = -1;
@@ -545,9 +547,10 @@
 		printk(KERN_INFO "3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
 		     inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
 		irq = inw(ioaddr + 0x2002) & 15;
-		corkscrew_found_device(dev, ioaddr, irq, CORKSCREW_ID, dev
-				       && dev->mem_start ? dev->
-				       mem_start : options[cards_found]);
+		corkscrew_found_device(dev, ioaddr, irq, CORKSCREW_ID,
+				       dev && dev->mem_start ?  dev->mem_start :
+				         (cards_found >= MAX_UNITS ? -1 :
+						options[cards_found]));
 		dev = 0;
 		cards_found++;
 	}
diff -Nru a/drivers/net/3c523.c b/drivers/net/3c523.c
--- a/drivers/net/3c523.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/net/3c523.c	Mon Dec  9 18:46:37 2002
@@ -210,10 +210,11 @@
 	volatile struct iscp_struct *iscp;	/* volatile is important */
 	volatile struct scb_struct *scb;	/* volatile is important */
 	volatile struct tbd_struct *xmit_buffs[NUM_XMIT_BUFFS];
-	volatile struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS];
 #if (NUM_XMIT_BUFFS == 1)
+	volatile struct transmit_cmd_struct *xmit_cmds[2];
 	volatile struct nop_cmd_struct *nop_cmds[2];
 #else
+	volatile struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS];
 	volatile struct nop_cmd_struct *nop_cmds[NUM_XMIT_BUFFS];
 #endif
 	volatile int nop_point, num_recv_buffs;
diff -Nru a/drivers/net/8139too.c b/drivers/net/8139too.c
--- a/drivers/net/8139too.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/net/8139too.c	Mon Dec  9 18:46:34 2002
@@ -969,7 +969,12 @@
 	dev->do_ioctl = netdev_ioctl;
 	dev->tx_timeout = rtl8139_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
-	dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
+
+	/* note: the hardware is not capable of sg/csum/highdma, however
+	 * through the use of skb_copy_and_csum_dev we enable these
+	 * features
+	 */
+	dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA;
 
 	dev->irq = pdev->irq;
 
diff -Nru a/drivers/net/Kconfig b/drivers/net/Kconfig
--- a/drivers/net/Kconfig	Mon Dec  9 18:46:51 2002
+++ b/drivers/net/Kconfig	Mon Dec  9 18:46:51 2002
@@ -1719,6 +1719,17 @@
 	  say M here and read <file:Documentation/modules.txt>.  This is
 	  recommended.  The module will be called yellowfin.o.
 
+config R8169
+	tristate "Realtek 8169 gigabit ethernet support"
+	depends on PCI
+	---help---
+	  Say Y here if you have a Realtek 8169 PCI Gigabit Ethernet adapter.
+
+	  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>.  This is
+	  recommended.  The module will be called r8169.o.
+
 config SK98LIN
 	tristate "SysKonnect SK-98xx support"
 	depends on PCI
diff -Nru a/drivers/net/Makefile b/drivers/net/Makefile
--- a/drivers/net/Makefile	Mon Dec  9 18:46:35 2002
+++ b/drivers/net/Makefile	Mon Dec  9 18:46:35 2002
@@ -182,6 +182,10 @@
 obj-$(CONFIG_MAC89x0) += mac89x0.o
 obj-$(CONFIG_TUN) += tun.o
 obj-$(CONFIG_DL2K) += dl2k.o
+obj-$(CONFIG_R8169) += r8169.o
+
+# non-drivers/net drivers who want mii lib
+obj-$(CONFIG_PCMCIA_SMC91C92) += mii.o
 
 obj-$(CONFIG_ARCH_ACORN) += ../acorn/net/
 obj-$(CONFIG_NET_FC) += fc/
diff -Nru a/drivers/net/Makefile.lib b/drivers/net/Makefile.lib
--- a/drivers/net/Makefile.lib	Mon Dec  9 18:46:50 2002
+++ b/drivers/net/Makefile.lib	Mon Dec  9 18:46:50 2002
@@ -36,6 +36,7 @@
 obj-$(CONFIG_VIA_RHINE)		+= crc32.o
 obj-$(CONFIG_YELLOWFIN)		+= crc32.o
 obj-$(CONFIG_WINBOND_840)	+= crc32.o
+obj-$(CONFIG_R8169)		+= crc32.o
 
 
 # These rely on drivers/net/7990.o which requires crc32.o
diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c
--- a/drivers/net/Space.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/net/Space.c	Mon Dec  9 18:46:34 2002
@@ -48,7 +48,6 @@
 extern int hp100_probe(struct net_device *dev);
 extern int ultra_probe(struct net_device *dev);
 extern int ultra32_probe(struct net_device *dev);
-extern int ultramca_probe(struct net_device *dev);
 extern int wd_probe(struct net_device *dev);
 extern int el2_probe(struct net_device *dev);
 extern int ne_probe(struct net_device *dev);
@@ -105,7 +104,6 @@
 extern int mc32_probe(struct net_device *dev);
   
 /* Detachable devices ("pocket adaptors") */
-extern int de600_probe(struct net_device *);
 extern int de620_probe(struct net_device *);
 
 /* FDDI adapters */
@@ -192,9 +190,6 @@
 
 
 static struct devprobe mca_probes[] __initdata = {
-#ifdef CONFIG_ULTRAMCA 
-	{ultramca_probe, 0},
-#endif
 #ifdef CONFIG_NE2_MCA
 	{ne2_probe, 0},
 #endif
@@ -315,9 +310,6 @@
 };
 
 static struct devprobe parport_probes[] __initdata = {
-#ifdef CONFIG_DE600		/* D-Link DE-600 adapter */
-	{de600_probe, 0},
-#endif
 #ifdef CONFIG_DE620		/* D-Link DE-620 adapter */
 	{de620_probe, 0},
 #endif
diff -Nru a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c
--- a/drivers/net/appletalk/cops.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/net/appletalk/cops.c	Mon Dec  9 18:46:37 2002
@@ -68,6 +68,7 @@
 #include <linux/if_ltalk.h>	/* For ltalk_setup() */
 #include <linux/delay.h>	/* For udelay() */
 #include <linux/atalk.h>
+#include <linux/spinlock.h>
 
 #include <asm/system.h>
 #include <asm/bitops.h>
@@ -320,7 +321,7 @@
 
         lp = (struct cops_local *)dev->priv;
         memset(lp, 0, sizeof(struct cops_local));
-        spinlock_init(&lp->lock);
+        spin_lock_init(&lp->lock);
 
 	/* Copy local board variable to lp struct. */
 	lp->board               = board;
diff -Nru a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
--- a/drivers/net/au1000_eth.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/net/au1000_eth.c	Mon Dec  9 18:46:38 2002
@@ -122,9 +122,12 @@
   au1500_iflist[NUM_INTERFACES] = {
 		{AU1500_ETH0_BASE, AU1000_ETH0_IRQ}, 
 		{AU1500_ETH1_BASE, AU1000_ETH1_IRQ}
+	},
+  au1100_iflist[NUM_INTERFACES] = {
+		{AU1000_ETH0_BASE, AU1000_ETH0_IRQ}, 
+		{NULL, NULL}
 	};
 
-
 static char version[] __devinitdata =
     "au1000eth.c:1.0 ppopov@mvista.com\n";
 
@@ -176,6 +179,11 @@
 	data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO;
 	mdio_write(dev, phy_addr, MII_CONTROL, data);
 
+	/* Enable TX LED instead of FDX */
+	data = mdio_read(dev, phy_addr, MII_INT);
+	data &= ~MII_FDX_LED;
+	mdio_write(dev, phy_addr, MII_INT, data);
+
 	if (au1000_debug > 4) dump_mii(dev, phy_addr);
 	return 0;
 }
@@ -249,6 +257,8 @@
 	/* restart auto-negotiation */
 	mdio_write(dev, phy_addr, 0, 0x3200);
 
+	mdelay(1);
+
 	/* set up LEDs to correct display */
 	mdio_write(dev, phy_addr, 17, 0xffc0);
 
@@ -367,6 +377,7 @@
 	{"Broadcom BCM5201 10/100 BaseT PHY",  0x0040, 0x6212, &bcm_5201_ops },
 	{"AMD 79C901 HomePNA PHY",  0x0000, 0x35c8, &am79c901_ops },
 	{"LSI 80227 10/100 BaseT PHY", 0x0016, 0xf840, &lsi_80227_ops },
+	{"Broadcom BCM5221 10/100 BaseT PHY",  0x0040, 0x61e4, &bcm_5201_ops },
 	{0,},
 };
 
@@ -637,13 +648,19 @@
 		} else if ( (prid & 0xffff0000) == 0x01030000 ) {
 			base_addr = au1500_iflist[i].port;
 			irq = au1500_iflist[i].irq;
+		} else if ( (prid & 0xffff0000) == 0x02030000 ) {
+			base_addr = au1100_iflist[i].port;
+			irq = au1100_iflist[i].irq;
 		} else {
 			printk(KERN_ERR "au1000 eth: unknown Processor ID\n");
 			return -ENODEV;
 		}
+		// check for valid entries, au1100 only has one entry
+		if (base_addr && irq) {
 		if (au1000_probe1(NULL, base_addr, irq, i) != 0) {
 			return -ENODEV;
 		}
+	}
 	}
 	return 0;
 }
diff -Nru a/drivers/net/au1000_eth.h b/drivers/net/au1000_eth.h
--- a/drivers/net/au1000_eth.h	Mon Dec  9 18:46:35 2002
+++ b/drivers/net/au1000_eth.h	Mon Dec  9 18:46:35 2002
@@ -39,7 +39,7 @@
 #define ETH_TX_TIMEOUT HZ/4
 #define MAC_MIN_PKT_SIZE 64
 
-#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1500)
+#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1100)
 #define PHY_ADDRESS              0
 #define PHY_CONTROL_DEFAULT 0x3000
 #define PHY_CONTROL_REG_ADDR     0
@@ -63,6 +63,7 @@
 #define MII_LSI_CONFIG 0x0011
 #define MII_LSI_STAT   0x0012
 #define MII_AUX_CNTRL  0x0018
+#define MII_INT        0x001A
 
 /* mii registers specific to AMD 79C901 */
 #define	MII_STATUS_SUMMARY = 0x0018
@@ -128,14 +129,15 @@
 
 /* lsi status register */
 
-#define MII_LSI_STAT_FDX	0x0008
-#define MII_LSI_STAT_SPD	0x0010
+#define MII_LSI_STAT_FDX	0x0040
+#define MII_LSI_STAT_SPD	0x0080
 
 /* Auxilliary Control/Status Register */
 #define MII_AUX_FDX      0x0001
 #define MII_AUX_100      0x0002
 #define MII_AUX_F100     0x0004
 #define MII_AUX_ANEG     0x0008
+#define MII_FDX_LED      0x8000
 
 typedef struct mii_phy {
 	struct mii_phy * next;
diff -Nru a/drivers/net/b44.c b/drivers/net/b44.c
--- a/drivers/net/b44.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/net/b44.c	Mon Dec  9 18:46:36 2002
@@ -12,8 +12,8 @@
 #include <linux/if_ether.h>
 #include <linux/etherdevice.h>
 #include <linux/pci.h>
-#include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/init.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -23,8 +23,8 @@
 
 #define DRV_MODULE_NAME		"b44"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"0.1"
-#define DRV_MODULE_RELDATE	"Nov 6, 2002"
+#define DRV_MODULE_VERSION	"0.6"
+#define DRV_MODULE_RELDATE	"Nov 11, 2002"
 
 #define B44_DEF_MSG_ENABLE	  \
 	(NETIF_MSG_DRV		| \
@@ -62,7 +62,6 @@
 	  (BP)->tx_cons - (BP)->tx_prod - TX_RING_GAP(BP))
 #define NEXT_TX(N)		(((N) + 1) & (B44_TX_RING_SIZE - 1))
 
-/* XXX check this */
 #define RX_PKT_BUF_SZ		(1536 + bp->rx_offset + 64)
 
 /* minimum number of free TX descriptors required to wake up TX process */
@@ -72,18 +71,13 @@
 	DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
 
 MODULE_AUTHOR("David S. Miller (davem@redhat.com)");
-MODULE_DESCRIPTION("Broadcom 4400 ethernet driver");
+MODULE_DESCRIPTION("Broadcom 4400 10/100 PCI ethernet driver");
 MODULE_LICENSE("GPL");
 MODULE_PARM(b44_debug, "i");
 MODULE_PARM_DESC(b44_debug, "B44 bitmapped debugging message enable value");
 
 static int b44_debug = -1;	/* -1 == use B44_DEF_MSG_ENABLE as value */
 
-/* XXX put this to pci_ids.h and pci.ids */
-#ifndef PCI_DEVICE_ID_BCM4401
-#define PCI_DEVICE_ID_BCM4401 0x4401
-#endif
-
 static struct pci_device_id b44_pci_tbl[] __devinitdata = {
 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
@@ -96,8 +90,8 @@
 static void b44_init_rings(struct b44 *);
 static int b44_init_hw(struct b44 *);
 
-static void b44_wait_bit(struct b44 *bp, unsigned long reg,
-			 u32 bit, unsigned long timeout, int clear)
+static int b44_wait_bit(struct b44 *bp, unsigned long reg,
+			u32 bit, unsigned long timeout, const int clear)
 {
 	unsigned long i;
 
@@ -116,7 +110,9 @@
 		       bp->dev->name,
 		       bit, reg,
 		       (clear ? "clear" : "set"));
+		return -ENODEV;
 	}
+	return 0;
 }
 
 /* Sonics SiliconBackplane support routines.  ROFL, you should see all the
@@ -301,15 +297,18 @@
 
 static int b44_readphy(struct b44 *bp, int reg, u32 *val)
 {
+	int err;
+
 	bw32(B44_EMAC_ISTAT, EMAC_INT_MII);
 	bw32(B44_MDIO_DATA, (MDIO_DATA_SB_START |
 			     (MDIO_OP_READ << MDIO_DATA_OP_SHIFT) |
 			     (bp->phy_addr << MDIO_DATA_PMD_SHIFT) |
 			     (reg << MDIO_DATA_RA_SHIFT) |
 			     (MDIO_TA_VALID << MDIO_DATA_TA_SHIFT)));
-	b44_wait_bit(bp, B44_EMAC_ISTAT, EMAC_INT_MII, 100, 0);
+	err = b44_wait_bit(bp, B44_EMAC_ISTAT, EMAC_INT_MII, 100, 0);
 	*val = br32(B44_MDIO_DATA) & MDIO_DATA_DATA;
-	return 0;
+
+	return err;
 }
 
 static int b44_writephy(struct b44 *bp, int reg, u32 val)
@@ -321,8 +320,7 @@
 			     (reg << MDIO_DATA_RA_SHIFT) |
 			     (MDIO_TA_VALID << MDIO_DATA_TA_SHIFT) |
 			     (val & MDIO_DATA_DATA)));
-	b44_wait_bit(bp, B44_EMAC_ISTAT, EMAC_INT_MII, 100, 0);
-	return 0;
+	return b44_wait_bit(bp, B44_EMAC_ISTAT, EMAC_INT_MII, 100, 0);
 }
 
 static int b44_phy_reset(struct b44 *bp)
@@ -346,12 +344,6 @@
 	return 0;
 }
 
-#if 0
-static int b44_set_power_state(struct b44 *bp, int state)
-{
-}
-#endif
-
 static void __b44_set_flow_ctrl(struct b44 *bp, u32 pause_flags)
 {
 	u32 val;
@@ -575,7 +567,6 @@
 		if (unlikely(skb == NULL))
 			BUG();
 
-
 		pci_unmap_single(bp->pdev,
 				 pci_unmap_addr(rp, mapping),
 				 skb->len,
@@ -592,10 +583,16 @@
 	bw32(B44_GPTIMER, 0);
 }
 
+/* Works like this.  This chip writes a 'struct rx_header" 30 bytes
+ * before the DMA address you give it.  So we allocate 30 more bytes
+ * for the RX buffer, DMA map all of it, skb_reserve the 30 bytes, then
+ * point the chip at 30 bytes past where the rx_header will go.
+ */
 static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
 {
 	struct dma_desc *dp;
 	struct ring_info *src_map, *map;
+	struct rx_header *rh;
 	struct sk_buff *skb;
 	dma_addr_t mapping;
 	int dest_idx;
@@ -616,6 +613,11 @@
 				 PCI_DMA_FROMDEVICE);
 	skb_reserve(skb, bp->rx_offset);
 
+	rh = (struct rx_header *)
+		(skb->data - bp->rx_offset);
+	rh->len = 0;
+	rh->flags = 0;
+
 	map->skb = skb;
 	pci_unmap_addr_set(map, mapping, mapping);
 
@@ -637,6 +639,7 @@
 {
 	struct dma_desc *src_desc, *dest_desc;
 	struct ring_info *src_map, *dest_map;
+	struct rx_header *rh;
 	int dest_idx;
 	u32 ctrl;
 
@@ -647,6 +650,10 @@
 	src_map = &bp->rx_buffers[src_idx];
 
 	dest_map->skb = src_map->skb;
+	rh = (struct rx_header *)
+		(src_map->skb->data - bp->rx_offset);
+	rh->len = 0;
+	rh->flags = 0;
 	pci_unmap_addr_set(dest_map, mapping,
 			   pci_unmap_addr(src_map, mapping));
 
@@ -680,7 +687,8 @@
 				    PCI_DMA_FROMDEVICE);
 		rh = (struct rx_header *) (skb->data - bp->rx_offset);
 		len = cpu_to_le16(rh->len);
-		if (rh->flags & cpu_to_le16(RX_FLAG_ERRORS)) {
+		if ((len > (RX_PKT_BUF_SZ - bp->rx_offset)) ||
+		    (rh->flags & cpu_to_le16(RX_FLAG_ERRORS))) {
 		drop_it:
 			b44_recycle_rx(bp, cons, bp->rx_prod);
 		drop_it_no_recycle:
@@ -688,6 +696,21 @@
 			goto next_pkt;
 		}
 
+		if (len == 0) {
+			int i = 0;
+
+			do {
+				udelay(2);
+				barrier();
+				len = cpu_to_le16(rh->len);
+			} while (len == 0 && i++ < 5);
+			if (len == 0)
+				goto drop_it;
+		}
+
+		/* Omit CRC. */
+		len -= 4;
+
 		if (len > RX_COPY_THRESHOLD) {
 			int skb_size;
 			skb_size = b44_alloc_rx_skb(bp, cons, bp->rx_prod);
@@ -927,7 +950,7 @@
 			continue;
 		pci_unmap_single(bp->pdev,
 				 pci_unmap_addr(rp, mapping),
-				 RX_PKT_BUF_SZ - bp->rx_offset,
+				 RX_PKT_BUF_SZ,
 				 PCI_DMA_FROMDEVICE);
 		dev_kfree_skb_any(rp->skb);
 		rp->skb = NULL;
@@ -1053,7 +1076,10 @@
 		b44_wait_bit(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE, 100, 1);
 		bw32(B44_DMATX_CTRL, 0);
 		bp->tx_prod = bp->tx_cons = 0;
-		b44_wait_bit(bp, B44_DMARX_STAT, DMARX_STAT_SIDLE, 100, 0);
+		if (br32(B44_DMARX_STAT) & DMARX_STAT_EMASK) {
+			b44_wait_bit(bp, B44_DMARX_STAT, DMARX_STAT_SIDLE,
+				     100, 0);
+		}
 		bw32(B44_DMARX_CTRL, 0);
 		bp->rx_prod = bp->rx_cons = 0;
 	} else {
@@ -1173,45 +1199,38 @@
 	if (err)
 		return err;
 
-	err = request_irq(dev->irq, b44_interrupt,
-			  SA_SHIRQ, dev->name, dev);
-	if (err) {
-		b44_free_consistent(bp);
-		return err;
-	}
+	err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev);
+	if (err)
+		goto err_out_free;
 
 	spin_lock_irq(&bp->lock);
 
 	b44_init_rings(bp);
 	err = b44_init_hw(bp);
-	if (err) {
-		b44_halt(bp);
-		b44_free_rings(bp);
-	} else {
-		bp->flags |= B44_FLAG_INIT_COMPLETE;
-	}
+	if (err)
+		goto err_out_noinit;
+	bp->flags |= B44_FLAG_INIT_COMPLETE;
 
 	spin_unlock_irq(&bp->lock);
 
-	if (err) {
-		free_irq(dev->irq, dev);
-		b44_free_consistent(bp);
-		return err;
-	} else {
-		init_timer(&bp->timer);
-		bp->timer.expires = jiffies + HZ;
-		bp->timer.data = (unsigned long) bp;
-		bp->timer.function = b44_timer;
-		add_timer(&bp->timer);
-	}
-
-	spin_lock_irq(&bp->lock);
+	init_timer(&bp->timer);
+	bp->timer.expires = jiffies + HZ;
+	bp->timer.data = (unsigned long) bp;
+	bp->timer.function = b44_timer;
+	add_timer(&bp->timer);
 
 	b44_enable_ints(bp);
 
-	spin_unlock_irq(&bp->lock);
-
 	return 0;
+
+err_out_noinit:
+	b44_halt(bp);
+	b44_free_rings(bp);
+	spin_unlock_irq(&bp->lock);
+	free_irq(dev->irq, dev);
+err_out_free:
+	b44_free_consistent(bp);
+	return err;
 }
 
 #if 0
@@ -1232,7 +1251,18 @@
 
 	netif_stop_queue(dev);
 
+	del_timer_sync(&bp->timer);
+
 	spin_lock_irq(&bp->lock);
+
+#if 0
+	b44_dump_state(bp);
+#endif
+	b44_halt(bp);
+	b44_free_rings(bp);
+	bp->flags &= ~B44_FLAG_INIT_COMPLETE;
+	netif_carrier_off(bp->dev);
+
 	spin_unlock_irq(&bp->lock);
 
 	free_irq(dev->irq, dev);
@@ -1711,8 +1741,8 @@
 	bp = dev->priv;
 	bp->pdev = pdev;
 	bp->dev = dev;
-	if (b44_debug > 0)
-		bp->msg_enable = b44_debug;
+	if (b44_debug >= 0)
+		bp->msg_enable = (1 << b44_debug) - 1;
 	else
 		bp->msg_enable = B44_DEF_MSG_ENABLE;
 
@@ -1809,10 +1839,6 @@
 	.id_table	= b44_pci_tbl,
 	.probe		= b44_init_one,
 	.remove		= __devexit_p(b44_remove_one),
-#if 0
-	.suspend	= b44_suspend,
-	.resume		= b44_resume
-#endif
 };
 
 static int __init b44_init(void)
@@ -1827,3 +1853,4 @@
 
 module_init(b44_init);
 module_exit(b44_cleanup);
+
diff -Nru a/drivers/net/de620.c b/drivers/net/de620.c
--- a/drivers/net/de620.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/net/de620.c	Mon Dec  9 18:46:38 2002
@@ -844,12 +844,6 @@
 		return -ENODEV;
 	}
 
-#if 0 /* Not yet */
-	if (check_region(dev->base_addr, 3)) {
-		printk(", port 0x%x busy\n", dev->base_addr);
-		return -EBUSY;
-	}
-#endif
 	if (!request_region(dev->base_addr, 3, "de620")) {
 		printk(KERN_ERR "io 0x%3lX, which is busy.\n", dev->base_addr);
 		return -EBUSY;
diff -Nru a/drivers/net/dgrs.c b/drivers/net/dgrs.c
--- a/drivers/net/dgrs.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/net/dgrs.c	Mon Dec  9 18:46:34 2002
@@ -1278,8 +1278,10 @@
 	dev->init = dgrs_probe1;
 	SET_MODULE_OWNER(dev);
 	ether_setup(dev);
-	if (register_netdev(dev) != 0)
+	if (register_netdev(dev) != 0) {
+		kfree(dev);
 		return -EIO;
+	}
 
 	priv->next_dev = dgrs_root_dev;
 	dgrs_root_dev = dev;
diff -Nru a/drivers/net/dl2k.c b/drivers/net/dl2k.c
--- a/drivers/net/dl2k.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/net/dl2k.c	Mon Dec  9 18:46:36 2002
@@ -50,7 +50,7 @@
 
 */
 #define DRV_NAME	"D-Link DL2000-based linux driver"
-#define DRV_VERSION	"v1.17"
+#define DRV_VERSION	"v1.17a"
 #define DRV_RELDATE	"2002/10/04"
 #include "dl2k.h"
 
@@ -1007,7 +1007,9 @@
 {
 	long ioaddr = dev->base_addr;
 	struct netdev_private *np = dev->priv;
+#ifdef MEM_MAPPING
 	int i;
+#endif
 	unsigned int stat_reg;
 
 	/* All statistics registers need to be acknowledged,
@@ -1050,9 +1052,10 @@
 	readw (ioaddr + MacControlFramesXmtd);
 	readw (ioaddr + FramesWEXDeferal);
 
-
+#ifdef MEM_MAPPING
 	for (i = 0x100; i <= 0x150; i += 4)
 		readl (ioaddr + i);
+#endif
 	readw (ioaddr + TxJumboFrames);
 	readw (ioaddr + RxJumboFrames);
 	readw (ioaddr + TCPCheckSumErrors);
@@ -1065,7 +1068,9 @@
 clear_stats (struct net_device *dev)
 {
 	long ioaddr = dev->base_addr;
+#ifdef MEM_MAPPING
 	int i;
+#endif 
 
 	/* All statistics registers need to be acknowledged,
 	   else statistic overflow could cause problems */
@@ -1101,9 +1106,10 @@
 	readw (ioaddr + BcstFramesXmtdOk);
 	readw (ioaddr + MacControlFramesXmtd);
 	readw (ioaddr + FramesWEXDeferal);
-
+#ifdef MEM_MAPPING
 	for (i = 0x100; i <= 0x150; i += 4)
 		readl (ioaddr + i);
+#endif 
 	readw (ioaddr + TxJumboFrames);
 	readw (ioaddr + RxJumboFrames);
 	readw (ioaddr + TCPCheckSumErrors);
@@ -1136,7 +1142,7 @@
 	u16 rx_mode = 0;
 	int i;
 	int bit;
-	int index, crc;
+	long index, crc;
 	struct dev_mc_list *mclist;
 	struct netdev_private *np = dev->priv;
 	
diff -Nru a/drivers/net/e100/e100_main.c b/drivers/net/e100/e100_main.c
--- a/drivers/net/e100/e100_main.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/net/e100/e100_main.c	Mon Dec  9 18:46:37 2002
@@ -87,8 +87,8 @@
 extern int e100_create_proc_subdir(struct e100_private *, char *);
 extern void e100_remove_proc_subdir(struct e100_private *, char *);
 #else
-#define e100_create_proc_subdir(X) 0
-#define e100_remove_proc_subdir(X) do {} while(0)
+#define e100_create_proc_subdir(X, Y) 0
+#define e100_remove_proc_subdir(X, Y) do {} while(0)
 #endif
 
 static int e100_do_ethtool_ioctl(struct net_device *, struct ifreq *);
diff -Nru a/drivers/net/eepro.c b/drivers/net/eepro.c
--- a/drivers/net/eepro.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/net/eepro.c	Mon Dec  9 18:46:50 2002
@@ -820,7 +820,6 @@
 				}
 				if (dev->irq < 2) {
 			printk(KERN_ERR " Duh! illegal interrupt vector stored in EEPROM.\n");
-					kfree(dev->priv);
 			retval = -ENODEV;
 			goto freeall;
 				} else
diff -Nru a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c
--- a/drivers/net/ewrk3.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/net/ewrk3.c	Mon Dec  9 18:46:51 2002
@@ -707,6 +707,7 @@
 	struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv;
 	u_char csr, page;
 	u_long iobase = dev->base_addr;
+	int i;
 
 	/*
 	   ** Enable any multicasts
@@ -714,6 +715,13 @@
 	set_multicast_list(dev);
 
 	/*
+	** Set hardware MAC address. Address is initialized from the EEPROM
+	** during startup but may have since been changed by the user.
+	*/
+	for (i=0; i<ETH_ALEN; i++)
+		outb(dev->dev_addr[i], EWRK3_PAR0 + i);
+
+	/*
 	   ** Clean out any remaining entries in all the queues here
 	 */
 	while (inb(EWRK3_TQ));
@@ -1754,23 +1762,17 @@
 		return 0;
 	}
 
-#ifdef BROKEN
 	/* Blink LED for identification */
 	case ETHTOOL_PHYS_ID: {
 		struct ethtool_value edata;
 		u_long flags;
-		long delay, ret;
 		u_char cr;
 		int count;
-		wait_queue_head_t wait;
-
-		init_waitqueue_head(&wait);
 
 		if (copy_from_user(&edata, useraddr, sizeof(edata)))
 			return -EFAULT;
 
 		/* Toggle LED 4x per second */
-		delay = HZ >> 2;
 		count = edata.data << 2;
 
 		spin_lock_irqsave(&lp->hw_lock, flags);
@@ -1791,24 +1793,21 @@
 
 			/* Wait a little while */
 			spin_unlock_irqrestore(&lp->hw_lock, flags);
-			ret = delay;
-			__wait_event_interruptible_timeout(wait, 0, ret);
+			set_current_state(TASK_UNINTERRUPTIBLE);
+			schedule_timeout(HZ>>2);
 			spin_lock_irqsave(&lp->hw_lock, flags);
 
 			/* Exit if we got a signal */
-			if (ret == -ERESTARTSYS)
-				goto out;
+			if (signal_pending(current))
+				break;
 		}
 
-		ret = 0;
-out:
 		lp->led_mask = CR_LED;
 		cr = inb(EWRK3_CR);
 		outb(cr & ~CR_LED, EWRK3_CR);
 		spin_unlock_irqrestore(&lp->hw_lock, flags);
-		return ret;
+		return signal_pending(current) ? -ERESTARTSYS : 0;
 	}
-#endif /* BROKEN */
 
 	}
 
diff -Nru a/drivers/net/fealnx.c b/drivers/net/fealnx.c
--- a/drivers/net/fealnx.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/net/fealnx.c	Mon Dec  9 18:46:50 2002
@@ -1155,8 +1155,8 @@
 	unsigned int old_linkok = np->linkok;
 
 	if (debug)
-		printk(KERN_DEBUG "%s: Media selection timer tick, status %8.8lx "
-		       "config %8.8lx.\n", dev->name, readl(ioaddr + ISR),
+		printk(KERN_DEBUG "%s: Media selection timer tick, status %8.8x "
+		       "config %8.8x.\n", dev->name, readl(ioaddr + ISR),
 		       readl(ioaddr + TCRRCR));
 
 	if (np->flags == HAS_MII_XCVR) {
@@ -1184,7 +1184,7 @@
 	long ioaddr = dev->base_addr;
 	int i;
 
-	printk(KERN_WARNING "%s: Transmit timed out, status %8.8lx,"
+	printk(KERN_WARNING "%s: Transmit timed out, status %8.8x,"
 	       " resetting...\n", dev->name, readl(ioaddr + ISR));
 
 	{
@@ -1198,7 +1198,6 @@
 		printk("\n");
 	}
 
-	   + dev->if_port = np->default_port;
 	/* Reinit. Gross */
 
 	/* Reset the chip's Tx and Rx processes. */
@@ -1555,7 +1554,7 @@
 	np->stats.rx_crc_errors += (readl(ioaddr + TALLY) & 0x7fff0000) >> 16;
 
 	if (debug)
-		printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4lx.\n",
+		printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
 		       dev->name, readl(ioaddr + ISR));
 
 	writel(np->imrvalue, ioaddr + IMR);
diff -Nru a/drivers/net/fec.c b/drivers/net/fec.c
--- a/drivers/net/fec.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/net/fec.c	Mon Dec  9 18:46:34 2002
@@ -196,6 +196,7 @@
 static void set_multicast_list(struct net_device *dev);
 static void fec_restart(struct net_device *dev, int duplex);
 static void fec_stop(struct net_device *dev);
+static void fec_set_mac_address(struct net_device *dev);
 
 
 /* MII processing.  We keep this as simple as possible.  Requests are
@@ -1479,6 +1480,8 @@
 	 * a simple way to do that.
 	 */
 
+	fec_set_mac_address(dev);
+
 	fep->sequence_done = 0;
 	fep->link = 0;
 
@@ -1487,6 +1490,10 @@
 		mii_do_cmd(dev, fep->phy->config);
 		mii_do_cmd(dev, phy_cmd_config);  /* display configuration */
 
+		/* FIXME: use netif_carrier_{on,off} ; this polls
+		 * until link is up which is wrong...  could be
+		 * 30 seconds or more we are trapped in here. -jgarzik
+		 */
 		while(!fep->sequence_done)
 			schedule();
 
@@ -1602,6 +1609,25 @@
 	}
 }
 
+/* Set a MAC change in hardware.
+ */
+static void
+fec_set_mac_address(struct net_device *dev)
+{
+	int i;
+	volatile fec_t *fecp;
+
+	fecp = fec_hwp;
+
+	/* Set our copy of the Ethernet address */
+	for (i = 0; i < (ETH_ALEN / 2); i++)
+		my_enet_addr[i] = (dev->dev_addr[i*2] << 8) | dev->dev_addr[i*2 + 1];
+
+	/* Set station address. */
+	fecp->fec_addr_low = (my_enet_addr[0] << 16) | my_enet_addr[1];
+	fecp->fec_addr_high = my_enet_addr[2] << 16;
+}
+
 /* Initialize the FEC Ethernet on 860T (or ColdFire 5272).
  */
 int __init fec_enet_init(struct net_device *dev)
@@ -1643,6 +1669,9 @@
 
 	/* Set the Ethernet address.  If using multiple Enets on the 8xx,
 	 * this needs some work to get unique addresses.
+	 *
+	 * This is our default MAC address unless the user changes
+	 * it via eth_mac_addr (our dev->set_mac_addr handler).
 	 */
 	fec_get_mac(dev, fep);
 
@@ -1767,9 +1796,9 @@
 {
 	struct fec_enet_private *fep;
 	int i;
-	unsigned char	*eap;
-	volatile	cbd_t	*bdp;
-	volatile	fec_t	*fecp;
+	unsigned char *eap;
+	volatile cbd_t *bdp;
+	volatile fec_t *fecp;
 
 	fecp = fec_hwp;
 
diff -Nru a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
--- a/drivers/net/hamradio/dmascc.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/net/hamradio/dmascc.c	Mon Dec  9 18:46:36 2002
@@ -400,7 +400,7 @@
     /* Check valid I/O address regions */
     for (i = 0; i < hw[h].num_devs; i++)
       if (base[i]) {
-	if (check_region(base[i], hw[h].io_size))
+	if (!request_region(base[i], hw[h].io_size, "dmascc"))
 	  base[i] = 0;
 	else {
 	  tcmd[i] = base[i] + hw[h].tmr_offset + TMR_CTRL;
@@ -446,11 +446,12 @@
     /* Evaluate measurements */
     for (i = 0; i < hw[h].num_devs; i++)
       if (base[i]) {
-	if (delay[i] >= 9 && delay[i] <= 11) {
-	  /* Ok, we have found an adapter */
-	  if (setup_adapter(base[i], h, n) == 0)
-	    n++;
-	}
+	if ((delay[i] >= 9 && delay[i] <= 11)&& 
+	    /* Ok, we have found an adapter */
+	    (setup_adapter(base[i], h, n) == 0))
+	  n++;
+	else
+	  release_region(base[i], hw[h].io_size);
       }
 
   } /* NUM_TYPES */
@@ -606,7 +607,6 @@
     rtnl_unlock();
   }
 
-  request_region(card_base, hw[type].io_size, "dmascc");
 
   info->next = first;
   first = info;
diff -Nru a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
--- a/drivers/net/irda/irda-usb.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/net/irda/irda-usb.c	Mon Dec  9 18:46:37 2002
@@ -107,9 +107,9 @@
 static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *dev);
 static int irda_usb_open(struct irda_usb_cb *self);
 static int irda_usb_close(struct irda_usb_cb *self);
-static void speed_bulk_callback(struct urb *urb);
-static void write_bulk_callback(struct urb *urb);
-static void irda_usb_receive(struct urb *urb);
+static void speed_bulk_callback(struct urb *urb, struct pt_regs *regs);
+static void write_bulk_callback(struct urb *urb, struct pt_regs *regs);
+static void irda_usb_receive(struct urb *urb, struct pt_regs *regs);
 static int irda_usb_net_init(struct net_device *dev);
 static int irda_usb_net_open(struct net_device *dev);
 static int irda_usb_net_close(struct net_device *dev);
@@ -284,7 +284,7 @@
  * Speed URB callback
  * Now, we can only get called for the speed URB.
  */
-static void speed_bulk_callback(struct urb *urb)
+static void speed_bulk_callback(struct urb *urb, struct pt_regs *regs)
 {
 	struct irda_usb_cb *self = urb->context;
 	
@@ -486,7 +486,7 @@
 /*
  * Note : this function will be called only for tx_urb...
  */
-static void write_bulk_callback(struct urb *urb)
+static void write_bulk_callback(struct urb *urb, struct pt_regs *regs)
 {
 	unsigned long flags;
 	struct sk_buff *skb = urb->context;
@@ -753,7 +753,7 @@
  *     Called by the USB subsystem when a frame has been received
  *
  */
-static void irda_usb_receive(struct urb *urb) 
+static void irda_usb_receive(struct urb *urb, struct pt_regs *regs)
 {
 	struct sk_buff *skb = (struct sk_buff *) urb->context;
 	struct irda_usb_cb *self; 
diff -Nru a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c
--- a/drivers/net/irda/w83977af_ir.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/net/irda/w83977af_ir.c	Mon Dec  9 18:46:36 2002
@@ -119,9 +119,6 @@
 	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
 	for (i=0; (io[i] < 2000) && (i < 4); i++) { 
-		int ioaddr = io[i];
-		if (check_region(ioaddr, CHIP_IO_EXTENT) < 0)
-			continue;
 		if (w83977af_open(i, io[i], irq[i], dma[i]) == 0)
 			return 0;
 	}
@@ -157,14 +154,21 @@
 {
 	struct net_device *dev;
         struct w83977af_ir *self;
-	void *ret;
 	int err;
 
 	IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
 
-	if (w83977af_probe(iobase, irq, dma) == -1)
-		return -1;
+	/* Lock the port that we need */
+	if (!request_region(iobase, CHIP_IO_EXTENT, driver_name)) {
+		IRDA_DEBUG(0, "%s(), can't get iobase of 0x%03x\n",
+		      __FUNCTION__ , iobase);
+		return -ENODEV;
+	}
 
+	if (w83977af_probe(iobase, irq, dma) == -1) {
+		err = -1;
+		goto err_out;
+	}
 	/*
 	 *  Allocate new instance of the driver
 	 */
@@ -172,13 +176,12 @@
 	if (self == NULL) {
 		printk( KERN_ERR "IrDA: Can't allocate memory for "
 			"IrDA control block!\n");
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto err_out;
 	}
 	memset(self, 0, sizeof(struct w83977af_ir));
 	spin_lock_init(&self->lock);
    
-	/* Need to store self somewhere */
-	dev_self[i] = self;
 
 	/* Initialize IO */
 	self->io.fir_base   = iobase;
@@ -187,15 +190,6 @@
         self->io.dma       = dma;
         self->io.fifo_size = 32;
 
-	/* Lock the port that we need */
-	ret = request_region(self->io.fir_base, self->io.fir_ext, driver_name);
-	if (!ret) { 
-		IRDA_DEBUG(0, "%s(), can't get iobase of 0x%03x\n",
-		      __FUNCTION__ , self->io.fir_base);
-		/* w83977af_cleanup( self);  */
-		return -ENODEV;
-	}
-
 	/* Initialize QoS for this device */
 	irda_init_max_qos_capabilies(&self->qos);
 	
@@ -218,16 +212,18 @@
 	/* Allocate memory if needed */
 	self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
 					      GFP_KERNEL|GFP_DMA);
-	if (self->rx_buff.head == NULL)
-		return -ENOMEM;
+	if (self->rx_buff.head == NULL) {
+		err = -ENOMEM;
+		goto err_out1;
+	}
 
 	memset(self->rx_buff.head, 0, self->rx_buff.truesize);
 	
 	self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
 					      GFP_KERNEL|GFP_DMA);
 	if (self->tx_buff.head == NULL) {
-		kfree(self->rx_buff.head);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto err_out2;
 	}
 	memset(self->tx_buff.head, 0, self->tx_buff.truesize);
 
@@ -238,7 +234,8 @@
 	
 	if (!(dev = dev_alloc("irda%d", &err))) {
 		ERROR("%s(), dev_alloc() failed!\n", __FUNCTION__);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto err_out3;
 	}
 	dev->priv = (void *) self;
 	self->netdev = dev;
@@ -256,11 +253,24 @@
 	rtnl_unlock();
 	if (err) {
 		ERROR("%s(), register_netdevice() failed!\n", __FUNCTION__);
-		return -1;
+		err = -1;
+		goto err_out3;
 	}
 	MESSAGE("IrDA: Registered device %s\n", dev->name);
+
+	/* Need to store self somewhere */
+	dev_self[i] = self;
 	
 	return 0;
+err_out3:
+	kfree(self->tx_buff.head);
+err_out2:	
+	kfree(self->rx_buff.head);
+err_out1:
+	kfree(self);
+err_out:
+	release_region(iobase, CHIP_IO_EXTENT);
+	return err;
 }
 
 /*
diff -Nru a/drivers/net/lance.c b/drivers/net/lance.c
--- a/drivers/net/lance.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/net/lance.c	Mon Dec  9 18:46:34 2002
@@ -390,7 +390,7 @@
 static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int options)
 {
 	struct lance_private *lp;
-	short dma_channels;					/* Mark spuriously-busy DMA channels */
+	long dma_channels;			/* Mark spuriously-busy DMA channels */
 	int i, reset_val, lance_version;
 	const char *chipname;
 	/* Flags for specific chips or boards. */
diff -Nru a/drivers/net/ni52.c b/drivers/net/ni52.c
--- a/drivers/net/ni52.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/net/ni52.c	Mon Dec  9 18:46:38 2002
@@ -226,10 +226,11 @@
 	volatile struct iscp_struct	*iscp;	/* volatile is important */
 	volatile struct scb_struct	*scb;	/* volatile is important */
 	volatile struct tbd_struct	*xmit_buffs[NUM_XMIT_BUFFS];
-	volatile struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS];
 #if (NUM_XMIT_BUFFS == 1)
+	volatile struct transmit_cmd_struct *xmit_cmds[2];
 	volatile struct nop_cmd_struct *nop_cmds[2];
 #else
+	volatile struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS];
 	volatile struct nop_cmd_struct *nop_cmds[NUM_XMIT_BUFFS];
 #endif
 	volatile int		nop_point,num_recv_buffs;
diff -Nru a/drivers/net/ni65.c b/drivers/net/ni65.c
--- a/drivers/net/ni65.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/net/ni65.c	Mon Dec  9 18:46:35 2002
@@ -184,11 +184,41 @@
 	short addr_offset;
 	unsigned char *vendor_id;
 	char *cardname;
-	unsigned char config;
+	long config;
 } cards[] = {
-	{ NI65_ID0,NI65_ID1,0x0e,0x10,0x0,0x8,ni_vendor,"ni6510", 0x1 } ,
-	{ NI65_EB_ID0,NI65_EB_ID1,0x0e,0x18,0x10,0x0,ni_vendor,"ni6510 EtherBlaster", 0x2 } ,
-	{ NE2100_ID0,NE2100_ID1,0x0e,0x18,0x10,0x0,NULL,"generic NE2100", 0x0 }
+	{
+		.id0	     = NI65_ID0,
+		.id1	     = NI65_ID1,
+		.id_offset   = 0x0e,
+		.total_size  = 0x10,
+		.cmd_offset  = 0x0,
+		.addr_offset = 0x8,
+		.vendor_id   = ni_vendor,
+		.cardname    = "ni6510",
+		.config	     = 0x1,
+       	},
+	{
+		.id0	     = NI65_EB_ID0,
+		.id1	     = NI65_EB_ID1,
+		.id_offset   = 0x0e,
+		.total_size  = 0x18,
+		.cmd_offset  = 0x10,
+		.addr_offset = 0x0,
+		.vendor_id   = ni_vendor,
+		.cardname    = "ni6510 EtherBlaster",
+		.config	     = 0x2,
+       	},
+	{
+		.id0	     = NE2100_ID0,
+		.id1	     = NE2100_ID1,
+		.id_offset   = 0x0e,
+		.total_size  = 0x18,
+		.cmd_offset  = 0x10,
+		.addr_offset = 0x0,
+		.vendor_id   = NULL,
+		.cardname    = "generic NE2100",
+		.config	     = 0x0,
+	},
 };
 #define NUM_CARDS 3
 
@@ -415,7 +445,8 @@
 	else {
 		if(dev->dma == 0) {
 		/* 'stuck test' from lance.c */
-			int dma_channels = ((inb(DMA1_STAT_REG) >> 4) & 0x0f) | (inb(DMA2_STAT_REG) & 0xf0);
+			long dma_channels = ((inb(DMA1_STAT_REG) >> 4) & 0x0f) |
+					    (inb(DMA2_STAT_REG) & 0xf0);
 			for(i=1;i<5;i++) {
 				int dma = dmatab[i];
 				if(test_bit(dma,&dma_channels) || request_dma(dma,"ni6510"))
diff -Nru a/drivers/net/ns83820.c b/drivers/net/ns83820.c
--- a/drivers/net/ns83820.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/net/ns83820.c	Mon Dec  9 18:46:51 2002
@@ -1215,7 +1215,7 @@
 
 static int ns83820_ioctl(struct net_device *_dev, struct ifreq *rq, int cmd)
 {
-	struct ns83820 *dev = _dev->priv;
+	struct ns83820 *dev = (struct ns83820 *)_dev;
 
 	switch(cmd) {
 	case SIOCETHTOOL:
@@ -1788,6 +1788,7 @@
 	dev->ee.cache = &dev->MEAR_cache;
 	dev->ee.lock = &dev->misc_lock;
 	dev->net_dev.owner = THIS_MODULE;
+	dev->net_dev.priv = dev;
 
 	INIT_WORK(&dev->tq_refill, queue_refill, dev);
 	tasklet_init(&dev->rx_tasklet, rx_action, (unsigned long)dev);
diff -Nru a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
--- a/drivers/net/pcmcia/fmvj18x_cs.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/net/pcmcia/fmvj18x_cs.c	Mon Dec  9 18:46:50 2002
@@ -289,6 +289,7 @@
     link = &lp->link; dev = &lp->dev;
     link->priv = dev->priv = link->irq.Instance = lp;
 
+    init_timer(&link->release);
     link->release.function = &fmvj18x_release;
     link->release.data = (u_long)link;
 
diff -Nru a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
--- a/drivers/net/ppp_generic.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/net/ppp_generic.c	Mon Dec  9 18:46:51 2002
@@ -776,8 +776,6 @@
 
 #define PPP_MAJOR	108
 
-static devfs_handle_t devfs_handle;
-
 /* Called at boot time if ppp is compiled into the kernel,
    or at module load time (from init_module) if compiled as a module. */
 int __init ppp_init(void)
@@ -788,11 +786,8 @@
 	err = register_chrdev(PPP_MAJOR, "ppp", &ppp_device_fops);
 	if (err)
 		printk(KERN_ERR "failed to register PPP device (%d)\n", err);
-	devfs_handle = devfs_register(NULL, "ppp", DEVFS_FL_DEFAULT,
-				      PPP_MAJOR, 0,
-				      S_IFCHR | S_IRUSR | S_IWUSR,
-				      &ppp_device_fops, NULL);
-
+	devfs_register(NULL, "ppp", DEVFS_FL_DEFAULT, PPP_MAJOR, 0,
+		       S_IFCHR | S_IRUSR | S_IWUSR, &ppp_device_fops, NULL);
 	return 0;
 }
 
@@ -2511,7 +2506,7 @@
 	cardmap_destroy(&all_ppp_units);
 	if (unregister_chrdev(PPP_MAJOR, "ppp") != 0)
 		printk(KERN_ERR "PPP: failed to unregister PPP device\n");
-	devfs_unregister(devfs_handle);
+	devfs_remove("ppp");
 }
 
 /*
diff -Nru a/drivers/net/r8169.c b/drivers/net/r8169.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/net/r8169.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,1125 @@
+/*
+=========================================================================
+ r8169.c: A RealTek RTL-8169 Gigabit Ethernet driver for Linux kernel 2.4.x.
+ --------------------------------------------------------------------
+
+ History:
+ Feb  4 2002	- created initially by ShuChen <shuchen@realtek.com.tw>.
+ May 20 2002	- Add link status force-mode and TBI mode support.
+=========================================================================
+  1. The media can be forced in 5 modes.
+	 Command: 'insmod r8169 media = SET_MEDIA'
+	 Ex:	  'insmod r8169 media = 0x04' will force PHY to operate in 100Mpbs Half-duplex.
+	
+	 SET_MEDIA can be:
+ 		_10_Half	= 0x01
+ 		_10_Full	= 0x02
+ 		_100_Half	= 0x04
+ 		_100_Full	= 0x08
+ 		_1000_Full	= 0x10
+  
+  2. Support TBI mode.
+=========================================================================
+VERSION 1.1	<2002/10/4>
+
+	The bit4:0 of MII register 4 is called "selector field", and have to be
+	00001b to indicate support of IEEE std 802.3 during NWay process of
+	exchanging Link Code Word (FLP). 
+
+VERSION 1.2	<2002/11/30>
+
+	- Large style cleanup
+	- Use ether_crc in stock kernel (linux/crc32.h)
+	- Copy mc_filter setup code from 8139cp
+	  (includes an optimization, and avoids set_bit use)
+
+*/
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/delay.h>
+#include <linux/crc32.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+
+#define RTL8169_VERSION "1.2"
+#define MODULENAME "r8169"
+#define RTL8169_DRIVER_NAME   MODULENAME " Gigabit Ethernet driver " RTL8169_VERSION
+#define PFX MODULENAME ": "
+
+#ifdef RTL8169_DEBUG
+#define assert(expr) \
+        if(!(expr)) {					\
+	        printk( "Assertion failed! %s,%s,%s,line=%d\n",	\
+        	#expr,__FILE__,__FUNCTION__,__LINE__);		\
+        }
+#else
+#define assert(expr) do {} while (0)
+#endif
+
+/* media options */
+#define MAX_UNITS 8
+static int media[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
+
+/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
+static int max_interrupt_work = 20;
+
+/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
+   The RTL chips use a 64 element hash table based on the Ethernet CRC.  */
+static int multicast_filter_limit = 32;
+
+/* MAC address length*/
+#define MAC_ADDR_LEN	6
+
+/* max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4).*/
+#define MAX_ETH_FRAME_SIZE	1536
+
+#define TX_FIFO_THRESH 256	/* In bytes */
+
+#define RX_FIFO_THRESH	7	/* 7 means NO threshold, Rx buffer level before first PCI xfer.  */
+#define RX_DMA_BURST	6	/* Maximum PCI burst, '6' is 1024 */
+#define TX_DMA_BURST	6	/* Maximum PCI burst, '6' is 1024 */
+#define EarlyTxThld 	0x3F	/* 0x3F means NO early transmit */
+#define RxPacketMaxSize	0x0800	/* Maximum size supported is 16K-1 */
+#define InterFrameGap	0x03	/* 3 means InterFrameGap = the shortest one */
+
+#define NUM_TX_DESC	64	/* Number of Tx descriptor registers */
+#define NUM_RX_DESC	64	/* Number of Rx descriptor registers */
+#define RX_BUF_SIZE	1536	/* Rx Buffer size */
+
+#define RTL_MIN_IO_SIZE 0x80
+#define TX_TIMEOUT  (6*HZ)
+
+/* write/read MMIO register */
+#define RTL_W8(reg, val8)	writeb ((val8), ioaddr + (reg))
+#define RTL_W16(reg, val16)	writew ((val16), ioaddr + (reg))
+#define RTL_W32(reg, val32)	writel ((val32), ioaddr + (reg))
+#define RTL_R8(reg)		readb (ioaddr + (reg))
+#define RTL_R16(reg)		readw (ioaddr + (reg))
+#define RTL_R32(reg)		((unsigned long) readl (ioaddr + (reg)))
+
+static struct {
+	const char *name;
+} board_info[] __devinitdata = {
+	{
+"RealTek RTL8169 Gigabit Ethernet"},};
+
+static struct pci_device_id rtl8169_pci_tbl[] __devinitdata = {
+	{0x10ec, 0x8169, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0,},
+};
+
+MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl);
+
+enum RTL8169_registers {
+	MAC0 = 0,		/* Ethernet hardware address. */
+	MAR0 = 8,		/* Multicast filter. */
+	TxDescStartAddr = 0x20,
+	TxHDescStartAddr = 0x28,
+	FLASH = 0x30,
+	ERSR = 0x36,
+	ChipCmd = 0x37,
+	TxPoll = 0x38,
+	IntrMask = 0x3C,
+	IntrStatus = 0x3E,
+	TxConfig = 0x40,
+	RxConfig = 0x44,
+	RxMissed = 0x4C,
+	Cfg9346 = 0x50,
+	Config0 = 0x51,
+	Config1 = 0x52,
+	Config2 = 0x53,
+	Config3 = 0x54,
+	Config4 = 0x55,
+	Config5 = 0x56,
+	MultiIntr = 0x5C,
+	PHYAR = 0x60,
+	TBICSR = 0x64,
+	TBI_ANAR = 0x68,
+	TBI_LPAR = 0x6A,
+	PHYstatus = 0x6C,
+	RxMaxSize = 0xDA,
+	CPlusCmd = 0xE0,
+	RxDescStartAddr = 0xE4,
+	EarlyTxThres = 0xEC,
+	FuncEvent = 0xF0,
+	FuncEventMask = 0xF4,
+	FuncPresetState = 0xF8,
+	FuncForceEvent = 0xFC,
+};
+
+enum RTL8169_register_content {
+	/*InterruptStatusBits */
+	SYSErr = 0x8000,
+	PCSTimeout = 0x4000,
+	SWInt = 0x0100,
+	TxDescUnavail = 0x80,
+	RxFIFOOver = 0x40,
+	RxUnderrun = 0x20,
+	RxOverflow = 0x10,
+	TxErr = 0x08,
+	TxOK = 0x04,
+	RxErr = 0x02,
+	RxOK = 0x01,
+
+	/*RxStatusDesc */
+	RxRES = 0x00200000,
+	RxCRC = 0x00080000,
+	RxRUNT = 0x00100000,
+	RxRWT = 0x00400000,
+
+	/*ChipCmdBits */
+	CmdReset = 0x10,
+	CmdRxEnb = 0x08,
+	CmdTxEnb = 0x04,
+	RxBufEmpty = 0x01,
+
+	/*Cfg9346Bits */
+	Cfg9346_Lock = 0x00,
+	Cfg9346_Unlock = 0xC0,
+
+	/*rx_mode_bits */
+	AcceptErr = 0x20,
+	AcceptRunt = 0x10,
+	AcceptBroadcast = 0x08,
+	AcceptMulticast = 0x04,
+	AcceptMyPhys = 0x02,
+	AcceptAllPhys = 0x01,
+
+	/*RxConfigBits */
+	RxCfgFIFOShift = 13,
+	RxCfgDMAShift = 8,
+
+	/*TxConfigBits */
+	TxInterFrameGapShift = 24,
+	TxDMAShift = 8,		/* DMA burst value (0-7) is shift this many bits */
+
+	/*rtl8169_PHYstatus */
+	TBI_Enable = 0x80,
+	TxFlowCtrl = 0x40,
+	RxFlowCtrl = 0x20,
+	_1000bpsF = 0x10,
+	_100bps = 0x08,
+	_10bps = 0x04,
+	LinkStatus = 0x02,
+	FullDup = 0x01,
+
+	/*GIGABIT_PHY_registers */
+	PHY_CTRL_REG = 0,
+	PHY_STAT_REG = 1,
+	PHY_AUTO_NEGO_REG = 4,
+	PHY_1000_CTRL_REG = 9,
+
+	/*GIGABIT_PHY_REG_BIT */
+	PHY_Restart_Auto_Nego = 0x0200,
+	PHY_Enable_Auto_Nego = 0x1000,
+
+	//PHY_STAT_REG = 1;
+	PHY_Auto_Neco_Comp = 0x0020,
+
+	//PHY_AUTO_NEGO_REG = 4;
+	PHY_Cap_10_Half = 0x0020,
+	PHY_Cap_10_Full = 0x0040,
+	PHY_Cap_100_Half = 0x0080,
+	PHY_Cap_100_Full = 0x0100,
+
+	//PHY_1000_CTRL_REG = 9;
+	PHY_Cap_1000_Full = 0x0200,
+
+	PHY_Cap_Null = 0x0,
+
+	/*_MediaType*/
+	_10_Half = 0x01,
+	_10_Full = 0x02,
+	_100_Half = 0x04,
+	_100_Full = 0x08,
+	_1000_Full = 0x10,
+
+	/*_TBICSRBit*/
+	TBILinkOK = 0x02000000,
+};
+
+const static struct {
+	const char *name;
+	u8 version;		/* depend on RTL8169 docs */
+	u32 RxConfigMask;	/* should clear the bits supported by this chip */
+} rtl_chip_info[] = {
+	{
+"RTL-8169", 0x00, 0xff7e1880,},};
+
+enum _DescStatusBit {
+	OWNbit = 0x80000000,
+	EORbit = 0x40000000,
+	FSbit = 0x20000000,
+	LSbit = 0x10000000,
+};
+
+struct TxDesc {
+	u32 status;
+	u32 vlan_tag;
+	u32 buf_addr;
+	u32 buf_Haddr;
+};
+
+struct RxDesc {
+	u32 status;
+	u32 vlan_tag;
+	u32 buf_addr;
+	u32 buf_Haddr;
+};
+
+struct rtl8169_private {
+	void *mmio_addr;	/* memory map physical address */
+	struct pci_dev *pci_dev;	/* Index of PCI device  */
+	struct net_device_stats stats;	/* statistics of net device */
+	spinlock_t lock;	/* spin lock flag */
+	int chipset;
+	unsigned long cur_rx;	/* Index into the Rx descriptor buffer of next Rx pkt. */
+	unsigned long cur_tx;	/* Index into the Tx descriptor buffer of next Rx pkt. */
+	unsigned long dirty_tx;
+	unsigned char *TxDescArrays;	/* Index of Tx Descriptor buffer */
+	unsigned char *RxDescArrays;	/* Index of Rx Descriptor buffer */
+	struct TxDesc *TxDescArray;	/* Index of 256-alignment Tx Descriptor buffer */
+	struct RxDesc *RxDescArray;	/* Index of 256-alignment Rx Descriptor buffer */
+	unsigned char *RxBufferRings;	/* Index of Rx Buffer  */
+	unsigned char *RxBufferRing[NUM_RX_DESC];	/* Index of Rx Buffer array */
+	struct sk_buff *Tx_skbuff[NUM_TX_DESC];	/* Index of Transmit data buffer */
+};
+
+MODULE_AUTHOR("Realtek");
+MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
+MODULE_PARM(media, "1-" __MODULE_STRING(MAX_UNITS) "i");
+
+static int rtl8169_open(struct net_device *dev);
+static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static void rtl8169_interrupt(int irq, void *dev_instance,
+			      struct pt_regs *regs);
+static void rtl8169_init_ring(struct net_device *dev);
+static void rtl8169_hw_start(struct net_device *dev);
+static int rtl8169_close(struct net_device *dev);
+static void rtl8169_set_rx_mode(struct net_device *dev);
+static void rtl8169_tx_timeout(struct net_device *dev);
+static struct net_device_stats *rtl8169_get_stats(struct net_device *netdev);
+
+static const u16 rtl8169_intr_mask =
+    SYSErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver | TxErr | TxOK |
+    RxErr | RxOK;
+static const unsigned int rtl8169_rx_config =
+    (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
+
+void
+mdio_write(void *ioaddr, int RegAddr, int value)
+{
+	int i;
+
+	RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value);
+	udelay(1000);
+
+	for (i = 2000; i > 0; i--) {
+		// Check if the RTL8169 has completed writing to the specified MII register
+		if (!(RTL_R32(PHYAR) & 0x80000000)) {
+			break;
+		} else {
+			udelay(100);
+		}
+	}
+}
+
+int
+mdio_read(void *ioaddr, int RegAddr)
+{
+	int i, value = -1;
+
+	RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16);
+	udelay(1000);
+
+	for (i = 2000; i > 0; i--) {
+		// Check if the RTL8169 has completed retrieving data from the specified MII register
+		if (RTL_R32(PHYAR) & 0x80000000) {
+			value = (int) (RTL_R32(PHYAR) & 0xFFFF);
+			break;
+		} else {
+			udelay(100);
+		}
+	}
+	return value;
+}
+
+static int __devinit
+rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
+		   void **ioaddr_out)
+{
+	void *ioaddr = NULL;
+	struct net_device *dev;
+	struct rtl8169_private *tp;
+	int rc, i;
+	unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;
+	u32 tmp;
+
+	assert(pdev != NULL);
+	assert(ioaddr_out != NULL);
+
+	*ioaddr_out = NULL;
+	*dev_out = NULL;
+
+	// dev zeroed in init_etherdev 
+	dev = init_etherdev(NULL, sizeof (*tp));
+	if (dev == NULL) {
+		printk(KERN_ERR PFX "unable to alloc new ethernet\n");
+		return -ENOMEM;
+	}
+
+	SET_MODULE_OWNER(dev);
+	tp = dev->priv;
+
+	// enable device (incl. PCI PM wakeup and hotplug setup)
+	rc = pci_enable_device(pdev);
+	if (rc)
+		goto err_out;
+
+	mmio_start = pci_resource_start(pdev, 1);
+	mmio_end = pci_resource_end(pdev, 1);
+	mmio_flags = pci_resource_flags(pdev, 1);
+	mmio_len = pci_resource_len(pdev, 1);
+
+	// make sure PCI base addr 1 is MMIO
+	if (!(mmio_flags & IORESOURCE_MEM)) {
+		printk(KERN_ERR PFX
+		       "region #1 not an MMIO resource, aborting\n");
+		rc = -ENODEV;
+		goto err_out;
+	}
+	// check for weird/broken PCI region reporting
+	if (mmio_len < RTL_MIN_IO_SIZE) {
+		printk(KERN_ERR PFX "Invalid PCI region size(s), aborting\n");
+		rc = -ENODEV;
+		goto err_out;
+	}
+
+	rc = pci_request_regions(pdev, dev->name);
+	if (rc)
+		goto err_out;
+
+	// enable PCI bus-mastering
+	pci_set_master(pdev);
+
+	// ioremap MMIO region 
+	ioaddr = ioremap(mmio_start, mmio_len);
+	if (ioaddr == NULL) {
+		printk(KERN_ERR PFX "cannot remap MMIO, aborting\n");
+		rc = -EIO;
+		goto err_out_free_res;
+	}
+
+	// Soft reset the chip. 
+	RTL_W8(ChipCmd, CmdReset);
+
+	// Check that the chip has finished the reset.
+	for (i = 1000; i > 0; i--)
+		if ((RTL_R8(ChipCmd) & CmdReset) == 0)
+			break;
+		else
+			udelay(10);
+
+	// identify chip attached to board
+	tmp = RTL_R32(TxConfig);
+	tmp = ((tmp & 0x7c000000) + ((tmp & 0x00800000) << 2)) >> 24;
+
+	for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--)
+		if (tmp == rtl_chip_info[i].version) {
+			tp->chipset = i;
+			goto match;
+		}
+	//if unknown chip, assume array element #0, original RTL-8169 in this case
+	printk(KERN_DEBUG PFX
+	       "PCI device %s: unknown chip version, assuming RTL-8169\n",
+	       pdev->slot_name);
+	printk(KERN_DEBUG PFX "PCI device %s: TxConfig = 0x%lx\n",
+	       pdev->slot_name, (unsigned long) RTL_R32(TxConfig));
+	tp->chipset = 0;
+
+match:
+	*ioaddr_out = ioaddr;
+	*dev_out = dev;
+	return 0;
+
+err_out_free_res:
+	pci_release_regions(pdev);
+
+err_out:
+	unregister_netdev(dev);
+	kfree(dev);
+	return rc;
+}
+
+static int __devinit
+rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	struct net_device *dev = NULL;
+	struct rtl8169_private *tp = NULL;
+	void *ioaddr = NULL;
+	static int board_idx = -1;
+	static int printed_version = 0;
+	int i;
+	int option = -1, Cap10_100 = 0, Cap1000 = 0;
+
+	assert(pdev != NULL);
+	assert(ent != NULL);
+
+	board_idx++;
+
+	if (!printed_version) {
+		printk(KERN_INFO RTL8169_DRIVER_NAME " loaded\n");
+		printed_version = 1;
+	}
+
+	i = rtl8169_init_board(pdev, &dev, &ioaddr);
+	if (i < 0) {
+		return i;
+	}
+
+	tp = dev->priv;
+	assert(ioaddr != NULL);
+	assert(dev != NULL);
+	assert(tp != NULL);
+
+	// Get MAC address //
+	for (i = 0; i < MAC_ADDR_LEN; i++) {
+		dev->dev_addr[i] = RTL_R8(MAC0 + i);
+	}
+
+	dev->open = rtl8169_open;
+	dev->hard_start_xmit = rtl8169_start_xmit;
+	dev->get_stats = rtl8169_get_stats;
+	dev->stop = rtl8169_close;
+	dev->tx_timeout = rtl8169_tx_timeout;
+	dev->set_multicast_list = rtl8169_set_rx_mode;
+	dev->watchdog_timeo = TX_TIMEOUT;
+	dev->irq = pdev->irq;
+	dev->base_addr = (unsigned long) ioaddr;
+//      dev->do_ioctl           = mii_ioctl;
+
+	tp = dev->priv;		// private data //
+	tp->pci_dev = pdev;
+	tp->mmio_addr = ioaddr;
+
+	printk(KERN_DEBUG "%s: Identified chip type is '%s'.\n", dev->name,
+	       rtl_chip_info[tp->chipset].name);
+
+	spin_lock_init(&tp->lock);
+
+	pci_set_drvdata(pdev, dev);
+
+	printk(KERN_INFO "%s: %s at 0x%lx, "
+	       "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
+	       "IRQ %d\n",
+	       dev->name,
+	       board_info[ent->driver_data].name,
+	       dev->base_addr,
+	       dev->dev_addr[0], dev->dev_addr[1],
+	       dev->dev_addr[2], dev->dev_addr[3],
+	       dev->dev_addr[4], dev->dev_addr[5], dev->irq);
+
+	// if TBI is not endbled
+	if (!(RTL_R8(PHYstatus) & TBI_Enable)) {
+		int val = mdio_read(ioaddr, PHY_AUTO_NEGO_REG);
+
+		option = (board_idx >= MAX_UNITS) ? 0 : media[board_idx];
+		// Force RTL8169 in 10/100/1000 Full/Half mode.
+		if (option > 0) {
+			printk(KERN_INFO "%s: Force-mode Enabled.\n",
+			       dev->name);
+			Cap10_100 = 0, Cap1000 = 0;
+			switch (option) {
+			case _10_Half:
+				Cap10_100 = PHY_Cap_10_Half;
+				Cap1000 = PHY_Cap_Null;
+				break;
+			case _10_Full:
+				Cap10_100 = PHY_Cap_10_Full;
+				Cap1000 = PHY_Cap_Null;
+				break;
+			case _100_Half:
+				Cap10_100 = PHY_Cap_100_Half;
+				Cap1000 = PHY_Cap_Null;
+				break;
+			case _100_Full:
+				Cap10_100 = PHY_Cap_100_Full;
+				Cap1000 = PHY_Cap_Null;
+				break;
+			case _1000_Full:
+				Cap10_100 = PHY_Cap_Null;
+				Cap1000 = PHY_Cap_1000_Full;
+				break;
+			default:
+				break;
+			}
+			mdio_write(ioaddr, PHY_AUTO_NEGO_REG, Cap10_100 | (val & 0x1F));	//leave PHY_AUTO_NEGO_REG bit4:0 unchanged
+			mdio_write(ioaddr, PHY_1000_CTRL_REG, Cap1000);
+		} else {
+			printk(KERN_INFO "%s: Auto-negotiation Enabled.\n",
+			       dev->name);
+
+			// enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged
+			mdio_write(ioaddr, PHY_AUTO_NEGO_REG,
+				   PHY_Cap_10_Half | PHY_Cap_10_Full |
+				   PHY_Cap_100_Half | PHY_Cap_100_Full | (val &
+									  0x1F));
+
+			// enable 1000 Full Mode
+			mdio_write(ioaddr, PHY_1000_CTRL_REG,
+				   PHY_Cap_1000_Full);
+
+		}
+
+		// Enable auto-negotiation and restart auto-nigotiation
+		mdio_write(ioaddr, PHY_CTRL_REG,
+			   PHY_Enable_Auto_Nego | PHY_Restart_Auto_Nego);
+		udelay(100);
+
+		// wait for auto-negotiation process
+		for (i = 10000; i > 0; i--) {
+			//check if auto-negotiation complete
+			if (mdio_read(ioaddr, PHY_STAT_REG) &
+			    PHY_Auto_Neco_Comp) {
+				udelay(100);
+				option = RTL_R8(PHYstatus);
+				if (option & _1000bpsF) {
+					printk(KERN_INFO
+					       "%s: 1000Mbps Full-duplex operation.\n",
+					       dev->name);
+				} else {
+					printk(KERN_INFO
+					       "%s: %sMbps %s-duplex operation.\n",
+					       dev->name,
+					       (option & _100bps) ? "100" :
+					       "10",
+					       (option & FullDup) ? "Full" :
+					       "Half");
+				}
+				break;
+			} else {
+				udelay(100);
+			}
+		}		// end for-loop to wait for auto-negotiation process
+
+	} else {
+		udelay(100);
+		printk(KERN_INFO
+		       "%s: 1000Mbps Full-duplex operation, TBI Link %s!\n",
+		       dev->name,
+		       (RTL_R32(TBICSR) & TBILinkOK) ? "OK" : "Failed");
+
+	}
+
+	return 0;
+}
+
+static void __devexit
+rtl8169_remove_one(struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct rtl8169_private *tp = (struct rtl8169_private *) (dev->priv);
+
+	assert(dev != NULL);
+	assert(tp != NULL);
+
+	unregister_netdev(dev);
+	iounmap(tp->mmio_addr);
+	pci_release_regions(pdev);
+
+	// poison memory before freeing 
+	memset(dev, 0xBC,
+	       sizeof (struct net_device) + sizeof (struct rtl8169_private));
+
+	kfree(dev);
+	pci_set_drvdata(pdev, NULL);
+}
+
+static int
+rtl8169_open(struct net_device *dev)
+{
+	struct rtl8169_private *tp = dev->priv;
+	int retval;
+	u8 diff;
+	u32 TxPhyAddr, RxPhyAddr;
+
+	retval =
+	    request_irq(dev->irq, rtl8169_interrupt, SA_SHIRQ, dev->name, dev);
+	if (retval) {
+		return retval;
+	}
+
+	tp->TxDescArrays =
+	    kmalloc(NUM_TX_DESC * sizeof (struct TxDesc) + 256, GFP_KERNEL);
+	// Tx Desscriptor needs 256 bytes alignment;
+	TxPhyAddr = virt_to_bus(tp->TxDescArrays);
+	diff = 256 - (TxPhyAddr - ((TxPhyAddr >> 8) << 8));
+	TxPhyAddr += diff;
+	tp->TxDescArray = (struct TxDesc *) (tp->TxDescArrays + diff);
+
+	tp->RxDescArrays =
+	    kmalloc(NUM_RX_DESC * sizeof (struct RxDesc) + 256, GFP_KERNEL);
+	// Rx Desscriptor needs 256 bytes alignment;
+	RxPhyAddr = virt_to_bus(tp->RxDescArrays);
+	diff = 256 - (RxPhyAddr - ((RxPhyAddr >> 8) << 8));
+	RxPhyAddr += diff;
+	tp->RxDescArray = (struct RxDesc *) (tp->RxDescArrays + diff);
+
+	if (tp->TxDescArrays == NULL || tp->RxDescArrays == NULL) {
+		printk(KERN_INFO
+		       "Allocate RxDescArray or TxDescArray failed\n");
+		free_irq(dev->irq, dev);
+		if (tp->TxDescArrays)
+			kfree(tp->TxDescArrays);
+		if (tp->RxDescArrays)
+			kfree(tp->RxDescArrays);
+		return -ENOMEM;
+	}
+	tp->RxBufferRings = kmalloc(RX_BUF_SIZE * NUM_RX_DESC, GFP_KERNEL);
+	if (tp->RxBufferRings == NULL) {
+		printk(KERN_INFO "Allocate RxBufferRing failed\n");
+	}
+
+	rtl8169_init_ring(dev);
+	rtl8169_hw_start(dev);
+
+	return 0;
+
+}
+
+static void
+rtl8169_hw_start(struct net_device *dev)
+{
+	struct rtl8169_private *tp = dev->priv;
+	void *ioaddr = tp->mmio_addr;
+	u32 i;
+
+	/* Soft reset the chip. */
+	RTL_W8(ChipCmd, CmdReset);
+
+	/* Check that the chip has finished the reset. */
+	for (i = 1000; i > 0; i--) {
+		if ((RTL_R8(ChipCmd) & CmdReset) == 0)
+			break;
+		else
+			udelay(10);
+	}
+
+	RTL_W8(Cfg9346, Cfg9346_Unlock);
+	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
+	RTL_W8(EarlyTxThres, EarlyTxThld);
+
+	// For gigabit rtl8169
+	RTL_W16(RxMaxSize, RxPacketMaxSize);
+
+	// Set Rx Config register
+	i = rtl8169_rx_config | (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].
+				 RxConfigMask);
+	RTL_W32(RxConfig, i);
+
+	/* Set DMA burst size and Interframe Gap Time */
+	RTL_W32(TxConfig,
+		(TX_DMA_BURST << TxDMAShift) | (InterFrameGap <<
+						TxInterFrameGapShift));
+
+	tp->cur_rx = 0;
+
+	RTL_W32(TxDescStartAddr, virt_to_bus(tp->TxDescArray));
+	RTL_W32(RxDescStartAddr, virt_to_bus(tp->RxDescArray));
+	RTL_W8(Cfg9346, Cfg9346_Lock);
+	udelay(10);
+
+	RTL_W32(RxMissed, 0);
+
+	rtl8169_set_rx_mode(dev);
+
+	/* no early-rx interrupts */
+	RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
+
+	/* Enable all known interrupts by setting the interrupt mask. */
+	RTL_W16(IntrMask, rtl8169_intr_mask);
+
+	netif_start_queue(dev);
+
+}
+
+static void
+rtl8169_init_ring(struct net_device *dev)
+{
+	struct rtl8169_private *tp = dev->priv;
+	int i;
+
+	tp->cur_rx = 0;
+	tp->cur_tx = 0;
+	tp->dirty_tx = 0;
+	memset(tp->TxDescArray, 0x0, NUM_TX_DESC * sizeof (struct TxDesc));
+	memset(tp->RxDescArray, 0x0, NUM_RX_DESC * sizeof (struct RxDesc));
+
+	for (i = 0; i < NUM_TX_DESC; i++) {
+		tp->Tx_skbuff[i] = NULL;
+	}
+	for (i = 0; i < NUM_RX_DESC; i++) {
+		if (i == (NUM_RX_DESC - 1))
+			tp->RxDescArray[i].status =
+			    (OWNbit | EORbit) + RX_BUF_SIZE;
+		else
+			tp->RxDescArray[i].status = OWNbit + RX_BUF_SIZE;
+
+		tp->RxBufferRing[i] = &(tp->RxBufferRings[i * RX_BUF_SIZE]);
+		tp->RxDescArray[i].buf_addr = virt_to_bus(tp->RxBufferRing[i]);
+	}
+}
+
+static void
+rtl8169_tx_clear(struct rtl8169_private *tp)
+{
+	int i;
+
+	tp->cur_tx = 0;
+	for (i = 0; i < NUM_TX_DESC; i++) {
+		if (tp->Tx_skbuff[i] != NULL) {
+			dev_kfree_skb(tp->Tx_skbuff[i]);
+			tp->Tx_skbuff[i] = NULL;
+			tp->stats.tx_dropped++;
+		}
+	}
+}
+
+static void
+rtl8169_tx_timeout(struct net_device *dev)
+{
+	struct rtl8169_private *tp = dev->priv;
+	void *ioaddr = tp->mmio_addr;
+	u8 tmp8;
+
+	/* disable Tx, if not already */
+	tmp8 = RTL_R8(ChipCmd);
+	if (tmp8 & CmdTxEnb)
+		RTL_W8(ChipCmd, tmp8 & ~CmdTxEnb);
+
+	/* Disable interrupts by clearing the interrupt mask. */
+	RTL_W16(IntrMask, 0x0000);
+
+	/* Stop a shared interrupt from scavenging while we are. */
+	spin_lock_irq(&tp->lock);
+	rtl8169_tx_clear(tp);
+	spin_unlock_irq(&tp->lock);
+
+	/* ...and finally, reset everything */
+	rtl8169_hw_start(dev);
+
+	netif_wake_queue(dev);
+}
+
+static int
+rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct rtl8169_private *tp = dev->priv;
+	void *ioaddr = tp->mmio_addr;
+	int entry = tp->cur_tx % NUM_TX_DESC;
+
+	spin_lock_irq(&tp->lock);
+
+	if ((tp->TxDescArray[entry].status & OWNbit) == 0) {
+		tp->Tx_skbuff[entry] = skb;
+		tp->TxDescArray[entry].buf_addr = virt_to_bus(skb->data);
+		if (entry != (NUM_TX_DESC - 1))
+			tp->TxDescArray[entry].status =
+			    (OWNbit | FSbit | LSbit) | ((skb->len > ETH_ZLEN) ?
+							skb->len : ETH_ZLEN);
+		else
+			tp->TxDescArray[entry].status =
+			    (OWNbit | EORbit | FSbit | LSbit) |
+			    ((skb->len > ETH_ZLEN) ? skb->len : ETH_ZLEN);
+
+		RTL_W8(TxPoll, 0x40);	//set polling bit
+
+		dev->trans_start = jiffies;
+
+		tp->cur_tx++;
+	}
+
+	spin_unlock_irq(&tp->lock);
+
+	if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx) {
+		netif_stop_queue(dev);
+	}
+
+	return 0;
+}
+
+static void
+rtl8169_tx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
+		     void *ioaddr)
+{
+	unsigned long dirty_tx, tx_left = 0;
+	int entry = tp->cur_tx % NUM_TX_DESC;
+
+	assert(dev != NULL);
+	assert(tp != NULL);
+	assert(ioaddr != NULL);
+
+	dirty_tx = tp->dirty_tx;
+	tx_left = tp->cur_tx - dirty_tx;
+
+	while (tx_left > 0) {
+		if ((tp->TxDescArray[entry].status & OWNbit) == 0) {
+			dev_kfree_skb_irq(tp->
+					  Tx_skbuff[dirty_tx % NUM_TX_DESC]);
+			tp->Tx_skbuff[dirty_tx % NUM_TX_DESC] = NULL;
+			tp->stats.tx_packets++;
+			dirty_tx++;
+			tx_left--;
+			entry++;
+		}
+	}
+
+	if (tp->dirty_tx != dirty_tx) {
+		tp->dirty_tx = dirty_tx;
+		if (netif_queue_stopped(dev))
+			netif_wake_queue(dev);
+	}
+}
+
+static void
+rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
+		     void *ioaddr)
+{
+	int cur_rx;
+	struct sk_buff *skb;
+	int pkt_size = 0;
+
+	assert(dev != NULL);
+	assert(tp != NULL);
+	assert(ioaddr != NULL);
+
+	cur_rx = tp->cur_rx;
+
+	while ((tp->RxDescArray[cur_rx].status & OWNbit) == 0) {
+
+		if (tp->RxDescArray[cur_rx].status & RxRES) {
+			printk(KERN_INFO "%s: Rx ERROR!!!\n", dev->name);
+			tp->stats.rx_errors++;
+			if (tp->RxDescArray[cur_rx].status & (RxRWT | RxRUNT))
+				tp->stats.rx_length_errors++;
+			if (tp->RxDescArray[cur_rx].status & RxCRC)
+				tp->stats.rx_crc_errors++;
+		} else {
+			pkt_size =
+			    (int) (tp->RxDescArray[cur_rx].
+				   status & 0x00001FFF) - 4;
+			skb = dev_alloc_skb(pkt_size + 2);
+			if (skb != NULL) {
+				skb->dev = dev;
+				skb_reserve(skb, 2);	// 16 byte align the IP fields. //
+				eth_copy_and_sum(skb, tp->RxBufferRing[cur_rx],
+						 pkt_size, 0);
+				skb_put(skb, pkt_size);
+				skb->protocol = eth_type_trans(skb, dev);
+				netif_rx(skb);
+
+				if (cur_rx == (NUM_RX_DESC - 1))
+					tp->RxDescArray[cur_rx].status =
+					    (OWNbit | EORbit) + RX_BUF_SIZE;
+				else
+					tp->RxDescArray[cur_rx].status =
+					    OWNbit + RX_BUF_SIZE;
+
+				tp->RxDescArray[cur_rx].buf_addr =
+				    virt_to_bus(tp->RxBufferRing[cur_rx]);
+				dev->last_rx = jiffies;
+				tp->stats.rx_bytes += pkt_size;
+				tp->stats.rx_packets++;
+			} else {
+				printk(KERN_WARNING
+				       "%s: Memory squeeze, deferring packet.\n",
+				       dev->name);
+				/* We should check that some rx space is free.
+				   If not, free one and mark stats->rx_dropped++. */
+				tp->stats.rx_dropped++;
+			}
+		}
+
+		cur_rx = (cur_rx + 1) % NUM_RX_DESC;
+
+	}
+
+	tp->cur_rx = cur_rx;
+}
+
+/* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */
+static void
+rtl8169_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *) dev_instance;
+	struct rtl8169_private *tp = dev->priv;
+	int boguscnt = max_interrupt_work;
+	void *ioaddr = tp->mmio_addr;
+	int status = 0;
+
+	do {
+		status = RTL_R16(IntrStatus);
+
+		/* h/w no longer present (hotplug?) or major error, bail */
+		if (status == 0xFFFF)
+			break;
+
+/*
+		if (status & RxUnderrun)
+			link_changed = RTL_R16 (CSCR) & CSCR_LinkChangeBit;
+*/
+		RTL_W16(IntrStatus,
+			(status & RxFIFOOver) ? (status | RxOverflow) : status);
+
+		if ((status &
+		     (SYSErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver
+		      | TxErr | TxOK | RxErr | RxOK)) == 0)
+			break;
+
+		// Rx interrupt 
+		if (status & (RxOK | RxUnderrun | RxOverflow | RxFIFOOver)) {
+			rtl8169_rx_interrupt(dev, tp, ioaddr);
+		}
+		// Tx interrupt
+		if (status & (TxOK | TxErr)) {
+			spin_lock(&tp->lock);
+			rtl8169_tx_interrupt(dev, tp, ioaddr);
+			spin_unlock(&tp->lock);
+		}
+
+		boguscnt--;
+	} while (boguscnt > 0);
+
+	if (boguscnt <= 0) {
+		printk(KERN_WARNING "%s: Too much work at interrupt!\n",
+		       dev->name);
+		/* Clear all interrupt sources. */
+		RTL_W16(IntrStatus, 0xffff);
+	}
+}
+
+static int
+rtl8169_close(struct net_device *dev)
+{
+	struct rtl8169_private *tp = dev->priv;
+	void *ioaddr = tp->mmio_addr;
+	int i;
+
+	netif_stop_queue(dev);
+
+	spin_lock_irq(&tp->lock);
+
+	/* Stop the chip's Tx and Rx DMA processes. */
+	RTL_W8(ChipCmd, 0x00);
+
+	/* Disable interrupts by clearing the interrupt mask. */
+	RTL_W16(IntrMask, 0x0000);
+
+	/* Update the error counts. */
+	tp->stats.rx_missed_errors += RTL_R32(RxMissed);
+	RTL_W32(RxMissed, 0);
+
+	spin_unlock_irq(&tp->lock);
+
+	synchronize_irq(dev->irq);
+	free_irq(dev->irq, dev);
+
+	rtl8169_tx_clear(tp);
+	kfree(tp->TxDescArrays);
+	kfree(tp->RxDescArrays);
+	tp->TxDescArrays = NULL;
+	tp->RxDescArrays = NULL;
+	tp->TxDescArray = NULL;
+	tp->RxDescArray = NULL;
+	kfree(tp->RxBufferRings);
+	for (i = 0; i < NUM_RX_DESC; i++) {
+		tp->RxBufferRing[i] = NULL;
+	}
+
+	return 0;
+}
+
+static void
+rtl8169_set_rx_mode(struct net_device *dev)
+{
+	struct rtl8169_private *tp = dev->priv;
+	void *ioaddr = tp->mmio_addr;
+	unsigned long flags;
+	u32 mc_filter[2];	/* Multicast hash filter */
+	int i, rx_mode;
+	u32 tmp = 0;
+
+	if (dev->flags & IFF_PROMISC) {
+		/* Unconditionally log net taps. */
+		printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n",
+		       dev->name);
+		rx_mode =
+		    AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
+		    AcceptAllPhys;
+		mc_filter[1] = mc_filter[0] = 0xffffffff;
+	} else if ((dev->mc_count > multicast_filter_limit)
+		   || (dev->flags & IFF_ALLMULTI)) {
+		/* Too many to filter perfectly -- accept all multicasts. */
+		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
+		mc_filter[1] = mc_filter[0] = 0xffffffff;
+	} else {
+		struct dev_mc_list *mclist;
+		rx_mode = AcceptBroadcast | AcceptMyPhys;
+		mc_filter[1] = mc_filter[0] = 0;
+		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
+		     i++, mclist = mclist->next) {
+			int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
+			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
+			rx_mode |= AcceptMulticast;
+		}
+	}
+
+	spin_lock_irqsave(&tp->lock, flags);
+
+	tmp =
+	    rtl8169_rx_config | rx_mode | (RTL_R32(RxConfig) &
+					   rtl_chip_info[tp->chipset].
+					   RxConfigMask);
+
+	RTL_W32(RxConfig, tmp);
+	RTL_W32(MAR0 + 0, mc_filter[0]);
+	RTL_W32(MAR0 + 4, mc_filter[1]);
+
+	spin_unlock_irqrestore(&tp->lock, flags);
+}
+
+struct net_device_stats *
+rtl8169_get_stats(struct net_device *dev)
+{
+	struct rtl8169_private *tp = dev->priv;
+
+	return &tp->stats;
+}
+
+static struct pci_driver rtl8169_pci_driver = {
+	.name		= MODULENAME,
+	.id_table	= rtl8169_pci_tbl,
+	.probe		= rtl8169_init_one,
+	.remove		= rtl8169_remove_one,
+	.suspend	= NULL,
+	.resume		= NULL,
+};
+
+static int __init
+rtl8169_init_module(void)
+{
+	return pci_module_init(&rtl8169_pci_driver);
+}
+
+static void __exit
+rtl8169_cleanup_module(void)
+{
+	pci_unregister_driver(&rtl8169_pci_driver);
+}
+
+module_init(rtl8169_init_module);
+module_exit(rtl8169_cleanup_module);
diff -Nru a/drivers/net/rcpci45.c b/drivers/net/rcpci45.c
--- a/drivers/net/rcpci45.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/net/rcpci45.c	Mon Dec  9 18:46:50 2002
@@ -29,6 +29,9 @@
 **  along with this program; if not, write to the Free Software
 **  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 **
+**  Pete Popov, Oct 2001: Fixed a few bugs to make the driver functional
+**  again. Note that this card is not supported or manufactured by 
+**  RedCreek anymore.
 **   
 **  Rasmus Andersen, December 2000: Converted to new PCI API and general
 **  cleanup.
@@ -63,7 +66,7 @@
 #include <asm/uaccess.h>
 
 static char version[] __initdata =
-    "RedCreek Communications PCI linux driver version 2.03\n";
+    "RedCreek Communications PCI linux driver version 2.20\n";
 
 #define RC_LINUX_MODULE
 #include "rclanmtl.h"
@@ -88,6 +91,14 @@
 /* RedCreek's OSM default LAN receive Initiator */
 #define DEFAULT_RECV_INIT_CONTEXT  0xA17
 
+/* minimum msg buffer size needed by the card 
+ * Note that the size of this buffer is hard code in the
+ * ipsec card's firmware. Thus, the size MUST be a minimum
+ * of 16K. Otherwise the card will end up using memory
+ * that does not belong to it.
+ */
+#define MSG_BUF_SIZE  16384
+
 static U32 DriverControlWord;
 
 static void rc_timer (unsigned long);
@@ -119,39 +130,25 @@
 	PDPA pDpa = dev->priv;
 
 	if (!dev) {
-		printk (KERN_ERR
-			"(rcpci45 driver:) remove non-existent device\n");
+		printk (KERN_ERR "%s: remove non-existent device\n",
+				dev->name);
 		return;
 	}
 
-	dprintk ("remove_one: IOP reset: 0x%x\n", RCResetIOP (dev));
-
-	/* RAA Inspired by starfire.c and yellowfin.c we keep these
-	 * here. */
+	RCResetIOP (dev);
 	unregister_netdev (dev);
 	free_irq (dev->irq, dev);
 	iounmap ((void *) dev->base_addr);
 	pci_release_regions (pdev);
-	kfree (pDpa->PLanApiPA);
-	kfree (pDpa->pPab);
-	kfree (pDpa);
+	if (pDpa->msgbuf)
+		kfree (pDpa->msgbuf);
+	if (pDpa->pPab)
+		kfree (pDpa->pPab);
 	kfree (dev);
 	pci_set_drvdata (pdev, NULL);
 }
 
 static int
-RCinit (struct net_device *dev)
-{
-	dev->open = &RCopen;
-	dev->hard_start_xmit = &RC_xmit_packet;
-	dev->stop = &RCclose;
-	dev->get_stats = &RCget_stats;
-	dev->do_ioctl = &RCioctl;
-	dev->set_config = &RCconfig;
-	return 0;
-}
-
-static int
 rcpci45_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	unsigned long *vaddr;
@@ -165,17 +162,17 @@
 
 	/* 
 	 * Allocate and fill new device structure. 
-	 * We need enough for struct net_device plus DPA plus the LAN API private
-	 * area, which requires a minimum of 16KB.  The top of the allocated
-	 * area will be assigned to struct net_device; the next chunk will be
-	 * assigned to DPA; and finally, the rest will be assigned to the
-	 * the LAN API layer.
+	 * We need enough for struct net_device plus DPA plus the LAN 
+	 * API private area, which requires a minimum of 16KB.  The top 
+	 * of the allocated area will be assigned to struct net_device; 
+	 * the next chunk will be assigned to DPA; and finally, the rest 
+	 * will be assigned to the LAN API layer.
 	 */
 
 	dev = init_etherdev (NULL, sizeof (*pDpa));
 	if (!dev) {
 		printk (KERN_ERR
-			"(rcpci45 driver:) unable to allocate in init_etherdev\n");
+			"(rcpci45 driver:) init_etherdev alloc failed\n");
 		error = -ENOMEM;
 		goto err_out;
 	}
@@ -183,13 +180,14 @@
 	error = pci_enable_device (pdev);
 	if (error) {
 		printk (KERN_ERR
-			"(rcpci45 driver:) %d: unable to enable pci device, aborting\n",
+			"(rcpci45 driver:) %d: pci enable device error\n",
 			card_idx);
 		goto err_out;
 	}
 	error = -ENOMEM;
 	pci_start = pci_resource_start (pdev, 0);
 	pci_len = pci_resource_len (pdev, 0);
+	printk("pci_start %lx pci_len %lx\n", pci_start, pci_len);
 
 	pci_set_drvdata (pdev, dev);
 
@@ -199,29 +197,30 @@
 
 	if (!pci_start || !(pci_resource_flags (pdev, 0) & IORESOURCE_MEM)) {
 		printk (KERN_ERR
-			"(rcpci45 driver:) No PCI memory resources! Aborting.\n");
+			"(rcpci45 driver:) No PCI mem resources! Aborting\n");
 		error = -EBUSY;
 		goto err_out_free_dev;
 	}
 
 	/*
-	 * Save the starting address of the LAN API private area.  We'll
-	 * pass that to RCInitI2OMsgLayer().
+	 * pDpa->msgbuf is where the card will dma the I2O 
+	 * messages. Thus, we need contiguous physical pages of
+	 * memory.
 	 */
-	/* RAA FIXME: This size should be a #define somewhere after I
-	 * clear up some questions: What flags are neeeded in the alloc below
-	 * and what needs to be done before the memarea is long word aligned?
-	 * (Look in old code for an approach.) (Also note that the 16K below
-	 * is substantially less than the 32K allocated before (even though
-	 * some of the spacce was used for data structures.) */
-	pDpa->msgbuf = kmalloc (16384, GFP_KERNEL);
+	pDpa->msgbuf = kmalloc (MSG_BUF_SIZE, GFP_DMA|GFP_ATOMIC|GFP_KERNEL);
 	if (!pDpa->msgbuf) {
-		printk (KERN_ERR "(rcpci45 driver:) Could not allocate %d byte memory for the private msgbuf!\n", 16384);	/* RAA FIXME not hardcoded! */
+		printk (KERN_ERR "(rcpci45 driver:) \
+			Could not allocate %d byte memory for the \
+				private msgbuf!\n", MSG_BUF_SIZE);
 		goto err_out_free_dev;
 	}
-	pDpa->PLanApiPA = (void *) (((long) pDpa->msgbuf + 0xff) & ~0xff);
 
-	dprintk ("pDpa->PLanApiPA = %p\n", pDpa->PLanApiPA);
+	/*
+	 * Save the starting address of the LAN API private area.  We'll
+	 * pass that to RCInitI2OMsgLayer().
+	 *
+	 */
+	pDpa->PLanApiPA = (void *) (((long) pDpa->msgbuf + 0xff) & ~0xff);
 
 	/* The adapter is accessible through memory-access read/write, not
 	 * I/O read/write.  Thus, we need to map it to some virtual address
@@ -234,17 +233,20 @@
 	vaddr = (ulong *) ioremap (pci_start, pci_len);
 	if (!vaddr) {
 		printk (KERN_ERR
-			"(rcpci45 driver:) Unable to remap address range from %lu to %lu\n",
+			"(rcpci45 driver:) \
+			Unable to remap address range from %lu to %lu\n",
 			pci_start, pci_start + pci_len);
 		goto err_out_free_region;
 	}
 
-	dprintk ("rcpci45_init_one: 0x%x, priv = 0x%x, vaddr = 0x%x\n",
-		 (uint) dev, (uint) dev->priv, (uint) vaddr);
 	dev->base_addr = (unsigned long) vaddr;
 	dev->irq = pdev->irq;
-
-	dev->init = &RCinit;
+	dev->open = &RCopen;
+	dev->hard_start_xmit = &RC_xmit_packet;
+	dev->stop = &RCclose;
+	dev->get_stats = &RCget_stats;
+	dev->do_ioctl = &RCioctl;
+	dev->set_config = &RCconfig;
 
 	return 0;		/* success */
 
@@ -257,7 +259,7 @@
 	kfree (dev);
 err_out:
 	card_idx--;
-	return error;
+	return -ENODEV;
 }
 
 static struct pci_driver rcpci45_driver = {
@@ -271,9 +273,8 @@
 rcpci_init_module (void)
 {
 	int rc = pci_module_init (&rcpci45_driver);
-
 	if (!rc)
-		printk (KERN_INFO "%s", version);
+		printk (KERN_ERR "%s", version);
 	return rc;
 }
 
@@ -286,56 +287,56 @@
 	int requested = 0;
 	int error;
 
-	dprintk ("(rcpci45 driver:) RCopen\n");
+	MOD_INC_USE_COUNT;
+	if (pDpa->nexus) {
+		/* This is not the first time RCopen is called.  Thus,
+		 * the interface was previously opened and later closed
+		 * by RCclose().  RCclose() does a Shutdown; to wake up
+		 * the adapter, a reset is mandatory before we can post
+		 * receive buffers.  However, if the adapter initiated 
+		 * a reboot while the interface was closed -- and interrupts
+		 * were turned off -- we need will need to reinitialize
+		 * the adapter, rather than simply waking it up.  
+		 */
+		printk (KERN_INFO "Waking up adapter...\n");
+		RCResetLANCard (dev, 0, 0, 0);
+	} else {
+		pDpa->nexus = 1;
+		/* 
+		 * RCInitI2OMsgLayer is done only once, unless the
+		 * adapter was sent a warm reboot
+		 */
+		error = RCInitI2OMsgLayer (dev, (PFNTXCALLBACK) RCxmit_callback,
+					   (PFNRXCALLBACK) RCrecv_callback,
+					   (PFNCALLBACK) RCreboot_callback);
+		if (error) {
+			printk (KERN_ERR "%s: Unable to init msg layer (%x)\n",
+					dev->name, error);
+			goto err_out;
+		}
+		if ((error = RCGetMAC (dev, NULL))) {
+			printk (KERN_ERR "%s: Unable to get adapter MAC\n",
+					dev->name);
+			goto err_out;
+		}
+	}
 
 	/* Request a shared interrupt line. */
 	error = request_irq (dev->irq, RCinterrupt, SA_SHIRQ, dev->name, dev);
 	if (error) {
-		printk (KERN_ERR "(rcpci45 driver:) %s: unable to get IRQ %d\n",
-			dev->name, dev->irq);
+		printk (KERN_ERR "%s: unable to get IRQ %d\n", 
+				dev->name, dev->irq);
 		goto err_out;
 	}
 
-	error = RCInitI2OMsgLayer (dev, (PFNTXCALLBACK) RCxmit_callback,
-				   (PFNRXCALLBACK) RCrecv_callback,
-				   (PFNCALLBACK) RCreboot_callback);
-	if (error) {
-		printk (KERN_ERR
-			"(rcpci45 driver:) Unable to initialize msg layer\n");
-		goto err_out_free_irq;
-	}
-	if ((error = RCGetMAC (dev, NULL))) {
-		printk (KERN_ERR
-			"(rcpci45 driver:) Unable to get adapter MAC\n");
-		goto err_out_free_irq;
-	}
-
 	DriverControlWord |= WARM_REBOOT_CAPABLE;
 	RCReportDriverCapability (dev, DriverControlWord);
 
 	printk (KERN_INFO "%s: RedCreek Communications IPSEC VPN adapter\n",
 		dev->name);
 
-	/* RAA: Old RCopen starts here */
 	RCEnableI2OInterrupts (dev);
 
-	/* RAA Hmm, how does the comment below jibe with the newly imported
-	 * code above? A FIXME!!*/
-	if (pDpa->nexus) {
-		/* This is not the first time RCopen is called.  Thus,
-		 * the interface was previously opened and later closed
-		 * by RCclose().  RCclose() does a Shutdown; to wake up
-		 * the adapter, a reset is mandatory before we can post
-		 * receive buffers.  However, if the adapter initiated 
-		 * a reboot while the interface was closed -- and interrupts
-		 * were turned off -- we need will need to reinitialize
-		 * the adapter, rather than simply waking it up.  
-		 */
-		dprintk (KERN_INFO "Waking up adapter...\n");
-		RCResetLANCard (dev, 0, 0, 0);
-	} else
-		pDpa->nexus = 1;
-
 	while (post_buffers) {
 		if (post_buffers > MAX_NMBR_POST_BUFFERS_PER_MSG)
 			requested = MAX_NMBR_POST_BUFFERS_PER_MSG;
@@ -345,29 +346,30 @@
 
 		if (count < requested) {
 			/*
-			 * Check to see if we were able to post any buffers at all.
+			 * Check to see if we were able to post 
+			 * any buffers at all.
 			 */
 			if (post_buffers == MAX_NMBR_RCV_BUFFERS) {
-				printk (KERN_ERR
-					"(rcpci45 driver:) Error RCopen: not able to allocate any buffers\r\n");
-				return (-ENOMEM);
+				printk (KERN_ERR "%s: \
+					unable to allocate any buffers\n", 
+						dev->name);
+				goto err_out_free_irq;
 			}
-			printk (KERN_WARNING
-				"(rcpci45 driver:) Warning RCopen: not able to allocate all requested buffers\r\n");
+			printk (KERN_WARNING "%s: \
+			unable to allocate all requested buffers\n", dev->name);
 			break;	/* we'll try to post more buffers later */
 		} else
 			post_buffers -= count;
 	}
 	pDpa->numOutRcvBuffers = MAX_NMBR_RCV_BUFFERS - post_buffers;
 	pDpa->shutdown = 0;	/* just in case */
-	dprintk ("RCopen: posted %d buffers\n", (uint) pDpa->numOutRcvBuffers);
-	MOD_INC_USE_COUNT;
 	netif_start_queue (dev);
 	return 0;
 
 err_out_free_irq:
 	free_irq (dev->irq, dev);
 err_out:
+	MOD_DEC_USE_COUNT;
 	return error;
 }
 
@@ -383,15 +385,16 @@
 	netif_stop_queue (dev);
 
 	if (pDpa->shutdown || pDpa->reboot) {
-		dprintk ("RC_xmit_packet: tbusy!\n");
+		printk ("RC_xmit_packet: tbusy!\n");
 		return 1;
 	}
 
 	/*
-	 * The user is free to reuse the TCB after RCI2OSendPacket() returns, since
-	 * the function copies the necessary info into its own private space.  Thus,
-	 * our TCB can be a local structure.  The skb, on the other hand, will be
-	 * freed up in our interrupt handler.
+	 * The user is free to reuse the TCB after RCI2OSendPacket() 
+	 * returns, since the function copies the necessary info into its 
+	 * own private space.  Thus, our TCB can be a local structure.  
+	 * The skb, on the other hand, will be freed up in our interrupt 
+	 * handler.
 	 */
 
 	ptcb->bcount = 1;
@@ -405,11 +408,9 @@
 	ptcb->b.size = skb->len;
 	ptcb->b.addr = virt_to_bus ((void *) skb->data);
 
-	dprintk ("RC xmit: skb = 0x%x, pDpa = 0x%x, id = %d, ptcb = 0x%x\n",
-		 (uint) skb, (uint) pDpa, (uint) pDpa->id, (uint) ptcb);
 	if ((status = RCI2OSendPacket (dev, (U32) NULL, (PRCTCB) ptcb))
 	    != RC_RTN_NO_ERROR) {
-		dprintk ("RC send error 0x%x\n", (uint) status);
+		printk ("%s: send error 0x%x\n", dev->name, (uint) status);
 		return 1;
 	} else {
 		dev->trans_start = jiffies;
@@ -439,23 +440,20 @@
 	PDPA pDpa = dev->priv;
 
 	if (!pDpa) {
-		printk (KERN_ERR
-			"(rcpci45 driver:) Fatal error: xmit callback, !pDpa\n");
+		printk (KERN_ERR "%s: Fatal Error in xmit callback, !pDpa\n",
+				dev->name);
 		return;
 	}
 
-/*      dprintk("xmit_callback: Status = 0x%x\n", (uint)Status); */
 	if (Status != I2O_REPLY_STATUS_SUCCESS)
-		dprintk ("xmit_callback: Status = 0x%x\n", (uint) Status);
+		printk (KERN_INFO "%s: xmit_callback: Status = 0x%x\n", 
+				dev->name, (uint) Status);
 	if (pDpa->shutdown || pDpa->reboot)
-		dprintk ("xmit callback: shutdown||reboot\n");
-
-	dprintk ("xmit_callback: PcktCount = %d, BC = 0x%x\n",
-		 (uint) PcktCount, (uint) BufferContext);
+		printk (KERN_INFO "%s: xmit callback: shutdown||reboot\n",
+				dev->name);
 
 	while (PcktCount--) {
 		skb = (struct sk_buff *) (BufferContext[0]);
-		dprintk ("skb = 0x%x\n", (uint) skb);
 		BufferContext++;
 		dev_kfree_skb_irq (skb);
 	}
@@ -467,19 +465,18 @@
 {
 	PDPA pDpa = dev->priv;
 
-	dprintk ("RCreset_callback Status 0x%x\n", (uint) Status);
+	printk ("RCreset_callback Status 0x%x\n", (uint) Status);
 	/*
 	 * Check to see why we were called.
 	 */
 	if (pDpa->shutdown) {
-		printk (KERN_INFO
-			"(rcpci45 driver:) Shutting down interface\n");
+		printk (KERN_INFO "%s: shutting down interface\n",
+				dev->name);
 		pDpa->shutdown = 0;
 		pDpa->reboot = 0;
-		MOD_DEC_USE_COUNT;
 	} else if (pDpa->reboot) {
-		printk (KERN_INFO
-			"(rcpci45 driver:) reboot, shutdown adapter\n");
+		printk (KERN_INFO "%s: reboot, shutdown adapter\n",
+				dev->name);
 		/*
 		 * We don't set any of the flags in RCShutdownLANCard()
 		 * and we don't pass a callback routine to it.
@@ -488,7 +485,7 @@
 		 */
 		RCDisableI2OInterrupts (dev);
 		RCShutdownLANCard (dev, 0, 0, 0);
-		printk (KERN_INFO "(rcpci45 driver:) scheduling timer...\n");
+		printk (KERN_INFO "%s: scheduling timer...\n", dev->name);
 		init_timer (&pDpa->timer);
 		pDpa->timer.expires = RUN_AT ((40 * HZ) / 10);	/* 4 sec. */
 		pDpa->timer.data = (unsigned long) dev;
@@ -502,12 +499,12 @@
 {
 	PDPA pDpa = dev->priv;
 
-	dprintk ("RCreboot: rcv buffers outstanding = %d\n",
-		 (uint) pDpa->numOutRcvBuffers);
+	printk (KERN_INFO "%s: reboot: rcv buffers outstanding = %d\n",
+		 dev->name, (uint) pDpa->numOutRcvBuffers);
 
 	if (pDpa->shutdown) {
-		printk (KERN_INFO
-			"(rcpci45 driver:) skipping reboot sequence -- shutdown already initiated\n");
+		printk (KERN_INFO "%s: skip reboot, shutdown initiated\n",
+				dev->name);
 		return;
 	}
 	pDpa->reboot = 1;
@@ -559,12 +556,9 @@
 
 	ptcb->bcount = 1;
 
-	dprintk ("RCrecv_callback: 0x%x, 0x%x, 0x%x\n",
-		 (uint) PktCount, (uint) BucketsRemain, (uint) PacketDescBlock);
-
 	if ((pDpa->shutdown || pDpa->reboot) && !Status)
-		dprintk ("shutdown||reboot && !Status: PktCount = %d\n",
-			 PktCount);
+		printk (KERN_INFO "%s: shutdown||reboot && !Status (%d)\n",
+				dev->name, PktCount);
 
 	if ((Status != I2O_REPLY_STATUS_SUCCESS) || pDpa->shutdown) {
 		/*
@@ -573,76 +567,38 @@
 		 */
 
 		if (!pDpa->shutdown && !pDpa->reboot)
-			printk (KERN_INFO
-				"(rcpci45 driver:) RCrecv error: status = 0x%x\n",
-				(uint) Status);
+			printk (KERN_INFO "%s: recv error status = 0x%x\n",
+					dev->name, (uint) Status);
 		else
-			dprintk ("Returning %d buffers, status = 0x%x\n",
-				 PktCount, (uint) Status);
+			printk (KERN_DEBUG "%s: Returning %d buffs stat 0x%x\n",
+					dev->name, PktCount, (uint) Status);
 		/*
-		 * TO DO: check the nature of the failure and put the adapter in
-		 * failed mode if it's a hard failure.  Send a reset to the adapter
-		 * and free all outstanding memory.
+		 * TO DO: check the nature of the failure and put the 
+		 * adapter in failed mode if it's a hard failure.  
+		 * Send a reset to the adapter and free all outstanding memory.
 		 */
-		if (Status == I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER)
-			dprintk ("RCrecv status ABORT NO DATA TRANSFER\n");
-
-		/* check for reset status: I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER */
 		if (PacketDescBlock) {
 			while (PktCount--) {
 				skb = (struct sk_buff *) PacketDescBlock[0];
-				dprintk ("free skb 0x%p\n", skb);
 				dev_kfree_skb (skb);
 				pDpa->numOutRcvBuffers--;
-				PacketDescBlock += BD_SIZE;	/* point to next context field */
+				/* point to next context field */
+				PacketDescBlock += BD_SIZE;
 			}
 		}
 		return;
 	} else {
 		while (PktCount--) {
 			skb = (struct sk_buff *) PacketDescBlock[0];
-			if (pDpa->shutdown)
-				dprintk ("shutdown: skb=0x%x\n", (uint) skb);
-
-			dprintk ("skb = 0x%x: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
-				 (uint) skb, (uint) skb->data[0],
-				 (uint) skb->data[1], (uint) skb->data[2],
-				 (uint) skb->data[3], (uint) skb->data[4],
-				 (uint) skb->data[5]);
-
-#ifdef PROMISCUOUS_BY_DEFAULT	/* early 2.x firmware */
-			if ((memcmp (dev->dev_addr, skb->data, 6)) &&
-			    (!broadcast_packet (skb->data))) {
-				/*
-				 * Re-post the buffer to the adapter.  Since the adapter usually
-				 * return 1 to 2 receive buffers at a time, it's not too inefficient
-				 * post one buffer at a time but ... may be that should be 
-				 * optimized at some point.
-				 */
-				ptcb->b.context = (U32) skb;
-				ptcb->b.scount = 1;
-				ptcb->b.size = MAX_ETHER_SIZE;
-				ptcb->b.addr = virt_to_bus ((void *) skb->data);
-
-				if (RCPostRecvBuffers (dev, (PRCTCB) ptcb) !=
-				    RC_RTN_NO_ERROR) {
-					printk (KERN_WARNING
-						"(rcpci45 driver:) RCrecv_callback: post buffer failed!\n");
-					dev_kfree_skb (skb);
-				} else
-					pDpa->numOutRcvBuffers++;
-			} else
-#endif				/* PROMISCUOUS_BY_DEFAULT */
-			{
-				len = PacketDescBlock[2];
-				skb->dev = dev;
-				skb_put (skb, len);	/* adjust length and tail */
-				skb->protocol = eth_type_trans (skb, dev);
-				netif_rx (skb);	/* send the packet to the kernel */
-				dev->last_rx = jiffies;
-			}
-			pDpa->numOutRcvBuffers--;
-			PacketDescBlock += BD_SIZE;	/* point to next context field */
+			len = PacketDescBlock[2];
+			skb->dev = dev;
+			skb_put (skb, len);	/* adjust length and tail */
+			skb->protocol = eth_type_trans (skb, dev);
+			netif_rx (skb);	/* send the packet to the kernel */
+			dev->last_rx = jiffies;
+			pDpa->numOutRcvBuffers--;	
+			/* point to next context field */
+			PacketDescBlock += BD_SIZE;
 		}
 	}
 
@@ -679,11 +635,8 @@
 	pDpa = dev->priv;
 
 	if (pDpa->shutdown)
-		dprintk ("shutdown: service irq\n");
-
-	dprintk ("RC irq: pDpa = 0x%x, dev = 0x%x, id = %d\n",
-		 (uint) pDpa, (uint) dev, (uint) pDpa->id);
-	dprintk ("dev = 0x%x\n", (uint) dev);
+		printk (KERN_DEBUG "%s: shutdown, service irq\n",
+				dev->name);
 
 	RCProcI2OMsgQ (dev);
 }
@@ -714,62 +667,60 @@
 			RCReportDriverCapability (dev, DriverControlWord);
 			RCEnableI2OInterrupts (dev);
 
-			if (dev->flags & IFF_UP) {
-				while (post_buffers) {
-					if (post_buffers >
-					    MAX_NMBR_POST_BUFFERS_PER_MSG)
-						requested =
-						    MAX_NMBR_POST_BUFFERS_PER_MSG;
-					else
-						requested = post_buffers;
-					count =
-					    RC_allocate_and_post_buffers (dev,
-									  requested);
-					post_buffers -= count;
-					if (count < requested)
-						break;
-				}
-				pDpa->numOutRcvBuffers =
-				    MAX_NMBR_RCV_BUFFERS - post_buffers;
-				dprintk ("rc: posted %d buffers \r\n",
-					 (uint) pDpa->numOutRcvBuffers);
+
+			if (!(dev->flags & IFF_UP)) {
+				retry = 0;
+				return;
+			}
+			while (post_buffers) {
+				if (post_buffers > 
+						MAX_NMBR_POST_BUFFERS_PER_MSG)
+					requested = 
+						MAX_NMBR_POST_BUFFERS_PER_MSG;
+				else
+					requested = post_buffers;
+				count =
+				    RC_allocate_and_post_buffers (dev,
+								  requested);
+				post_buffers -= count;
+				if (count < requested)
+					break;
 			}
-			dprintk ("Initialization done.\n");
+			pDpa->numOutRcvBuffers =
+			    MAX_NMBR_RCV_BUFFERS - post_buffers;
+			printk ("Initialization done.\n");
 			netif_wake_queue (dev);
 			retry = 0;
 			return;
 		case RC_RTN_FREE_Q_EMPTY:
 			retry++;
-			printk (KERN_WARNING
-				"(rcpci45 driver:) inbound free q empty\n");
+			printk (KERN_WARNING "%s inbound free q empty\n",
+					dev->name);
 			break;
 		default:
 			retry++;
-			printk (KERN_WARNING
-				"(rcpci45 driver:) bad status after reboot: %d\n",
-				init_status);
+			printk (KERN_WARNING "%s bad stat after reboot: %d\n",
+					dev->name, init_status);
 			break;
 		}
 
 		if (retry > REBOOT_REINIT_RETRY_LIMIT) {
-			printk (KERN_WARNING
-				"(rcpci45 driver:) unable to reinitialize adapter after reboot\n");
-			printk (KERN_WARNING
-				"(rcpci45 driver:) decrementing driver and closing interface\n");
+			printk (KERN_WARNING "%s unable to reinitialize adapter after reboot\n", dev->name);
+			printk (KERN_WARNING "%s decrementing driver and closing interface\n", dev->name);
 			RCDisableI2OInterrupts (dev);
 			dev->flags &= ~IFF_UP;
 			MOD_DEC_USE_COUNT;
 		} else {
-			printk (KERN_INFO
-				"(rcpci45 driver:) rescheduling timer...\n");
+			printk (KERN_INFO "%s: rescheduling timer...\n",
+					dev->name);
 			init_timer (&pDpa->timer);
-			pDpa->timer.expires = RUN_AT ((40 * HZ) / 10);	/* 3 sec. */
+			pDpa->timer.expires = RUN_AT ((40 * HZ) / 10);
 			pDpa->timer.data = (unsigned long) dev;
-			pDpa->timer.function = &rc_timer;	/* timer handler */
+			pDpa->timer.function = &rc_timer;
 			add_timer (&pDpa->timer);
 		}
 	} else
-		printk (KERN_WARNING "(rcpci45 driver:) timer??\n");
+		printk (KERN_WARNING "%s: unexpected timer irq\n", dev->name);
 }
 
 static int
@@ -777,19 +728,16 @@
 {
 	PDPA pDpa = dev->priv;
 
+	printk("RCclose\n");
 	netif_stop_queue (dev);
 
-	dprintk ("RCclose\r\n");
-
 	if (pDpa->reboot) {
-		printk (KERN_INFO
-			"(rcpci45 driver:) skipping reset -- adapter already in reboot mode\n");
+		printk (KERN_INFO "%s skipping reset -- adapter already in reboot mode\n", dev->name);
 		dev->flags &= ~IFF_UP;
 		pDpa->shutdown = 1;
+		MOD_DEC_USE_COUNT;
 		return 0;
 	}
-	dprintk ("receive buffers outstanding: %d\n",
-		 (uint) pDpa->numOutRcvBuffers);
 
 	pDpa->shutdown = 1;
 
@@ -805,6 +753,7 @@
 			   (PFNCALLBACK) RCreset_callback);
 
 	dev->flags &= ~IFF_UP;
+	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
@@ -816,56 +765,42 @@
 	PDPA pDpa = dev->priv;
 
 	if (!pDpa) {
-		dprintk ("RCget_stats: !pDpa\n");
 		return 0;
 	} else if (!(dev->flags & IFF_UP)) {
-		dprintk ("RCget_stats: device down\n");
 		return 0;
 	}
 
 	memset (&RCstats, 0, sizeof (RCLINKSTATS));
 	if ((RCGetLinkStatistics (dev, &RCstats, (void *) 0)) ==
 	    RC_RTN_NO_ERROR) {
-		dprintk ("TX_good 0x%x\n", (uint) RCstats.TX_good);
-		dprintk ("TX_maxcol 0x%x\n", (uint) RCstats.TX_maxcol);
-		dprintk ("TX_latecol 0x%x\n", (uint) RCstats.TX_latecol);
-		dprintk ("TX_urun 0x%x\n", (uint) RCstats.TX_urun);
-		dprintk ("TX_crs 0x%x\n", (uint) RCstats.TX_crs);
-		dprintk ("TX_def 0x%x\n", (uint) RCstats.TX_def);
-		dprintk ("TX_singlecol 0x%x\n", (uint) RCstats.TX_singlecol);
-		dprintk ("TX_multcol 0x%x\n", (uint) RCstats.TX_multcol);
-		dprintk ("TX_totcol 0x%x\n", (uint) RCstats.TX_totcol);
-
-		dprintk ("Rcv_good 0x%x\n", (uint) RCstats.Rcv_good);
-		dprintk ("Rcv_CRCerr 0x%x\n", (uint) RCstats.Rcv_CRCerr);
-		dprintk ("Rcv_alignerr 0x%x\n", (uint) RCstats.Rcv_alignerr);
-		dprintk ("Rcv_reserr 0x%x\n", (uint) RCstats.Rcv_reserr);
-		dprintk ("Rcv_orun 0x%x\n", (uint) RCstats.Rcv_orun);
-		dprintk ("Rcv_cdt 0x%x\n", (uint) RCstats.Rcv_cdt);
-		dprintk ("Rcv_runt 0x%x\n", (uint) RCstats.Rcv_runt);
-
-		pDpa->stats.rx_packets = RCstats.Rcv_good;	/* total packets received    */
-		pDpa->stats.tx_packets = RCstats.TX_good;	/* total packets transmitted    */
 
-		pDpa->stats.rx_errors = RCstats.Rcv_CRCerr + RCstats.Rcv_alignerr + RCstats.Rcv_reserr + RCstats.Rcv_orun + RCstats.Rcv_cdt + RCstats.Rcv_runt;	/* bad packets received        */
+		/* total packets received    */
+		pDpa->stats.rx_packets = RCstats.Rcv_good
+		/* total packets transmitted    */;
+		pDpa->stats.tx_packets = RCstats.TX_good;
+
+		pDpa->stats.rx_errors = RCstats.Rcv_CRCerr + 
+			RCstats.Rcv_alignerr + RCstats.Rcv_reserr + 
+			RCstats.Rcv_orun + RCstats.Rcv_cdt + RCstats.Rcv_runt;
 
-		pDpa->stats.tx_errors = RCstats.TX_urun + RCstats.TX_crs + RCstats.TX_def + RCstats.TX_totcol;	/* packet transmit problems    */
+		pDpa->stats.tx_errors = RCstats.TX_urun + RCstats.TX_crs + 
+			RCstats.TX_def + RCstats.TX_totcol;
 
 		/*
 		 * This needs improvement.
 		 */
-		pDpa->stats.rx_dropped = 0;	/* no space in linux buffers    */
-		pDpa->stats.tx_dropped = 0;	/* no space available in linux    */
-		pDpa->stats.multicast = 0;	/* multicast packets received    */
+		pDpa->stats.rx_dropped = 0; /* no space in linux buffers   */
+		pDpa->stats.tx_dropped = 0; /* no space available in linux */
+		pDpa->stats.multicast = 0;  /* multicast packets received  */
 		pDpa->stats.collisions = RCstats.TX_totcol;
 
 		/* detailed rx_errors: */
 		pDpa->stats.rx_length_errors = 0;
-		pDpa->stats.rx_over_errors = RCstats.Rcv_orun;	/* receiver ring buff overflow    */
-		pDpa->stats.rx_crc_errors = RCstats.Rcv_CRCerr;	/* recved pkt with crc error    */
-		pDpa->stats.rx_frame_errors = 0;	/* recv'd frame alignment error */
-		pDpa->stats.rx_fifo_errors = 0;	/* recv'r fifo overrun        */
-		pDpa->stats.rx_missed_errors = 0;	/* receiver missed packet    */
+		pDpa->stats.rx_over_errors = RCstats.Rcv_orun;
+		pDpa->stats.rx_crc_errors = RCstats.Rcv_CRCerr;
+		pDpa->stats.rx_frame_errors = 0;
+		pDpa->stats.rx_fifo_errors = 0;	
+		pDpa->stats.rx_missed_errors = 0;
 
 		/* detailed tx_errors */
 		pDpa->stats.tx_aborted_errors = 0;
@@ -885,8 +820,6 @@
 	RCuser_struct RCuser;
 	PDPA pDpa = dev->priv;
 
-	dprintk ("RCioctl: cmd = 0x%x\n", cmd);
-
 	if (!capable (CAP_NET_ADMIN))
 		return -EPERM;
 
@@ -910,16 +843,12 @@
 
 			switch (RCuser.cmd) {
 			case RCUC_GETFWVER:
-				printk (KERN_INFO
-					"(rcpci45 driver:) RC GETFWVER\n");
 				RCUD_GETFWVER = &RCuser.RCUS_GETFWVER;
 				RCGetFirmwareVer (dev,
 						  (PU8) & RCUD_GETFWVER->
 						  FirmString, NULL);
 				break;
 			case RCUC_GETINFO:
-				printk (KERN_INFO
-					"(rcpci45 driver:) RC GETINFO\n");
 				RCUD_GETINFO = &RCuser.RCUS_GETINFO;
 				RCUD_GETINFO->mem_start = dev->base_addr;
 				RCUD_GETINFO->mem_end =
@@ -928,8 +857,6 @@
 				RCUD_GETINFO->irq = dev->irq;
 				break;
 			case RCUC_GETIPANDMASK:
-				printk (KERN_INFO
-					"(rcpci45 driver:) RC GETIPANDMASK\n");
 				RCUD_GETIPANDMASK = &RCuser.RCUS_GETIPANDMASK;
 				RCGetRavlinIPandMask (dev,
 						      (PU32) &
@@ -939,8 +866,6 @@
 						      NetMask, NULL);
 				break;
 			case RCUC_GETLINKSTATISTICS:
-				printk (KERN_INFO
-					"(rcpci45 driver:) RC GETLINKSTATISTICS\n");
 				RCUD_GETLINKSTATISTICS =
 				    &RCuser.RCUS_GETLINKSTATISTICS;
 				RCGetLinkStatistics (dev,
@@ -949,75 +874,39 @@
 						     StatsReturn, NULL);
 				break;
 			case RCUC_GETLINKSTATUS:
-				printk (KERN_INFO
-					"(rcpci45 driver:) RC GETLINKSTATUS\n");
 				RCUD_GETLINKSTATUS = &RCuser.RCUS_GETLINKSTATUS;
 				RCGetLinkStatus (dev,
 						 (PU32) & RCUD_GETLINKSTATUS->
 						 ReturnStatus, NULL);
 				break;
 			case RCUC_GETMAC:
-				printk (KERN_INFO
-					"(rcpci45 driver:) RC GETMAC\n");
 				RCUD_GETMAC = &RCuser.RCUS_GETMAC;
 				RCGetMAC (dev, NULL);
+				memcpy(RCUD_GETMAC, dev->dev_addr, 8);
 				break;
 			case RCUC_GETPROM:
-				printk (KERN_INFO
-					"(rcpci45 driver:) RC GETPROM\n");
 				RCUD_GETPROM = &RCuser.RCUS_GETPROM;
 				RCGetPromiscuousMode (dev,
 						      (PU32) & RCUD_GETPROM->
 						      PromMode, NULL);
 				break;
 			case RCUC_GETBROADCAST:
-				printk (KERN_INFO
-					"(rcpci45 driver:) RC GETBROADCAST\n");
 				RCUD_GETBROADCAST = &RCuser.RCUS_GETBROADCAST;
 				RCGetBroadcastMode (dev,
 						    (PU32) & RCUD_GETBROADCAST->
 						    BroadcastMode, NULL);
 				break;
 			case RCUC_GETSPEED:
-				printk (KERN_INFO
-					"(rcpci45 driver:) RC GETSPEED\n");
 				if (!(dev->flags & IFF_UP)) {
-					printk (KERN_ERR
-						"(rcpci45 driver:) RCioctl, GETSPEED error: interface down\n");
 					return -ENODATA;
 				}
 				RCUD_GETSPEED = &RCuser.RCUS_GETSPEED;
 				RCGetLinkSpeed (dev,
 						(PU32) & RCUD_GETSPEED->
 						LinkSpeedCode, NULL);
-				printk (KERN_INFO
-					"(rcpci45 driver:) RC speed = 0x%u\n",
-					RCUD_GETSPEED->LinkSpeedCode);
 				break;
 			case RCUC_SETIPANDMASK:
-				printk (KERN_INFO
-					"(rcpci45 driver:) RC SETIPANDMASK\n");
 				RCUD_SETIPANDMASK = &RCuser.RCUS_SETIPANDMASK;
-				printk (KERN_INFO
-					"(rcpci45 driver:) RC New IP Addr = %d.%d.%d.%d, ",
-					(U8) ((RCUD_SETIPANDMASK->
-					       IpAddr) & 0xff),
-					(U8) ((RCUD_SETIPANDMASK->
-					       IpAddr >> 8) & 0xff),
-					(U8) ((RCUD_SETIPANDMASK->
-					       IpAddr >> 16) & 0xff),
-					(U8) ((RCUD_SETIPANDMASK->
-					       IpAddr >> 24) & 0xff));
-				printk (KERN_INFO
-					"(rcpci45 driver:) RC New Mask = %d.%d.%d.%d\n",
-					(U8) ((RCUD_SETIPANDMASK->
-					       NetMask) & 0xff),
-					(U8) ((RCUD_SETIPANDMASK->
-					       NetMask >> 8) & 0xff),
-					(U8) ((RCUD_SETIPANDMASK->
-					       NetMask >> 16) & 0xff),
-					(U8) ((RCUD_SETIPANDMASK->
-					       NetMask >> 24) & 0xff));
 				RCSetRavlinIPandMask (dev,
 						      (U32) RCUD_SETIPANDMASK->
 						      IpAddr,
@@ -1025,61 +914,33 @@
 						      NetMask);
 				break;
 			case RCUC_SETMAC:
-				printk (KERN_INFO
-					"(rcpci45 driver:) RC SETMAC\n");
-				RCUD_SETMAC = &RCuser.RCUS_SETMAC;
-				printk (KERN_INFO
-					"(rcpci45 driver:) RC New MAC addr = %02X:%02X:%02X:%02X:%02X:%02X\n",
-					(U8) (RCUD_SETMAC->mac[0]),
-					(U8) (RCUD_SETMAC->mac[1]),
-					(U8) (RCUD_SETMAC->mac[2]),
-					(U8) (RCUD_SETMAC->mac[3]),
-					(U8) (RCUD_SETMAC->mac[4]),
-					(U8) (RCUD_SETMAC->mac[5]));
 				RCSetMAC (dev, (PU8) & RCUD_SETMAC->mac);
 				break;
 			case RCUC_SETSPEED:
-				printk (KERN_INFO
-					"(rcpci45 driver:) RC SETSPEED\n");
 				RCUD_SETSPEED = &RCuser.RCUS_SETSPEED;
 				RCSetLinkSpeed (dev,
 						(U16) RCUD_SETSPEED->
 						LinkSpeedCode);
-				printk (KERN_INFO
-					"(rcpci45 driver:) RC New speed = 0x%x\n",
-					RCUD_SETSPEED->LinkSpeedCode);
 				break;
 			case RCUC_SETPROM:
-				printk (KERN_INFO
-					"(rcpci45 driver:) RC SETPROM\n");
 				RCUD_SETPROM = &RCuser.RCUS_SETPROM;
 				RCSetPromiscuousMode (dev,
 						      (U16) RCUD_SETPROM->
 						      PromMode);
-				printk (KERN_INFO
-					"(rcpci45 driver:) RC New prom mode = 0x%x\n",
-					RCUD_SETPROM->PromMode);
 				break;
 			case RCUC_SETBROADCAST:
-				printk (KERN_INFO
-					"(rcpci45 driver:) RC SETBROADCAST\n");
 				RCUD_SETBROADCAST = &RCuser.RCUS_SETBROADCAST;
 				RCSetBroadcastMode (dev,
 						    (U16) RCUD_SETBROADCAST->
 						    BroadcastMode);
-				printk (KERN_INFO
-					"(rcpci45 driver:) RC New broadcast mode = 0x%x\n",
-					RCUD_SETBROADCAST->BroadcastMode);
 				break;
 			default:
-				printk (KERN_INFO
-					"(rcpci45 driver:) RC command default\n");
 				RCUD_DEFAULT = &RCuser.RCUS_DEFAULT;
 				RCUD_DEFAULT->rc = 0x11223344;
 				break;
 			}
-			if (copy_to_user
-			    (rq->ifr_data, &RCuser, sizeof (RCuser)))
+			if (copy_to_user (rq->ifr_data, &RCuser, 
+						sizeof (RCuser)))
 				return -EFAULT;
 			break;
 		}		/* RCU_COMMAND */
@@ -1097,15 +958,14 @@
 	/*
 	 * To be completed ...
 	 */
-	dprintk ("RCconfig\n");
 	return 0;
 	if (dev->flags & IFF_UP)	/* can't act on a running interface */
 		return -EBUSY;
 
 	/* Don't allow changing the I/O address */
 	if (map->base_addr != dev->base_addr) {
-		printk (KERN_WARNING
-			"(rcpci45 driver:)  Change I/O address not implemented\n");
+		printk (KERN_WARNING "%s Change I/O address not implemented\n",
+				dev->name);
 		return -EOPNOTSUPP;
 	}
 	return 0;
@@ -1134,44 +994,36 @@
 	if (!numBuffers)
 		return 0;
 	else if (numBuffers > MAX_NMBR_POST_BUFFERS_PER_MSG) {
-		dprintk ("Too many buffers requested!\n");
-		dprintk ("attempting to allocate only 32 buffers\n");
+		printk (KERN_ERR "%s: Too many buffers requested!\n",
+				dev->name);
 		numBuffers = 32;
 	}
 
 	p = (PU32) kmalloc (sizeof (U32) + numBuffers * sizeof (singleB),
-			    GFP_KERNEL);
-
-	dprintk ("TCB = 0x%x\n", (uint) p);
+			    GFP_DMA|GFP_ATOMIC|GFP_KERNEL);
 
 	if (!p) {
-		printk (KERN_WARNING
-			"(rcpci45 driver:) RCopen: unable to allocate TCB\n");
+		printk (KERN_WARNING "%s unable to allocate TCB\n",
+				dev->name);
 		return 0;
 	}
 
 	p[0] = 0;		/* Buffer Count */
-	pB = (psingleB) ((U32) p + sizeof (U32));	/* point to the first buffer */
-
-	dprintk ("p[0] = 0x%x, p = 0x%x, pB = 0x%x\n", (uint) p[0], (uint) p,
-		 (uint) pB);
-	dprintk ("pB = 0x%x\n", (uint) pB);
+	pB = (psingleB) ((U32) p + sizeof (U32));/* point to the first buffer */
 
 	for (i = 0; i < numBuffers; i++) {
 		skb = dev_alloc_skb (MAX_ETHER_SIZE + 2);
 		if (!skb) {
-			dprintk
-			    ("Doh! RCopen: unable to allocate enough skbs!\n");
-			if (*p != 0) {	/* did we allocate any buffers at all? */
-				dprintk ("will post only %d buffers \n",
-					 (uint) (*p));
+			printk (KERN_WARNING 
+					"%s: unable to allocate enough skbs!\n",
+					dev->name);
+			if (*p != 0) {	/* did we allocate any buffers */
 				break;
 			} else {
 				kfree (p);	/* Free the TCB */
 				return 0;
 			}
 		}
-		dprintk ("post 0x%x\n", (uint) skb);
 		skb_reserve (skb, 2);	/* Align IP on 16 byte boundaries */
 		pB->context = (U32) skb;
 		pB->scount = 1;	/* segment count */
@@ -1182,18 +1034,16 @@
 	}
 
 	if ((status = RCPostRecvBuffers (dev, (PRCTCB) p)) != RC_RTN_NO_ERROR) {
-		printk (KERN_WARNING
-			"(rcpci45 driver:) Post buffer failed with error code 0x%x!\n",
-			status);
-		pB = (psingleB) ((U32) p + sizeof (U32));	/* point to the first buffer */
+		printk (KERN_WARNING "%s: Post buffer failed, error 0x%x\n",
+				dev->name, status);
+		/* point to the first buffer */
+		pB = (psingleB) ((U32) p + sizeof (U32));
 		while (p[0]) {
 			skb = (struct sk_buff *) pB->context;
-			dprintk ("freeing 0x%x\n", (uint) skb);
 			dev_kfree_skb (skb);
 			p[0]--;
 			pB++;
 		}
-		dprintk ("freed all buffers, p[0] = %d\n", (uint) p[0]);
 	}
 	res = p[0];
 	kfree (p);
diff -Nru a/drivers/net/setup.c b/drivers/net/setup.c
--- a/drivers/net/setup.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/net/setup.c	Mon Dec  9 18:46:51 2002
@@ -142,14 +142,13 @@
 static void __init special_device_init(void)
 {
 #ifdef CONFIG_NET_SB1000
-	{
-		extern int sb1000_probe(struct net_device *dev);
-		static struct net_device sb1000_dev = 
-		{
-			"cm0" __PAD3, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, sb1000_probe 
-		};
-		register_netdev(&sb1000_dev);
-	}
+	extern int sb1000_probe(struct net_device *dev);
+
+	static struct net_device sb1000_dev = {
+		.name = "cm0" __PAD3,
+		.init = sb1000_probe,
+	};
+	register_netdev(&sb1000_dev);
 #endif
 }
 
diff -Nru a/drivers/net/shaper.c b/drivers/net/shaper.c
--- a/drivers/net/shaper.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/net/shaper.c	Mon Dec  9 18:46:50 2002
@@ -697,12 +697,13 @@
 
 static struct net_device *devs;
 
+static unsigned int shapers_registered = 0;
+
 static int __init shaper_init(void)
 {
 	int i, err;
 	size_t alloc_size;
 	struct shaper *sp;
-	unsigned int shapers_registered = 0;
 
 	if (shapers < 1)
 		return -ENODEV;
@@ -738,7 +739,7 @@
 {
 	int i;
 
-	for (i = 0; i < shapers; i++)
+	for (i = 0; i < shapers_registered; i++)
 		unregister_netdev(&devs[i]);
 
 	kfree(devs);
diff -Nru a/drivers/net/sis900.c b/drivers/net/sis900.c
--- a/drivers/net/sis900.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/net/sis900.c	Mon Dec  9 18:46:36 2002
@@ -531,6 +531,13 @@
 		
 		if ((mii_phy = kmalloc(sizeof(struct mii_phy), GFP_KERNEL)) == NULL) {
 			printk(KERN_INFO "Cannot allocate mem for struct mii_phy\n");
+			mii_phy = sis_priv->first_mii;
+			while (mii_phy) {
+				struct mii_phy *phy;
+				phy = mii_phy;
+				mii_phy = mii_phy->next;
+				kfree(phy);
+			}
 			return 0;
 		}
 		
diff -Nru a/drivers/net/sk98lin/h/skgehw.h b/drivers/net/sk98lin/h/skgehw.h
--- a/drivers/net/sk98lin/h/skgehw.h	Mon Dec  9 18:46:51 2002
+++ b/drivers/net/sk98lin/h/skgehw.h	Mon Dec  9 18:46:51 2002
@@ -384,7 +384,6 @@
 /* VPD Region */
 /*	PCI_VPD_ADR_REG		16 bit	VPD Address Register */
 #define	PCI_VPD_FLAG	(1L<<15)	/* Bit 15:	starts VPD rd/wd cycle*/
-#define PCI_VPD_ADDR	(0x3fffL<<0)	/* Bit 14..0:	VPD address */
 
 /*
  *	Control Register File:
diff -Nru a/drivers/net/skfp/h/skfbi.h b/drivers/net/skfp/h/skfbi.h
--- a/drivers/net/skfp/h/skfbi.h	Mon Dec  9 18:46:36 2002
+++ b/drivers/net/skfp/h/skfbi.h	Mon Dec  9 18:46:36 2002
@@ -1039,7 +1039,6 @@
 /*	PCI_VPD_NITEM		 8 bit (ML)	Next Item Ptr */
 /*	PCI_VPD_ADR_REG		16 bit (ML)	VPD Address Register */
 #define	PCI_VPD_FLAG	(1<<15)		/* Bit 15	starts VPD rd/wd cycle*/
-#define PCI_VPD_ADDR	(0x3fff<<0)	/* Bit  0..14	VPD address */
 
 /*	PCI_VPD_DAT_REG		32 bit (ML)	VPD Data Register */
 
diff -Nru a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c
--- a/drivers/net/smc-mca.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/net/smc-mca.c	Mon Dec  9 18:46:34 2002
@@ -51,8 +51,6 @@
 #include "8390.h"
 #include "smc-mca.h"
 
-int ultramca_probe(struct net_device *dev);
-
 static int ultramca_open(struct net_device *dev);
 static void ultramca_reset_8390(struct net_device *dev);
 static void ultramca_get_8390_hdr(struct net_device *dev,
@@ -89,37 +87,57 @@
 	char *name;
 };
 
-static struct smc_mca_adapters_t smc_mca_adapters[] __initdata = {
-    { 0x61c8, "SMC Ethercard PLUS Elite/A BNC/AUI (WD8013EP/A)" },
-    { 0x61c9, "SMC Ethercard PLUS Elite/A UTP/AUI (WD8013WP/A)" },
-    { 0x6fc0, "WD Ethercard PLUS/A (WD8003E/A or WD8003ET/A)" },
-    { 0x6fc1, "WD Starcard PLUS/A (WD8003ST/A)" },
-    { 0x6fc2, "WD Ethercard PLUS 10T/A (WD8003W/A)" },
-    { 0xefd4, "IBM PS/2 Adapter/A for Ethernet UTP/AUI (WD8013WP/A)" },
-    { 0xefd5, "IBM PS/2 Adapter/A for Ethernet BNC/AUI (WD8013EP/A)" },
-    { 0xefe5, "IBM PS/2 Adapter/A for Ethernet" },
-    { 0x0000, NULL }
+#define MAX_ULTRAMCA_CARDS 4	/* Max number of Ultra cards per module */
+
+static int ultra_io[MAX_ULTRAMCA_CARDS];
+static int ultra_irq[MAX_ULTRAMCA_CARDS];
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(ultra_io, "1-" __MODULE_STRING(MAX_ULTRAMCA_CARDS) "i");
+MODULE_PARM(ultra_irq, "1-" __MODULE_STRING(MAX_ULTRAMCA_CARDS) "i");
+MODULE_PARM_DESC(ultra_io, "SMC Ultra/EtherEZ MCA I/O base address(es)");
+MODULE_PARM_DESC(ultra_irq, "SMC Ultra/EtherEZ MCA IRQ number(s)");
+
+static short smc_mca_adapter_ids[] __initdata = {
+	0x61c8,
+	0x61c9,
+	0x6fc0,
+	0x6fc1,
+	0x6fc2,
+	0xefd4,
+	0xefd5,
+	0xefe5,
+	0x0000
+};
+
+static char *smc_mca_adapter_names[] __initdata = {
+	"SMC Ethercard PLUS Elite/A BNC/AUI (WD8013EP/A)",
+	"SMC Ethercard PLUS Elite/A UTP/AUI (WD8013WP/A)",
+	"WD Ethercard PLUS/A (WD8003E/A or WD8003ET/A)",
+	"WD Starcard PLUS/A (WD8003ST/A)",
+	"WD Ethercard PLUS 10T/A (WD8003W/A)",
+	"IBM PS/2 Adapter/A for Ethernet UTP/AUI (WD8013WP/A)",
+	"IBM PS/2 Adapter/A for Ethernet BNC/AUI (WD8013EP/A)",
+	"IBM PS/2 Adapter/A for Ethernet",
+	NULL
 };
 
-int __init ultramca_probe(struct net_device *dev)
+static int ultra_found = 0;
+
+int __init ultramca_probe(struct device *gen_dev)
 {
 	unsigned short ioaddr;
+	struct net_device *dev;
 	unsigned char reg4, num_pages;
-	char slot = -1;
+	struct mca_device *mca_dev = to_mca_device(gen_dev);
+	char slot = mca_dev->slot;
 	unsigned char pos2 = 0xff, pos3 = 0xff, pos4 = 0xff, pos5 = 0xff;
-	int i, j;
-	int adapter_found = 0;
-	int adapter = 0;
+	int i;
+	int adapter = mca_dev->index;
 	int tbase = 0;
 	int tirq = 0;
-	int base_addr = dev->base_addr;
-	int irq = dev->irq;
-
-	if (!MCA_bus) {
-		return -ENODEV;
-	}
-
-	SET_MODULE_OWNER(dev);
+	int base_addr = ultra_io[ultra_found];
+	int irq = ultra_irq[ultra_found];
 
 	if (base_addr || irq) {
 		printk(KERN_INFO "Probing for SMC MCA adapter");
@@ -132,82 +150,76 @@
 		}
 	}
 
-        /* proper multicard detection by ZP Gu (zpg@castle.net) */
-
-	for (j = 0; (smc_mca_adapters[j].name != NULL) && !adapter_found; j++) {
-		slot = mca_find_unused_adapter(smc_mca_adapters[j].id, 0);
+	tirq = 0;
+	tbase = 0;
 
-		while((slot != MCA_NOTFOUND) && !adapter_found) {
-			tirq = 0;
-			tbase = 0;
-
-                        /* If we're trying to match a specificied irq or
-			 * io address, we'll reject the adapter
-			 * found unless it's the one we're looking for
-			 */
-
-			pos2 = mca_read_stored_pos(slot, 2); /* io_addr */
-			pos3 = mca_read_stored_pos(slot, 3); /* shared mem */
-			pos4 = mca_read_stored_pos(slot, 4); /* ROM bios addr
-							      * range */
-			pos5 = mca_read_stored_pos(slot, 5); /* irq, media
-							      * and RIPL */
-
-			/* Test the following conditions:
-			 * - If an irq parameter is supplied, compare it
-			 *   with the irq of the adapter we found
-			 * - If a base_addr paramater is given, compare it
-			 *   with the base_addr of the adapter we found
-			 * - Check that the irq and the base_addr of the
-			 *   adapter we found is not already in use by
-			 *   this driver
-			 */
-
-			switch (j) { /* j = card-idx (card array above) [hs] */
-				case _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A:
-		                case _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A:
-				case _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A:
-				case _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A:
-				{
-					tbase = addr_table[(pos2 & 0xf0) >> 4].base_addr;
-					tirq  = irq_table[(pos5 & 0xc) >> 2].new_irq;
-					break;
-				}
-				case _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A:
-				case _6fc1_WD_Starcard_PLUS_A_WD8003ST_A:
-				case _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A:
-				case _efe5_IBM_PS2_Adapter_A_for_Ethernet:
-				{
-					tbase = ((pos2 & 0x0fe) * 0x10);
-					tirq  = irq_table[(pos5 & 3)].old_irq;
-					break;
-				}
-			}
+	/* If we're trying to match a specificied irq or io address,
+	 * we'll reject the adapter found unless it's the one we're
+	 * looking for */
+
+	pos2 = mca_device_read_stored_pos(mca_dev, 2); /* io_addr */
+	pos3 = mca_device_read_stored_pos(mca_dev, 3); /* shared mem */
+	pos4 = mca_device_read_stored_pos(mca_dev, 4); /* ROM bios addr range */
+	pos5 = mca_device_read_stored_pos(mca_dev, 5); /* irq, media and RIPL */
+
+	/* Test the following conditions:
+	 * - If an irq parameter is supplied, compare it
+	 *   with the irq of the adapter we found
+	 * - If a base_addr paramater is given, compare it
+	 *   with the base_addr of the adapter we found
+	 * - Check that the irq and the base_addr of the
+	 *   adapter we found is not already in use by
+	 *   this driver
+	 */
 
-			if(!tirq || !tbase || (irq && irq != tirq) || (base_addr && tbase != base_addr)) {
-				slot = mca_find_unused_adapter(smc_mca_adapters[j].id, slot + 1);
-			} else {
-				adapter_found = 1;
-				adapter = j;
-			}
+	switch (mca_dev->index) {
+	case _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A:
+	case _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A:
+	case _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A:
+	case _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A:
+		{
+			tbase = addr_table[(pos2 & 0xf0) >> 4].base_addr;
+			tirq  = irq_table[(pos5 & 0xc) >> 2].new_irq;
+			break;
+		}
+	case _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A:
+	case _6fc1_WD_Starcard_PLUS_A_WD8003ST_A:
+	case _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A:
+	case _efe5_IBM_PS2_Adapter_A_for_Ethernet:
+		{
+			tbase = ((pos2 & 0x0fe) * 0x10);
+			tirq  = irq_table[(pos5 & 3)].old_irq;
+			break;
 		}
 	}
-
-	if(!adapter_found) {
-		return ((base_addr || irq) ? -ENXIO : -ENODEV);
-	}
+	
+	if(!tirq || !tbase 
+	   || (irq && irq != tirq) 
+	   || (base_addr && tbase != base_addr))
+		/* FIXME: we're trying to force the ordering of the
+		 * devices here, there should be a way of getting this
+		 * to happen */
+		return -ENXIO;
 
         /* Adapter found. */
+	dev  = alloc_etherdev(0);
+	if(!dev)
+		return -ENODEV;
 
-	printk(KERN_INFO "%s: %s found in slot %d\n",
-	       dev->name, smc_mca_adapters[adapter].name, slot + 1);
+	SET_MODULE_OWNER(dev);
+
+	if((i = register_netdev(dev)) != 0)
+		return i;
 
-	mca_set_adapter_name(slot, smc_mca_adapters[adapter].name);
-	mca_mark_as_used(slot);
+	printk(KERN_INFO "%s: %s found in slot %d\n",
+	       dev->name, smc_mca_adapter_names[adapter], slot + 1);
 
+	strncpy(gen_dev->name, smc_mca_adapter_names[adapter], sizeof(gen_dev->name));
+	mca_device_set_claim(mca_dev, 1);
+	ultra_found++;
 
-	dev->base_addr = ioaddr = tbase;
-	dev->irq       = tirq;
+	dev->base_addr = ioaddr = mca_device_transform_ioport(mca_dev, tbase);
+	dev->irq       = mca_device_transform_irq(mca_dev, tirq);
 	dev->mem_start = 0;
 	num_pages      = 40;
 
@@ -218,7 +230,8 @@
 			for (i = 0; i < 16; i++) { /* taking 16 counts
 						    * up to 15 [hs] */
 				if (mem_table[i].mem_index == (pos3 & ~MEM_MASK)) {
-					dev->mem_start = mem_table[i].mem_start;
+					dev->mem_start = (unsigned long)
+					  mca_device_transform_memory(mca_dev, (void *)mem_table[i].mem_start);
 					num_pages = mem_table[i].num_pages;
 				}
 			}
@@ -229,7 +242,8 @@
 		case _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A:
 		case _efe5_IBM_PS2_Adapter_A_for_Ethernet:
 		{
-			dev->mem_start = ((pos3 & 0xfc) * 0x1000);
+			dev->mem_start = (unsigned long)
+			  mca_device_transform_memory(mca_dev, (void *)((pos3 & 0xfc) * 0x1000));
 			num_pages = 0x40;
 			break;
 		}
@@ -240,7 +254,8 @@
 			 * the index of the 0x2000 step.
 			 * beware different number of pages [hs]
 			 */
-			dev->mem_start = 0xc0000 + (0x2000 * (pos3 & 0xf));
+			dev->mem_start = (unsigned long) 
+			  mca_device_transform_memory(mca_dev, (void *)(0xc0000 + (0x2000 * (pos3 & 0xf))));
 			num_pages = 0x20 + (2 * (pos3 & 0x10));
 			break;
 		}
@@ -258,7 +273,7 @@
 	printk(KERN_INFO "%s: Parameters: %#3x,", dev->name, ioaddr);
 
 	for (i = 0; i < 6; i++)
-		printk(KERN_INFO " %2.2X", dev->dev_addr[i] = inb(ioaddr + 8 + i));
+		printk(" %2.2X", dev->dev_addr[i] = inb(ioaddr + 8 + i));
 
 	/* Switch from the station address to the alternate register set
 	 * and read the useful registers there.
@@ -281,10 +296,11 @@
 	 */
 
 	if (ethdev_init(dev)) {
-		printk (KERN_INFO ", no memory for dev->priv.\n");
+		printk (", no memory for dev->priv.\n");
 		release_region(ioaddr, ULTRA_IO_EXTENT);
 		return -ENOMEM;
 	}
+	gen_dev->driver_data = dev;
 
 	/* The 8390 isn't at the base address, so fake the offset
 	 */
@@ -301,7 +317,7 @@
 	dev->mem_end = ei_status.rmem_end =
 	dev->mem_start + (ei_status.stop_page - START_PG) * 256;
 
-	printk(KERN_INFO ", IRQ %d memory %#lx-%#lx.\n",
+	printk(", IRQ %d memory %#lx-%#lx.\n",
 	dev->irq, dev->mem_start, dev->mem_end - 1);
 
 	ei_status.reset_8390 = &ultramca_reset_8390;
@@ -313,6 +329,7 @@
 
 	dev->open = &ultramca_open;
 	dev->stop = &ultramca_close_card;
+
 	NS8390_init(dev, 0);
 
 	return 0;
@@ -426,69 +443,48 @@
 	return 0;
 }
 
+static int ultramca_remove(struct device *gen_dev)
+{
+	struct mca_device *mca_dev = to_mca_device(gen_dev);
+	struct net_device *dev = (struct net_device *)gen_dev->driver_data;
 
-#ifdef MODULE
-#undef MODULE        /* don't want to bother now! */
+	if(dev && dev->priv) {
+		/* NB: ultra_close_card() does free_irq */
+		int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET;
 
-#define MAX_ULTRAMCA_CARDS 4	/* Max number of Ultra cards per module */
+		mca_device_set_claim(mca_dev, 0);
+		release_region(ioaddr, ULTRA_IO_EXTENT);
+		unregister_netdev(dev);
+		kfree(dev->priv);
+	}
+	return 0;
+}
 
-static struct net_device dev_ultra[MAX_ULTRAMCA_CARDS];
-static int io[MAX_ULTRAMCA_CARDS];
-static int irq[MAX_ULTRAMCA_CARDS];
-MODULE_LICENSE("GPL");
 
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ULTRAMCA_CARDS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ULTRAMCA_CARDS) "i");
-MODULE_PARM_DESC(io, "SMC Ultra/EtherEZ MCA I/O base address(es)");
-MODULE_PARM_DESC(irq, "SMC Ultra/EtherEZ MCA IRQ number(s)");
+static struct mca_driver ultra_driver = {
+	.id_table = smc_mca_adapter_ids,
+	.driver = {
+		.name = "smc-mca",
+		.bus = &mca_bus_type,
+		.probe = ultramca_probe,
+		.remove = ultramca_remove,
+	}
+};
 
-int init_module(void)
+static int __init ultramca_init_module(void)
 {
-	int this_dev, found = 0;
+	if(!MCA_bus)
+		return -ENXIO;
 
-	for (this_dev = 0; this_dev < MAX_ULTRAMCA_CARDS; this_dev++) {
-		struct net_device *dev = &dev_ultra[this_dev];
-		dev->irq = irq[this_dev];
-		dev->base_addr = io[this_dev];
-		dev->init = ultramca_probe;
-
-		if (register_netdev(dev) != 0) {
-			if (found != 0) {	/* Got at least one. */
-				return 0;
-			}
-			printk(KERN_NOTICE "smc-mca.c: No SMC Ultra card found (i/o = 0x%x).\n", io[this_dev]);
-			return -ENXIO;
-		}
-		found++;
-	}
-	return 0;
+	mca_register_driver(&ultra_driver);
+
+	return ultra_found ? 0 : -ENXIO;
 }
 
-void cleanup_module(void)
+static void __exit ultramca_cleanup_module(void)
 {
-	int this_dev;
-
-	for (this_dev = 0; this_dev < MAX_ULTRAMCA_CARDS; this_dev++) {
-		struct net_device *dev = &dev_ultra[this_dev];
-		if (dev->priv != NULL) {
-			void *priv = dev->priv;
-			/* NB: ultra_close_card() does free_irq */
-			int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET;
-			mca_mark_as_unused(ei_status.priv);
-			release_region(ioaddr, ULTRA_IO_EXTENT);
-			unregister_netdev(dev);
-			kfree(priv);
-		}
-	}
+	mca_unregister_driver(&ultra_driver);
 }
-#endif /* MODULE */
+module_init(ultramca_init_module);
+module_exit(ultramca_cleanup_module);
 
-/*
- * Local variables:
- *  compile-command: "gcc -D__KERNEL__ -Wall -O6 -I/usr/src/linux/net/inet -c smc-mca.c"
- *  version-control: t
- *  kept-new-versions: 5
- *  c-indent-level: 8
- *  tab-width: 8
- * End:
- */
diff -Nru a/drivers/net/starfire.c b/drivers/net/starfire.c
--- a/drivers/net/starfire.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/net/starfire.c	Mon Dec  9 18:46:35 2002
@@ -905,6 +905,7 @@
 		return -ENOMEM;
 	}
 
+	netif_carrier_off(dev);
 	init_ring(dev);
 	/* Set the size of the Rx buffers. */
 	writel((np->rx_buf_sz << RxBufferLenShift) |
@@ -1587,6 +1588,7 @@
 			else
 				np->mii_if.full_duplex = 0;
 		}
+		netif_carrier_on(dev);
 		printk(KERN_DEBUG "%s: Link is up, running at %sMbit %s-duplex\n",
 		       dev->name,
 		       np->speed100 ? "100" : "10",
@@ -1602,6 +1604,7 @@
 			writel(np->tx_mode, ioaddr + TxMode);
 		}
 	} else {
+		netif_carrier_off(dev);
 		printk(KERN_DEBUG "%s: Link is down\n", dev->name);
 	}
 }
diff -Nru a/drivers/net/sungem.c b/drivers/net/sungem.c
--- a/drivers/net/sungem.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/net/sungem.c	Mon Dec  9 18:46:51 2002
@@ -99,11 +99,6 @@
 #define GEM_MODULE_NAME	"gem"
 #define PFX GEM_MODULE_NAME ": "
 
-/* Until this gets merged from 2.4.x... */
-#ifndef PCI_DEVICE_ID_APPLE_UNI_N_GMACP
-#define PCI_DEVICE_ID_APPLE_UNI_N_GMACP 0x0024
-#endif
-
 static struct pci_device_id gem_pci_tbl[] __devinitdata = {
 	{ PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_GEM,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
diff -Nru a/drivers/net/sunhme.c b/drivers/net/sunhme.c
--- a/drivers/net/sunhme.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/net/sunhme.c	Mon Dec  9 18:46:35 2002
@@ -2698,7 +2698,6 @@
 	}
 
 	hp = dev->priv;
-	memset(hp, 0, sizeof(*hp));
 
 	hp->happy_dev = sdev;
 
diff -Nru a/drivers/net/tc35815.c b/drivers/net/tc35815.c
--- a/drivers/net/tc35815.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/net/tc35815.c	Mon Dec  9 18:46:34 2002
@@ -536,10 +536,15 @@
 	struct net_device *dev;
 
 	/* Allocate a new 'dev' if needed. */
-	dev = init_etherdev(NULL, 0);
+	dev = init_etherdev(NULL, sizeof(struct tc35815_local));
 	if (dev == NULL)
 		return -ENOMEM;
 
+	/*
+	 * init_etherdev allocs and zeros dev->priv
+	 */
+	lp = dev->priv;
+
 	if (tc35815_debug  &&  version_printed++ == 0)
 		printk(KERN_DEBUG "%s", version);
 
@@ -571,17 +576,7 @@
 	printk("\n");
 
 	/* Initialize the device structure. */
-	if (dev->priv == NULL) {
-		dev->priv = kmalloc(sizeof(struct tc35815_local), GFP_KERNEL);
-		if (dev->priv == NULL)
-			return -ENODEV;
-	}
-	lp = dev->priv;
-
 	lp->pdev = pdev;
-
-	memset(lp, 0, sizeof(struct tc35815_local));
-
 	lp->next_module = root_tc35815_dev;
 	root_tc35815_dev = dev;
 
@@ -1764,7 +1759,6 @@
 	while (root_tc35815_dev) {
 		struct net_device *dev = root_tc35815_dev;
 		next_dev = ((struct tc35815_local *)dev->priv)->next_module;
-		kfree(dev->priv);
 		iounmap((void *)(dev->base_addr));
 		unregister_netdev(dev);
 		kfree(dev);
diff -Nru a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c
--- a/drivers/net/tokenring/lanstreamer.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/net/tokenring/lanstreamer.c	Mon Dec  9 18:46:51 2002
@@ -66,6 +66,8 @@
  *             the number of TX descriptors to 1, which together can prevent 
  *             the card from locking up the box - <yoder1@us.ibm.com>
  *  09/27/02 - New PCI interface + bug fix. - <yoder1@us.ibm.com>
+ *  11/13/02 - Removed free_irq calls which could cause a hang, added
+ *	       netif_carrier_{on|off} - <yoder1@us.ibm.com>
  *  
  *  To Do:
  *
@@ -136,7 +138,7 @@
  */
 
 static char version[] = "LanStreamer.c v0.4.0 03/08/01 - Mike Sullivan\n"
-                        "              v0.5.2 09/30/02 - Kent Yoder";
+                        "              v0.5.3 11/13/02 - Kent Yoder";
 
 static struct pci_device_id streamer_pci_tbl[] __initdata = {
 	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_TR, PCI_ANY_ID, PCI_ANY_ID,},
@@ -878,6 +880,7 @@
 #endif
 
 	netif_start_queue(dev);
+	netif_carrier_on(dev);
 	return 0;
 }
 
@@ -1101,7 +1104,9 @@
 			       ntohs(readw(streamer_mmio + LAPDINC)),
 			       ntohs(readw(streamer_mmio + LAPDINC)),
 			       ntohs(readw(streamer_mmio + LAPDINC)));
-			free_irq(dev->irq, dev);
+			netif_stop_queue(dev);
+			netif_carrier_off(dev);
+			printk(KERN_WARNING "%s: Adapter must be manually reset.\n", dev->name);
 		}
 
 		/* SISR_ADAPTER_CHECK */
@@ -1199,6 +1204,7 @@
 	int i;
 
 	netif_stop_queue(dev);
+	netif_carrier_off(dev);
 	writew(streamer_priv->srb, streamer_mmio + LAPA);
 	writew(htons(SRB_CLOSE_ADAPTER << 8),streamer_mmio+LAPDINC);
 	writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC);
@@ -1669,11 +1675,10 @@
 			/* @TBD. no llc reset on autostreamer writel(readl(streamer_mmio+BCTL)|(3<<13),streamer_mmio+BCTL);
 			   udelay(1);
 			   writel(readl(streamer_mmio+BCTL)&~(3<<13),streamer_mmio+BCTL); */
-			netif_stop_queue(dev);
-			free_irq(dev->irq, dev);
-
-			printk(KERN_WARNING "%s: Adapter has been closed \n", dev->name);
 
+			netif_stop_queue(dev);
+			netif_carrier_off(dev);
+			printk(KERN_WARNING "%s: Adapter must be manually reset.\n", dev->name);
 		}
 		/* If serious error */
 		if (streamer_priv->streamer_message_level) {
diff -Nru a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
--- a/drivers/net/tulip/de2104x.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/net/tulip/de2104x.c	Mon Dec  9 18:46:50 2002
@@ -2014,7 +2014,6 @@
 	dev->watchdog_timeo = TX_TIMEOUT;
 
 	dev->irq = pdev->irq;
-	init_timer(&de->media_timer);
 
 	de = dev->priv;
 	de->de21040 = ent->driver_data == 0 ? 1 : 0;
@@ -2217,8 +2216,7 @@
 	.name		= DRV_NAME,
 	.id_table	= de_pci_tbl,
 	.probe		= de_init_one,
-#warning only here to fix build.  should be __exit_p not __devexit_p.
-	.remove		= __devexit_p(de_remove_one),
+	.remove		= __exit_p(de_remove_one),
 #ifdef CONFIG_PM
 	.suspend	= de_suspend,
 	.resume		= de_resume,
diff -Nru a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c
--- a/drivers/net/tulip/media.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/net/tulip/media.c	Mon Dec  9 18:46:35 2002
@@ -352,9 +352,9 @@
 		if (tulip_media_cap[dev->if_port] & MediaIsMII) {
 			new_csr6 = 0x020E0000;
 		} else if (tulip_media_cap[dev->if_port] & MediaIsFx) {
-			new_csr6 = 0x028600000;
+			new_csr6 = 0x02860000;
 		} else
-			new_csr6 = 0x038600000;
+			new_csr6 = 0x03860000;
 		if (tulip_debug > 1)
 			printk(KERN_DEBUG "%s: No media description table, assuming "
 				   "%s transceiver, CSR12 %2.2x.\n",
diff -Nru a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
--- a/drivers/net/tulip/tulip_core.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/net/tulip/tulip_core.c	Mon Dec  9 18:46:38 2002
@@ -222,6 +222,7 @@
 	{ 0x1186, 0x1561, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x1626, 0x8410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x1737, 0xAB09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+	{ 0x17B3, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ } /* terminate list */
 };
 MODULE_DEVICE_TABLE(pci, tulip_pci_tbl);
diff -Nru a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
--- a/drivers/net/tulip/winbond-840.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/net/tulip/winbond-840.c	Mon Dec  9 18:46:35 2002
@@ -341,7 +341,6 @@
 	DescIntr=0x80000000,
 };
 
-#define PRIV_ALIGN	15 	/* Required alignment mask */
 #define MII_CNT		1 /* winbond only supports one MII */
 struct netdev_private {
 	struct w840_rx_desc *rx_ring;
@@ -1585,10 +1584,10 @@
 	if (debug > 2) {
 		int i;
 
-		printk("\n"KERN_DEBUG"  Tx ring at %8.8x:\n",
+		printk(KERN_DEBUG"  Tx ring at %8.8x:\n",
 			   (int)np->tx_ring);
 		for (i = 0; i < TX_RING_SIZE; i++)
-			printk(" #%d desc. %4.4x %4.4x %8.8x.\n",
+			printk(KERN_DEBUG " #%d desc. %4.4x %4.4x %8.8x.\n",
 				   i, np->tx_ring[i].length,
 				   np->tx_ring[i].status, np->tx_ring[i].buffer1);
 		printk("\n"KERN_DEBUG "  Rx ring %8.8x:\n",
@@ -1688,7 +1687,6 @@
 	return 0;
 }
 
-
 static int w840_resume (struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
@@ -1712,8 +1710,7 @@
 
 		netif_wake_queue(dev);
 
-		np->timer.expires = jiffies + 1*HZ;
-		add_timer(&np->timer);
+		mod_timer(&np->timer, jiffies + 1*HZ);
 	} else {
 		netif_device_attach(dev);
 	}
diff -Nru a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
--- a/drivers/net/via-rhine.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/net/via-rhine.c	Mon Dec  9 18:46:51 2002
@@ -93,14 +93,19 @@
 	- transmit frame queue message is off by one - fixed
 	- adds IntrNormalSummary to "Something Wicked" exclusion list
 	  so normal interrupts will not trigger the message (src: Donald Becker)
-	(Roger Lahti)
-	- cosmetic cleanups, remove 3 unused members of struct netdev_private
+ 	(Roger Luethi)
+ 	- show confused chip where to continue after Tx error
+ 	- location of collision counter is chip specific
+ 	- allow selecting backoff algorithm (module parameter)
+
+	LK1.1.15 (jgarzik):
+	- Use new MII lib helper generic_mii_ioctl
 
 */
 
 #define DRV_NAME	"via-rhine"
-#define DRV_VERSION	"1.1.14"
-#define DRV_RELDATE	"May-3-2002"
+#define DRV_VERSION	"1.1.15"
+#define DRV_RELDATE	"November-22-2002"
 
 
 /* A few user-configurable values.
@@ -113,6 +118,9 @@
    Setting to > 1518 effectively disables this feature. */
 static int rx_copybreak;
 
+/* Select a backoff algorithm (Ethernet capture effect) */
+static int backoff;
+
 /* Used to pass the media type, etc.
    Both 'options[]' and 'full_duplex[]' should exist for driver
    interoperability.
@@ -215,11 +223,13 @@
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM(debug, "i");
 MODULE_PARM(rx_copybreak, "i");
+MODULE_PARM(backoff, "i");
 MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM_DESC(max_interrupt_work, "VIA Rhine maximum events handled per interrupt");
 MODULE_PARM_DESC(debug, "VIA Rhine debug level (0-7)");
 MODULE_PARM_DESC(rx_copybreak, "VIA Rhine copy breakpoint for copy-only-tiny-frames");
+MODULE_PARM_DESC(backoff, "VIA Rhine: Bits 0-3: backoff algorithm");
 MODULE_PARM_DESC(options, "VIA Rhine: Bits 0-3: media type, bit 17: full duplex");
 MODULE_PARM_DESC(full_duplex, "VIA Rhine full duplex setting(s) (1)");
 
@@ -236,7 +246,8 @@
 Boards with this chip are functional only in a bus-master PCI slot.
 
 Many operational settings are loaded from the EEPROM to the Config word at
-offset 0x78.  This driver assumes that they are correct.
+offset 0x78. For most of these settings, this driver assumes that they are
+correct.
 If this driver is compiled to use PCI memory space operations the EEPROM
 must be configured to enable memory ops.
 
@@ -388,9 +399,10 @@
 	StickyHW=0x83, WOLcrClr=0xA4, WOLcgClr=0xA7, PwrcsrClr=0xAC,
 };
 
-/* Bits in ConfigD (select backoff algorithm (Ethernet capture effect)) */
+/* Bits in ConfigD */
 enum backoff_bits {
-	BackOpt=0x01, BackAMD=0x02, BackDEC=0x04, BackRandom=0x08
+	BackOptional=0x01, BackModify=0x02,
+	BackCaptureEffect=0x04, BackRandom=0x08
 };
 
 #ifdef USE_MEM
@@ -404,7 +416,7 @@
 /* Bits in the interrupt status/mask registers. */
 enum intr_status_bits {
 	IntrRxDone=0x0001, IntrRxErr=0x0004, IntrRxEmpty=0x0020,
-	IntrTxDone=0x0002, IntrTxAbort=0x0008, IntrTxUnderrun=0x0010,
+	IntrTxDone=0x0002, IntrTxError=0x0008, IntrTxUnderrun=0x0010,
 	IntrPCIErr=0x0040,
 	IntrStatsMax=0x0080, IntrRxEarly=0x0100, IntrMIIChange=0x0200,
 	IntrRxOverflow=0x0400, IntrRxDropped=0x0800, IntrRxNoBuf=0x1000,
@@ -430,24 +442,27 @@
 /* The Rx and Tx buffer descriptors. */
 struct rx_desc {
 	s32 rx_status;
-	u32 desc_length;
+	u32 desc_length; /* Chain flag, Buffer/frame length */
 	u32 addr;
 	u32 next_desc;
 };
 struct tx_desc {
 	s32 tx_status;
-	u32 desc_length;
+	u32 desc_length; /* Chain flag, Tx Config, Frame length */
 	u32 addr;
 	u32 next_desc;
 };
 
+/* Initial value for tx_desc.desc_length, Buffer size goes to bits 0-10 */
+#define TXDESC 0x00e08000
+
 enum rx_status_bits {
 	RxOK=0x8000, RxWholePkt=0x0300, RxErr=0x008F
 };
 
-/* Bits in *_desc.status */
+/* Bits in *_desc.*_status */
 enum desc_status_bits {
-	DescOwn=0x80000000, DescEndPacket=0x4000, DescIntr=0x1000,
+	DescOwn=0x80000000
 };
 
 /* Bits in ChipCmd. */
@@ -519,6 +534,7 @@
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static int  via_rhine_close(struct net_device *dev);
 static inline void clear_tally_counters(long ioaddr);
+static inline void via_restart_tx(struct net_device *dev);
 
 static void wait_for_reset(struct net_device *dev, int chip_id, char *name)
 {
@@ -705,6 +721,11 @@
 		writeb(readb(ioaddr + ConfigA) & 0xFE, ioaddr + ConfigA);
 	}
 
+	/* Select backoff algorithm */
+	if (backoff)
+		writeb(readb(ioaddr + ConfigD) & (0xF0 | backoff),
+			ioaddr + ConfigD);
+
 	dev->irq = pdev->irq;
 
 	np = dev->priv;
@@ -941,7 +962,7 @@
 	for (i = 0; i < TX_RING_SIZE; i++) {
 		np->tx_skbuff[i] = 0;
 		np->tx_ring[i].tx_status = 0;
-		np->tx_ring[i].desc_length = cpu_to_le32(0x00e08000);
+		np->tx_ring[i].desc_length = cpu_to_le32(TXDESC);
 		next += sizeof(struct tx_desc);
 		np->tx_ring[i].next_desc = cpu_to_le32(next);
 		np->tx_buf[i] = &np->tx_bufs[i * PKT_BUF_SZ];
@@ -957,7 +978,7 @@
 
 	for (i = 0; i < TX_RING_SIZE; i++) {
 		np->tx_ring[i].tx_status = 0;
-		np->tx_ring[i].desc_length = cpu_to_le32(0x00e08000);
+		np->tx_ring[i].desc_length = cpu_to_le32(TXDESC);
 		np->tx_ring[i].addr = cpu_to_le32(0xBADF00D0); /* An invalid address. */
 		if (np->tx_skbuff[i]) {
 			if (np->tx_skbuff_dma[i]) {
@@ -982,7 +1003,7 @@
 		writeb(dev->dev_addr[i], ioaddr + StationAddr + i);
 
 	/* Initialize other registers. */
-	writew(0x0006, ioaddr + PCIBusConfig);	/* Store & forward */
+	writew(0x0006, ioaddr + PCIBusConfig);	/* Tune configuration??? */
 	/* Configure initial FIFO thresholds. */
 	writeb(0x20, ioaddr + TxConfig);
 	np->tx_thresh = 0x20;
@@ -997,8 +1018,9 @@
 	via_rhine_set_rx_mode(dev);
 
 	/* Enable interrupts by setting the interrupt mask. */
-	writew(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow| IntrRxDropped|
-		   IntrTxDone | IntrTxAbort | IntrTxUnderrun |
+	writew(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow |
+		   IntrRxDropped | IntrRxNoBuf | IntrTxAborted |
+		   IntrTxDone | IntrTxError | IntrTxUnderrun |
 		   IntrPCIErr | IntrStatsMax | IntrLinkChange | IntrMIIChange,
 		   ioaddr + IntrEnable);
 
@@ -1241,7 +1263,7 @@
 	}
 
 	np->tx_ring[entry].desc_length = 
-		cpu_to_le32(0x00E08000 | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN));
+		cpu_to_le32(TXDESC | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN));
 
 	/* lock eth irq */
 	spin_lock_irq (&np->lock);
@@ -1293,13 +1315,14 @@
 						   IntrRxWakeUp | IntrRxEmpty | IntrRxNoBuf))
 			via_rhine_rx(dev);
 
-		if (intr_status & (IntrTxDone | IntrTxAbort | IntrTxUnderrun |
+		if (intr_status & (IntrTxDone | IntrTxError | IntrTxUnderrun |
 						   IntrTxAborted))
 			via_rhine_tx(dev);
 
 		/* Abnormal error summary/uncommon events handlers. */
 		if (intr_status & (IntrPCIErr | IntrLinkChange | IntrMIIChange |
-						   IntrStatsMax | IntrTxAbort | IntrTxUnderrun))
+				   IntrStatsMax | IntrTxError | IntrTxAborted |
+				   IntrTxUnderrun))
 			via_rhine_error(dev, intr_status);
 
 		if (--boguscnt < 0) {
@@ -1311,7 +1334,7 @@
 	}
 
 	if (debug > 3)
-		printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
+		printk(KERN_DEBUG "%s: exiting interrupt, status=%4.4x.\n",
 			   dev->name, readw(ioaddr + IntrStatus));
 }
 
@@ -1327,11 +1350,11 @@
 	/* find and cleanup dirty tx descriptors */
 	while (np->dirty_tx != np->cur_tx) {
 		txstatus = le32_to_cpu(np->tx_ring[entry].tx_status);
-		if (txstatus & DescOwn)
-			break;
 		if (debug > 6)
 			printk(KERN_DEBUG " Tx scavenge %d status %8.8x.\n",
 				   entry, txstatus);
+		if (txstatus & DescOwn)
+			break;
 		if (txstatus & 0x8000) {
 			if (debug > 1)
 				printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n",
@@ -1341,10 +1364,22 @@
 			if (txstatus & 0x0200) np->stats.tx_window_errors++;
 			if (txstatus & 0x0100) np->stats.tx_aborted_errors++;
 			if (txstatus & 0x0080) np->stats.tx_heartbeat_errors++;
-			if (txstatus & 0x0002) np->stats.tx_fifo_errors++;
+			if (((np->chip_id == VT86C100A) && txstatus & 0x0002) ||
+				(txstatus & 0x0800) || (txstatus & 0x1000)) {
+				np->stats.tx_fifo_errors++;
+				np->tx_ring[entry].tx_status = cpu_to_le32(DescOwn);
+				break; /* Keep the skb - we try again */
+			}
 			/* Transmitter restarted in 'abnormal' handler. */
 		} else {
-			np->stats.collisions += (txstatus >> 3) & 15;
+			if (np->chip_id == VT86C100A)
+				np->stats.collisions += (txstatus >> 3) & 0x0F;
+			else
+				np->stats.collisions += txstatus & 0x0F;
+			if (debug > 6)
+				printk(KERN_DEBUG "collisions: %1.1x:%1.1x\n",
+					(txstatus >> 3) & 0xF,
+					txstatus & 0xF);
 			np->stats.tx_bytes += np->tx_skbuff[entry]->len;
 			np->stats.tx_packets++;
 		}
@@ -1480,6 +1515,17 @@
 	writew(CmdRxDemand | np->chip_cmd, dev->base_addr + ChipCmd);
 }
 
+static inline void via_restart_tx(struct net_device *dev) {
+	struct netdev_private *np = dev->priv;
+	int entry = np->dirty_tx % TX_RING_SIZE;
+
+	/* We know better than the chip where it should continue */
+	writel(np->tx_ring_dma + entry * sizeof(struct tx_desc),
+		   dev->base_addr + TxRingPtr);
+
+	writew(CmdTxDemand | np->chip_cmd, dev->base_addr + ChipCmd);
+}
+
 static void via_rhine_error(struct net_device *dev, int intr_status)
 {
 	struct netdev_private *np = dev->priv;
@@ -1505,19 +1551,23 @@
 		np->stats.rx_missed_errors	+= readw(ioaddr + RxMissed);
 		clear_tally_counters(ioaddr);
 	}
-	if (intr_status & IntrTxAbort) {
-		/* Stats counted in Tx-done handler, just restart Tx. */
-		writew(CmdTxDemand | np->chip_cmd, dev->base_addr + ChipCmd);
+	if (intr_status & IntrTxError) {
+		if (debug > 1)
+			printk(KERN_INFO "%s: Abort %4.4x, frame dropped.\n",
+				   dev->name, intr_status);
+		via_restart_tx(dev);
 	}
 	if (intr_status & IntrTxUnderrun) {
 		if (np->tx_thresh < 0xE0)
 			writeb(np->tx_thresh += 0x20, ioaddr + TxConfig);
 		if (debug > 1)
-			printk(KERN_INFO "%s: Transmitter underrun, increasing Tx "
-				   "threshold setting to %2.2x.\n", dev->name, np->tx_thresh);
+			printk(KERN_INFO "%s: Transmitter underrun, Tx "
+				   "threshold now %2.2x.\n",
+				   dev->name, np->tx_thresh);
+		via_restart_tx(dev);
 	}
 	if (intr_status & ~( IntrLinkChange | IntrStatsMax |
- 						 IntrTxAbort | IntrTxAborted | IntrNormalSummary)) {
+ 						 IntrTxError | IntrTxAborted | IntrNormalSummary)) {
 		if (debug > 1)
 			printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n",
 			   dev->name, intr_status);
diff -Nru a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
--- a/drivers/net/wan/cosa.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/net/wan/cosa.c	Mon Dec  9 18:46:34 2002
@@ -357,8 +357,6 @@
 
 /* ---------- Initialization stuff ---------- */
 
-static devfs_handle_t devfs_handle;
-
 #ifdef MODULE
 int init_module(void)
 #else
@@ -387,16 +385,20 @@
 		cosa_cards[i].num = -1;
 	for (i=0; io[i] != 0 && i < MAX_CARDS; i++)
 		cosa_probe(io[i], irq[i], dma[i]);
-	devfs_handle = devfs_mk_dir (NULL, "cosa", NULL);
-	devfs_register_series (devfs_handle, "%u", nr_cards, DEVFS_FL_DEFAULT,
-			       cosa_major, 0,
-			       S_IFCHR | S_IRUSR | S_IWUSR,
-			       &cosa_fops, NULL);
 	if (!nr_cards) {
 		printk(KERN_WARNING "cosa: no devices found.\n");
 		unregister_chrdev(cosa_major, "cosa");
 		return -ENODEV;
 	}
+	devfs_mk_dir (NULL, "cosa", NULL);
+	for (i=0; i<nr_cards; i++) {
+		char name[16];
+		sprintf(name, "cosa/%d", i);
+		devfs_register(NULL, name, DEVFS_FL_DEFAULT,
+			       cosa_major, i,
+			       S_IFCHR | S_IRUSR | S_IWUSR,
+			       &cosa_fops, NULL);
+	}
 	return 0;
 }
 
@@ -404,11 +406,13 @@
 void cleanup_module (void)
 {
 	struct cosa_data *cosa;
+	int i;
 	printk(KERN_INFO "Unloading the cosa module\n");
 
-	devfs_unregister (devfs_handle);
+	for (i=0; i<nr_cards; i++)
+		devfs_remove("cosa/%d", i);
+	devfs_remove("cosa");
 	for (cosa=cosa_cards; nr_cards--; cosa++) {
-		int i;
 		/* Clean up the per-channel data */
 		for (i=0; i<cosa->nchannels; i++) {
 			/* Chardev driver has no alloc'd per-channel data */
@@ -443,7 +447,7 @@
 static int cosa_probe(int base, int irq, int dma)
 {
 	struct cosa_data *cosa = cosa_cards+nr_cards;
-	int i;
+	int i, err = 0;
 
 	memset(cosa, 0, sizeof(struct cosa_data));
 
@@ -478,12 +482,13 @@
 	cosa->statusreg = is_8bit(cosa)?base+1:base+2;
 	spin_lock_init(&cosa->lock);
 
-	if (check_region(base, is_8bit(cosa)?2:4))
+	if (!request_region(base, is_8bit(cosa)?2:4,"cosa"))
 		return -1;
 	
 	if (cosa_reset_and_read_id(cosa, cosa->id_string) < 0) {
 		printk(KERN_DEBUG "cosa: probe at 0x%x failed.\n", base);
-		return -1;
+		err = -1;
+		goto err_out;
 	}
 
 	/* Test the validity of identification string */
@@ -497,6 +502,13 @@
 		printk(KERN_INFO "cosa: valid signature not found at 0x%x.\n",
 			base);
 #endif
+		err = -1;
+		goto err_out;
+	}
+	/* Update the name of the region now we know the type of card */ 
+	release_region(base, is_8bit(cosa)?2:4);
+	if (!request_region(base, is_8bit(cosa)?2:4, cosa->type)) {
+		printk(KERN_DEBUG "cosa: changing name at 0x%x failed.\n", base);
 		return -1;
 	}
 
@@ -525,7 +537,8 @@
 		if (irq < 0) {
 			printk (KERN_INFO "cosa IRQ autoprobe: multiple interrupts obtained (%d, board at 0x%x)\n",
 				irq, cosa->datareg);
-			return -1;
+			err = -1;
+			goto err_out;
 		}
 		if (irq == 0) {
 			printk (KERN_INFO "cosa IRQ autoprobe: no interrupt obtained (board at 0x%x)\n",
@@ -539,23 +552,29 @@
 	cosa->usage = 0;
 	cosa->nchannels = 2;	/* FIXME: how to determine this? */
 
-	request_region(base, is_8bit(cosa)?2:4, cosa->type);
-	if (request_irq(cosa->irq, cosa_interrupt, 0, cosa->type, cosa))
-		goto bad1;
+	if (request_irq(cosa->irq, cosa_interrupt, 0, cosa->type, cosa)) {
+		err = -1;
+		goto err_out;
+	}
 	if (request_dma(cosa->dma, cosa->type)) {
-		free_irq(cosa->irq, cosa);
-bad1:		release_region(cosa->datareg,is_8bit(cosa)?2:4);
-		printk(KERN_NOTICE "cosa%d: allocating resources failed\n",
-			cosa->num);
-		return -1;
+		err = -1;
+		goto err_out1;
 	}
 	
 	cosa->bouncebuf = kmalloc(COSA_MTU, GFP_KERNEL|GFP_DMA);
+	if (!cosa->bouncebuf) {
+		err = -ENOMEM;
+		goto err_out2;
+	}
 	sprintf(cosa->name, "cosa%d", cosa->num);
 
 	/* Initialize the per-channel data */
 	cosa->chan = kmalloc(sizeof(struct channel_data)*cosa->nchannels,
-		GFP_KERNEL);
+			     GFP_KERNEL);
+	if (!cosa->chan) {
+	        err = -ENOMEM;
+		goto err_out3;
+	}
 	memset(cosa->chan, 0, sizeof(struct channel_data)*cosa->nchannels);
 	for (i=0; i<cosa->nchannels; i++) {
 		cosa->chan[i].cosa = cosa;
@@ -568,6 +587,17 @@
 		cosa->datareg, cosa->irq, cosa->dma, cosa->nchannels);
 
 	return nr_cards++;
+err_out3:
+	kfree(cosa->bouncebuf);
+err_out2:
+	free_dma(cosa->dma);
+err_out1:
+	free_irq(cosa->irq, cosa);
+err_out:	
+	release_region(cosa->datareg,is_8bit(cosa)?2:4);
+	printk(KERN_NOTICE "cosa%d: allocating resources failed\n",
+	       cosa->num);
+	return err;
 }
 
 
diff -Nru a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c
--- a/drivers/net/wan/hostess_sv11.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/net/wan/hostess_sv11.c	Mon Dec  9 18:46:50 2002
@@ -211,7 +211,6 @@
 {
 	struct z8530_dev *dev;
 	struct sv11_device *sv;
-	unsigned long flags;
 	
 	/*
 	 *	Get the needed I/O space
diff -Nru a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c
--- a/drivers/net/wan/lapbether.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/net/wan/lapbether.c	Mon Dec  9 18:46:36 2002
@@ -186,6 +186,7 @@
 	skb->mac.raw  = skb->data;
 	skb->pkt_type = PACKET_HOST;
 
+	skb->dev->last_rx = jiffies;
 	return netif_rx(skb);
 }
 
@@ -283,6 +284,7 @@
 	skb->mac.raw  = skb->data;
 	skb->pkt_type = PACKET_HOST;
 
+	skb->dev->last_rx = jiffies;
 	netif_rx(skb);
 }
 
@@ -305,6 +307,7 @@
 	skb->mac.raw  = skb->data;
 	skb->pkt_type = PACKET_HOST;
 
+	skb->dev->last_rx = jiffies;
 	netif_rx(skb);
 }
 
diff -Nru a/drivers/net/wan/lmc/lmc_proto.c b/drivers/net/wan/lmc/lmc_proto.c
--- a/drivers/net/wan/lmc/lmc_proto.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/net/wan/lmc/lmc_proto.c	Mon Dec  9 18:46:38 2002
@@ -253,6 +253,7 @@
     case LMC_PPP:
     case LMC_NET:
     default:
+        skb->dev->last_rx = jiffies;
         netif_rx(skb);
         break;
     case LMC_RAW:
diff -Nru a/drivers/net/wan/sdla_chdlc.c b/drivers/net/wan/sdla_chdlc.c
--- a/drivers/net/wan/sdla_chdlc.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/net/wan/sdla_chdlc.c	Mon Dec  9 18:46:37 2002
@@ -2219,6 +2219,7 @@
                 skb->dev = dev;
                 skb->mac.raw  = skb->data;
                 netif_rx(skb);
+                dev->last_rx = jiffies;
 	}
 
 rx_exit:
@@ -3276,6 +3277,7 @@
 	    		new_skb->mac.raw  = new_skb->data;
 	
 			netif_rx(new_skb);
+			dev->last_rx = jiffies;
 		} else {
 	    	
 			printk(KERN_INFO "%s: no socket buffers available!\n",
diff -Nru a/drivers/net/wan/sdla_fr.c b/drivers/net/wan/sdla_fr.c
--- a/drivers/net/wan/sdla_fr.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/net/wan/sdla_fr.c	Mon Dec  9 18:46:51 2002
@@ -225,10 +225,10 @@
 	sdla_t *card;			/* -> owner */
 	unsigned route_flag;		/* Add/Rem dest addr in route tables */
 	unsigned inarp;			/* Inverse Arp Request status */ 
-	unsigned char inarp_ready;	/* Ready to send requests */
+	long inarp_ready;		/* Ready to send requests */
 	int inarp_interval;		/* Time between InArp Requests */
 	unsigned long inarp_tick;	/* InArp jiffies tick counter */
-	unsigned char interface_down;	/* Bring interface down on disconnect */
+	long interface_down;		/* Bring interface down on disconnect */
       #if defined(LINUX_2_1) || defined(LINUX_2_4)
 	struct net_device_stats ifstats;	/* interface statistics */
       #else
@@ -259,8 +259,8 @@
 
 	u32 ip_local;
 	u32 ip_remote;
-	u8  config_dlci;
-	u32 unconfig_dlci;
+	long config_dlci;
+	long unconfig_dlci;
 
 	/* Whether this interface should be setup as a gateway.
 	 * Used by dynamic route setup code */
@@ -1459,7 +1459,8 @@
         int err;
     	unsigned char *sendpacket;
     	fr508_flags_t* adptr_flags = card->flags;
-	int udp_type, delay_tx_queued=0;
+	int udp_type;
+	long delay_tx_queued = 0;
 	unsigned long smp_flags=0;
 	unsigned char attr = 0;
 
@@ -2352,6 +2353,7 @@
 		
 
 		/* Send a packed up the IP stack */
+		skb->dev->last_rx = jiffies;
 		netif_rx(skb);
 		++chan->drvstats_rx_intr.rx_intr_bfr_passed_to_stack;
 		++chan->ifstats.rx_packets;
@@ -2810,7 +2812,7 @@
 				chan->name, NIPQUAD(chan->ip_remote));
 
 		}else {
-			printk(KERN_INFO "%s: Route Added Successfully: %u.%u.%u.%U\n",
+			printk(KERN_INFO "%s: Route Added Successfully: %u.%u.%u.%u\n",
 				card->devname,NIPQUAD(chan->ip_remote));
 			chan->route_flag = ROUTE_ADDED;
 		}
diff -Nru a/drivers/net/wan/sdla_ppp.c b/drivers/net/wan/sdla_ppp.c
--- a/drivers/net/wan/sdla_ppp.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/net/wan/sdla_ppp.c	Mon Dec  9 18:46:35 2002
@@ -1897,6 +1897,7 @@
 #endif
 		    		++ppp_priv_area->rx_intr_stat.rx_intr_bfr_passed_to_stack;	
 				netif_rx(skb);
+				dev->last_rx = jiffies;
 			}
 
 		} else {
@@ -2451,7 +2452,7 @@
 #endif
 
 		default:
-			printk(KERN_INFO "%s: ERROR: Unsuported PPP Mode Selected\n",
+			printk(KERN_INFO "%s: ERROR: Unsupported PPP Mode Selected\n",
 					card->devname);
 			printk(KERN_INFO "%s:        PPP IP Modes: STATIC, PEER or HOST\n",
 					card->devname);	
@@ -2943,6 +2944,7 @@
             		new_skb->dev = dev;
 	    		new_skb->mac.raw  = new_skb->data;
 			netif_rx(new_skb);
+			dev->last_rx = jiffies;
 		
 		} else {
 	    	
diff -Nru a/drivers/net/wan/sdlamain.c b/drivers/net/wan/sdlamain.c
--- a/drivers/net/wan/sdlamain.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/net/wan/sdlamain.c	Mon Dec  9 18:46:50 2002
@@ -503,7 +503,7 @@
 		}
 
 	}else{
-		printk(KERN_INFO "%s: Card Configured %i or Piggybacking %i!\n",
+		printk(KERN_INFO "%s: Card Configured %lu or Piggybacking %i!\n",
 			wandev->name,card->configured,card->wandev.piggyback);
 	} 
 
diff -Nru a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c
--- a/drivers/net/wan/sealevel.c	Mon Dec  9 18:46:49 2002
+++ b/drivers/net/wan/sealevel.c	Mon Dec  9 18:46:49 2002
@@ -211,8 +211,6 @@
 	struct z8530_dev *dev;
 	struct slvl_device *sv;
 	struct slvl_board *b;
-	
-	unsigned long flags;
 	int u;
 	
 	/*
diff -Nru a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c
--- a/drivers/net/wan/syncppp.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/net/wan/syncppp.c	Mon Dec  9 18:46:35 2002
@@ -276,6 +276,7 @@
 					printk(KERN_DEBUG "Yow an IP frame.\n");
 				skb->protocol=htons(ETH_P_IP);
 				netif_rx(skb);
+				dev->last_rx = jiffies;
 				return;
 			}
 			break;
@@ -285,6 +286,7 @@
 			if (sp->lcp.state == LCP_STATE_OPENED) {
 				skb->protocol=htons(ETH_P_IPX);
 				netif_rx(skb);
+				dev->last_rx = jiffies;
 				return;
 			}
 			break;
@@ -312,12 +314,14 @@
 		case ETH_P_IP:
 			skb->protocol=htons(ETH_P_IP);
 			netif_rx(skb);
+			dev->last_rx = jiffies;
 			return;
 #endif
 #ifdef CONFIG_IPX
 		case ETH_P_IPX:
 			skb->protocol=htons(ETH_P_IPX);
 			netif_rx(skb);
+			dev->last_rx = jiffies;
 			return;
 #endif
 		}
diff -Nru a/drivers/net/wan/wanpipe_multppp.c b/drivers/net/wan/wanpipe_multppp.c
--- a/drivers/net/wan/wanpipe_multppp.c	Mon Dec  9 18:46:52 2002
+++ b/drivers/net/wan/wanpipe_multppp.c	Mon Dec  9 18:46:52 2002
@@ -1572,6 +1572,7 @@
                 skb->dev = dev;
                 skb->mac.raw  = skb->data;
                 netif_rx(skb);
+                dev->last_rx = jiffies;
 	}
 
 rx_exit:
@@ -2175,6 +2176,7 @@
 	    		new_skb->mac.raw  = new_skb->data;
 	
 			netif_rx(new_skb);
+			dev->last_rx = jiffies;
 		} else {
 	    	
 			printk(KERN_INFO "%s: no socket buffers available!\n",
@@ -2470,6 +2472,7 @@
 		new_skb->mac.raw  = new_skb->data;
 
 		netif_rx(new_skb);
+		dev->last_rx = jiffies;
 	}
 }
 
diff -Nru a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
--- a/drivers/net/wan/x25_asy.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/net/wan/x25_asy.c	Mon Dec  9 18:46:35 2002
@@ -250,6 +250,7 @@
 	else
 	{
 		netif_rx(skb);
+		sl->dev->last_rx = jiffies;
 		sl->rx_packets++;
 	}
 }
@@ -397,6 +398,7 @@
   
 static int x25_asy_data_indication(void *token, struct sk_buff *skb)
 {
+	skb->dev->last_rx = jiffies;
 	return netif_rx(skb);
 }
 
@@ -449,6 +451,7 @@
 	skb->pkt_type = PACKET_HOST;
 
 	netif_rx(skb);
+	sl->dev->last_rx = jiffies;
 }
 
 static void x25_asy_disconnected(void *token, int reason)
@@ -471,6 +474,7 @@
 	skb->pkt_type = PACKET_HOST;
 
 	netif_rx(skb);
+	sl->dev->last_rx = jiffies;
 }
 
 
diff -Nru a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
--- a/drivers/oprofile/buffer_sync.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/oprofile/buffer_sync.c	Mon Dec  9 18:46:35 2002
@@ -245,7 +245,7 @@
  
 static inline int is_kernel(unsigned long val)
 {
-	return val > __PAGE_OFFSET;
+	return val > PAGE_OFFSET;
 }
 
 
diff -Nru a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
--- a/drivers/oprofile/cpu_buffer.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/oprofile/cpu_buffer.c	Mon Dec  9 18:46:34 2002
@@ -21,6 +21,7 @@
 #include <linux/vmalloc.h>
 #include <linux/smp.h>
 #include <linux/errno.h>
+#include <linux/cache.h>
  
 #include "cpu_buffer.h"
 #include "oprof.h"
diff -Nru a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h
--- a/drivers/oprofile/cpu_buffer.h	Mon Dec  9 18:46:51 2002
+++ b/drivers/oprofile/cpu_buffer.h	Mon Dec  9 18:46:51 2002
@@ -12,6 +12,7 @@
 
 #include <linux/types.h>
 #include <linux/spinlock.h>
+#include <linux/cache.h>
  
 struct task_struct;
  
diff -Nru a/drivers/parport/daisy.c b/drivers/parport/daisy.c
--- a/drivers/parport/daisy.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/parport/daisy.c	Mon Dec  9 18:46:35 2002
@@ -21,6 +21,9 @@
 
 #include <linux/parport.h>
 #include <linux/delay.h>
+#include <linux/sched.h>
+
+#include <asm/current.h>
 #include <asm/uaccess.h>
 
 #define DEBUG /* undef me for production */
diff -Nru a/drivers/parport/ieee1284_ops.c b/drivers/parport/ieee1284_ops.c
--- a/drivers/parport/ieee1284_ops.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/parport/ieee1284_ops.c	Mon Dec  9 18:46:51 2002
@@ -17,6 +17,7 @@
 #include <linux/config.h>
 #include <linux/parport.h>
 #include <linux/delay.h>
+#include <linux/sched.h>
 #include <asm/uaccess.h>
 
 #undef DEBUG /* undef me for production */
diff -Nru a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
--- a/drivers/parport/parport_pc.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/parport/parport_pc.c	Mon Dec  9 18:46:51 2002
@@ -2973,7 +2973,7 @@
 #endif /* CONFIG_PCI */
 
 #ifdef CONFIG_PNP
-static const struct pnp_id pnp_dev_table[] = {
+static const struct pnp_device_id pnp_dev_table[] = {
 	/* Standard LPT Printer Port */
 	{.id = "PNP0400", .driver_data = 0},
 	/* ECP Printer Port */
@@ -2984,7 +2984,6 @@
 /* we only need the pnp layer to activate the device, at least for now */
 static struct pnp_driver parport_pc_pnp_driver = {
 	.name		= "parport_pc",
-	.card_id_table	= NULL,
 	.id_table	= pnp_dev_table,
 };
 #else
diff -Nru a/drivers/parport/probe.c b/drivers/parport/probe.c
--- a/drivers/parport/probe.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/parport/probe.c	Mon Dec  9 18:46:35 2002
@@ -7,6 +7,7 @@
 
 #include <linux/parport.h>
 #include <linux/ctype.h>
+#include <linux/string.h>
 #include <asm/uaccess.h>
 
 static struct {
diff -Nru a/drivers/pci/pci.c b/drivers/pci/pci.c
--- a/drivers/pci/pci.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/pci/pci.c	Mon Dec  9 18:46:35 2002
@@ -88,6 +88,8 @@
  *  %PCI_CAP_ID_MSI          Message Signalled Interrupts
  *
  *  %PCI_CAP_ID_CHSWP        CompactPCI HotSwap 
+ *
+ *  %PCI_CAP_ID_PCIX         PCI-X
  */
 int
 pci_find_capability(struct pci_dev *dev, int cap)
diff -Nru a/drivers/pci/probe.c b/drivers/pci/probe.c
--- a/drivers/pci/probe.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/pci/probe.c	Mon Dec  9 18:46:50 2002
@@ -448,6 +448,7 @@
 
 	/* now put in global tree */
 	strcpy(dev->dev.bus_id,dev->slot_name);
+	dev->dev.dma_mask = &dev->dma_mask;
 
 	device_register(&dev->dev);
 	return dev;
diff -Nru a/drivers/pci/quirks.c b/drivers/pci/quirks.c
--- a/drivers/pci/quirks.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/pci/quirks.c	Mon Dec  9 18:46:34 2002
@@ -301,7 +301,8 @@
 
 
 #ifdef CONFIG_X86_IO_APIC 
-extern int nr_ioapics;
+
+#include <asm/io_apic.h>
 
 /*
  * VIA 686A/B: If an IO-APIC is active, we need to route all on-chip
@@ -561,7 +562,7 @@
 #ifdef CONFIG_X86_IO_APIC 
 	{ PCI_FIXUP_FINAL,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686,	quirk_via_ioapic },
 	{ PCI_FIXUP_FINAL, 	PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_VIPER_7410,	quirk_amd_ioapic },
-	{ PCI_FIXUP_FINAL,	PCI_VENDOR_ID_SIS,	PCI_ANY_ID,			quirk_ioapic_rmw },
+	{ PCI_FIXUP_FINAL,	PCI_VENDOR_ID_SI,	PCI_ANY_ID,			quirk_ioapic_rmw },
 #endif
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C586_3,	quirk_via_acpi },
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_4,	quirk_via_acpi },
diff -Nru a/drivers/pnp/Kconfig b/drivers/pnp/Kconfig
--- a/drivers/pnp/Kconfig	Mon Dec  9 18:46:37 2002
+++ b/drivers/pnp/Kconfig	Mon Dec  9 18:46:37 2002
@@ -2,7 +2,7 @@
 # Plug and Play configuration
 #
 
-menu "Plug and Play configuration"
+menu "Plug and Play support"
 
 config PNP
 	bool "Plug and Play support"
@@ -30,11 +30,20 @@
 
 	  If unsure, say Y.
 
+config PNP_CARD
+	bool "Plug and Play card services"
+	depends on PNP
+	help
+	  Select Y if you want the PnP Layer to manage cards.  Cards are groups
+	  of PnP devices.  Some drivers, especially PnP sound card drivers, use
+	  these cards.  If you want to use the protocol ISAPNP you will need to
+	  say Y here.
+
 config PNP_DEBUG
 	bool "PnP Debug Messages"
 	depends on PNP
 	help
-	  Say Y if you want the Plug and Play Layer to print debug messages.  
+	  Say Y if you want the Plug and Play Layer to print debug messages.
 	  This is useful if you are developing a PnP driver or troubleshooting.
 
 comment "Protocols"
@@ -42,7 +51,7 @@
 
 config ISAPNP
 	bool "ISA Plug and Play support (EXPERIMENTAL)"
-	depends on PNP && EXPERIMENTAL
+	depends on PNP && EXPERIMENTAL && PNP_CARD
 	help
 	  Say Y here if you would like support for ISA Plug and Play devices.
 	  Some information is in <file:Documentation/isapnp.txt>.
diff -Nru a/drivers/pnp/Makefile b/drivers/pnp/Makefile
--- a/drivers/pnp/Makefile	Mon Dec  9 18:46:34 2002
+++ b/drivers/pnp/Makefile	Mon Dec  9 18:46:34 2002
@@ -2,11 +2,13 @@
 # Makefile for the Linux Plug-and-Play Support.
 #
 
-obj-y		:= core.o driver.o resource.o interface.o quirks.o names.o system.o
+pnp-card-$(CONFIG_PNP_CARD) = card.o
+
+obj-y		:= core.o driver.o resource.o interface.o quirks.o names.o system.o $(pnp-card-y)
 
 obj-$(CONFIG_PNPBIOS)		+= pnpbios/
 obj-$(CONFIG_ISAPNP)		+= isapnp/
 
-export-objs	:= core.o driver.o resource.o
+export-objs	:= core.o driver.o resource.o $(pnp-card-y)
 
 include $(TOPDIR)/Rules.make
diff -Nru a/drivers/pnp/base.h b/drivers/pnp/base.h
--- a/drivers/pnp/base.h	Mon Dec  9 18:46:35 2002
+++ b/drivers/pnp/base.h	Mon Dec  9 18:46:35 2002
@@ -4,5 +4,6 @@
 extern int pnp_interface_attach_device(struct pnp_dev *dev);
 extern void pnp_name_device(struct pnp_dev *dev);
 extern void pnp_fixup_device(struct pnp_dev *dev);
-extern void pnp_free_ids(struct pnp_dev *dev);
 extern void pnp_free_resources(struct pnp_resources *resources);
+extern int __pnp_add_device(struct pnp_dev *dev);
+extern void __pnp_remove_device(struct pnp_dev *dev);
diff -Nru a/drivers/pnp/card.c b/drivers/pnp/card.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/pnp/card.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,342 @@
+/*
+ * card.c - contains functions for managing groups of PnP devices
+ *
+ * Copyright 2002 Adam Belay <ambx1@neo.rr.com>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#ifdef CONFIG_PNP_DEBUG
+	#define DEBUG
+#else
+	#undef DEBUG
+#endif
+
+#include <linux/pnp.h>
+#include <linux/init.h>
+#include "base.h"
+
+
+LIST_HEAD(pnp_cards);
+
+static const struct pnp_card_id * match_card(struct pnpc_driver *drv, struct pnp_card *card)
+{
+	const struct pnp_card_id *drv_id = drv->id_table;
+	while (*drv_id->id){
+		if (compare_pnp_id(card->id,drv_id->id))
+			return drv_id;
+		drv_id++;
+	}
+	return NULL;
+}
+
+static int card_bus_match(struct device *dev, struct device_driver *drv)
+{
+	struct pnp_card * card = to_pnp_card(dev);
+	struct pnpc_driver * pnp_drv = to_pnpc_driver(drv);
+	if (match_card(pnp_drv, card) == NULL)
+		return 0;
+	return 1;
+}
+
+struct bus_type pnpc_bus_type = {
+	name:	"pnp_card",
+	match:	card_bus_match,
+};
+
+
+/**
+ * pnpc_add_id - adds an EISA id to the specified card
+ * @id: pointer to a pnp_id structure
+ * @card: pointer to the desired card
+ *
+ */
+
+int pnpc_add_id(struct pnp_id *id, struct pnp_card *card)
+{
+	struct pnp_id *ptr;
+	if (!id)
+		return -EINVAL;
+	if (!card)
+		return -EINVAL;
+	ptr = card->id;
+	while (ptr && ptr->next)
+		ptr = ptr->next;
+	if (ptr)
+		ptr->next = id;
+	else
+		card->id = id;
+	return 0;
+}
+
+static void pnpc_free_ids(struct pnp_card *card)
+{
+	struct pnp_id * id;
+	struct pnp_id *next;
+	if (!card)
+		return;
+	id = card->id;
+	while (id) {
+		next = id->next;
+		kfree(id);
+		id = next;
+	}
+}
+
+static void pnp_release_card(struct device *dmdev)
+{
+	struct pnp_card * card = to_pnp_card(dmdev);
+	pnpc_free_ids(card);
+	kfree(card);
+}
+
+/**
+ * pnpc_add_card - adds a PnP card to the PnP Layer
+ * @card: pointer to the card to add
+ */
+
+int pnpc_add_card(struct pnp_card *card)
+{
+	int error = 0;
+	if (!card || !card->protocol)
+		return -EINVAL;
+	sprintf(card->dev.bus_id, "%02x:%02x", card->protocol->number, card->number);
+	INIT_LIST_HEAD(&card->rdevs);
+	strcpy(card->dev.name,card->name);
+	card->dev.parent = &card->protocol->dev;
+	card->dev.bus = &pnpc_bus_type;
+	card->dev.release = &pnp_release_card;
+	error = device_register(&card->dev);
+	if (error == 0){
+		struct list_head *pos;
+		spin_lock(&pnp_lock);
+		list_add_tail(&card->global_list, &pnp_cards);
+		list_add_tail(&card->protocol_list, &card->protocol->cards);
+		spin_unlock(&pnp_lock);
+		list_for_each(pos,&card->devices){
+			struct pnp_dev *dev = card_to_pnp_dev(pos);
+			__pnp_add_device(dev);
+		}
+	}
+	return error;
+}
+
+/**
+ * pnpc_remove_card - removes a PnP card from the PnP Layer
+ * @card: pointer to the card to remove
+ */
+
+void pnpc_remove_card(struct pnp_card *card)
+{
+	struct list_head *pos;
+	if (!card)
+		return;
+	device_unregister(&card->dev);
+	spin_lock(&pnp_lock);
+	list_del_init(&card->global_list);
+	list_del_init(&card->protocol_list);
+	spin_unlock(&pnp_lock);
+	list_for_each(pos,&card->devices){
+		struct pnp_dev *dev = card_to_pnp_dev(pos);
+		__pnp_remove_device(dev);
+	}
+}
+
+/**
+ * pnpc_add_device - adds a device to the specified card
+ * @card: pointer to the card to add to
+ * @dev: pointer to the device to add
+ */
+
+int pnpc_add_device(struct pnp_card *card, struct pnp_dev *dev)
+{
+	if (!dev || !dev->protocol || !card)
+		return -EINVAL;
+	dev->dev.parent = &card->dev;
+	sprintf(dev->dev.bus_id, "%02x:%02x.%02x", dev->protocol->number, card->number,dev->number);
+	spin_lock(&pnp_lock);
+	dev->card = card;
+	list_add_tail(&dev->card_list, &card->devices);
+	spin_unlock(&pnp_lock);
+	return 0;
+}
+
+/**
+ * pnpc_remove_device- removes a device from the specified card
+ * @card: pointer to the card to remove from
+ * @dev: pointer to the device to remove
+ */
+
+void pnpc_remove_device(struct pnp_dev *dev)
+{
+	spin_lock(&pnp_lock);
+	dev->card = NULL;
+	list_del_init(&dev->card_list);
+	spin_unlock(&pnp_lock);
+	__pnp_remove_device(dev);
+}
+
+/**
+ * pnp_request_card_device - Searches for a PnP device under the specified card
+ * @card: pointer to the card to search under, cannot be NULL
+ * @id: pointer to a PnP ID structure that explains the rules for finding the device
+ * @from: Starting place to search from. If NULL it will start from the begining.
+ *
+ * Will activate the device
+ */
+
+struct pnp_dev * pnp_request_card_device(struct pnp_card *card, const char *id, struct pnp_dev *from)
+{
+	struct list_head *pos;
+	struct pnp_dev *dev;
+	if (!card || !id)
+		goto done;
+	if (!from) {
+		pos = card->devices.next;
+	} else {
+		if (from->card != card)
+			goto done;
+		pos = from->card_list.next;
+	}
+	while (pos != &card->devices) {
+		dev = card_to_pnp_dev(pos);
+		if (compare_pnp_id(dev->id,id))
+			goto found;
+		pos = pos->next;
+	}
+
+done:
+	return NULL;
+
+found:
+	if (dev->active == 0)
+		if(pnp_activate_dev(dev)<0)
+			return NULL;
+	spin_lock(&pnp_lock);
+	list_add_tail(&dev->rdev_list, &card->rdevs);
+	spin_unlock(&pnp_lock);
+	return dev;
+}
+
+/**
+ * pnp_release_card_device - call this when the driver no longer needs the device
+ * @dev: pointer to the PnP device stucture
+ *
+ * Will disable the device
+ */
+
+void pnp_release_card_device(struct pnp_dev *dev)
+{
+	spin_lock(&pnp_lock);
+	list_del_init(&dev->rdev_list);
+	spin_unlock(&pnp_lock);
+	pnp_disable_dev(dev);
+}
+
+static void pnpc_recover_devices(struct pnp_card *card)
+{
+	struct list_head *pos;
+	list_for_each(pos,&card->rdevs){
+		struct pnp_dev *dev = list_entry(pos, struct pnp_dev, rdev_list);
+		pnp_release_card_device(dev);
+	}
+}
+
+static int pnpc_card_probe(struct device *dev)
+{
+	int error = 0;
+	struct pnpc_driver *drv = to_pnpc_driver(dev->driver);
+	struct pnp_card *card = to_pnp_card(dev);
+	const struct pnp_card_id *card_id = NULL;
+
+	pnp_dbg("pnp: match found with the PnP card '%s' and the driver '%s'", dev->bus_id,drv->name);
+
+	if (drv->probe) {
+		card_id = match_card(drv, card);
+		if (card_id != NULL)
+			error = drv->probe(card, card_id);
+		if (error >= 0){
+			card->driver = drv;
+			error = 0;
+		} else
+			pnpc_recover_devices(card);
+	}
+	return error;
+}
+
+static int pnpc_card_remove(struct device *dev)
+{
+	struct pnp_card * card = to_pnp_card(dev);
+	struct pnpc_driver * drv = card->driver;
+
+	if (drv) {
+		if (drv->remove)
+			drv->remove(card);
+		card->driver = NULL;
+	}
+	pnpc_recover_devices(card);
+	return 0;
+}
+
+/**
+ * pnpc_register_driver - registers a PnP card driver with the PnP Layer
+ * @cdrv: pointer to the driver to register
+ */
+
+int pnpc_register_driver(struct pnpc_driver * drv)
+{
+	int count;
+	struct list_head *pos;
+
+	drv->driver.name = drv->name;
+	drv->driver.bus = &pnpc_bus_type;
+	drv->driver.probe = pnpc_card_probe;
+	drv->driver.remove = pnpc_card_remove;
+
+	pnp_dbg("the card driver '%s' has been registered", drv->name);
+
+	count = driver_register(&drv->driver);
+
+	/* get the number of initial matches */
+	if (count >= 0){
+		count = 0;
+		list_for_each(pos,&drv->driver.devices){
+			count++;
+		}
+	}
+	return count;
+}
+
+/**
+ * pnpc_unregister_driver - unregisters a PnP card driver from the PnP Layer
+ * @cdrv: pointer to the driver to unregister
+ *
+ * Automatically disables requested devices
+ */
+
+void pnpc_unregister_driver(struct pnpc_driver *drv)
+{
+	driver_unregister(&drv->driver);
+	pnp_dbg("the card driver '%s' has been unregistered", drv->name);
+}
+
+static int __init pnp_card_init(void)
+{
+	printk(KERN_INFO "pnp: Enabling Plug and Play Card Services.\n");
+	return bus_register(&pnpc_bus_type);
+}
+
+subsys_initcall(pnp_card_init);
+
+EXPORT_SYMBOL(pnpc_add_card);
+EXPORT_SYMBOL(pnpc_remove_card);
+EXPORT_SYMBOL(pnpc_add_device);
+EXPORT_SYMBOL(pnpc_remove_device);
+EXPORT_SYMBOL(pnp_request_card_device);
+EXPORT_SYMBOL(pnp_release_card_device);
+EXPORT_SYMBOL(pnpc_register_driver);
+EXPORT_SYMBOL(pnpc_unregister_driver);
+EXPORT_SYMBOL(pnpc_add_id);
diff -Nru a/drivers/pnp/core.c b/drivers/pnp/core.c
--- a/drivers/pnp/core.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/pnp/core.c	Mon Dec  9 18:46:35 2002
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/string.h>
 #include <linux/slab.h>
+#include <linux/errno.h>
 
 #include "base.h"
 
@@ -41,7 +42,7 @@
  *  Ex protocols: ISAPNP, PNPBIOS, etc
  */
 
-int pnp_protocol_register(struct pnp_protocol *protocol)
+int pnp_register_protocol(struct pnp_protocol *protocol)
 {
 	int nodenum;
 	struct list_head * pos;
@@ -50,6 +51,7 @@
 		return -EINVAL;
 
 	INIT_LIST_HEAD(&protocol->devices);
+	INIT_LIST_HEAD(&protocol->cards);
 	nodenum = 0;
 	spin_lock(&pnp_lock);
 
@@ -76,7 +78,7 @@
  * @protocol: pointer to the corresponding pnp_protocol structure
  *
  */
-void pnp_protocol_unregister(struct pnp_protocol *protocol)
+void pnp_unregister_protocol(struct pnp_protocol *protocol)
 {
 	spin_lock(&pnp_lock);
 	list_del_init(&protocol->protocol_list);
@@ -84,17 +86,19 @@
 	device_unregister(&protocol->dev);
 }
 
-/**
- * pnp_init_device - pnp protocols should call this before adding a PnP device
- * @dev: pointer to dev to init
- *
- *  for now it only inits dev->ids, more later?
- */
 
-int pnp_init_device(struct pnp_dev *dev)
+static void pnp_free_ids(struct pnp_dev *dev)
 {
-	INIT_LIST_HEAD(&dev->ids);
-	return 0;
+	struct pnp_id * id;
+	struct pnp_id * next;
+	if (!dev)
+		return;
+	id = dev->id;
+	while (id) {
+		next = id->next;
+		kfree(id);
+		id = next;
+	}
 }
 
 static void pnp_release_device(struct device *dmdev)
@@ -106,68 +110,73 @@
 	kfree(dev);
 }
 
-/**
- * pnp_add_device - adds a pnp device to the pnp layer
- * @dev: pointer to dev to add
- *
- *  adds to driver model, name database, fixups, interface, etc.
- */
-
-int pnp_add_device(struct pnp_dev *dev)
+int __pnp_add_device(struct pnp_dev *dev)
 {
 	int error = 0;
-	if (!dev || !dev->protocol)
-		return -EINVAL;
-	if (dev->card)
-		sprintf(dev->dev.bus_id, "%02x:%02x.%02x", dev->protocol->number,
-		  dev->card->number,dev->number);
-	else
-		sprintf(dev->dev.bus_id, "%02x:%02x", dev->protocol->number,
-		  dev->number);
 	pnp_name_device(dev);
 	pnp_fixup_device(dev);
 	strcpy(dev->dev.name,dev->name);
-	dev->dev.parent = &dev->protocol->dev;
 	dev->dev.bus = &pnp_bus_type;
 	dev->dev.release = &pnp_release_device;
 	error = device_register(&dev->dev);
 	if (error == 0){
 		spin_lock(&pnp_lock);
 		list_add_tail(&dev->global_list, &pnp_global);
-		list_add_tail(&dev->dev_list, &dev->protocol->devices);
+		list_add_tail(&dev->protocol_list, &dev->protocol->devices);
 		spin_unlock(&pnp_lock);
 		pnp_interface_attach_device(dev);
 	}
 	return error;
 }
 
+/*
+ * pnp_add_device - adds a pnp device to the pnp layer
+ * @dev: pointer to dev to add
+ *
+ *  adds to driver model, name database, fixups, interface, etc.
+ */
+
+int pnp_add_device(struct pnp_dev *dev)
+{
+	if (!dev || !dev->protocol || dev->card)
+		return -EINVAL;
+	dev->dev.parent = &dev->protocol->dev;
+	sprintf(dev->dev.bus_id, "%02x:%02x", dev->protocol->number, dev->number);
+	return __pnp_add_device(dev);
+}
+
+void __pnp_remove_device(struct pnp_dev *dev)
+{
+	spin_lock(&pnp_lock);
+	list_del_init(&dev->global_list);
+	list_del_init(&dev->protocol_list);
+	spin_unlock(&pnp_lock);
+	device_unregister(&dev->dev);
+}
+
 /**
  * pnp_remove_device - removes a pnp device from the pnp layer
  * @dev: pointer to dev to add
  *
  * this function will free all mem used by dev
  */
+
 void pnp_remove_device(struct pnp_dev *dev)
 {
-	if (!dev)
+	if (!dev || dev->card)
 		return;
-	device_unregister(&dev->dev);
-	spin_lock(&pnp_lock);
-	list_del_init(&dev->global_list);
-	list_del_init(&dev->dev_list);
-	spin_unlock(&pnp_lock);
+	__pnp_remove_device(dev);
 }
 
 static int __init pnp_init(void)
 {
-	printk(KERN_INFO "Linux Plug and Play Support v0.9 (c) Adam Belay\n");
+	printk(KERN_INFO "Linux Plug and Play Support v0.93 (c) Adam Belay\n");
 	return bus_register(&pnp_bus_type);
 }
 
 subsys_initcall(pnp_init);
 
-EXPORT_SYMBOL(pnp_protocol_register);
-EXPORT_SYMBOL(pnp_protocol_unregister);
+EXPORT_SYMBOL(pnp_register_protocol);
+EXPORT_SYMBOL(pnp_unregister_protocol);
 EXPORT_SYMBOL(pnp_add_device);
 EXPORT_SYMBOL(pnp_remove_device);
-EXPORT_SYMBOL(pnp_init_device);
diff -Nru a/drivers/pnp/driver.c b/drivers/pnp/driver.c
--- a/drivers/pnp/driver.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/pnp/driver.c	Mon Dec  9 18:46:50 2002
@@ -34,46 +34,30 @@
 	return 1;
 }
 
-int compare_pnp_id(struct list_head *id_list, const char *id)
+int compare_pnp_id(struct pnp_id *pos, const char *id)
 {
-	struct list_head *pos;
-	if (!id_list || !id || (strlen(id) != 7))
+	if (!pos || !id || (strlen(id) != 7))
 		return 0;
 	if (memcmp(id,"ANYDEVS",7)==0)
 		return 1;
-	list_for_each(pos,id_list){
-		struct pnp_id *pnp_id = to_pnp_id(pos);
-		if (memcmp(pnp_id->id,id,3)==0)
-			if (compare_func(pnp_id->id,id)==1)
+	while (pos){
+		if (memcmp(pos->id,id,3)==0)
+			if (compare_func(pos->id,id)==1)
 				return 1;
+		pos = pos->next;
 	}
 	return 0;
 }
 
-static const struct pnp_id * match_card(struct pnp_driver *drv, struct pnp_card *card)
+static const struct pnp_device_id * match_device(struct pnp_driver *drv, struct pnp_dev *dev)
 {
-	const struct pnp_id *drv_card_id = drv->card_id_table;
-	if (!drv)
-		return NULL;
-	if (!card)
-		return NULL;
-	while (*drv_card_id->id){
-		if (compare_pnp_id(&card->ids,drv_card_id->id))
-			return drv_card_id;
-		drv_card_id++;
-	}
-	return NULL;
-}
-
-static const struct pnp_id * match_device(struct pnp_driver *drv, struct pnp_dev *dev)
-{
-	const struct pnp_id *drv_id = drv->id_table;
+	const struct pnp_device_id *drv_id = drv->id_table;
 	if (!drv)
 		return NULL;
 	if (!dev)
 		return NULL;
 	while (*drv_id->id){
-		if (compare_pnp_id(&dev->ids,drv_id->id))
+		if (compare_pnp_id(dev->id,drv_id->id))
 			return drv_id;
 		drv_id++;
 	}
@@ -85,32 +69,23 @@
 	int error = 0;
 	struct pnp_driver *pnp_drv;
 	struct pnp_dev *pnp_dev;
-	const struct pnp_id *card_id = NULL;
-	const struct pnp_id *dev_id = NULL;
+	const struct pnp_device_id *dev_id = NULL;
 	pnp_dev = to_pnp_dev(dev);
 	pnp_drv = to_pnp_driver(dev->driver);
+
 	pnp_dbg("pnp: match found with the PnP device '%s' and the driver '%s'", dev->bus_id,pnp_drv->name);
 
 	if (pnp_dev->active == 0)
 		if(pnp_activate_dev(pnp_dev)<0)
 			return -1;
 	if (pnp_drv->probe && pnp_dev->active) {
-		if (pnp_dev->card && pnp_drv->card_id_table){
-			card_id = match_card(pnp_drv, pnp_dev->card);
-			if (card_id != NULL)
-				dev_id = match_device(pnp_drv, pnp_dev);
-			if (dev_id != NULL)
-				error = pnp_drv->probe(pnp_dev, card_id, dev_id);
-		}
-		else{
-			dev_id = match_device(pnp_drv, pnp_dev);
-			if (dev_id != NULL)
-				error = pnp_drv->probe(pnp_dev, card_id, dev_id);
-		}
-		if (error >= 0){
-			pnp_dev->driver = pnp_drv;
-			error = 0;
-		}
+		dev_id = match_device(pnp_drv, pnp_dev);
+		if (dev_id != NULL)
+			error = pnp_drv->probe(pnp_dev, dev_id);
+	}
+	if (error >= 0){
+		pnp_dev->driver = pnp_drv;
+		error = 0;
 	}
 	return error;
 }
@@ -133,9 +108,6 @@
 {
 	struct pnp_dev * pnp_dev = to_pnp_dev(dev);
 	struct pnp_driver * pnp_drv = to_pnp_driver(drv);
-	if (pnp_dev->card && pnp_drv->card_id_table
-	    && match_card(pnp_drv, pnp_dev->card) == NULL)
-		return 0;
 	if (match_device(pnp_drv, pnp_dev) == NULL)
 		return 0;
 	return 1;
@@ -174,8 +146,8 @@
 
 void pnp_unregister_driver(struct pnp_driver *drv)
 {
-	pnp_dbg("the driver '%s' has been unregistered", drv->name);
 	driver_unregister(&drv->driver);
+	pnp_dbg("the driver '%s' has been unregistered", drv->name);
 }
 
 /**
@@ -187,23 +159,19 @@
 
 int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev)
 {
+	struct pnp_id *ptr;
 	if (!id)
 		return -EINVAL;
 	if (!dev)
 		return -EINVAL;
-	list_add_tail(&id->id_list,&dev->ids);
+	ptr = dev->id;
+	while (ptr && ptr->next)
+		ptr = ptr->next;
+	if (ptr)
+		ptr->next = id;
+	else
+		dev->id = id;
 	return 0;
-}
-
-void pnp_free_ids(struct pnp_dev *dev)
-{
-	struct list_head *pos;
-	if (!dev)
-		return;
-	list_for_each(pos,&dev->ids){
-		struct pnp_id *pnp_id = to_pnp_id(pos);
-		kfree(pnp_id);
-	}
 }
 
 EXPORT_SYMBOL(pnp_register_driver);
diff -Nru a/drivers/pnp/interface.c b/drivers/pnp/interface.c
--- a/drivers/pnp/interface.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/pnp/interface.c	Mon Dec  9 18:46:35 2002
@@ -321,13 +321,13 @@
 static ssize_t pnp_show_current_ids(struct device *dmdev, char *buf, size_t count, loff_t off)
 {
 	char *str = buf;
-	struct list_head * pos;
 	struct pnp_dev *dev = to_pnp_dev(dmdev);
+	struct pnp_id * pos = dev->id;
 	if (off)
 		return 0;
-	list_for_each(pos,&dev->ids) {
-		struct pnp_id * cur = to_pnp_id(pos);
-		str += sprintf(str,"%s\n", cur->id);
+	while (pos) {
+		str += sprintf(str,"%s\n", pos->id);
+		pos = pos->next;
 	}
 	return (str - buf);
 }
diff -Nru a/drivers/pnp/isapnp/Makefile b/drivers/pnp/isapnp/Makefile
--- a/drivers/pnp/isapnp/Makefile	Mon Dec  9 18:46:34 2002
+++ b/drivers/pnp/isapnp/Makefile	Mon Dec  9 18:46:34 2002
@@ -2,10 +2,10 @@
 # Makefile for the kernel ISAPNP driver.
 #
 
-export-objs := core.o compat.o
+export-objs := core.o
 
 isapnp-proc-$(CONFIG_PROC_FS) = proc.o
 
-obj-y := core.o compat.o $(isapnp-proc-y)
+obj-y := core.o $(isapnp-proc-y)
 
 include $(TOPDIR)/Rules.make
diff -Nru a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
--- a/drivers/pnp/isapnp/core.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/pnp/isapnp/core.c	Mon Dec  9 18:46:38 2002
@@ -449,13 +449,13 @@
 	dev = isapnp_alloc(sizeof(struct pnp_dev));
 	if (!dev)
 		return NULL;
-	pnp_init_device(dev);
 	dev->number = number;
 	isapnp_parse_id(dev, (tmp[1] << 8) | tmp[0], (tmp[3] << 8) | tmp[2]);
 	dev->regs = tmp[4];
 	dev->card = card;
 	if (size > 5)
 		dev->regs |= tmp[5] << 8;
+	dev->protocol = &isapnp_protocol;
 	return dev;
 }
 
@@ -640,7 +640,7 @@
 		return 1;
 	if (pnp_build_resource(dev, 0) == NULL)
 		return 1;
-	list_add_tail(&dev->card_list, &card->devices);
+	pnpc_add_device(card,dev);
 	while (1) {
 		if (isapnp_read_tag(&type, &size)<0)
 			return 1;
@@ -653,7 +653,7 @@
 				if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
 					return 1;
 				pnp_build_resource(dev,0);
-				list_add_tail(&dev->card_list, &card->devices);
+				pnpc_add_device(card,dev);
 				size = 0;
 				skip = 0;
 			} else {
@@ -848,7 +848,7 @@
 			device & 0x0f,
 			(device >> 12) & 0x0f,
 			(device >> 8) & 0x0f);
-	list_add_tail(&id->id_list,&card->ids);
+	pnpc_add_id(id,card);
 }
 
 /*
@@ -879,12 +879,11 @@
 			;
 		else if (checksum == 0x00 || checksum != header[8])	/* not valid CSN */
 			continue;
-		if ((card = isapnp_alloc(sizeof(struct pci_bus))) == NULL)
+		if ((card = isapnp_alloc(sizeof(struct pnp_card))) == NULL)
 			continue;
 
 		card->number = csn;
 		INIT_LIST_HEAD(&card->devices);
-		INIT_LIST_HEAD(&card->ids);
 		isapnp_parse_card_id(card, (header[1] << 8) | header[0], (header[3] << 8) | header[2]);
 		card->serial = (header[7] << 24) | (header[6] << 16) | (header[5] << 8) | header[4];
 		isapnp_checksum_value = 0x00;
@@ -892,8 +891,8 @@
 		if (isapnp_checksum_value != 0x00)
 			printk(KERN_ERR "isapnp: checksum for device %i is not valid (0x%x)\n", csn, isapnp_checksum_value);
 		card->checksum = isapnp_checksum_value;
-
-		list_add_tail(&card->node, &isapnp_cards);
+		card->protocol = &isapnp_protocol;
+		pnpc_add_card(card);
 	}
 	return 0;
 }
@@ -1061,25 +1060,6 @@
 	.disable = isapnp_disable_resources,
 };
 
-static inline int isapnp_init_device_tree(void)
-{
-
-	struct pnp_card *card;
-
-	isapnp_for_each_card(card) {
-		struct list_head *devlist;
-		for (devlist = card->devices.next; devlist != &card->devices; devlist = devlist->next) {
-			struct pnp_dev *dev = card_to_pnp_dev(devlist);
-			snprintf(dev->dev.name, sizeof(dev->dev.name), "%s", dev->name);
-			dev->card = card;
-			dev->protocol = &isapnp_protocol;
-			pnp_add_device(dev);
-		}
-	}
-
-	return 0;
-}
-
 int __init isapnp_init(void)
 {
 	int cards;
@@ -1104,7 +1084,7 @@
 		return -EBUSY;
 	}
 
-	if(pnp_protocol_register(&isapnp_protocol)<0)
+	if(pnp_register_protocol(&isapnp_protocol)<0)
 		return -EBUSY;
 
 	/*
@@ -1143,7 +1123,7 @@
 	isapnp_build_device_list();
 	cards = 0;
 
-	isapnp_for_each_card(card) {
+	protocol_for_each_card(&isapnp_protocol,card) {
 		cards++;
 		if (isapnp_verbose) {
 			struct list_head *devlist;
@@ -1162,7 +1142,6 @@
 		printk(KERN_INFO "isapnp: No Plug & Play card found\n");
 	}
 
-	isapnp_init_device_tree();
 	isapnp_proc_init();
 	return 0;
 }
diff -Nru a/drivers/pnp/isapnp/proc.c b/drivers/pnp/isapnp/proc.c
--- a/drivers/pnp/isapnp/proc.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/pnp/isapnp/proc.c	Mon Dec  9 18:46:36 2002
@@ -146,7 +146,7 @@
 {
 	struct pnp_dev *dev;
 	isapnp_proc_bus_dir = proc_mkdir("isapnp", proc_bus);
-	isapnp_for_each_dev(dev) {
+	protocol_for_each_dev(&isapnp_protocol,dev) {
 		isapnp_proc_attach_device(dev);
 	}
 	return 0;
diff -Nru a/drivers/pnp/names.c b/drivers/pnp/names.c
--- a/drivers/pnp/names.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/pnp/names.c	Mon Dec  9 18:46:34 2002
@@ -32,7 +32,7 @@
 	int i;
 	char *name = dev->name;
 	for(i=0; i<sizeof(pnp_id_eisaid)/sizeof(pnp_id_eisaid[0]); i++){
-		if (compare_pnp_id(&dev->ids,pnp_id_eisaid[i])){
+		if (compare_pnp_id(dev->id,pnp_id_eisaid[i])){
 			sprintf(name, "%s", pnp_id_names[i]);
 			return;
 		}
diff -Nru a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
--- a/drivers/pnp/pnpbios/core.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/pnp/pnpbios/core.c	Mon Dec  9 18:46:34 2002
@@ -1256,6 +1256,12 @@
 	struct pnp_dev_node_info node_info;
 	u8 nodenum = dev->number;
 	struct pnp_bios_node * node;
+		
+	/* just in case */
+	if(dev->driver)
+		return -EBUSY;
+	if(!pnp_is_dynamic(dev))
+		return -EPERM;
 	if (pnp_bios_dev_node_info(&node_info) != 0)
 		return -ENODEV;
 	node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
@@ -1273,10 +1279,15 @@
 	struct pnp_dev_node_info node_info;
 	u8 nodenum = dev->number;
 	struct pnp_bios_node * node;
-	node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
 
+	/* just in case */
+	if(dev->driver)
+		return -EBUSY;
+	if (flags == PNP_DYNAMIC && !pnp_is_dynamic(dev))
+		return -EPERM;
 	if (pnp_bios_dev_node_info(&node_info) != 0)
 		return -ENODEV;
+	node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
 	if (!node)
 		return -1;
 	if (pnp_bios_get_dev_node(&nodenum, (char )1, node))
@@ -1323,16 +1334,21 @@
 	struct pnp_bios_node * node;
 	if (!config)
 		return -1;
+	/* just in case */
+	if(dev->driver)
+		return -EBUSY;
+	if(dev->flags & PNP_NO_DISABLE || !pnp_is_dynamic(dev))
+		return -EPERM;
 	memset(config, 0, sizeof(struct pnp_cfg));
 	if (!dev || !dev->active)
 		return -EINVAL;
-	for (i=0; i <= 8; i++)
+	for (i=0; i < 8; i++)
 		config->port[i] = &port;
-	for (i=0; i <= 4; i++)
+	for (i=0; i < 4; i++)
 		config->mem[i] = &mem;
-	for (i=0; i <= 2; i++)
+	for (i=0; i < 2; i++)
 		config->irq[i] = &irq;
-	for (i=0; i <= 2; i++)
+	for (i=0; i < 2; i++)
 		config->dma[i] = &dma;
 	dev->active = 0;
 
@@ -1369,7 +1385,7 @@
 	struct list_head * pos;
 	struct pnp_dev * pnp_dev;
 	list_for_each (pos, &pnpbios_protocol.devices){
-		pnp_dev = list_entry(pos, struct pnp_dev, dev_list);
+		pnp_dev = list_entry(pos, struct pnp_dev, protocol_list);
 		if (dev->number == pnp_dev->number)
 			return -1;
 	}
@@ -1402,10 +1418,13 @@
 	for(nodenum=0; nodenum<0xff; ) {
 		u8 thisnodenum = nodenum;
 		/* We build the list from the "boot" config because
-		 * asking for the "current" config causes some
-		 * BIOSes to crash.
+		 * we know that the resources couldn't have changed
+		 * at this stage.  Furthermore some buggy PnP BIOSes
+		 * will crash if we request the "current" config
+		 * from devices that are can only be static such as
+		 * those controlled by the "system" driver.
 		 */
-		if (pnp_bios_get_dev_node(&nodenum, (char )0 , node))
+		if (pnp_bios_get_dev_node(&nodenum, (char )1, node))
 			break;
 		nodes_got++;
 		dev =  pnpbios_kmalloc(sizeof (struct pnp_dev), GFP_KERNEL);
@@ -1416,7 +1435,6 @@
 		if (!dev_id)
 			break;
 		memset(dev_id,0,sizeof(struct pnp_id));
-		pnp_init_device(dev);
 		dev->number = thisnodenum;
 		memcpy(dev->name,"Unknown Device",13);
 		dev->name[14] = '\0';
@@ -1426,6 +1444,7 @@
 		pos = node_current_resource_data_to_dev(node,dev);
 		pos = node_possible_resource_data_to_dev(pos,node,dev);
 		node_id_data_to_dev(pos,node,dev);
+		dev->flags = node->flags;
 
 		dev->protocol = &pnpbios_protocol;
 
@@ -1450,10 +1469,7 @@
  *
  */
 
-extern int is_sony_vaio_laptop;
-
 static int pnpbios_disabled; /* = 0 */
-static int dont_reserve_resources; /* = 0 */
 int pnpbios_dont_use_current_config; /* = 0 */
 
 #ifndef MODULE
@@ -1471,8 +1487,6 @@
 			str += 3;
 		if (strncmp(str, "curr", 4) == 0)
 			pnpbios_dont_use_current_config = invert;
-		if (strncmp(str, "res", 3) == 0)
-			dont_reserve_resources = invert;
 		str = strchr(str, ',');
 		if (str != NULL)
 			str += strspn(str, ", \t");
@@ -1499,9 +1513,6 @@
 		return -ENODEV;
 	}
 
-	if ( is_sony_vaio_laptop )
-		pnpbios_dont_use_current_config = 1;
-
 	/*
  	 * Search the defined area (0xf0000-0xffff0) for a valid PnP BIOS
 	 * structure and, if one is found, sets up the selectors and
@@ -1544,7 +1555,7 @@
 	}
 	if (!pnp_bios_present())
 		return -ENODEV;
-	pnp_protocol_register(&pnpbios_protocol);
+	pnp_register_protocol(&pnpbios_protocol);
 	build_devlist();
 	/*if ( ! dont_reserve_resources )*/
 		/*reserve_resources();*/
diff -Nru a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
--- a/drivers/pnp/quirks.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/pnp/quirks.c	Mon Dec  9 18:46:51 2002
@@ -157,7 +157,7 @@
 	int i = 0;
 
 	while (*pnp_fixups[i].id) {
-		if (compare_pnp_id(&dev->ids,pnp_fixups[i].id)) {
+		if (compare_pnp_id(dev->id,pnp_fixups[i].id)) {
 			pnp_dbg("Calling quirk for %s",
 		                  dev->dev.bus_id);
 			pnp_fixups[i].quirk_function(dev);
diff -Nru a/drivers/pnp/system.c b/drivers/pnp/system.c
--- a/drivers/pnp/system.c	Mon Dec  9 18:46:52 2002
+++ b/drivers/pnp/system.c	Mon Dec  9 18:46:52 2002
@@ -13,12 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/ioport.h>
 
-static const struct pnp_id pnp_card_table[] = {
-	{	"ANYDEVS",		0	},
-	{	"",			0	}
-};
-
-static const struct pnp_id pnp_dev_table[] = {
+static const struct pnp_device_id pnp_dev_table[] = {
 	/* General ID for reserving resources */
 	{	"PNP0c02",		0	},
 	/* memory controller */
@@ -101,7 +96,7 @@
 	return;
 }
 
-static int system_pnp_probe(struct pnp_dev * dev, const struct pnp_id *card_id, const struct pnp_id *dev_id)
+static int system_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id)
 {
 	reserve_resources_of_dev(dev);
 	return 0;
@@ -109,7 +104,6 @@
 
 static struct pnp_driver system_pnp_driver = {
 	.name		= "system",
-	.card_id_table	= pnp_card_table,
 	.id_table	= pnp_dev_table,
 	.probe		= system_pnp_probe,
 	.remove		= NULL,
diff -Nru a/drivers/s390/Kconfig b/drivers/s390/Kconfig
--- a/drivers/s390/Kconfig	Mon Dec  9 18:46:51 2002
+++ b/drivers/s390/Kconfig	Mon Dec  9 18:46:51 2002
@@ -138,49 +138,34 @@
 	  S/390s channel subsystem commands. This is necessary for running
 	  natively on a single image or an LPAR.
 
+config DASD_PROFILE
+	bool "Profiling support for dasd devices"
+	help
+	  Enable this option if you want to see profiling information
+          in /proc/dasd/statistics.
+
 config DASD_ECKD
 	tristate "Support for ECKD Disks"
 	depends on DASD
 	help
-	  ECKD devices are the most commonly used devices. you should enable
+	  ECKD devices are the most commonly used devices. You should enable
 	  this option unless you are very sure to have no ECKD device.
 
-config DASD_AUTO_ECKD
-	bool "Automatic activation of ECKD module"
-	depends on DASD && DASD_ECKD=m
-	help
-	  Enable this option if you want your ECKD discipline module loaded
-	  on DASD driver startup.
-
 config DASD_FBA
 	tristate "Support for FBA  Disks"
 	depends on DASD
 	help
-	  FBA devices are currently unsupported.
-
-config DASD_AUTO_FBA
-	bool "Automatic activation of FBA  module"
-	depends on DASD && DASD_FBA=m
-	help
-	  Enable this option if you want your FBA discipline module loaded
-	  on DASD driver startup.
+	  Select this option to be able to access FBA devices. It is safe to
+	  say "Y".
 
-#  dep_tristate '   Support for CKD  Disks' CONFIG_DASD_CKD $CONFIG_DASD
 config DASD_DIAG
 	tristate "Support for DIAG access to CMS reserved Disks"
-	depends on !ARCH_S390X && DASD
+	depends on DASD
 	help
 	  Select this option if you want to use CMS reserved Disks under VM
 	  with the Diagnose250 command.  If you are not running under VM or
 	  unsure what it is, say "N".
 
-config DASD_AUTO_DIAG
-	bool "Automatic activation of DIAG module"
-	depends on DASD && !ARCH_S390X && DASD_DIAG=m
-	help
-	  Enable this option if you want your DIAG discipline module loaded
-	  on DASD driver startup.
-
 endmenu
 
 source "drivers/md/Kconfig"
@@ -257,6 +242,11 @@
 	  Include support for using an IBM 3215 line-mode terminal as a
 	  Linux system console.
 
+config CCW_CONSOLE
+ 	bool
+ 	depends on TN3215_CONSOLE || TN3270_CONSOLE
+ 	default y
+ 
 config SCLP
 	bool "Support for SCLP"
 	help
@@ -302,16 +292,6 @@
 comment "S/390 tape interface support"
 	depends on S390_TAPE
 
-config S390_TAPE_CHAR
-	bool "Support for tape character devices"
-	depends on S390_TAPE
-	help
-	  Select this option if you want to access your channel-attached
-	  tape devices using the character device interface.
-	  This interface is similar to other Linux tape devices like
-	  SCSI-Tapes (st) and the floppy tape device (ftape).
-	  If unsure, say "Y".
-
 config S390_TAPE_BLOCK
 	bool "Support for tape block devices"
 	depends on S390_TAPE
@@ -326,21 +306,14 @@
 comment "S/390 tape hardware support"
 	depends on S390_TAPE
 
-config S390_TAPE_3490
-	tristate "Support for 3490 tape hardware"
+config S390_TAPE_34XX
+	tristate "Support for 3480/3490 tape hardware"
 	depends on S390_TAPE
 	help
-	  Select this option if you want to access IBM 3480 magnetic
+	  Select this option if you want to access IBM 3480/3490 magnetic
 	  tape subsystems and 100% compatibles.
 	  It is safe to say "Y" here.
 
-config S390_TAPE_3480
-	tristate "Support for 3480 tape hardware"
-	depends on S390_TAPE
-	help
-	  Select this option if you want to access IBM 3490 magnetic
-	  tape subsystems and 100% compatibles.
-
 endmenu
 
 
@@ -524,47 +497,8 @@
 comment "S/390 network device drivers"
 	depends on NETDEVICES
 
-config CHANDEV
-	bool "Channel Device Configuration"
-	depends on NETDEVICES
-	---help---
-	  The channel device layer is a layer to provide a consistent
-	  interface for configuration & default machine check (devices
-	  appearing & disappearing) handling on Linux for s/390 & z/Series
-	  channel devices.
-
-	  s/390 & z/Series channel devices include among others
-
-	  lcs (the most common ethernet/token ring/fddi standard on
-	  zSeries)
-	  ctc/escon hi speed like serial link standard on zSeries
-	  claw used to talk to cisco routers.
-	  qeth gigabit ethernet.
-
-	  These devices use two channels one read & one write for
-	  configuration & communication (& a third channel, the data
-	  channel the case of gigabit ethernet). The motivation
-	  behind developing this layer was that there was a lot of
-	  duplicate code among the channel device drivers for
-	  configuration.
-
-	  Also the lcs & ctc drivers tended to fight over
-	  3088/08's & 3088/1F's which could be either 2216/3172
-	  channel attached lcs compatible devices or escon/ctc pipes
-	  had to be configured separately as they couldn't autodetect,
-	  this is now simplified by doing the configuration in a single
-	  place (the channel device layer).
-
-	  This layer isn't invasive & it is quite okay to use channel
-	  drivers which don't use the channel device layer in
-	  conjunction with drivers which do.
-
-	  For more info see the chandev manpage usually distributed in
-	  <file:Documentation/s390/chandev.8> in the Linux source tree.
-
 config HOTPLUG
 	bool
-	depends on CHANDEV
 	default y
 	---help---
 	  Say Y here if you want to plug devices into your computer while
@@ -584,7 +518,13 @@
 
 config LCS
 	tristate "Lan Channel Station Interface"
-	depends on NETDEVICES && (NET_ETHERNET || TR)
+	depends on NETDEVICES && (NET_ETHERNET || TR || FDDI)
+	help
+	   Select this option if you want to use LCS networking  on IBM S/390
+  	   or zSeries. This device driver supports Token Ring (IEEE 802.5),
+  	   FDDI (IEEE 802.7) and Ethernet. 
+	   This option is also available as a module which will be
+	   called lcs.o . If you do not know what it is, it's safe to say "Y".
 
 config CTC
 	tristate "CTC device support"
@@ -605,5 +545,10 @@
 	  vehicle networking under VM or VIF.  This option is also available
 	  as a module which will be called iucv.o. If unsure, say "Y".
 
+config CCWGROUP
+ 	tristate
+ 	depends on LCS || CTC
+	default m if LCS!=y && CTC!=y
+	default y if LCS=y || CTC=y
 endmenu
 
diff -Nru a/drivers/s390/Makefile b/drivers/s390/Makefile
--- a/drivers/s390/Makefile	Mon Dec  9 18:46:37 2002
+++ b/drivers/s390/Makefile	Mon Dec  9 18:46:37 2002
@@ -2,11 +2,7 @@
 # Makefile for the S/390 specific device drivers
 #
 
-export-objs := s390dyn.o qdio.o
-
-obj-$(CONFIG_QDIO) += qdio.o
-
-obj-y += s390mach.o s390dyn.o sysinfo.o
+obj-y += s390mach.o sysinfo.o
 obj-y += cio/ block/ char/ misc/ net/
 
 drivers-y += drivers/s390/built-in.o
diff -Nru a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
--- a/drivers/s390/block/dasd.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/s390/block/dasd.c	Mon Dec  9 18:46:36 2002
@@ -7,6 +7,8 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
  *
+ * $Revision: 1.71 $
+ *
  * History of changes (starts July 2000)
  * 11/09/00 complete redesign after code review
  * 02/01/01 added dynamic registration of ioctls
@@ -51,7 +53,7 @@
 #include <linux/slab.h>
 #include <linux/buffer_head.h>
 
-#include <asm/div64.h>
+#include <asm/ccwdev.h>
 #include <asm/ebcdic.h>
 #include <asm/idals.h>
 #include <asm/todclk.h>
@@ -60,10 +62,6 @@
 #define PRINTK_HEADER "dasd:"
 
 #include "dasd_int.h"
-#include "dasd_eckd.h"
-#include "dasd_fba.h"
-#include "dasd_diag.h"
-
 /*
  * SECTION: Constant definitions to be used within this file
  */
@@ -80,121 +78,23 @@
 MODULE_SUPPORTED_DEVICE("dasd");
 MODULE_PARM(dasd, "1-" __MODULE_STRING(256) "s");
 MODULE_PARM(dasd_disciplines, "1-" __MODULE_STRING(8) "s");
+MODULE_LICENSE("GPL");
 
 /*
  * SECTION: prototypes for static functions of dasd.c
  */
-static void dasd_enable_discipline(dasd_discipline_t *);
-static void dasd_disable_discipline(dasd_discipline_t *);
-static void dasd_not_oper_handler(int irq, int status);
 static int  dasd_setup_blkdev(dasd_device_t * device);
 static void dasd_disable_blkdev(dasd_device_t * device);
 static void dasd_flush_request_queue(dasd_device_t *);
-static void dasd_int_handler(int, void *, struct pt_regs *);
+static void dasd_int_handler(struct ccw_device *, unsigned long, struct irb *);
 static void dasd_flush_ccw_queue(dasd_device_t *, int);
 static void dasd_tasklet(dasd_device_t *);
 static void do_kick_device(void *data);
-
-/*
- * Parameter parsing functions. There are two for the dasd driver:
- *   <dasd_disciplines> : <dasd_module>(,<dasd_module>)*
- */
-
-static char *dasd_disciplines[8];
-
-#ifndef MODULE
-/*
- * The parameter parsing functions for builtin-drivers are called
- * before kmalloc works. Store the pointers to the parameters strings
- * into dasd_disciplines[] for later processing.
- */
-static int __init
-dasd_disciplines_setup(char *str)
-{
-	static int count = 0;
-
-	if (count < 8)
-		dasd_disciplines[count++] = str;
-	return 1;
-}
-
-__setup ("dasd_disciplines=", dasd_disciplines_setup);
-#endif	/* #ifndef MODULE */
-
-/*
- * SECTION: managing dasd disciplines
- */
-static struct list_head dasd_disc_head = LIST_HEAD_INIT(dasd_disc_head);
-static spinlock_t discipline_lock = SPIN_LOCK_UNLOCKED;
-
-/*
- * Add a discipline to the head of the discipline chain. The last added
- * discipline that matches a device is used. In particular disciplines
- * added by a module will have precedence over statically linked 
- * disciplines.
- */
-void
-dasd_discipline_add(dasd_discipline_t * discipline)
-{
-	MOD_INC_USE_COUNT;
-	spin_lock(&discipline_lock);
-	list_add(&discipline->list, &dasd_disc_head);
-	spin_unlock(&discipline_lock);
-	/* Setup devices for discipline. */
-	dasd_enable_discipline(discipline);
-}
-
-/*
- * Remove a discipline from the discipline list and disable all devices
- * that rely on that discipline.
- */
-void
-dasd_discipline_del(dasd_discipline_t * discipline)
-{
-	struct list_head *l;
-
-	spin_lock(&discipline_lock);
-	/* Check if the discipline was added. */
-	list_for_each(l, &dasd_disc_head) {
-		if (list_entry(l, dasd_discipline_t, list) == discipline) {
-			list_del(&discipline->list);
-			break;
-		}
-	}
-	spin_unlock(&discipline_lock);
-	/* Disable devices for discipline. */
-	dasd_disable_discipline(discipline);
-	MOD_DEC_USE_COUNT;
-}
-
-/*
- * Find the discipline for a device.
- */
-static inline int
-dasd_find_disc(dasd_device_t * device)
-{
-	struct list_head *l;
-	dasd_discipline_t *discipline, *tmp;
-
-	discipline = NULL;
-	spin_lock(&discipline_lock);
-	list_for_each(l, &dasd_disc_head) {
-		tmp = list_entry(l, dasd_discipline_t, list);
-		if (tmp->check_device(device) == 0) {
-			/* Found a matching discipline. */
-			discipline = tmp;
-			break;
-		}
-	}
-	device->discipline = discipline;
-	spin_unlock(&discipline_lock);
-	return (discipline != NULL) ? 0 : -ENODEV;
-}
+static int  dasd_add_sysfs_files(struct ccw_device *cdev);
 
 /*
  * SECTION: Operations on the device structure.
  */
-static devfs_handle_t dasd_devfs_handle;
 static wait_queue_head_t dasd_init_waitq;
 
 /*
@@ -205,22 +105,13 @@
 {
 	dasd_device_t *device;
 	struct gendisk *gdp;
-	int rc;
 
 	device = kmalloc(sizeof (dasd_device_t), GFP_ATOMIC);
 	if (device == NULL)
 		return ERR_PTR(-ENOMEM);
 	memset(device, 0, sizeof (dasd_device_t));
 
-	/* Get devinfo from the common io layer. */
-	rc = get_dev_info_by_devno(devmap->devno, &device->devinfo);
-	if (rc) {
-		kfree(device);
-		return ERR_PTR(rc);
-	}
-	DBF_EVENT(DBF_NOTICE, "got devinfo CU-type %04x and dev-type %04x",
-		  device->devinfo.sid_data.cu_type,
-		  device->devinfo.sid_data.dev_type);
+	device->devno = devmap->devno;
 
 	/* Get two pages for normal block device operations. */
 	device->ccw_mem = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, 1);
@@ -256,7 +147,7 @@
 		     (unsigned long) device);
 	INIT_LIST_HEAD(&device->ccw_queue);
 	init_timer(&device->timer);
-	INIT_WORK(&device->kick_work, do_kick_device, (void *) (addr_t) device->devinfo.devno);
+	INIT_WORK(&device->kick_work, do_kick_device, (void *) (addr_t) device->devno);
 	device->state = DASD_STATE_NEW;
 	device->target = DASD_STATE_NEW;
 
@@ -287,9 +178,13 @@
 	dasd_devmap_t *devmap;
 	umode_t devfs_perm;
 	devfs_handle_t dir;
-	int major, minor, rc;
+	int major, minor;
+
+	/* Increase reference count of bdev. */
+	if (bdget(MKDEV(device->gdp->major, device->gdp->first_minor)) == NULL)
+		return -ENODEV;
 
-	devmap = dasd_devmap_from_devno(device->devinfo.devno);
+	devmap = dasd_devmap_from_devno(device->devno);
 	if (devmap == NULL)
 		return -ENODEV;
 	major = dasd_gendisk_index_major(devmap->devindex);
@@ -297,16 +192,11 @@
 		return -ENODEV;
 	minor = devmap->devindex % DASD_PER_MAJOR;
 
-	/* Find a discipline for the device. */
-	rc = dasd_find_disc(device);
-	if (rc)
-		return rc;
-
 	/* Add a proc directory and the dasd device entry to devfs. */
-	sprintf(buffer, "dasd/%04x", device->devinfo.devno);
-	dir = devfs_mk_dir(NULL, buffer, NULL);
+ 	sprintf(buffer, "dasd/%04x", device->devno);
+ 	dir = devfs_mk_dir(NULL, buffer, NULL);
 	device->gdp->de = dir;
-	if (devmap->features & DASD_FEATURE_READONLY)
+	if (device->ro_flag)
 		devfs_perm = S_IFBLK | S_IRUSR;
 	else
 		devfs_perm = S_IFBLK | S_IRUSR | S_IWUSR;
@@ -324,12 +214,7 @@
 static inline void
 dasd_state_known_to_new(dasd_device_t * device)
 {
-	dasd_devmap_t *devmap;
 	struct block_device *bdev;
-	int minor;
-
-	devmap = dasd_devmap_from_devno(device->devinfo.devno);
-	minor = devmap->devindex % DASD_PER_MAJOR;
 
 	/* Remove device entry and devfs directory. */
 	devfs_unregister(device->devfs_entry);
@@ -338,6 +223,11 @@
 	/* Forget the discipline information. */
 	device->discipline = NULL;
 	device->state = DASD_STATE_NEW;
+
+	/* Decrease reference count of bdev. */
+	bdev = bdget(MKDEV(device->gdp->major, device->gdp->first_minor));
+	bdput(bdev);
+	bdput(bdev);
 }
 
 /*
@@ -346,8 +236,6 @@
 static inline int
 dasd_state_known_to_basic(dasd_device_t * device)
 {
-	int rc;
-
 	/* register 'device' debug area, used for all DBF_DEV_XXX calls */
 	device->debug_area = debug_register(device->gdp->disk_name, 0, 2,
 					    8 * sizeof (long));
@@ -355,19 +243,6 @@
 	debug_set_level(device->debug_area, DBF_ERR);
 	DBF_DEV_EVENT(DBF_EMERG, device, "%s", "debug area created");
 
-	/*
-	 * We request the "official" irq line even for dasd diag device.
-	 * The interrupts for dasd diag will arrive at dasd_ext_handler
-	 * instead of dasd_int_handler so this is just a placeholder.
-	 */
-	rc = s390_request_irq_special(device->devinfo.irq,
-				      dasd_int_handler,
-				      dasd_not_oper_handler,
-				      0, "dasd", &device->dev_status);
-	if (rc) {
-		MESSAGE(KERN_ERR, "%s", "No request IRQ");
-		return rc;
-	}
 	device->state = DASD_STATE_BASIC;
 	return 0;
 }
@@ -379,7 +254,6 @@
 dasd_state_basic_to_known(dasd_device_t * device)
 {
 	dasd_flush_ccw_queue(device, 1);
-	free_irq(device->devinfo.irq, &device->dev_status);
 	DBF_DEV_EVENT(DBF_EMERG, device, "%p debug area deleted", device);
 	if (device->debug_area != NULL) {
 		debug_unregister(device->debug_area);
@@ -429,15 +303,8 @@
 static inline int
 dasd_state_accept_to_ready(dasd_device_t * device)
 {
-	dasd_devmap_t *devmap;
-	int rc, i;
+	int rc;
 
-	devmap = dasd_devmap_from_devno(device->devinfo.devno);
-	if (devmap->features & DASD_FEATURE_READONLY) {
-		device->ro_flag = 1;
-		DEV_MESSAGE (KERN_WARNING, device, "%s",
-			     "setting read-only mode ");
-	}
 	rc = dasd_setup_blkdev(device);
 	if (rc == 0) {
 		dasd_setup_partitions(device);
@@ -560,7 +427,7 @@
         if (rc && rc != -EAGAIN) {
 		if (rc != -ENODEV)
 			MESSAGE (KERN_INFO, "giving up on dasd device with "
-				 "devno %04x", device->devinfo.devno);
+				 "devno %04x", device->devno);
                 device->target = device->state;
         }
 
@@ -623,255 +490,25 @@
  * Enable devices with device numbers in [from..to].
  */
 static inline int
-_wait_for_devices(int from, int to)
+_wait_for_device(dasd_device_t *device)
 {
-	dasd_devmap_t *devmap;
-	dasd_device_t *device;
-	int devno, rc;
-
-	rc = 0;
-	for (devno = from; devno <= to && rc == 0; devno++) {
-		devmap = dasd_devmap_from_devno(devno);
-		device = (devmap != NULL) ?
-			dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-		if (IS_ERR(device))
-			continue;
-		if (device->state != device->target)
-			rc = 1;
-		dasd_put_device(devmap);
-	}
-	return rc;
-}
-
-void
-dasd_enable_devices(int from, int to)
-{
-	dasd_devmap_t *devmap;
-	dasd_device_t *device;
-	int devno;
-
-	for (devno = from; devno <= to; devno++) {
-		devmap = dasd_devmap_from_devno(devno);
-		device = (devmap != NULL) ?
-			dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-		if (IS_ERR(device))
-			continue;
-		dasd_set_target_state(device, DASD_STATE_ONLINE);
-		if (device->state <= DASD_STATE_KNOWN)
-			/* No discipline for device found. */
-			dasd_set_target_state(device, DASD_STATE_NEW);
-		dasd_put_device(devmap);
-	}
-	/* Now wait for the devices to come up. */
-	wait_event(dasd_init_waitq, _wait_for_devices(from, to) == 0);
+	return (device->state == device->target);
 }
 
-/*
- * Disable devices with device numbers in [from..to].
- */
+// FIXME: if called from dasd_devices_write discpline is not set -> oops.
 void
-dasd_disable_devices(int from, int to)
+dasd_enable_device(dasd_device_t *device)
 {
-	dasd_devmap_t *devmap;
-	dasd_device_t *device;
-	int devno;
-
-	for (devno = from; devno <= to; devno++) {
-		devmap = dasd_devmap_from_devno(devno);
-		device = (devmap != NULL) ?
-			dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-		if (IS_ERR(device))
-			continue;
+	dasd_set_target_state(device, DASD_STATE_ONLINE);
+	if (device->state <= DASD_STATE_KNOWN)
+		/* No discipline for device found. */
 		dasd_set_target_state(device, DASD_STATE_NEW);
-		dasd_put_device(devmap);
-	}
-}
-
-/*
- * Enable devices that use a specific discipline.
- */
-static inline int
-_wait_for_disc_devices(dasd_discipline_t *discipline)
-{
-	dasd_devmap_t *devmap;
-	dasd_device_t *device;
-	int devindex, rc;
-
-	rc = 0;
-	for (devindex = 0; devindex < dasd_max_devindex; devindex++) {
-		devmap = dasd_devmap_from_devindex(devindex);
-		device = (devmap != NULL) ?
-			dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-		if (IS_ERR(device))
-			continue;
-		if (device->discipline == discipline &&
-		    device->state != device->target)
-			rc = 1;
-		dasd_put_device(devmap);
-	}
-	return rc;
-}
-
-static void
-dasd_enable_discipline(dasd_discipline_t *discipline)
-{
-	dasd_devmap_t *devmap;
-	dasd_device_t *device;
-	int devindex;
-
-	for (devindex = 0; devindex < dasd_max_devindex; devindex++) {
-		devmap = dasd_devmap_from_devindex(devindex);
-		device = (devmap != NULL) ?
-			dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-		if (IS_ERR(device))
-			continue;
-		if (device->discipline != NULL &&
-		    device->discipline != discipline)
-			continue;
-		dasd_set_target_state(device, DASD_STATE_ONLINE);
-		if (device->discipline == NULL)
-			/* No discipline for device found. */
-			dasd_set_target_state(device, DASD_STATE_NEW);
-		dasd_put_device(devmap);
-	}
 	/* Now wait for the devices to come up. */
-	wait_event(dasd_init_waitq, _wait_for_disc_devices(discipline) == 0);
-}
-
-/*
- * Disable devices that use a specific discipline.
- */
-static void
-dasd_disable_discipline(dasd_discipline_t *discipline)
-{
-	dasd_devmap_t *devmap;
-	dasd_device_t *device;
-	int devindex;
-
-	/* Shutdown device that use the discipline. */
-	for (devindex = 0; devindex < dasd_max_devindex; devindex++) {
-		devmap = dasd_devmap_from_devindex(devindex);
-		device = (devmap != NULL) ?
-			dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-		if (IS_ERR(device))
-			continue;
-		if (device->discipline == discipline)
-			dasd_set_target_state(device, DASD_STATE_NEW);
-		dasd_put_device(devmap);
-	}
-}
-
-/*
- * Deactivate a device that has vaninshed.
- */
-
-static void
-do_not_oper_handler(void *data)
-{
-	struct {
-		struct work_struct work;
-		int irq;
-	} *p;
-	dasd_device_t *device;
-	dasd_devmap_t *devmap;
-
-	/*
-	 * find out devno of leaving device: CIO has already deleted
-	 * this information so we need to find it by irq!
-	 */
-	p = data;
-	devmap = dasd_devmap_from_irq(p->irq);
-	if (devmap == NULL) {
-		MESSAGE(KERN_WARNING,
-			"not_oper_handler called on irq 0x%04x no devno!",
-			p->irq);
-		return;
-	} else
-		DBF_EVENT(DBF_NOTICE, "called for devno %04x", devmap->devno);
-	device = dasd_get_device(devmap);
-	if (IS_ERR(device))
-		return;
-	dasd_set_target_state(device, DASD_STATE_NEW);
-	dasd_put_device(devmap);
-	kfree(p);
-}
-
-void
-dasd_not_oper_handler(int irq, int status)
-{
-	struct {
-		struct work_struct work;
-		int irq;
-	} *p;
-
-	p = kmalloc(sizeof(*p), GFP_ATOMIC);
-	if (p == NULL)
-		/* FIXME: No memory, we loose. */
-		return;
-	INIT_WORK(&p->work, (void *) do_not_oper_handler, p);
-	p->irq = irq;
-	/* queue call to do_not_oper_handler to the kernel event daemon. */
-	schedule_work(&p->work);
+	wait_event(dasd_init_waitq, _wait_for_device(device));
 }
 
 /*
- * Activate a device that appeared out of nowhere.
- */
-static void
-do_oper_handler(void *data)
-{
-	struct {
-		struct work_struct work;
-		int devno;
-	} *p;
-	dasd_devmap_t *devmap;
-	dasd_device_t *device;
-
-	p = data;
-	DBF_EVENT(DBF_NOTICE, "called for devno %04x", p->devno);
-
-	if (dasd_autodetect &&
-            dasd_add_range(p->devno, p->devno, DASD_FEATURE_DEFAULT) != 0)
-                return;
-
-	/* Get/create the device structure for devno. */
-	devmap = dasd_devmap_from_devno(p->devno);
-	if (devmap == NULL) {
-		DBF_EXC(DBF_ALERT, "no dasd: devno %04x", p->devno);
-		return;
-	}
-	device = dasd_get_device(devmap);
-	if (IS_ERR(device))
-		return;
-	dasd_enable_devices(p->devno, p->devno);
-	dasd_put_device(devmap);
-	kfree(p);
-}
-
-int
-dasd_oper_handler(int irq, devreg_t * devreg)
-{
-	struct {
-		struct work_struct work;
-		int devno;
-	} *p;
-
-	p = kmalloc(sizeof(*p), GFP_ATOMIC);
-	if (p == NULL)
-		/* FIXME: No memory, we loose. */
-		return -ENOMEM;
-	p->devno = get_devno_by_irq(irq);
-	if (p->devno == -ENODEV)
-		return -ENODEV;
-	INIT_WORK(&p->work, (void *) do_oper_handler, p);
-	/* queue call to do_oper_handler to the kernel event daemon. */
-	schedule_work(&p->work);
-        return 0;
-
-}
-
-/*
- * SECTION: device operation (interrupt handler, start_IO, term_IO ...)
+ * SECTION: device operation (interrupt handler, start i/o, term i/o ...)
  */
 #ifdef CONFIG_DASD_PROFILE
 
@@ -974,7 +611,7 @@
 
 	/* Sanity checks */
 	if ( magic == NULL || datasize > PAGE_SIZE ||
-	     (cplength*sizeof(ccw1_t)) > PAGE_SIZE)
+	     (cplength*sizeof(struct ccw1)) > PAGE_SIZE)
 		BUG();
 	debug_text_event ( dasd_debug_area, 1, "ALLC");
 	debug_text_event ( dasd_debug_area, 1, magic);
@@ -987,13 +624,13 @@
 	memset(cqr, 0, sizeof(dasd_ccw_req_t));
 	cqr->cpaddr = NULL;
 	if (cplength > 0) {
-		cqr->cpaddr = kmalloc(cplength*sizeof(ccw1_t),
+		cqr->cpaddr = kmalloc(cplength*sizeof(struct ccw1),
 				      GFP_ATOMIC | GFP_DMA);
 		if (cqr->cpaddr == NULL) {
 			kfree(cqr);
 			return ERR_PTR(-ENOMEM);
 		}
-		memset(cqr->cpaddr, 0, cplength*sizeof(ccw1_t));
+		memset(cqr->cpaddr, 0, cplength*sizeof(struct ccw1));
 	}
 	cqr->data = NULL;
 	if (datasize > 0) {
@@ -1023,7 +660,7 @@
 
 	/* Sanity checks */
 	if ( magic == NULL || datasize > PAGE_SIZE ||
-	     (cplength*sizeof(ccw1_t)) > PAGE_SIZE)
+	     (cplength*sizeof(struct ccw1)) > PAGE_SIZE)
 		BUG();
 	debug_text_event ( dasd_debug_area, 1, "ALLC");
 	debug_text_event ( dasd_debug_area, 1, magic);
@@ -1032,7 +669,7 @@
 
 	size = (sizeof(dasd_ccw_req_t) + 7L) & -8L;
 	if (cplength > 0)
-		size += cplength * sizeof(ccw1_t);
+		size += cplength * sizeof(struct ccw1);
 	if (datasize > 0)
 		size += datasize;
 	spin_lock_irqsave(&device->mem_lock, flags);
@@ -1044,9 +681,9 @@
 	data = (char *) cqr + ((sizeof(dasd_ccw_req_t) + 7L) & -8L);
 	cqr->cpaddr = NULL;
 	if (cplength > 0) {
-		cqr->cpaddr = (ccw1_t *) data;
-		data += cplength*sizeof(ccw1_t);
-		memset(cqr->cpaddr, 0, cplength*sizeof(ccw1_t));
+		cqr->cpaddr = (struct ccw1 *) data;
+		data += cplength*sizeof(struct ccw1);
+		memset(cqr->cpaddr, 0, cplength*sizeof(struct ccw1));
 	}
 	cqr->data = NULL;
 	if (datasize > 0) {
@@ -1068,7 +705,7 @@
 dasd_kfree_request(dasd_ccw_req_t * cqr, dasd_device_t * device)
 {
 #ifdef CONFIG_ARCH_S390X
-	ccw1_t *ccw;
+	struct ccw1 *ccw;
 
 	/* Clear any idals used for the request. */
 	ccw = cqr->cpaddr;
@@ -1127,7 +764,8 @@
 
 /*
  * Terminate the current i/o and set the request to failed.
- * halt_IO/clear_IO can fail if the i/o subsystem is in a bad mood.
+ * ccw_device_halt/ccw_device_clear can fail if the i/o subsystem 
+ * is in a bad mood.
  */
 int
 dasd_term_IO(dasd_ccw_req_t * cqr)
@@ -1143,11 +781,9 @@
 	device = (dasd_device_t *) cqr->device;
 	while ((retries < 5) && (cqr->status == DASD_CQR_IN_IO)) {
 		if (retries < 2)
-			rc = halt_IO(device->devinfo.irq,
-				     (long) cqr, cqr->options);
+			rc = ccw_device_halt(device->cdev, (long) cqr);
 		else
-			rc = clear_IO(device->devinfo.irq,
-				      (long) cqr, cqr->options);
+			rc = ccw_device_clear(device->cdev, (long) cqr);
 		switch (rc) {
 		case 0:	/* termination successful */
 			cqr->status = DASD_CQR_FAILED;
@@ -1173,6 +809,7 @@
 			BUG();
 			break;
 		}
+		retries++;
 	}
 	dasd_schedule_bh(device);
 	return rc;
@@ -1194,17 +831,11 @@
 		return rc;
 	device = (dasd_device_t *) cqr->device;
 	cqr->startclk = get_clock();
-	rc = do_IO(device->devinfo.irq,
-		   cqr->cpaddr, (long) cqr, cqr->lpm, cqr->options);
+	rc = ccw_device_start(device->cdev, cqr->cpaddr, (long) cqr,
+			      cqr->lpm, 0);
 	switch (rc) {
 	case 0:
-		if (cqr->options & DOIO_WAIT_FOR_INTERRUPT) {
-			/* request already finished (synchronous IO) */
-			cqr->status = DASD_CQR_DONE;
-			cqr->stopclk = cqr->startclk;
-			dasd_schedule_bh(device);
-		} else
-			cqr->status = DASD_CQR_IN_IO;
+		cqr->status = DASD_CQR_IN_IO;
 		break;
 	case -EBUSY:
 		DBF_DEV_EVENT(DBF_ERR, device, "%s",
@@ -1245,14 +876,14 @@
 	dasd_ccw_req_t *cqr;
 
 	device = (dasd_device_t *) ptr;
-	spin_lock_irqsave(get_irq_lock(device->devinfo.irq), flags);
+	spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
 	/* re-activate first request in queue */
 	if (!list_empty(&device->ccw_queue)) {
 		cqr = list_entry(device->ccw_queue.next, dasd_ccw_req_t, list);
 		if (cqr->status == DASD_CQR_PENDING)
 			cqr->status = DASD_CQR_QUEUED;
 	}
-	spin_unlock_irqrestore(get_irq_lock(device->devinfo.irq), flags);
+	spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 	dasd_schedule_bh(device);
 }
 
@@ -1265,18 +896,19 @@
 	/* FIXME: timeouts are based on jiffies but the timeout
 	 * comparision in __dasd_check_expire is based on the
 	 * TOD clock. */
-	if (expires != 0) {
-		if (!timer_pending(&device->timer)) {
-			device->timer.function = dasd_timeout_device;
-			device->timer.data = (unsigned long) device;
-			device->timer.expires = jiffies + expires;
-			add_timer(&device->timer);
-		} else
-			mod_timer(&device->timer, jiffies + expires);
-	} else {
+	if (expires == 0) {
 		if (timer_pending(&device->timer))
 			del_timer(&device->timer);
+		return;
 	}
+	if (timer_pending(&device->timer)) {
+		if (mod_timer(&device->timer, jiffies + expires))
+			return;
+	}
+	device->timer.function = dasd_timeout_device;
+	device->timer.data = (unsigned long) device;
+	device->timer.expires = jiffies + expires;
+	add_timer(&device->timer);
 }
 
 /*
@@ -1301,33 +933,36 @@
 {
 	struct {
 		struct work_struct work;
-		unsigned short devno;
+		dasd_device_t *device;
 	} *p;
 	dasd_devmap_t *devmap;
 	dasd_device_t *device;
 	dasd_ccw_req_t *cqr;
+	int devno;
 
 	p = data;
-	DBF_EVENT(DBF_NOTICE, "State change Interrupt: %04x", p->devno);
+	device = p->device;
+	DBF_EVENT(DBF_NOTICE, "State change Interrupt for bus_id %s",
+		  device->cdev->dev.bus_id);
 
-	devmap = dasd_devmap_from_devno(p->devno);
-	device = (devmap != NULL) ?
-		dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-	if (IS_ERR(device)) {
-		MESSAGE(KERN_DEBUG,
-			"unable to find device for state change pending "
-			"interrupt: devno%04x", p->devno);
-		return;
-	}
-
-	spin_lock_irq(get_irq_lock(device->devinfo.irq));
+	// FIXME: get rid of devmap.
+	devno = _ccw_device_get_device_number(device->cdev);
+	devmap = dasd_devmap_from_devno(devno);
+	spin_lock_irq(get_ccwdev_lock(device->cdev));
 	/* re-activate first request in queue */
 	if (!list_empty(&device->ccw_queue)) {
 		cqr = list_entry(device->ccw_queue.next, dasd_ccw_req_t, list);
+		if (cqr == NULL) {
+			MESSAGE (KERN_DEBUG,
+				 "got state change pending interrupt on"
+				 "an idle device: bus_id %s",
+				 device->cdev->dev.bus_id);
+			return;
+		}
 		if (cqr->status == DASD_CQR_PENDING)
 			cqr->status = DASD_CQR_QUEUED;
 	}
-	spin_unlock_irq(get_irq_lock(device->devinfo.irq));
+	spin_unlock_irq(get_ccwdev_lock(device->cdev));
 	dasd_schedule_bh(device);
 	dasd_put_device(devmap);
 	kfree(p);
@@ -1335,11 +970,11 @@
 
 
 static void
-dasd_handle_state_change_pending(devstat_t * stat)
+dasd_handle_state_change_pending(dasd_device_t *device)
 {
 	struct {
 		struct work_struct work;
-		unsigned short devno;
+		dasd_device_t *device;
 	} *p;
 
 	p = kmalloc(sizeof(*p), GFP_ATOMIC);
@@ -1347,7 +982,8 @@
 		/* No memory, let the timeout do the reactivation. */
 		return;
 	INIT_WORK(&p->work, (void *) do_state_change_pending, p);
-	p->devno = stat->devno;
+	p->device = device;
+	atomic_inc(&device->ref_count);
 	/* queue call to do_state_change_pending to the kernel event daemon. */
 	schedule_work(&p->work);
 }
@@ -1356,71 +992,61 @@
  * Interrupt handler for "normal" ssch-io based dasd devices.
  */
 void
-dasd_int_handler(int irq, void *ds, struct pt_regs *regs)
+dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
+		 struct irb *irb)
 {
 	dasd_ccw_req_t *cqr, *next;
 	dasd_device_t *device;
 	unsigned long long now;
 	int expires;
 	dasd_era_t era;
-	devstat_t *stat;
 	char mask;
 
 	now = get_clock();
-	stat = (devstat_t *) ds;
 
-	DBF_EVENT(DBF_DEBUG, "Interrupt: IRQ %02x, stat %02x, devno %04x",
-		  irq, stat->dstat, stat->devno);
+	DBF_EVENT(DBF_DEBUG, "Interrupt: stat %02x, bus_id %s",
+		  irb->scsw.dstat, cdev->dev.bus_id);
 
 	/* first of all check for state change pending interrupt */
 	mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP;
-	if ((stat->dstat & mask) == mask) {
-		dasd_handle_state_change_pending(stat);
+	if ((irb->scsw.dstat & mask) == mask) {
+		dasd_handle_state_change_pending(cdev->dev.driver_data);
 		return;
 	}
 
-	if (stat->intparm == 0) {	/* no intparm: unsolicited interrupt */
-		MESSAGE(KERN_DEBUG,
-			"unsolicited interrupt: irq 0x%x devno %04x",
-			irq, stat->devno);
-		return;
-	}
-
-	cqr = (dasd_ccw_req_t *) (unsigned long) stat->intparm;
+	cqr = (dasd_ccw_req_t *) intparm;
 	/*
 	 * check status - the request might have been killed
 	 * because of dyn detach
 	 */
 	if (cqr->status != DASD_CQR_IN_IO) {
 		MESSAGE(KERN_DEBUG,
-			"invalid status: irq 0x%x devno %04x, status %02x",
-			irq, stat->devno, cqr->status);
+			"invalid status: bus_id %s, status %02x",
+			cdev->dev.bus_id, cqr->status);
 		return;
 	}
 
 	device = (dasd_device_t *) cqr->device;
 	if (device == NULL ||
-	    device != ds - offsetof(dasd_device_t, dev_status) ||
-	    device->devinfo.irq != irq ||
+	    device != cdev->dev.driver_data ||
 	    strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
-		MESSAGE(KERN_DEBUG,
-			"invalid device in request: irq 0x%x devno %04x",
-			irq, stat->devno);
+		MESSAGE(KERN_DEBUG, "invalid device in request: bus_id %s",
+			cdev->dev.bus_id);
 		return;
 	}
 
-	DBF_DEV_EVENT(DBF_DEBUG, device,
-		      "Int: CS/DS 0x%04x", ((stat->cstat << 8) | stat->dstat));
+	DBF_DEV_EVENT(DBF_DEBUG, device, "Int: CS/DS 0x%04x",
+		      ((irb->scsw.cstat << 8) | irb->scsw.dstat));
 
 	/* Find out the appropriate era_action. */
 	era = dasd_era_none;
-	if (stat->flag & DEVSTAT_FLAG_SENSE_AVAIL ||
-	    stat->dstat & ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) {
+	if (irb->scsw.dstat & ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END) ||
+	    irb->esw.esw0.erw.cons) {
 		/* The request did end abnormally. */
-		if (stat->flag & DEVSTAT_HALT_FUNCTION)
+		if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC)
 			era = dasd_era_fatal;
 		else
-			era = device->discipline->examine_error(cqr, stat);
+			era = device->discipline->examine_error(cqr, irb);
 		DBF_EVENT(DBF_NOTICE, "era_code %d", era);
 	}
 	expires = 0;
@@ -1441,9 +1067,9 @@
 		}
 	} else {		/* error */
 		if (cqr->dstat == NULL)
-			cqr->dstat = kmalloc(sizeof(devstat_t), GFP_ATOMIC);
+			cqr->dstat = kmalloc(sizeof(struct irb), GFP_ATOMIC);
 		if (cqr->dstat)
-			memcpy(cqr->dstat, stat, sizeof (devstat_t));
+			memcpy(cqr->dstat, irb, sizeof (struct irb));
 		else
 			MESSAGE(KERN_ERR, "%s",
 				"no memory for dstat...ignoring");
@@ -1522,7 +1148,7 @@
 		/*  Process requests with DASD_CQR_ERROR */
 		if (cqr->status == DASD_CQR_ERROR) {
 			cqr->retries--;
-			if (cqr->dstat->flag & DEVSTAT_HALT_FUNCTION) {
+			if (cqr->dstat->scsw.fctl & SCSW_FCTL_HALT_FUNC) {
 				cqr->status = DASD_CQR_FAILED;
 				cqr->stopclk = get_clock();
 			} else {
@@ -1537,7 +1163,7 @@
 			goto restart;
 		}
 
-		/* Rechain request on device device request queue */
+		/* Rechain finished requests to final queue */
 		cqr->endclk = get_clock();
 		list_move_tail(&cqr->list, final_queue);
 	}
@@ -1596,7 +1222,7 @@
 		if (device->ro_flag && rq_data_dir(req) == WRITE) {
 			DBF_EVENT(DBF_ERR,
 				  "(%04x) Rejecting write request %p",
-				  device->devinfo.devno, req);
+				  device->devno, req);
 			blkdev_dequeue_request(req);
 			dasd_end_request(req, 0);
 			continue;
@@ -1607,7 +1233,7 @@
 				break;	/* terminate request queue loop */
 			DBF_EVENT(DBF_ERR,
 				  "(%04x) CCW creation failed on request %p",
-				  device->devinfo.devno, req);
+				  device->devno, req);
 			blkdev_dequeue_request(req);
 			dasd_end_request(req, 0);
 			continue;
@@ -1624,7 +1250,7 @@
 
 /*
  * Take a look at the first request on the ccw queue and check
- * if it reached its expire time.
+ * if it reached its expire time. If so, terminate the IO.
  */
 static inline void
 __dasd_check_expire(dasd_device_t * device)
@@ -1680,7 +1306,7 @@
 	dasd_ccw_req_t *cqr;
 
 	INIT_LIST_HEAD(&flush_queue);
-	spin_lock_irq(get_irq_lock(device->devinfo.irq));
+	spin_lock_irq(get_ccwdev_lock(device->cdev));
 	list_for_each_safe(l, n, &device->ccw_queue) {
 		cqr = list_entry(l, dasd_ccw_req_t, list);
 		/* Flush all request or only block device requests? */
@@ -1702,7 +1328,7 @@
 		cqr->endclk = get_clock();
 		list_move_tail(&cqr->list, &flush_queue);
 	}
-	spin_unlock_irq(get_irq_lock(device->devinfo.irq));
+	spin_unlock_irq(get_ccwdev_lock(device->cdev));
 	/* Now call the callback function of flushed requests */
 	list_for_each_safe(l, n, &flush_queue) {
 		cqr = list_entry(l, dasd_ccw_req_t, list);
@@ -1723,12 +1349,12 @@
 
 	atomic_set (&device->tasklet_scheduled, 0);
 	INIT_LIST_HEAD(&final_queue);
-	spin_lock_irq(get_irq_lock(device->devinfo.irq));
+	spin_lock_irq(get_ccwdev_lock(device->cdev));
 	/* Check expire time of first request on the ccw queue. */
 	__dasd_check_expire(device);
 	/* Finish off requests on ccw queue */
 	__dasd_process_ccw_queue(device, &final_queue);
-	spin_unlock_irq(get_irq_lock(device->devinfo.irq));
+	spin_unlock_irq(get_ccwdev_lock(device->cdev));
 	/* Now call the callback function of requests with final status */
 	list_for_each_safe(l, n, &final_queue) {
 		cqr = list_entry(l, dasd_ccw_req_t, list);
@@ -1737,19 +1363,19 @@
 			(cqr->callback)(cqr, cqr->callback_data);
 	}
 	spin_lock_irq(&device->request_queue_lock);
-	spin_lock(get_irq_lock(device->devinfo.irq));
+	spin_lock(get_ccwdev_lock(device->cdev));
 	/* Get new request from the block device request queue */
 	__dasd_process_blk_queue(device);
 	/* Now check if the head of the ccw queue needs to be started. */
 	__dasd_start_head(device);
-	spin_unlock(get_irq_lock(device->devinfo.irq));
+	spin_unlock(get_ccwdev_lock(device->cdev));
 	spin_unlock_irq(&device->request_queue_lock);
 	/* FIXME: what if ref_count == 0 && state == DASD_STATE_NEW ?? */
 	atomic_dec(&device->ref_count);
 }
 
 /*
- * Schedules a call to dasd_process_queues over the device tasklet.
+ * Schedules a call to dasd_tasklet over the device tasklet.
  */
 void
 dasd_schedule_bh(dasd_device_t * device)
@@ -1772,13 +1398,13 @@
 	unsigned long flags;
 
 	device = req->device;
-	spin_lock_irqsave(get_irq_lock(device->devinfo.irq), flags);
+	spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
 	req->status = DASD_CQR_QUEUED;
 	req->device = device;
 	list_add(&req->list, &device->ccw_queue);
 	/* let the bh start the request to keep them in order */
 	dasd_schedule_bh(device);
-	spin_unlock_irqrestore(get_irq_lock(device->devinfo.irq), flags);
+	spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 }
 
 /*
@@ -1792,13 +1418,13 @@
 	unsigned long flags;
 
 	device = req->device;
-	spin_lock_irqsave(get_irq_lock(device->devinfo.irq), flags);
+	spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
 	req->status = DASD_CQR_QUEUED;
 	req->device = device;
 	list_add_tail(&req->list, &device->ccw_queue);
 	/* let the bh start the request to keep them in order */
 	dasd_schedule_bh(device);
-	spin_unlock_irqrestore(get_irq_lock(device->devinfo.irq), flags);
+	spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 }
 
 /*
@@ -1817,9 +1443,9 @@
 	int rc;
 
 	device = cqr->device;
-	spin_lock_irq(get_irq_lock(device->devinfo.irq));
+	spin_lock_irq(get_ccwdev_lock(device->cdev));
 	rc = cqr->status == DASD_CQR_DONE || cqr->status == DASD_CQR_FAILED;
-	spin_unlock_irq(get_irq_lock(device->devinfo.irq));
+	spin_unlock_irq(get_ccwdev_lock(device->cdev));
 	return rc;
 }
 
@@ -1834,7 +1460,7 @@
 	int rc;
 	
 	device = cqr->device;
-	spin_lock_irq(get_irq_lock(device->devinfo.irq));
+	spin_lock_irq(get_ccwdev_lock(device->cdev));
 	
 	init_waitqueue_head (&wait_q);
 	cqr->callback = dasd_wakeup_cb;
@@ -1845,7 +1471,7 @@
 	/* let the bh start the request to keep them in order */
 	dasd_schedule_bh(device);
 	
-	spin_unlock_irq(get_irq_lock(device->devinfo.irq));
+	spin_unlock_irq(get_ccwdev_lock(device->cdev));
 
 	wait_event(wait_q, _wait_for_wakeup(cqr));
 	
@@ -1866,7 +1492,7 @@
 	int rc, finished;
 
 	device = cqr->device;
-	spin_lock_irq(get_irq_lock(device->devinfo.irq));
+	spin_lock_irq(get_ccwdev_lock(device->cdev));
 
 	init_waitqueue_head (&wait_q);
 	cqr->callback = dasd_wakeup_cb;
@@ -1876,7 +1502,7 @@
 
 	/* let the bh start the request to keep them in order */
 	dasd_schedule_bh(device);
-	spin_unlock_irq(get_irq_lock(device->devinfo.irq));
+	spin_unlock_irq(get_ccwdev_lock(device->cdev));
 
 	finished = 0;
 	while (!finished) {
@@ -1886,13 +1512,13 @@
 			rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0;
 			break;
 		}
-		spin_lock_irq(get_irq_lock(device->devinfo.irq));
+		spin_lock_irq(get_ccwdev_lock(device->cdev));
 		if (cqr->status == DASD_CQR_IN_IO &&
 		    device->discipline->term_IO(cqr) == 0) {
 			list_del(&cqr->list);
 			finished = 1;
 		}
-		spin_unlock_irq(get_irq_lock(device->devinfo.irq));
+		spin_unlock_irq(get_ccwdev_lock(device->cdev));
 	}
 	return rc;
 }
@@ -1929,10 +1555,10 @@
 	int rc;
 	
 	device = cqr->device;
-	spin_lock_irq(get_irq_lock(device->devinfo.irq));
+	spin_lock_irq(get_ccwdev_lock(device->cdev));
 	rc = _dasd_term_running_cqr(device);
 	if (rc) {
-		spin_unlock_irq(get_irq_lock(device->devinfo.irq));
+		spin_unlock_irq(get_ccwdev_lock(device->cdev));
 		return rc;
 	}
 	
@@ -1945,7 +1571,7 @@
 	/* let the bh start the request to keep them in order */
 	dasd_schedule_bh(device);
 	
-	spin_unlock_irq(get_irq_lock(device->devinfo.irq));
+	spin_unlock_irq(get_ccwdev_lock(device->cdev));
 
 	wait_event(wait_q, _wait_for_wakeup(cqr));
 	
@@ -1967,7 +1593,7 @@
 	int rc;
 
 	rc = 0;
-	spin_lock_irqsave(get_irq_lock(device->devinfo.irq), flags);
+	spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
 	switch (cqr->status) {
 	case DASD_CQR_QUEUED:
 		/* request was not started - just set to failed */
@@ -1993,7 +1619,7 @@
 		BUG();
 
 	}
-	spin_unlock_irqrestore(get_irq_lock(device->devinfo.irq), flags);
+	spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 	dasd_schedule_bh(device);
 	return rc;
 }
@@ -2011,12 +1637,12 @@
 	dasd_device_t *device;
 
 	device = (dasd_device_t *) queue->queuedata;
-	spin_lock(get_irq_lock(device->devinfo.irq));
+	spin_lock(get_ccwdev_lock(device->cdev));
 	/* Get new request from the block device request queue */
 	__dasd_process_blk_queue(device);
 	/* Now check if the head of the ccw queue needs to be started. */
 	__dasd_start_head(device);
-	spin_unlock(get_irq_lock(device->devinfo.irq));
+	spin_unlock(get_ccwdev_lock(device->cdev));
 }
 
 /*
@@ -2089,7 +1715,6 @@
 static int
 dasd_open(struct inode *inp, struct file *filp)
 {
-	dasd_devmap_t *devmap;
 	dasd_device_t *device;
 	int rc;
 	
@@ -2099,55 +1724,35 @@
 			major(inp->i_rdev), minor(inp->i_rdev));
 		return -EPERM;
 	}
-	devmap = dasd_devmap_from_bdev(inp->i_bdev);
-	device = (devmap != NULL) ?
-		dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-	if (IS_ERR(device)) {
-		MESSAGE(KERN_WARNING,
-			"No device registered as (%d:%d)",
-			major(inp->i_rdev), minor(inp->i_rdev));
-		return PTR_ERR(device);
-	}
+
+	device = inp->i_bdev->bd_disk->private_data;
 	if (device->state < DASD_STATE_BASIC) {
 		DBF_DEV_EVENT(DBF_ERR, device, " %s",
 			      " Cannot open unrecognized device");
-		dasd_put_device(devmap);
 		return -ENODEV;
 	}
 	rc = 0;
-	spin_lock(&discipline_lock);
-	if (atomic_inc_return(&device->open_count) == 1 &&
-	    device->discipline->owner != NULL) {
+
+	if (atomic_inc_return(&device->open_count) == 1) {
 		if (!try_inc_mod_count(device->discipline->owner)) {
 			/* Discipline is currently unloaded! */
 			atomic_dec(&device->open_count);
 			rc = -ENODEV;
 		}
 	}
-	spin_unlock(&discipline_lock);
-	dasd_put_device(devmap);
 	return rc;
 }
 
 static int
 dasd_release(struct inode *inp, struct file *filp)
 {
-	dasd_devmap_t *devmap;
 	dasd_device_t *device;
 
-	devmap = dasd_devmap_from_bdev(inp->i_bdev);
-	device = (devmap != NULL) ?
-		dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-	if (IS_ERR(device)) {
-		MESSAGE(KERN_WARNING,
-			"No device registered as %d:%d",
-			major(inp->i_rdev), minor(inp->i_rdev));
-		return -EINVAL;
-	}
+	device = inp->i_bdev->bd_disk->private_data;
+
 	if (device->state < DASD_STATE_ACCEPT) {
 		DBF_DEV_EVENT(DBF_ERR, device, " %s",
 			      " Cannot release unrecognized device");
-		dasd_put_device(devmap);
 		return -EINVAL;
 	}
 	if (atomic_dec_return(&device->open_count) == 0) {
@@ -2155,7 +1760,6 @@
 		if (device->discipline->owner)
 			__MOD_DEC_USE_COUNT(device->discipline->owner);
 	}
-	dasd_put_device(devmap);
 	return 0;
 }
 
@@ -2171,26 +1775,13 @@
 static void
 dasd_exit(void)
 {
-	dasd_disable_devices(0, dasd_max_devindex);
-#ifdef CONFIG_DASD_DIAG
-	if (MACHINE_IS_VM)
-		dasd_diag_cleanup();
-#endif
-#ifdef CONFIG_DASD_FBA
-	dasd_fba_cleanup();
-#endif
-#ifdef CONFIG_DASD_ECKD
-	dasd_eckd_cleanup();
-#endif
-
 #ifdef CONFIG_PROC_FS
 	dasd_proc_exit();
 #endif
 	dasd_ioctl_exit();
 	dasd_gendisk_exit();
 	dasd_devmap_exit();
-	if (dasd_devfs_handle)
-		devfs_unregister(dasd_devfs_handle);
+	devfs_remove("dasd");
 	if (dasd_debug_area != NULL) {
 		debug_unregister(dasd_debug_area);
 		dasd_debug_area = NULL;
@@ -2198,30 +1789,295 @@
 }
 
 /*
- * SECTION: Initializing the driver
+ * SECTION: common functions for ccw_driver use
  */
-static int
-dasd_request_module(void *name)
+
+/* initial attempt at a probe function. this can be simplified once
+ * the other detection code is gone */
+int
+dasd_generic_probe (struct ccw_device *cdev, dasd_discipline_t *discipline)
 {
-	int rc = -ERESTARTSYS;
+	int devno;
+	int ret = 0;
+
+	snprintf(cdev->dev.name, DEVICE_NAME_SIZE,
+		 "Direct Access Storage Device");
+
+	devno = _ccw_device_get_device_number(cdev);
+	if (dasd_autodetect
+	    && (ret = dasd_add_range(devno, devno, DASD_FEATURE_DEFAULT))) {
+		printk (KERN_WARNING
+			"dasd_generic_probe: cannot autodetect %s\n",
+			cdev->dev.bus_id);
+		return ret;
+	}
+
+	if (!ret && (ret = dasd_add_sysfs_files(cdev))) {
+		printk(KERN_WARNING
+		       "dasd_generic_probe: could not add driverfs entries"
+		       "for %s\n", cdev->dev.bus_id);
+	}
 
-	strcpy(current->comm, name);
-	daemonize();
-	while (current->fs->root == NULL)	/* wait for root-FS */
-		schedule_timeout(HZ);	/* wait a second */
-	while ((rc = request_module(name)) != 0) {
-		MESSAGE(KERN_INFO, "request_module returned %d for %s",
-			rc, (char *) name);
-		schedule_timeout(5 * HZ);	/* wait 5 seconds */
+	cdev->handler = &dasd_int_handler;
+
+	if (dasd_autodetect ||
+	    dasd_devmap_from_devno(devno) != 0) {
+		/* => device was in dasd parameter line */
+		ccw_device_set_online(cdev);
+	}
+
+	return ret;
+}
+
+/* this will one day be called from a global not_oper handler.
+ * It is also used by driver_unregister during module unload */
+int
+dasd_generic_remove (struct ccw_device *cdev)
+{
+	struct dasd_device_t *device;
+
+	device = cdev->dev.driver_data;
+	cdev->dev.driver_data = NULL;
+	if (device)
+		kfree(device);
+	return 0;
+}
+
+/* activate a device. This is called from dasd_{eckd,fba}_probe() when either
+ * the device is detected for the first time and is supposed to be used
+ * or the user has started activation through sysfs */
+int
+dasd_generic_set_online (struct ccw_device *cdev,
+			 dasd_discipline_t *discipline)
+
+{
+	int devno;
+	dasd_devmap_t *devmap;
+	dasd_device_t *device;
+	int rc;
+
+	if (cdev->dev.driver_data != NULL) /* already enabled */
+		return 0;
+
+	devno = _ccw_device_get_device_number(cdev);
+	rc = dasd_add_range(devno, devno, DASD_FEATURE_DEFAULT);
+	if (rc)
+		return rc;
+
+	if (!(devmap = dasd_devmap_from_devno (devno)))
+		return 0; /* device is still disabled -> ignore it */
+
+	if (IS_ERR(device = dasd_get_device(devmap))) {
+		printk (KERN_WARNING "dasd_generic could not get %s\n",
+				cdev->dev.bus_id);
+		return PTR_ERR(device);
+	}
+
+	device->gdp->driverfs_dev = &cdev->dev;
+	device->cdev = cdev;
+
+	if (device->use_diag_flag)
+		device->discipline = dasd_diag_discipline_pointer;
+
+	rc = 0;
+	if (!device->discipline ||
+	    (rc = device->discipline->check_device(device))) {
+		pr_debug("device %s is not diag (%d)\n", 
+			 cdev->dev.bus_id, rc);
+		if (device->private != NULL) {
+			kfree(device->private);
+			device->private = NULL;
+		}
+		device->discipline = discipline;
+		rc = discipline->check_device(device);
+	}
+
+	if (rc) {
+		printk (KERN_WARNING "dasd_generic found a bad device %s\n", 
+			cdev->dev.bus_id);
+		dasd_put_device(devmap);
+		return rc;
+	}
+
+	dasd_set_target_state(device, DASD_STATE_ONLINE);
+	if (device->state <= DASD_STATE_KNOWN) {
+		printk (KERN_WARNING
+			"dasd_generic discipline not found for %s\n",
+			cdev->dev.bus_id);
+		rc = -ENODEV;
+		dasd_set_target_state(device, DASD_STATE_NEW);
+	} else {
+		pr_debug("dasd_generic device %s found\n",
+				cdev->dev.bus_id);
+		cdev->dev.driver_data = device;
 	}
+
+	dasd_put_device(devmap);
+	/* FIXME: we have to wait for the root device but we don't want
+	 * to wait for each single device but for all at once. */
+	wait_event(dasd_init_waitq, _wait_for_device(device));
 	return rc;
 }
 
+int
+dasd_generic_set_offline (struct ccw_device *cdev)
+{
+	dasd_device_t *device;
+	dasd_devmap_t *devmap;
+	int devno;
+
+	devno = _ccw_device_get_device_number(cdev);
+	device = cdev->dev.driver_data;
+	devmap = dasd_devmap_from_devno(devno);
+	if (device == NULL || devmap == NULL)
+		return -ENODEV;
+
+	device = dasd_get_device(devmap);
+	if (IS_ERR(device))
+		return PTR_ERR(device);
+
+	dasd_set_target_state(device, DASD_STATE_NEW);
+	dasd_put_device(devmap);
+	
+	return 0;
+}
+
+/*
+ * SECTION: files in sysfs
+ */
+
+/*
+ * readonly controls the readonly status of a dasd
+ */
+static ssize_t
+dasd_ro_show(struct device *dev, char *buf, size_t count, loff_t off)
+{
+	dasd_device_t *device;
+
+	if (off)
+		return 0;
+
+	device = dev->driver_data;
+	if (!device)
+		return snprintf(buf, count, "n/a\n");
+
+	return snprintf(buf, count, device->ro_flag ? "1\n" : "0\n");
+}
+
+static ssize_t
+dasd_ro_store(struct device *dev, const char *buf, size_t count, loff_t off)
+{
+	dasd_device_t *device = dev->driver_data;
+
+	if (off)
+		return 0;
+
+	if (device)
+		device->ro_flag = (buf[0] == '1') ? 1 : 0;
+	return count;
+}
+
+static DEVICE_ATTR(readonly, 0644, dasd_ro_show, dasd_ro_store);
+
+/*
+ * use_diag controls whether the driver should use diag rather than ssch
+ * to talk to the device
+ */
+/* TODO: Implement */
+static ssize_t 
+dasd_use_diag_show(struct device *dev, char *buf, size_t count, loff_t off)
+{
+	dasd_device_t *device;
+
+	if (off)
+		return 0;
+
+	device = dev->driver_data;
+	if (!device)
+		return snprintf(buf, count, "n/a\n");
+
+	return snprintf(buf, count, device->use_diag_flag ? "1\n" : "0\n");
+}
+
+static ssize_t
+dasd_use_diag_store(struct device *dev, const char *buf, 
+		    size_t count, loff_t off)
+{
+	dasd_device_t *device = dev->driver_data;
+
+	if (off)
+		return 0;
+
+	if (device)
+		device->use_diag_flag = (buf[0] == '1') ? 1 : 0;
+	return count;
+}
+
+static
+DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store);
+
+#if 0
+/* this file shows the same information as /proc/dasd/devices using
+ * an inaccaptable interface */
+/* TODO: Split this up into smaller files! */
+static ssize_t
+dasd_devices_show(struct device *dev, char *buf, size_t count, loff_t off)
+{
+	
+	dasd_device_t *device;
+	dasd_devmap_t *devmap;
+
+	if (off)	/* ignore partial write */
+		return 0;
+
+	devmap = NULL;
+	device = dev->driver_data;
+	if (device)
+		devmap = dasd_devmap_from_devno(device->devno);
+
+	if (!devmap)
+		return snprintf(buf, count, "unused\n");
+
+	return min ((size_t) dasd_devices_print(devmap, buf), count);
+}
+
+static DEVICE_ATTR(dasd, 0444, dasd_devices_show, 0);
+#endif
+
+static ssize_t
+dasd_discipline_show(struct device *dev, char *buf, size_t count, loff_t off)
+{
+	dasd_device_t *device;
+
+	if (off)
+		return 0;
+	device = dev->driver_data;
+	if (!device || !device->discipline)
+		return snprintf(buf, count, "none\n");
+	return snprintf(buf, count, "%s\n", device->discipline->name);
+}
+
+static DEVICE_ATTR(discipline, 0444, dasd_discipline_show, 0);
+
+static int
+dasd_add_sysfs_files(struct ccw_device *cdev)
+{
+	int ret;
+
+	if (/* (ret = device_create_file(&cdev->dev, &dev_attr_dasd)) || */
+	    (ret = device_create_file(&cdev->dev, &dev_attr_readonly)) ||
+	    (ret = device_create_file(&cdev->dev, &dev_attr_discipline)) ||
+	    (ret = device_create_file(&cdev->dev, &dev_attr_use_diag))) {
+		device_remove_file(&cdev->dev, &dev_attr_discipline);
+		device_remove_file(&cdev->dev, &dev_attr_readonly);
+		/* device_remove_file(&cdev->dev, &dev_attr_dasd); */
+	}
+	return ret;
+}
+
 static int __init
 dasd_init(void)
 {
-	char **disc;
-	int irq, devno;
 	int rc;
 
 	init_waitqueue_head(&dasd_init_waitq);
@@ -2237,8 +2093,7 @@
 
 	DBF_EVENT(DBF_EMERG, "%s", "debug area created");
 
-	dasd_devfs_handle = devfs_mk_dir(NULL, "dasd", NULL);
-	if (dasd_devfs_handle < 0) {
+	if (devfs_mk_dir(NULL, "dasd", NULL)) {
 		DBF_EVENT(DBF_ALERT, "%s", "no devfs");
 		rc = -ENOSYS;
 		goto failed;
@@ -2261,60 +2116,6 @@
 		goto failed;
 #endif
 
-	if (dasd_autodetect) {
-		/* update device range to all devices */
-		irq = get_irq_first();
-		while (irq != -ENODEV) {
-			devno = get_devno_by_irq(irq);
-			if (dasd_devmap_from_devno(devno) == NULL) {
-				/* devno not included yet */
-				DBF_EVENT(DBF_NOTICE, "add %04x to range",
-					  devno);
-				dasd_add_range(devno, devno,
-					       DASD_FEATURE_DEFAULT);
-			}
-			irq = get_irq_next(irq);
-		}
-	}
-
-	if (MACHINE_IS_VM) {
-#ifdef CONFIG_DASD_DIAG
-		rc = dasd_diag_init();
-		if (rc != 0) {
-			DBF_EVENT(DBF_ALERT, "%s",
-				  "Register DIAG discipline failed");
-			goto failed;
-		}
-#endif				/* CONFIG_DASD_DIAG */
-#if defined(CONFIG_DASD_DIAG_MODULE) && defined(CONFIG_DASD_AUTO_DIAG)
-		kernel_thread(dasd_request_module, "dasd_diag_mod", SIGCHLD);
-#endif
-	}
-#ifdef CONFIG_DASD_ECKD
-	rc = dasd_eckd_init();
-	if (rc != 0) {
-		DBF_EVENT(DBF_ALERT, "%s", "Register ECKD discipline failed");
-		goto failed;
-	}
-#endif				/* CONFIG_DASD_ECKD */
-#if defined(CONFIG_DASD_ECKD_MODULE) && defined(CONFIG_DASD_AUTO_ECKD)
-	kernel_thread(dasd_request_module, "dasd_eckd_mod", SIGCHLD);
-#endif
-#ifdef CONFIG_DASD_FBA
-	rc = dasd_fba_init();
-	if (rc != 0) {
-		DBF_EVENT(DBF_ALERT, "%s", "Register FBA discipline failed");
-		goto failed;
-	}
-#endif
-#if defined(CONFIG_DASD_FBA_MODULE) && defined(CONFIG_DASD_AUTO_FBA)
-	kernel_thread(dasd_request_module, "dasd_fba_mod", SIGCHLD);
-#endif				/* CONFIG_DASD_AUTO_FBA */
-	disc = dasd_disciplines;
-	while (*disc) {
-		kernel_thread(dasd_request_module, *disc, SIGCHLD);
-		disc++;
-	}
 	return 0;
 failed:
 	MESSAGE(KERN_INFO, "%s", "initialization not performed due to errors");
@@ -2331,16 +2132,11 @@
 EXPORT_SYMBOL(dasd_add_request_tail);
 EXPORT_SYMBOL(dasd_cancel_req);
 EXPORT_SYMBOL(dasd_clear_timer);
-EXPORT_SYMBOL(dasd_disable_devices);
-EXPORT_SYMBOL(dasd_discipline_add);
-EXPORT_SYMBOL(dasd_discipline_del);
-EXPORT_SYMBOL(dasd_enable_devices);
+EXPORT_SYMBOL(dasd_enable_device);
 EXPORT_SYMBOL(dasd_int_handler);
 EXPORT_SYMBOL(dasd_kfree_request);
 EXPORT_SYMBOL(dasd_kick_device);
 EXPORT_SYMBOL(dasd_kmalloc_request);
-EXPORT_SYMBOL(dasd_not_oper_handler);
-EXPORT_SYMBOL(dasd_oper_handler);
 EXPORT_SYMBOL(dasd_schedule_bh);
 EXPORT_SYMBOL(dasd_set_target_state);
 EXPORT_SYMBOL(dasd_set_timer);
diff -Nru a/drivers/s390/block/dasd_3370_erp.c b/drivers/s390/block/dasd_3370_erp.c
--- a/drivers/s390/block/dasd_3370_erp.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/s390/block/dasd_3370_erp.c	Mon Dec  9 18:46:38 2002
@@ -3,6 +3,11 @@
  * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
+ *
+ * $Revision: 1.7 $
+ *
+ * History of changes 
+ *
  */
 
 #define PRINTK_HEADER "dasd_erp(3370)"
@@ -27,13 +32,13 @@
  *   dasd_era_recover	for all others.
  */
 dasd_era_t
-dasd_3370_erp_examine(dasd_ccw_req_t * cqr, devstat_t * stat)
+dasd_3370_erp_examine(dasd_ccw_req_t * cqr, struct irb * irb)
 {
-	char *sense = stat->ii.sense.data;
+	char *sense = irb->ecw;
 
 	/* check for successful execution first */
-	if (stat->cstat == 0x00 &&
-	    stat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
+	if (irb->scsw.cstat == 0x00 &&
+	    irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
 		return dasd_era_none;
 	if (sense[0] & 0x80) {	/* CMD reject */
 		return dasd_era_fatal;
diff -Nru a/drivers/s390/block/dasd_3370_erp.h b/drivers/s390/block/dasd_3370_erp.h
--- a/drivers/s390/block/dasd_3370_erp.h	Mon Dec  9 18:46:36 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,15 +0,0 @@
-/* 
- * File...........: linux/drivers/s390/block/dasd_3370_erp.h
- * Author(s)......: Horst Hummel <Horst Hummel@de.ibm.com>
- * Bugreports.to..: <Linux390@de.ibm.com>
- * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
- *
- * History of changes (starts July 2000)
- */
-
-#ifndef DASD_3370_ERP_H
-#define DASD_3370_ERP_H
-
-dasd_era_t dasd_3370_erp_examine(dasd_ccw_req_t *, devstat_t *);
-
-#endif				/* DASD_3990_ERP_H */
diff -Nru a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
--- a/drivers/s390/block/dasd_3990_erp.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/s390/block/dasd_3990_erp.c	Mon Dec  9 18:46:50 2002
@@ -5,6 +5,8 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001
  *
+ * $Revision: 1.19 $
+ *
  * History of changes:
  * 05/14/01 fixed PL030160GTO (BUG() in erp_action_5)
  * 05/04/02 code restructuring.
@@ -13,7 +15,6 @@
 #include <linux/timer.h>
 #include <linux/slab.h>
 #include <asm/idals.h>
-#include <asm/s390io.h>
 #include <asm/todclk.h>
 
 #define PRINTK_HEADER "dasd_erp(3990): "
@@ -148,16 +149,16 @@
  *   dasd_era_recover	for all others.
  */
 dasd_era_t
-dasd_3990_erp_examine(dasd_ccw_req_t * cqr, devstat_t * stat)
+dasd_3990_erp_examine(dasd_ccw_req_t * cqr, struct irb * irb)
 {
 
-	char *sense = stat->ii.sense.data;
+	char *sense = irb->ecw;
 	dasd_era_t era = dasd_era_recover;
 	dasd_device_t *device = cqr->device;
 
 	/* check for successful execution first */
-	if (stat->cstat == 0x00 &&
-	    stat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
+	if (irb->scsw.cstat == 0x00 &&
+	    irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
 		return dasd_era_none;
 
 	/* distinguish between 24 and 32 byte sense data */
@@ -172,8 +173,10 @@
 	}
 
 	/* log the erp chain if fatal error occurred */
-	if ((era == dasd_era_fatal) && (device->state >= DASD_STATE_READY))
-		dasd_log_ccw(cqr, 0, stat->cpa);
+	if ((era == dasd_era_fatal) && (device->state >= DASD_STATE_READY)) {
+		dasd_log_sense(cqr, irb);
+		dasd_log_ccw(cqr, 0, irb->scsw.cpa);
+	}
 
 	return era;
 
@@ -296,42 +299,39 @@
  *
  * RETURN VALUES
  *   erp		modified pointer to the ERP
- *
  */
 static void
 dasd_3990_erp_alternate_path(dasd_ccw_req_t * erp)
 {
-
 	dasd_device_t *device = erp->device;
-	int irq = device->devinfo.irq;
+	__u8 opm;
 
 	/* try alternate valid path */
-	erp->lpm &= ~(erp->dstat->lpum);
-	erp->options |= DOIO_VALID_LPM;	/* use LPM for DO_IO */
+	opm = ccw_device_get_path_mask(device->cdev);
+	//FIXME: start with get_opm ?
+	if (erp->lpm == 0)
+		erp->lpm = LPM_ANYPATH & ~(erp->dstat->esw.esw0.sublog.lpum);
+	else
+		erp->lpm &= ~(erp->dstat->esw.esw0.sublog.lpum);
 
-	if ((erp->lpm & ioinfo[irq]->opm) != 0x00) {
+	if ((erp->lpm & opm) != 0x00) {
 
 		DEV_MESSAGE(KERN_DEBUG, device,
 			    "try alternate lpm=%x (lpum=%x / opm=%x)",
-			    erp->lpm, erp->dstat->lpum, ioinfo[irq]->opm);
+			    erp->lpm, erp->dstat->esw.esw0.sublog.lpum, opm);
 
 		/* reset status to queued to handle the request again... */
 		erp->status = DASD_CQR_QUEUED;
-
 		erp->retries = 1;
-
 	} else {
-
 		DEV_MESSAGE(KERN_ERR, device,
 			    "No alternate channel path left (lpum=%x / "
 			    "opm=%x) -> permanent error",
-			    erp->dstat->lpum, ioinfo[irq]->opm);
+			    erp->dstat->esw.esw0.sublog.lpum, opm);
 
 		/* post request with permanent error */
 		erp->status = DASD_CQR_FAILED;
-
 	}
-
 }				/* end dasd_3990_erp_alternate_path */
 
 /*
@@ -355,7 +355,7 @@
 
 	dasd_device_t *device = erp->device;
 	DCTL_data_t *DCTL_data;
-	ccw1_t *ccw;
+	struct ccw1 *ccw;
 	dasd_ccw_req_t *dctl_cqr;
 
 	dctl_cqr = dasd_alloc_erp_request((char *) &erp->magic, 1,
@@ -373,7 +373,7 @@
 	DCTL_data->modifier = modifier;
 
 	ccw = dctl_cqr->cpaddr;
-	memset(ccw, 0, sizeof (ccw1_t));
+	memset(ccw, 0, sizeof (struct ccw1));
 	ccw->cmd_code = CCW_CMD_DCTL;
 	ccw->count = 4;
 	ccw->cda = (__u32)(addr_t) DCTL_data;
@@ -381,7 +381,6 @@
 	dctl_cqr->refers = erp;
 	dctl_cqr->device = erp->device;
 	dctl_cqr->magic = erp->magic;
-	dctl_cqr->lpm = LPM_ANYPATH;
 	dctl_cqr->expires = 5 * 60 * HZ;
 	dctl_cqr->retries = 2;
 
@@ -1122,6 +1121,9 @@
 		break;
 
 	default:	/* unknown message format - should not happen */
+	        DEV_MESSAGE (KERN_WARNING, device,
+                             "unknown message format %02x",
+                             msg_format);
 		break;
 	}			/* end switch message format */
 
@@ -1650,7 +1652,7 @@
 	dasd_ccw_req_t *erp;
 	DE_eckd_data_t *DE_data;
 	char *LO_data;		/* LO_eckd_data_t */
-	ccw1_t *ccw;
+	struct ccw1 *ccw;
 
 	DEV_MESSAGE(KERN_DEBUG, device, "%s",
 		    "Write not finished because of unexpected condition");
@@ -1675,7 +1677,7 @@
 
 	/* determine the address of the CCW to be restarted */
 	/* Imprecise ending is not set -> addr from IRB-SCSW */
-	cpa = default_erp->refers->dstat->cpa;
+	cpa = default_erp->refers->dstat->scsw.cpa;
 
 	if (cpa == 0) {
 
@@ -1735,7 +1737,7 @@
 
 	/* create DE ccw */
 	ccw = erp->cpaddr;
-	memset(ccw, 0, sizeof (ccw1_t));
+	memset(ccw, 0, sizeof (struct ccw1));
 	ccw->cmd_code = DASD_ECKD_CCW_DEFINE_EXTENT;
 	ccw->flags = CCW_FLAG_CC;
 	ccw->count = 16;
@@ -1743,7 +1745,7 @@
 
 	/* create LO ccw */
 	ccw++;
-	memset(ccw, 0, sizeof (ccw1_t));
+	memset(ccw, 0, sizeof (struct ccw1));
 	ccw->cmd_code = DASD_ECKD_CCW_LOCATE_RECORD;
 	ccw->flags = CCW_FLAG_CC;
 	ccw->count = 16;
@@ -1759,7 +1761,6 @@
 	erp->refers = default_erp->refers;
 	erp->device = device;
 	erp->magic = default_erp->magic;
-	erp->lpm = 0xFF;
 	erp->expires = 0;
 	erp->retries = 256;
 	erp->status = DASD_CQR_FILLED;
@@ -1795,7 +1796,7 @@
 	dasd_ccw_req_t *cqr;
 	dasd_ccw_req_t *erp;
 	char *LO_data;		/* LO_eckd_data_t */
-	ccw1_t *ccw;
+	struct ccw1 *ccw;
 
 	DEV_MESSAGE(KERN_DEBUG, device, "%s",
 		    "Write not finished because of unexpected condition"
@@ -1821,7 +1822,7 @@
 
 	/* determine the address of the CCW to be restarted */
 	/* Imprecise ending is not set -> addr from IRB-SCSW */
-	cpa = previous_erp->dstat->cpa;
+	cpa = previous_erp->dstat->scsw.cpa;
 
 	if (cpa == 0) {
 
@@ -1954,7 +1955,7 @@
 			/* reset the lpm and the status to be able to 
 			 * try further actions. */
 
-			erp->lpm = LPM_ANYPATH;
+			erp->lpm = 0;
 
 			erp->status = DASD_CQR_ERROR;
 
@@ -2234,7 +2235,7 @@
 	dasd_ccw_req_t *erp_new = NULL;
 	/* sense data are located in the refers record of the */
 	/* already set up new ERP !			      */
-	char *sense = erp->refers->dstat->ii.sense.data;
+	char *sense = erp->refers->dstat->ecw;
 
 	/* distinguish between 24 and 32 byte sense data */
 	if (sense[27] & DASD_SENSE_BIT_0) {
@@ -2291,7 +2292,6 @@
 	erp->refers = cqr;
 	erp->device = cqr->device;
 	erp->magic = cqr->magic;
-	erp->lpm = 0xFF;
 	erp->expires = 0;
 	erp->retries = 256;
 
@@ -2357,18 +2357,14 @@
 {
 
 	/* check failed CCW */
-	if (cqr1->dstat->cpa != cqr2->dstat->cpa) {
+	if (cqr1->dstat->scsw.cpa != cqr2->dstat->scsw.cpa) {
 		//	return 0;	/* CCW doesn't match */
 	}
 
 	/* check sense data; byte 0-2,25,27 */
-	if (!((strncmp(cqr1->dstat->ii.sense.data,
-		       cqr2->dstat->ii.sense.data,
-		       3) == 0) &&
-	      (cqr1->dstat->ii.sense.data[27] ==
-	       cqr2->dstat->ii.sense.data[27]) &&
-	      (cqr1->dstat->ii.sense.data[25] ==
-	       cqr2->dstat->ii.sense.data[25]))) {
+	if (!((strncmp(cqr1->dstat->ecw, cqr2->dstat->ecw, 3) == 0) &&
+	      (cqr1->dstat->ecw[27] == cqr2->dstat->ecw[27]) &&
+	      (cqr1->dstat->ecw[25] == cqr2->dstat->ecw[25]))) {
 
 		return 0;	/* sense doesn't match */
 	}
@@ -2441,7 +2437,7 @@
 {
 
 	dasd_device_t *device = erp->device;
-	char *sense = erp->dstat->ii.sense.data;
+	char *sense = erp->dstat->ecw;
 
 	/* check for 24 byte sense ERP */
 	if ((erp->function == dasd_3990_erp_bus_out) ||
@@ -2553,7 +2549,7 @@
 
 	if (erp->retries > 0) {
 
-		char *sense = erp->dstat->ii.sense.data;
+		char *sense = erp->dstat->ecw;
 
 		/* check for special retries */
 		if (erp->function == dasd_3990_erp_action_4) {
@@ -2611,7 +2607,7 @@
 
 	dasd_ccw_req_t *erp = NULL;
 	dasd_device_t *device = cqr->device;
-	__u32 cpa = cqr->dstat->cpa;
+	__u32 cpa = cqr->dstat->scsw.cpa;
 
 #ifdef ERP_DEBUG
 	/* print current erp_chain */
@@ -2631,8 +2627,8 @@
 #endif				/* ERP_DEBUG */
 
 	/* double-check if current erp/cqr was successfull */
-	if ((cqr->dstat->cstat == 0x00) &&
-	    (cqr->dstat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))) {
+	if ((cqr->dstat->scsw.cstat == 0x00) &&
+	    (cqr->dstat->scsw.dstat == (DEV_STAT_CHN_END|DEV_STAT_DEV_END))) {
 
 		DEV_MESSAGE(KERN_DEBUG, device,
 			    "ERP called for successful request %p"
@@ -2643,7 +2639,7 @@
 		return cqr;
 	}
 	/* check if sense data are available */
-	if (!cqr->dstat->ii.sense.data) {
+	if (!cqr->dstat->ecw) {
 		DEV_MESSAGE(KERN_DEBUG, device,
 			    "ERP called witout sense data avail ..."
 			    "request %p - NO ERP possible", cqr);
diff -Nru a/drivers/s390/block/dasd_3990_erp.h b/drivers/s390/block/dasd_3990_erp.h
--- a/drivers/s390/block/dasd_3990_erp.h	Mon Dec  9 18:46:34 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,26 +0,0 @@
-/* 
- * File...........: linux/drivers/s390/block/dasd_3990_erp.h
- * Author(s)......: Horst Hummel <Horst Hummel@de.ibm.com>
- * Bugreports.to..: <Linux390@de.ibm.com>
- * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
- *
- * History of changes (starts July 2000)
- */
-
-#ifndef DASD_3990_ERP_H
-#define DASD_3990_ERP_H
-
-dasd_era_t dasd_3990_erp_examine(dasd_ccw_req_t *, devstat_t *);
-
-dasd_ccw_req_t *dasd_3990_erp_action(dasd_ccw_req_t *);
-dasd_ccw_req_t *dasd_2105_erp_action(ccw_req_t *);
-
-void dasd_3990_erp_restart_queue(unsigned long);
-
-typedef struct DCTL_data_t {
-	unsigned char subcommand;	/* e.g Inhibit Write, Enable Write,... */
-	unsigned char modifier;	/* Subcommand modifier		       */
-	unsigned short res;	/* reserved */
-} __attribute__ ((packed)) DCTL_data_t;
-
-#endif				/* DASD_3990_ERP_H */
diff -Nru a/drivers/s390/block/dasd_9336_erp.c b/drivers/s390/block/dasd_9336_erp.c
--- a/drivers/s390/block/dasd_9336_erp.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/s390/block/dasd_9336_erp.c	Mon Dec  9 18:46:50 2002
@@ -3,6 +3,11 @@
  * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
+ *
+ * $Revision: 1.6 $
+ *
+ * History of changes 
+ *
  */
 
 #define PRINTK_HEADER "dasd_erp(9336)"
@@ -27,11 +32,11 @@
  *   dasd_era_recover	for all others.
  */
 dasd_era_t
-dasd_9336_erp_examine(dasd_ccw_req_t * cqr, devstat_t * stat)
+dasd_9336_erp_examine(dasd_ccw_req_t * cqr, struct irb * irb)
 {
 	/* check for successful execution first */
-	if (stat->cstat == 0x00 &&
-	    stat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
+	if (irb->scsw.cstat == 0x00 &&
+	    irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
 		return dasd_era_none;
 
 	/* examine the 24 byte sense data */
diff -Nru a/drivers/s390/block/dasd_9336_erp.h b/drivers/s390/block/dasd_9336_erp.h
--- a/drivers/s390/block/dasd_9336_erp.h	Mon Dec  9 18:46:37 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,15 +0,0 @@
-/* 
- * File...........: linux/drivers/s390/block/dasd_9336_erp.h
- * Author(s)......: Horst Hummel <Horst Hummel@de.ibm.com>
- * Bugreports.to..: <Linux390@de.ibm.com>
- * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
- *
- * History of changes (starts July 2000)
- */
-
-#ifndef DASD_9336_ERP_H
-#define DASD_9336_ERP_H
-
-dasd_era_t dasd_9336_erp_examine(dasd_ccw_req_t *, devstat_t *);
-
-#endif				/* DASD_3990_ERP_H */
diff -Nru a/drivers/s390/block/dasd_9343_erp.c b/drivers/s390/block/dasd_9343_erp.c
--- a/drivers/s390/block/dasd_9343_erp.c	Mon Dec  9 18:46:52 2002
+++ b/drivers/s390/block/dasd_9343_erp.c	Mon Dec  9 18:46:52 2002
@@ -1,8 +1,13 @@
 /* 
- * File...........: linux/drivers/s390/block/dasd_9345_erp.h
+ * File...........: linux/drivers/s390/block/dasd_9345_erp.c
  * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
+ *
+ * $Revision: 1.11 $
+ *
+ * History of changes 
+ * 
  */
 
 #define PRINTK_HEADER "dasd_erp(9343)"
@@ -10,10 +15,11 @@
 #include "dasd_int.h"
 
 dasd_era_t
-dasd_9343_erp_examine(dasd_ccw_req_t * cqr, devstat_t * stat)
+dasd_9343_erp_examine(dasd_ccw_req_t * cqr, struct irb * irb)
 {
-	if (stat->cstat == 0x00 &&
-	    stat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
+	if (irb->scsw.cstat == 0x00 &&
+	    irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
 		return dasd_era_none;
+
 	return dasd_era_recover;
 }
diff -Nru a/drivers/s390/block/dasd_9343_erp.h b/drivers/s390/block/dasd_9343_erp.h
--- a/drivers/s390/block/dasd_9343_erp.h	Mon Dec  9 18:46:35 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,17 +0,0 @@
-/* 
- * File...........: linux/drivers/s390/block/dasd_9343_erp.h
- * Author(s)......: Horst Hummel <Horst Hummel@de.ibm.com>
- * Bugreports.to..: <Linux390@de.ibm.com>
- * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
- *
- * History of changes (starts July 2000)
- */
-
-#ifndef DASD_9343_ERP_H
-#define DASD_9343_ERP_H
-
-dasd_era_t dasd_9343_erp_examine(dasd_ccw_req_t *, devstat_t *);
-
-dasd_ccw_req_t *dasd_9343_erp_action(dasd_ccw_req_t *);
-
-#endif				/* DASD_9343_ERP_H */
diff -Nru a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
--- a/drivers/s390/block/dasd_devmap.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/s390/block/dasd_devmap.c	Mon Dec  9 18:46:37 2002
@@ -11,6 +11,9 @@
  * functions may not be called from interrupt context. In particular
  * dasd_get_device is a no-no from interrupt context.
  *
+ * $Revision: 1.11 $
+ *
+ * History of changes 
  * 05/04/02 split from dasd.c, code restructuring.
  */
 
@@ -20,7 +23,6 @@
 #include <linux/init.h>
 
 #include <asm/debug.h>
-#include <asm/irq.h>
 #include <asm/uaccess.h>
 
 /* This is ugly... */
@@ -84,9 +86,11 @@
  * Read a device number from a string. The number is always in hex,
  * a leading 0x is accepted.
  */
-int
+static inline int
 dasd_devno(char *str, char **endp)
 {
+	int val;
+ 
 	/* remove leading '0x' */
 	if (*str == '0') {
 		str++;
@@ -96,7 +100,10 @@
 	/* We require at least one hex digit */
 	if (!isxdigit(*str))
 		return -EINVAL;
-	return simple_strtoul(str, endp, 16);
+	val = simple_strtoul(str, endp, 16);
+	if ((val > 0xFFFF) || (val < 0))
+		return -EINVAL;
+	return val;
 }
 
 /*
@@ -104,7 +111,7 @@
  * only one: "ro" for read-only devices. The default feature set
  * is empty (value 0).
  */
-int
+static inline int
 dasd_feature_list(char *str, char **endp)
 {
 	int features, len, rc;
@@ -260,64 +267,12 @@
 			devmap->devindex = devindex;
 			devmap->devno = devno;
 			devmap->features = features;
-			devmap->devreg = NULL;
 			devmap->device = NULL;
 			list_add(&devmap->devindex_list,
 				 &dasd_devindex_hashlists[devindex & 255]);
 			list_add(&devmap->devno_list,
 				 &dasd_devno_hashlists[devno & 255]);
 		}
-		if (devmap->devreg == NULL) {
-			/* The devreg is missing. */
-			devmap->devreg = (devreg_t *)
-				kmalloc(sizeof(devreg_t), GFP_KERNEL);
-			if (devmap->devreg == NULL)
-				return -ENOMEM;
-			memset(devmap->devreg, sizeof(devreg_t), 0);
-			devmap->devreg->ci.devno = devno;
-			devmap->devreg->flag = DEVREG_TYPE_DEVNO;
-			devmap->devreg->oper_func = dasd_oper_handler;
-			s390_device_register(devmap->devreg);
-		}
-	}
-	spin_unlock(&dasd_devmap_lock);
-	return 0;
-}
-
-/*
- * Removes the devreg_t structures for a range of devices. This does
- * NOT remove the range itself. The mapping between devno and kdevs
- * for the devices is remembered until dasd_forget_ranges() is called.
- */
-static int
-dasd_clear_range(int from, int to)
-{
-	int devno;
-
-	if (from > to) {
-		MESSAGE(KERN_ERR,
-			"Invalid device range %04x-%04x", from, to);
-		return -EINVAL;
-	}
-	spin_lock(&dasd_devmap_lock);
-	for (devno = from; devno <= to; devno++) {
-		struct list_head *l;
-		dasd_devmap_t *devmap = NULL;
-		/* Find previous devmap for device number i */
-		list_for_each(l, &dasd_devno_hashlists[devno & 255]) {
-			devmap = list_entry(l, dasd_devmap_t, devno_list);
-			if (devmap->devno == devno)
-				break;
-		}
-		if (devmap == NULL)
-			continue;
-		if (devmap->device != NULL)
-			BUG();
-		if (devmap->devreg == NULL)
-			continue;
-		s390_device_unregister(devmap->devreg);
-		kfree(devmap->devreg);
-		devmap->devreg = NULL;
 	}
 	spin_unlock(&dasd_devmap_lock);
 	return 0;
@@ -340,11 +295,6 @@
 			devmap = list_entry(l, dasd_devmap_t, devno_list);
 			if (devmap->device != NULL)
 				BUG();
-			if (devmap->devreg != NULL) {
-				s390_device_unregister(devmap->devreg);
-				kfree(devmap->devreg);
-				devmap->devreg = NULL;
-			}
 			list_del(&devmap->devindex_list);
 			list_del(&devmap->devno_list);
 			kfree(devmap);
@@ -404,52 +354,6 @@
 }
 
 /*
- * Find the devmap for a device by its irq line.
- */
-dasd_devmap_t *
-dasd_devmap_from_irq(int irq)
-{
-	struct list_head *l;
-	dasd_devmap_t *devmap, *tmp;
-	int i;
-
-	devmap = NULL;
-	spin_lock(&dasd_devmap_lock);
-	for (i = 0; (i < 256) && (devmap == NULL); i++) {
-		list_for_each(l, &dasd_devno_hashlists[i & 255]) {
-			tmp = list_entry(l, dasd_devmap_t, devno_list);
-			if (tmp->device != NULL &&
-			    tmp->device->devinfo.irq == irq) {
-				devmap = tmp;
-				break;
-			}
-		}
-	}
-	spin_unlock(&dasd_devmap_lock);
-	return devmap;
-}
-
-/*
- * Find the devmap for a device corresponding to a block_device.
- */
-dasd_devmap_t *
-dasd_devmap_from_bdev(struct block_device *bdev)
-{
-	kdev_t kdev = to_kdev_t(bdev->bd_dev);
-	int devindex;
-
-	/* Find the devindex for kdev. */
-	devindex = dasd_gendisk_major_index(major(kdev));
-	if (devindex < 0)
-		/* No such major -> no devmap */
-		return NULL;
-	devindex += minor(kdev) >> DASD_PARTN_BITS;
-
-	/* Now find the devmap by the devindex. */
-	return dasd_devmap_from_devindex(devindex);
-}
-
-/*
  * Find the device structure for device number devno. If it does not
  * exists yet, allocate it. Increase the reference counter in the device
  * structure and return a pointer to it.
@@ -479,6 +383,8 @@
 	} else
 		devmap->device = device;
 	atomic_inc(&device->ref_count);
+	device->ro_flag = (devmap->features & DASD_FEATURE_READONLY) ? 1 : 0;
+	device->use_diag_flag = 1;
 	spin_unlock(&dasd_devmap_lock);
 	return device;
 }
@@ -523,9 +429,3 @@
 {
 	dasd_forget_ranges();
 }
-
-EXPORT_SYMBOL(dasd_devmap_from_devno);
-EXPORT_SYMBOL(dasd_devmap_from_devindex);
-EXPORT_SYMBOL(dasd_devmap_from_irq);
-EXPORT_SYMBOL(dasd_get_device);
-EXPORT_SYMBOL(dasd_put_device);
diff -Nru a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
--- a/drivers/s390/block/dasd_diag.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/s390/block/dasd_diag.c	Mon Dec  9 18:46:34 2002
@@ -5,7 +5,9 @@
  * ...............: by Hartmunt Penner <hpenner@de.ibm.com>
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
-
+ *
+ * $Revision: 1.27 $
+ *
  * History of changes
  * 07/13/00 Added fixup sections for diagnoses ans saved some registers
  * 07/14/00 fixed constraints in newly generated inline asm
@@ -22,13 +24,13 @@
 #include <linux/slab.h>
 #include <linux/hdreg.h>	/* HDIO_GETGEO			    */
 #include <linux/bio.h>
+#include <linux/module.h>
+#include <linux/init.h>
 
 #include <asm/dasd.h>
 #include <asm/debug.h>
 #include <asm/ebcdic.h>
 #include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/s390dyn.h>
 #include <asm/s390_ext.h>
 #include <asm/todclk.h>
 
@@ -40,7 +42,7 @@
 #endif				/* PRINTK_HEADER */
 #define PRINTK_HEADER "dasd(diag):"
 
-static dasd_discipline_t dasd_diag_discipline;
+MODULE_LICENSE("GPL");
 
 typedef struct dasd_diag_private_t {
 	dasd_diag_characteristics_t rdc_data;
@@ -57,25 +59,30 @@
 static __inline__ int
 dia250(void *iob, int cmd)
 {
-	__asm__ __volatile__("	  lr	0,%1\n"
-			     "	  diag	0,%0,0x250\n"
+	int rc;
+
+	__asm__ __volatile__("    lhi   %0,3\n"
+			     "	  lr	0,%2\n"
+			     "	  diag	0,%1,0x250\n"
 			     "0:  ipm	%0\n"
 			     "	  srl	%0,28\n"
 			     "	  or	%0,1\n"
 			     "1:\n"
-			     ".section .fixup,\"ax\"\n"
-			     "2:  lhi	%0,3\n"
-			     "	  bras	1,3f\n"
-			     "	  .long 1b\n"
-			     "3:  l	1,0(1)\n"
-			     "	  br	1\n"
-			     ".previous\n"
+#ifndef CONFIG_ARCH_S390X
 			     ".section __ex_table,\"a\"\n"
 			     "	  .align 4\n"
-			     "	  .long 0b,2b\n" ".previous\n":"+d"(cmd)
-			     :"d"((void *) __pa(iob))
-			     :"0", "1", "cc");
-	return cmd;
+			     "	  .long 0b,1b\n"
+			     ".previous\n"
+#else
+			     ".section __ex_table,\"a\"\n"
+			     "	  .align 8\n"
+			     "	  .quad  0b,1b\n"
+			     ".previous\n"
+#endif
+			     : "=&d" (rc)
+			     : "d" (cmd), "d" ((void *) __pa(iob))
+			     : "0", "1", "cc");
+	return rc;
 }
 
 static __inline__ int
@@ -89,7 +96,7 @@
 	iib = &private->iib;
 	memset(iib, 0, sizeof (diag_init_io_t));
 
-	iib->dev_nr = device->devinfo.devno;
+	iib->dev_nr = device->devno;
 	iib->block_size = blocksize;
 	iib->offset = offset;
 	iib->start_block = 0;
@@ -110,7 +117,7 @@
 	private = (dasd_diag_private_t *) device->private;
 	iib = &private->iib;
 	memset(iib, 0, sizeof (diag_init_io_t));
-	iib->dev_nr = device->devinfo.devno;
+	iib->dev_nr = device->devno;
 	rc = dia250(iib, TERM_BIO);
 	return rc & 3;
 }
@@ -127,7 +134,7 @@
 	private = (dasd_diag_private_t *) device->private;
 	dreq = (dasd_diag_req_t *) cqr->data;
 
-	private->iob.dev_nr = device->devinfo.devno;
+	private->iob.dev_nr = device->devno;
 	private->iob.key = 0;
 	private->iob.flags = 2;	/* do asynchronous io */
 	private->iob.block_count = dreq->block_count;
@@ -191,7 +198,7 @@
 	}
 
 	/* get irq lock to modify request queue */
-	spin_lock_irqsave(get_irq_lock(device->devinfo.irq), flags);
+	spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
 
 	cqr->stopclk = get_clock();
 
@@ -219,7 +226,7 @@
 		dasd_clear_timer(device);
 	dasd_schedule_bh(device);
 
-	spin_unlock_irqrestore(get_irq_lock(device->devinfo.irq), flags);
+	spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 	irq_exit();
 }
 
@@ -245,10 +252,10 @@
 	}
 	/* Read Device Characteristics */
 	rdc_data = (void *) &(private->rdc_data);
-	rdc_data->dev_nr = device->devinfo.devno;
+	rdc_data->dev_nr = device->devno;
 	rdc_data->rdc_len = sizeof (dasd_diag_characteristics_t);
 
-	rc = diag210((diag210_t *) rdc_data);
+	rc = diag210((struct diag210 *) rdc_data);
 	if (rc)
 		return -ENOTSUPP;
 
@@ -328,7 +335,7 @@
 }
 
 static dasd_era_t
-dasd_diag_examine_error(dasd_ccw_req_t * cqr, devstat_t * stat)
+dasd_diag_examine_error(dasd_ccw_req_t * cqr, struct irb * stat)
 {
 	return dasd_era_fatal;
 }
@@ -433,7 +440,8 @@
 }
 
 static void
-dasd_diag_dump_sense(dasd_device_t *device, dasd_ccw_req_t * req)
+dasd_diag_dump_sense(dasd_device_t *device, dasd_ccw_req_t * req,
+		     struct irb *stat)
 {
 	char *page;
 
@@ -443,8 +451,8 @@
 		return;
 	}
 	sprintf(page, KERN_WARNING PRINTK_HEADER
-		"device %04X on irq %d: I/O status report:\n",
-		device->devinfo.devno, device->devinfo.irq);
+		"device %s: I/O status report:\n",
+		device->cdev->dev.bus_id);
 
 	MESSAGE(KERN_ERR, "Sense data:\n%s", page);
 
@@ -463,7 +471,7 @@
  * start the next request if one finishes off. That makes 252.75 blocks
  * for one request. Give a little safety and the result is 240.
  */
-static dasd_discipline_t dasd_diag_discipline = {
+dasd_discipline_t dasd_diag_discipline = {
 	.owner = THIS_MODULE,
 	.name = "DIAG",
 	.ebcname = "DIAG",
@@ -479,7 +487,7 @@
 	.fill_info = dasd_diag_fill_info,
 };
 
-int
+static int __init
 dasd_diag_init(void)
 {
 	if (!MACHINE_IS_VM) {
@@ -489,13 +497,13 @@
 		return -EINVAL;
 	}
 	ASCEBC(dasd_diag_discipline.ebcname, 4);
+
 	ctl_set_bit(0, 9);
 	register_external_interrupt(0x2603, dasd_ext_handler);
-	dasd_discipline_add(&dasd_diag_discipline);
 	return 0;
 }
 
-void
+static void __exit
 dasd_diag_cleanup(void)
 {
 	if (!MACHINE_IS_VM) {
@@ -504,24 +512,12 @@
 			dasd_diag_discipline.name);
 		return;
 	}
-	dasd_discipline_del(&dasd_diag_discipline);
 	unregister_external_interrupt(0x2603, dasd_ext_handler);
 	ctl_clear_bit(0, 9);
 }
 
-#ifdef MODULE
-int
-init_module(void)
-{
-	return dasd_diag_init();
-}
-
-void
-cleanup_module(void)
-{
-	dasd_diag_cleanup();
-}
-#endif
+module_init(dasd_diag_init);
+module_exit(dasd_diag_cleanup);
 
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
diff -Nru a/drivers/s390/block/dasd_diag.h b/drivers/s390/block/dasd_diag.h
--- a/drivers/s390/block/dasd_diag.h	Mon Dec  9 18:46:36 2002
+++ b/drivers/s390/block/dasd_diag.h	Mon Dec  9 18:46:36 2002
@@ -5,6 +5,11 @@
  * ...............: by Hartmunt Penner <hpenner@de.ibm.com>
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
+ *
+ * $Revision: 1.4 $
+ *
+ * History of changes
+ *
  */
 
 #define MDSK_WRITE_REQ 0x01
@@ -70,5 +75,3 @@
 
     diag_rw_io_t;
 
-int dasd_diag_init(void);
-void dasd_diag_cleanup(void);
diff -Nru a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
--- a/drivers/s390/block/dasd_eckd.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/s390/block/dasd_eckd.c	Mon Dec  9 18:46:34 2002
@@ -7,6 +7,8 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
+ * $Revision: 1.35 $
+ *
  * History of changes (starts July 2000)
  * 07/11/00 Enabled rotational position sensing
  * 07/14/00 Reorganized the format process for better ERP
@@ -30,15 +32,16 @@
 #include <linux/slab.h>
 #include <linux/hdreg.h>	/* HDIO_GETGEO			    */
 #include <linux/bio.h>
+#include <linux/module.h>
+#include <linux/init.h>
 
 #include <asm/debug.h>
 #include <asm/idals.h>
 #include <asm/ebcdic.h>
 #include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/s390dyn.h>
 #include <asm/todclk.h>
 #include <asm/uaccess.h>
+#include <asm/ccwdev.h>
 
 #include "dasd_int.h"
 #include "dasd_eckd.h"
@@ -59,6 +62,8 @@
 #define ECKD_F7(i) (i->factor7)
 #define ECKD_F8(i) (i->factor8)
 
+MODULE_LICENSE("GPL");
+
 static dasd_discipline_t dasd_eckd_discipline;
 
 typedef struct dasd_eckd_private_t {
@@ -70,29 +75,44 @@
 	attrib_data_t attrib;	/* e.g. cache operations */
 } dasd_eckd_private_t;
 
-static
-devreg_t dasd_eckd_known_devices[] = {
-	{
-		.ci = { .hc = { .ctype = 0x3880, .dtype = 3390 } },
-		.flag = (DEVREG_MATCH_CU_TYPE | DEVREG_MATCH_DEV_TYPE |
-		      DEVREG_TYPE_DEVCHARS),
-		.oper_func = dasd_oper_handler
-	},
-	{
-		.ci = { .hc = { .ctype = 0x3990 } },
-		.flag = (DEVREG_MATCH_CU_TYPE | DEVREG_TYPE_DEVCHARS),
-		.oper_func = dasd_oper_handler
-	},
-	{
-		.ci = { .hc = { .ctype = 0x2105 } },
-		.flag = (DEVREG_MATCH_CU_TYPE | DEVREG_TYPE_DEVCHARS),
-		.oper_func = dasd_oper_handler
-	},
-	{
-		.ci = { .hc = { .ctype = 0x9343 } },
-		.flag = (DEVREG_MATCH_CU_TYPE | DEVREG_TYPE_DEVCHARS),
-		.oper_func = dasd_oper_handler
-	}
+/* The ccw bus type uses this table to find devices that it sends to
+ * dasd_eckd_probe */
+static struct ccw_device_id dasd_eckd_ids[] = {
+	{ CCW_DEVICE_DEVTYPE (0x3990, 0, 0x3390, 0), driver_info: 0x1},
+	{ CCW_DEVICE_DEVTYPE (0x2105, 0, 0x3390, 0), driver_info: 0x2},
+	{ CCW_DEVICE_DEVTYPE (0x3880, 0, 0x3390, 0), driver_info: 0x3},
+	{ CCW_DEVICE_DEVTYPE (0x3990, 0, 0x3380, 0), driver_info: 0x4},
+	{ CCW_DEVICE_DEVTYPE (0x2105, 0, 0x3380, 0), driver_info: 0x5},
+	{ CCW_DEVICE_DEVTYPE (0x9343, 0, 0x9345, 0), driver_info: 0x6},
+	{ /* end of list */ },
+};
+
+MODULE_DEVICE_TABLE(ccw, dasd_eckd_ids);
+
+static struct ccw_driver dasd_eckd_driver; /* see below */
+
+/* initial attempt at a probe function. this can be simplified once
+ * the other detection code is gone */
+static int
+dasd_eckd_probe (struct ccw_device *cdev)
+{
+	return dasd_generic_probe (cdev, &dasd_eckd_discipline);
+}
+
+static int
+dasd_eckd_set_online(struct ccw_device *cdev)
+{
+	return dasd_generic_set_online (cdev, &dasd_eckd_discipline);
+}
+
+static struct ccw_driver dasd_eckd_driver = {
+	.name        = "dasd-eckd",
+	.owner       = THIS_MODULE,
+	.ids         = dasd_eckd_ids,
+	.probe       = dasd_eckd_probe,
+	.remove      = dasd_generic_remove,
+	.set_offline = dasd_generic_set_offline,
+	.set_online  = dasd_eckd_set_online,
 };
 
 static const int sizes_trk0[] = { 28, 148, 84 };
@@ -183,7 +203,32 @@
 }
 
 static inline void
-define_extent(ccw1_t * ccw, DE_eckd_data_t * data, int trk, int totrk,
+check_XRC (struct ccw1         *de_ccw,
+           DE_eckd_data_t *data,
+           dasd_device_t  *device)
+{
+        dasd_eckd_private_t *private;
+
+        private = (dasd_eckd_private_t *) device->private;
+
+        /* switch on System Time Stamp - needed for XRC Support */
+        if (private->rdc_data.facilities.XRC_supported) {
+                
+                data->ga_extended |= 0x08;   /* switch on 'Time Stamp Valid'   */
+                data->ga_extended |= 0x02;   /* switch on 'Extended Parameter' */
+                
+                data->ep_sys_time = get_clock ();
+                
+                de_ccw->count = sizeof (DE_eckd_data_t);
+                de_ccw->flags = CCW_FLAG_SLI;  
+        }
+
+        return;
+
+} /* end check_XRC */
+
+static inline void
+define_extent(struct ccw1 * ccw, DE_eckd_data_t * data, int trk, int totrk,
 	      int cmd, dasd_device_t * device)
 {
 	dasd_eckd_private_t *private;
@@ -216,10 +261,12 @@
 	case DASD_ECKD_CCW_WRITE_KD_MT:
 		data->mask.perm = 0x02;
 		data->attributes.operation = private->attrib.operation;
+                check_XRC (ccw, data, device);
 		break;
 	case DASD_ECKD_CCW_WRITE_CKD:
 	case DASD_ECKD_CCW_WRITE_CKD_MT:
 		data->attributes.operation = DASD_BYPASS_CACHE;
+                check_XRC (ccw, data, device);
 		break;
 	case DASD_ECKD_CCW_ERASE:
 	case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
@@ -227,6 +274,7 @@
 		data->mask.perm = 0x3;
 		data->mask.auth = 0x1;
 		data->attributes.operation = DASD_BYPASS_CACHE;
+                check_XRC (ccw, data, device);
 		break;
 	default:
 		MESSAGE(KERN_ERR, "unknown opcode 0x%x", cmd);
@@ -271,7 +319,7 @@
 }
 
 static inline void
-locate_record(ccw1_t *ccw, LO_eckd_data_t *data, int trk,
+locate_record(struct ccw1 *ccw, LO_eckd_data_t *data, int trk,
 	      int rec_on_trk, int no_rec, int cmd,
 	      dasd_device_t * device, int reclen)
 {
@@ -407,24 +455,7 @@
 	return LABEL_SIZE;
 }
 
-static inline int
-dasd_eckd_id_check(s390_dev_info_t * info)
-{
-	if (info->sid_data.cu_type == 0x3990 ||
-	    info->sid_data.cu_type == 0x2105)
-		if (info->sid_data.dev_type == 0x3390)
-			return 0;
-	if (info->sid_data.cu_type == 0x3990 ||
-	    info->sid_data.cu_type == 0x2105)
-		if (info->sid_data.dev_type == 0x3380)
-			return 0;
-	if (info->sid_data.cu_type == 0x9343)
-		if (info->sid_data.dev_type == 0x9345)
-			return 0;
-	return -ENODEV;
-}
-
-static inline int
+static int
 dasd_eckd_check_characteristics(dasd_device_t *device)
 {
 	dasd_eckd_private_t *private;
@@ -452,7 +483,7 @@
 
 	/* Read Device Characteristics */
 	rdc_data = (void *) &(private->rdc_data);
-	rc = read_dev_chars(device->devinfo.irq, &rdc_data, 64);
+	rc = read_dev_chars(device->cdev, &rdc_data, 64);
 	if (rc) {
 		MESSAGE(KERN_WARNING,
 			"Read device characteristics returned error %d", rc);
@@ -470,8 +501,7 @@
 		    private->rdc_data.sec_per_trk);
 
 	/* Read Configuration Data */
-	rc = read_conf_data(device->devinfo.irq,
-			    &conf_data, &conf_len, LPM_ANYPATH);
+	rc = read_conf_data(device->cdev, &conf_data, &conf_len);
 	if (rc && rc != -EOPNOTSUPP) {	/* -EOPNOTSUPP is ok */
 		MESSAGE(KERN_WARNING,
 			"Read configuration data returned error %d", rc);
@@ -497,17 +527,11 @@
 		    private->rdc_data.cu_type,
 		    private->rdc_data.cu_model.model);
 	return 0;
-}
-
-static int
-dasd_eckd_check_device(struct dasd_device_t *device)
-{
-	int rc;
 
-	rc = dasd_eckd_id_check(&device->devinfo);
-	if (rc)
-		return rc;
-	return dasd_eckd_check_characteristics(device);
+        /* get characteristis via diag to determine the kind of minidisk under VM */
+        /* needed beacause XRC is not support by VM (jet)                         */
+        /* Can be removed as soon as VM supports XRC                              */
+	// TBD ??? HUM
 }
 
 static dasd_ccw_req_t *
@@ -517,7 +541,7 @@
 	eckd_count_t *count_data;
 	LO_eckd_data_t *LO_data;
 	dasd_ccw_req_t *cqr;
-	ccw1_t *ccw;
+	struct ccw1 *ccw;
 	int cplength, datasize;
 	int i;
 
@@ -563,6 +587,7 @@
 
 	cqr->device = device;
 	cqr->retries = 0;
+	cqr->buildclk = get_clock();
 	cqr->status = DASD_CQR_FILLED;
 	return cqr;
 }
@@ -716,7 +741,7 @@
 	dasd_eckd_private_t *private;
 	dasd_ccw_req_t *fcp;
 	eckd_count_t *ect;
-	ccw1_t *ccw;
+	struct ccw1 *ccw;
 	void *data;
 	int rpt, cyl, head;
 	int cplength, datasize;
@@ -881,25 +906,28 @@
 	}
 	fcp->device = device;
 	fcp->retries = 2;	/* set retry counter to enable ERP */
+	fcp->buildclk = get_clock();
 	fcp->status = DASD_CQR_FILLED;
 	return fcp;
 }
 
 static dasd_era_t
-dasd_eckd_examine_error(dasd_ccw_req_t * cqr, devstat_t * stat)
+dasd_eckd_examine_error(dasd_ccw_req_t * cqr, struct irb * irb)
 {
 	dasd_device_t *device = (dasd_device_t *) cqr->device;
+	struct ccw_device *cdev = device->cdev;
 
-	if (stat->cstat == 0x00 &&
-	    stat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
+	if (irb->scsw.cstat == 0x00 &&
+	    irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
 		return dasd_era_none;
 
-	switch (device->devinfo.sid_data.cu_type) {
+	switch (cdev->id.cu_type) {
 	case 0x3990:
 	case 0x2105:
-		return dasd_3990_erp_examine(cqr, stat);
+		return dasd_3990_erp_examine(cqr, irb);
 	case 0x9343:
-		return dasd_9343_erp_examine(cqr, stat);
+		return dasd_9343_erp_examine(cqr, irb);
+	case 0x3880:
 	default:
 		MESSAGE(KERN_WARNING, "%s",
 			"default (unknown CU type) - RECOVERABLE return");
@@ -911,13 +939,15 @@
 dasd_eckd_erp_action(dasd_ccw_req_t * cqr)
 {
 	dasd_device_t *device = (dasd_device_t *) cqr->device;
+	struct ccw_device *cdev = device->cdev;
 
-	switch (device->devinfo.sid_data.cu_type) {
+	switch (cdev->id.cu_type) {
 	case 0x3990:
 	case 0x2105:
 		return dasd_3990_erp_action;
 	case 0x9343:
 		/* Return dasd_9343_erp_action; */
+	case 0x3880:
 	default:
 		return dasd_default_erp_action;
 	}
@@ -936,13 +966,15 @@
 	unsigned long *idaws;
 	LO_eckd_data_t *LO_data;
 	dasd_ccw_req_t *cqr;
-	ccw1_t *ccw;
+	struct ccw1 *ccw;
 	struct bio *bio;
 	struct bio_vec *bv;
 	char *dst;
 	unsigned int blksize, blk_per_trk, off;
 	int count, cidaw, cplength, datasize;
 	sector_t recid, first_rec, last_rec;
+	sector_t first_trk, last_trk;
+	unsigned int first_offs, last_offs;
 	unsigned char cmd, rcmd;
 	int i;
 
@@ -957,8 +989,10 @@
 	blksize = device->bp_block;
 	blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
 	/* Calculate record id of first and last block. */
-	first_rec = req->sector >> device->s2b_shift;
-	last_rec = (req->sector + req->nr_sectors - 1) >> device->s2b_shift;
+	first_rec = first_trk = req->sector >> device->s2b_shift;
+	first_offs = sector_div(first_trk, blk_per_trk);
+	last_rec = last_trk = (req->sector + req->nr_sectors - 1) >> device->s2b_shift;
+	last_offs = sector_div(last_trk, blk_per_trk);
 	/* Check struct bio and count the number of blocks for the request. */
 	count = 0;
 	cidaw = 0;
@@ -996,8 +1030,7 @@
 		return cqr;
 	ccw = cqr->cpaddr;
 	/* First ccw is define extent. */
-	define_extent(ccw++, cqr->data, first_rec / blk_per_trk, 
-		      last_rec / blk_per_trk, cmd, device);
+	define_extent(ccw++, cqr->data, first_trk, last_trk, cmd, device);
 	/* Build locate_record+read/write/ccws. */
 	idaws = (unsigned long *) (cqr->data + sizeof(DE_eckd_data_t));
 	LO_data = (LO_eckd_data_t *) (idaws + cidaw);
@@ -1005,13 +1038,14 @@
 	if (private->uses_cdl == 0 || recid > 2*blk_per_trk) {
 		/* Only standard blocks so there is just one locate record. */
 		ccw[-1].flags |= CCW_FLAG_CC;
-		locate_record(ccw++, LO_data++,
-			      recid / blk_per_trk, recid % blk_per_trk + 1,
+		locate_record(ccw++, LO_data++, first_trk, first_offs + 1,
 			      last_rec - recid + 1, cmd, device, blksize);
 	}
 	rq_for_each_bio(bio, req) bio_for_each_segment(bv, bio, i) {
 		dst = kmap(bv->bv_page) + bv->bv_offset;
 		for (off = 0; off < bv->bv_len; off += blksize) {
+			sector_t trkid = recid;
+			unsigned int recoffs = sector_div(trkid, blk_per_trk);
 			rcmd = cmd;
 			count = blksize;
 			/* Locate record for cdl special block ? */
@@ -1025,16 +1059,14 @@
 				}
 				ccw[-1].flags |= CCW_FLAG_CC;
 				locate_record(ccw++, LO_data++,
-					      recid / blk_per_trk,
-					      recid % blk_per_trk + 1,
+					      trkid, recoffs + 1,
 					      1, rcmd, device, count);
 			}
 			/* Locate record for standard blocks ? */
 			if (private->uses_cdl && recid == 2*blk_per_trk) {
 				ccw[-1].flags |= CCW_FLAG_CC;
 				locate_record(ccw++, LO_data++,
-					      recid / blk_per_trk,
-					      recid % blk_per_trk + 1,
+					      trkid, recoffs + 1,
 					      last_rec - recid + 1,
 					      cmd, device, count);
 			}
@@ -1094,37 +1126,34 @@
 static int
 dasd_eckd_release(struct block_device *bdev, int no, long args)
 {
-	dasd_devmap_t *devmap;
 	dasd_device_t *device;
 	dasd_ccw_req_t *cqr;
 	int rc;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
-	devmap = dasd_devmap_from_bdev(bdev);
-	device = (devmap != NULL) ?
-		dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-	if (IS_ERR(device))
-		return PTR_ERR(device);
+
+	device = bdev->bd_disk->private_data;
+	if (device == NULL)
+		return -ENODEV;
 
 	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
 				   1, 0, device);
 	if (cqr == NULL) {
 		MESSAGE(KERN_WARNING, "%s",
 			"No memory to allocate initialization request");
-		dasd_put_device(devmap);
 		return -ENOMEM;
 	}
 	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RELEASE;
 	cqr->device = device;
 	cqr->retries = 0;
 	cqr->expires = 10 * HZ;
+	cqr->buildclk = get_clock();
 	cqr->status = DASD_CQR_FILLED;
 
 	rc = dasd_sleep_on_immediatly(cqr);
 
 	dasd_kfree_request(cqr, cqr->device);
-	dasd_put_device(devmap);
 	return rc;
 }
 
@@ -1137,18 +1166,16 @@
 static int
 dasd_eckd_reserve(struct block_device *bdev, int no, long args)
 {
-	dasd_devmap_t *devmap;
 	dasd_device_t *device;
 	dasd_ccw_req_t *cqr;
 	int rc;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
-	devmap = dasd_devmap_from_bdev(bdev);
-	device = (devmap != NULL) ?
-		dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-	if (IS_ERR(device))
-		return PTR_ERR(device);
+
+	device = bdev->bd_disk->private_data;
+	if (device == NULL)
+		return -ENODEV;
 
 	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
 				   1, 0, device);
@@ -1156,13 +1183,13 @@
 	if (cqr == NULL) {
 		MESSAGE(KERN_WARNING, "%s",
 			"No memory to allocate initialization request");
-		dasd_put_device(devmap);
 		return -ENOMEM;
 	}
 	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RESERVE;
 	cqr->device = device;
 	cqr->retries = 0;
 	cqr->expires = 10 * HZ;
+	cqr->buildclk = get_clock();
 	cqr->status = DASD_CQR_FILLED;
 
 	rc = dasd_sleep_on_immediatly(cqr);
@@ -1172,7 +1199,6 @@
 		dasd_eckd_release(bdev, no, args);
 	}
 	dasd_kfree_request(cqr, cqr->device);
-	dasd_put_device(devmap);
 	return rc;
 }
 
@@ -1184,31 +1210,29 @@
 static int
 dasd_eckd_steal_lock(struct block_device *bdev, int no, long args)
 {
-	dasd_devmap_t *devmap;
 	dasd_device_t *device;
 	dasd_ccw_req_t *cqr;
 	int rc;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
-	devmap = dasd_devmap_from_bdev(bdev);
-	device = (devmap != NULL) ?
-		dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-	if (IS_ERR(device))
-		return PTR_ERR(device);
+
+	device = bdev->bd_disk->private_data;
+	if (device == NULL)
+		return -ENODEV;
 
 	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
 				   1, 0, device);
 	if (cqr == NULL) {
 		MESSAGE(KERN_WARNING, "%s",
 			"No memory to allocate initialization request");
-		dasd_put_device(devmap);
 		return -ENOMEM;
 	}
 	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SLCK;
 	cqr->device = device;
 	cqr->retries = 0;
 	cqr->expires = 10 * HZ;
+	cqr->buildclk = get_clock();
 	cqr->status = DASD_CQR_FILLED;
 
 	rc = dasd_sleep_on_immediatly(cqr);
@@ -1218,7 +1242,6 @@
 		dasd_eckd_release(bdev, no, args);
 	}
 	dasd_kfree_request(cqr, cqr->device);
-	dasd_put_device(devmap);
 	return rc;
 }
 
@@ -1228,19 +1251,16 @@
 static int
 dasd_eckd_performance(struct block_device *bdev, int no, long args)
 {
-	dasd_devmap_t *devmap;
 	dasd_device_t *device;
 	dasd_psf_prssd_data_t *prssdp;
 	dasd_rssd_perf_stats_t *stats;
 	dasd_ccw_req_t *cqr;
-	ccw1_t *ccw;
+	struct ccw1 *ccw;
 	int rc;
 
-	devmap = dasd_devmap_from_bdev(bdev);
-	device = (devmap != NULL) ?
-		dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-	if (IS_ERR(device))
-		return PTR_ERR(device);
+	device = bdev->bd_disk->private_data;
+	if (device == NULL)
+		return -ENODEV;
 
 	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
 				   1 /* PSF */  + 1 /* RSSD */ ,
@@ -1249,7 +1269,6 @@
 	if (cqr == NULL) {
 		MESSAGE(KERN_WARNING, "%s",
 			"No memory to allocate initialization request");
-		dasd_put_device(devmap);
 		return -ENOMEM;
 	}
 	cqr->device = device;
@@ -1277,6 +1296,7 @@
 	ccw->count = sizeof (dasd_rssd_perf_stats_t);
 	ccw->cda = (__u32)(addr_t) stats;
 
+	cqr->buildclk = get_clock();
 	cqr->status = DASD_CQR_FILLED;
 	rc = dasd_sleep_on(cqr);
 	if (rc == 0) {
@@ -1287,7 +1307,6 @@
 				  sizeof(dasd_rssd_perf_stats_t));
 	}
 	dasd_sfree_request(cqr, cqr->device);
-	dasd_put_device(devmap);
 	return rc;
 }
 
@@ -1298,7 +1317,6 @@
 static int
 dasd_eckd_set_attrib(struct block_device *bdev, int no, long args)
 {
-	dasd_devmap_t *devmap;
 	dasd_device_t *device;
 	dasd_eckd_private_t *private;
 	attrib_data_t attrib;
@@ -1308,14 +1326,11 @@
 	if (!args)
 		return -EINVAL;
 
-	devmap = dasd_devmap_from_bdev(bdev);
-	device = (devmap != NULL) ?
-		dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-	if (IS_ERR(device))
-		return PTR_ERR(device);
+	device = bdev->bd_disk->private_data;
+	if (device == NULL)
+		return -ENODEV;
 
 	if (copy_from_user(&attrib, (void *) args, sizeof (attrib_data_t))) {
-		dasd_put_device(devmap);
 		return -EFAULT;
 	}
 
@@ -1332,16 +1347,16 @@
 		      "cache operation mode set to "
 		      "%x (%i cylinder prestage)",
 		      private->attrib.operation, private->attrib.nr_cyl);
-	dasd_put_device(devmap);
 	return 0;
 }
 
 static void
-dasd_eckd_dump_sense(struct dasd_device_t *device, dasd_ccw_req_t * req)
+dasd_eckd_dump_sense(struct dasd_device_t *device, dasd_ccw_req_t * req,
+		     struct irb *irb)
 {
 
-	char *page, *sense;
-	ccw1_t *act;
+	char *page;
+	struct ccw1 *act;
 	int len, sl, sct;
 
 	page = (char *) get_zeroed_page(GFP_ATOMIC);
@@ -1350,14 +1365,14 @@
 		return;
 	}
 	len = sprintf(page, KERN_ERR PRINTK_HEADER
-		      "device %04X on irq %d: I/O status report:\n",
-		      device->devinfo.devno, device->devinfo.irq);
+		      "device %s: I/O status report:\n",
+		      device->cdev->dev.bus_id);
 	len += sprintf(page + len, KERN_ERR PRINTK_HEADER
 		       "in req: %p CS: 0x%02X DS: 0x%02X\n", req,
-		       device->dev_status.cstat, device->dev_status.dstat);
+		       irb->scsw.cstat, irb->scsw.dstat);
 	len += sprintf(page + len, KERN_ERR PRINTK_HEADER
 		       "Failing CCW: %p\n", 
-		       (void *) (addr_t) device->dev_status.cpa);
+		       (void *) (addr_t) irb->scsw.cpa);
 	act = req->cpaddr;
 	do {
 		DBF_EVENT(DBF_INFO,
@@ -1370,8 +1385,7 @@
 			  ((int *) (addr_t) act->cda)[2],
 			  ((int *) (addr_t) act->cda)[3]);
 	} while (act++->flags & (CCW_FLAG_CC | CCW_FLAG_DC));
-	sense = device->dev_status.ii.sense.data;
-	if (device->dev_status.flag & DEVSTAT_FLAG_SENSE_AVAIL) {
+	if (irb->esw.esw0.erw.cons) {
 		for (sl = 0; sl < 4; sl++) {
 			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
 				       "Sense(hex) %2d-%2d:",
@@ -1379,23 +1393,23 @@
 
 			for (sct = 0; sct < 8; sct++) {
 				len += sprintf(page + len, " %02x",
-					       sense[8 * sl + sct]);
+					       irb->ecw[8 * sl + sct]);
 			}
 			len += sprintf(page + len, "\n");
 		}
 
-		if (sense[27] & DASD_SENSE_BIT_0) {
+		if (irb->ecw[27] & DASD_SENSE_BIT_0) {
 			/* 24 Byte Sense Data */
 			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
 				       "24 Byte: %x MSG %x, %s MSGb to SYSOP\n",
-				       sense[7] >> 4, sense[7] & 0x0f,
-				       sense[1] & 0x10 ? "" : "no");
+				       irb->ecw[7] >> 4, irb->ecw[7] & 0x0f,
+				       irb->ecw[1] & 0x10 ? "" : "no");
 		} else {
 			/* 32 Byte Sense Data */
 			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
 				       "32 Byte: Format: %x "
 				       "Exception class %x\n",
-				       sense[6] & 0x0f, sense[22] >> 4);
+				       irb->ecw[6] & 0x0f, irb->ecw[22] >> 4);
 		}
 	}
 
@@ -1422,7 +1436,7 @@
 	.name = "ECKD",
 	.ebcname = "ECKD",
 	.max_blocks = 240,
-	.check_device = dasd_eckd_check_device,
+	.check_device = dasd_eckd_check_characteristics,
 	.do_analysis = dasd_eckd_do_analysis,
 	.fill_geometry = dasd_eckd_fill_geometry,
 	.start_IO = dasd_start_IO,
@@ -1436,12 +1450,9 @@
 	.fill_info = dasd_eckd_fill_info,
 };
 
-int
+static int __init
 dasd_eckd_init(void)
 {
-	int i;
-	printk("sizeof(dasd_ccw_req_t) = %li\n",
-	       sizeof(dasd_ccw_req_t));
 	dasd_ioctl_no_register(THIS_MODULE, BIODASDSATTR,
 			       dasd_eckd_set_attrib);
 	dasd_ioctl_no_register(THIS_MODULE, BIODASDPSRD,
@@ -1454,22 +1465,15 @@
 			       dasd_eckd_steal_lock);
 
 	ASCEBC(dasd_eckd_discipline.ebcname, 4);
-	dasd_discipline_add(&dasd_eckd_discipline);
 
-	for (i = 0; i < sizeof(dasd_eckd_known_devices)/sizeof(devreg_t); i++)
-			s390_device_register(&dasd_eckd_known_devices[i]);
+	ccw_driver_register(&dasd_eckd_driver);
 	return 0;
 }
 
-void
+static void __exit
 dasd_eckd_cleanup(void)
 {
-	int i;
-
-	for (i = 0; i < sizeof(dasd_eckd_known_devices)/sizeof(devreg_t); i++)
-		s390_device_unregister(&dasd_eckd_known_devices[i]);
-
-	dasd_discipline_del(&dasd_eckd_discipline);
+	ccw_driver_unregister(&dasd_eckd_driver);
 
 	dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSATTR,
 				 dasd_eckd_set_attrib);
@@ -1483,19 +1487,8 @@
 				 dasd_eckd_steal_lock);
 }
 
-#ifdef MODULE
-int
-init_module(void)
-{
-	return dasd_eckd_init();
-}
-
-void
-cleanup_module(void)
-{
-	dasd_eckd_cleanup();
-}
-#endif
+module_init(dasd_eckd_init);
+module_exit(dasd_eckd_cleanup);
 
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
diff -Nru a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h
--- a/drivers/s390/block/dasd_eckd.h	Mon Dec  9 18:46:36 2002
+++ b/drivers/s390/block/dasd_eckd.h	Mon Dec  9 18:46:36 2002
@@ -1,3 +1,16 @@
+/* 
+ * File...........: linux/drivers/s390/block/dasd_eckd.h
+ * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
+ *                  Horst Hummel <Horst.Hummel@de.ibm.com> 
+ * Bugreports.to..: <Linux390@de.ibm.com>
+ * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
+ *
+ * $Revision: 1.5 $
+ *
+ * History of changes 
+ * 
+ */
+
 #ifndef DASD_ECKD_H
 #define DASD_ECKD_H
 
@@ -102,6 +115,10 @@
 	__u8 ga_extended;	/* Global Attributes Extended	*/
 	ch_t beg_ext;
 	ch_t end_ext;
+	unsigned long long ep_sys_time; /* Extended Parameter - System Time Stamp */
+	__u8 ep_format;        /* Extended Parameter format byte       */
+	__u8 ep_prio;          /* Extended Parameter priority I/O byte */
+	__u8 ep_reserved[6];   /* Extended Parameter Reserved          */
 } __attribute__ ((packed)) DE_eckd_data_t;
 
 typedef struct LO_eckd_data_t {
@@ -141,7 +158,8 @@
 		unsigned char reserved2:4;
 		unsigned char reserved3:8;
 		unsigned char defect_wr:1;
-		unsigned char reserved4:2;
+		unsigned char XRC_supported:1; 
+		unsigned char reserved4:1;
 		unsigned char striping:1;
 		unsigned char reserved5:4;
 		unsigned char cfw:1;
@@ -322,6 +340,4 @@
 	unsigned char varies[9];
 } __attribute__ ((packed)) dasd_psf_prssd_data_t;
 
-int dasd_eckd_init(void);
-void dasd_eckd_cleanup(void);
 #endif				/* DASD_ECKD_H */
diff -Nru a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c
--- a/drivers/s390/block/dasd_erp.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/s390/block/dasd_erp.c	Mon Dec  9 18:46:35 2002
@@ -7,6 +7,9 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
  *
+ * $Revision: 1.6 $
+ *
+ * History of changes
  * 05/04/02 split from dasd.c, code restructuring.
  */
 
@@ -17,7 +20,6 @@
 
 #include <asm/debug.h>
 #include <asm/ebcdic.h>
-#include <asm/irq.h>
 #include <asm/uaccess.h>
 
 /* This is ugly... */
@@ -36,7 +38,7 @@
 
 	/* Sanity checks */
 	if ( magic == NULL || datasize > PAGE_SIZE ||
-	     (cplength*sizeof(ccw1_t)) > PAGE_SIZE)
+	     (cplength*sizeof(struct ccw1)) > PAGE_SIZE)
 		BUG();
 	debug_text_event ( dasd_debug_area, 1, "ALLC");
 	debug_text_event ( dasd_debug_area, 1, magic);
@@ -45,7 +47,7 @@
 
 	size = (sizeof(dasd_ccw_req_t) + 7L) & -8L;
 	if (cplength > 0)
-		size += cplength * sizeof(ccw1_t);
+		size += cplength * sizeof(struct ccw1);
 	if (datasize > 0)
 		size += datasize;
 	spin_lock_irqsave(&device->mem_lock, flags);
@@ -57,9 +59,9 @@
 	data = (char *) cqr + ((sizeof(dasd_ccw_req_t) + 7L) & -8L);
 	cqr->cpaddr = NULL;
 	if (cplength > 0) {
-		cqr->cpaddr = (ccw1_t *) data;
-		data += cplength*sizeof(ccw1_t);
-		memset(cqr->cpaddr, 0, cplength*sizeof(ccw1_t));
+		cqr->cpaddr = (struct ccw1 *) data;
+		data += cplength*sizeof(struct ccw1);
+		memset(cqr->cpaddr, 0, cplength*sizeof(struct ccw1));
 	}
 	cqr->data = NULL;
 	if (datasize > 0) {
@@ -201,18 +203,25 @@
 }
 
 void
-dasd_log_ccw(dasd_ccw_req_t * cqr, int caller, __u32 cpa)
+dasd_log_sense(dasd_ccw_req_t *cqr, struct irb *irb)
 {
 	dasd_device_t *device;
-	dasd_ccw_req_t *lcqr;
-	ccw1_t *ccw;
-	int cplength;
 
 	device = cqr->device;
 	/* dump sense data */
 	if (device->discipline && device->discipline->dump_sense)
-		device->discipline->dump_sense(device, cqr);
+		device->discipline->dump_sense(device, cqr, irb);
+}
 
+void
+dasd_log_ccw(dasd_ccw_req_t * cqr, int caller, __u32 cpa)
+{
+	dasd_device_t *device;
+	dasd_ccw_req_t *lcqr;
+	struct ccw1 *ccw;
+	int cplength;
+
+	device = cqr->device;
 	/* log the channel program */
 	for (lcqr = cqr; lcqr != NULL; lcqr = lcqr->refers) {
 		DEV_MESSAGE(KERN_ERR, device,
@@ -229,17 +238,17 @@
 			DEV_MESSAGE(KERN_ERR, device, "%s",
 				    "Start of channel program:");
 			hex_dump_memory(device, lcqr->cpaddr,
-					40*sizeof(ccw1_t));
+					40*sizeof(struct ccw1));
 
 			DEV_MESSAGE(KERN_ERR, device, "%s",
 				    "End of channel program:");
 			hex_dump_memory(device, lcqr->cpaddr + cplength - 10,
-					10*sizeof(ccw1_t));
+					10*sizeof(struct ccw1));
 		} else {	/* log the whole CP */
 			DEV_MESSAGE(KERN_ERR, device, "%s",
 				    "Channel program (complete):");
 			hex_dump_memory(device, lcqr->cpaddr,
-					cplength*sizeof(ccw1_t));
+					cplength*sizeof(struct ccw1));
 		}
 
 		if (lcqr != cqr)
@@ -258,7 +267,7 @@
 				    "Failed CCW (%p) (area):",
 				    (void *) (long) cpa);
 			hex_dump_memory(device, cqr->cpaddr - 10,
-					20*sizeof(ccw1_t));
+					20*sizeof(struct ccw1));
 		}
 	}
 
@@ -268,4 +277,5 @@
 EXPORT_SYMBOL(dasd_default_erp_postaction);
 EXPORT_SYMBOL(dasd_alloc_erp_request);
 EXPORT_SYMBOL(dasd_free_erp_request);
+EXPORT_SYMBOL(dasd_log_sense);
 EXPORT_SYMBOL(dasd_log_ccw);
diff -Nru a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
--- a/drivers/s390/block/dasd_fba.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/s390/block/dasd_fba.c	Mon Dec  9 18:46:50 2002
@@ -1,9 +1,12 @@
-
 /* 
  * File...........: linux/drivers/s390/block/dasd_fba.c
  * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
+ *
+ * $Revision: 1.25 $
+ *
+ * History of changes
  *	    fixed partition handling and HDIO_GETGEO
  * 2002/01/04 Created 2.4-2.5 compatibility mode
  * 05/04/02 code restructuring.
@@ -17,13 +20,14 @@
 #include <linux/slab.h>
 #include <linux/hdreg.h>	/* HDIO_GETGEO			    */
 #include <linux/bio.h>
+#include <linux/module.h>
+#include <linux/init.h>
 
 #include <asm/idals.h>
 #include <asm/ebcdic.h>
 #include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/s390dyn.h>
 #include <asm/todclk.h>
+#include <asm/ccwdev.h>
 
 #include "dasd_int.h"
 #include "dasd_fba.h"
@@ -38,30 +42,47 @@
 #define DASD_FBA_CCW_LOCATE 0x43
 #define DASD_FBA_CCW_DEFINE_EXTENT 0x63
 
+MODULE_LICENSE("GPL");
+
 static dasd_discipline_t dasd_fba_discipline;
 
 typedef struct dasd_fba_private_t {
 	dasd_fba_characteristics_t rdc_data;
 } dasd_fba_private_t;
 
-static
-devreg_t dasd_fba_known_devices[] = {
-	{
-		.ci = {.hc = {.ctype = 0x6310, .dtype = 0x9336}},
-		.flag = (DEVREG_MATCH_CU_TYPE |
-		      DEVREG_MATCH_DEV_TYPE | DEVREG_TYPE_DEVCHARS),
-		.oper_func = dasd_oper_handler
-	},
-	{
-		.ci = {.hc = {.ctype = 0x3880, .dtype = 0x3370}},
-		.flag = (DEVREG_MATCH_CU_TYPE |
-		      DEVREG_MATCH_DEV_TYPE | DEVREG_TYPE_DEVCHARS),
-		.oper_func = dasd_oper_handler
-	}
+static struct ccw_device_id dasd_fba_ids[] = {
+	{ CCW_DEVICE_DEVTYPE (0x6310, 0, 0x9336, 0), driver_info: 0x1},
+	{ CCW_DEVICE_DEVTYPE (0x3880, 0, 0x3370, 0), driver_info: 0x2},
+	{ /* end of list */ },
+};
+
+MODULE_DEVICE_TABLE(ccw, dasd_fba_ids);
+
+static struct ccw_driver dasd_fba_driver; /* see below */
+static int
+dasd_fba_probe(struct ccw_device *cdev)
+{
+	return  dasd_generic_probe (cdev, &dasd_fba_discipline);
+}
+
+static int
+dasd_fba_set_online(struct ccw_device *cdev)
+{
+	return dasd_generic_set_online (cdev, &dasd_fba_discipline);
+}
+
+static struct ccw_driver dasd_fba_driver = {
+	.name        = "dasd-fba",
+	.owner       = THIS_MODULE,
+	.ids         = dasd_fba_ids,
+	.probe       = dasd_fba_probe,
+	.remove      = dasd_generic_remove,
+	.set_offline = dasd_generic_set_offline,
+	.set_online  = dasd_fba_set_online,
 };
 
 static inline void
-define_extent(ccw1_t * ccw, DE_fba_data_t *data, int rw,
+define_extent(struct ccw1 * ccw, DE_fba_data_t *data, int rw,
 	      int blksize, int beg, int nr)
 {
 	ccw->cmd_code = DASD_FBA_CCW_DEFINE_EXTENT;
@@ -81,7 +102,7 @@
 }
 
 static inline void
-locate_record(ccw1_t * ccw, LO_fba_data_t *data, int rw,
+locate_record(struct ccw1 * ccw, LO_fba_data_t *data, int rw,
 	      int block_nr, int block_ct)
 {
 	ccw->cmd_code = DASD_FBA_CCW_LOCATE;
@@ -99,22 +120,11 @@
 	data->blk_ct = block_ct;
 }
 
-static inline int
-dasd_fba_id_check(s390_dev_info_t * info)
-{
-	if (info->sid_data.cu_type == 0x3880)
-		if (info->sid_data.dev_type == 0x3370)
-			return 0;
-	if (info->sid_data.cu_type == 0x6310)
-		if (info->sid_data.dev_type == 0x9336)
-			return 0;
-	return -ENODEV;
-}
-
-static inline int
+static int
 dasd_fba_check_characteristics(struct dasd_device_t *device)
 {
 	dasd_fba_private_t *private;
+	struct ccw_device *cdev = device->cdev;	
 	void *rdc_data;
 	int rc;
 
@@ -130,7 +140,7 @@
 	}
 	/* Read Device Characteristics */
 	rdc_data = (void *) &(private->rdc_data);
-	rc = read_dev_chars(device->devinfo.irq, &rdc_data, 32);
+	rc = read_dev_chars(device->cdev, &rdc_data, 32);
 	if (rc) {
 		MESSAGE(KERN_WARNING,
 			"Read device characteristics returned error %d", rc);
@@ -139,10 +149,10 @@
 
 	DEV_MESSAGE(KERN_INFO, device,
 		    "%04X/%02X(CU:%04X/%02X) %dMB at(%d B/blk)",
-		    device->devinfo.sid_data.dev_type,
-		    device->devinfo.sid_data.dev_model,
-		    device->devinfo.sid_data.cu_type,
-		    device->devinfo.sid_data.cu_model,
+		    cdev->id.dev_type,
+		    cdev->id.dev_model,
+		    cdev->id.cu_type,
+		    cdev->id.cu_model,
 		    ((private->rdc_data.blk_bdsa *
 		      (private->rdc_data.blk_size >> 9)) >> 11),
 		    private->rdc_data.blk_size);
@@ -150,17 +160,6 @@
 }
 
 static int
-dasd_fba_check_device(struct dasd_device_t *device)
-{
-	int rc;
-
-	rc = dasd_fba_id_check(&device->devinfo);
-	if (rc)
-		return rc;
-	return dasd_fba_check_characteristics(device);
-}
-
-static int
 dasd_fba_do_analysis(struct dasd_device_t *device)
 {
 	dasd_fba_private_t *private;
@@ -193,20 +192,22 @@
 }
 
 static dasd_era_t
-dasd_fba_examine_error(dasd_ccw_req_t * cqr, devstat_t * stat)
+dasd_fba_examine_error(dasd_ccw_req_t * cqr, struct irb * irb)
 {
 	dasd_device_t *device;
+	struct ccw_device *cdev;
 
 	device = (dasd_device_t *) cqr->device;
-	if (stat->cstat == 0x00 &&
-	    stat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
+	if (irb->scsw.cstat == 0x00 &&
+	    irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
 		return dasd_era_none;
-
-	switch (device->devinfo.sid_data.dev_model) {
+	
+	cdev = device->cdev;
+	switch (cdev->id.dev_model) {
 	case 0x3370:
-		return dasd_3370_erp_examine(cqr, stat);
+		return dasd_3370_erp_examine(cqr, irb);
 	case 0x9336:
-		return dasd_9336_erp_examine(cqr, stat);
+		return dasd_9336_erp_examine(cqr, irb);
 	default:
 		return dasd_era_recover;
 	}
@@ -236,7 +237,7 @@
 	unsigned long *idaws;
 	LO_fba_data_t *LO_data;
 	dasd_ccw_req_t *cqr;
-	ccw1_t *ccw;
+	struct ccw1 *ccw;
 	struct bio *bio;
 	struct bio_vec *bv;
 	char *dst;
@@ -359,7 +360,8 @@
 }
 
 static void
-dasd_fba_dump_sense(struct dasd_device_t *device, dasd_ccw_req_t * req)
+dasd_fba_dump_sense(struct dasd_device_t *device, dasd_ccw_req_t * req,
+		    struct irb *irb)
 {
 	char *page;
 
@@ -369,8 +371,8 @@
 		return;
 	}
 	sprintf(page, KERN_WARNING PRINTK_HEADER
-		"device %04X on irq %d: I/O status report:\n",
-		device->devinfo.devno, device->devinfo.irq);
+		"device %s: I/O status report:\n",
+		device->cdev->dev.bus_id);
 
 	MESSAGE(KERN_ERR, "Sense data:\n%s", page);
 
@@ -396,7 +398,7 @@
 	.name = "FBA ",
 	.ebcname = "FBA ",
 	.max_blocks = 96,
-	.check_device = dasd_fba_check_device,
+	.check_device = dasd_fba_check_characteristics,
 	.do_analysis = dasd_fba_do_analysis,
 	.fill_geometry = dasd_fba_fill_geometry,
 	.start_IO = dasd_start_IO,
@@ -409,41 +411,22 @@
 	.fill_info = dasd_fba_fill_info,
 };
 
-int
+static int __init
 dasd_fba_init(void)
 {
-	int i;
-
 	ASCEBC(dasd_fba_discipline.ebcname, 4);
-	dasd_discipline_add(&dasd_fba_discipline);
-	for (i = 0; i < sizeof(dasd_fba_known_devices) / sizeof(devreg_t); i++)
-		s390_device_register(&dasd_fba_known_devices[i]);
-	return 0;
-}
-
-void
-dasd_fba_cleanup(void)
-{
-	int i;
 
-	for (i = 0; i < sizeof(dasd_fba_known_devices) / sizeof(devreg_t); i++)
-		s390_device_unregister(&dasd_fba_known_devices[i]);
-	dasd_discipline_del(&dasd_fba_discipline);
+	return ccw_driver_register(&dasd_fba_driver);
 }
 
-#ifdef MODULE
-int
-init_module(void)
+static void __exit
+dasd_fba_cleanup(void)
 {
-	return dasd_fba_init();
+	ccw_driver_unregister(&dasd_fba_driver);
 }
 
-void
-cleanup_module(void)
-{
-	dasd_fba_cleanup();
-}
-#endif
+module_init(dasd_fba_init);
+module_exit(dasd_fba_cleanup);
 
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
diff -Nru a/drivers/s390/block/dasd_fba.h b/drivers/s390/block/dasd_fba.h
--- a/drivers/s390/block/dasd_fba.h	Mon Dec  9 18:46:52 2002
+++ b/drivers/s390/block/dasd_fba.h	Mon Dec  9 18:46:52 2002
@@ -1,3 +1,14 @@
+/* 
+ * File...........: linux/drivers/s390/block/dasd_fba.h
+ * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
+ * Bugreports.to..: <Linux390@de.ibm.com>
+ * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
+ *
+ * $Revision: 1.4 $
+ *
+ * History of changes 
+ * 
+ */
 
 #ifndef DASD_FBA_H
 #define DASD_FBA_H
@@ -71,6 +82,4 @@
 
     dasd_fba_characteristics_t;
 
-int dasd_fba_init(void);
-void dasd_fba_cleanup(void);
 #endif				/* DASD_FBA_H */
diff -Nru a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
--- a/drivers/s390/block/dasd_genhd.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/s390/block/dasd_genhd.c	Mon Dec  9 18:46:50 2002
@@ -1,5 +1,5 @@
 /*
- * File...........: linux/drivers/s390/block/dasd_ioctl.c
+ * File...........: linux/drivers/s390/block/dasd_genhd.c
  * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
  *		    Horst Hummel <Horst.Hummel@de.ibm.com>
  *		    Carsten Otte <Cotte@de.ibm.com>
@@ -9,6 +9,9 @@
  *
  * Dealing with devices registered to multiple major numbers.
  *
+ * $Revision: 1.23 $
+ *
+ * History of changes
  * 05/04/02 split from dasd.c, code restructuring.
  */
 
@@ -19,7 +22,6 @@
 #include <linux/blkpg.h>
 #include <linux/blk.h>
 
-#include <asm/irq.h>
 #include <asm/uaccess.h>
 
 /* This is ugly... */
@@ -72,7 +74,6 @@
 	/* Initialize major info structure. */
 	mi->major = new_major;
 
-	/* Setup block device pointers for the new major. */
 	/* Insert the new major info structure into dasd_major_info list. */
 	spin_lock(&dasd_major_lock);
 	list_add_tail(&mi->list, &dasd_major_info);
@@ -105,35 +106,6 @@
 }
 
 /*
- * This one is needed for naming 18000+ possible dasd devices.
- *   dasda - dasdz : 26 devices
- *   dasdaa - dasdzz : 676 devices, added up = 702
- *   dasdaaa - dasdzzz : 17576 devices, added up = 18278
- */
-int
-dasd_device_name(char *str, int index, int partition)
-{
-	int len;
-
-	if (partition > DASD_PARTN_MASK)
-		return -EINVAL;
-
-	len = sprintf(str, "dasd");
-	if (index > 25) {
-		if (index > 701)
-			len += sprintf(str + len, "%c",
-				       'a' + (((index - 702) / 676) % 26));
-		len += sprintf(str + len, "%c",
-			       'a' + (((index - 26) / 26) % 26));
-	}
-	len += sprintf(str + len, "%c", 'a' + (index % 26));
-
-	if (partition)
-		len += sprintf(str + len, "%d", partition);
-	return 0;
-}
-
-/*
  * Allocate gendisk structure for devindex.
  */
 struct gendisk *
@@ -164,7 +136,7 @@
 			return ERR_PTR(rc);
 		}
 	}
-
+	
 	gdp = alloc_disk(1 << DASD_PARTN_BITS);
 	if (!gdp)
 		return ERR_PTR(-ENOMEM);
@@ -196,7 +168,7 @@
 /*
  * Return devindex of first device using a specific major number.
  */
-int dasd_gendisk_major_index(int major)
+static int dasd_gendisk_major_index(int major)
 {
 	struct list_head *l;
 	struct major_info *mi;
diff -Nru a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
--- a/drivers/s390/block/dasd_int.h	Mon Dec  9 18:46:50 2002
+++ b/drivers/s390/block/dasd_int.h	Mon Dec  9 18:46:50 2002
@@ -1,10 +1,13 @@
 /* 
- * File...........: linux/drivers/s390/block/dasd.c
+ * File...........: linux/drivers/s390/block/dasd_int.h
  * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
+ *                  Horst Hummel <Horst.Hummel@de.ibm.com> 
  *		    Martin Schwidefsky <schwidefsky@de.ibm.com>
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
+ * $Revision: 1.36 $
+ *
  * History of changes (starts July 2000)
  * 02/01/01 added dynamic registration of ioctls
  * 2002/01/04 Created 2.4-2.5 compatibility mode
@@ -58,12 +61,11 @@
 #include <linux/genhd.h>
 #include <linux/hdreg.h>
 #include <linux/interrupt.h>
+#include <asm/ccwdev.h>
 #include <linux/workqueue.h>
 #include <asm/debug.h>
 #include <asm/dasd.h>
 #include <asm/idals.h>
-#include <asm/irq.h>
-#include <asm/s390dyn.h>
 
 /*
  * SECTION: Type definitions
@@ -140,10 +142,9 @@
 /* messages to be written via klogd and dbf */
 #define DEV_MESSAGE(d_loglevel,d_device,d_string,d_args...)\
 do { \
-	printk(d_loglevel PRINTK_HEADER " %s,%04x@%02x: " \
+	printk(d_loglevel PRINTK_HEADER " %s,%s: " \
 	       d_string "\n", d_device->gdp->disk_name, \
-	       d_device->devinfo.devno, d_device->devinfo.irq, \
-	       d_args); \
+	       d_device->cdev->dev.bus_id, d_args); \
 	DBF_DEV_EVENT(DBF_ALERT, d_device, d_string, d_args); \
 } while(0)
 
@@ -159,18 +160,17 @@
 
 	/* Where to execute what... */
 	struct dasd_device_t *device;	/* device the request is for */
-	ccw1_t *cpaddr;			/* address of channel program */
+	struct ccw1 *cpaddr;		/* address of channel program */
 	char status;	        	/* status of this request */
 	short retries;			/* A retry counter */
 
 	/* ... and how */
-	int options;			/* options for execution */
 	int expires;			/* expiration period in jiffies */
 	char lpm;               	/* logical path mask */
 	void *data;			/* pointer to data area */
 
 	/* these are important for recovering erroneous requests          */
-	devstat_t *dstat;		/* device status in case of an error */
+	struct irb *dstat;		/* device status in case of an error */
 	struct dasd_ccw_req_t *refers;	/* ERP-chain queueing. */
 	void *function; 		/* originating ERP action */
 
@@ -247,16 +247,24 @@
          * is called for every error condition to print the sense data
          * to the console.
          */
-	dasd_era_t(*examine_error) (dasd_ccw_req_t *, devstat_t *);
+	dasd_era_t(*examine_error) (dasd_ccw_req_t *, struct irb *);
 	dasd_erp_fn_t(*erp_action) (dasd_ccw_req_t *);
 	dasd_erp_fn_t(*erp_postaction) (dasd_ccw_req_t *);
-	void (*dump_sense) (struct dasd_device_t *, dasd_ccw_req_t *);
+	void (*dump_sense) (struct dasd_device_t *, dasd_ccw_req_t *,
+			    struct irb *);
 
         /* i/o control functions. */
 	int (*fill_geometry) (struct dasd_device_t *, struct hd_geometry *);
 	int (*fill_info) (struct dasd_device_t *, dasd_information2_t *);
 } dasd_discipline_t;
 
+extern dasd_discipline_t dasd_diag_discipline;
+#ifdef CONFIG_DASD_DIAG
+#define dasd_diag_discipline_pointer (&dasd_diag_discipline)
+#else
+#define dasd_diag_discipline_pointer (0)
+#endif
+
 typedef struct dasd_device_t {
 	/* Block device stuff. */
 	struct gendisk *gdp;
@@ -267,6 +275,8 @@
 	unsigned int bp_block;		/* bytes per block */
 	unsigned int s2b_shift;		/* log2 (bp_block/512) */
 	int ro_flag;			/* read-only flag */
+	int use_diag_flag;		/* diag allowed flag */
+
 
 	/* Device discipline stuff. */
 	dasd_discipline_t *discipline;
@@ -288,8 +298,8 @@
 	struct list_head erp_chunks;
 
 	/* Common i/o stuff. */
-	s390_dev_info_t devinfo;
-	devstat_t dev_status;
+	/* FIXME: remove the next */
+	int devno;
 
 	atomic_t tasklet_scheduled;
         struct tasklet_struct tasklet;
@@ -297,6 +307,9 @@
 	struct timer_list timer;
 
 	debug_info_t *debug_area;
+
+	struct ccw_device *cdev;
+
 #ifdef CONFIG_DASD_PROFILE
 	dasd_profile_info_t profile;
 #endif
@@ -318,7 +331,6 @@
         unsigned int devindex;
         unsigned short devno;
         unsigned short features;
-        devreg_t *devreg;
         dasd_device_t *device;
 } dasd_devmap_t;
 
@@ -427,17 +439,14 @@
 void dasd_sfree_request(dasd_ccw_req_t *, dasd_device_t *);
 
 static inline int
-dasd_kmalloc_set_cda(ccw1_t *ccw, void *cda, dasd_device_t *device)
+dasd_kmalloc_set_cda(struct ccw1 *ccw, void *cda, dasd_device_t *device)
 {
 	return set_normalized_cda(ccw, cda);
 }
 
 dasd_device_t *dasd_alloc_device(dasd_devmap_t *);
 void dasd_free_device(dasd_device_t *);
-void dasd_enable_devices(int, int);
-void dasd_disable_devices(int, int);
-void dasd_discipline_add(dasd_discipline_t *);
-void dasd_discipline_del(dasd_discipline_t *);
+void dasd_enable_device(dasd_device_t *);
 void dasd_set_target_state(dasd_device_t *, int);
 void dasd_kick_device(dasd_device_t *);
 
@@ -445,7 +454,6 @@
 void dasd_add_request_tail(dasd_ccw_req_t *); /* unused */
 int  dasd_start_IO(dasd_ccw_req_t *);
 int  dasd_term_IO(dasd_ccw_req_t *);
-int  dasd_oper_handler(int, devreg_t *);
 void dasd_schedule_bh(dasd_device_t *);
 int  dasd_sleep_on(dasd_ccw_req_t *);
 int  dasd_sleep_on_immediatly(dasd_ccw_req_t *);
@@ -453,6 +461,12 @@
 void dasd_set_timer(dasd_device_t *, int);
 void dasd_clear_timer(dasd_device_t *);
 int  dasd_cancel_req(dasd_ccw_req_t *); /* unused */
+int dasd_generic_probe (struct ccw_device *cdev, 
+			dasd_discipline_t *discipline);
+int dasd_generic_remove (struct ccw_device *cdev);
+int dasd_generic_set_online(struct ccw_device *cdev, 
+			    dasd_discipline_t *discipline);
+int dasd_generic_set_offline (struct ccw_device *cdev);
 
 /* externals in dasd_devmap.c */
 extern int dasd_max_devindex;
@@ -463,20 +477,15 @@
 void dasd_devmap_exit(void);
 dasd_devmap_t *dasd_devmap_from_devno(int);
 dasd_devmap_t *dasd_devmap_from_devindex(int);
-dasd_devmap_t *dasd_devmap_from_irq(int);
-dasd_devmap_t *dasd_devmap_from_bdev(struct block_device *bdev);
 dasd_device_t *dasd_get_device(dasd_devmap_t *);
 void dasd_put_device(dasd_devmap_t *);
 
-int dasd_devno(char *, char **);
-int dasd_feature_list(char *, char **);
 int dasd_parse(void);
 int dasd_add_range(int, int, int);
 
 /* externals in dasd_gendisk.c */
 int  dasd_gendisk_init(void);
 void dasd_gendisk_exit(void);
-int  dasd_gendisk_major_index(int);
 int  dasd_gendisk_index_major(int);
 struct gendisk *dasd_gendisk_alloc(int);
 void dasd_setup_partitions(dasd_device_t *);
@@ -498,22 +507,21 @@
 dasd_ccw_req_t *dasd_default_erp_postaction(dasd_ccw_req_t *);
 dasd_ccw_req_t *dasd_alloc_erp_request(char *, int, int, dasd_device_t *);
 void dasd_free_erp_request(dasd_ccw_req_t *, dasd_device_t *);
+void dasd_log_sense(dasd_ccw_req_t *, struct irb *);
 void dasd_log_ccw(dasd_ccw_req_t *, int, __u32);
 
 /* externals in dasd_3370_erp.c */
-dasd_era_t dasd_3370_erp_examine(dasd_ccw_req_t *, devstat_t *);
+dasd_era_t dasd_3370_erp_examine(dasd_ccw_req_t *, struct irb *);
 
 /* externals in dasd_3990_erp.c */
-dasd_era_t dasd_3990_erp_examine(dasd_ccw_req_t *, devstat_t *);
+dasd_era_t dasd_3990_erp_examine(dasd_ccw_req_t *, struct irb *);
 dasd_ccw_req_t *dasd_3990_erp_action(dasd_ccw_req_t *);
-dasd_ccw_req_t *dasd_2105_erp_action(dasd_ccw_req_t *);
-void dasd_3990_erp_restart_queue(unsigned long);
 
 /* externals in dasd_9336_erp.c */
-dasd_era_t dasd_9336_erp_examine(dasd_ccw_req_t *, devstat_t *);
+dasd_era_t dasd_9336_erp_examine(dasd_ccw_req_t *, struct irb *);
 
 /* externals in dasd_9336_erp.c */
-dasd_era_t dasd_9343_erp_examine(dasd_ccw_req_t *, devstat_t *);
+dasd_era_t dasd_9343_erp_examine(dasd_ccw_req_t *, struct irb *);
 dasd_ccw_req_t *dasd_9343_erp_action(dasd_ccw_req_t *);
 
 #endif				/* __KERNEL__ */
diff -Nru a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
--- a/drivers/s390/block/dasd_ioctl.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/s390/block/dasd_ioctl.c	Mon Dec  9 18:46:38 2002
@@ -19,7 +19,7 @@
 #include <linux/blkpg.h>
 #include <linux/blk.h>
 
-#include <asm/irq.h>
+#include <asm/ccwdev.h>
 #include <asm/uaccess.h>
 
 /* This is ugly... */
@@ -125,7 +125,7 @@
 	DBF_DEV_EVENT(DBF_INFO, device,
 		      "unknown ioctl 0x%08x=%s'0x%x'%d(%d) data %8lx", no,
 		      dir, _IOC_TYPE(no), _IOC_NR(no), _IOC_SIZE(no), data);
-	return -ENOTTY;
+	return -EINVAL;
 }
 
 static int
@@ -137,24 +137,20 @@
 
 /*
  * Enable device.
+ * FIXME: how can we get here if the device is not already enabled?
+ * 	-arnd
  */
 static int
 dasd_ioctl_enable(struct block_device *bdev, int no, long args)
 {
-	dasd_devmap_t *devmap;
 	dasd_device_t *device;
-	int devno;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
-	devmap = dasd_devmap_from_bdev(bdev);
-	device = (devmap != NULL) ?
-		dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-	if (IS_ERR(device))
-		return PTR_ERR(device);
-	devno = device->devinfo.devno;
-	dasd_enable_devices(devno, devno);
-	dasd_put_device(devmap);
+	device = bdev->bd_disk->private_data;
+	if (device == NULL)
+		return -ENODEV;
+	dasd_enable_device(device);
 	return 0;
 }
 
@@ -164,16 +160,13 @@
 static int
 dasd_ioctl_disable(struct block_device *bdev, int no, long args)
 {
-	dasd_devmap_t *devmap;
 	dasd_device_t *device;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
-	devmap = dasd_devmap_from_bdev(bdev);
-	device = (devmap != NULL) ?
-		dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-	if (IS_ERR(device))
-		return PTR_ERR(device);
+	device = bdev->bd_disk->private_data;
+	if (device == NULL)
+		return -ENODEV;
 	/*
 	 * Man this is sick. We don't do a real disable but only downgrade
 	 * the device to DASD_STATE_BASIC. The reason is that dasdfmt uses
@@ -183,7 +176,6 @@
 	 * device is DASD_STATE_BASIC that allows to do basic i/o.
 	 */
 	dasd_set_target_state(device, DASD_STATE_BASIC);
-	dasd_put_device(devmap);
 	return 0;
 }
 
@@ -238,35 +230,28 @@
 static int
 dasd_ioctl_format(struct block_device *bdev, int no, long args)
 {
-	dasd_devmap_t *devmap;
 	dasd_device_t *device;
 	format_data_t fdata;
-	int rc;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
 	if (!args)
 		return -EINVAL;
 	/* fdata == NULL is no longer a valid arg to dasd_format ! */
-	devmap = dasd_devmap_from_bdev(bdev);
-	device = (devmap != NULL) ?
-		dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-	if (IS_ERR(device))
-		return PTR_ERR(device);
+	device = bdev->bd_disk->private_data;
 
-	rc = 0;
-	if (devmap->features & DASD_FEATURE_READONLY)
-		rc = -EROFS;
-	else if (copy_from_user(&fdata, (void *) args, sizeof (format_data_t)))
-		rc = -EFAULT;
-	else if (bdev != bdev->bd_contains) {
+	if (device == NULL)
+		return -ENODEV;
+	if (device->ro_flag)
+		return -EROFS;
+	if (copy_from_user(&fdata, (void *) args, sizeof (format_data_t)))
+		return -EFAULT;
+	if (bdev != bdev->bd_contains) {
 		DEV_MESSAGE(KERN_WARNING, device, "%s",
 			    "Cannot low-level format a partition");
-		rc = -EINVAL;
-	} else
-		rc = dasd_format(device, &fdata);
-	dasd_put_device(devmap);
-	return rc;
+		return -EINVAL;
+	}
+	return dasd_format(device, &fdata);
 }
 
 #ifdef CONFIG_DASD_PROFILE
@@ -276,18 +261,16 @@
 static int
 dasd_ioctl_reset_profile(struct block_device *bdev, int no, long args)
 {
-	dasd_devmap_t *devmap;
 	dasd_device_t *device;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
-	devmap = dasd_devmap_from_bdev(bdev);
-	device = (devmap != NULL) ?
-		dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-	if (IS_ERR(device))
-		return PTR_ERR(device);
+
+	device = = bdev->bd_disk->private_data;
+	if (device == NULL)
+		return -ENODEV;
+
 	memset(&device->profile, 0, sizeof (dasd_profile_info_t));
-	dasd_put_device(devmap);
 	return 0;
 }
 
@@ -297,21 +280,16 @@
 static int
 dasd_ioctl_read_profile(struct block_device *bdev, int no, long args)
 {
-	dasd_devmap_t *devmap;
 	dasd_device_t *device;
-	int rc;
 
-	devmap = dasd_devmap_from_bdev(bdev);
-	device = (devmap != NULL) ?
-		dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-	if (IS_ERR(device))
-		return PTR_ERR(device);
-	rc = 0;
+	device = = bdev->bd_disk->private_data;
+	if (device == NULL)
+		return -ENODEV;
+
 	if (copy_to_user((long *) args, (long *) &device->profile,
 			 sizeof (dasd_profile_info_t)))
-		rc = -EFAULT;
-	dasd_put_device(devmap);
-	return rc;
+		return -EFAULT;
+	return 0;
 }
 #else
 static int
@@ -333,40 +311,37 @@
 static int
 dasd_ioctl_information(struct block_device *bdev, int no, long args)
 {
-	dasd_devmap_t *devmap;
 	dasd_device_t *device;
 	dasd_information2_t *dasd_info;
 	unsigned long flags;
 	int rc;
+	struct ccw_device *cdev;
+
+	device = bdev->bd_disk->private_data;
+	if (device == NULL)
+		return -ENODEV;
 
-	devmap = dasd_devmap_from_bdev(bdev);
-	device = (devmap != NULL) ?
-		dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-	if (IS_ERR(device))
-		return PTR_ERR(device);
-	if (!device->discipline->fill_info) {
-		dasd_put_device(devmap);
+	if (!device->discipline->fill_info)
 		return -EINVAL;
-	}
 
 	dasd_info = kmalloc(sizeof(dasd_information2_t), GFP_KERNEL);
-	if (dasd_info == NULL) {
-		dasd_put_device(devmap);
+	if (dasd_info == NULL)
 		return -ENOMEM;
-	}
+
 	rc = device->discipline->fill_info(device, dasd_info);
 	if (rc) {
-		dasd_put_device(devmap);
 		kfree(dasd_info);
 		return rc;
 	}
 
-	dasd_info->devno = device->devinfo.devno;
-	dasd_info->schid = device->devinfo.irq;
-	dasd_info->cu_type = device->devinfo.sid_data.cu_type;
-	dasd_info->cu_model = device->devinfo.sid_data.cu_model;
-	dasd_info->dev_type = device->devinfo.sid_data.dev_type;
-	dasd_info->dev_model = device->devinfo.sid_data.dev_model;
+	cdev = device->cdev;
+
+	dasd_info->devno = device->devno;
+	dasd_info->schid = _ccw_device_get_subchannel_number(device->cdev);
+	dasd_info->cu_type = cdev->id.cu_type;
+	dasd_info->cu_model = cdev->id.cu_model;
+	dasd_info->dev_type = cdev->id.dev_type;
+	dasd_info->dev_model = cdev->id.dev_model;
 	dasd_info->open_count = atomic_read(&device->open_count);
 	dasd_info->status = device->state;
 	
@@ -378,8 +353,9 @@
 	    (dasd_check_blocksize(device->bp_block)))
 		dasd_info->format = DASD_FORMAT_NONE;
 	
-	dasd_info->features = devmap->features;
-	
+	dasd_info->features |= device->ro_flag ? DASD_FEATURE_READONLY
+					       : DASD_FEATURE_DEFAULT;
+
 	if (device->discipline)
 		memcpy(dasd_info->type, device->discipline->name, 4);
 	else
@@ -397,10 +373,10 @@
 			spin_unlock_irqrestore(&device->lock, flags);
 		}
 #endif				/* DASD_EXTENDED_PROFILING */
-		spin_lock_irqsave(get_irq_lock(device->devinfo.irq), flags);
+		spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
 		list_for_each(l, &device->ccw_queue)
 			dasd_info->chanq_len++;
-		spin_unlock_irqrestore(get_irq_lock(device->devinfo.irq),
+		spin_unlock_irqrestore(get_ccwdev_lock(device->cdev),
 				       flags);
 	}
 	
@@ -410,7 +386,6 @@
 			  sizeof (dasd_information2_t) :
 			  sizeof (dasd_information_t))))
 		rc = -EFAULT;
-	dasd_put_device(devmap);
 	kfree(dasd_info);
 	return rc;
 }
@@ -421,9 +396,8 @@
 static int
 dasd_ioctl_set_ro(struct block_device *bdev, int no, long args)
 {
-	dasd_devmap_t *devmap;
 	dasd_device_t *device;
-	int intval, i;
+	int intval;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
@@ -432,18 +406,11 @@
 		return -EINVAL;
 	if (get_user(intval, (int *) args))
 		return -EFAULT;
-	devmap = dasd_devmap_from_bdev(bdev);
-	device = (devmap != NULL) ?
-		dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-	if (IS_ERR(device))
-		return PTR_ERR(device);
-	if (intval)
-		devmap->features |= DASD_FEATURE_READONLY;
-	else
-		devmap->features &= ~DASD_FEATURE_READONLY;
+	device =  bdev->bd_disk->private_data;
+	if (device == NULL)
+		return -ENODEV;
 	set_disk_ro(bdev->bd_disk, intval);
 	device->ro_flag = intval;
-	dasd_put_device(devmap);
 	return 0;
 }
 
@@ -454,27 +421,24 @@
 dasd_ioctl_getgeo(struct block_device *bdev, int no, long args)
 {
 	struct hd_geometry geo = { 0, };
-	dasd_devmap_t *devmap;
 	dasd_device_t *device;
-	int rc;
 
-	devmap = dasd_devmap_from_bdev(bdev);
-	device = (devmap != NULL) ?
-		dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-	if (IS_ERR(device))
-		return PTR_ERR(device);
-	rc = 0;
-	if (device != NULL && device->discipline != NULL &&
-	    device->discipline->fill_geometry != NULL) {
-		device->discipline->fill_geometry(device, &geo);
-		geo.start = get_start_sect(bdev);
-		if (copy_to_user((struct hd_geometry *) args, &geo,
-				 sizeof (struct hd_geometry)))
-			rc = -EFAULT;
-	} else
-		rc = -EINVAL;
-	dasd_put_device(devmap);
-	return rc;
+	device =  bdev->bd_disk->private_data;
+	if (device == NULL)
+		return -ENODEV;
+
+	if (device == NULL || device->discipline == NULL ||
+	    device->discipline->fill_geometry == NULL)
+		return -EINVAL;
+
+	geo = (struct hd_geometry) {};
+	device->discipline->fill_geometry(device, &geo);
+	geo.start = get_start_sect(bdev) >> device->s2b_shift;
+	if (copy_to_user((struct hd_geometry *) args, &geo,
+			 sizeof (struct hd_geometry)))
+		return -EFAULT;
+
+	return 0;
 }
 
 /*
diff -Nru a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
--- a/drivers/s390/block/dasd_proc.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/s390/block/dasd_proc.c	Mon Dec  9 18:46:35 2002
@@ -9,16 +9,19 @@
  *
  * /proc interface for the dasd driver.
  *
+ * $Revision: 1.17 $
+ *
+ * History of changes
  * 05/04/02 split from dasd.c, code restructuring.
  */
 
 #include <linux/config.h>
 #include <linux/version.h>
 #include <linux/ctype.h>
+#include <linux/seq_file.h>
 #include <linux/vmalloc.h>
 
 #include <asm/debug.h>
-#include <asm/irq.h>
 #include <asm/uaccess.h>
 
 /* This is ugly... */
@@ -26,47 +29,9 @@
 
 #include "dasd_int.h"
 
-typedef struct {
-	char *data;
-	int len;
-} tempinfo_t;
-
 static struct proc_dir_entry *dasd_proc_root_entry = NULL;
-static struct proc_dir_entry *dasd_devices_entry;
-static struct proc_dir_entry *dasd_statistics_entry;
-
-static ssize_t
-dasd_generic_read(struct file *file, char *user_buf, size_t user_len,
-		  loff_t * offset)
-{
-	loff_t len;
-	tempinfo_t *p_info = (tempinfo_t *) file->private_data;
-
-	if (*offset >= p_info->len)
-		return 0;	/* EOF */
-	len = p_info->len - *offset;
-	if (user_len < len)
-		len = user_len;
-	if (copy_to_user(user_buf, &(p_info->data[*offset]), len))
-		return -EFAULT;
-	(*offset) += len;
-	return len;		/* number of bytes "read" */
-}
-
-static int
-dasd_generic_close (struct inode *inode, struct file *file)
-{
-	tempinfo_t *info;
-
-	info = (tempinfo_t *) file->private_data;
-	file->private_data = NULL;
-	if (info) {
-		if (info->data)
-			vfree (info->data);
-		kfree (info);
-	}
-	return 0;
-}
+static struct proc_dir_entry *dasd_devices_entry = NULL;
+static struct proc_dir_entry *dasd_statistics_entry = NULL;
 
 static inline char *
 dasd_get_user_string(const char *user_buf, size_t user_len)
@@ -88,189 +53,121 @@
 	return buffer;
 }
 
-static ssize_t
-dasd_devices_write(struct file *file, const char *user_buf,
-		   size_t user_len, loff_t * offset)
-{
-	char *buffer, *str;
-	int add_or_set;
-	int from, to, features;
-
-	buffer = dasd_get_user_string(user_buf, user_len);
-	MESSAGE(KERN_INFO, "/proc/dasd/devices: '%s'", buffer);
-
-	/* Scan for "add " or "set ". */
-	for (str = buffer; isspace(*str); str++);
-	if (strncmp(str, "add", 3) == 0 && isspace(str[3]))
-		add_or_set = 0;
-	else if (strncmp(str, "set", 3) == 0 && isspace(str[3]))
-		add_or_set = 1;
-	else
-		goto out_error;
-	for (str = str + 4; isspace(*str); str++);
-
-	/* Scan for "device " and "range=" and ignore it. This is sick. */
-	if (strncmp(str, "device", 6) == 0 && isspace(str[6]))
-		for (str = str + 6; isspace(*str); str++);
-	if (strncmp(str, "range=", 6) == 0) 
-		for (str = str + 6; isspace(*str); str++);
-
-	/* Scan device number range and feature string. */
-	to = from = dasd_devno(str, &str);
-	if (*str == '-') {
-		str++;
-		to = dasd_devno(str, &str);
-	}
-	features = dasd_feature_list(str, &str);
-	/* Negative numbers in from/to/features indicate errors */
-	if (from < 0 || to < 0 || from > 65546 || to > 65536 || features < 0)
-		goto out_error;
-
-	if (add_or_set == 0) {
-		dasd_add_range(from, to, features);
-		dasd_enable_devices(from, to);
-	} else {
-		for (; isspace(*str); str++);
-		if (strcmp(str, "on") == 0)
-			dasd_enable_devices(from, to);
-		else if (strcmp(str, "off") == 0)
-			dasd_disable_devices(from, to);
-		else
-			goto out_error;
-	}
-	kfree(buffer);
-	return user_len;
-out_error:
-	MESSAGE(KERN_WARNING,
-		"/proc/dasd/devices: range parse error in '%s'",
-		buffer);
-	kfree(buffer);
-	return -EINVAL;
-}
-
-static inline int
-dasd_devices_print(dasd_devmap_t *devmap, char *str)
+static int
+dasd_devices_show(struct seq_file *m, void *v)
 {
+	dasd_devmap_t *devmap;
 	dasd_device_t *device;
 	char *substr;
-	int len;
 
-	device = dasd_get_device(devmap);
+	devmap = dasd_devmap_from_devindex((unsigned long) v - 1);
+	device = (devmap != NULL) ?
+		dasd_get_device(devmap) : ERR_PTR(-ENODEV);
 	if (IS_ERR(device))
 		return 0;
 	/* Print device number. */
-	len = sprintf(str, "%04x", devmap->devno);
+	seq_printf(m, "%04x", devmap->devno);
 	/* Print discipline string. */
 	if (device != NULL && device->discipline != NULL)
-		len += sprintf(str + len, "(%s)", device->discipline->name);
+		seq_printf(m, "(%s)", device->discipline->name);
 	else
-		len += sprintf(str + len, "(none)");
+		seq_printf(m, "(none)");
 	/* Print kdev. */
-	len += sprintf(str + len, " at (%3d:%3d)",
-		       device->gdp->major, device->gdp->first_minor);
+	seq_printf(m, " at (%3d:%3d)",
+		   device->gdp->major, device->gdp->first_minor);
 	/* Print device name. */
-	len += sprintf(str + len, " is %-7s", device->gdp->disk_name);
+	seq_printf(m, " is %-7s", device->gdp->disk_name);
 	/* Print devices features. */
-	substr = (devmap->features & DASD_FEATURE_READONLY) ? "(ro)" : " ";
-	len += sprintf(str + len, "%4s: ", substr);
+	substr = device->ro_flag ? "(ro)" : " ";
+	seq_printf(m, "%4s: ", substr);
 	/* Print device status information. */
-	if (device == NULL) {
-		len += sprintf(str + len, "unknown");
-		dasd_put_device(devmap);
-		return len;
-	}
-	switch (device->state) {
+	switch ((device != NULL) ? device->state : -1) {
+	case -1:
+		seq_printf(m, "unknown");
+		break;
 	case DASD_STATE_NEW:
-		len += sprintf(str + len, "new");
+		seq_printf(m, "new");
 		break;
 	case DASD_STATE_KNOWN:
-		len += sprintf(str + len, "detected");
+		seq_printf(m, "detected");
 		break;
 	case DASD_STATE_BASIC:
-		len += sprintf(str + len, "basic");
+		seq_printf(m, "basic");
 		break;
 	case DASD_STATE_ACCEPT:
-		len += sprintf(str + len, "accepted");
+		seq_printf(m, "accepted");
 		break;
 	case DASD_STATE_READY:
 	case DASD_STATE_ONLINE:
-		if (device->state < DASD_STATE_ONLINE)
-			len += sprintf(str + len, "fenced ");
-		else
-			len += sprintf(str + len, "active ");
+		seq_printf(m, "active ");
 		if (dasd_check_blocksize(device->bp_block))
-			len += sprintf(str + len, "n/f	 ");
+			seq_printf(m, "n/f	 ");
 		else
-			len += sprintf(str + len,
-				       "at blocksize: %d, %ld blocks, %ld MB",
-				       device->bp_block, device->blocks,
-				       ((device->bp_block >> 9) *
-					device->blocks) >> 11);
+			seq_printf(m,
+				   "at blocksize: %d, %ld blocks, %ld MB",
+				   device->bp_block, device->blocks,
+				   ((device->bp_block >> 9) *
+				    device->blocks) >> 11);
 		break;
 	default:
-		len += sprintf(str + len, "no stat");
+		seq_printf(m, "no stat");
 		break;
 	}
 	dasd_put_device(devmap);
-	return len;
+	if (dasd_probeonly)
+		seq_printf(m, "(probeonly)");
+	seq_printf(m, "\n");
+	return 0;
 }
 
-static int
-dasd_devices_open(struct inode *inode, struct file *file)
+static void *dasd_devices_start(struct seq_file *m, loff_t *pos)
 {
-	tempinfo_t *info;
-	int size, len;
-	int devindex;
-
-	info = (tempinfo_t *) kmalloc(sizeof (tempinfo_t), GFP_KERNEL);
-	if (info == NULL) {
-		MESSAGE(KERN_WARNING, "%s",
-			"No memory available for data (tempinfo)");
-		return -ENOMEM;
+	if (*pos >= dasd_max_devindex)
+		return NULL;
+	return (void *)((unsigned long) *pos + 1);
+}
 
-	}
+static void *dasd_devices_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	++*pos;
+	return dasd_devices_start(m, pos);
+}
 
-	size = dasd_max_devindex * 128;
-	info->data = (char *) vmalloc (size);
-	if (size && info->data == NULL) {
-		MESSAGE(KERN_WARNING, "%s",
-			"No memory available for data (info->data)");
-		kfree(info);
-		return -ENOMEM;
-	}
-	file->private_data = (void *) info;
+static void dasd_devices_stop(struct seq_file *m, void *v)
+{
+}
 
-	DBF_EVENT(DBF_NOTICE,
-		  "procfs-area: %p, size 0x%x allocated", info->data, size);
+static struct seq_operations dasd_devices_seq_ops = {
+	.start		= dasd_devices_start,
+	.next		= dasd_devices_next,
+	.stop		= dasd_devices_stop,
+	.show		= dasd_devices_show,
+};
 
-	len = 0;
-	for (devindex = 0; devindex < dasd_max_devindex; devindex++) {
-		dasd_devmap_t *devmap;
-
-		devmap = dasd_devmap_from_devindex(devindex);
-		len += dasd_devices_print(devmap, info->data + len);
-		if (dasd_probeonly)
-			len += sprintf(info->data + len, "(probeonly)");
-		len += sprintf(info->data + len, "\n");
-	}
-	info->len = len;
-	if (len > size) {
-		printk("len = %i, size = %i\n", len, size);
-		BUG();
-	}
-	return 0;
+static int dasd_devices_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &dasd_devices_seq_ops);
 }
 
 static struct file_operations dasd_devices_file_ops = {
-	.owner = THIS_MODULE,
-	.read = dasd_generic_read,		/* read */
-	.write = dasd_devices_write,	/* write */
-	.open = dasd_devices_open,		/* open */
-	.release = dasd_generic_close,	/* close */
+	.open		= dasd_devices_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release,
 };
 
-static struct inode_operations dasd_devices_inode_ops = {
-};
+static inline int
+dasd_calc_metrics(char *page, char **start, off_t off,
+		  int count, int *eof, int len)
+{
+	len = (len > off) ? len - off : 0;
+	if (len > count)
+		len = count;
+	if (len < count)
+		*eof = 1;
+	*start = page + off;
+	return len;
+}
 
 static inline char *
 dasd_statistics_array(char *str, int *array, int shift)
@@ -287,48 +184,28 @@
 }
 
 static int
-dasd_statistics_open(struct inode *inode, struct file *file)
+dasd_statistics_read(char *page, char **start, off_t off,
+		     int count, int *eof, void *data)
 {
-	tempinfo_t *info;
+	unsigned long len;
 #ifdef CONFIG_DASD_PROFILE
 	dasd_profile_info_t *prof;
 	char *str;
 	int shift;
-#endif
 
-	info = (tempinfo_t *) kmalloc(sizeof (tempinfo_t), GFP_KERNEL);
-	if (info == NULL) {
-		MESSAGE(KERN_WARNING, "%s",
-			"No memory available for data (tempinfo)");
-		return -ENOMEM;
-	}
-
-	file->private_data = (void *) info;
-	/* FIXME! determine space needed in a better way */
-	info->data = (char *) vmalloc (PAGE_SIZE);
-
-	if (info->data == NULL) {
-		MESSAGE(KERN_WARNING, "%s",
-			"No memory available for data (info->data)");
-		kfree(info);
-		file->private_data = NULL;
-		return -ENOMEM;
-	}
-#ifdef CONFIG_DASD_PROFILE
 	/* check for active profiling */
 	if (dasd_profile_level == DASD_PROFILE_OFF) {
-		info->len = sprintf(info->data,
-				    "Statistics are off - they might be "
+		len = sprintf(page, "Statistics are off - they might be "
 				    "switched on using 'echo set on > "
 				    "/proc/dasd/statistics'\n");
-		return 0;
+		return dasd_calc_metrics(page, start, off, count, eof, len);
 	}
 
 	prof = &dasd_global_profile;
 	/* prevent couter 'overflow' on output */
 	for (shift = 0; (prof->dasd_io_reqs >> shift) > 9999999; shift++);
 
-	str = info->data;
+	str = page;
 	str += sprintf(str, "%d dasd I/O requests\n", prof->dasd_io_reqs);
 	str += sprintf(str, "with %d sectors(512B each)\n",
 		       prof->dasd_io_sects);
@@ -358,22 +235,22 @@
 	str = dasd_statistics_array(str, prof->dasd_io_time3, shift);
 	str += sprintf(str, "# of req in chanq at enqueuing (1..32) \n");
 	str = dasd_statistics_array(str, prof->dasd_io_nr_req, shift);
-
-	info->len = str - info->data;
+	len = str - page;
 #else
-	info->len = sprintf(info->data,
-			    "Statistics are not activated in this kernel\n");
+	len = sprintf(page, "Statistics are not activated in this kernel\n");
 #endif
-	return 0;
+	return dasd_calc_metrics(page, start, off, count, eof, len);
 }
 
-static ssize_t
+static int
 dasd_statistics_write(struct file *file, const char *user_buf,
-		      size_t user_len, loff_t * offset)
+		      unsigned long user_len, void *data)
 {
 #ifdef CONFIG_DASD_PROFILE
 	char *buffer, *str;
 
+	if (user_len > 65536)
+		user_len = 65536;
 	buffer = dasd_get_user_string(user_buf, user_len);
 	MESSAGE(KERN_INFO, "/proc/dasd/statictics: '%s'", buffer);
 
@@ -415,31 +292,22 @@
 #endif				/* CONFIG_DASD_PROFILE */
 }
 
-static struct file_operations dasd_statistics_file_ops = {
-	.owner	= THIS_MODULE,
-	.read	= dasd_generic_read,	/* read */
-	.write	= dasd_statistics_write,	/* write */
-	.open	= dasd_statistics_open,	/* open */
-	.release = dasd_generic_close,	/* close */
-};
-
-static struct inode_operations dasd_statistics_inode_ops = {
-};
-
 int
 dasd_proc_init(void)
 {
 	dasd_proc_root_entry = proc_mkdir("dasd", &proc_root);
+	dasd_proc_root_entry->owner = THIS_MODULE;
 	dasd_devices_entry = create_proc_entry("devices",
 					       S_IFREG | S_IRUGO | S_IWUSR,
 					       dasd_proc_root_entry);
 	dasd_devices_entry->proc_fops = &dasd_devices_file_ops;
-	dasd_devices_entry->proc_iops = &dasd_devices_inode_ops;
+	dasd_devices_entry->owner = THIS_MODULE;
 	dasd_statistics_entry = create_proc_entry("statistics",
 						  S_IFREG | S_IRUGO | S_IWUSR,
 						  dasd_proc_root_entry);
-	dasd_statistics_entry->proc_fops = &dasd_statistics_file_ops;
-	dasd_statistics_entry->proc_iops = &dasd_statistics_inode_ops;
+	dasd_statistics_entry->read_proc = dasd_statistics_read;
+	dasd_statistics_entry->write_proc = dasd_statistics_write;
+	dasd_statistics_entry->owner = THIS_MODULE;
 	return 0;
 }
 
diff -Nru a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
--- a/drivers/s390/block/xpram.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/s390/block/xpram.c	Mon Dec  9 18:46:50 2002
@@ -65,7 +65,6 @@
 static struct gendisk *xpram_disks[XPRAM_MAX_DEVS];
 static unsigned long xpram_pages;
 static int xpram_devs;
-static devfs_handle_t xpram_devfs_handle;
 
 /*
  * Parameter parsing functions.
@@ -437,11 +436,7 @@
 		goto out;
 	}
 
-	xpram_devfs_handle = devfs_mk_dir (NULL, "slram", NULL);
-	devfs_register_series (xpram_devfs_handle, "%u", xpram_devs,
-			       DEVFS_FL_DEFAULT, XPRAM_MAJOR, 0,
-			       S_IFBLK | S_IRUSR | S_IWUSR,
-			       &xpram_devops, NULL);
+	devfs_mk_dir (NULL, "slram", NULL);
 
 	/*
 	 * Assign the other needed values: make request function, sizes and
@@ -456,6 +451,7 @@
 	offset = 0;
 	for (i = 0; i < xpram_devs; i++) {
 		struct gendisk *disk = xpram_disks[i];
+		char name[16];
 		xpram_devices[i].size = xpram_sizes[i] / 4;
 		xpram_devices[i].offset = offset;
 		offset += xpram_devices[i].size;
@@ -467,6 +463,11 @@
 		sprintf(disk->disk_name, "slram%d", i);
 		set_capacity(disk, xpram_sizes[i] << 1);
 		add_disk(disk);
+		sprintf(name, "slram/%d", i);
+		devfs_register(NULL, name, DEVFS_FL_DEFAULT,
+			       disk->major, disk->first_minor,
+			       S_IFBLK | S_IRUSR | S_IWUSR,
+			       disk->fops, NULL);
 	}
 
 	return 0;
@@ -485,9 +486,10 @@
 	for (i = 0; i < xpram_devs; i++) {
 		del_gendisk(xpram_disks[i]);
 		put_disk(xpram_disks[i]);
+		devfs_remove("slram/%d", i);
 	}
 	unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME);
-	devfs_unregister(xpram_devfs_handle);
+	devfs_remove("slram");
 	sys_device_unregister(&xpram_sys_device);
 }
 
diff -Nru a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile
--- a/drivers/s390/char/Makefile	Mon Dec  9 18:46:36 2002
+++ b/drivers/s390/char/Makefile	Mon Dec  9 18:46:36 2002
@@ -2,7 +2,7 @@
 # S/390 character devices
 #
 
-export-objs := sclp_rw.o tape_core.o tape_devmap.o tape_std.o
+export-objs := sclp.o tape_core.o tape_devmap.o tape_std.o
 
 tub3270-objs := tuball.o tubfs.o tubtty.o \
                      tubttyaid.o tubttybld.o tubttyscl.o \
@@ -10,8 +10,8 @@
 
 obj-y += ctrlchar.o
 obj-$(CONFIG_TN3215) += con3215.o
-obj-$(CONFIG_SCLP) += sclp.o
-obj-$(CONFIG_SCLP_TTY) += sclp_rw.o sclp_tty.o
+obj-$(CONFIG_SCLP) += sclp.o sclp_rw.o
+obj-$(CONFIG_SCLP_TTY) += sclp_tty.o
 obj-$(CONFIG_SCLP_CONSOLE) += sclp_con.o
 obj-$(CONFIG_SCLP_CPI) += sclp_cpi.o
 obj-$(CONFIG_TN3270) += tub3270.o
diff -Nru a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
--- a/drivers/s390/char/con3215.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/s390/char/con3215.c	Mon Dec  9 18:46:50 2002
@@ -8,10 +8,11 @@
  *
  *  Updated:
  *   Aug-2000: Added tab support
- *             Dan Morrison, IBM Corporation (dmorriso@cse.buffalo.edu)
+ *	       Dan Morrison, IBM Corporation (dmorriso@cse.buffalo.edu)
  */
 
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kdev_t.h>
 #include <linux/tty.h>
@@ -22,14 +23,14 @@
 
 #include <linux/slab.h>
 #include <linux/bootmem.h>
-#include <linux/devfs_fs_kernel.h>
 
+#include <asm/ccwdev.h>
+#include <asm/cio.h>
 #include <asm/io.h>
 #include <asm/ebcdic.h>
 #include <asm/uaccess.h>
 #include <asm/delay.h>
 #include <asm/cpcmd.h>
-#include <asm/irq.h>
 #include <asm/setup.h>
 
 #include "ctrlchar.h"
@@ -41,7 +42,7 @@
 #define RAW3215_MIN_SPACE   128	      /* minimum free space for wakeup */
 #define RAW3215_MIN_WRITE   1024      /* min. length for immediate output */
 #define RAW3215_MAX_BYTES   3968      /* max. bytes to write with one ssch */
-#define RAW3215_MAX_NEWLINE 50        /* max. lines to write with one ssch */
+#define RAW3215_MAX_NEWLINE 50	      /* max. lines to write with one ssch */
 #define RAW3215_NR_CCWS	    3
 #define RAW3215_TIMEOUT	    HZ/10     /* time for delayed output */
 
@@ -53,56 +54,58 @@
 #define RAW3215_CLOSING	    32	      /* set while in close process */
 #define RAW3215_TIMER_RUNS  64	      /* set if the output delay timer is on */
 #define RAW3215_FLUSHING    128	      /* set to flush buffer (no delay) */
-#define RAW3215_BH_PENDING  256       /* indication for bh scheduling */
 
-#define TAB_STOP_SIZE	    8         /* tab stop size */
-
-struct _raw3215_info;		      /* forward declaration ... */
+#define TAB_STOP_SIZE	    8	      /* tab stop size */
 
 /*
  * Request types for a 3215 device
  */
-typedef enum {
+enum raw3215_type {
 	RAW3215_FREE, RAW3215_READ, RAW3215_WRITE
-} raw3215_type;
+};
 
 /*
  * Request structure for a 3215 device
  */
-typedef struct _raw3215_req {
-	raw3215_type type;	      /* type of the request */
+struct raw3215_req {
+	enum raw3215_type type;	      /* type of the request */
 	int start, len;		      /* start index & len in output buffer */
-        int delayable;                /* indication to wait for more data */
+	int delayable;		      /* indication to wait for more data */
 	int residual;		      /* residual count for read request */
-	ccw1_t ccws[RAW3215_NR_CCWS]; /* space for the channel program */
-	struct _raw3215_info *info;   /* pointer to main structure */
-	struct _raw3215_req *next;    /* pointer to next request */
-} raw3215_req  __attribute__ ((aligned(8)));
-
-typedef struct _raw3215_info {
+	struct ccw1 ccws[RAW3215_NR_CCWS]; /* space for the channel program */
+	struct raw3215_info *info;    /* pointer to main structure */
+	struct raw3215_req *next;     /* pointer to next request */
+} __attribute__ ((aligned(8)));
+
+struct raw3215_info {
+	struct ccw_device *cdev;      /* device for tty driver */
+	spinlock_t *lock;	      /* pointer to irq lock */
 	int flags;		      /* state flags */
-	int irq;		      /* interrupt number to do_IO */
 	char *buffer;		      /* pointer to output buffer */
 	char *inbuf;		      /* pointer to input buffer */
 	int head;		      /* first free byte in output buffer */
 	int count;		      /* number of bytes in output buffer */
-        int written;                  /* number of bytes in write requests */
-	devstat_t devstat;	      /* device status structure for do_IO */
+	int written;		      /* number of bytes in write requests */
 	struct tty_struct *tty;	      /* pointer to tty structure if present */
 	struct tasklet_struct tasklet;
-	raw3215_req *queued_read;     /* pointer to queued read requests */
-	raw3215_req *queued_write;    /* pointer to queued write requests */
+	struct raw3215_req *queued_read; /* pointer to queued read requests */
+	struct raw3215_req *queued_write;/* pointer to queued write requests */
 	wait_queue_head_t empty_wait; /* wait queue for flushing */
 	struct timer_list timer;      /* timer for delayed output */
-	char *message;                /* pending message from raw3215_irq */
-	int msg_dstat;                /* dstat for pending message */
-	int msg_cstat;                /* cstat for pending message */
+	char *message;		      /* pending message from raw3215_irq */
+	int msg_dstat;		      /* dstat for pending message */
+	int msg_cstat;		      /* cstat for pending message */
 	int line_pos;		      /* position on the line (for tabs) */
-} raw3215_info;
+};
 
-static raw3215_info *raw3215[NR_3215];	/* array of 3215 devices structures */
-static raw3215_req *raw3215_freelist;	/* list of free request structures */
-static spinlock_t raw3215_freelist_lock;/* spinlock to protect free list */
+/* array of 3215 devices structures */
+static struct raw3215_info *raw3215[NR_3215];
+/* spinlock to protect the raw3215 array */
+static spinlock_t raw3215_device_lock = SPIN_LOCK_UNLOCKED;
+/* list of free request structures */
+static struct raw3215_req *raw3215_freelist;
+/* spinlock to protect free list */
+static spinlock_t raw3215_freelist_lock;
 
 static struct tty_driver tty3215_driver;
 static struct tty_struct *tty3215_table[NR_3215];
@@ -110,15 +113,12 @@
 static struct termios *tty3215_termios_locked[NR_3215];
 static int tty3215_refcount;
 
-#ifndef MIN
-#define MIN(a,b)	((a) < (b) ? (a) : (b))
-#endif
-
 /*
  * Get a request structure from the free list
  */
-extern inline raw3215_req *raw3215_alloc_req(void) {
-	raw3215_req *req;
+static inline struct raw3215_req *
+raw3215_alloc_req(void) {
+	struct raw3215_req *req;
 	unsigned long flags;
 
 	spin_lock_irqsave(&raw3215_freelist_lock, flags);
@@ -131,12 +131,13 @@
 /*
  * Put a request structure back to the free list
  */
-extern inline void raw3215_free_req(raw3215_req *req) {
+static inline void
+raw3215_free_req(struct raw3215_req *req) {
 	unsigned long flags;
 
-        if (req->type == RAW3215_FREE)
-                return;         /* don't free a free request */
-        req->type = RAW3215_FREE;
+	if (req->type == RAW3215_FREE)
+		return;		/* don't free a free request */
+	req->type = RAW3215_FREE;
 	spin_lock_irqsave(&raw3215_freelist_lock, flags);
 	req->next = raw3215_freelist;
 	raw3215_freelist = req;
@@ -149,10 +150,11 @@
  * because a 3215 terminal won't accept a new read before the old one is
  * completed.
  */
-static void raw3215_mk_read_req(raw3215_info *raw)
+static void
+raw3215_mk_read_req(struct raw3215_info *raw)
 {
-	raw3215_req *req;
-        ccw1_t *ccw;
+	struct raw3215_req *req;
+	struct ccw1 *ccw;
 
 	/* there can only be ONE read request at a time */
 	req = raw->queued_read;
@@ -161,14 +163,14 @@
 		req = raw3215_alloc_req();
 		req->type = RAW3215_READ;
 		req->info = raw;
-                raw->queued_read = req;
+		raw->queued_read = req;
 	}
 
-        ccw = req->ccws;
-        ccw->cmd_code = 0x0A; /* read inquiry */
-        ccw->flags = 0x20;    /* ignore incorrect length */
-        ccw->count = 160;
-        ccw->cda = (__u32) __pa(raw->inbuf);
+	ccw = req->ccws;
+	ccw->cmd_code = 0x0A; /* read inquiry */
+	ccw->flags = 0x20;    /* ignore incorrect length */
+	ccw->count = 160;
+	ccw->cda = (__u32) __pa(raw->inbuf);
 }
 
 /*
@@ -177,49 +179,50 @@
  * buffer to the 3215 device. If a queued write exists it is replaced by
  * the new, probably lengthened request.
  */
-static void raw3215_mk_write_req(raw3215_info *raw)
+static void
+raw3215_mk_write_req(struct raw3215_info *raw)
 {
-        raw3215_req *req;
-	ccw1_t *ccw;
+	struct raw3215_req *req;
+	struct ccw1 *ccw;
 	int len, count, ix, lines;
 
-        if (raw->count <= raw->written)
-                return;
-        /* check if there is a queued write request */
-        req = raw->queued_write;
-        if (req == NULL) {
-                /* no queued write request, use new req structure */
-                req = raw3215_alloc_req();
-                req->type = RAW3215_WRITE;
-                req->info = raw;
-                raw->queued_write = req;
-        } else {
-                raw->written -= req->len;
-        }
+	if (raw->count <= raw->written)
+		return;
+	/* check if there is a queued write request */
+	req = raw->queued_write;
+	if (req == NULL) {
+		/* no queued write request, use new req structure */
+		req = raw3215_alloc_req();
+		req->type = RAW3215_WRITE;
+		req->info = raw;
+		raw->queued_write = req;
+	} else {
+		raw->written -= req->len;
+	}
 
 	ccw = req->ccws;
-        req->start = (raw->head - raw->count + raw->written) &
-                     (RAW3215_BUFFER_SIZE - 1);
-        /*
-         * now we have to count newlines. We can at max accept
-         * RAW3215_MAX_NEWLINE newlines in a single ssch due to
-         * a restriction in VM
-         */
-        lines = 0;
-        ix = req->start;
-        while (lines < RAW3215_MAX_NEWLINE && ix != raw->head) {
-                if (raw->buffer[ix] == 0x15)
-                        lines++;
-                ix = (ix + 1) & (RAW3215_BUFFER_SIZE - 1);
-        }
+	req->start = (raw->head - raw->count + raw->written) &
+		     (RAW3215_BUFFER_SIZE - 1);
+	/*
+	 * now we have to count newlines. We can at max accept
+	 * RAW3215_MAX_NEWLINE newlines in a single ssch due to
+	 * a restriction in VM
+	 */
+	lines = 0;
+	ix = req->start;
+	while (lines < RAW3215_MAX_NEWLINE && ix != raw->head) {
+		if (raw->buffer[ix] == 0x15)
+			lines++;
+		ix = (ix + 1) & (RAW3215_BUFFER_SIZE - 1);
+	}
 	len = ((ix - 1 - req->start) & (RAW3215_BUFFER_SIZE - 1)) + 1;
-        if (len > RAW3215_MAX_BYTES)
-                len = RAW3215_MAX_BYTES;
-        req->len = len;
-        raw->written += len;
+	if (len > RAW3215_MAX_BYTES)
+		len = RAW3215_MAX_BYTES;
+	req->len = len;
+	raw->written += len;
 
-        /* set the indication if we should try to enlarge this request */
-        req->delayable = (ix == raw->head) && (len < RAW3215_MIN_WRITE);
+	/* set the indication if we should try to enlarge this request */
+	req->delayable = (ix == raw->head) && (len < RAW3215_MIN_WRITE);
 
 	ix = req->start;
 	while (len > 0) {
@@ -237,25 +240,26 @@
 		ix = (ix + count) & (RAW3215_BUFFER_SIZE - 1);
 		ccw++;
 	}
-        /*
-         * Add a NOP to the channel program. 3215 devices are purely
-         * emulated and its much better to avoid the channel end
-         * interrupt in this case.
-         */
-        if (ccw > req->ccws)
-                ccw[-1].flags |= 0x40; /* use command chaining */
-        ccw->cmd_code = 0x03; /* NOP */
-        ccw->flags = 0;
-        ccw->cda = 0;
-        ccw->count = 1;
+	/*
+	 * Add a NOP to the channel program. 3215 devices are purely
+	 * emulated and its much better to avoid the channel end
+	 * interrupt in this case.
+	 */
+	if (ccw > req->ccws)
+		ccw[-1].flags |= 0x40; /* use command chaining */
+	ccw->cmd_code = 0x03; /* NOP */
+	ccw->flags = 0;
+	ccw->cda = 0;
+	ccw->count = 1;
 }
 
 /*
  * Start a read or a write request
  */
-static void raw3215_start_io(raw3215_info *raw)
+static void
+raw3215_start_io(struct raw3215_info *raw)
 {
-	raw3215_req *req;
+	struct raw3215_req *req;
 	int res;
 
 	req = raw->queued_read;
@@ -263,20 +267,22 @@
 	    !(raw->flags & (RAW3215_WORKING | RAW3215_THROTTLED))) {
 		/* dequeue request */
 		raw->queued_read = NULL;
-		res = do_IO(raw->irq, req->ccws, (unsigned long) req, 0, 0);
+		res = ccw_device_start(raw->cdev, req->ccws,
+				       (unsigned long) req, 0, 0);
 		if (res != 0) {
 			/* do_IO failed, put request back to queue */
 			raw->queued_read = req;
 		} else {
 			raw->flags |= RAW3215_WORKING;
-		} 
+		}
 	}
 	req = raw->queued_write;
 	if (req != NULL &&
 	    !(raw->flags & (RAW3215_WORKING | RAW3215_STOPPED))) {
 		/* dequeue request */
 		raw->queued_write = NULL;
-		res = do_IO(raw->irq, req->ccws, (unsigned long) req, 0, 0);
+		res = ccw_device_start(raw->cdev, req->ccws,
+				       (unsigned long) req, 0, 0);
 		if (res != 0) {
 			/* do_IO failed, put request back to queue */
 			raw->queued_write = req;
@@ -289,19 +295,20 @@
 /*
  * Function to start a delayed output after RAW3215_TIMEOUT seconds
  */
-static void raw3215_timeout(unsigned long __data)
+static void
+raw3215_timeout(unsigned long __data)
 {
-	raw3215_info *raw = (raw3215_info *) __data;
+	struct raw3215_info *raw = (struct raw3215_info *) __data;
 	unsigned long flags;
 
-	s390irq_spin_lock_irqsave(raw->irq, flags);
+	spin_lock_irqsave(raw->lock, flags);
 	if (raw->flags & RAW3215_TIMER_RUNS) {
 		del_timer(&raw->timer);
 		raw->flags &= ~RAW3215_TIMER_RUNS;
-                raw3215_mk_write_req(raw);
+		raw3215_mk_write_req(raw);
 		raw3215_start_io(raw);
 	}
-	s390irq_spin_unlock_irqrestore(raw->irq, flags);
+	spin_unlock_irqrestore(raw->lock, flags);
 }
 
 /*
@@ -310,7 +317,8 @@
  * amount of data is bigger than RAW3215_MIN_WRITE. If a write is not
  * done immediatly a timer is started with a delay of RAW3215_TIMEOUT.
  */
-extern inline void raw3215_try_io(raw3215_info *raw)
+static inline void
+raw3215_try_io(struct raw3215_info *raw)
 {
 	if (!(raw->flags & RAW3215_ACTIVE))
 		return;
@@ -320,7 +328,7 @@
 		if ((raw->queued_write->delayable == 0) ||
 		    (raw->flags & RAW3215_FLUSHING)) {
 			/* execute write requests bigger than minimum size */
-                        raw3215_start_io(raw);
+			raw3215_start_io(raw);
 			if (raw->flags & RAW3215_TIMER_RUNS) {
 				del_timer(&raw->timer);
 				raw->flags &= ~RAW3215_TIMER_RUNS;
@@ -341,21 +349,21 @@
  * The bottom half handler routine for 3215 devices. It tries to start
  * the next IO and wakes up processes waiting on the tty.
  */
-static void raw3215_tasklet(void *data)
+static void
+raw3215_tasklet(void *data)
 {
-	raw3215_info *raw;
+	struct raw3215_info *raw;
 	struct tty_struct *tty;
 	unsigned long flags;
 
-	raw = (raw3215_info *) data;
-	s390irq_spin_lock_irqsave(raw->irq, flags);
-        raw3215_mk_write_req(raw);
-        raw3215_try_io(raw);
-	raw->flags &= ~RAW3215_BH_PENDING;
-	s390irq_spin_unlock_irqrestore(raw->irq, flags);
+	raw = (struct raw3215_info *) data;
+	spin_lock_irqsave(raw->lock, flags);
+	raw3215_mk_write_req(raw);
+	raw3215_try_io(raw);
+	spin_unlock_irqrestore(raw->lock, flags);
 	/* Check for pending message from raw3215_irq */
 	if (raw->message != NULL) {
-		printk(raw->message, raw->irq, raw->msg_dstat, raw->msg_cstat);
+		printk(raw->message, raw->msg_dstat, raw->msg_cstat);
 		raw->message = NULL;
 	}
 	tty = raw->tty;
@@ -369,99 +377,67 @@
 }
 
 /*
+ * Interrupt routine, called from common io layer
  */
-static inline void raw3215_sched_tasklet(raw3215_info *raw)
-{
-	if (raw->flags & RAW3215_BH_PENDING)
-		return;		/* already pending */
-	raw->flags |= RAW3215_BH_PENDING;
-	tasklet_hi_schedule(&raw->tasklet);
-}
-
-/*
- * Find the raw3215_info structure associated with irq
- */
-static inline raw3215_info *raw3215_find_info(int irq) {
-	raw3215_info *raw;
-	int i;
-
-	for (i = 0; i < NR_3215; i++) {
-		raw = raw3215[i];
-		if (raw != NULL && raw->irq == irq &&
-		    (raw->flags & RAW3215_ACTIVE))
-			break;
-	}
-	return (i >= NR_3215) ? NULL : raw;
-}
-
-/*
- * Interrupt routine, called from Ingo's I/O layer
- */
-static void raw3215_irq(int irq, void *int_parm, struct pt_regs *regs)
+static void
+raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
 {
-	raw3215_info *raw;
-	raw3215_req *req;
+	struct raw3215_info *raw;
+	struct raw3215_req *req;
 	struct tty_struct *tty;
-	devstat_t *stat;
-        int cstat, dstat;
+	int cstat, dstat;
 	int count, slen;
 
-	stat = (devstat_t *) int_parm;
-	req = (raw3215_req *) stat->intparm;
-	cstat = stat->cstat;
-	dstat = stat->dstat;
+	raw = cdev->dev.driver_data;
+	req = (struct raw3215_req *) intparm;
+	cstat = irb->scsw.cstat;
+	dstat = irb->scsw.dstat;
 	if (cstat != 0) {
-		raw = raw3215_find_info(irq);
-		if (raw != NULL) {
-			raw->message = KERN_WARNING
-				"Got nonzero channel status in raw3215_irq "
-				"(dev %i, dev sts 0x%2x, sch sts 0x%2x)";
-			raw->msg_dstat = dstat;
-			raw->msg_cstat = cstat;
-			raw3215_sched_tasklet(raw);
-		}
+		raw->message = KERN_WARNING
+			"Got nonzero channel status in raw3215_irq "
+			"(dev sts 0x%2x, sch sts 0x%2x)";
+		raw->msg_dstat = dstat;
+		raw->msg_cstat = cstat;
+		tasklet_schedule(&raw->tasklet);
+	}
+	if (dstat & 0x01) { /* we got a unit exception */
+		dstat &= ~0x01;	 /* we can ignore it */
 	}
-        if (dstat & 0x01) { /* we got a unit exception */
-		dstat &= ~0x01;  /* we can ignore it */
-        }
 	switch (dstat) {
 	case 0x80:
 		if (cstat != 0)
 			break;
 		/* Attention interrupt, someone hit the enter key */
-		if ((raw = raw3215_find_info(irq)) == NULL)
-			return;              /* That shouldn't happen ... */
-		/* Setup a read request */
 		raw3215_mk_read_req(raw);
-                if (MACHINE_IS_P390)
-                        memset(raw->inbuf, 0, RAW3215_INBUF_SIZE);
- 		raw3215_sched_tasklet(raw);
+		if (MACHINE_IS_P390)
+			memset(raw->inbuf, 0, RAW3215_INBUF_SIZE);
+		tasklet_schedule(&raw->tasklet);
 		break;
 	case 0x08:
 	case 0x0C:
 		/* Channel end interrupt. */
 		if ((raw = req->info) == NULL)
-                        return;              /* That shouldn't happen ... */
+			return;		     /* That shouldn't happen ... */
 		if (req->type == RAW3215_READ) {
 			/* store residual count, then wait for device end */
-			req->residual = stat->rescnt;
+			req->residual = irb->scsw.count;
 		}
 		if (dstat == 0x08)
 			break;
 	case 0x04:
 		/* Device end interrupt. */
-                if ((raw = req->info) == NULL)
-                        return;              /* That shouldn't happen ... */
+		if ((raw = req->info) == NULL)
+			return;		     /* That shouldn't happen ... */
 		if (req->type == RAW3215_READ && raw->tty != NULL) {
 			unsigned int cchar;
 
 			tty = raw->tty;
-                        count = 160 - req->residual;
-                        if (MACHINE_IS_P390) {
-                                slen = strnlen(raw->inbuf, RAW3215_INBUF_SIZE);
-                                if (count > slen)
-                                        count = slen;
-                        } else
+			count = 160 - req->residual;
+			if (MACHINE_IS_P390) {
+				slen = strnlen(raw->inbuf, RAW3215_INBUF_SIZE);
+				if (count > slen)
+					count = slen;
+			} else
 			if (count >= TTY_FLIPBUF_SIZE - tty->flip.count)
 				count = TTY_FLIPBUF_SIZE - tty->flip.count - 1;
 			EBCASC(raw->inbuf, count);
@@ -498,9 +474,8 @@
 			}
 		} else if (req->type == RAW3215_WRITE) {
 			raw->count -= req->len;
-                        raw->written -= req->len;
-		} 
-
+			raw->written -= req->len;
+		}
 		raw->flags &= ~RAW3215_WORKING;
 		raw3215_free_req(req);
 		/* check for empty wait */
@@ -509,27 +484,24 @@
 		    raw->queued_read == NULL) {
 			wake_up_interruptible(&raw->empty_wait);
 		}
- 		raw3215_sched_tasklet(raw);
+		tasklet_schedule(&raw->tasklet);
 		break;
 	default:
 		/* Strange interrupt, I'll do my best to clean up */
-                if ((raw = raw3215_find_info(irq)) == NULL)
-                        return;              /* That shouldn't happen ... */
-                if (raw == NULL) break;
 		if (req != NULL && req->type != RAW3215_FREE) {
-		        if (req->type == RAW3215_WRITE) {
-			        raw->count -= req->len;
-                                raw->written -= req->len;
-                        }
-                        raw->flags &= ~RAW3215_WORKING;
-                        raw3215_free_req(req);
+			if (req->type == RAW3215_WRITE) {
+				raw->count -= req->len;
+				raw->written -= req->len;
+			}
+			raw->flags &= ~RAW3215_WORKING;
+			raw3215_free_req(req);
 		}
 		raw->message = KERN_WARNING
 			"Spurious interrupt in in raw3215_irq "
-			"(dev %i, dev sts 0x%2x, sch sts 0x%2x)";
+			"(dev sts 0x%2x, sch sts 0x%2x)";
 		raw->msg_dstat = dstat;
 		raw->msg_cstat = cstat;
- 		raw3215_sched_tasklet(raw);
+		tasklet_schedule(&raw->tasklet);
 	}
 	return;
 }
@@ -539,7 +511,8 @@
  * Has to be called with the s390irq lock held. Can be called
  * disabled.
  */
-static void raw3215_make_room(raw3215_info *raw, unsigned int length)
+static void
+raw3215_make_room(struct raw3215_info *raw, unsigned int length)
 {
 	while (RAW3215_BUFFER_SIZE - raw->count < length) {
 		/* there might be a request pending */
@@ -547,18 +520,16 @@
 		raw3215_mk_write_req(raw);
 		raw3215_try_io(raw);
 		raw->flags &= ~RAW3215_FLUSHING;
-		if (wait_cons_dev(raw->irq) != 0) {
-			/* that shouldn't happen */
-			raw->count = 0;
-			raw->written = 0;
-		}
+#ifdef CONFIG_TN3215_CONSOLE
+		wait_cons_dev();
+#endif
 		/* Enough room freed up ? */
 		if (RAW3215_BUFFER_SIZE - raw->count >= length)
 			break;
 		/* there might be another cpu waiting for the lock */
-		s390irq_spin_unlock(raw->irq);
+		spin_unlock(raw->lock);
 		udelay(100);
-		s390irq_spin_lock(raw->irq);
+		spin_lock(raw->lock);
 	}
 }
 
@@ -566,27 +537,27 @@
  * String write routine for 3215 devices
  */
 static int
-raw3215_write(raw3215_info *raw, const char *str,
+raw3215_write(struct raw3215_info *raw, const char *str,
 	      int from_user, unsigned int length)
 {
 	unsigned long flags;
 	int ret, c;
 	int count;
-	
+
 	ret = 0;
 	while (length > 0) {
-		s390irq_spin_lock_irqsave(raw->irq, flags);
+		spin_lock_irqsave(raw->lock, flags);
 		count = (length > RAW3215_BUFFER_SIZE) ?
 					     RAW3215_BUFFER_SIZE : length;
 		length -= count;
 
-                raw3215_make_room(raw, count);
+		raw3215_make_room(raw, count);
 
 		/* copy string to output buffer and convert it to EBCDIC */
 		if (from_user) {
 			while (1) {
-				c = MIN(count,
-					MIN(RAW3215_BUFFER_SIZE - raw->count,
+				c = min_t(int, count,
+					min(RAW3215_BUFFER_SIZE - raw->count,
 					    RAW3215_BUFFER_SIZE - raw->head));
 				if (c <= 0)
 					break;
@@ -608,8 +579,8 @@
 			}
 		} else {
 			while (1) {
-				c = MIN(count,
-					MIN(RAW3215_BUFFER_SIZE - raw->count,
+				c = min_t(int, count,
+					min(RAW3215_BUFFER_SIZE - raw->count,
 					    RAW3215_BUFFER_SIZE - raw->head));
 				if (c <= 0)
 					break;
@@ -624,12 +595,12 @@
 				ret += c;
 			}
 		}
-                if (!(raw->flags & RAW3215_WORKING)) {
-                        raw3215_mk_write_req(raw);
-		        /* start or queue request */
-		        raw3215_try_io(raw);
-                }
-		s390irq_spin_unlock_irqrestore(raw->irq, flags);
+		if (!(raw->flags & RAW3215_WORKING)) {
+			raw3215_mk_write_req(raw);
+			/* start or queue request */
+			raw3215_try_io(raw);
+		}
+		spin_unlock_irqrestore(raw->lock, flags);
 	}
 
 	return ret;
@@ -638,162 +609,239 @@
 /*
  * Put character routine for 3215 devices
  */
-	
-static void raw3215_putchar(raw3215_info *raw, unsigned char ch)
+static void
+raw3215_putchar(struct raw3215_info *raw, unsigned char ch)
 {
 	unsigned long flags;
-        unsigned int length, i;
+	unsigned int length, i;
 
-	s390irq_spin_lock_irqsave(raw->irq, flags);
+	spin_lock_irqsave(raw->lock, flags);
 	if (ch == '\t') {
 		length = TAB_STOP_SIZE - (raw->line_pos%TAB_STOP_SIZE);
 		raw->line_pos += length;
 		ch = ' ';
-        } else if (ch == '\n') {
+	} else if (ch == '\n') {
 		length = 1;
 		raw->line_pos = 0;
 	} else {
 		length = 1;
 		raw->line_pos++;
 	}
-        raw3215_make_room(raw, length);
+	raw3215_make_room(raw, length);
 
 	for (i = 0; i < length; i++) {
 		raw->buffer[raw->head] = (char) _ascebc[(int) ch];
 		raw->head = (raw->head + 1) & (RAW3215_BUFFER_SIZE - 1);
 		raw->count++;
 	}
-        if (!(raw->flags & RAW3215_WORKING)) {
-                raw3215_mk_write_req(raw);
-	        /* start or queue request */
-	        raw3215_try_io(raw);
-        }
-	s390irq_spin_unlock_irqrestore(raw->irq, flags);
+	if (!(raw->flags & RAW3215_WORKING)) {
+		raw3215_mk_write_req(raw);
+		/* start or queue request */
+		raw3215_try_io(raw);
+	}
+	spin_unlock_irqrestore(raw->lock, flags);
 }
 
 /*
- * Flush routine, it simply sets the flush flag and tries to start 
+ * Flush routine, it simply sets the flush flag and tries to start
  * pending IO.
  */
-static void raw3215_flush_buffer(raw3215_info *raw)
+static void
+raw3215_flush_buffer(struct raw3215_info *raw)
 {
 	unsigned long flags;
 
-	s390irq_spin_lock_irqsave(raw->irq, flags);
+	spin_lock_irqsave(raw->lock, flags);
 	if (raw->count > 0) {
 		raw->flags |= RAW3215_FLUSHING;
 		raw3215_try_io(raw);
 		raw->flags &= ~RAW3215_FLUSHING;
 	}
-	s390irq_spin_unlock_irqrestore(raw->irq, flags);
+	spin_unlock_irqrestore(raw->lock, flags);
 }
 
 /*
  * Fire up a 3215 device.
  */
-static int raw3215_startup(raw3215_info *raw)
+static int
+raw3215_startup(struct raw3215_info *raw)
 {
 	unsigned long flags;
 
 	if (raw->flags & RAW3215_ACTIVE)
 		return 0;
-	if (s390_request_console_irq(raw->irq, raw3215_irq, SA_INTERRUPT,
-				"3215 terminal driver", &raw->devstat) != 0)
-		return -1;
 	raw->line_pos = 0;
 	raw->flags |= RAW3215_ACTIVE;
-	s390irq_spin_lock_irqsave(raw->irq, flags);
+	spin_lock_irqsave(raw->lock, flags);
 	raw3215_try_io(raw);
-	s390irq_spin_unlock_irqrestore(raw->irq, flags);
+	spin_unlock_irqrestore(raw->lock, flags);
 
-	return 0;	
+	return 0;
 }
 
 /*
  * Shutdown a 3215 device.
  */
-static void raw3215_shutdown(raw3215_info *raw)
+static void
+raw3215_shutdown(struct raw3215_info *raw)
 {
-        DECLARE_WAITQUEUE(wait, current);
+	DECLARE_WAITQUEUE(wait, current);
 	unsigned long flags;
 
 	if (!(raw->flags & RAW3215_ACTIVE) || (raw->flags & RAW3215_FIXED))
 		return;
 	/* Wait for outstanding requests, then free irq */
-	s390irq_spin_lock_irqsave(raw->irq, flags);
+	spin_lock_irqsave(raw->lock, flags);
 	if ((raw->flags & RAW3215_WORKING) ||
 	    raw->queued_write != NULL ||
 	    raw->queued_read != NULL) {
 		raw->flags |= RAW3215_CLOSING;
 		add_wait_queue(&raw->empty_wait, &wait);
-#warning FIXME: use set_current_state instead of current->state=
 		current->state = TASK_INTERRUPTIBLE;
-                s390irq_spin_unlock_irqrestore(raw->irq, flags);
-		/* FIXME: what if schedule is interrupted by a signal,
-		 * shouldn't we loop here? */
+		spin_unlock_irqrestore(raw->lock, flags);
 		schedule();
-		s390irq_spin_lock_irqsave(raw->irq, flags);
+		spin_lock_irqsave(raw->lock, flags);
 		remove_wait_queue(&raw->empty_wait, &wait);
-                current->state = TASK_RUNNING;
+		current->state = TASK_RUNNING;
 		raw->flags &= ~(RAW3215_ACTIVE | RAW3215_CLOSING);
 	}
-	free_irq(raw->irq, NULL);
-	s390irq_spin_unlock_irqrestore(raw->irq, flags);
+	spin_unlock_irqrestore(raw->lock, flags);
 }
 
 static int
-raw3215_find_dev(int number)
+raw3215_probe (struct ccw_device *cdev)
 {
-	s390_dev_info_t dinfo;
-	int irq;
-	int count;
+	struct raw3215_info *raw;
+	int line;
+
+	raw = kmalloc(sizeof(struct raw3215_info) +
+		      RAW3215_INBUF_SIZE, GFP_KERNEL|GFP_DMA);
+	if (raw == NULL)
+		return -ENOMEM;
+
+	spin_lock(&raw3215_device_lock);
+	for (line = 0; line < NR_3215; line++) {
+		if (!raw3215[line]) {
+			raw3215[line] = raw;
+			break;
+		}
+	}
+	spin_unlock(&raw3215_device_lock);
+	if (line == NR_3215) {
+		kfree(raw);
+		return -ENODEV;
+	}
+
+	raw->cdev = cdev;
+	raw->lock = get_ccwdev_lock(cdev);
+	raw->inbuf = (char *) raw + sizeof(struct raw3215_info);
+	memset(raw, 0, sizeof(struct raw3215_info));
+	raw->buffer = (char *) kmalloc(RAW3215_BUFFER_SIZE,
+				       GFP_KERNEL|GFP_DMA);
+	if (raw->buffer == NULL) {
+		spin_lock(&raw3215_device_lock);
+		raw3215[line] = 0;
+		spin_unlock(&raw3215_device_lock);
+		kfree(raw);
+		return -ENOMEM;
+	}
+	tasklet_init(&raw->tasklet,
+		     (void (*)(unsigned long)) raw3215_tasklet,
+		     (unsigned long) raw);
+	init_waitqueue_head(&raw->empty_wait);
+
+	cdev->dev.driver_data = raw;
+	cdev->handler = raw3215_irq;
 
-	irq = get_irq_first();
-	count = 0;
-        while (count <= number && irq != -ENODEV) {
-                if (get_dev_info_by_irq(irq, &dinfo) == -ENODEV)
-                        break;
-                if (dinfo.devno == console_device ||
-                    dinfo.sid_data.cu_type == 0x3215) {
-                        count++;
-                    if (count > number)
-                        return irq;
-                }
-                irq = get_irq_next(irq);
-        }
-        return -1;            /* console not found */
+	return 0;
 }
 
-#ifdef CONFIG_TN3215_CONSOLE
+static int
+raw3215_remove (struct ccw_device *cdev)
+{
+	struct raw3215_info *raw;
 
+	raw = cdev->dev.driver_data;
+	if (raw) {
+		cdev->dev.driver_data = NULL;
+		if (raw->buffer)
+			kfree(raw->buffer);
+		kfree(raw);
+	}
+	return 0;
+}
+
+static int
+raw3215_set_online (struct ccw_device *cdev)
+{
+	struct raw3215_info *raw;
+
+	raw = cdev->dev.driver_data;
+	if (!raw)
+		return -ENODEV;
+
+	return raw3215_startup(raw);
+}
+
+static int
+raw3215_set_offline (struct ccw_device *cdev)
+{
+	struct raw3215_info *raw;
+
+	raw = cdev->dev.driver_data;
+	if (!raw)
+		return -ENODEV;
+
+	raw3215_shutdown(raw);
+
+	return 0;
+}
+
+static struct ccw_device_id raw3215_id[] = {
+	{ CCW_DEVICE(0x3215, 0) },
+	{ /* end of list */ },
+};
+
+static struct ccw_driver raw3215_ccw_driver = {
+	.name		= "3215",
+	.owner		= THIS_MODULE,
+	.ids		= raw3215_id,
+	.probe		= &raw3215_probe,
+	.remove		= &raw3215_remove,
+	.set_online	= &raw3215_set_online,
+	.set_offline	= &raw3215_set_offline,
+};
+
+#ifdef CONFIG_TN3215_CONSOLE
 /*
  * Write a string to the 3215 console
  */
 static void
 con3215_write(struct console *co, const char *str, unsigned int count)
 {
-	raw3215_info *raw;
+	struct raw3215_info *raw;
 	int i;
 
 	if (count <= 0)
 		return;
-        raw = raw3215[0];       /* console 3215 is the first one */
-        while (count > 0) {
-                for (i = 0; i < count; i++)
-                        if (str[i] == '\t' || str[i] == '\n')
-                                break;
-                raw3215_write(raw, str, 0, i);
+	raw = raw3215[0];	/* console 3215 is the first one */
+	while (count > 0) {
+		for (i = 0; i < count; i++)
+			if (str[i] == '\t' || str[i] == '\n')
+				break;
+		raw3215_write(raw, str, 0, i);
 		count -= i;
 		str += i;
-                if (count > 0) {
+		if (count > 0) {
 			raw3215_putchar(raw, *str);
 			count--;
 			str++;
-                }
-        }
+		}
+	}
 }
 
-static kdev_t con3215_device(struct console *c)
+static kdev_t
+con3215_device(struct console *c)
 {
 	return mk_kdev(TTY_MAJOR, c->index + 64 );
 }
@@ -802,18 +850,20 @@
  * panic() calls console_unblank before the system enters a
  * disabled, endless loop.
  */
-static void con3215_unblank(void)
+static void
+con3215_unblank(void)
 {
-	raw3215_info *raw;
+	struct raw3215_info *raw;
 	unsigned long flags;
 
 	raw = raw3215[0];  /* console 3215 is the first one */
-	s390irq_spin_lock_irqsave(raw->irq, flags);
+	spin_lock_irqsave(raw->lock, flags);
 	raw3215_make_room(raw, RAW3215_BUFFER_SIZE);
-	s390irq_spin_unlock_irqrestore(raw->irq, flags);
+	spin_unlock_irqrestore(raw->lock, flags);
 }
 
-static int __init con3215_consetup(struct console *co, char *options)
+static int __init
+con3215_consetup(struct console *co, char *options)
 {
 	return 0;
 }
@@ -822,14 +872,76 @@
  *  The console structure for the 3215 console
  */
 static struct console con3215 = {
-	.name		= "tty3215",
-	.write		= con3215_write,
-	.device		= con3215_device,
-	.unblank	= con3215_unblank,
-	.setup		= con3215_consetup,
-	.flags		= CON_PRINTBUFFER,
+	.name	 = "tty3215",
+	.write	 = con3215_write,
+	.device	 = con3215_device,
+	.unblank = con3215_unblank,
+	.setup	 = con3215_consetup,
+	.flags	 = CON_PRINTBUFFER,
 };
 
+/*
+ * 3215 console initialization code called from console_init().
+ * NOTE: This is called before kmalloc is available.
+ */
+void __init
+con3215_init(void)
+{
+	struct ccw_device *cdev;
+	struct raw3215_info *raw;
+	struct raw3215_req *req;
+	int i;
+
+	/* Check if 3215 is to be the console */
+	if (!CONSOLE_IS_3215)
+		return;
+
+	/* Set the console mode for VM */
+	if (MACHINE_IS_VM) {
+		cpcmd("TERM CONMODE 3215", NULL, 0);
+		cpcmd("TERM AUTOCR OFF", NULL, 0);
+	}
+
+	/* allocate 3215 request structures */
+	raw3215_freelist = NULL;
+	spin_lock_init(&raw3215_freelist_lock);
+	for (i = 0; i < NR_3215_REQ; i++) {
+		req = (struct raw3215_req *) alloc_bootmem_low(sizeof(struct raw3215_req));
+		req->next = raw3215_freelist;
+		raw3215_freelist = req;
+	}
+
+	cdev = ccw_device_probe_console();
+	if (!cdev)
+		return;
+
+	raw3215[0] = raw = (struct raw3215_info *)
+		alloc_bootmem_low(sizeof(struct raw3215_info));
+	memset(raw, 0, sizeof(struct raw3215_info));
+	raw->buffer = (char *) alloc_bootmem_low(RAW3215_BUFFER_SIZE);
+	raw->inbuf = (char *) alloc_bootmem_low(RAW3215_INBUF_SIZE);
+	raw->cdev = cdev;
+	raw->lock = get_ccwdev_lock(cdev);
+	cdev->dev.driver_data = raw;
+	cdev->handler = raw3215_irq;
+
+	raw->flags |= RAW3215_FIXED;
+	tasklet_init(&raw->tasklet,
+		     (void (*)(unsigned long)) raw3215_tasklet,
+		     (unsigned long) raw);
+	init_waitqueue_head(&raw->empty_wait);
+
+	/* Request the console irq */
+	if (raw3215_startup(raw) != 0) {
+		free_bootmem((unsigned long) raw->inbuf, RAW3215_INBUF_SIZE);
+		free_bootmem((unsigned long) raw->buffer, RAW3215_BUFFER_SIZE);
+		free_bootmem((unsigned long) raw, sizeof(struct raw3215_info));
+		raw3215[0] = NULL;
+		printk("Couldn't find a 3215 console device\n");
+		return;
+	}
+	register_console(&con3215);
+}
 #endif
 
 /*
@@ -837,9 +949,10 @@
  *
  * This routine is called whenever a 3215 tty is opened.
  */
-static int tty3215_open(struct tty_struct *tty, struct file * filp)
+static int
+tty3215_open(struct tty_struct *tty, struct file * filp)
 {
-	raw3215_info *raw;
+	struct raw3215_info *raw;
 	int retval, line;
 
 	line = minor(tty->device) - tty->driver.minor_start;
@@ -847,27 +960,8 @@
 		return -ENODEV;
 
 	raw = raw3215[line];
-	if (raw == NULL) {
-		raw = kmalloc(sizeof(raw3215_info) +
-			      RAW3215_INBUF_SIZE, GFP_KERNEL|GFP_DMA);
-		if (raw == NULL)
-			return -ENOMEM;
-		raw->irq = raw3215_find_dev(line);
-		if (raw->irq == -1) {
-			kfree(raw);
-			return -ENODEV;
-		}
-		raw->inbuf = (char *) raw + sizeof(raw3215_info);
-		memset(raw, 0, sizeof(raw3215_info));
-		raw->buffer = (char *) kmalloc(RAW3215_BUFFER_SIZE,
-					       GFP_KERNEL|GFP_DMA);
-		if (raw->buffer == NULL) {
-			kfree(raw);
-			return -ENOMEM;
-		}
-                init_waitqueue_head(&raw->empty_wait);
-		raw3215[line] = raw;
-	}
+	if (raw == NULL)
+		return -ENODEV;
 
 	tty->driver_data = raw;
 	raw->tty = tty;
@@ -889,11 +983,12 @@
  * This routine is called when the 3215 tty is closed. We wait
  * for the remaining request to be completed. Then we clean up.
  */
-static void tty3215_close(struct tty_struct *tty, struct file * filp)
+static void
+tty3215_close(struct tty_struct *tty, struct file * filp)
 {
-	raw3215_info *raw;
+	struct raw3215_info *raw;
 
-	raw = (raw3215_info *) tty->driver_data;
+	raw = (struct raw3215_info *) tty->driver_data;
 	if (raw == NULL || tty->count > 1)
 		return;
 	tty->closing = 1;
@@ -906,11 +1001,12 @@
 /*
  * Returns the amount of free space in the output buffer.
  */
-static int tty3215_write_room(struct tty_struct *tty)
+static int
+tty3215_write_room(struct tty_struct *tty)
 {
-	raw3215_info *raw;
-				
-	raw = (raw3215_info *) tty->driver_data;
+	struct raw3215_info *raw;
+
+	raw = (struct raw3215_info *) tty->driver_data;
 
 	/* Subtract TAB_STOP_SIZE to allow for a tab, 8 <<< 64K */
 	if ((RAW3215_BUFFER_SIZE - raw->count - TAB_STOP_SIZE) >= 0)
@@ -922,15 +1018,16 @@
 /*
  * String write routine for 3215 ttys
  */
-static int tty3215_write(struct tty_struct * tty, int from_user,
-		    const unsigned char *buf, int count)
+static int
+tty3215_write(struct tty_struct * tty, int from_user,
+	      const unsigned char *buf, int count)
 {
-	raw3215_info *raw;
+	struct raw3215_info *raw;
 	int ret = 0;
-				
+
 	if (!tty)
 		return 0;
-	raw = (raw3215_info *) tty->driver_data;
+	raw = (struct raw3215_info *) tty->driver_data;
 	ret = raw3215_write(raw, buf, from_user, count);
 	return ret;
 }
@@ -938,36 +1035,40 @@
 /*
  * Put character routine for 3215 ttys
  */
-static void tty3215_put_char(struct tty_struct *tty, unsigned char ch)
+static void
+tty3215_put_char(struct tty_struct *tty, unsigned char ch)
 {
-	raw3215_info *raw;
+	struct raw3215_info *raw;
 
 	if (!tty)
 		return;
-	raw = (raw3215_info *) tty->driver_data;
+	raw = (struct raw3215_info *) tty->driver_data;
 	raw3215_putchar(raw, ch);
 }
 
-static void tty3215_flush_chars(struct tty_struct *tty)
+static void
+tty3215_flush_chars(struct tty_struct *tty)
 {
 }
 
 /*
  * Returns the number of characters in the output buffer
  */
-static int tty3215_chars_in_buffer(struct tty_struct *tty)
+static int
+tty3215_chars_in_buffer(struct tty_struct *tty)
 {
-	raw3215_info *raw;
+	struct raw3215_info *raw;
 
-	raw = (raw3215_info *) tty->driver_data;
+	raw = (struct raw3215_info *) tty->driver_data;
 	return raw->count;
 }
 
-static void tty3215_flush_buffer(struct tty_struct *tty)
+static void
+tty3215_flush_buffer(struct tty_struct *tty)
 {
-	raw3215_info *raw;
+	struct raw3215_info *raw;
 
-	raw = (raw3215_info *) tty->driver_data;
+	raw = (struct raw3215_info *) tty->driver_data;
 	raw3215_flush_buffer(raw);
 	wake_up_interruptible(&tty->write_wait);
 	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
@@ -978,8 +1079,9 @@
 /*
  * Currently we don't have any io controls for 3215 ttys
  */
-static int tty3215_ioctl(struct tty_struct *tty, struct file * file,
-		    unsigned int cmd, unsigned long arg)
+static int
+tty3215_ioctl(struct tty_struct *tty, struct file * file,
+	      unsigned int cmd, unsigned long arg)
 {
 	if (tty->flags & (1 << TTY_IO_ERROR))
 		return -EIO;
@@ -994,145 +1096,79 @@
 /*
  * Disable reading from a 3215 tty
  */
-static void tty3215_throttle(struct tty_struct * tty)
+static void
+tty3215_throttle(struct tty_struct * tty)
 {
-	raw3215_info *raw;
+	struct raw3215_info *raw;
 
-	raw = (raw3215_info *) tty->driver_data;
+	raw = (struct raw3215_info *) tty->driver_data;
 	raw->flags |= RAW3215_THROTTLED;
 }
 
 /*
  * Enable reading from a 3215 tty
  */
-static void tty3215_unthrottle(struct tty_struct * tty)
+static void
+tty3215_unthrottle(struct tty_struct * tty)
 {
-	raw3215_info *raw;
+	struct raw3215_info *raw;
 	unsigned long flags;
 
-	raw = (raw3215_info *) tty->driver_data;
+	raw = (struct raw3215_info *) tty->driver_data;
 	if (raw->flags & RAW3215_THROTTLED) {
-		s390irq_spin_lock_irqsave(raw->irq, flags);
+		spin_lock_irqsave(raw->lock, flags);
 		raw->flags &= ~RAW3215_THROTTLED;
 		raw3215_try_io(raw);
-		s390irq_spin_unlock_irqrestore(raw->irq, flags);
+		spin_unlock_irqrestore(raw->lock, flags);
 	}
 }
 
 /*
  * Disable writing to a 3215 tty
  */
-static void tty3215_stop(struct tty_struct *tty)
+static void
+tty3215_stop(struct tty_struct *tty)
 {
-	raw3215_info *raw;
+	struct raw3215_info *raw;
 
-	raw = (raw3215_info *) tty->driver_data;
+	raw = (struct raw3215_info *) tty->driver_data;
 	raw->flags |= RAW3215_STOPPED;
 }
 
 /*
  * Enable writing to a 3215 tty
  */
-static void tty3215_start(struct tty_struct *tty)
+static void
+tty3215_start(struct tty_struct *tty)
 {
-	raw3215_info *raw;
+	struct raw3215_info *raw;
 	unsigned long flags;
 
-	raw = (raw3215_info *) tty->driver_data;
+	raw = (struct raw3215_info *) tty->driver_data;
 	if (raw->flags & RAW3215_STOPPED) {
-		s390irq_spin_lock_irqsave(raw->irq, flags);
+		spin_lock_irqsave(raw->lock, flags);
 		raw->flags &= ~RAW3215_STOPPED;
 		raw3215_try_io(raw);
-		s390irq_spin_unlock_irqrestore(raw->irq, flags);
+		spin_unlock_irqrestore(raw->lock, flags);
 	}
 }
 
 
 /*
- * 3215 console initialization code called from console_init().
- * NOTE: This is called before kmalloc is available.
+ * 3215 tty registration code called from tty_init().
+ * Most kernel services (incl. kmalloc) are available at this poimt.
  */
-void __init con3215_init(void)
+int __init
+tty3215_init(void)
 {
-#ifdef CONFIG_TN3215_CONSOLE
-	raw3215_info *raw;
-#endif
-	raw3215_req *req;
-	int irq;
-	int i;
+	int ret;
 
-	/* Check if 3215 is to be the console */
 	if (!CONSOLE_IS_3215)
-		return;
-
-	/* Set the console mode for VM */
-	if (MACHINE_IS_VM) {
-		cpcmd("TERM CONMODE 3215", NULL, 0);
-		cpcmd("TERM AUTOCR OFF", NULL, 0);
-	}
-
-	if (console_device != -1) {
-		/* use the device number that was specified on the
-		 * command line */
-		irq = raw3215_find_dev(0);
-	} else if (MACHINE_IS_VM) {
-		/* under VM, the console is at device number 0009
-		 * by default, so try that */
-		irq = get_irq_by_devno(0x0009);
-	} else {
-		/* unlike in 2.4, we cannot autoprobe here, since
-		 * the channel subsystem is not fully initialized.
-		 * With some luck, the HWC console can take over */
-		printk(KERN_WARNING "3215 console not found\n");
-		return;
-	}
-
-	/* allocate 3215 request structures */
-	raw3215_freelist = NULL;
-	spin_lock_init(&raw3215_freelist_lock);
-	for (i = 0; i < NR_3215_REQ; i++) {
-                req = (raw3215_req *) alloc_bootmem_low(sizeof(raw3215_req));
-		req->next = raw3215_freelist;
-		raw3215_freelist = req;
-	}
-
-#ifdef CONFIG_TN3215_CONSOLE
-        raw3215[0] = raw = (raw3215_info *)
-                alloc_bootmem_low(sizeof(raw3215_info));
-	memset(raw, 0, sizeof(raw3215_info));
-        raw->buffer = (char *) alloc_bootmem_low(RAW3215_BUFFER_SIZE);
-        raw->inbuf = (char *) alloc_bootmem_low(RAW3215_INBUF_SIZE);
-
-	/* Find the first console */
-	raw->irq = irq;
-	raw->flags |= RAW3215_FIXED;
-	tasklet_init(&raw->tasklet, 
-		     (void (*)(unsigned long)) raw3215_tasklet,
-		     (unsigned long) raw);
-        init_waitqueue_head(&raw->empty_wait);
-
-	/* Request the console irq */
-	if ( raw3215_startup(raw) != 0 )
-		raw->irq = -1;
-
-	if (raw->irq != -1) {
-		register_console(&con3215);
-	} else {
-                free_bootmem((unsigned long) raw->inbuf, RAW3215_INBUF_SIZE);
-                free_bootmem((unsigned long) raw->buffer, RAW3215_BUFFER_SIZE);
-                free_bootmem((unsigned long) raw, sizeof(raw3215_info));
-		raw3215[0] = NULL;
-		printk("Couldn't find a 3215 console device\n");
-	}
-#endif
-}
+		return 0;
 
-/*
- * 3215 tty registration code called from tty_init().
- * Most kernel services (incl. kmalloc) are available at this poimt.
- */
-void __init tty3215_init(void)
-{
+	ret = ccw_driver_register(&raw3215_ccw_driver);
+	if (ret)
+		return ret;
 	/*
 	 * Initialize the tty_driver structure
 	 * Entries in tty3215_driver that are NOT initialized:
@@ -1153,7 +1189,7 @@
 	tty3215_driver.init_termios.c_iflag = IGNBRK | IGNPAR;
 	tty3215_driver.init_termios.c_oflag = ONLCR | XTABS;
 	tty3215_driver.init_termios.c_lflag = ISIG;
-	tty3215_driver.flags = TTY_DRIVER_REAL_RAW; 
+	tty3215_driver.flags = TTY_DRIVER_REAL_RAW;
 	tty3215_driver.refcount = &tty3215_refcount;
 	tty3215_driver.table = tty3215_table;
 	tty3215_driver.termios = tty3215_termios;
@@ -1179,6 +1215,18 @@
 	tty3215_driver.wait_until_sent = NULL;
 	tty3215_driver.read_proc = NULL;
 
-	if (tty_register_driver(&tty3215_driver))
-		panic("Couldn't register tty3215 driver\n");
+	ret = tty_register_driver(&tty3215_driver);
+	if (ret)
+		printk("Couldn't register tty3215 driver\n");
+	return ret;
+}
+
+static void __exit
+tty3215_exit(void)
+{
+	tty_unregister_driver(&tty3215_driver);
+	ccw_driver_unregister(&raw3215_ccw_driver);
 }
+
+module_init(tty3215_init);
+module_exit(tty3215_exit);
diff -Nru a/drivers/s390/char/ctrlchar.c b/drivers/s390/char/ctrlchar.c
--- a/drivers/s390/char/ctrlchar.c	Mon Dec  9 18:46:52 2002
+++ b/drivers/s390/char/ctrlchar.c	Mon Dec  9 18:46:52 2002
@@ -9,6 +9,7 @@
 
 #include <linux/config.h>
 #include <linux/stddef.h>
+#include <asm/errno.h>
 #include <linux/sysrq.h>
 #include <linux/ctype.h>
 
@@ -20,7 +21,7 @@
 static void
 ctrlchar_handle_sysrq(void *tty)
 {
-	handle_sysrq(ctrlchar_sysrq_key, NULL, tty);
+	handle_sysrq(ctrlchar_sysrq_key, NULL, (struct tty_struct *) tty);
 }
 
 static DECLARE_WORK(ctrlchar_work, ctrlchar_handle_sysrq, 0);
@@ -39,7 +40,7 @@
  *         with CTRLCHAR_CTRL
  */
 unsigned int
-ctrlchar_handle(const char *buf, int len, struct tty_struct *tty)
+ctrlchar_handle(const unsigned char *buf, int len, struct tty_struct *tty)
 {
 	if ((len < 2) || (len > 3))
 		return CTRLCHAR_NONE;
diff -Nru a/drivers/s390/char/ctrlchar.h b/drivers/s390/char/ctrlchar.h
--- a/drivers/s390/char/ctrlchar.h	Mon Dec  9 18:46:51 2002
+++ b/drivers/s390/char/ctrlchar.h	Mon Dec  9 18:46:51 2002
@@ -10,7 +10,7 @@
 #include <linux/tty.h>
 
 extern unsigned int
-ctrlchar_handle(const char *buf, int len, struct tty_struct *tty);
+ctrlchar_handle(const unsigned char *buf, int len, struct tty_struct *tty);
 
 
 #define CTRLCHAR_NONE  (1 << 8)
diff -Nru a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
--- a/drivers/s390/char/sclp.c	Mon Dec  9 18:46:49 2002
+++ b/drivers/s390/char/sclp.c	Mon Dec  9 18:46:49 2002
@@ -10,6 +10,7 @@
 
 #include <linux/config.h>
 #include <linux/version.h>
+#include <linux/module.h>
 #include <linux/kmod.h>
 #include <linux/bootmem.h>
 #include <linux/err.h>
@@ -17,6 +18,7 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
+#include <linux/timer.h>
 #include <asm/s390_ext.h>
 
 #include "sclp.h"
@@ -29,7 +31,7 @@
  * different behaviour); otherwise we use the default
  * settings in sclp_data.init_ioctls
  */
-#define	 USE_VM_DETECTION
+#define USE_VM_DETECTION
 
 /* Structure for register_early_external_interrupt. */
 static ext_int_info_t ext_int_info_hwc;
@@ -53,12 +55,21 @@
 /* sccb for write mask sccb */
 static char sclp_init_sccb[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
 
+/* Timer for init mask retries. */
+static struct timer_list retry_timer;
+
 static unsigned long sclp_status = 0;
 /* some status flags */
 #define SCLP_INIT		0
 #define SCLP_RUNNING		1
 #define SCLP_READING		2
 
+#define SCLP_INIT_POLL_INTERVAL	1
+
+#define SCLP_COMMAND_INITIATED	0
+#define SCLP_BUSY		2
+#define SCLP_NOT_OPERATIONAL	3
+
 /*
  * assembler instruction for Service Call
  */
@@ -86,7 +97,7 @@
 	 *	      new SCCB unchanged
 	 * cc == 3:   SCLP function not operational
 	 */
-	if (cc == 3)
+	if (cc == SCLP_NOT_OPERATIONAL)
 		return -EIO;
 	/*
 	 * We set the SCLP_RUNNING bit for cc 2 as well because if
@@ -94,7 +105,7 @@
 	 * that has to complete first
 	 */
 	set_bit(SCLP_RUNNING, &sclp_status);
-	if (cc == 2)
+	if (cc == SCLP_BUSY)
 		return -EBUSY;
 	return 0;
 }
@@ -130,6 +141,7 @@
 static int
 sclp_process_evbufs(struct sccb_header *sccb)
 {
+	int result;
 	unsigned long flags;
 	struct evbuf_header *evbuf;
 	struct list_head *l;
@@ -137,8 +149,10 @@
 
 	spin_lock_irqsave(&sclp_lock, flags);
 	evbuf = (struct evbuf_header *) (sccb + 1);
-	while ((void *) evbuf < (void *) sccb + sccb->length) {
+	result = 0;
+	while ((addr_t) evbuf < (addr_t) sccb + sccb->length) {
 		/* check registered event */
+		t = NULL;
 		list_for_each(l, &sclp_reg_list) {
 			t = list_entry(l, struct sclp_register, list);
 			if (t->receive_mask & (1 << (32 - evbuf->type))) {
@@ -146,56 +160,72 @@
 					t->receiver_fn(evbuf);
 				break;
 			}
+			else
+				t = NULL;
 		}
+		/* Check for unrequested event buffer */
+		if (t == NULL)
+			result = -ENOSYS;
+		evbuf = (struct evbuf_header *)
+				((addr_t) evbuf + evbuf->length);
 	}
 	spin_unlock_irqrestore(&sclp_lock, flags);
-	return -ENOSYS;
+	return result;
 }
 
-/*
- * postprocessing of unconditional read service call
- */
-static void
-sclp_unconditional_read_cb(struct sclp_req *read_req, void *data)
+char *
+sclp_error_message(u16 rc)
 {
 	static struct {
 		u16 code; char *msg;
-	} errors[] = {
+	} sclp_errors[] = {
+		{ 0x0000, "No response code stored (machine malfunction)" },
+		{ 0x0020, "Normal Completion" },
 		{ 0x0040, "SCLP equipment check" },
 		{ 0x0100, "SCCB boundary violation" },
-		{ 0x01f0, "invalid command" },
-		{ 0x0300, "insufficient SCCB length" },
-		{ 0x40f0, "invalid function code" },
-		{ 0x60f0, "got interrupt but no data found" },
-		{ 0x62f0, "got interrupt but no data found" },
-		{ 0x70f0, "invalid selection mask" }
+		{ 0x01f0, "Invalid command" },
+		{ 0x0220, "Normal Completion; suppressed buffers pending" },
+		{ 0x0300, "Insufficient SCCB length" },
+		{ 0x0340, "Contained SCLP equipment check" },
+		{ 0x05f0, "Target resource in improper state" },
+		{ 0x40f0, "Invalid function code/not installed" },
+		{ 0x60f0, "No buffers stored" },
+		{ 0x62f0, "No buffers stored; suppressed buffers pending" },
+		{ 0x70f0, "Invalid selection mask" },
+		{ 0x71f0, "Event buffer exceeds available space" },
+		{ 0x72f0, "Inconsistent lengths" },
+		{ 0x73f0, "Event buffer syntax error" }
 	};
-	struct sccb_header *sccb;
-	char *errmsg;
 	int i;
+	for (i = 0; i < sizeof(sclp_errors)/sizeof(sclp_errors[0]); i++)
+		if (rc == sclp_errors[i].code)
+			return sclp_errors[i].msg;
+	return "Invalid response code";
+}
+
+/*
+ * postprocessing of unconditional read service call
+ */
+static void
+sclp_unconditional_read_cb(struct sclp_req *read_req, void *data)
+{
+	struct sccb_header *sccb;
 
 	sccb = read_req->sccb;
 	if (sccb->response_code == 0x0020 ||
 	    sccb->response_code == 0x0220) {
-		/* normal read completion, event buffers stored in sccb */
-		if (sclp_process_evbufs(sccb) == 0) {
-			clear_bit(SCLP_READING, &sclp_status);
-			return;
-		}
-		errmsg = "invalid response code";
-	} else {
-		errmsg = NULL;
-		for (i = 0; i < sizeof(errors)/sizeof(errors[0]); i++)
-			if (sccb->response_code == errors[i].code) {
-				errmsg = errors[i].msg;
-				break;
-			}
-		if (errmsg == NULL)
-			errmsg = "invalid response code";
+		if (sclp_process_evbufs(sccb) != 0)
+			printk(KERN_WARNING SCLP_CORE_PRINT_HEADER
+			       "unconditional read: "
+			       "unrequested event buffer received.\n");
 	}
-	printk(KERN_WARNING SCLP_CORE_PRINT_HEADER
-	       "unconditional read: %s (response code =0x%x).\n",
-	       errmsg, sccb->response_code);
+
+	if (sccb->response_code != 0x0020)
+		printk(KERN_WARNING SCLP_CORE_PRINT_HEADER
+		       "unconditional read: %s (response code=0x%x).\n",
+		       sclp_error_message(sccb->response_code),
+		       sccb->response_code);
+
 	clear_bit(SCLP_READING, &sclp_status);
 }
 
@@ -209,7 +239,7 @@
 	struct sclp_req *read_req;
 
 	/*
-	 * Don´t try to initiate Unconditional Read if we are not able to
+	 * Don't try to initiate Unconditional Read if we are not able to
 	 * receive anything
 	 */
 	if (sclp_receive_mask == 0)
@@ -217,13 +247,13 @@
 	/* Don't try reading if a read is already outstanding */
 	if (test_and_set_bit(SCLP_READING, &sclp_status))
 		return;
-	/* Initialise read sccb */
+	/* Initialize read sccb */
 	sccb = (struct sccb_header *) sclp_read_sccb;
 	clear_page(sccb);
 	sccb->length = PAGE_SIZE;
 	sccb->function_code = 0;	/* unconditional read */
 	sccb->control_mask[2] = 0x80;	/* variable length response */
-	/* stick the request structure to the end of the page */
+	/* Initialize request structure */
 	read_req = &sclp_read_req;
 	read_req->command = SCLP_CMDW_READDATA;
 	read_req->status = SCLP_REQ_QUEUED;
@@ -233,6 +263,11 @@
 	list_add(&read_req->list, &sclp_req_queue);
 }
 
+/* Bit masks to interpret external interruption parameter contents. */
+#define EXT_INT_SCCB_MASK		0xfffffff8
+#define EXT_INT_STATECHANGE_PENDING	0x00000002
+#define EXT_INT_EVBUF_PENDING		0x00000001
+
 /*
  * Handler for service-signal external interruptions
  */
@@ -242,15 +277,14 @@
 	u32 ext_int_param, finished_sccb, evbuf_pending;
 	struct list_head *l;
 	struct sclp_req *req, *tmp;
-	int cpu;
 
-	cpu = smp_processor_id();
 	ext_int_param = S390_lowcore.ext_params;
-	finished_sccb = ext_int_param & -8U;
-	evbuf_pending = ext_int_param & 1;
+	finished_sccb = ext_int_param & EXT_INT_SCCB_MASK;
+	evbuf_pending = ext_int_param & (EXT_INT_EVBUF_PENDING |
+					 EXT_INT_STATECHANGE_PENDING);
 	irq_enter();
 	/*
-	 * Only do request callsbacks if sclp is initialised.
+	 * Only do request callbacks if sclp is initialized.
 	 * This avoids strange effects for a pending request
 	 * from before the last re-ipl.
 	 */
@@ -326,8 +360,8 @@
 }
 
 /*
- * Queue a request to the tail of the ccw_queue. Start the I/O if
- * possible.
+ * Queue an SCLP request. Request will immediately be processed if queue is
+ * empty.
  */
 void
 sclp_add_request(struct sclp_req *req)
@@ -391,17 +425,17 @@
 	scbuf = (struct sclp_statechangebuf *) evbuf;
 
 	if (scbuf->validity_sclp_receive_mask) {
-		if (scbuf->mask_length != 4)
+		if (scbuf->mask_length != sizeof(sccb_mask_t))
 			printk(KERN_WARNING SCLP_CORE_PRINT_HEADER
 			       "state change event with mask length %i\n",
 			       scbuf->mask_length);
 		else
-			/* set new send mask */
+			/* set new receive mask */
 			sclp_receive_mask = scbuf->sclp_receive_mask;
 	}
 
 	if (scbuf->validity_sclp_send_mask) {
-		if (scbuf->mask_length != 4)
+		if (scbuf->mask_length != sizeof(sccb_mask_t))
 			printk(KERN_WARNING SCLP_CORE_PRINT_HEADER
 			       "state change event with mask length %i\n",
 			       scbuf->mask_length);
@@ -496,6 +530,8 @@
 	sccb_mask_t sclp_receive_mask;
 } __attribute__((packed));
 
+static void sclp_init_mask_retry(unsigned long);
+
 static int
 sclp_init_mask(void)
 {
@@ -557,13 +593,34 @@
 			spin_lock_irqsave(&sclp_lock, flags);
 		} while (rc == -EBUSY);
 	}
-	sclp_receive_mask = sccb->sclp_receive_mask;
-	sclp_send_mask = sccb->sclp_send_mask;
-	__sclp_notify_state_change();
+	if (sccb->header.response_code != 0x0020) {
+		/* WRITEMASK failed - we cannot rely on receiving a state
+		   change event, so initially, polling is the only alternative
+		   for us to ever become operational. */
+		if (!timer_pending(&retry_timer) ||
+		    !mod_timer(&retry_timer,
+			       jiffies + SCLP_INIT_POLL_INTERVAL*HZ)) {
+			retry_timer.function = sclp_init_mask_retry;
+			retry_timer.data = 0;
+			retry_timer.expires = jiffies +
+				SCLP_INIT_POLL_INTERVAL*HZ;
+			add_timer(&retry_timer);
+		}
+	} else {
+		sclp_receive_mask = sccb->sclp_receive_mask;
+		sclp_send_mask = sccb->sclp_send_mask;
+		__sclp_notify_state_change();
+	}
 	spin_unlock_irqrestore(&sclp_lock, flags);
 	return 0;
 }
 
+static void
+sclp_init_mask_retry(unsigned long data) 
+{
+	sclp_init_mask();
+}
+
 /*
  * sclp setup function. Called early (no kmalloc!) from sclp_console_init().
  */
@@ -573,7 +630,7 @@
 	int rc;
 
 	if (test_bit(SCLP_INIT, &sclp_status))
-		/* Already initialised. */
+		/* Already initialized. */
 		return 0;
 
 	/*
@@ -600,6 +657,7 @@
 	 */
 	ctl_set_bit(0, 9);
 
+	init_timer(&retry_timer);
 	/* do the initial write event mask */
 	rc = sclp_init_mask();
 	if (rc == 0) {
@@ -616,6 +674,15 @@
 	return rc;
 }
 
+/*
+ * Register the SCLP event listener identified by REG. Return 0 on success.
+ * Some error codes and their meaning:
+ *
+ *  -ENODEV = SCLP interface is not supported on this machine
+ *   -EBUSY = there is already a listener registered for the requested
+ *            event type
+ *     -EIO = SCLP interface is currently not operational
+ */
 int
 sclp_register(struct sclp_register *reg)
 {
@@ -650,6 +717,9 @@
 	return 0;
 }
 
+/*
+ * Unregister the SCLP event listener identified by REG.
+ */
 void
 sclp_unregister(struct sclp_register *reg)
 {
@@ -661,3 +731,7 @@
 	sclp_init_mask();
 }
 
+EXPORT_SYMBOL(sclp_add_request);
+EXPORT_SYMBOL(sclp_sync_wait);
+EXPORT_SYMBOL(sclp_register);
+EXPORT_SYMBOL(sclp_unregister);
diff -Nru a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h
--- a/drivers/s390/char/sclp.h	Mon Dec  9 18:46:35 2002
+++ b/drivers/s390/char/sclp.h	Mon Dec  9 18:46:35 2002
@@ -45,10 +45,6 @@
 #define LnTpFlgs_EndText	0x1000
 #define LnTpFlgs_PromptText	0x0800
 
-#define SCLP_COMMAND_INITIATED	0
-#define SCLP_BUSY		2
-#define SCLP_NOT_OPERATIONAL	3
-
 typedef unsigned int sclp_cmdw_t;
 
 #define SCLP_CMDW_READDATA	0x00770005
@@ -129,6 +125,7 @@
 void sclp_sync_wait(void);
 int sclp_register(struct sclp_register *reg);
 void sclp_unregister(struct sclp_register *reg);
+char *sclp_error_message(u16 response_code);
 
 /* useful inlines */
 
diff -Nru a/drivers/s390/char/sclp_con.c b/drivers/s390/char/sclp_con.c
--- a/drivers/s390/char/sclp_con.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/s390/char/sclp_con.c	Mon Dec  9 18:46:37 2002
@@ -51,13 +51,14 @@
 	struct sclp_buffer *next;
 	void *page;
 
-	/* FIXME: what if rc != 0x0020 */
+	/* Ignore return code - because console-writes aren't critical,
+	   we do without a sophisticated error recovery mechanism.  */
 	page = sclp_unmake_buffer(buffer);
 	spin_lock_irqsave(&sclp_con_lock, flags);
-	list_add_tail((struct list_head *) page, &sclp_con_pages);
-	sclp_con_buffer_count--;
 	/* Remove buffer from outqueue */
 	list_del(&buffer->list);
+	sclp_con_buffer_count--;
+	list_add_tail((struct list_head *) page, &sclp_con_pages);
 	/* Check if there is a pending buffer on the out queue. */
 	next = NULL;
 	if (!list_empty(&sclp_con_outqueue))
@@ -104,7 +105,7 @@
 	void *page;
 	int written;
 
-	if (count <= 0)
+	if (count == 0)
 		return;
 	spin_lock_irqsave(&sclp_con_lock, flags);
 	/*
@@ -125,7 +126,8 @@
 						       sclp_con_width_htab);
 		}
 		/* try to write the string to the current output buffer */
-		written = sclp_write(sclp_conbuf, message, count, 0);
+		written = sclp_write(sclp_conbuf, (const unsigned char *)
+				     message, count, 0);
 		if (written == -EFAULT || written == count)
 			break;
 		/*
@@ -232,6 +234,6 @@
 		sclp_con_columns = 80;
 	sclp_con_width_htab = 8;
 
-	/* enable printk´s access to this driver */
+	/* enable printk-access to this driver */
 	register_console(&sclp_console);
 }
diff -Nru a/drivers/s390/char/sclp_cpi.c b/drivers/s390/char/sclp_cpi.c
--- a/drivers/s390/char/sclp_cpi.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/s390/char/sclp_cpi.c	Mon Dec  9 18:46:38 2002
@@ -130,7 +130,7 @@
 	req = (struct sclp_req *) kmalloc(sizeof(struct sclp_req), GFP_KERNEL);
 	if (req == NULL)
 		return ERR_PTR(-ENOMEM);
-	sccb = (struct cpi_sccb *) get_free_page(GFP_KERNEL);
+	sccb = (struct cpi_sccb *) __get_free_page(GFP_KERNEL);
 	if (sccb == NULL) {
 		kfree(req);
 		return ERR_PTR(-ENOMEM);
@@ -227,6 +227,7 @@
 		rc = 0;
 
 	cpi_free_req(req);
+	sclp_unregister(&sclp_cpi_event);
 
 	return rc;
 }
diff -Nru a/drivers/s390/char/sclp_rw.c b/drivers/s390/char/sclp_rw.c
--- a/drivers/s390/char/sclp_rw.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/s390/char/sclp_rw.c	Mon Dec  9 18:46:37 2002
@@ -54,6 +54,8 @@
 	 */
 	buffer = ((struct sclp_buffer *) ((addr_t) sccb + PAGE_SIZE)) - 1;
 	buffer->sccb = sccb;
+	buffer->retry_count = 0;
+	init_timer(&buffer->retry_timer);
 	buffer->mto_number = 0;
 	buffer->mto_char_sum = 0;
 	buffer->current_line = NULL;
@@ -87,14 +89,11 @@
 }
 
 /*
- * Creates a new Message Text Object with enough room for str_len
- * characters. This function will create a new sccb for buffering
- * the mto if the current buffer sccb is full. A full buffer sccb
- * is submitted for output.
- * Returns a pointer to the start of the string in the mto.
+ * Initialize a new Message Text Object (MTO) at the end of the provided buffer
+ * with enough room for max_len characters. Return 0 on success.
  */
 static int
-sclp_create_mto(struct sclp_buffer *buffer, int max_len)
+sclp_initialize_mto(struct sclp_buffer *buffer, int max_len)
 {
 	struct write_sccb *sccb;
 	struct mto *mto;
@@ -109,7 +108,7 @@
 		return -ENOMEM;
 
 	/* find address of new message text object */
-	mto = (struct mto *)(((unsigned long) sccb) + sccb->header.length);
+	mto = (struct mto *)(((addr_t) sccb) + sccb->header.length);
 
 	/*
 	 * fill the new Message-Text Object,
@@ -128,11 +127,11 @@
 }
 
 /*
- * Add the mto created with sclp_create_mto to the buffer sccb using
- * the str_len parameter as the real length of the string.
+ * Finalize MTO initialized by sclp_initialize_mto(), updating the sizes of
+ * MTO, enclosing MDB, event buffer and SCCB.
  */
 static void
-sclp_add_mto(struct sclp_buffer *buffer)
+sclp_finalize_mto(struct sclp_buffer *buffer)
 {
 	struct write_sccb *sccb;
 	struct mto *mto;
@@ -147,7 +146,7 @@
 
 	/* find address of new message text object */
 	sccb = buffer->sccb;
-	mto = (struct mto *)(((unsigned long) sccb) + sccb->header.length);
+	mto = (struct mto *)(((addr_t) sccb) + sccb->header.length);
 
 	/* set size of message text object */
 	mto->length = mto_size;
@@ -169,23 +168,6 @@
 	buffer->mto_char_sum += str_len;
 }
 
-void
-sclp_move_current_line(struct sclp_buffer *to, struct sclp_buffer *from)
-{
-	if (from->current_line == NULL)
-		return;
-	if (sclp_create_mto(to, from->columns) != 0)
-		return;
-	if (from->current_length > 0) {
-		memcpy(to->current_line,
-		       from->current_line - from->current_length,
-		       from->current_length);
-		to->current_line += from->current_length;
-		to->current_length = from->current_length;
-	}
-	from->current_line = NULL;
-}
-
 /*
  * processing of a message including escape characters,
  * returns number of characters written to the output sccb
@@ -195,7 +177,7 @@
  */
 int
 sclp_write(struct sclp_buffer *buffer,
-	   const char *msg, int count, int from_user)
+	   const unsigned char *msg, int count, int from_user)
 {
 	int spaces, i_msg;
 	char ch;
@@ -203,7 +185,7 @@
 
 	/*
 	 * parse msg for escape sequences (\t,\v ...) and put formated
-	 * msg into an mto (created by sclp_create_mto).
+	 * msg into an mto (created by sclp_initialize_mto).
 	 *
 	 * We have to do this work ourselfs because there is no support for
 	 * these characters on the native machine and only partial support
@@ -235,11 +217,11 @@
 		case '\n':	/* new line, line feed (ASCII)	*/
 			/* check if new mto needs to be created */
 			if (buffer->current_line == NULL) {
-				rc = sclp_create_mto(buffer, 0);
+				rc = sclp_initialize_mto(buffer, 0);
 				if (rc)
 					return i_msg;
 			}
-			sclp_add_mto(buffer);
+			sclp_finalize_mto(buffer);
 			break;
 		case '\a':	/* bell, one for several times	*/
 			/* set SCLP sound alarm bit in General Object */
@@ -249,7 +231,8 @@
 		case '\t':	/* horizontal tabulator	 */
 			/* check if new mto needs to be created */
 			if (buffer->current_line == NULL) {
-				rc = sclp_create_mto(buffer, buffer->columns);
+				rc = sclp_initialize_mto(buffer,
+							 buffer->columns);
 				if (rc)
 					return i_msg;
 			}
@@ -268,8 +251,9 @@
 			/* = new line, leading spaces */
 			if (buffer->current_line != NULL) {
 				spaces = buffer->current_length;
-				sclp_add_mto(buffer);
-				rc = sclp_create_mto(buffer, buffer->columns);
+				sclp_finalize_mto(buffer);
+				rc = sclp_initialize_mto(buffer,
+							 buffer->columns);
 				if (rc)
 					return i_msg;
 				memset(buffer->current_line, 0x40, spaces);
@@ -277,10 +261,11 @@
 				buffer->current_length = spaces;
 			} else {
 				/* one an empty line this is the same as \n */
-				rc = sclp_create_mto(buffer, buffer->columns);
+				rc = sclp_initialize_mto(buffer,
+							 buffer->columns);
 				if (rc)
 					return i_msg;
-				sclp_add_mto(buffer);
+				sclp_finalize_mto(buffer);
 			}
 			break;
 		case '\b':	/* backspace  */
@@ -296,7 +281,7 @@
 		case 0x00:	/* end of string  */
 			/* transfer current line to SCCB */
 			if (buffer->current_line != NULL)
-				sclp_add_mto(buffer);
+				sclp_finalize_mto(buffer);
 			/* skip the rest of the message including the 0 byte */
 			i_msg = count;
 			break;
@@ -306,7 +291,8 @@
 				break;
 			/* check if new mto needs to be created */
 			if (buffer->current_line == NULL) {
-				rc = sclp_create_mto(buffer, buffer->columns);
+				rc = sclp_initialize_mto(buffer,
+							 buffer->columns);
 				if (rc)
 					return i_msg;
 			}
@@ -317,7 +303,7 @@
 		/* check if current mto is full */
 		if (buffer->current_line != NULL &&
 		    buffer->current_length >= buffer->columns)
-			sclp_add_mto(buffer);
+			sclp_finalize_mto(buffer);
 	}
 
 	/* return number of processed characters */
@@ -361,7 +347,7 @@
 	buffer->columns = columns;
 	if (buffer->current_line != NULL &&
 	    buffer->current_length > buffer->columns)
-		sclp_add_mto(buffer);
+		sclp_finalize_mto(buffer);
 }
 
 void
@@ -377,13 +363,62 @@
 sclp_rw_init(void)
 {
 	static int init_done = 0;
+	int rc;
 
 	if (init_done)
 		return 0;
-	init_done = 1;
-	return sclp_register(&sclp_rw_event);
+
+	rc = sclp_register(&sclp_rw_event);
+	if (rc == 0)
+		init_done = 1;
+	return rc;
 }
 
+#define	SCLP_EVBUF_PROCESSED	0x80
+
+/*
+ * Traverse array of event buffers contained in SCCB and remove all buffers
+ * with a set "processed" flag. Return the number of unprocessed buffers.
+ */
+static int
+sclp_remove_processed(struct sccb_header *sccb)
+{
+	struct evbuf_header *evbuf;
+	int unprocessed;
+	u16 remaining;
+
+	evbuf = (struct evbuf_header *) (sccb + 1);
+	unprocessed = 0;
+	remaining = sccb->length - sizeof(struct sccb_header);
+	while (remaining > 0) {
+		remaining -= evbuf->length;
+		if (evbuf->flags & SCLP_EVBUF_PROCESSED) {
+			sccb->length -= evbuf->length;
+			memcpy((void *) evbuf,
+			       (void *) ((addr_t) evbuf + evbuf->length),
+			       remaining);
+		} else {
+			unprocessed++;
+			evbuf = (struct evbuf_header *)
+					((addr_t) evbuf + evbuf->length);
+		}
+	}
+
+	return unprocessed;
+}
+
+static void
+sclp_buffer_retry(unsigned long data)
+{
+	struct sclp_buffer *buffer = (struct sclp_buffer *) data;
+	buffer->request.status = SCLP_REQ_FILLED;
+	buffer->sccb->header.response_code = 0x0000;
+	sclp_add_request(&buffer->request);
+}
+
+#define SCLP_BUFFER_MAX_RETRY		5
+#define	SCLP_BUFFER_RETRY_INTERVAL	2
+
 /*
  * second half of Write Event Data-function that has to be done after
  * interruption indicating completion of Service Call.
@@ -391,32 +426,68 @@
 static void
 sclp_writedata_callback(struct sclp_req *request, void *data)
 {
+	int rc;
 	struct sclp_buffer *buffer;
 	struct write_sccb *sccb;
 
 	buffer = (struct sclp_buffer *) data;
 	sccb = buffer->sccb;
 
-	/* FIXME: proper error handling */
+	if (request->status == SCLP_REQ_FAILED) {
+		if (buffer->callback != NULL)
+			buffer->callback(buffer, -EIO);
+		return;
+	}
 	/* check SCLP response code and choose suitable action	*/
 	switch (sccb->header.response_code) {
 	case 0x0020 :
-		/* normal completion, buffer processed, message(s) sent */
+		/* Normal completion, buffer processed, message(s) sent */
+		rc = 0;
 		break;
 
-	case 0x0340:	/* contained SCLP equipment check */
-	case 0x40F0:	/* function code disabled in SCLP receive mask */
+	case 0x0340: /* Contained SCLP equipment check */
+		if (buffer->retry_count++ > SCLP_BUFFER_MAX_RETRY) {
+			rc = -EIO;
+			break;
+		}
+		/* remove processed buffers and requeue rest */
+		if (sclp_remove_processed((struct sccb_header *) sccb) > 0) {
+			/* not all buffers were processed */
+			sccb->header.response_code = 0x0000;
+			buffer->request.status = SCLP_REQ_FILLED;
+			sclp_add_request(request);
+			return;
+		}
+		rc = 0;
 		break;
+
+	case 0x0040: /* SCLP equipment check */
+	case 0x05f0: /* Target resource in improper state */
+		if (buffer->retry_count++ > SCLP_BUFFER_MAX_RETRY) {
+			rc = -EIO;
+			break;
+		}
+		/* wait some time, then retry request */
+		buffer->retry_timer.function = sclp_buffer_retry;
+		buffer->retry_timer.data = (unsigned long) buffer;
+		buffer->retry_timer.expires = jiffies +
+						SCLP_BUFFER_RETRY_INTERVAL*HZ;
+		add_timer(&buffer->retry_timer);
+		return;
+
 	default:
-		/* sclp_free_sccb(sccb); */
+		if (sccb->header.response_code == 0x71f0)
+			rc = -ENOMEM;
+		else
+			rc = -EINVAL;
 		printk(KERN_WARNING SCLP_RW_PRINT_HEADER
-		       "write event data failed "
-		       "(response code: 0x%x SCCB address %p).\n",
-		       sccb->header.response_code, sccb);
+		       "sclp_writedata_callback: %s (response code=0x%x).\n",
+		       sclp_error_message(sccb->header.response_code),
+		       sccb->header.response_code);
 		break;
 	}
 	if (buffer->callback != NULL)
-		buffer->callback(buffer, sccb->header.response_code);
+		buffer->callback(buffer, rc);
 }
 
 /*
@@ -431,10 +502,10 @@
 
 	/* add current line if there is one */
 	if (buffer->current_line != NULL)
-		sclp_add_mto(buffer);
+		sclp_finalize_mto(buffer);
 
 	/* Are there messages in the output buffer ? */
-	if (buffer->mto_number <= 0)
+	if (buffer->mto_number == 0)
 		return;
 
 	sccb = buffer->sccb;
diff -Nru a/drivers/s390/char/sclp_rw.h b/drivers/s390/char/sclp_rw.h
--- a/drivers/s390/char/sclp_rw.h	Mon Dec  9 18:46:38 2002
+++ b/drivers/s390/char/sclp_rw.h	Mon Dec  9 18:46:38 2002
@@ -11,6 +11,9 @@
 #ifndef __SCLP_RW_H__
 #define __SCLP_RW_H__
 
+#include <linux/list.h>
+#include <linux/timer.h>
+
 struct mto {
 	u16 length;
 	u16 type;
@@ -70,6 +73,8 @@
 	struct write_sccb *sccb;
 	char *current_line;
 	int current_length;
+	int retry_count;
+	struct timer_list retry_timer;
 	/* output format settings */
 	unsigned short columns;
 	unsigned short htab;
@@ -84,8 +89,7 @@
 struct sclp_buffer *sclp_make_buffer(void *, unsigned short, unsigned short);
 void *sclp_unmake_buffer(struct sclp_buffer *);
 int sclp_buffer_space(struct sclp_buffer *);
-int sclp_write(struct sclp_buffer *buffer, const char *, int, int);
-void sclp_move_current_line(struct sclp_buffer *, struct sclp_buffer *);
+int sclp_write(struct sclp_buffer *buffer, const unsigned char *, int, int);
 void sclp_emit_buffer(struct sclp_buffer *,void (*)(struct sclp_buffer *,int));
 void sclp_set_columns(struct sclp_buffer *, unsigned short);
 void sclp_set_htab(struct sclp_buffer *, unsigned short);
diff -Nru a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c
--- a/drivers/s390/char/sclp_tty.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/s390/char/sclp_tty.c	Mon Dec  9 18:46:35 2002
@@ -32,7 +32,7 @@
 #define SCLP_TTY_BUF_SIZE 512
 
 /*
- * There is excatly one SCLP terminal, so we can keep things simple
+ * There is exactly one SCLP terminal, so we can keep things simple
  * and allocate all variables statically.
  */
 
@@ -265,13 +265,14 @@
 	struct sclp_buffer *next;
 	void *page;
 
-	/* FIXME: what if rc != 0x0020 */
+	/* Ignore return code - because tty-writes aren't critical,
+	   we do without a sophisticated error recovery mechanism.  */
 	page = sclp_unmake_buffer(buffer);
 	spin_lock_irqsave(&sclp_tty_lock, flags);
-	list_add_tail((struct list_head *) page, &sclp_tty_pages);
-	sclp_tty_buffer_count--;
 	/* Remove buffer from outqueue */
 	list_del(&buffer->list);
+	sclp_tty_buffer_count--;
+	list_add_tail((struct list_head *) page, &sclp_tty_pages);
 	/* Check if there is a pending buffer on the out queue. */
 	next = NULL;
 	if (!list_empty(&sclp_tty_outqueue))
@@ -489,8 +490,8 @@
 		/* send (normal) input to line discipline */
 		memcpy(sclp_tty->flip.char_buf_ptr, buf, count);
 		if (count < 2 ||
-		    strncmp (buf + count - 2, "^n", 2) ||
-		    strncmp (buf + count - 2, "\0252n", 2)) {
+		    strncmp ((const char *) buf + count - 2, "^n", 2) ||
+		    strncmp ((const char *) buf + count - 2, "\0252n", 2)) {
 			sclp_tty->flip.char_buf_ptr[count] = '\n';
 			count++;
 		} else
@@ -558,7 +559,7 @@
 }
 
 static void
-sclp_get_input(char *start, char *end)
+sclp_get_input(unsigned char *start, unsigned char *end)
 {
 	int count;
 
@@ -572,7 +573,7 @@
 
 	/*
 	 * if set in ioctl find out characters in lower or upper case
-	 * (depends on current case) seperated by a special character,
+	 * (depends on current case) separated by a special character,
 	 * works on EBCDIC
 	 */
 	if (sclp_ioctls.delim)
@@ -625,8 +626,8 @@
 		subvec = find_gds_subvector(subvec, end, 0x30);
 		if (!subvec)
 			break;
-		sclp_get_input((void *)(subvec + 1),
-			       (void *) subvec + subvec->length);
+		sclp_get_input((unsigned char *)(subvec + 1),
+			       (unsigned char *) subvec + subvec->length);
 		(void *) subvec += subvec->length;
 	}
 }
diff -Nru a/drivers/s390/char/sclp_tty.h b/drivers/s390/char/sclp_tty.h
--- a/drivers/s390/char/sclp_tty.h	Mon Dec  9 18:46:38 2002
+++ b/drivers/s390/char/sclp_tty.h	Mon Dec  9 18:46:38 2002
@@ -18,9 +18,9 @@
 	unsigned short htab;
 	unsigned char echo;
 	unsigned short columns;
-	signed char final_nl;
+	unsigned char final_nl;
 	unsigned short max_sccb;
-	unsigned short kmem_sccb;	/* can´t be modified at run time */
+	unsigned short kmem_sccb;	/* can't be modified at run time */
 	unsigned char tolower;
 	unsigned char delim;
 };
diff -Nru a/drivers/s390/char/tape.c b/drivers/s390/char/tape.c
--- a/drivers/s390/char/tape.c	Mon Dec  9 18:46:49 2002
+++ b/drivers/s390/char/tape.c	Mon Dec  9 18:46:49 2002
@@ -152,7 +152,6 @@
  *******************************************************************/
 
 #ifdef CONFIG_DEVFS_FS
-devfs_handle_t tape_devfs_root_entry;
 
 /*
  * Create devfs root entry (devno in hex) for device td
@@ -161,9 +160,9 @@
 static inline devfs_handle_t
 tape_mkdevfsroot (tape_dev_t* td) 
 {
-    char devno [5];
-    sprintf (devno,"%04x",td->devinfo.devno);
-    return (td->devfs_dir=devfs_mk_dir (tape_devfs_root_entry, devno, td));
+    char devno [10];
+    sprintf (devno,"tape/%04x",td->devinfo.devno);
+    return devfs_mk_dir(NULL, devno, NULL);
 }
 
 /*
@@ -173,8 +172,7 @@
 static inline void
 tape_rmdevfsroot (tape_dev_t* td)
 {
-    if (td->devfs_dir)
-            devfs_unregister (td->devfs_dir);
+    devfs_remove("tape/%04x", td->devinfo.devno);
 }
 
 #endif
@@ -1715,7 +1713,7 @@
         tape_split_parm_string(tape_parm_string);
 #endif
 #ifdef CONFIG_DEVFS_FS
-        tape_devfs_root_entry=devfs_mk_dir (NULL, "tape", NULL);
+        devfs_mk_dir (NULL, "tape", NULL);
 #endif /* CONFIG_DEVFS_FS */
 
         tape_sprintf_event (tape_dbf_area,3,"dev detect\n");
@@ -1816,7 +1814,7 @@
         tape_sprintf_event (tape_dbf_area,6,"cleaup mod");
 	tape_cleanup_disciplines();
 #ifdef CONFIG_DEVFS_FS
-	devfs_unregister (tape_devfs_root_entry); /* devfs checks for NULL */
+	devfs_remove("tape"); /* devfs checks for NULL */
 #endif CONFIG_DEVFS_FS
 #ifdef CONFIG_PROC_FS
 	tape_proc_cleanup();
diff -Nru a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h
--- a/drivers/s390/char/tape.h	Mon Dec  9 18:46:50 2002
+++ b/drivers/s390/char/tape.h	Mon Dec  9 18:46:50 2002
@@ -1,14 +1,12 @@
-/***************************************************************************
- *
+/*
  *  drivers/s390/char/tape.h
  *    tape device driver for 3480/3490E/3590 tapes.
  *
  *  S390 and zSeries version
- *    Copyright (C) 2001 IBM Corporation
+ *    Copyright (C) 2001,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
  *    Author(s): Carsten Otte <cotte@de.ibm.com>
- *               Tuan Ngo-Anh <ngoanh@de.ibm.com>
- *
- ****************************************************************************
+ *		 Tuan Ngo-Anh <ngoanh@de.ibm.com>
+ *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
  */
 
 #ifndef _TAPE_H
@@ -20,360 +18,338 @@
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/mtio.h>
+#include <linux/interrupt.h>
+#include <asm/ccwdev.h>
 #include <asm/debug.h>
-#ifdef CONFIG_DEVFS_FS
-#include <linux/devfs_fs_kernel.h>
-#endif
-#include "tape_idalbuf.h"
+#include <asm/idals.h>
 
-#define TAPE_VERSION_MAJOR 1
-#define TAPE_VERSION_MINOR 10
+/*
+ * macros s390 debug feature (dbf)
+ */
+#define DBF_EVENT(d_level, d_str...) \
+do { \
+	debug_sprintf_event(tape_dbf_area, d_level, d_str); \
+} while (0)
+
+#define DBF_EXCEPTION(d_level, d_str...) \
+do { \
+	debug_sprintf_exception(tape_dbf_area, d_level, d_str); \
+} while (0)
+
+#define TAPE_VERSION_MAJOR 2
+#define TAPE_VERSION_MINOR 0
 #define TAPE_MAGIC "tape"
-#define TAPE_BUSY(td) (td->treq != NULL)
-#define TAPE_MINORS_PER_DEV 2       /* two minors per device */
 
-#define TAPE_MERGE_RC(treq,rc) \
-	if( ((rc) == 0) && ((treq)->rc != 0) ) \
-		rc = (treq)->rc;
-
-typedef enum{
-	TAPE_NO_WAIT,
-	TAPE_WAIT,
-	TAPE_WAIT_INTERRUPTIBLE,
-	TAPE_WAIT_INTERRUPTIBLE_NOHALTIO,
-	TAPE_REMOVE_REQ_ON_WAKEUP,
-	TAPE_SCHED_BLOCK,
-} tape_wait_t;
+#define TAPE_MINORS_PER_DEV 2	    /* two minors per device */
+#define TAPEBLOCK_HSEC_SIZE	2048
+#define TAPEBLOCK_HSEC_S2B	2
+#define TAPEBLOCK_RETRIES	5
+
+#define TAPE_BUSY(td) (td->treq != NULL)
 
-typedef enum {
+enum tape_medium_state {
 	MS_UNKNOWN,
 	MS_LOADED,
 	MS_UNLOADED,
 	MS_SIZE
-} tape_medium_state_t;
+};
 
-typedef enum {
+enum tape_state {
 	TS_UNUSED=0,
 	TS_IN_USE,
 	TS_INIT,
 	TS_NOT_OPER,
 	TS_SIZE
-} tape_state_t;
+};
 
-typedef enum {
-	TO_BLOCK,
-	TO_BSB,
-	TO_BSF,
-	TO_DSE,
-	TO_EGA,
-	TO_FSB,
-	TO_FSF,
-	TO_LDI,
-	TO_LBL,
-	TO_MSE,
-	TO_NOP,
-	TO_RBA,
-	TO_RBI,
-	TO_RBU,
-	TO_RBL,
-	TO_RDC,
-	TO_RFO,
-	TO_RSD,
-	TO_REW,
-	TO_RUN,
-	TO_SEN,
-	TO_SID,
-	TO_SNP,
-	TO_SPG,
-	TO_SWI,
-	TO_SMR,
-	TO_SYN,
-	TO_TIO,
-	TO_UNA,
-	TO_WRI,
-	TO_WTM,
-	TO_MSEN,
-	TO_LOAD,
-	TO_READ_CONFIG, /* 3590 */
-	TO_READ_ATTMSG, /* 3590 */
-	TO_NOTHING,
-	TO_DIS,
-	TO_SIZE
-} tape_op_t;
-
-#define TAPE_INTERRUPTIBLE_OP(op) \
-	(op == MTEOM) || \
-	(op == MTRETEN)
+enum tape_op {
+	TO_BLOCK,	/* Block read */
+	TO_BSB,		/* Backward space block */
+	TO_BSF,		/* Backward space filemark */
+	TO_DSE,		/* Data security erase */
+	TO_FSB,		/* Forward space block */
+	TO_FSF,		/* Forward space filemark */
+	TO_LBL,		/* Locate block label */
+	TO_NOP,		/* No operation */
+	TO_RBA,		/* Read backward */
+	TO_RBI,		/* Read block information */
+	TO_RFO,		/* Read forward */
+	TO_REW,		/* Rewind tape */
+	TO_RUN,		/* Rewind and unload tape */
+	TO_WRI,		/* Write block */
+	TO_WTM,		/* Write tape mark */
+	TO_MSEN,	/* Medium sense */
+	TO_LOAD,	/* Load tape */
+	TO_READ_CONFIG, /* Read configuration data */
+	TO_READ_ATTMSG, /* Read attention message */
+	TO_DIS,		/* Tape display */
+	TO_ASSIGN,	/* Assign tape to channel path */
+	TO_UNASSIGN,	/* Unassign tape from channel path */
+	TO_SIZE		/* #entries in tape_op_t */
+};
 
-struct _tape_dev_t; //Forward declaration
+/* Forward declaration */
+struct tape_device;
 
-/* The tape device list lock */
-extern rwlock_t   tape_dev_lock;
+/* tape_request->status can be: */
+enum tape_request_status {
+	TAPE_REQUEST_INIT,	/* request is ready to be processed */
+	TAPE_REQUEST_QUEUED,	/* request is queued to be processed */
+	TAPE_REQUEST_IN_IO,	/* request is currently in IO */
+	TAPE_REQUEST_DONE,	/* request is completed. */
+};
 
 /* Tape CCW request */
- 
-typedef struct _tape_ccw_req_t{
-	wait_queue_head_t wq;
-	ccw1_t*           cpaddr;
-	size_t            cplength;
-	int               options;
-	void*             kernbuf;
-	size_t            kernbuf_size;
-	idalbuf_t*        idal_buf;
-	void*             userbuf;
-	size_t            userbuf_size; 
-	tape_op_t op;
-	void   (*wakeup)(struct _tape_ccw_req_t* treq);
-	void   (*wait)(struct _tape_ccw_req_t* treq);
-        struct _tape_dev_t* tape_dev;  // Pointer for back reference
+struct tape_request {
+	struct list_head list;		/* list head for request queueing. */
+	struct tape_device *device;	/* tape device of this request */
+	struct ccw1 *cpaddr;		/* address of the channel program. */
+	void *cpdata;			/* pointer to ccw data. */
+	enum tape_request_status status;/* status of this request */
+	int options;			/* options for execution. */
+	int retries;			/* retry counter for error recovery. */
+	int rescnt;			/* residual count from devstat. */
+
+	/* Callback for delivering final status. */
+	void (*callback)(struct tape_request *, void *);
+	void *callback_data;
+
+	enum tape_op op;
 	int rc;
-	struct _tape_ccw_req_t* recover;
-} tape_ccw_req_t;
+};
 
-/* Callback typedefs */
+/* Function type for magnetic tape commands */
+typedef int (*tape_mtop_fn)(struct tape_device *, int);
 
-typedef void (*tape_disc_shutdown_t) (void);
-typedef void (*tape_event_handler_t) (struct _tape_dev_t*);
-typedef tape_ccw_req_t* (*tape_reqgen_ioctl_t)(struct _tape_dev_t* td,int op,int count,int* rc);
-typedef tape_ccw_req_t* (*tape_reqgen_bread_t)(struct request* req,struct _tape_dev_t* td,int tapeblock_major);
-typedef void (*tape_reqgen_enable_loc_t) (tape_ccw_req_t*);
-typedef void (*tape_free_bread_t)(tape_ccw_req_t*);
-typedef tape_ccw_req_t* (*tape_reqgen_rw_t)(const char* data,size_t count,struct _tape_dev_t* td);
-typedef int (*tape_setup_device_t) (struct _tape_dev_t*);
-typedef void (*tape_cleanup_device_t) (struct _tape_dev_t*);
-typedef int (*tape_disc_ioctl_overl_t)(struct _tape_dev_t*, unsigned int,unsigned long);
-#ifdef CONFIG_DEVFS_FS
-typedef devfs_handle_t (*tape_devfs_constructor_t) (struct _tape_dev_t*);
-typedef void (*tape_devfs_destructor_t) (struct _tape_dev_t*);
-#endif
+/* Size of the arry containing the mtops for a discipline */
+#define TAPE_NR_MTOPS (MTMKPART+1)
 
 /* Tape Discipline */
-
-typedef struct _tape_discipline_t {
-	struct module               *owner;
-	unsigned int                cu_type;
-	tape_setup_device_t         setup_device;
-	tape_cleanup_device_t       cleanup_device;
-	tape_event_handler_t        init_device;
-	tape_event_handler_t        process_eov;
-	tape_event_handler_t        irq;
-	tape_reqgen_bread_t         bread;
-	tape_free_bread_t           free_bread;
-	tape_reqgen_enable_loc_t    bread_enable_locate;
-	tape_reqgen_rw_t            write_block;
-	tape_reqgen_rw_t            read_block;
-	tape_reqgen_ioctl_t         ioctl;
-	tape_disc_shutdown_t        shutdown;
-	tape_disc_ioctl_overl_t     discipline_ioctl_overload;
-	void*                       next;
-} tape_discipline_t  __attribute__ ((aligned(8)));
-
-/* Frontend */
-
-typedef struct _tape_frontend_t {
-	tape_setup_device_t device_setup;
-#ifdef CONFIG_DEVFS_FS
-	tape_devfs_constructor_t mkdevfstree;
-	tape_devfs_destructor_t rmdevfstree;
+struct tape_discipline {
+	struct module *owner;
+	int  (*setup_device)(struct tape_device *);
+	void (*cleanup_device)(struct tape_device *);
+	int (*assign)(struct tape_device *);
+	int (*unassign)(struct tape_device *);
+	int (*irq)(struct tape_device *, struct tape_request *, struct irb *);
+	struct tape_request *(*read_block)(struct tape_device *, size_t);
+	struct tape_request *(*write_block)(struct tape_device *, size_t);
+	void (*process_eov)(struct tape_device*);
+#ifdef CONFIG_S390_TAPE_BLOCK
+	/* Block device stuff. */
+	struct tape_request *(*bread)(struct tape_device *, struct request *);
+	void (*check_locate)(struct tape_device *, struct tape_request *);
+	void (*free_bread)(struct tape_request *);
 #endif
-	void* next;
-} tape_frontend_t  __attribute__ ((aligned(8)));
+	/* ioctl function for additional ioctls. */
+	int (*ioctl_fn)(struct tape_device *, unsigned int, unsigned long);
+	/* Array of tape commands with TAPE_NR_MTOPS entries */
+	tape_mtop_fn *mtop_array;
+};
 
-/* Char Frontend Data */
+/*
+ * The discipline irq function either returns an error code (<0) which
+ * means that the request has failed with an error or one of the following:
+ */
+#define TAPE_IO_SUCCESS 0	/* request sucessful */
+#define TAPE_IO_PENDING 1	/* request still running */
+#define TAPE_IO_RETRY	2	/* retry to current request */
+#define TAPE_IO_STOP	3	/* stop the running request */
 
-typedef struct _tape_char_front_data_t{
-	int     block_size;               /* block size of tape */
-#ifdef CONFIG_DEVFS_FS
-	devfs_handle_t devfs_char_dir;    /* tape/DEVNO/char dir */
-	devfs_handle_t devfs_nonrewinding;/* tape/DEVNO/char/nonrewinding */
-	devfs_handle_t devfs_rewinding;   /* tape/DEVNO/char/rewinding */
-#endif /* CONFIG_DEVFS_FS */
-} tape_char_data_t;
+/* Char Frontend Data */
+struct tape_char_data {
+	struct idal_buffer *idal_buf;	/* idal buffer for user char data */
+	int block_size;			/*   of size block_size. */
+};
 
+#ifdef CONFIG_S390_TAPE_BLOCK
 /* Block Frontend Data */
-
-typedef struct _tape_blk_front_data_t{
+struct tape_blk_data
+{
+	/* Block device request queue. */
 	request_queue_t request_queue;
-	struct request* current_request;
-	int blk_retries;
-	long position;
-	atomic_t bh_scheduled;
-	struct tq_struct bh_tq;
-#ifdef CONFIG_DEVFS_FS
-	devfs_handle_t devfs_block_dir;    /* tape/DEVNO/block dir */
-	devfs_handle_t devfs_disc;         /* tape/DEVNO/block/disc */
-#endif /* CONFIG_DEVFS_FS */
-} tape_blk_data_t;
+	spinlock_t request_queue_lock;
+	/* Block frontend tasklet */
+	struct tasklet_struct tasklet;
+	/* Current position on the tape. */
+	long block_position;
+};
+#endif
 
 /* Tape Info */
- 
-typedef struct _tape_dev_t {
-	atomic_t use_count;            /* Reference count, when == 0 delete */
-	int      first_minor;          /* each tape device has two minors */
-	s390_dev_info_t devinfo;       /* device info from Common I/O */
-	devstat_t devstat;             /* contains irq, devno, status */
-	struct file *filp;             /* backpointer to file structure */
-	int tape_state;                /* State of the device. See tape_stat */
-	int medium_state;              /* loaded, unloaded, unkown etc. */
-	tape_discipline_t* discipline; /* The used discipline */
-	void* discdata;                /* discipline specific data */
-	tape_ccw_req_t* treq;          /* Active Tape request */
-	tape_op_t last_op;             /* Last Tape operation */
-	void*  next;                   /* ptr to next tape_dev */
-#ifdef CONFIG_DEVFS_FS
-	devfs_handle_t devfs_dir;      /* toplevel devfs dir */
-#endif /* CONFIG_DEVFS_FS */
-	tape_char_data_t  char_data;   /* Character dev frontend data */
-	tape_blk_data_t   blk_data;    /* Block dev frontend data */
-} tape_dev_t  __attribute__ ((aligned(8)));
-
-/* tape functions */
-
-#define TAPE_MEMB_IRQ       0
-#define TAPE_MEMB_MINOR     1
-#define TAPE_MEMB_QUEUE     2
-
-tape_dev_t* __tape_get_device_by_member(unsigned long value, int member);
-
-/*
- * Search for tape structure with specific minor number
- */
- 
-static inline tape_dev_t *
-tape_get_device_by_minor(int minor)
-{
-        return __tape_get_device_by_member(minor, TAPE_MEMB_MINOR);
-}
-
-/*
- * Search for tape structure with specific IRQ
- */
- 
-static inline tape_dev_t *
-tape_get_device_by_irq(int irq)
-{
-        return __tape_get_device_by_member(irq, TAPE_MEMB_IRQ);
-}
+struct tape_device {
+	/* entry in tape_device_list */
+	struct list_head node;
+
+	struct ccw_device *cdev;
+
+	/* Device discipline information. */
+	struct tape_discipline *discipline;
+	void *discdata;
+
+	/* Generic status flags */
+	long                    tape_generic_status;
+
+	/* Device state information. */
+	wait_queue_head_t       state_change_wq;
+	enum tape_state         tape_state;
+	enum tape_medium_state  medium_state;
+	unsigned char          *modeset_byte;
+
+	/* Reference count. */
+	atomic_t ref_count;
+
+	/* Request queue. */
+	struct list_head req_queue;
+
+	int first_minor;	       /* each tape device has two minors */
+	/* Character device frontend data */
+	struct tape_char_data char_data;
+#ifdef CONFIG_S390_TAPE_BLOCK
+	/* Block dev frontend data */
+	struct tape_blk_data blk_data;
+#endif
+};
 
-/*
- * Search for tape structure with specific queue
- */
+/* Externals from tape_core.c */
+extern struct tape_request *tape_alloc_request(int cplength, int datasize);
+extern void tape_free_request(struct tape_request *);
+extern int tape_do_io(struct tape_device *, struct tape_request *);
+extern int tape_do_io_async(struct tape_device *, struct tape_request *);
+extern int tape_do_io_interruptible(struct tape_device *, struct tape_request *);
 
-static inline tape_dev_t*
-tape_get_device_by_queue(void* queue)
+static inline int
+tape_do_io_free(struct tape_device *device, struct tape_request *request)
 {
-	return __tape_get_device_by_member((unsigned long)queue, TAPE_MEMB_QUEUE);
-}
+	int rc;
 
-/*
- * Increment use count of tape structure
- */
- 
-static inline void
-tape_get_device(tape_dev_t* td)
-{
-        if (td!=NULL)
-                atomic_inc(&(td->use_count));
+	rc = tape_do_io(device, request);
+	tape_free_request(request);
+	return rc;
 }
 
-void tape_put_device(tape_dev_t* td);
-
-/* Discipline functions */
-int tape_register_discipline(tape_discipline_t* disc);
-void tape_unregister_discipline(tape_discipline_t* disc);
+extern int tape_oper_handler(int irq, int status);
+extern void tape_noper_handler(int irq, int status);
+extern int tape_open(struct tape_device *);
+extern int tape_release(struct tape_device *);
+extern int tape_assign(struct tape_device *);
+extern int tape_unassign(struct tape_device *);
+extern int tape_mtop(struct tape_device *, int, int);
+
+extern int tape_enable_device(struct tape_device *, struct tape_discipline *);
+extern void tape_disable_device(struct tape_device *device);
+
+/* Externals from tape_devmap.c */
+extern int tape_generic_probe(struct ccw_device *);
+extern int tape_generic_remove(struct ccw_device *);
+
+extern struct tape_device *tape_get_device(int devindex);
+extern void tape_put_device(struct tape_device *);
+
+/* Externals from tape_char.c */
+extern int tapechar_init(void);
+extern void tapechar_exit(void);
+extern int  tapechar_setup_device(struct tape_device *);
+extern void tapechar_cleanup_device(struct tape_device *);
+
+/* Externals from tape_block.c */
+#ifdef CONFIG_S390_TAPE_BLOCK
+extern int tapeblock_init (void);
+extern void tapeblock_exit(void);
+extern int tapeblock_setup_device(struct tape_device *);
+extern void tapeblock_cleanup_device(struct tape_device *);
+#else
+static inline int tapeblock_init (void) {return 0;}
+static inline void tapeblock_exit (void) {;}
+static inline int tapeblock_setup_device(struct tape_device *t) {return 0;}
+static inline void tapeblock_cleanup_device (struct tape_device *t) {;}
+#endif
 
 /* tape initialisation functions */
-int tape_init(void);
+#ifdef CONFIG_PROC_FS
+extern void tape_proc_init (void);
+extern void tape_proc_cleanup (void);
+#else
+static inline void tape_proc_init (void) {;}
+static inline void tape_proc_cleanup (void) {;}
+#endif
 
 /* a function for dumping device sense info */
-void tape_dump_sense (tape_dev_t* td);
-void tape_dump_sense_dbf(tape_dev_t* td);
- 
+extern void tape_dump_sense(struct tape_device *, struct tape_request *,
+			    struct irb *);
+extern void tape_dump_sense_dbf(struct tape_device *, struct tape_request *,
+				struct irb *);
+
 /* functions for handling the status of a device */
-inline void tape_state_set (tape_dev_t* td, tape_state_t newstate);
-inline tape_state_t tape_state_get (tape_dev_t* td);
-inline void tape_med_state_set(tape_dev_t* td, tape_medium_state_t newstate);
-
-/* functions for alloc'ing ccw and IO stuff */
-inline  tape_ccw_req_t* tape_alloc_ccw_req(int cplength,int datasize,int idal_buf_size, tape_op_t op);
-void tape_free_ccw_req (tape_ccw_req_t * request);
-int tape_do_io(tape_dev_t * td,tape_ccw_req_t *treq,tape_wait_t type);
-int tape_do_io_irq(tape_dev_t * td,tape_ccw_req_t *treq,tape_wait_t type);
-int tape_do_io_and_wait(tape_dev_t * td,tape_ccw_req_t *treq,tape_wait_t type);
-int tape_do_wait_req(tape_dev_t * td,tape_ccw_req_t *treq,tape_wait_t type);
-int tape_remove_ccw_req(tape_dev_t* td,tape_ccw_req_t* treq);
-tape_ccw_req_t* tape_get_active_ccw_req(tape_dev_t* td);
+extern void tape_med_state_set(struct tape_device *, enum tape_medium_state);
 
 /* The debug area */
-#ifdef TAPE_DEBUG
-        extern debug_info_t *tape_dbf_area;
-        #define tape_sprintf_event debug_sprintf_event
-        #define tape_sprintf_exception debug_sprintf_exception
-#else
-        #define tape_sprintf_event
-        #define tape_sprintf_exception
-#endif
+extern debug_info_t *tape_dbf_area;
 
 /* functions for building ccws */
-static inline ccw1_t* 
-__ccwprep(ccw1_t* ccw, __u8 cmd_code, __u8 flags, __u16 memsize, void* cda,int ccw_count)
+static inline struct ccw1 *
+tape_ccw_cc(struct ccw1 *ccw, __u8 cmd_code, __u16 memsize, void *cda)
 {
-	int i;
-#ifdef CONFIG_ARCH_S390X
-        if ((unsigned long)cda >= (1UL<<31)){
-                printk("cda: %p\n",cda);
-	        BUG();
-        }
-#endif /* CONFIG_ARCH_S390X */
-	for(i = 0 ; i < ccw_count; i++){
-        	ccw[i].cmd_code = cmd_code;
-		ccw[i].flags |= CCW_FLAG_CC;
-		ccw[i].count = memsize;
-		if(cda == 0)
-			ccw[i].cda = (unsigned long)&(ccw[i].cmd_code);
-		else
-			ccw[i].cda = (unsigned long)cda;
-	}
-        ccw[ccw_count-1].flags = flags;
-	return &ccw[ccw_count];
-};
+	ccw->cmd_code = cmd_code;
+	ccw->flags = CCW_FLAG_CC;
+	ccw->count = memsize;
+	ccw->cda = (__u32)(addr_t) cda;
+	return ccw + 1;
+}
 
-extern inline ccw1_t*
-tape_ccw_cc(ccw1_t *ccw,__u8 cmd_code,__u16 memsize,void* cda,int ccw_count)
+static inline struct ccw1 *
+tape_ccw_end(struct ccw1 *ccw, __u8 cmd_code, __u16 memsize, void *cda)
 {
-        return __ccwprep(ccw,cmd_code,CCW_FLAG_CC,memsize,cda,ccw_count);
+	ccw->cmd_code = cmd_code;
+	ccw->flags = 0;
+	ccw->count = memsize;
+	ccw->cda = (__u32)(addr_t) cda;
+	return ccw + 1;
 }
- 
-extern inline ccw1_t*
-tape_ccw_end(ccw1_t *ccw,__u8 cmd_code,__u16 memsize,void* cda,int ccw_count)
+
+static inline struct ccw1 *
+tape_ccw_cmd(struct ccw1 *ccw, __u8 cmd_code)
 {
-        return __ccwprep(ccw,cmd_code,0,memsize,cda,ccw_count);
+	ccw->cmd_code = cmd_code;
+	ccw->flags = 0;
+	ccw->count = 0;
+	ccw->cda = (__u32)(addr_t) &ccw->cmd_code;
+	return ccw + 1;
+}
+
+static inline struct ccw1 *
+tape_ccw_repeat(struct ccw1 *ccw, __u8 cmd_code, int count)
+{
+	while (count-- > 0) {
+		ccw->cmd_code = cmd_code;
+		ccw->flags = CCW_FLAG_CC;
+		ccw->count = 0;
+		ccw->cda = (__u32)(addr_t) &ccw->cmd_code;
+		ccw++;
+	}
+	return ccw;
 }
 
-extern inline ccw1_t*
-tape_ccw_cc_idal(ccw1_t *ccw,__u8 cmd_code,idalbuf_t* idal)
+static inline struct ccw1 *
+tape_ccw_cc_idal(struct ccw1 *ccw, __u8 cmd_code, struct idal_buffer *idal)
 {
 	ccw->cmd_code = cmd_code;
 	ccw->flags    = CCW_FLAG_CC;
-	idalbuf_set_normalized_cda(ccw,idal);
+	idal_buffer_set_cda(idal, ccw);
 	return ccw++;
 }
 
-extern inline ccw1_t*
-tape_ccw_end_idal(ccw1_t *ccw,__u8 cmd_code,idalbuf_t* idal)
+static inline struct ccw1 *
+tape_ccw_end_idal(struct ccw1 *ccw, __u8 cmd_code, struct idal_buffer *idal)
 {
-        ccw->cmd_code = cmd_code;
-        ccw->flags    = 0;
-        idalbuf_set_normalized_cda(ccw,idal);
-        return ccw++;
+	ccw->cmd_code = cmd_code;
+	ccw->flags    = 0;
+	idal_buffer_set_cda(idal, ccw);
+	return ccw++;
 }
 
 /* Global vars */
-extern const char* tape_state_verbose[TS_SIZE];
-extern const char* tape_op_verbose[TO_SIZE];
-
-/* Some linked lists for storing plugins and devices */
-extern tape_dev_t *tape_first_dev;
-extern tape_frontend_t *tape_first_front;
+extern const char *tape_state_verbose[];
+extern const char *tape_op_verbose[];
 
 #endif /* for ifdef tape.h */
diff -Nru a/drivers/s390/char/tape3480.c b/drivers/s390/char/tape3480.c
--- a/drivers/s390/char/tape3480.c	Mon Dec  9 18:46:34 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,96 +0,0 @@
-/***************************************************************************
- *
- *  drivers/s390/char/tape3480.c
- *    tape device discipline for 3480 tapes.
- *
- *  S390 and zSeries version
- *    Copyright (C) 2001 IBM Corporation
- *    Author(s): Carsten Otte <cotte@de.ibm.com>
- *               Tuan Ngo-Anh <ngoanh@de.ibm.com>
- * 
- ****************************************************************************
- */
-
-#include "tapedefs.h"
-#include <linux/version.h>
-#include <linux/compatmac.h>
-#include "tape.h"
-#include "tape34xx.h"
-#include "tape3480.h"
-
-#ifdef CONFIG_S390_TAPE_3480_MODULE
-static tape_discipline_t* disc;
-
-void
-init_module(void)
-{
-        disc = tape3480_init();
-        if (disc!= NULL) 
-		tape_register_discipline(disc);
-}
-
-void
-cleanup_module(void)
-{
-	if (disc!=NULL){
-		tape_unregister_discipline(disc);
-		kfree(disc);
-	}
-}
-#endif /* CONFIG_S390_TAPE_3480_MODULE */
-
-int
-tape3480_setup_device(tape_dev_t * td)
-{
-	tape3480_disc_data_t *data = NULL;
-	tape_sprintf_event (tape_dbf_area,6,"3480 dsetup:  %x\n",td->first_minor);
-	data = kmalloc (sizeof (tape3480_disc_data_t), GFP_KERNEL | GFP_DMA);
-	if(data == NULL)
-		return -1;
-	data->modeset_byte = 0x00;
-	td->discdata = (void *) data;
-	return 0;
-}
-
-void
-tape3480_cleanup_device(tape_dev_t * td)
-{
-	if(td->discdata){
-		kfree(td->discdata);
-		td->discdata = NULL;
-	}
-}
-
-void
-tape3480_shutdown (void) {
-}
-
-tape_discipline_t *
-tape3480_init (void)
-{
-	tape_discipline_t *disc;
-	tape_sprintf_event (tape_dbf_area,3,"3480 init\n");
-	disc = kmalloc (sizeof (tape_discipline_t), GFP_ATOMIC);
-	if (disc == NULL) {
-	        tape_sprintf_exception (tape_dbf_area,3,"disc:nomem\n");
-		return disc;
-	}
-	disc->owner = THIS_MODULE;
-	disc->cu_type = 0x3480;
-	disc->setup_device = tape3480_setup_device;
-	disc->cleanup_device = tape3480_cleanup_device;
-	disc->init_device = NULL;
-	disc->process_eov = tape34xx_process_eov;
-	disc->irq = tape34xx_irq;
-	disc->write_block = tape34xx_write_block;
-	disc->read_block = tape34xx_read_block;
-	disc->ioctl = tape34xx_ioctl;
-	disc->shutdown = tape3480_shutdown;
-	disc->discipline_ioctl_overload = tape34xx_ioctl_overload;
-	disc->bread = tape34xx_bread;
-	disc->free_bread = tape34xx_free_bread;
-	disc->bread_enable_locate = tape34xx_bread_enable_locate;
-	disc->next = NULL;
-	tape_sprintf_event (tape_dbf_area,3,"3480 regis\n");
-	return disc;
-}
diff -Nru a/drivers/s390/char/tape3480.h b/drivers/s390/char/tape3480.h
--- a/drivers/s390/char/tape3480.h	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,23 +0,0 @@
-/***************************************************************************
- *
- *  drivers/s390/char/tape3480.h
- *    tape device discipline for 3480 tapes.
- *
- *  S390 and zSeries version
- *    Copyright (C) 2001 IBM Corporation
- *    Author(s): Carsten Otte <cotte@de.ibm.com>
- *               Tuan Ngo-Anh <ngoanh@de.ibm.com>
- *
- ****************************************************************************
- */
-
-#ifndef _TAPE3480_H
-
-#define _TAPE3480_H
-
-
-typedef struct _tape3480_disc_data_t {
-    __u8 modeset_byte;
-} tape3480_disc_data_t  __attribute__ ((packed, aligned(8)));
-tape_discipline_t * tape3480_init (void);
-#endif // _TAPE3480_H
diff -Nru a/drivers/s390/char/tape3490.c b/drivers/s390/char/tape3490.c
--- a/drivers/s390/char/tape3490.c	Mon Dec  9 18:46:51 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,97 +0,0 @@
-/***************************************************************************
- *
- *  drivers/s390/char/tape3490.c
- *    tape device discipline for 3490E tapes.
- *
- *  S390 and zSeries version
- *    Copyright (C) 2001 IBM Corporation
- *    Author(s): Carsten Otte <cotte@de.ibm.com>
- *               Tuan Ngo-Anh <ngoanh@de.ibm.com>
- *
- ****************************************************************************
- */
-
-#include "tapedefs.h"
-#include <linux/version.h>
-#include <linux/compatmac.h>
-#include "tape.h"
-#include "tape34xx.h"
-#include "tape3490.h"
-
-#ifdef CONFIG_S390_TAPE_3490_MODULE 
-static tape_discipline_t* disc;
-
-void
-init_module(void)
-{
-        disc = tape3490_init();
-	if (disc!=NULL) 
-		tape_register_discipline(disc);
-}
- 
-void
-cleanup_module(void)
-{
-	if (disc!=NULL){
-		tape_unregister_discipline(disc);
-		kfree(disc);
-	}
-}
-#endif /* CONFIG_S390_TAPE_3490_MODULE */
-
-int
-tape3490_setup_device (tape_dev_t * td)
-{
-	tape3490_disc_data_t *data = NULL;
-	tape_sprintf_event (tape_dbf_area,1,"3490 dsetup: %x\n",td->first_minor);
-	data = kmalloc (sizeof (tape3490_disc_data_t), GFP_KERNEL | GFP_DMA);
-	if(data == NULL)
-		return -1;
-	data->modeset_byte = 0x00;
-	td->discdata = (void *) data;
-	return 0;
-}
-
-void
-tape3490_cleanup_device(tape_dev_t * td)
-{
-	if(td->discdata){
-		kfree(td->discdata);
-		td->discdata = NULL;
-	}
-}
-
-void
-tape3490_shutdown (void) {
-}
-
-
-tape_discipline_t *
-tape3490_init (void)
-{
-	tape_discipline_t *disc;
-	tape_sprintf_event (tape_dbf_area,3,"3490 init\n");
-	disc = kmalloc (sizeof (tape_discipline_t), GFP_ATOMIC);
-	if (disc == NULL) {
-	        tape_sprintf_exception (tape_dbf_area,3,"disc:nomem\n");
-		return disc;
-	}
-	disc->owner = THIS_MODULE;
-	disc->cu_type = 0x3490;
-	disc->setup_device = tape3490_setup_device;
-	disc->cleanup_device = tape3490_cleanup_device;
-	disc->init_device = NULL;
-	disc->process_eov = tape34xx_process_eov;
-	disc->irq = tape34xx_irq;
-	disc->write_block = tape34xx_write_block;
-	disc->read_block = tape34xx_read_block;
-	disc->ioctl = tape34xx_ioctl;
-	disc->shutdown = tape3490_shutdown;
-	disc->discipline_ioctl_overload = tape34xx_ioctl_overload;
-	disc->bread = tape34xx_bread;
-	disc->free_bread = tape34xx_free_bread;
-	disc->bread_enable_locate = tape34xx_bread_enable_locate;
-	disc->next = NULL;
-	tape_sprintf_event (tape_dbf_area,3,"3490 regis\n");
-	return disc;
-}
diff -Nru a/drivers/s390/char/tape3490.h b/drivers/s390/char/tape3490.h
--- a/drivers/s390/char/tape3490.h	Mon Dec  9 18:46:52 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,23 +0,0 @@
-/***************************************************************************
- *
- *  drivers/s390/char/tape3490.h
- *    tape device discipline for 3490E tapes.
- *
- *  S390 and zSeries version
- *    Copyright (C) 2001 IBM Corporation
- *    Author(s): Carsten Otte <cotte@de.ibm.com>
- *               Tuan Ngo-Anh <ngoanh@de.ibm.com>
- *
- ****************************************************************************
- */
-
-#ifndef _TAPE3490_H
-
-#define _TAPE3490_H
-
-
-typedef struct _tape3490_disc_data_t {
-    __u8 modeset_byte;
-} tape3490_disc_data_t  __attribute__ ((packed, aligned(8)));
-tape_discipline_t * tape3490_init (void);
-#endif // _TAPE3490_H
diff -Nru a/drivers/s390/char/tape34xx.c b/drivers/s390/char/tape34xx.c
--- a/drivers/s390/char/tape34xx.c	Mon Dec  9 18:46:34 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1254 +0,0 @@
-/***************************************************************************
- *
- *  drivers/s390/char/tape34xx.c
- *    common tape device discipline for 34xx tapes.
- *
- *  S390 and zSeries version
- *    Copyright (C) 2001 IBM Corporation
- *    Author(s): Carsten Otte <cotte@de.ibm.com>
- *               Michael Holzheu <holzheu@de.ibm.com>
- *               Tuan Ngo-Anh <ngoanh@de.ibm.com>
- *
- ****************************************************************************
- */
-
-#include "tapedefs.h"
-#include <linux/config.h>
-#include <linux/version.h>
-#include <linux/stddef.h>
-#include <linux/kernel.h>
-#include <asm/types.h>
-#include <linux/compatmac.h>
-#include "tape.h"
-#include "tape34xx.h"
-#include <asm/idals.h>
-#include <asm/ebcdic.h>
-#include <asm/tape390.h>
-
-#define PRINTK_HEADER "T3xxx:"
-
-/*
- * Done Handler is called when dev stat = DEVICE-END (successfull operation)
- */
-
-void tape34xx_done_handler(tape_dev_t* td)
-{
-	__u8 *data = NULL;
-	int i;
-	tape_ccw_req_t *treq = tape_get_active_ccw_req(td);
-
-	tape_sprintf_event (tape_dbf_area,6,"%s\n",tape_op_verbose[treq->op]);
-	tape_sprintf_event (tape_dbf_area,6,"done\n");
-
-	treq->rc = 0;
-	switch(treq->op){
-		case TO_BSB:
-		case TO_BSF:
-		case TO_DSE:
-		case TO_FSB:
-		case TO_FSF:
-		case TO_LBL:
-		case TO_RFO:
-		case TO_RBA:
-		case TO_REW:
-		case TO_WRI:
-		case TO_WTM: 
-		case TO_BLOCK:
-		case TO_LOAD:
-	        case TO_DIS:
-			tape_med_state_set(td,MS_LOADED);
-			break;
-		case TO_NOP:
-			break;
-		case TO_RUN:
-			tape_med_state_set(td,MS_UNLOADED);
-                        break;
-		case TO_RBI:
-			data = treq->kernbuf;
-			tape_sprintf_event (tape_dbf_area,6,"data: %04x %04x\n",*((unsigned int*)&data[0]),*((unsigned int*)&data[4]));
-			i = 0;
-			i = data[3];
-			i += 256 * data[2];
-			i += 65536 * (data[1] & 0x3F);
-			memcpy(data,&i,4);
-			tape_med_state_set(td,MS_LOADED);
-			break;
-		default:
-			tape_sprintf_exception (tape_dbf_area,3,"TE UNEXPEC\n");
-			tape34xx_default_handler (td);
-			return;
-	}
-	
-	if(treq->wakeup)
-		treq->wakeup (treq);
-	return;
-}
-
-/*
- * This function is called, when no request is outstanding and we get an
- * interrupt
- */
-
-void tape34xx_unsolicited_irq(tape_dev_t* td)
-{
-	if(td->devstat.dstat == 0x85 /* READY */) {
-		// A medium was inserted in the drive!
-		tape_sprintf_event (tape_dbf_area,6,"xuud med\n");
-		tape_med_state_set(td,MS_LOADED);
-	} else {
-		tape_sprintf_event (tape_dbf_area,3,"unsol.irq! dev end: %x\n",td->devinfo.irq);
-		PRINT_WARN ("Unsolicited IRQ (Device End) caught.\n");
-		tape_dump_sense (td);
-        }
-}
-
-
-/*
- * tape34xx_display 
- */
-
-int
-tape34xx_display (tape_dev_t* td, unsigned long arg)
-{
-        struct display_struct d_struct;
-        tape_ccw_req_t *treq = NULL;
-        ccw1_t *ccw = NULL;
-        int ds = 17;           /* datasize  */
-        int ccw_cnt = 2;       /* ccw count */
-        int op = TO_DIS;       /* tape operation */
-        int i = 0, rc = -1;
-
-        rc = copy_from_user(&d_struct, (char *)arg, sizeof(d_struct));
-        if (rc != 0)
-                goto error;
-
-        treq=tape_alloc_ccw_req(ccw_cnt, ds, 0, op);
-        if (!treq)
-	        goto error;
-
-        ((unsigned char *)treq->kernbuf)[0] = d_struct.cntrl;
-
-        for (i = 0; i < 8; i++) {
-                ((unsigned char *)treq->kernbuf)[i+1] = d_struct.message1[i];
-                ((unsigned char *)treq->kernbuf)[i+9] = d_struct.message2[i];
-        }
-
-        ASCEBC (((unsigned char*)treq->kernbuf) + 1, 16);
-
-        ccw = treq->cpaddr;
-        ccw = tape_ccw_cc(ccw, LOAD_DISPLAY, 17, treq->kernbuf, 1);
-        ccw = tape_ccw_end(ccw,NOP,0,0,1);
-
-        tape_do_io_and_wait(td,treq,TAPE_WAIT_INTERRUPTIBLE);
-    
-        tape_free_ccw_req(treq);
-
-        return(0);
-
- error:
-	return -EINVAL;
-
-}
-
-
-/*
- * ioctl_overload 
- */
-
-int
-tape34xx_ioctl_overload (tape_dev_t* td, unsigned int cmd, unsigned long arg)
-{
-        if (cmd == TAPE390_DISPLAY)
-	        return tape34xx_display(td, arg);
-	else
-                return -EINVAL;		// no additional ioctls
-}
-
-
-/*******************************************************************
- * Request creating functions:
- *******************************************************************/
-
-/*
- * 34xx IOCTLS
- *
- * MTFSF: Forward space over 'count' file marks. The tape is positioned
- * at the EOT (End of Tape) side of the file mark.
- *
- * MTBSF: Backward space over 'count' file marks. The tape is positioned at
- * the EOT (End of Tape) side of the last skipped file mark.
- *
- * MTFSR: Forward space over 'count' tape blocks (blocksize is set
- * via MTSETBLK.
- *
- * MTBSR: Backward space over 'count' tape blocks.
- * (blocksize is set via MTSETBLK.
- *
- * MTWEOF: Write 'count' file marks at the current position.
- *
- * MTREW: Rewind the tape.
- *
- * MTOFFL: Rewind the tape and put the drive off-line.
- * Implement 'rewind unload'
- *
- * MTNOP: 'No operation'.
- *
- * MTBSFM: Backward space over 'count' file marks.
- * The tape is positioned at the BOT (Begin Of Tape) side of the
- * last skipped file mark.
- *
- * MTFSFM: Forward space over 'count' file marks.
- * The tape is positioned at the BOT (Begin Of Tape) side
- * of the last skipped file mark.
- *
- * MTEOM: positions at the end of the portion of the tape already used
- * for recordind data. MTEOM positions after the last file mark, ready for
- * appending another file.
- * MTRETEN: Retension the tape, i.e. forward space to end of tape and rewind.
- *
- * MTERASE: erases the tape.
- *
- * MTSETDENSITY: set tape density.
- *
- * MTSEEK: seek to the specified block.
- *
- * MTTELL: Tell block. Return the number of block relative to current file.
- *
- * MTSETDRVBUFFER: Set the tape drive buffer code to number.
- * Implement NOP.
- *
- * MTLOCK: Locks the tape drive door.
- * Implement NOP CCW command.
- *
- * MTUNLOCK: Unlocks the tape drive door.
- * Implement the NOP CCW command.
- *
- * MTLOAD: Loads the tape.
- * This function is not implemented and returns NULL, which causes the
- * Frontend to wait for a medium being loaded.
- * The 3480/3490 type Tapes do not support a load command
- *
- * MTUNLOAD: Rewind the tape and unload it.
- *
- * MTCOMPRESSION: used to enable compression.
- * Sets the IDRC on/off.
- *
- * MTSTPART: Move the tape head at the partition with the number 'count'.
- * Implement the NOP CCW command.
- *
- * MTMKPART: .... dummy .
- * Implement the NOP CCW command.
- *
- * MTIOCGET: query the tape drive status.
- *
- * MTIOCPOS: query the tape position.
- *
- */ 
-
-tape_ccw_req_t *
-tape34xx_ioctl(tape_dev_t* td, int mtcmd,int count, int* rc)
-{
-	tape_ccw_req_t *treq = NULL;
-        ccw1_t *ccw = NULL;
-	int ds = 0;   /* datasize  */
-	int ccw_cnt;  /* ccw count */
-	int op = -1;  /* tape operation */
-
-	tape_sprintf_event(tape_dbf_area,6,"34xxioctl: op(%x) count(%x)\n",mtcmd,count);
-	/* Preprocessing */
-
-	switch(mtcmd){
-		case MTLOAD:   *rc = -EINVAL; goto error;
-		case MTIOCGET: *rc = -EINVAL; goto error;
-		case MTIOCPOS: *rc = -EINVAL; goto error;
-
-		case MTFSF:          op=TO_FSF; ccw_cnt=count+2; ds=0; break;
-		case MTBSF:          op=TO_BSF; ccw_cnt=count+2; ds=0; break;
-		case MTFSR:          op=TO_FSB; ccw_cnt=count+2; ds=0; break;
-		case MTBSR:          op=TO_BSB; ccw_cnt=count+2; ds=0; break;
-		case MTWEOF:         op=TO_WTM; ccw_cnt=count+2; ds=0; break;
-		case MTREW:          op=TO_REW; ccw_cnt=3;       ds=0; break;
-		case MTOFFL:         op=TO_RUN; ccw_cnt=3;       ds=0; break;
-		case MTNOP:          op=TO_NOP; ccw_cnt=2;       ds=0; break; 
-		case MTBSFM:         op=TO_BSF; ccw_cnt=count+2; ds=0; break;
-		case MTFSFM:         op=TO_FSF; ccw_cnt=count+2; ds=0; break;
-		case MTEOM:          op=TO_FSF; ccw_cnt=4;       ds=0; break;
-		case MTERASE:        op=TO_DSE; ccw_cnt=5;       ds=0; break;
-		case MTSETDENSITY:   op=TO_NOP; ccw_cnt=3;       ds=0; break;
-		case MTSEEK:         op=TO_LBL; ccw_cnt=3;       ds=4; break;
-		case MTTELL:         op=TO_RBI; ccw_cnt=3;       ds=8; break;
-		case MTSETDRVBUFFER: op=TO_NOP; ccw_cnt=3;       ds=0; break;
-		case MTLOCK:         op=TO_NOP; ccw_cnt=3;       ds=0; break;
-		case MTUNLOCK:       op=TO_NOP; ccw_cnt=3;       ds=0; break;
-		case MTUNLOAD:       op=TO_RUN; ccw_cnt=3;       ds=32; break;
-		case MTCOMPRESSION:  op=TO_NOP; ccw_cnt=3;       ds=0; break;
-		case MTSETPART:      op=TO_NOP; ccw_cnt=3;       ds=0; break;
-		case MTMKPART:       op=TO_NOP; ccw_cnt=3;       ds=0; break;
-		default:
-			PRINT_ERR( "IOCTL %x not implemented\n",op );
-			*rc = -EINVAL;
-			goto error;
-	}
-
-	if (ccw_cnt > 510) {
-		tape_sprintf_exception (tape_dbf_area,6,"wrng parm\n");
-		*rc = -EINVAL;
-		goto error;
-	}
-
-	treq=tape_alloc_ccw_req(ccw_cnt,ds,0,op);
-        if (!treq){
-		*rc = -ENOSPC;
-                goto error;
-	}
-	ccw = treq->cpaddr;
-
-	/* setup first ccw */
-	ccw = tape_ccw_cc(ccw,MODE_SET_DB,1,&MOD_BYTE,1);
-
-	/* setup middle ccw(s) */
-
-	switch(mtcmd){
-		case MTFSF:
-                	ccw = tape_ccw_cc(ccw,FORSPACEFILE,0,0,count);
-			break;
-		case MTBSF:
-			ccw = tape_ccw_cc(ccw,BACKSPACEFILE,0,0,count);
-			break;
-		case MTFSR:
-			ccw = tape_ccw_cc(ccw,FORSPACEBLOCK,0,0,count);
-			break;
-		case MTBSR:
-			ccw = tape_ccw_cc(ccw,BACKSPACEBLOCK,0,0,count);
-			break;
-		case MTWEOF:
-			ccw = tape_ccw_cc(ccw,WRITETAPEMARK,0,0,count); // this operation does _always_ write only one tape mark :(
-			break;
-		case MTREW:
-			ccw = tape_ccw_cc(ccw,REWIND,0,0,1);
-			break;
-		case MTOFFL:
-			ccw = tape_ccw_cc(ccw,REWIND_UNLOAD,0,0,1);
-			break;
-		case MTUNLOCK:
-		case MTLOCK:
-		case MTSETDRVBUFFER:
-		case MTSETDENSITY:
-		case MTSETPART:
-		case MTMKPART:
-		case MTNOP:
-			ccw = tape_ccw_cc(ccw,NOP,0,0,1);
-			break;
-		case MTBSFM:
-			ccw = tape_ccw_cc(ccw,BACKSPACEFILE,0,0,count);
-			break;
-		case MTFSFM:
-			ccw = tape_ccw_cc(ccw,FORSPACEFILE,0,0,count);
-			break;
-		case MTEOM:
-			ccw = tape_ccw_cc(ccw,FORSPACEFILE,0,0,1);
-			ccw = tape_ccw_cc(ccw,NOP,0,0,1);
-			break;
-		case MTERASE:
-			ccw = tape_ccw_cc(ccw,REWIND,0,0,1);
-			ccw = tape_ccw_cc(ccw,ERASE_GAP,0,0,1);
-			ccw = tape_ccw_cc(ccw,DATA_SEC_ERASE,0,0,1);
-			break;
-		case MTTELL:
-			ccw = tape_ccw_cc(ccw,READ_BLOCK_ID,8,treq->kernbuf,1);
-			break;
-		case MTUNLOAD:
-			ccw = tape_ccw_cc(ccw,REWIND_UNLOAD,0,0,1);
-			break;
-		case MTCOMPRESSION:
-			if((count < 0) || (count > 1)){
-				tape_sprintf_exception (tape_dbf_area,6,"xcom parm\n");
-				goto error;
-			}
-			if(count == 0){
-				PRINT_INFO( "(%x) Compression switched off\n", td->devstat.devno);
-				MOD_BYTE = 0x00; // IDRC off
-			} else {
-				PRINT_INFO( "(%x) Compression switched on\n", td->devstat.devno);
-				MOD_BYTE = 0x08; // IDRC on
-			}
-			ccw = tape_ccw_cc(ccw,NOP,0,0,1);
-			break; // Modset does the job
-		case MTSEEK:
-			{
-			__u8* data = treq->kernbuf;
-			data[0] = 0x01;
-			data[1] = data[2] = data[3] = 0x00;
-			if (count >= 4194304){
-				tape_sprintf_exception(tape_dbf_area,6,"xsee parm\n");
-				*rc = -EINVAL;
-				goto error;
-			}
-			if(MOD_BYTE && 0x08)
-				data[1] = data[1] | 0x80;
-
-			data[3] += count % 256;
-			data[2] += (count / 256) % 256;
-			data[1] += (count / 65536);
-			ccw = tape_ccw_cc(ccw,LOCATE,4,treq->kernbuf,1);
-			break;
-			}
-		default:
-			PRINT_WARN( "IOCTL %x not implemented\n",op );
-			*rc = -EINVAL;
-			goto error;
-
-        }
-
-	/* setup last ccw */
-
-	switch(mtcmd){
-		case MTEOM:
-			ccw = tape_ccw_end(ccw,CCW_CMD_TIC,0,treq->cpaddr,1);
-			break;
-		case MTUNLOAD:
-			ccw = tape_ccw_end(ccw,SENSE,32,treq->kernbuf,1);
-			break;
-		default:
-			ccw = tape_ccw_end(ccw,NOP,0,0,1);
-			break;
-	}
-	*rc = 0;
-	return treq;
-error:
-	if (treq)
-	        tape_free_ccw_req(treq);
-	return NULL;
-}
-
-/*
- * Write Block 
- */
-
-tape_ccw_req_t *
-tape34xx_write_block (const char *data, size_t count, tape_dev_t* td)
-{
-	tape_ccw_req_t *treq = NULL;
-	ccw1_t *ccw;
-	treq = tape_alloc_ccw_req (2, 0, count,TO_WRI);
-	if (!treq)
-		goto error;
-	if (idalbuf_copy_from_user (treq->idal_buf, data, count)) {
-	        tape_sprintf_exception (tape_dbf_area,6,"xwbl segf.\n");
-		goto error;
-	}
-	ccw = treq->cpaddr;
-	ccw = tape_ccw_cc(ccw,MODE_SET_DB,1,&MOD_BYTE,1);
-	ccw = tape_ccw_end_idal(ccw,WRITE_CMD,treq->idal_buf);
-	treq->userbuf = (void *) data;
-	tape_sprintf_event (tape_dbf_area,6,"xwbl ccwg\n");
-	return treq;
-error:
-	tape_sprintf_exception (tape_dbf_area,6,"xwbl fail\n");
-	if (treq)
-	        tape_free_ccw_req(treq);
-	return NULL;
-}
-
-/*
- * Read Block
- */
-
-tape_ccw_req_t *
-tape34xx_read_block (const char *data, size_t count, tape_dev_t* td)
-{
-	tape_ccw_req_t *treq = NULL;
-	ccw1_t *ccw;
-	/* we have to alloc 4 ccws in order to be able to transform request */
-	/* into a read backward request in error case                       */
-	treq = tape_alloc_ccw_req (4, 0, count,TO_RFO);
-	if (!treq) 
-		goto error;
-	treq->userbuf = (void*)data;
-	treq->userbuf_size = count;
-	ccw = treq->cpaddr;
-	ccw = tape_ccw_cc(ccw,MODE_SET_DB,1,&MOD_BYTE,1);
-	ccw = tape_ccw_end_idal(ccw,READ_FORWARD,treq->idal_buf);
-	tape_sprintf_event (tape_dbf_area,6,"xrbl ccwg\n");
-	return treq;
-error:
-	tape_sprintf_exception (tape_dbf_area,6,"xrbl fail");
-	if (treq)
-	        tape_free_ccw_req(treq);
-	return NULL;
-}
-
-/*
- * Read Opposite Error Recovery Function:
- * Used, when Read Forward does not work
- */
-
-tape_ccw_req_t *
-tape34xx_read_opposite (tape_dev_t* td)
-{
-	ccw1_t *ccw;
-	tape_ccw_req_t* treq = tape_get_active_ccw_req(td);
-	if (treq==NULL) // no request to recover?
-		BUG();
-
-	// transform read forward request into read backward request.
-	ccw = treq->cpaddr;
-	ccw = tape_ccw_cc(ccw,MODE_SET_DB,1,&MOD_BYTE,1);
-	ccw = tape_ccw_cc_idal(ccw,READ_BACKWARD,treq->idal_buf);
-	ccw = tape_ccw_cc(ccw,FORSPACEBLOCK,0,0,1);
-	ccw = tape_ccw_end(ccw,NOP,0,0,1);
-	treq->op = TO_RBA;
-	tape_sprintf_event (tape_dbf_area,6,"xrop ccwg");
-	return treq;
-}
-
-/*
- * Tape Block READ
- */
-
-tape_ccw_req_t * tape34xx_bread (struct request *req,tape_dev_t* td,int tapeblock_major) {
-	tape_ccw_req_t *treq;
-	ccw1_t *ccw;
-	__u8 *data;
-	int s2b = blksize_size[tapeblock_major][td->first_minor]/hardsect_size[tapeblock_major][td->first_minor];
-	int realcount = 0;
-	int size,bhct = 0;
-	struct buffer_head* bh;
-	for (bh = req->bh; bh; bh = bh->b_reqnext) {
-		if (bh->b_size > blksize_size[tapeblock_major][td->first_minor])
-			for (size = 0; size < bh->b_size; size += blksize_size[tapeblock_major][td->first_minor])
-				bhct++;
-		else
-			bhct++;
-	}
-	tape_sprintf_event (tape_dbf_area,6,"xBREDid:");
-	treq = tape_alloc_ccw_req (2+bhct+1, 4,0,TO_BLOCK);
-	if (!treq) {
-		tape_sprintf_exception (tape_dbf_area,6,"xBREDnomem\n");
-                goto error;
-        }
-
-	data = treq->kernbuf;
-	data[0] = 0x01;
-	data[1] = data[2] = data[3] = 0x00;
-	realcount=req->sector/s2b;
-	if (MOD_BYTE & 0x08)	// IDRC on
-		data[1] = data[1] | 0x80;
-	data[3] += realcount % 256;
-	data[2] += (realcount / 256) % 256;
-	data[1] += (realcount / 65536);
-	tape_sprintf_event (tape_dbf_area,6,"realcount = %i\n",realcount);
-
-	ccw = treq->cpaddr;
-	ccw = tape_ccw_cc(ccw,MODE_SET_DB,1,&MOD_BYTE,1);
-	if (realcount!=td->blk_data.position)
-		ccw = tape_ccw_cc(ccw,LOCATE,4,treq->kernbuf,1);
-	else
-		ccw = tape_ccw_cc(ccw,NOP,0,0,1);
-	td->blk_data.position=realcount+req->nr_sectors/s2b;
-	for (bh=req->bh;bh!=NULL;) {
-		if (bh->b_size >= blksize_size[tapeblock_major][td->first_minor]) {
-			for (size = 0; size < bh->b_size; size += blksize_size[tapeblock_major][td->first_minor]){
-				ccw->flags = CCW_FLAG_CC;
-				ccw->cmd_code = READ_FORWARD;
-				ccw->count = blksize_size[tapeblock_major][td->first_minor];
-				set_normalized_cda(ccw,__pa(bh->b_data+size));
-				ccw++;
-			}
-			bh = bh->b_reqnext;
-		} else {	/* group N bhs to fit into byt_per_blk */
-		    BUG();
-		}
-	}
-	ccw = tape_ccw_end(ccw,NOP,0,0,1);
-	tape_sprintf_event (tape_dbf_area,6,"xBREDccwg\n");
-	return treq;
-error:
-	tape_sprintf_exception (tape_dbf_area,6,"xBREDccwg fail");
-	if (treq)
-	        tape_free_ccw_req(treq);
-	return NULL;
-}
-
-void tape34xx_free_bread (tape_ccw_req_t* treq) {
-	ccw1_t* ccw;
-	for (ccw=(ccw1_t*)treq->cpaddr;ccw->flags & CCW_FLAG_CC;ccw++)
-	if (ccw->cmd_code == READ_FORWARD)
-		clear_normalized_cda(ccw);
-	tape_free_ccw_req(treq); 
-}
-
-// FIXME: Comment?
-
-void tape34xx_bread_enable_locate (tape_ccw_req_t * treq) {
-	ccw1_t *ccw;
-	if (treq==NULL) BUG();
-	ccw=treq->cpaddr;
-	ccw++;
-	ccw = tape_ccw_cc(ccw,LOCATE,4,treq->kernbuf,1);
-	return;
-}
-
-/*******************************************************************
- * Event Handlers
- *******************************************************************/
-
-/*
- * Default Handler is called, when an unexpected IRQ comes in
- */
-
-void
-tape34xx_default_handler (tape_dev_t * td)
-{
-	tape_ccw_req_t* treq = tape_get_active_ccw_req(td);
-	tape_sprintf_event (tape_dbf_area,6,"xdefhandle\n");
-	PRINT_ERR ("TAPE34XX: An unexpected Unit Check occurred.\n");
-	PRINT_ERR ("TAPE34XX: Please read Documentation/s390/TAPE and report it!\n");
-	PRINT_ERR ("TAPE34XX: Current op is: %s",tape_op_verbose[treq->op]);
-	tape_dump_sense (td);
-	treq->rc = -EIO;
-	if(treq->wakeup)
-		treq->wakeup (treq);
-}
-
-/* This function analyses the tape's sense-data in case of a unit-check. */
-/* If possible, it tries to recover from the error. Else the user is */ 
-/* informed about the problem.  */
-
-void
-tape34xx_error_recovery (tape_dev_t* td)
-{
-    __u8* sense=td->devstat.ii.sense.data;
-    int inhibit_cu_recovery=0;
-    int cu_type=td->discipline->cu_type;
-    tape_ccw_req_t *treq = tape_get_active_ccw_req(td);
-
-    if (treq==NULL) {
-	    // Nothing to recover! Why call me?
-	    BUG();
-    }
-    if (MOD_BYTE&0x80) inhibit_cu_recovery=1;
-    if (treq->op==TO_BLOCK) {
-	// no recovery for block device, bottom half will retry...
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    }
-    if (sense[0]&SENSE_COMMAND_REJECT)
-	switch (treq->op) {
-	case TO_DSE:
-	case TO_EGA:
-	case TO_WRI:
-	case TO_WTM:
-	    if (sense[1]&SENSE_WRITE_PROTECT) {
-		// trying to write, but medium is write protected
-		tape34xx_error_recovery_has_failed(td,EACCES);
-		return;
-	    }
-	default:
-	    tape34xx_error_recovery_HWBUG(td,1);
-	    return;
-	}
-    // special cases for various tape-states when reaching end of recorded area
-    if (((sense[0]==0x08) || (sense[0]==0x10) || (sense[0]==0x12)) &&
-	((sense[1]==0x40) || (sense[1]==0x0c)))
-	switch (treq->op) {
-	case TO_FSF:
-	    // Trying to seek beyond end of recorded area
-	    tape34xx_error_recovery_has_failed(td,EIO);
-	    return;
-	case TO_LBL:
-	    // Block could not be located.
-	    tape34xx_error_recovery_has_failed(td,EIO);
-	    return;
-	case TO_RFO:
-	    // Try to read beyond end of recorded area -> 0 bytes read
-	    tape34xx_error_recovery_has_failed(td,0);
-	    return;
-	default:
-            PRINT_ERR("Invalid op in %s:%i\n",__FUNCTION__,__LINE__);
-            tape34xx_error_recovery_has_failed(td,0);
-            return;
-	}
-    // Sensing special bits
-    if (sense[0]&SENSE_BUS_OUT_CHECK) {
-	tape34xx_error_recovery_do_retry(td);
-	return;
-    }
-    if (sense[0]&SENSE_DATA_CHECK) {
-	// hardware failure, damaged tape or improper operating conditions
-	switch (sense[3]) {
-	case 0x23:
-	    // a read data check occurred
-	    if ((sense[2]&SENSE_TAPE_SYNC_MODE) ||
-		(inhibit_cu_recovery)) {
-		// data check is not permanent, may be recovered. 
-		// We always use async-mode with cu-recovery, so this should *never* happen.
-		tape34xx_error_recovery_HWBUG(td,2);
-		return;
-	    } else {
-		// data check is permanent, CU recovery has failed
-		PRINT_WARN("Permanent read error, recovery failed!\n");
-		tape34xx_error_recovery_has_failed(td,EIO);
-		return;
-	    }
-	case 0x25:
-	    // a write data check occurred
-	    if ((sense[2]&SENSE_TAPE_SYNC_MODE) ||
-		(inhibit_cu_recovery)) {
-		// data check is not permanent, may be recovered.
-		// We always use async-mode with cu-recovery, so this should *never* happen.
-		tape34xx_error_recovery_HWBUG(td,3);
-		return;
-	    } else {
-		// data check is permanent, cu-recovery has failed
-		PRINT_WARN("Permanent write error, recovery failed!\n");
-		tape34xx_error_recovery_has_failed(td,EIO);
-		return;
-	    }
-	case 0x26:
-	    // Data Check (read opposite) occurred. We'll recover this.
-	    tape34xx_error_recovery_read_opposite(td);
-	    return;
-	case 0x28:
-	    // The ID-Mark at the beginning of the tape could not be written. This is fatal, we'll report and exit.
-	    PRINT_WARN("ID-Mark could not be written. Check your hardware!\n");
-	    tape34xx_error_recovery_has_failed(td,EIO);
-	    return;
-	case 0x31:
-	    // Tape void. Tried to read beyond end of device. We'll report and exit.
-	    PRINT_WARN("Try to read beyond end of recorded area!\n");
-	    tape34xx_error_recovery_has_failed(td,ENOSPC);
-	    return;
-	case 0x41:
-	    // Record sequence error. cu detected incorrect block-id sequence on tape. We'll report and exit.
-	    PRINT_WARN("Illegal block-id sequence found!\n");
-	    tape34xx_error_recovery_has_failed(td,EIO);
-	    return;
-	    default:
-	    // well, all data checks for 3480 should result in one of the above erpa-codes. if not -> bug
-	    // On 3490, other data-check conditions do exist.
-		if (cu_type==0x3480) {
-		    tape34xx_error_recovery_HWBUG(td,4);
-		    return;
-		}
-	}
-    }
-    if (sense[0]&SENSE_OVERRUN) {
-	// A data overrun between cu and drive occurred. The channel speed is to slow! We'll report this and exit!
-	switch (sense[3]) {
-	case 0x40: // overrun error
-	    PRINT_WARN ("Data overrun error between control-unit and drive. Use a faster channel connection, if possible! \n");
-	    tape34xx_error_recovery_has_failed(td,EIO);
-	    return;
-	default:
-	    // Overrun bit is set, but erpa does not show overrun error. This is a bug.
-	    tape34xx_error_recovery_HWBUG(td,5);
-	    return;
-	}
-    }
-    if (sense[1]&SENSE_RECORD_SEQUENCE_ERR) {
-	switch (sense[3]) {
-	case 0x41:
-	    // Record sequence error. cu detected incorrect block-id sequence on tape. We'll report and exit.
-	    PRINT_WARN("Illegal block-id sequence found!\n");
-	    tape34xx_error_recovery_has_failed(td,EIO);
-	    return;
-	default:
-	    // Record sequence error bit is set, but erpa does not show record sequence error. This is a bug.
-	    tape34xx_error_recovery_HWBUG(td,6);
-	    return;
-	}
-    }
-    // Sensing erpa codes
-    switch (sense[3]) {
-    case 0x00:
-	// Everything is fine, but we got a unit check. Report and ignore!
-	PRINT_WARN ("Non-error sense was found. Unit-check will be ignored, expect errors...\n");
-	return;
-    case 0x21:
-	// Data streaming not operational. Cu switches to interlock mode, we reissue the command.
-	PRINT_WARN ("Data streaming not operational. Switching to interlock-mode! \n");
-	tape34xx_error_recovery_do_retry(td);
-	return;
-    case 0x22:
-	// Path equipment check. Might be drive adapter error, buffer error on the lower interface, internal path not useable, or error during cartridge load.
-	// All of the above are not recoverable
-	PRINT_WARN ("A path equipment check occurred. One of the following conditions occurred:\n");
-	PRINT_WARN ("drive adapter error,buffer error on the lower interface, internal path not useable, error during cartridge load.\n");
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    case 0x23:
-	// Read data check. Should have been be covered earlier -> Bug!
-	tape34xx_error_recovery_HWBUG(td,7);
-	return;
-    case 0x24:
-	// Load display check. Load display was command was issued, but the drive is displaying a drive check message. Can be threated as "device end".
-	tape34xx_error_recovery_succeded(td);
-	return;
-    case 0x25:
-	// Write data check. Should have been covered earlier -> Bug!
-	tape34xx_error_recovery_HWBUG(td,8);
-	return;
-    case 0x26:
-	// Data check (read opposite). Should have been covered earlier -> Bug!
-	tape34xx_error_recovery_HWBUG(td,9);
-	return;
-    case 0x27:
-	// Command reject. May indicate illegal channel program or buffer over/underrun. 
-	// Since all channel programms are issued by this driver and ought be correct,
-	// we assume a over/underrun situaltion and retry the channel program.
-	tape34xx_error_recovery_do_retry(td);
-	return;
-    case 0x28:
-	// Write id mark check. Should have beed covered earlier -> bug!
-	tape34xx_error_recovery_HWBUG(td,10);
-	return;
-    case 0x29:
-	// Function incompatible. Either idrc is on but hardware not capable doing idrc 
-	// or a perform subsystem func is issued and the cu is not online. Anyway, this 
-	// cannot be recovered and is an I/O error.
-	PRINT_WARN ("Function incompatible. Try to switch off idrc! \n");
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    case 0x2a:
-	// Unsolicited environmental data. An internal counter overflows, we can ignore
-	// this and reissue the cmd.
-	tape34xx_error_recovery_do_retry(td);
-	return;
-    case 0x2b:
-	// Environmental data present. Indicates either unload completed ok or read buffered 
-	// log command completed ok. 
-	if (treq->op==TO_RUN) {
-	    // Rewind unload completed ok.
-	    tape34xx_error_recovery_succeded(td);
-	    return;
-	}
-	// Since we do not issue read buffered log commands, this should never occur -> bug.
-	tape34xx_error_recovery_HWBUG(td,11);
-	return;
-    case 0x2c:
-	// Permanent equipment check. cu has tried recovery, but did not succeed. This is an
-	// I/O error.
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    case 0x2d:
-	// Data security erase failure.
-	if (treq->op==TO_DSE) {
-	    // report an I/O error
-	    tape34xx_error_recovery_has_failed(td,EIO);
-	    return;
-	}
-	// Data security erase failure, but no such command issued. This is a bug.
-	tape34xx_error_recovery_HWBUG(td,12);
-	return;
-    case 0x2e:
-	// Not capable. This indicates either that the drive fails reading the format id mark
-	// or that that format specified is not supported by the drive. We write a message and
-	// return an I/O error.
-	PRINT_WARN("Drive not capable processing the tape format!");
-	tape34xx_error_recovery_has_failed(td,EMEDIUMTYPE);
-	return;
-    case 0x2f:
-	// This erpa is reserved. This is a bug.
-	tape34xx_error_recovery_HWBUG(td,13);
-	return;
-    case 0x30:
-	// The medium is write protected, while trying to write on it. We'll report this.
-	PRINT_WARN("Medium is write protected!\n");
-	tape34xx_error_recovery_has_failed(td,EACCES);
-	return;
-    case 0x31:
-	// Tape void. Should have beed covered ealier -> bug
-	tape34xx_error_recovery_HWBUG(td,14);
-	return;
-    case 0x32:
-	// Tension loss. We cannot recover this, it's an I/O error.
-	PRINT_WARN("The drive lost tape tension.\n");
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    case 0x33:
-	// Load Failure. The catridge was not inserted correctly or the tape is not threaded
-	// correctly. We cannot recover this, the user has to reload the catridge.
-	PRINT_WARN("Cartridge load failure. Reload the cartridge and try again.\n");
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    case 0x34:
-	// Unload failure. The drive cannot maintain tape tension and control tape movement 
-	// during an unload operation. 
-	PRINT_WARN("Failure during cartridge unload. Please try manually.\n");
-	if (treq->op!=TO_RUN) {
-	    tape34xx_error_recovery_HWBUG(td,15);
-	    return;
-	}
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    case 0x35:
-	// Drive equipment check. One of the following:
-	// - cu cannot recover from a drive detected error
-	// - a check code message is displayed on drive message/load displays
-	// - the cartridge loader does not respond correctly
-	// - a failure occurs during an index, load, or unload cycle
-	PRINT_WARN("Equipment check! Please check the drive and the cartridge loader.\n");
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    case 0x36:
-	switch (cu_type) {
-	case 0x3480:
-	    // This erpa is reserved for 3480 -> BUG
-	    tape34xx_error_recovery_HWBUG(td,16);
-	    return;
-	case 0x3490:
-	    // End of data. This is a permanent I/O error, which cannot be recovered.
-	    // A read-type command has reached the end-of-data mark.
-	    tape34xx_error_recovery_has_failed(td,EIO);
-	    return;
-	}
-    case 0x37:
-	// Tape length error. The tape is shorter than reported in the beginning-of-tape data.
-	PRINT_WARN("Tape length error.\n");
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    case 0x38:
-	// Physical end of tape. A read/write operation reached the physical end of tape.
-        if (treq->op==TO_WRI ||
-            treq->op==TO_DSE ||
-            treq->op==TO_EGA ||
-            treq->op==TO_WTM){
-            tape34xx_error_recovery_has_failed(td,ENOSPC);
-        } else {
-            tape34xx_error_recovery_has_failed(td,EIO);
-        }
-        return;
-    case 0x39:
-	// Backward at BOT. The drive is at BOT and is requestet to move backward.
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    case 0x3a:
-	// Drive switched not ready, but the command needs the drive to be ready.
-	PRINT_WARN("Drive not ready. Turn the ready/not ready switch to ready position and try again.\n");
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    case 0x3b:
-	// Manual rewind or unload. This causes an I/O error.
-	PRINT_WARN("Medium was rewound or unloaded manually. Expect errors! Please do only use the mtoffl and mtrew ioctl to unload tapes or rewind tapes.\n");
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    case 0x3c:
-    case 0x3d:
-    case 0x3e:
-    case 0x3f:
-	// These erpas are reserved -> BUG
-	tape34xx_error_recovery_HWBUG(td,17);
-	return;
-    case 0x40:
-	// Overrun error. This should have been covered earlier -> bug.
-	tape34xx_error_recovery_HWBUG(td,18);
-	return;
-    case 0x41:
-	// Record sequence error. This should have been covered earlier -> bug.
-	tape34xx_error_recovery_HWBUG(td,19);
-	return;
-    case 0x42:
-	// Degraded mode. A condition that can cause degraded performace is detected.
-	PRINT_WARN("Subsystem is running in degraded mode. This may compromise your performace.\n");
-	tape34xx_error_recovery_do_retry(td);
-	return;
-    case 0x43:
-	// Drive not ready. Probably swith the ready/not ready switch to ready?
-	PRINT_WARN("The drive is not ready. Maybe no medium in?\n");
-	tape_med_state_set(td,MS_UNLOADED);
-	tape34xx_error_recovery_has_failed(td,ENOMEDIUM);
-	return;
-    case 0x44:
-	// Locate Block unsuccessfull. We'll report this.
-	if ((treq->op!=TO_BLOCK) &&
-	    (treq->op!=TO_LBL)) {
-	    tape34xx_error_recovery_HWBUG(td,20); // No locate block was issued...
-	    return;
-	}
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    case 0x45:
-	// The drive is assigned elsewhere [to a different channel path/computer].
-	PRINT_WARN("The drive is assigned elsewhere.\n");
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    case 0x46:
-	// Drive not online. Drive may be switched offline, the power supply may be switched off 
-	// or the drive address may not be set correctly.
-	PRINT_WARN("The drive is not online.");
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    case 0x47:
-	// Volume fenced. cu reports volume integrity is lost! 
-	PRINT_WARN("Volume fenced. The volume integrity is lost! \n");
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    case 0x48:
-	// Log sense data and retry request. We'll do so...
-	tape34xx_error_recovery_do_retry(td);
-	return;
-    case 0x49:
-	// Bus out check. A parity check error on the bus was found.	PRINT_WARN("Bus out check. A data transfer over the bus was corrupted.\n");
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    case 0x4a:
-	// Control unit erp failed. We'll report this.
-	PRINT_WARN("The control unit failed recovering an I/O error.\n");
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    case 0x4b:
-	// Cu and drive incompatible. The drive requests micro-program patches, which are not available on the cu.
-	PRINT_WARN("The drive needs microprogram patches from the control unit, which are not available.\n");
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    case 0x4c:
-	// Recovered Check-One failure. Cu develops a hardware error, but is able to recover. We'll reissue the command.
-	tape34xx_error_recovery_do_retry(td);
-	return;
-    case 0x4d:
-	switch (cu_type) {
-	case 0x3480:
-	    // This erpa is reserved for 3480 -> bug
-      	    tape34xx_error_recovery_HWBUG(td,21);
-	    return;
-	case 0x3490:
-	    // Resetting event received. Since the driver does not support resetting event recovery
-	    // (which has to be handled by the I/O Layer), we'll report and retry our command.
-	    tape34xx_error_recovery_do_retry(td);
-	    return;
-	}
-    case 0x4e:
-	switch (cu_type) {
-	case 0x3480:
-	    // This erpa is reserved for 3480 -> bug.
-	    tape34xx_error_recovery_HWBUG(td,22);
-	    return;
-	case 0x3490:
-	    // Maximum block size exeeded. This indicates, that the block to be written is larger
-	    // than allowed for buffered mode. We'll report this...
-	    PRINT_WARN("Maximum block size for buffered mode exceeded.\n");
-	    tape34xx_error_recovery_has_failed(td,ENOBUFS);
-	    return;
-	}
-    case 0x4f:
-	// These erpas are reserved -> bug
-	tape34xx_error_recovery_HWBUG(td,23);
-	return;
-    case 0x50:
-	// Read buffered log (Overflow). Cu is running in extended beffered log mode, and a counter overflows.
-	// This should never happen, since we're never running in extended buffered log mode -> bug.
-	tape34xx_error_recovery_do_retry(td);
-	return;
-    case 0x51:
-	// Read buffered log (EOV). EOF processing occurs while the cu is in extended buffered log mode.
-	// This should never happen, since we're never running in extended buffered log mode -> bug.
-	tape34xx_error_recovery_do_retry(td);
-	return;
-    case 0x52:
-	// End of Volume complete. Rewind unload completed ok. We'll report to the user...
-	if (treq->op!=TO_RUN) {
-	    tape34xx_error_recovery_HWBUG(td,24);
-	    return;
-	}
-	tape34xx_error_recovery_succeded(td);
-	return;
-    case 0x53:
-	// Global command intercept. We'll have to reissue our command.
-	tape34xx_error_recovery_do_retry(td);
-	return;
-    case 0x54:
-	// Channel interface recovery (temporary). This can be recovered by reissuing the command.
-	tape34xx_error_recovery_do_retry(td);
-	return;
-    case 0x55:
-	// Channel interface recovery (permanent). This cannot be recovered, we'll inform the user.
-	PRINT_WARN("A permanent channel interface error occurred.\n");
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    case 0x56:
-	// Channel protocol error. This cannot be recovered.
-	PRINT_WARN("A channel protocol error occurred.\n");
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    case 0x57:
-	switch (cu_type) {
-	case 0x3480:
-	    // Attention intercept. We have to reissue the command.
-	    PRINT_WARN("An attention intercept occurred, which will be recovered.\n");
-	    tape34xx_error_recovery_do_retry(td);
-	    return;
-	case 0x3490:
-	    // Global status intercept. We have to reissue the command.
-	    PRINT_WARN("An global status intercept was received, which will be recovered.\n");
-	    tape34xx_error_recovery_do_retry(td);
-	    return;
-	}
-    case 0x58:
-    case 0x59:
-	// These erpas are reserved -> bug.
-	tape34xx_error_recovery_HWBUG(td,25);
-	return;
-    case 0x5a:
-	// Tape length incompatible. The tape inserted is too long, 
-	// which could cause damage to the tape or the drive.
-	PRINT_WARN("Tape length incompatible [should be IBM Cartridge System Tape]. May cause damage to drive or tape.n");
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    case 0x5b:
-	// Format 3480 XF incompatible
-	if (sense[1]&SENSE_BEGINNING_OF_TAPE) {
-	    // Everything is fine. The tape will be overwritten in a different format.
-	    tape34xx_error_recovery_do_retry(td);
-	    return;
-	}
-	PRINT_WARN("Tape format is incompatible to the drive, which writes 3480-2 XF.\n");
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    case 0x5c:
-	// Format 3480-2 XF incompatible
-	PRINT_WARN("Tape format is incompatible to the drive. The drive cannot access 3480-2 XF volumes.\n");
-	tape34xx_error_recovery_has_failed(td,EIO);
-	return;
-    case 0x5d:
-	// Tape length violation. 
-	PRINT_WARN("Tape length violation [should be IBM Enhanced Capacity Cartridge System Tape]. May cause damage to drive or tape.\n");
-	tape34xx_error_recovery_has_failed(td,EMEDIUMTYPE);
-	return;
-    case 0x5e:
-	// Compaction algorithm incompatible.
-	PRINT_WARN("The volume is recorded using an incompatible compaction algorith, which is not supported by the control unit.\n");
-	tape34xx_error_recovery_has_failed(td,EMEDIUMTYPE);
-	return;
-    default:
-	// Reserved erpas -> bug
-	tape34xx_error_recovery_HWBUG(td,26);
-	return;
-    }
-}
-
-void tape34xx_error_recovery_has_failed (tape_dev_t* td,int error_id) {
-	tape_ccw_req_t *treq = tape_get_active_ccw_req(td);
-	tape_sprintf_event (tape_dbf_area,3,"Error Recovery failed for %s\n", tape_op_verbose[treq->op]);
-	treq->rc = -error_id;
-	if(treq->wakeup)
-		treq->wakeup (treq);
-}    
-
-void tape34xx_error_recovery_succeded(tape_dev_t* td) {
-	tape_ccw_req_t *treq = tape_get_active_ccw_req(td);
-	tape_sprintf_event (tape_dbf_area,3,"Error Recovery successfull for %s\n", tape_op_verbose[treq->op]);
-	tape34xx_done_handler(td);
-}
-
-void tape34xx_error_recovery_do_retry(tape_dev_t* td) {
-	tape_ccw_req_t* treq = tape_get_active_ccw_req(td);
-	tape_sprintf_event (tape_dbf_area,3,"xerp retr\n");
-	tape_sprintf_event (tape_dbf_area,3, "%s\n",tape_op_verbose[treq->op]);
-	tape_remove_ccw_req(td,treq);
-	tape_do_io_irq(td, treq,TAPE_NO_WAIT);
-}
-    
-void 
-tape34xx_error_recovery_read_opposite (tape_dev_t* td) {
-	tape_ccw_req_t *treq = tape_get_active_ccw_req(td);
-	switch (treq->op) {
-		case TO_RFO:
-			// We did read forward, but the data could not be read 
-			// *correctly*. We will read backward and then skip 
-			// forward again.
-			if(tape34xx_read_opposite(td))
-				tape34xx_error_recovery_do_retry(td);
-			else
-				tape34xx_error_recovery_has_failed(td,EIO);
-			break;
-		case TO_RBA:
-			// We tried to read forward and backward, but hat no 
-			// success -> failed.
-			tape34xx_error_recovery_has_failed(td,EIO);
-			break;
-		default:
-			PRINT_ERR("read_opposite_recovery_called_with_state:%s\n", tape_op_verbose[treq->op]);
-			tape34xx_error_recovery_has_failed(td,EIO);
-		}
-}
-
-void 
-tape34xx_error_recovery_HWBUG (tape_dev_t* td,int condno) {
-	tape_ccw_req_t *treq = tape_get_active_ccw_req(td);
-	PRINT_WARN("An unexpected condition #%d was caught in tape error recovery.\n",condno);
-	PRINT_WARN("Please report this incident.\n");
-	if(treq)
-	PRINT_WARN("Operation of tape:%s\n", tape_op_verbose[treq->op]);
-	tape_dump_sense(td);
-	tape34xx_error_recovery_has_failed(td,EIO);
-}
-
-/*
- * This routine is called by frontend after an ENOSP on write
- */
- 
-void tape34xx_process_eov(tape_dev_t* ti)
-{
-	tape_ccw_req_t *treq;
-	int rc;
-	int tm_written = 0;
- 
-	/* End of volume: We have to backspace the last written record, then */
-	/* we TRY to write a tapemark and then backspace over the written TM */
- 
-	treq = tape34xx_ioctl(ti,MTBSR,1,&rc);
-	if(treq){
-		tape_do_io_and_wait(ti,treq,TAPE_WAIT);
-		tape_free_ccw_req(treq);
-	}
-	treq = tape34xx_ioctl(ti,MTWEOF,1,&rc);
-	if(treq){
-		rc = tape_do_io_and_wait(ti,treq,TAPE_WAIT);
-		if((rc == 0) && (treq->rc == 0))
-			tm_written = 1;
-		tape_free_ccw_req(treq);
-	}
-	if(tm_written){
-		treq = tape34xx_ioctl(ti,MTBSR,1,&rc);
-		if(treq){
-			tape_do_io_and_wait(ti,treq,TAPE_WAIT);
-			tape_free_ccw_req(treq);
-		}
-	}
-}
-
-/*
- * 34xx first level interrupt handler
- */
-
-void tape34xx_irq(tape_dev_t* td)
-{
-	tape_ccw_req_t* treq = tape_get_active_ccw_req(td);
-	if (treq == NULL) {
-		tape34xx_unsolicited_irq(td);
-	} else if ((td->devstat.dstat & DEV_STAT_UNIT_EXCEP) && 
-		(td->devstat.dstat & DEV_STAT_DEV_END) &&
-		(treq->op == TO_WRI)){
-		/* Write at end of volume */
-		PRINT_INFO("End of volume\n"); /* XXX */
-		tape34xx_error_recovery_has_failed(td,ENOSPC);
-	} else if (td->devstat.dstat & DEV_STAT_UNIT_CHECK) {
-		tape34xx_error_recovery(td);
-	} else if (td->devstat.dstat & (DEV_STAT_DEV_END)) {
-		tape34xx_done_handler(td);
-        } else {
-		tape34xx_default_handler(td);
-	}
-}
-
-EXPORT_SYMBOL(tape34xx_irq);
-EXPORT_SYMBOL(tape34xx_write_block);
-EXPORT_SYMBOL(tape34xx_read_block);
-EXPORT_SYMBOL(tape34xx_ioctl);
-EXPORT_SYMBOL(tape34xx_ioctl_overload);
-EXPORT_SYMBOL(tape34xx_bread);
-EXPORT_SYMBOL(tape34xx_free_bread);
-EXPORT_SYMBOL(tape34xx_process_eov);
-EXPORT_SYMBOL(tape34xx_bread_enable_locate);
-
diff -Nru a/drivers/s390/char/tape34xx.h b/drivers/s390/char/tape34xx.h
--- a/drivers/s390/char/tape34xx.h	Mon Dec  9 18:46:49 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,133 +0,0 @@
-
-/***************************************************************************
- *
- *  drivers/s390/char/tape34xx.h
- *    common tape device discipline for 34xx tapes.
- *
- *  S390 and zSeries version
- *    Copyright (C) 2001 IBM Corporation
- *    Author(s): Carsten Otte <cotte@de.ibm.com>
- *               Tuan Ngo-Anh <ngoanh@de.ibm.com>
- *
- ****************************************************************************
- */
-
-#ifndef _TAPE34XX_H
-
-#define _TAPE34XX_H
-
-/*
- * The CCW commands for the Tape type of command.
- */
-
-#define         INVALID_00              0x00    /* Invalid cmd      */
-#define         BACKSPACEBLOCK          0x27    /* Back Space block */
-#define         BACKSPACEFILE           0x2f    /* Back Space file */
-#define         DATA_SEC_ERASE          0x97    /* Data security erase */
-#define         ERASE_GAP               0x17    /* Erase Gap */
-#define         FORSPACEBLOCK           0x37    /* Forward space block */
-#define         FORSPACEFILE            0x3F    /* Forward Space file */
-#define         FORCE_STREAM_CNT        0xEB    /* Forced streaming count #   */
-#define         NOP                     0x03    /* No operation  */
-#define         READ_FORWARD            0x02    /* Read forward */
-#define         REWIND                  0x07    /* Rewind */
-#define         REWIND_UNLOAD           0x0F    /* Rewind and Unload */
-#define         SENSE                   0x04    /* Sense */
-#define         NEW_MODE_SET            0xEB    /* Guess it is Mode set */
-#define         WRITE_CMD               0x01    /* Write */
-#define         WRITETAPEMARK           0x1F    /* Write Tape Mark */
-
-#define         ASSIGN                  0xB7    /* 3420 REJECT,3480 OK  */
-#define         CONTROL_ACCESS          0xE3    /* Set high speed */
-#define         DIAG_MODE_SET           0x0B    /* 3420 NOP, 3480 REJECT*/
-#define         LOAD_DISPLAY            0x9F    /* 3420 REJECT,3480 OK  */
-#define         LOCATE                  0x4F    /* 3420 REJ, 3480 NOP   */
-#define         LOOP_WRITE_TO_READ      0x8B    /* 3480 REJECT        */
-#define         MODE_SET_DB             0xDB    /* 3420 REJECT,3480 OK  */
-#define         MODE_SET_C3             0xC3    /* for 3420                */
-#define         MODE_SET_CB             0xCB    /* for 3420                */
-#define         MODE_SET_D3             0xD3    /* for 3420                */
-#define         READ_BACKWARD           0x0C    /*                      */
-#define         READ_BLOCK_ID           0x22    /* 3420 REJECT,3480 OK  */
-#define         READ_BUFFER             0x12    /* 3420 REJECT,3480 OK  */
-#define         READ_BUFF_LOG           0x24    /* 3420 REJECT,3480 OK  */
-#define         RELEASE                 0xD4    /* 3420 NOP, 3480 REJECT*/
-#define         REQ_TRK_IN_ERROR        0x1B    /* 3420 NOP, 3480 REJECT*/
-#define         RESERVE                 0xF4    /* 3420 NOP, 3480 REJECT*/
-#define         SENSE_GROUP_ID          0x34    /* 3420 REJECT,3480 OK  */
-#define         SENSE_ID                0xE4    /* 3420 REJECT,3480 OK */
-#define         READ_DEV_CHAR           0x64    /* Read device characteristics */
-#define         SET_DIAGNOSE            0x4B    /* 3420 NOP, 3480 REJECT*/
-#define         SET_GROUP_ID            0xAF    /* 3420 REJECT,3480 OK  */
-#define         SET_TAPE_WRITE_IMMED    0xC3    /* for 3480                */
-#define         SUSPEND                 0x5B    /* 3420 REJ, 3480 NOP   */
-#define         SYNC                    0x43    /* Synchronize (flush buffer) */
-#define         UNASSIGN                0xC7    /* 3420 REJECT,3480 OK  */
-#define         PERF_SUBSYS_FUNC        0x77    /* 3490 CMD */
-#define         READ_CONFIG_DATA        0xFA    /* 3490 CMD */
-#define         READ_MESSAGE_ID         0x4E    /* 3490 CMD */
-#define         READ_SUBSYS_DATA        0x3E    /* 3490 CMD */
-#define         SET_INTERFACE_ID        0x73    /* 3490 CMD */
-
-#define COMMAND_CHAIN    CCW_FLAG_CC      /* redefine from irq.h */
-#define CHANNEL_END      DEV_STAT_CHN_END /* redefine from irq.h */
-#define DEVICE_END       DEV_STAT_DEV_END /* redefine from irq.h */
-#define UNIT_CHECK       DEV_STAT_UNIT_CHECK  /* redefine from irq.h */
-#define UNIT_EXCEPTION   DEV_STAT_UNIT_EXCEP  /* redefine from irq.h */
-#define CONTROL_UNIT_END DEV_STAT_CU_END      /* redefine from irq.h */
-#define INCORR_LEN       SCHN_STAT_INCORR_LEN /* redefine from irq.h */
-
-#define SENSE_COMMAND_REJECT        0x80
-#define SENSE_INTERVENTION_REQUIRED 0x40
-#define SENSE_BUS_OUT_CHECK         0x20
-#define SENSE_EQUIPMENT_CHECK       0x10
-#define SENSE_DATA_CHECK            0x08
-#define SENSE_OVERRUN               0x04
-#define SENSE_DEFERRED_UNIT_CHECK   0x02
-#define SENSE_ASSIGNED_ELSEWHERE    0x01
-
-#define SENSE_LOCATE_FAILURE        0x80
-#define SENSE_DRIVE_ONLINE          0x40
-#define SENSE_RESERVED              0x20
-#define SENSE_RECORD_SEQUENCE_ERR   0x10
-#define SENSE_BEGINNING_OF_TAPE     0x08
-#define SENSE_WRITE_MODE            0x04
-#define SENSE_WRITE_PROTECT         0x02
-#define SENSE_NOT_CAPABLE           0x01
-
-#define SENSE_CHANNEL_ADAPTER_CODE  0xE0
-#define SENSE_CHANNEL_ADAPTER_LOC   0x10
-#define SENSE_REPORTING_CU          0x08
-#define SENSE_AUTOMATIC_LOADER      0x04
-#define SENSE_TAPE_SYNC_MODE        0x02
-#define SENSE_TAPE_POSITIONING      0x01
-
-typedef struct _tape34xx_disc_data_t {
-    __u8 modeset_byte;
-} tape34xx_disc_data_t  __attribute__ ((packed, aligned(8)));
-#define MOD_BYTE ((tape34xx_disc_data_t *)td->discdata)->modeset_byte
-
-/* discipline functions */
-int tape34xx_ioctl_overload (tape_dev_t* td, unsigned int cmd, unsigned long arg);
-tape_ccw_req_t * tape34xx_write_block (const char *data, size_t count, tape_dev_t* td);
-tape_ccw_req_t * tape34xx_read_block (const char *data, size_t count, tape_dev_t* td);
-tape_ccw_req_t * tape34xx_ioctl(tape_dev_t* td, int op,int count, int* rc);
-tape_ccw_req_t * tape34xx_bread (struct request *req, tape_dev_t* td,int tapeblock_major);
-void tape34xx_free_bread (tape_ccw_req_t* treq);
-void tape34xx_bread_enable_locate (tape_ccw_req_t * treq);
-tape_ccw_req_t * tape34xx_bwrite (struct request *req, tape_dev_t* td,int tapeblock_major);
-
-/* Event handlers */
-void tape34xx_default_handler (tape_dev_t * td);
-void tape34xx_unexpect_uchk_handler (tape_dev_t * td);
-void tape34xx_irq (tape_dev_t* td);
-void tape34xx_process_eov(tape_dev_t* td);
-
-// the error recovery stuff:
-void tape34xx_error_recovery (tape_dev_t* td);
-void tape34xx_error_recovery_has_failed (tape_dev_t* td,int error_id);
-void tape34xx_error_recovery_succeded(tape_dev_t* td);
-void tape34xx_error_recovery_do_retry(tape_dev_t* td);
-void tape34xx_error_recovery_read_opposite (tape_dev_t* td);
-void  tape34xx_error_recovery_HWBUG (tape_dev_t* td,int condno);
-#endif // _TAPE34XX_H
diff -Nru a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/char/tape_34xx.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,1068 @@
+/*
+ *  drivers/s390/char/tape_34xx.c
+ *    tape device discipline for 3480/3490 tapes.
+ *
+ *  S390 and zSeries version
+ *    Copyright (C) 2001,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Author(s): Carsten Otte <cotte@de.ibm.com>
+ *		 Tuan Ngo-Anh <ngoanh@de.ibm.com>
+ *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/bio.h>
+#include <linux/workqueue.h>
+#include <asm/tape390.h>
+
+#include "tape.h"
+#include "tape_std.h"
+
+#define PRINTK_HEADER "T34xx:"
+
+enum tape34xx_type {
+	tape_3480,
+	tape_3490,
+};
+
+/*
+ * Medium sense (asyncronous with callback) for 34xx tapes. There is no 'real'
+ * medium sense call. So we just do a normal sense.
+ */
+static void
+__tape_34xx_medium_sense_callback(struct tape_request *request, void *data)
+{
+	unsigned char      *sense;
+	struct tape_device *device;
+
+	request->callback = NULL;
+
+	if(request->rc == 0 && (device = request->device) != NULL) {
+		sense = request->cpdata;
+
+		/*
+		 * This isn't quite correct. But since INTERVENTION_REQUIRED
+		 * means that the drive is 'neither ready nor online' it is
+		 * only slightly inaccurate to say there is no tape loaded if
+		 * the drive isn't online...
+		 */
+		if(sense[0] & SENSE_INTERVENTION_REQUIRED)
+			tape_med_state_set(device, MS_UNLOADED);
+		else
+			tape_med_state_set(device, MS_LOADED);
+
+		if(sense[1] & SENSE_WRITE_PROTECT)
+			device->tape_generic_status |= GMT_WR_PROT(~0);
+		else
+			device->tape_generic_status &= ~GMT_WR_PROT(~0);
+	}
+	tape_free_request(request);
+}
+
+static int
+tape_34xx_medium_sense(struct tape_device *device)
+{
+	struct tape_request *request;
+	int                  rc;
+
+	request = tape_alloc_request(1, 32);
+	if(IS_ERR(request)) {
+		DBF_EXCEPTION(6, "MSEN fail\n");
+		return PTR_ERR(request);
+	}
+
+	request->op = TO_MSEN;
+	tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata);
+	request->callback = __tape_34xx_medium_sense_callback;
+
+	rc = tape_do_io_async(device, request);
+
+	return rc;
+}
+
+/*
+ * These functions are currently used only to schedule a medium_sense for
+ * later execution. This is because we get an interrupt whenever a medium
+ * is inserted but cannot call tape_do_io* from an interrupt context.
+ * Maybe that's useful for other actions we want to start from the
+ * interrupt handler.
+ */
+static void
+tape_34xx_work_handler(void *data)
+{
+	struct {
+		struct tape_device	*device;
+		enum tape_op		 op;
+		struct work_struct	 work;
+	} *p = data;
+
+	switch(p->op) {
+		case TO_MSEN:
+			tape_34xx_medium_sense(p->device);
+		default:
+			DBF_EVENT(3, "T34XX: internal error: unknown work\n");
+	}
+
+	tape_put_device(p->device);
+	kfree(p);
+}
+
+static int
+tape_34xx_schedule_work(struct tape_device *device, enum tape_op op)
+{
+	struct {
+		struct tape_device	*device;
+		enum tape_op		 op;
+		struct work_struct	 work;
+	} *p;
+
+	if((p = kmalloc(sizeof(*p), GFP_ATOMIC)) == NULL)
+		return -ENOMEM;
+
+	memset(p, 0, sizeof(*p));
+	INIT_WORK(&p->work, tape_34xx_work_handler, p);
+
+	atomic_inc(&device->ref_count);
+	p->device = device;
+	p->op     = op;
+
+	schedule_work(&p->work);
+	return 0;
+}
+
+/*
+ * Done Handler is called when dev stat = DEVICE-END (successfull operation)
+ */
+static int
+tape_34xx_done(struct tape_device *device, struct tape_request *request)
+{
+	DBF_EVENT(6, "%s done\n", tape_op_verbose[request->op]);
+
+	return TAPE_IO_SUCCESS;
+}
+
+static inline int
+tape_34xx_erp_failed(struct tape_device *device,
+		     struct tape_request *request, int rc)
+{
+	DBF_EVENT(3, "Error recovery failed for %s\n",
+		  tape_op_verbose[request->op]);
+	return rc;
+}
+
+static inline int
+tape_34xx_erp_succeded(struct tape_device *device,
+		       struct tape_request *request)
+{
+	DBF_EVENT(3, "Error Recovery successfull for %s\n",
+		  tape_op_verbose[request->op]);
+	return tape_34xx_done(device, request);
+}
+
+static inline int
+tape_34xx_erp_retry(struct tape_device *device, struct tape_request *request)
+{
+	DBF_EVENT(3, "xerp retr %s\n",
+		  tape_op_verbose[request->op]);
+	return TAPE_IO_RETRY;
+}
+
+/*
+ * This function is called, when no request is outstanding and we get an
+ * interrupt
+ */
+static int
+tape_34xx_unsolicited_irq(struct tape_device *device, struct irb *irb)
+{
+	if (irb->scsw.dstat == 0x85 /* READY */) {
+		/* A medium was inserted in the drive. */
+		DBF_EVENT(6, "xuud med\n");
+		tape_34xx_schedule_work(device, TO_MSEN);
+	} else {
+		DBF_EVENT(3, "unsol.irq! dev end: %s\n",
+				device->cdev->dev.bus_id);
+		PRINT_WARN("Unsolicited IRQ (Device End) caught.\n");
+		tape_dump_sense(device, NULL, irb);
+	}
+	return TAPE_IO_SUCCESS;
+}
+
+/*
+ * Read Opposite Error Recovery Function:
+ * Used, when Read Forward does not work
+ */
+static int
+tape_34xx_erp_read_opposite(struct tape_device *device,
+			    struct tape_request *request)
+{
+	if (request->op == TO_RFO) {
+		/*
+		 * We did read forward, but the data could not be read
+		 * *correctly*. We transform the request to a read backward
+		 * and try again.
+		 */
+		tape_std_read_backward(device, request);
+		return tape_34xx_erp_retry(device, request);
+	}
+	if (request->op != TO_RBA)
+		PRINT_ERR("read_opposite called with state:%s\n",
+			  tape_op_verbose[request->op]);
+	/*
+	 * We tried to read forward and backward, but hat no
+	 * success -> failed.
+	 */
+	return tape_34xx_erp_failed(device, request, -EIO);
+}
+
+static int
+tape_34xx_erp_bug(struct tape_device *device, struct tape_request *request,
+		  struct irb *irb, int no)
+{
+	if (request->op != TO_ASSIGN) {
+		PRINT_WARN("An unexpected condition #%d was caught in "
+			   "tape error recovery.\n", no);
+		PRINT_WARN("Please report this incident.\n");
+		if (request)
+			PRINT_WARN("Operation of tape:%s\n",
+				   tape_op_verbose[request->op]);
+		tape_dump_sense(device, request, irb);
+	}
+	return tape_34xx_erp_failed(device, request, -EIO);
+}
+
+/*
+ * Handle data overrun between cu and drive. The channel speed might
+ * be too slow.
+ */
+static int
+tape_34xx_erp_overrun(struct tape_device *device, struct tape_request *request,
+		      struct irb *irb)
+{
+	if (irb->ecw[3] == 0x40) {
+		PRINT_WARN ("Data overrun error between control-unit "
+			    "and drive. Use a faster channel connection, "
+			    "if possible! \n");
+		return tape_34xx_erp_failed(device, request, -EIO);
+	}
+	return tape_34xx_erp_bug(device, request, irb, -1);
+}
+
+/*
+ * Handle record sequence error.
+ */
+static int
+tape_34xx_erp_sequence(struct tape_device *device,
+		       struct tape_request *request, struct irb *irb)
+{
+	if (irb->ecw[3] == 0x41) {
+		/*
+		 * cu detected incorrect block-id sequence on tape.
+		 */
+		PRINT_WARN("Illegal block-id sequence found!\n");
+		return tape_34xx_erp_failed(device, request, -EIO);
+	}
+	/*
+	 * Record sequence error bit is set, but erpa does not
+	 * show record sequence error.
+	 */
+	return tape_34xx_erp_bug(device, request, irb, -2);
+}
+
+/*
+ * This function analyses the tape's sense-data in case of a unit-check.
+ * If possible, it tries to recover from the error. Else the user is
+ * informed about the problem.
+ */
+static int
+tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
+		     struct irb *irb)
+{
+	int inhibit_cu_recovery;
+	__u8* sense;
+
+#ifdef CONFIG_S390_TAPE_BLOCK
+	if (request->op == TO_BLOCK) {
+		/*
+		 * Recovery for block device requests. Set the block_position
+		 * to something invalid and retry.
+		 */
+		device->blk_data.block_position = -1;
+		if (request->retries-- <= 0)
+			return tape_34xx_erp_failed(device, request, -EIO);
+		else
+			return tape_34xx_erp_retry(device, request);
+	}
+#endif
+
+	inhibit_cu_recovery = (*device->modeset_byte & 0x80) ? 1 : 0;
+	sense = irb->ecw;
+
+	if (sense[0] & SENSE_COMMAND_REJECT) {
+		if ((sense[1] & SENSE_WRITE_PROTECT) &&
+		    (request->op == TO_DSE ||
+		     request->op == TO_WRI ||
+		     request->op == TO_WTM))
+			/* medium is write protected */
+			return tape_34xx_erp_failed(device, request, -EACCES);
+		else
+			return tape_34xx_erp_bug(device, request, irb, -3);
+	}
+
+	/*
+	 * special cases for various tape-states when reaching
+	 * end of recorded area
+	 */
+	if ((sense[0] == 0x08 || sense[0] == 0x10 || sense[0] == 0x12) &&
+	    (sense[1] == 0x40 || sense[1] == 0x0c))
+		switch (request->op) {
+		case TO_FSF:
+			/* Trying to seek beyond end of recorded area */
+			return tape_34xx_erp_failed(device, request, -ENOSPC);
+		case TO_LBL:
+			/* Block could not be located. */
+			return tape_34xx_erp_failed(device, request, -EIO);
+		case TO_RFO:
+			/* Read beyond end of recorded area -> 0 bytes read */
+			return tape_34xx_erp_failed(device, request, 0);
+		default:
+			PRINT_ERR("Invalid op in %s:%i\n",
+				  __FUNCTION__, __LINE__);
+			return tape_34xx_erp_failed(device, request, 0);
+		}
+
+	/* Sensing special bits */
+	if (sense[0] & SENSE_BUS_OUT_CHECK)
+		return tape_34xx_erp_retry(device, request);
+
+	if (sense[0] & SENSE_DATA_CHECK) {
+		/*
+		 * hardware failure, damaged tape or improper
+		 * operating conditions
+		 */
+		switch (sense[3]) {
+		case 0x23:
+			/* a read data check occurred */
+			if ((sense[2] & SENSE_TAPE_SYNC_MODE) ||
+			    inhibit_cu_recovery)
+				// data check is not permanent, may be
+				// recovered. We always use async-mode with
+				// cu-recovery, so this should *never* happen.
+				return tape_34xx_erp_bug(device, request,
+							 irb, -4);
+
+			/* data check is permanent, CU recovery has failed */
+			PRINT_WARN("Permanent read error\n");
+			return tape_34xx_erp_failed(device, request, -EIO);
+		case 0x25:
+			// a write data check occurred
+			if ((sense[2] & SENSE_TAPE_SYNC_MODE) ||
+			    inhibit_cu_recovery)
+				// data check is not permanent, may be
+				// recovered. We always use async-mode with
+				// cu-recovery, so this should *never* happen.
+				return tape_34xx_erp_bug(device, request,
+							 irb, -5);
+
+			// data check is permanent, cu-recovery has failed
+			PRINT_WARN("Permanent write error\n");
+			return tape_34xx_erp_failed(device, request, -EIO);
+		case 0x26:
+			/* Data Check (read opposite) occurred. */
+			return tape_34xx_erp_read_opposite(device, request);
+		case 0x28:
+			/* ID-Mark at tape start couldn't be written */
+			PRINT_WARN("ID-Mark could not be written.\n");
+			return tape_34xx_erp_failed(device, request, -EIO);
+		case 0x31:
+			/* Tape void. Tried to read beyond end of device. */
+			PRINT_WARN("Read beyond end of recorded area.\n");
+			return tape_34xx_erp_failed(device, request, -ENOSPC);
+		case 0x41:
+			/* Record sequence error. */
+			PRINT_WARN("Invalid block-id sequence found.\n");
+			return tape_34xx_erp_failed(device, request, -EIO);
+		default:
+			/* all data checks for 3480 should result in one of
+			 * the above erpa-codes. For 3490, other data-check
+			 * conditions do exist. */
+			if (device->cdev->id.driver_info == tape_3480)
+				return tape_34xx_erp_bug(device, request,
+							 irb, -6);
+		}
+	}
+
+	if (sense[0] & SENSE_OVERRUN)
+		return tape_34xx_erp_overrun(device, request, irb);
+
+	if (sense[1] & SENSE_RECORD_SEQUENCE_ERR)
+		return tape_34xx_erp_sequence(device, request, irb);
+
+	/* Sensing erpa codes */
+	switch (sense[3]) {
+	case 0x00:
+		/* Unit check with erpa code 0. Report and ignore. */
+		PRINT_WARN("Non-error sense was found. "
+			   "Unit-check will be ignored.\n");
+		return TAPE_IO_SUCCESS;
+	case 0x21:
+		/*
+		 * Data streaming not operational. CU will switch to
+		 * interlock mode. Reissue the command.
+		 */
+		PRINT_WARN("Data streaming not operational. "
+			   "Switching to interlock-mode.\n");
+		return tape_34xx_erp_retry(device, request);
+	case 0x22:
+		/*
+		 * Path equipment check. Might be drive adapter error, buffer
+		 * error on the lower interface, internal path not useable,
+		 * or error during cartridge load.
+		 */
+		PRINT_WARN("A path equipment check occurred. One of the "
+			   "following conditions occurred:\n");
+		PRINT_WARN("drive adapter error, buffer error on the lower "
+			   "interface, internal path not useable, error "
+			   "during cartridge load.\n");
+		return tape_34xx_erp_failed(device, request, -EIO);
+	case 0x24:
+		/*
+		 * Load display check. Load display was command was issued,
+		 * but the drive is displaying a drive check message. Can
+		 * be threated as "device end".
+		 */
+		return tape_34xx_erp_succeded(device, request);
+	case 0x27:
+		/*
+		 * Command reject. May indicate illegal channel program or
+		 * buffer over/underrun. Since all channel programms are
+		 * issued by this driver and ought be correct, we assume a
+		 * over/underrun situaltion and retry the channel program.
+		 */
+		return tape_34xx_erp_retry(device, request);
+	case 0x29:
+		/*
+		 * Function incompatible. Either the tape is idrc compressed
+		 * but the hardware isn't capable to do idrc, or a perform
+		 * subsystem func is issued and the CU is not online.
+		 */
+		PRINT_WARN ("Function incompatible. Try to switch off idrc\n");
+		return tape_34xx_erp_failed(device, request, -EIO);
+	case 0x2a:
+		/*
+		 * Unsolicited environmental data. An internal counter
+		 * overflows, we can ignore this and reissue the cmd.
+		 */
+		return tape_34xx_erp_retry(device, request);
+	case 0x2b:
+		/*
+		 * Environmental data present. Indicates either unload
+		 * completed ok or read buffered log command completed ok.
+		 */
+		if (request->op == TO_RUN) {
+			/* Rewind unload completed ok. */
+			tape_med_state_set(device, MS_UNLOADED);
+			return tape_34xx_erp_succeded(device, request);
+		}
+		/* tape_34xx doesn't use read buffered log commands. */
+		return tape_34xx_erp_bug(device, request, irb, sense[3]);
+	case 0x2c:
+		/*
+		 * Permanent equipment check. CU has tried recovery, but
+		 * did not succeed.
+		 */
+		return tape_34xx_erp_failed(device, request, -EIO);
+	case 0x2d:
+		/* Data security erase failure. */
+		if (request->op == TO_DSE)
+			return tape_34xx_erp_failed(device, request, -EIO);
+		/* Data security erase failure, but no such command issued. */
+		return tape_34xx_erp_bug(device, request, irb, sense[3]);
+	case 0x2e:
+		/*
+		 * Not capable. This indicates either that the drive fails
+		 * reading the format id mark or that that format specified
+		 * is not supported by the drive.
+		 */
+		PRINT_WARN("Drive not capable processing the tape format!");
+		return tape_34xx_erp_failed(device, request, -EMEDIUMTYPE);
+	case 0x30:
+		/* The medium is write protected. */
+		PRINT_WARN("Medium is write protected!\n");
+		return tape_34xx_erp_failed(device, request, -EACCES);
+	case 0x32:
+		// Tension loss. We cannot recover this, it's an I/O error.
+		PRINT_WARN("The drive lost tape tension.\n");
+		return tape_34xx_erp_failed(device, request, -EIO);
+	case 0x33:
+		/*
+		 * Load Failure. The catridge was not inserted correctly or
+		 * the tape is not threaded correctly.
+		 */
+		PRINT_WARN("Cartridge load failure. Reload the cartridge "
+			   "and try again.\n");
+		return tape_34xx_erp_failed(device, request, -EIO);
+	case 0x34:
+		/*
+		 * Unload failure. The drive cannot maintain tape tension
+		 * and control tape movement during an unload operation.
+		 */
+		PRINT_WARN("Failure during cartridge unload. "
+			   "Please try manually.\n");
+		if (request->op == TO_RUN)
+			return tape_34xx_erp_failed(device, request, -EIO);
+		return tape_34xx_erp_bug(device, request, irb, sense[3]);
+	case 0x35:
+		/*
+		 * Drive equipment check. One of the following:
+		 * - cu cannot recover from a drive detected error
+		 * - a check code message is shown on drive display
+		 * - the cartridge loader does not respond correctly
+		 * - a failure occurs during an index, load, or unload cycle
+		 */
+		PRINT_WARN("Equipment check! Please check the drive and "
+			   "the cartridge loader.\n");
+		return tape_34xx_erp_failed(device, request, -EIO);
+	case 0x36:
+		if (device->cdev->id.driver_info == tape_3490)
+			/* End of data. */
+			return tape_34xx_erp_failed(device, request, -EIO);
+		/* This erpa is reserved for 3480 */
+		return tape_34xx_erp_bug(device, request, irb, sense[3]);
+	case 0x37:
+		/*
+		 * Tape length error. The tape is shorter than reported in
+		 * the beginning-of-tape data.
+		 */
+		PRINT_WARN("Tape length error.\n");
+		return tape_34xx_erp_failed(device, request, -EIO);
+	case 0x38:
+		/*
+		 * Physical end of tape. A read/write operation reached
+		 * the physical end of tape.
+		 */
+		if (request->op==TO_WRI ||
+		    request->op==TO_DSE ||
+		    request->op==TO_WTM)
+			return tape_34xx_erp_failed(device, request, -ENOSPC);
+		return tape_34xx_erp_failed(device, request, -EIO);
+	case 0x39:
+		/* Backward at Beginnig of tape. */
+		return tape_34xx_erp_failed(device, request, -EIO);
+	case 0x3a:
+		/* Drive switched to not ready. */
+		PRINT_WARN("Drive not ready. Turn the ready/not ready switch "
+			   "to ready position and try again.\n");
+		return tape_34xx_erp_failed(device, request, -EIO);
+	case 0x3b:
+		/* Manual rewind or unload. This causes an I/O error. */
+		PRINT_WARN("Medium was rewound or unloaded manually.\n");
+		return tape_34xx_erp_failed(device, request, -EIO);
+	case 0x42:
+		/*
+		 * Degraded mode. A condition that can cause degraded
+		 * performace is detected.
+		 */
+		PRINT_WARN("Subsystem is running in degraded mode.\n");
+		return tape_34xx_erp_retry(device, request);
+	case 0x43:
+		/* Drive not ready. */
+		tape_med_state_set(device, MS_UNLOADED);
+		/* Some commands commands are sucessful even in this case */
+		if(sense[1] & SENSE_DRIVE_ONLINE) {
+			switch(request->op) {
+				case TO_ASSIGN:
+				case TO_UNASSIGN:
+				case TO_DIS:
+					return tape_34xx_done(device, request);
+					break;
+				default:
+					break;
+			}
+		}
+		PRINT_WARN("The drive is not ready.\n");
+		return tape_34xx_erp_failed(device, request, -ENOMEDIUM);
+	case 0x44:
+		/* Locate Block unsuccessfull. */
+		if (request->op != TO_BLOCK && request->op != TO_LBL)
+			/* No locate block was issued. */
+			return tape_34xx_erp_bug(device, request,
+						 irb, sense[3]);
+		return tape_34xx_erp_failed(device, request, -EIO);
+	case 0x45:
+		/* The drive is assigned to a different channel path. */
+		PRINT_WARN("The drive is assigned elsewhere.\n");
+		return tape_34xx_erp_failed(device, request, -EIO);
+	case 0x46:
+		/*
+		 * Drive not online. Drive may be switched offline,
+		 * the power supply may be switched off or
+		 * the drive address may not be set correctly.
+		 */
+		PRINT_WARN("The drive is not online.");
+		return tape_34xx_erp_failed(device, request, -EIO);
+	case 0x47:
+		/* Volume fenced. CU reports volume integrity is lost. */
+		PRINT_WARN("Volume fenced. The volume integrity is lost.\n");
+		return tape_34xx_erp_failed(device, request, -EIO);
+	case 0x48:
+		/* Log sense data and retry request. */
+		return tape_34xx_erp_retry(device, request);
+	case 0x49:
+		/* Bus out check. A parity check error on the bus was found. */
+		PRINT_WARN("Bus out check. A data transfer over the bus "
+			   "has been corrupted.\n");
+		return tape_34xx_erp_failed(device, request, -EIO);
+	case 0x4a:
+		/* Control unit erp failed. */
+		PRINT_WARN("The control unit I/O error recovery failed.\n");
+		return tape_34xx_erp_failed(device, request, -EIO);
+	case 0x4b:
+		/*
+		 * CU and drive incompatible. The drive requests micro-program
+		 * patches, which are not available on the CU.
+		 */
+		PRINT_WARN("The drive needs microprogram patches from the "
+			   "control unit, which are not available.\n");
+		return tape_34xx_erp_failed(device, request, -EIO);
+	case 0x4c:
+		/*
+		 * Recovered Check-One failure. Cu develops a hardware error,
+		 * but is able to recover.
+		 */
+		return tape_34xx_erp_retry(device, request);
+	case 0x4d:
+		if (device->cdev->id.driver_info == tape_3490)
+			/*
+			 * Resetting event received. Since the driver does
+			 * not support resetting event recovery (which has to
+			 * be handled by the I/O Layer), retry our command.
+			 */
+			return tape_34xx_erp_retry(device, request);
+		/* This erpa is reserved for 3480. */
+		return tape_34xx_erp_bug(device, request, irb, sense[3]);
+	case 0x4e:
+		if (device->cdev->id.driver_info == tape_3490) {
+			/*
+			 * Maximum block size exeeded. This indicates, that
+			 * the block to be written is larger than allowed for
+			 * buffered mode.
+			 */
+			PRINT_WARN("Maximum block size for buffered "
+				   "mode exceeded.\n");
+			return tape_34xx_erp_failed(device, request, -ENOBUFS);
+		}
+		/* This erpa is reserved for 3480. */
+		return tape_34xx_erp_bug(device, request, irb, sense[3]);
+	case 0x50:
+		/*
+		 * Read buffered log (Overflow). CU is running in extended
+		 * buffered log mode, and a counter overflows. This should
+		 * never happen, since we're never running in extended
+		 * buffered log mode.
+		 */
+		return tape_34xx_erp_retry(device, request);
+	case 0x51:
+		/*
+		 * Read buffered log (EOV). EOF processing occurs while the
+		 * CU is in extended buffered log mode. This should never
+		 * happen, since we're never running in extended buffered
+		 * log mode.
+		 */
+		return tape_34xx_erp_retry(device, request);
+	case 0x52:
+		/* End of Volume complete. Rewind unload completed ok. */
+		if (request->op == TO_RUN) {
+			tape_med_state_set(device, MS_UNLOADED);
+			return tape_34xx_erp_succeded(device, request);
+		}
+		return tape_34xx_erp_bug(device, request, irb, sense[3]);
+	case 0x53:
+		/* Global command intercept. */
+		return tape_34xx_erp_retry(device, request);
+	case 0x54:
+		/* Channel interface recovery (temporary). */
+		return tape_34xx_erp_retry(device, request);
+	case 0x55:
+		/* Channel interface recovery (permanent). */
+		PRINT_WARN("A permanent channel interface error occurred.\n");
+		return tape_34xx_erp_failed(device, request, -EIO);
+	case 0x56:
+		/* Channel protocol error. */
+		PRINT_WARN("A channel protocol error occurred.\n");
+		return tape_34xx_erp_failed(device, request, -EIO);
+	case 0x57:
+		if (device->cdev->id.driver_info == tape_3480) {
+			/* Attention intercept. */
+			PRINT_WARN("An attention intercept occurred, "
+				   "which will be recovered.\n");
+			return tape_34xx_erp_retry(device, request);
+		} else {
+			/* Global status intercept. */
+			PRINT_WARN("An global status intercept was recieved, "
+				   "which will be recovered.\n");
+			return tape_34xx_erp_retry(device, request);
+		}
+	case 0x5a:
+		/*
+		 * Tape length incompatible. The tape inserted is too long,
+		 * which could cause damage to the tape or the drive.
+		 */
+		PRINT_WARN("Tape length incompatible [should be IBM Cartridge "
+			   "System Tape]. May cause damage to drive or tape.\n");
+		return tape_34xx_erp_failed(device, request, -EIO);
+	case 0x5b:
+		/* Format 3480 XF incompatible */
+		if (sense[1] & SENSE_BEGINNING_OF_TAPE)
+			/* The tape will get overwritten. */
+			return tape_34xx_erp_retry(device, request);
+		PRINT_WARN("Tape format is incompatible to the drive, "
+			   "which writes 3480-2 XF.\n");
+		return tape_34xx_erp_failed(device, request, -EIO);
+	case 0x5c:
+		/* Format 3480-2 XF incompatible */
+		PRINT_WARN("Tape format is incompatible to the drive. "
+			   "The drive cannot access 3480-2 XF volumes.\n");
+		return tape_34xx_erp_failed(device, request, -EIO);
+	case 0x5d:
+		/* Tape length violation. */
+		PRINT_WARN("Tape length violation [should be IBM Enhanced "
+			   "Capacity Cartridge System Tape]. May cause "
+			   "damage to drive or tape.\n");
+		return tape_34xx_erp_failed(device, request, -EMEDIUMTYPE);
+	case 0x5e:
+		/* Compaction algorithm incompatible. */
+		PRINT_WARN("The volume is recorded using an incompatible "
+			   "compaction algorith, which is not supported by "
+			   "the control unit.\n");
+		return tape_34xx_erp_failed(device, request, -EMEDIUMTYPE);
+
+		/* The following erpas should have been covered earlier. */
+	case 0x23: /* Read data check. */
+	case 0x25: /* Write data check. */
+	case 0x26: /* Data check (read opposite). */
+	case 0x28: /* Write id mark check. */
+	case 0x31: /* Tape void. */
+	case 0x40: /* Overrun error. */
+	case 0x41: /* Record sequence error. */
+		/* All other erpas are reserved for future use. */
+	default:
+		return tape_34xx_erp_bug(device, request, irb, sense[3]);
+	}
+}
+
+/*
+ * 3480/3490 interrupt handler
+ */
+static int
+tape_34xx_irq(struct tape_device *device, struct tape_request *request,
+	      struct irb *irb)
+{
+	if (request == NULL)
+		return tape_34xx_unsolicited_irq(device, irb);
+
+	if ((irb->scsw.dstat & DEV_STAT_UNIT_EXCEP) &&
+	    (irb->scsw.dstat & DEV_STAT_DEV_END) &&
+	    (request->op == TO_WRI)) {
+		/* Write at end of volume */
+		PRINT_INFO("End of volume\n"); /* XXX */
+		return tape_34xx_erp_failed(device, request, -ENOSPC);
+	}
+
+	if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK)
+		return tape_34xx_unit_check(device, request, irb);
+
+	if (irb->scsw.dstat & DEV_STAT_DEV_END)
+		return tape_34xx_done(device, request);
+
+	DBF_EVENT(6, "xunknownirq\n");
+	PRINT_ERR("Unexpected interrupt.\n");
+	PRINT_ERR("Current op is: %s", tape_op_verbose[request->op]);
+	tape_dump_sense(device, request, irb);
+	return TAPE_IO_STOP;
+}
+
+/*
+ * ioctl_overload
+ */
+static int
+tape_34xx_ioctl(struct tape_device *device,
+		unsigned int cmd, unsigned long arg)
+{
+	if (cmd == TAPE390_DISPLAY)
+		return tape_std_display(device, cmd, arg);
+	else
+		return -EINVAL;
+}
+
+static int
+tape_34xx_setup_device(struct tape_device * device)
+{
+	DBF_EVENT(6, "34xx minor1: %x\n", device->first_minor);
+	tape_34xx_medium_sense(device);
+	return 0;
+}
+
+static void
+tape_34xx_cleanup_device(struct tape_device * device)
+{
+	if (device->discdata) {
+		kfree(device->discdata);
+		device->discdata = NULL;
+	}
+}
+
+/*
+ * MTTELL: Tell block. Return the number of block relative to current file.
+ */
+static int
+tape_34xx_mttell(struct tape_device *device, int mt_count)
+{
+	__u64 block_id;
+	int rc;
+
+	rc = tape_std_read_block_id(device, &block_id);
+	if (rc)
+		return rc;
+	return (block_id >> 32) & 0x3fffff;
+}
+
+/*
+ * MTSEEK: seek to the specified block.
+ */
+static int
+tape_34xx_mtseek(struct tape_device *device, int mt_count)
+{
+	struct tape_request *request;
+
+	if (mt_count > 0x400000) {
+		DBF_EXCEPTION(6, "xsee parm\n");
+		return -EINVAL;
+	}
+	request = tape_alloc_request(3, 4);
+	if (IS_ERR(request))
+		return PTR_ERR(request);
+	request->op = TO_LBL;
+	/* setup ccws */
+	tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
+	*(__u32 *) request->cpdata = mt_count |
+		((*device->modeset_byte & 0x08) ? 0x01800000 : 0x01000000);
+	tape_ccw_cc(request->cpaddr + 1, LOCATE, 4, request->cpdata);
+	tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
+	/* execute it */
+	return tape_do_io_free(device, request);
+}
+
+#ifdef CONFIG_S390_TAPE_BLOCK
+/*
+ * Tape block read for 34xx.
+ */
+static struct tape_request *
+tape_34xx_bread(struct tape_device *device, struct request *req)
+{
+	struct tape_request *request;
+	struct ccw1 *ccw;
+	int count = 0,start_block,i;
+	unsigned off;
+	char *dst;
+	struct bio_vec *bv;
+	struct bio *bio;
+
+	DBF_EVENT(6, "xBREDid:");
+	start_block = req->sector >> TAPEBLOCK_HSEC_S2B;
+	DBF_EVENT(6, "start_block = %i\n", start_block);
+
+	/* Count the number of blocks for the request. */
+	rq_for_each_bio(bio, req) {
+		bio_for_each_segment(bv, bio, i) {
+			count += bv->bv_len >> (TAPEBLOCK_HSEC_S2B + 9);
+		}
+	}
+	/* Allocate the ccw request. */
+	request = tape_alloc_request(2+count+1, 4);
+	if (IS_ERR(request))
+		return request;
+	/* Setup ccws. */
+	request->op = TO_BLOCK;
+	*(__u32 *) request->cpdata = (start_block & 0x3fffff) |
+		((*device->modeset_byte & 0x08) ? 0x81000000 : 0x01000000);
+	ccw = request->cpaddr;
+	ccw = tape_ccw_cc(ccw, MODE_SET_DB, 1, device->modeset_byte);
+
+	/*
+	 * We always setup a nop after the mode set ccw. This slot is
+	 * used in tape_std_check_locate to insert a locate ccw if the
+	 * current tape position doesn't match the start block to be read.
+	 */
+	ccw = tape_ccw_cc(ccw, NOP, 0, NULL);
+
+	rq_for_each_bio(bio, req) {
+		bio_for_each_segment(bv, bio, i) {
+			dst = kmap(bv->bv_page) + bv->bv_offset;
+			for (off = 0; off < bv->bv_len;
+			     off += TAPEBLOCK_HSEC_SIZE) {
+				ccw->flags = CCW_FLAG_CC;
+				ccw->cmd_code = READ_FORWARD;
+				ccw->count = TAPEBLOCK_HSEC_SIZE;
+				set_normalized_cda(ccw, (void*) __pa(dst));
+				ccw++;
+				dst += TAPEBLOCK_HSEC_SIZE;
+			}
+		}
+	}
+
+	ccw = tape_ccw_end(ccw, NOP, 0, NULL);
+	DBF_EVENT(6, "xBREDccwg\n");
+	return request;
+}
+
+static void
+tape_34xx_free_bread (struct tape_request *request)
+{
+	struct ccw1* ccw;
+
+	/* Last ccw is a nop and doesn't need clear_normalized_cda */
+	for (ccw = request->cpaddr; ccw->flags & CCW_FLAG_CC; ccw++)
+		if (ccw->cmd_code == READ_FORWARD)
+			clear_normalized_cda(ccw);
+	tape_free_request(request);
+}
+
+/*
+ * check_locate is called just before the tape request is passed to
+ * the common io layer for execution. It has to check the current
+ * tape position and insert a locate ccw if it doesn't match the
+ * start block for the request.
+ */
+static void
+tape_34xx_check_locate (struct tape_device *device,
+			struct tape_request *request)
+{
+	int start_block;
+
+	start_block = *(__u32 *) request->cpdata & 0x3fffff;
+	if (start_block != device->blk_data.block_position)
+		tape_ccw_cc(request->cpaddr + 1, LOCATE, 4, request->cpdata);
+}
+#endif
+
+/*
+ * List of 3480/3490 magnetic tape commands.
+ */
+static tape_mtop_fn tape_34xx_mtop[TAPE_NR_MTOPS] = {
+	[MTRESET]	 = tape_std_mtreset,
+	[MTFSF]		 = tape_std_mtfsf,
+	[MTBSF]		 = tape_std_mtbsf,
+	[MTFSR]		 = tape_std_mtfsr,
+	[MTBSR]		 = tape_std_mtbsr,
+	[MTWEOF]	 = tape_std_mtweof,
+	[MTREW]		 = tape_std_mtrew,
+	[MTOFFL]	 = tape_std_mtoffl,
+	[MTNOP]		 = tape_std_mtnop,
+	[MTRETEN]	 = tape_std_mtreten,
+	[MTBSFM]	 = tape_std_mtbsfm,
+	[MTFSFM]	 = tape_std_mtfsfm,
+	[MTEOM]		 = tape_std_mteom,
+	[MTERASE]	 = tape_std_mterase,
+	[MTRAS1]	 = NULL,
+	[MTRAS2]	 = NULL,
+	[MTRAS3]	 = NULL,
+	[MTSETBLK]	 = tape_std_mtsetblk,
+	[MTSETDENSITY]	 = NULL,
+	[MTSEEK]	 = tape_34xx_mtseek,
+	[MTTELL]	 = tape_34xx_mttell,
+	[MTSETDRVBUFFER] = NULL,
+	[MTFSS]		 = NULL,
+	[MTBSS]		 = NULL,
+	[MTWSM]		 = NULL,
+	[MTLOCK]	 = NULL,
+	[MTUNLOCK]	 = NULL,
+	[MTLOAD]	 = tape_std_mtload,
+	[MTUNLOAD]	 = tape_std_mtunload,
+	[MTCOMPRESSION]	 = tape_std_mtcompression,
+	[MTSETPART]	 = NULL,
+	[MTMKPART]	 = NULL
+};
+
+/*
+ * Tape discipline structure for 3480 and 3490.
+ */
+static struct tape_discipline tape_discipline_34xx = {
+	.owner = THIS_MODULE,
+	.setup_device = tape_34xx_setup_device,
+	.cleanup_device = tape_34xx_cleanup_device,
+	.process_eov = tape_std_process_eov,
+	.irq = tape_34xx_irq,
+	.read_block = tape_std_read_block,
+	.write_block = tape_std_write_block,
+	.assign = tape_std_assign,
+	.unassign = tape_std_unassign,
+#ifdef CONFIG_S390_TAPE_BLOCK
+	.bread = tape_34xx_bread,
+	.free_bread = tape_34xx_free_bread,
+	.check_locate = tape_34xx_check_locate,
+#endif
+	.ioctl_fn = tape_34xx_ioctl,
+	.mtop_array = tape_34xx_mtop
+};
+
+static struct ccw_device_id tape_34xx_ids[] = {
+	{ CCW_DEVICE_DEVTYPE(0x3480, 0, 0x3480, 0), driver_info: tape_3480},
+	{ CCW_DEVICE_DEVTYPE(0x3490, 0, 0x3490, 0), driver_info: tape_3490},
+	{ /* end of list */ }
+};
+
+static int
+tape_34xx_enable(struct ccw_device *cdev)
+{
+	return tape_enable_device(cdev->dev.driver_data,
+				  &tape_discipline_34xx);
+}
+
+static int
+tape_34xx_disable(struct ccw_device *cdev)
+{
+	tape_disable_device(cdev->dev.driver_data);
+	return 0;
+}
+
+static struct ccw_driver tape_34xx_driver = {
+	.name = "tape_34xx",
+	.owner = THIS_MODULE,
+	.ids = tape_34xx_ids,
+	.probe = tape_generic_probe,
+	.remove = tape_generic_remove,
+	.set_online = tape_34xx_enable,
+	.set_offline = tape_34xx_disable,
+};
+
+static int
+tape_34xx_init (void)
+{
+	int rc;
+
+	DBF_EVENT(3, "34xx init: $Revision: 1.6 $\n");
+	/* Register driver for 3480/3490 tapes. */
+	rc = ccw_driver_register(&tape_34xx_driver);
+	if (rc)
+		DBF_EVENT(3, "34xx init failed\n");
+	else
+		DBF_EVENT(3, "34xx registered\n");
+	return rc;
+}
+
+static void
+tape_34xx_exit(void)
+{
+	ccw_driver_unregister(&tape_34xx_driver);
+}
+
+MODULE_DEVICE_TABLE(ccw, tape_34xx_ids);
+MODULE_AUTHOR("(C) 2001-2002 IBM Deutschland Entwicklung GmbH");
+MODULE_DESCRIPTION("Linux on zSeries channel attached 3480 tape "
+		   "device driver ($Revision: 1.6 $)");
+MODULE_LICENSE("GPL");
+
+module_init(tape_34xx_init);
+module_exit(tape_34xx_exit);
diff -Nru a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/char/tape_block.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,355 @@
+/*
+ *  drivers/s390/char/tape_block.c
+ *    block device frontend for tape device driver
+ *
+ *  S390 and zSeries version
+ *    Copyright (C) 2001,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Author(s): Carsten Otte <cotte@de.ibm.com>
+ *		 Tuan Ngo-Anh <ngoanh@de.ibm.com>
+ *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/blkdev.h>
+#include <linux/blk.h>
+#include <linux/interrupt.h>
+#include <linux/buffer_head.h>
+
+#include <asm/debug.h>
+
+#include "tape.h"
+
+#define PRINTK_HEADER "TBLOCK:"
+
+#define TAPEBLOCK_MAX_SEC	100
+#define TAPEBLOCK_MIN_REQUEUE	3
+
+/*
+ * file operation structure for tape block frontend
+ */
+static int tapeblock_open(struct inode *, struct file *);
+static int tapeblock_release(struct inode *, struct file *);
+
+static struct block_device_operations tapeblock_fops = {
+	.owner		= THIS_MODULE,
+	.open		= tapeblock_open,
+	.release	= tapeblock_release,
+};
+
+static int tapeblock_major = 0;
+
+/*
+ * Post finished request.
+ */
+static inline void
+tapeblock_end_request(struct request *req, int uptodate)
+{
+	if (end_that_request_first(req, uptodate, req->hard_nr_sectors))
+		BUG();
+	end_that_request_last(req);
+}
+
+static void
+__tapeblock_end_request(struct tape_request *ccw_req, void *data)
+{
+	struct tape_device *device;
+	struct request *req;
+
+	device = ccw_req->device;
+	req = (struct request *) data;
+	tapeblock_end_request(req, ccw_req->rc == 0);
+	if (ccw_req->rc == 0)
+		/* Update position. */
+		device->blk_data.block_position =
+			(req->sector + req->nr_sectors) >> TAPEBLOCK_HSEC_S2B;
+	else
+		/* We lost the position information due to an error. */
+		device->blk_data.block_position = -1;
+	device->discipline->free_bread(ccw_req);
+	if (!list_empty(&device->req_queue) ||
+	    !blk_queue_empty(&device->blk_data.request_queue))
+		tasklet_schedule(&device->blk_data.tasklet);
+}
+
+/*
+ * Fetch requests from block device queue.
+ */
+static inline void
+__tape_process_blk_queue(struct tape_device *device, struct list_head *new_req)
+{
+	request_queue_t *queue;
+	struct list_head *l;
+	struct request *req;
+	struct tape_request *ccw_req;
+	int nr_queued;
+
+	/* FIXME: we have to make sure that the tapeblock frontend
+	   owns the device. tape_state != TS_IN_USE is NOT enough. */
+	if (device->tape_state != TS_IN_USE)
+		return;
+	queue = &device->blk_data.request_queue;
+	nr_queued = 0;
+	/* Count number of requests on ccw queue. */
+	list_for_each(l, &device->req_queue)
+		nr_queued++;
+	while (!blk_queue_plugged(queue) &&
+	       !blk_queue_empty(queue) &&
+	       nr_queued < TAPEBLOCK_MIN_REQUEUE) {
+		req = elv_next_request(queue);
+		if (rq_data_dir(req) == WRITE) {
+			DBF_EVENT(1, "TBLOCK: Rejecting write request\n");
+			blkdev_dequeue_request(req);
+			tapeblock_end_request(req, 0);
+			continue;
+		}
+		ccw_req = device->discipline->bread(device, req);
+		if (IS_ERR(ccw_req)) {
+			if (PTR_ERR(ccw_req) == -ENOMEM)
+				break; /* don't try again */
+			DBF_EVENT(1, "TBLOCK: bread failed\n");
+			blkdev_dequeue_request(req);
+			tapeblock_end_request(req, 0);
+			continue;
+		}
+		ccw_req->callback = __tapeblock_end_request;
+		ccw_req->callback_data = (void *) req;
+		ccw_req->retries = TAPEBLOCK_RETRIES;
+		blkdev_dequeue_request(req);
+		list_add_tail(new_req, &ccw_req->list);
+		nr_queued++;
+	}
+}
+
+/*
+ * Feed requests to the tape device.
+ */
+static inline int
+tape_queue_requests(struct tape_device *device, struct list_head *new_req)
+{
+	struct list_head *l, *n;
+	struct tape_request *ccw_req;
+	struct request *req;
+	int rc, fail;
+
+	fail = 0;
+	list_for_each_safe(l, n, new_req) {
+		ccw_req = list_entry(l, struct tape_request, list);
+		list_del(&ccw_req->list);
+		rc = tape_do_io_async(device, ccw_req);
+		if (rc) {
+			/*
+			 * Start/enqueueing failed. No retries in
+			 * this case.
+			 */
+			req = (struct request *) ccw_req->callback_data;
+			tapeblock_end_request(req, 0);
+			device->discipline->free_bread(ccw_req);
+			fail = 1;
+		}
+	}
+	return fail;
+}
+
+/*
+ * Tape request queue function. Called from ll_rw_blk.c
+ */
+static void
+tapeblock_request_fn(request_queue_t *queue)
+{
+	struct list_head new_req;
+	struct tape_device *device;
+
+	device = (struct tape_device *) queue->queuedata;
+	while (!blk_queue_empty(queue)) {
+		INIT_LIST_HEAD(&new_req);
+		spin_lock(get_ccwdev_lock(device->cdev));
+		__tape_process_blk_queue(device, &new_req);
+		spin_unlock(get_ccwdev_lock(device->cdev));
+		/*
+		 * Now queue the new request to the tape. This needs to be
+		 * done without the device lock held.
+		 */
+		if (tape_queue_requests(device, &new_req) == 0)
+			/* All requests queued. Thats enough for now. */
+			break;
+	}
+}
+
+/*
+ * Acquire the device lock and process queues for the device.
+ */
+static void
+tapeblock_tasklet(unsigned long data)
+{
+	struct list_head new_req;
+	struct tape_device *device;
+
+	device = (struct tape_device *) data;
+	while (!blk_queue_empty(&device->blk_data.request_queue)) {
+		INIT_LIST_HEAD(&new_req);
+		spin_lock_irq(get_ccwdev_lock(device->cdev));
+		__tape_process_blk_queue(device, &new_req);
+		spin_unlock_irq(get_ccwdev_lock(device->cdev));
+		/*
+		 * Now queue the new request to the tape. This needs to be
+		 * done without the device lock held.
+		 */
+		if (tape_queue_requests(device, &new_req) == 0)
+			/* All requests queued. Thats enough for now. */
+			break;
+	}
+}
+
+/*
+ * This function is called for every new tapedevice
+ */
+int
+tapeblock_setup_device(struct tape_device * device)
+{
+	request_queue_t *blk_queue;
+	int rc;
+
+	/* Setup request queue and initialize gendisk for this device. */
+	tasklet_init(&device->blk_data.tasklet, tapeblock_tasklet,
+		     (unsigned long) device);
+	spin_lock_init(&device->blk_data.request_queue_lock);
+	blk_queue = &device->blk_data.request_queue;
+	rc = blk_init_queue(blk_queue, tapeblock_request_fn,
+			    &device->blk_data.request_queue_lock);
+
+	elevator_exit(blk_queue);
+	rc = elevator_init(blk_queue, &elevator_noop);
+	if (rc) {
+		blk_cleanup_queue(blk_queue);
+		return rc;
+	}
+	/* FIXME: We should be able to sense the sectore size */
+	blk_queue_hardsect_size(blk_queue, TAPEBLOCK_HSEC_SIZE);
+	blk_queue_max_sectors(blk_queue, TAPEBLOCK_MAX_SEC);
+	blk_queue_max_phys_segments(blk_queue, -1L);
+	blk_queue_max_hw_segments(blk_queue, -1L);
+	blk_queue_max_segment_size(blk_queue, -1L);
+	blk_queue_segment_boundary(blk_queue, -1L);
+	return 0;
+}
+
+void
+tapeblock_cleanup_device(struct tape_device *device)
+{
+	blk_cleanup_queue(&device->blk_data.request_queue);
+	tasklet_kill(&device->blk_data.tasklet);
+}
+
+/*
+ * Detect number of blocks of the tape.
+ * FIXME: can we extent this to detect the blocks size as well ?
+ */
+static int tapeblock_mediumdetect(struct tape_device *device)
+{
+	unsigned int nr_of_blks;
+	int rc;
+
+	PRINT_INFO("Detecting media size...\n");
+	rc = tape_mtop(device, MTREW, 1);
+	if (rc)
+		return rc;
+	rc = tape_mtop(device, MTFSF, 1);
+	if (rc)
+		return rc;
+	rc = tape_mtop(device, MTTELL, 1);
+	if (rc)
+		return rc;
+	nr_of_blks = rc - 1; /* don't count FM */
+	rc = tape_mtop(device, MTREW, 1);
+	if (rc)
+		return rc;
+	PRINT_INFO("Found %i blocks on media\n", nr_of_blks);
+	return 0;
+}
+
+/*
+ * Block frontend tape device open function.
+ */
+int
+tapeblock_open(struct inode *inode, struct file *filp) {
+	struct tape_device *device;
+	int minor, rc;
+
+	MOD_INC_USE_COUNT;
+	if (major(filp->f_dentry->d_inode->i_rdev) != tapeblock_major)
+		return -ENODEV;
+	minor = minor(filp->f_dentry->d_inode->i_rdev);
+	device = tape_get_device(minor >> TAPE_MINORS_PER_DEV);
+	if (IS_ERR(device)) {
+		MOD_DEC_USE_COUNT;
+		return PTR_ERR(device);
+	}
+	DBF_EVENT(6, "TBLOCK:open:  %x\n", device->first_minor);
+	rc = tape_open(device);
+	if (rc == 0) {
+		rc = tape_assign(device);
+		if (rc == 0) {
+			device->blk_data.block_position = -1;
+			rc = tapeblock_mediumdetect(device);
+			if (rc == 0) {
+				filp->private_data = device;
+				return 0;
+			}
+			tape_unassign(device);
+		}
+		tape_release(device);
+	}
+	tape_put_device(device);
+	MOD_DEC_USE_COUNT;
+	return rc;
+}
+
+/*
+ * Block frontend tape device release function.
+ */
+int
+tapeblock_release(struct inode *inode, struct file *filp) {
+	struct tape_device *device;
+
+	/* Remove all buffers at device close. */
+	/* FIXME: can we do that a tape unload ? */
+	invalidate_buffers(inode->i_rdev);
+	device = (struct tape_device *) filp->private_data;
+	tape_release(device);
+	tape_unassign(device);
+	tape_put_device(device);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+/*
+ * Initialize block device frontend.
+ */
+int
+tapeblock_init(void)
+{
+	int rc;
+
+	/* Register the tape major number to the kernel */
+	rc = register_blkdev(tapeblock_major, "tBLK", &tapeblock_fops);
+	if (rc < 0) {
+		PRINT_ERR("can't get major %d for block device\n",
+			  tapeblock_major);
+		return rc;
+	}
+	if (tapeblock_major == 0)
+		tapeblock_major = rc;
+	PRINT_INFO("tape gets major %d for block device\n", tapeblock_major);
+	return 0;
+}
+
+/*
+ * Deregister major for block device frontend
+ */
+void
+tapeblock_exit(void)
+{
+	unregister_blkdev(tapeblock_major, "tBLK");
+}
diff -Nru a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/char/tape_char.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,391 @@
+/*
+ *  drivers/s390/char/tape_char.c
+ *    character device frontend for tape device driver
+ *
+ *  S390 and zSeries version
+ *    Copyright (C) 2001,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Author(s): Carsten Otte <cotte@de.ibm.com>
+ *		 Michael Holzheu <holzheu@de.ibm.com>
+ *		 Tuan Ngo-Anh <ngoanh@de.ibm.com>
+ *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/mtio.h>
+
+#include <asm/uaccess.h>
+
+#include "tape.h"
+
+#define PRINTK_HEADER "TCHAR:"
+
+#define TAPECHAR_MAJOR		0	/* get dynamic major */
+
+/*
+ * file operation structure for tape character frontend
+ */
+static ssize_t tapechar_read(struct file *, char *, size_t, loff_t *);
+static ssize_t tapechar_write(struct file *, const char *, size_t, loff_t *);
+static int tapechar_open(struct inode *,struct file *);
+static int tapechar_release(struct inode *,struct file *);
+static int tapechar_ioctl(struct inode *, struct file *, unsigned int,
+			  unsigned long);
+
+static struct file_operations tape_fops =
+{
+	.read = tapechar_read,
+	.write = tapechar_write,
+	.ioctl = tapechar_ioctl,
+	.open = tapechar_open,
+	.release = tapechar_release,
+};
+
+static int tapechar_major = TAPECHAR_MAJOR;
+
+/*
+ * This function is called for every new tapedevice
+ */
+int
+tapechar_setup_device(struct tape_device * device)
+{
+	return 0;
+}
+
+void
+tapechar_cleanup_device(struct tape_device *device)
+{
+}
+
+/*
+ * Terminate write command (we write two TMs and skip backward over last)
+ * This ensures that the tape is always correctly terminated.
+ * When the user writes afterwards a new file, he will overwrite the
+ * second TM and therefore one TM will remain to seperate the
+ * two files on the tape...
+ */
+static inline void
+tapechar_terminate_write(struct tape_device *device)
+{
+	if (tape_mtop(device, MTWEOF, 1) == 0 &&
+	    tape_mtop(device, MTWEOF, 1) == 0)
+		tape_mtop(device, MTBSR, 1);
+}
+
+static inline int
+tapechar_check_idalbuffer(struct tape_device *device, size_t block_size)
+{
+	struct idal_buffer *new;
+
+	if (device->char_data.idal_buf != NULL &&
+	    device->char_data.idal_buf->size >= block_size)
+		return 0;
+	/* The current idal buffer is not big enough. Allocate a new one. */
+	new = idal_buffer_alloc(block_size, 0);
+	if (new == NULL)
+		return -ENOMEM;
+	if (device->char_data.idal_buf != NULL)
+		idal_buffer_free(device->char_data.idal_buf);
+	device->char_data.idal_buf = new;
+	return 0;
+}
+
+/*
+ * Tape device read function
+ */
+ssize_t
+tapechar_read (struct file *filp, char *data, size_t count, loff_t *ppos)
+{
+	struct tape_device *device;
+	struct tape_request *request;
+	size_t block_size;
+	int rc;
+
+	DBF_EVENT(6, "TCHAR:read\n");
+	device = (struct tape_device *) filp->private_data;
+	/* Check position. */
+	if (ppos != &filp->f_pos) {
+		/*
+		 * "A request was outside the capabilities of the device."
+		 * This check uses internal knowledge about how pread and
+		 * read work...
+		 */
+		DBF_EVENT(6, "TCHAR:ppos wrong\n");
+		return -EOVERFLOW;
+	}
+	/* Find out block size to use */
+	if (device->char_data.block_size != 0) {
+		if (count < device->char_data.block_size) {
+			DBF_EVENT(3, "TCHAR:read smaller than block "
+				  "size was requested\n");
+			return -EINVAL;
+		}
+		block_size = device->char_data.block_size;
+	} else {
+		block_size = count;
+		rc = tapechar_check_idalbuffer(device, block_size);
+		if (rc)
+			return rc;
+	}
+	DBF_EVENT(6, "TCHAR:nbytes: %lx\n", block_size);
+	/* Let the discipline build the ccw chain. */
+	request = device->discipline->read_block(device, block_size);
+	if (IS_ERR(request))
+		return PTR_ERR(request);
+	/* Execute it. */
+	rc = tape_do_io(device, request);
+	if (rc == 0) {
+		rc = block_size - request->rescnt;
+		DBF_EVENT(6, "TCHAR:rbytes:  %x\n", rc);
+		filp->f_pos += rc;
+		/* Copy data from idal buffer to user space. */
+		if (idal_buffer_to_user(device->char_data.idal_buf,
+					data, rc) != 0)
+			rc = -EFAULT;
+	}
+	tape_free_request(request);
+	return rc;
+}
+
+/*
+ * Tape device write function
+ */
+ssize_t
+tapechar_write(struct file *filp, const char *data, size_t count, loff_t *ppos)
+{
+	struct tape_device *device;
+	struct tape_request *request;
+	size_t block_size;
+	size_t written;
+	int nblocks;
+	int i, rc;
+
+	DBF_EVENT(6, "TCHAR:write\n");
+	device = (struct tape_device *) filp->private_data;
+	/* Check position */
+	if (ppos != &filp->f_pos) {
+		/* "A request was outside the capabilities of the device." */
+		DBF_EVENT(6, "TCHAR:ppos wrong\n");
+		return -EOVERFLOW;
+	}
+	/* Find out block size and number of blocks */
+	if (device->char_data.block_size != 0) {
+		if (count < device->char_data.block_size) {
+			DBF_EVENT(3, "TCHAR:write smaller than block "
+				  "size was requested\n");
+			return -EINVAL;
+		}
+		block_size = device->char_data.block_size;
+		nblocks = count / block_size;
+	} else {
+		block_size = count;
+		rc = tapechar_check_idalbuffer(device, block_size);
+		if (rc)
+			return rc;
+		nblocks = 1;
+	}
+	DBF_EVENT(6,"TCHAR:nbytes: %lx\n", block_size);
+	DBF_EVENT(6, "TCHAR:nblocks: %x\n", nblocks);
+	/* Let the discipline build the ccw chain. */
+	request = device->discipline->write_block(device, block_size);
+	if (IS_ERR(request))
+		return PTR_ERR(request);
+	rc = 0;
+	written = 0;
+	for (i = 0; i < nblocks; i++) {
+		/* Copy data from user space to idal buffer. */
+		if (idal_buffer_from_user(device->char_data.idal_buf,
+					  data, block_size)) {
+			rc = -EFAULT;
+			break;
+		}
+		rc = tape_do_io(device, request);
+		if (rc)
+			break;
+		DBF_EVENT(6, "TCHAR:wbytes: %lx\n",
+			  block_size - request->rescnt);
+		filp->f_pos += block_size - request->rescnt;
+		written += block_size - request->rescnt;
+		if (request->rescnt != 0)
+			break;
+		data += block_size;
+	}
+	tape_free_request(request);
+	if (rc == -ENOSPC) {
+		/*
+		 * Ok, the device has no more space. It has NOT written
+		 * the block.
+		 */
+		if (device->discipline->process_eov)
+			device->discipline->process_eov(device);
+		if (written > 0)
+			rc = 0;
+
+	}
+	return rc ? rc : written;
+}
+
+/*
+ * Character frontend tape device open function.
+ */
+int
+tapechar_open (struct inode *inode, struct file *filp)
+{
+	struct tape_device *device;
+	int minor, rc;
+
+	MOD_INC_USE_COUNT;
+	if (major(filp->f_dentry->d_inode->i_rdev) != tapechar_major)
+		return -ENODEV;
+	minor = minor(filp->f_dentry->d_inode->i_rdev);
+	device = tape_get_device(minor / TAPE_MINORS_PER_DEV);
+	if (IS_ERR(device)) {
+		MOD_DEC_USE_COUNT;
+		return PTR_ERR(device);
+	}
+	DBF_EVENT(6, "TCHAR:open: %x\n", minor(inode->i_rdev));
+	rc = tape_open(device);
+	if (rc == 0) {
+		rc = tape_assign(device);
+		if (rc == 0) {
+			filp->private_data = device;
+			return 0;
+		}
+		tape_release(device);
+	}
+	tape_put_device(device);
+	MOD_DEC_USE_COUNT;
+	return rc;
+}
+
+/*
+ * Character frontend tape device release function.
+ */
+
+int
+tapechar_release(struct inode *inode, struct file *filp)
+{
+	struct tape_device *device;
+
+	device = (struct tape_device *) filp->private_data;
+	DBF_EVENT(6, "TCHAR:release: %x\n", minor(inode->i_rdev));
+#if 0
+	// FIXME: this is broken. Either MTWEOF/MTWEOF/MTBSR is done
+	// EVERYTIME the user switches from write to something different
+	// or it is not done at all. The second is IMHO better because
+	// we should NEVER do something the user didn't request.
+	if (device->last_op == TO_WRI)
+		tapechar_terminate_write(device);
+#endif
+	/*
+	 * If this is the rewinding tape minor then rewind.
+	 */
+	if ((minor(inode->i_rdev) & 1) != 0)
+		tape_mtop(device, MTREW, 1);
+	if (device->char_data.idal_buf != NULL) {
+		idal_buffer_free(device->char_data.idal_buf);
+		device->char_data.idal_buf = NULL;
+	}
+	device->char_data.block_size = 0;
+	tape_release(device);
+	tape_unassign(device);
+	tape_put_device(device);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+/*
+ * Tape device io controls.
+ */
+static int
+tapechar_ioctl(struct inode *inp, struct file *filp,
+	       unsigned int no, unsigned long data)
+{
+	struct tape_device *device;
+	int rc;
+
+	DBF_EVENT(6, "TCHAR:ioct\n");
+
+	device = (struct tape_device *) filp->private_data;
+
+	if (no == MTIOCTOP) {
+		struct mtop op;
+
+		if (copy_from_user(&op, (char *) data, sizeof(op)) != 0)
+			return -EFAULT;
+		if (op.mt_count < 0)
+			return -EINVAL;
+		return tape_mtop(device, op.mt_op, op.mt_count);
+	}
+	if (no == MTIOCPOS) {
+		/* MTIOCPOS: query the tape position. */
+		struct mtpos pos;
+
+		rc = tape_mtop(device, MTTELL, 1);
+		if (rc < 0)
+			return rc;
+		pos.mt_blkno = rc;
+		if (copy_to_user((char *) data, &pos, sizeof(pos)) != 0)
+			return -EFAULT;
+		return 0;
+	}
+	if (no == MTIOCGET) {
+		/* MTIOCGET: query the tape drive status. */
+		struct mtget get;
+
+		memset(&get, 0, sizeof(get));
+		rc = tape_mtop(device, MTTELL, 1);
+		if (rc < 0)
+			return rc;
+		get.mt_type = MT_ISUNKNOWN;
+		get.mt_dsreg = device->tape_state;
+		/* FIXME: mt_gstat, mt_erreg, mt_fileno */
+		get.mt_resid = 0 /* device->devstat.rescnt */;
+		get.mt_gstat = 0;
+		get.mt_erreg = 0;
+		get.mt_fileno = 0;
+		get.mt_blkno = rc;
+		if (copy_to_user((char *) data, &get, sizeof(get)) != 0)
+			return -EFAULT;
+		return 0;
+	}
+	/* Try the discipline ioctl function. */
+	if (device->discipline->ioctl_fn == NULL)
+		return -EINVAL;
+	return device->discipline->ioctl_fn(device, no, data);
+}
+
+/*
+ * Initialize character device frontend.
+ */
+int
+tapechar_init (void)
+{
+	int rc;
+
+	/* Register the tape major number to the kernel */
+	rc = register_chrdev(tapechar_major, "tape", &tape_fops);
+	if (rc < 0) {
+		PRINT_ERR("can't get major %d\n", tapechar_major);
+		DBF_EVENT(3, "TCHAR:initfail\n");
+		return rc;
+	}
+	if (tapechar_major == 0)
+		tapechar_major = rc;  /* accept dynamic major number */
+	PRINT_ERR("Tape gets major %d for char device\n", tapechar_major);
+	DBF_EVENT(3, "Tape gets major %d for char device\n", rc);
+	DBF_EVENT(3, "TCHAR:init ok\n");
+	return 0;
+}
+
+/*
+ * cleanup
+ */
+void
+tapechar_exit(void)
+{
+	unregister_chrdev (tapechar_major, "tape");
+}
diff -Nru a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/char/tape_core.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,950 @@
+/*
+ *  drivers/s390/char/tape_core.c
+ *    basic function of the tape device driver
+ *
+ *  S390 and zSeries version
+ *    Copyright (C) 2001,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Author(s): Carsten Otte <cotte@de.ibm.com>
+ *		 Michael Holzheu <holzheu@de.ibm.com>
+ *		 Tuan Ngo-Anh <ngoanh@de.ibm.com>
+ *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>	     // for kernel parameters
+#include <linux/kmod.h>	     // for requesting modules
+#include <linux/spinlock.h>  // for locks
+#include <linux/vmalloc.h>
+#include <linux/list.h>
+
+#include <asm/types.h>	     // for variable types
+
+#include "tape.h"
+#include "tape_std.h"
+
+#define PRINTK_HEADER "T390:"
+
+static void tape_do_irq (struct ccw_device *, unsigned long, struct irb *);
+
+/*
+ * One list to contain all tape devices of all disciplines, so
+ * we can assign the devices to minor numbers of the same major
+ * The list is protected by the rwlock
+ */
+static struct list_head tape_device_list = LIST_HEAD_INIT(tape_device_list);
+static rwlock_t tape_device_lock = RW_LOCK_UNLOCKED;
+
+/*
+ * Wait queue for tape_delete_device waits.
+ */
+static DECLARE_WAIT_QUEUE_HEAD(tape_delete_wq);
+
+/*
+ * Pointer to debug area.
+ */
+debug_info_t *tape_dbf_area = NULL;
+
+/*
+ * Printable strings for tape enumerations.
+ */
+const char *tape_state_verbose[TS_SIZE] =
+{
+	[TS_UNUSED] = "UNUSED",	[TS_IN_USE] = "IN_USE",
+	[TS_INIT] = "INIT  ",	[TS_NOT_OPER] = "NOT_OP"
+};
+
+const char *tape_op_verbose[TO_SIZE] =
+{
+	[TO_BLOCK] = "BLK",	[TO_BSB] = "BSB",
+	[TO_BSF] = "BSF",	[TO_DSE] = "DSE",
+	[TO_FSB] = "FSB",	[TO_FSF] = "FSF",
+	[TO_LBL] = "LBL",	[TO_NOP] = "NOP",
+	[TO_RBA] = "RBA",	[TO_RBI] = "RBI",
+	[TO_RFO] = "RFO",	[TO_REW] = "REW",
+	[TO_RUN] = "RUN",	[TO_WRI] = "WRI",
+	[TO_WTM] = "WTM",	[TO_MSEN] = "MSN",
+	[TO_LOAD] = "LOA",	[TO_READ_CONFIG] = "RCF",
+	[TO_READ_ATTMSG] = "RAT",
+	[TO_DIS] = "DIS",	[TO_ASSIGN] = "ASS",
+	[TO_UNASSIGN] = "UAS"
+};
+
+/*
+ * Tape state functions
+ */
+static void
+tape_state_set(struct tape_device *device, enum tape_state newstate)
+{
+	const char *str;
+
+	if (device->tape_state == TS_NOT_OPER) {
+		DBF_EVENT(3, "ts_set err: not oper\n");
+		return;
+	}
+	DBF_EVENT(4, "ts. dev:	%x\n", device->first_minor);
+	if (device->tape_state < TO_SIZE && device->tape_state >= 0)
+		str = tape_state_verbose[device->tape_state];
+	else
+		str = "UNKNOWN TS";
+	DBF_EVENT(4, "old ts:	%s\n", str);
+	if (device->tape_state < TO_SIZE && device->tape_state >=0 )
+		str = tape_state_verbose[device->tape_state];
+	else
+		str = "UNKNOWN TS";
+	DBF_EVENT(4, "%s\n", str);
+	DBF_EVENT(4, "new ts:\t\n");
+	if (newstate < TO_SIZE && newstate >= 0)
+		str = tape_state_verbose[newstate];
+	else
+		str = "UNKNOWN TS";
+	DBF_EVENT(4, "%s\n", str);
+	device->tape_state = newstate;
+	wake_up(&device->state_change_wq);
+}
+
+void
+tape_med_state_set(struct tape_device *device, enum tape_medium_state newstate)
+{
+	if (device->medium_state == newstate)
+		return;
+	switch(newstate){
+	case MS_UNLOADED:
+		device->tape_generic_status |= GMT_DR_OPEN(~0);
+		PRINT_INFO("(%s): Tape is unloaded\n",
+			   device->cdev->dev.bus_id);
+		break;
+	case MS_LOADED:
+		device->tape_generic_status &= ~GMT_DR_OPEN(~0);
+		PRINT_INFO("(%s): Tape has been mounted\n",
+			   device->cdev->dev.bus_id);
+		break;
+	default:
+		// print nothing
+		break;
+	}
+	device->medium_state = newstate;
+	wake_up(&device->state_change_wq);
+}
+
+/*
+ * Stop running ccw. Has to be called with the device lock held.
+ */
+static inline int
+__tape_halt_io(struct tape_device *device, struct tape_request *request)
+{
+	int retries;
+	int rc;
+
+	/* Check if interrupt has already been processed */
+	if (request->callback == NULL)
+		return 0;
+	rc = 0;
+	for (retries = 0; retries < 5; retries++) {
+		if (retries < 2)
+			rc = ccw_device_halt(device->cdev, (long) request);
+		else
+			rc = ccw_device_clear(device->cdev, (long) request);
+		if (rc == 0)
+			break;		/* termination successful */
+		if (rc == -ENODEV)
+			DBF_EXCEPTION(2, "device gone, retry\n");
+		else if (rc == -EIO)
+			DBF_EXCEPTION(2, "I/O error, retry\n");
+		else if (rc == -EBUSY)
+			DBF_EXCEPTION(2, "device busy, retry late\n");
+		else
+			BUG();
+	}
+	if (rc == 0)
+		request->status = TAPE_REQUEST_DONE;
+	return rc;
+}
+
+/*
+ * Add device into the sorted list, giving it the first
+ * available minor number.
+ */
+static int
+tape_assign_minor(struct tape_device *device)
+{
+	struct tape_device *tmp;
+	int minor;
+
+	minor = 0;
+	write_lock(&tape_device_lock);
+	list_for_each_entry(tmp, &tape_device_list, node) {
+		if (minor < tmp->first_minor)
+			break;
+		minor += TAPE_MINORS_PER_DEV;
+	}
+	if (minor >= (1 << KDEV_MINOR_BITS)) {
+		write_unlock(&tape_device_lock);
+		return -ENODEV;
+	}
+	device->first_minor = minor;
+	list_add_tail(&device->node, &tmp->node);
+	write_unlock(&tape_device_lock);
+	return 0;
+}
+
+/* remove device from the list */
+static void
+tape_remove_minor(struct tape_device *device)
+{
+	write_lock(&tape_device_lock);
+	list_del_init(&device->node);
+	device->first_minor = -1;
+	write_unlock(&tape_device_lock);
+}
+
+/*
+ * Enable tape device
+ */
+int
+tape_enable_device(struct tape_device *device,
+		   struct tape_discipline *discipline)
+{
+	int rc;
+
+	if (device->tape_state != TS_INIT)
+		return -EINVAL;
+
+	/* Let the discipline have a go at the device. */
+	device->discipline = discipline;
+	rc = discipline->setup_device(device);
+	if (rc)
+		goto out;
+	rc = tape_assign_minor(device);
+	if (rc)
+		goto out_discipline;
+	rc = tapechar_setup_device(device);
+	if (rc)
+		goto out_minor;
+	rc = tapeblock_setup_device(device);
+	if (rc)
+		goto out_char;
+
+	tape_state_set(device, TS_UNUSED);
+	return 0;
+
+out_char:
+	tapechar_cleanup_device(device);
+out_discipline:
+	device->discipline->cleanup_device(device);
+	device->discipline = NULL;
+out_minor:
+	tape_remove_minor(device);
+out:
+	return rc;
+}
+
+/*
+ * Disable tape device. Check if there is a running request and
+ * terminate it. Post all queued requests with -EIO.
+ */
+void
+tape_disable_device(struct tape_device *device)
+{
+	struct list_head *l, *n;
+	struct tape_request *request;
+
+	spin_lock_irq(get_ccwdev_lock(device->cdev));
+	tape_state_set(device, TS_NOT_OPER);
+	/* Post remaining requests with -EIO */
+	list_for_each_safe(l, n, &device->req_queue) {
+		request = list_entry(l, struct tape_request, list);
+		if (request->status == TAPE_REQUEST_IN_IO)
+			__tape_halt_io(device, request);
+		list_del(&request->list);
+		/* Decrease ref_count for removed request. */
+		tape_put_device(device);
+		request->rc = -EIO;
+		if (request->callback != NULL)
+			request->callback(request, request->callback_data);
+	}
+	spin_unlock_irq(get_ccwdev_lock(device->cdev));
+
+	tapeblock_cleanup_device(device);
+	tapechar_cleanup_device(device);
+	device->discipline->cleanup_device(device);
+	tape_remove_minor(device);
+}
+
+/*
+ * Allocate memory for a new device structure.
+ */
+static struct tape_device *
+tape_alloc_device(void)
+{
+	struct tape_device *device;
+
+	device = (struct tape_device *)
+		kmalloc(sizeof(struct tape_device), GFP_KERNEL);
+	if (device == NULL) {
+		DBF_EXCEPTION(2, "ti:no mem\n");
+		PRINT_INFO ("can't allocate memory for "
+			    "tape info structure\n");
+		return ERR_PTR(-ENOMEM);
+	}
+	memset(device, 0, sizeof(struct tape_device));
+	device->modeset_byte = (char *) kmalloc(1, GFP_KERNEL | GFP_DMA);
+	if (device->modeset_byte == NULL) {
+		DBF_EXCEPTION(2, "ti:no mem\n");
+		PRINT_INFO("can't allocate memory for modeset byte\n");
+		kfree(device);
+		return ERR_PTR(-ENOMEM);
+	}
+	INIT_LIST_HEAD(&device->req_queue);
+	INIT_LIST_HEAD(&device->node);
+	init_waitqueue_head(&device->state_change_wq);
+	device->tape_state = TS_INIT;
+	device->medium_state = MS_UNKNOWN;
+	*device->modeset_byte = 0;
+	return device;
+}
+
+/*
+ * Free memory of a device structure.
+ */
+static void
+tape_free_device(struct tape_device *device)
+{
+	kfree(device->modeset_byte);
+	kfree(device);
+}
+
+/*
+ * Find tape device by a device index.
+ */
+struct tape_device *
+tape_get_device(int devindex)
+{
+	struct tape_device *device, *tmp;
+
+	device = ERR_PTR(-ENODEV);
+	read_lock(&tape_device_lock);
+	list_for_each_entry(tmp, &tape_device_list, node) {
+		if (tmp->first_minor * TAPE_MINORS_PER_DEV == devindex) {
+			device = tmp;
+			atomic_inc(&device->ref_count);
+			break;
+		}
+	}
+	read_unlock(&tape_device_lock);
+	return device;
+}
+
+/*
+ * Decrease the reference counter of a devices structure. If the
+ * reference counter reaches zero free the device structure and
+ * wake up sleepers.
+ */
+void
+tape_put_device(struct tape_device *device)
+{
+	if (atomic_dec_return(&device->ref_count) > 0)
+		return;
+	/*
+	 * Reference counter dropped to zero. This means
+	 * that the device is deleted and the last user
+	 * of the device structure is gone. That is what
+	 * tape_delete_device is waiting for. Do a wake up.
+	 */
+	wake_up(&tape_delete_wq);
+}
+
+/*
+ * Driverfs tape probe function.
+ */
+int
+tape_generic_probe(struct ccw_device *cdev)
+{
+	struct tape_device *device;
+	char *bus_id = cdev->dev.bus_id;
+
+	device = tape_alloc_device();
+	if (IS_ERR(device))
+		return -ENODEV;
+	PRINT_INFO("tape device %s found\n", bus_id);
+	atomic_inc(&device->ref_count);
+	cdev->dev.driver_data = device;
+	device->cdev = cdev;
+	cdev->handler = tape_do_irq;
+
+	return 0;
+}
+
+/*
+ * Driverfs tape remove function.
+ */
+int
+tape_generic_remove(struct ccw_device *cdev)
+{
+	struct tape_device *device;
+
+	device = cdev->dev.driver_data;
+	cdev->dev.driver_data = NULL;
+	if (device != NULL) {
+		tape_put_device(device);
+		wait_event(tape_delete_wq, atomic_read(&device->ref_count) == 0);
+		tape_free_device(device);
+	}
+	return 0;
+}
+
+/*
+ * Allocate a new tape ccw request
+ */
+struct tape_request *
+tape_alloc_request(int cplength, int datasize)
+{
+	struct tape_request *request;
+
+	if (datasize > PAGE_SIZE || (cplength*sizeof(struct ccw1)) > PAGE_SIZE)
+		BUG();
+
+	request = (struct tape_request *) kmalloc(sizeof(struct tape_request),
+						  GFP_KERNEL);
+	if (request == NULL) {
+		DBF_EXCEPTION(1, "cqra nomem\n");
+		return ERR_PTR(-ENOMEM);
+	}
+	memset(request, 0, sizeof(struct tape_request));
+	/* allocate channel program */
+	if (cplength > 0) {
+		request->cpaddr = kmalloc(cplength*sizeof(struct ccw1),
+					  GFP_ATOMIC | GFP_DMA);
+		if (request->cpaddr == NULL) {
+			DBF_EXCEPTION(1, "cqra nomem\n");
+			kfree(request);
+			return ERR_PTR(-ENOMEM);
+		}
+		memset(request->cpaddr, 0, cplength*sizeof(struct ccw1));
+	}
+	/* alloc small kernel buffer */
+	if (datasize > 0) {
+		request->cpdata = kmalloc(datasize, GFP_KERNEL | GFP_DMA);
+		if (request->cpdata == NULL) {
+			DBF_EXCEPTION(1, "cqra nomem\n");
+			if (request->cpaddr != NULL)
+				kfree(request->cpaddr);
+			kfree(request);
+			return ERR_PTR(-ENOMEM);
+		}
+		memset(request->cpdata, 0, datasize);
+	}
+	return request;
+}
+
+/*
+ * Free tape ccw request
+ */
+void
+tape_free_request (struct tape_request * request)
+{
+	if (request->device != NULL) {
+		tape_put_device(request->device);
+		request->device = NULL;
+	}
+	if (request->cpdata != NULL)
+		kfree(request->cpdata);
+	if (request->cpaddr != NULL)
+		kfree(request->cpaddr);
+	kfree(request);
+}
+
+/*
+ * Write sense data to console/dbf
+ */
+void
+tape_dump_sense(struct tape_device* device, struct tape_request *request,
+		struct irb *irb)
+{
+	unsigned int *sptr;
+
+	PRINT_INFO("-------------------------------------------------\n");
+	PRINT_INFO("DSTAT : %02x  CSTAT: %02x	CPA: %04x\n",
+		   irb->scsw.dstat, irb->scsw.cstat, irb->scsw.cpa);
+	PRINT_INFO("DEVICE: %s\n", device->cdev->dev.bus_id);
+	if (request != NULL)
+		PRINT_INFO("OP	  : %s\n", tape_op_verbose[request->op]);
+
+	sptr = (unsigned int *) irb->ecw;
+	PRINT_INFO("Sense data: %08X %08X %08X %08X \n",
+		   sptr[0], sptr[1], sptr[2], sptr[3]);
+	PRINT_INFO("Sense data: %08X %08X %08X %08X \n",
+		   sptr[4], sptr[5], sptr[6], sptr[7]);
+	PRINT_INFO("--------------------------------------------------\n");
+}
+
+/*
+ * Write sense data to dbf
+ */
+void
+tape_dump_sense_dbf(struct tape_device *device, struct tape_request *request,
+		    struct irb *irb)
+{
+	unsigned int *sptr;
+	const char* op;
+
+	if (request != NULL)
+		op = tape_op_verbose[request->op];
+	else
+		op = "---";
+	DBF_EVENT(3, "DSTAT : %02x   CSTAT: %02x\n",
+		  irb->scsw.dstat,irb->scsw.cstat);
+	DBF_EVENT(3, "DEVICE: %s OP\t: %s\n", device->cdev->dev.bus_id,op);
+	sptr = (unsigned int *) irb->ecw;
+	DBF_EVENT(3, "%08x %08x\n", sptr[0], sptr[1]);
+	DBF_EVENT(3, "%08x %08x\n", sptr[2], sptr[3]);
+	DBF_EVENT(3, "%08x %08x\n", sptr[4], sptr[5]);
+	DBF_EVENT(3, "%08x %08x\n", sptr[6], sptr[7]);
+}
+
+/*
+ * I/O helper function. Adds the request to the request queue
+ * and starts it if the tape is idle. Has to be called with
+ * the device lock held.
+ */
+static inline int
+__tape_do_io(struct tape_device *device, struct tape_request *request)
+{
+	int rc;
+
+	if (device->tape_state != TS_IN_USE)
+		return -ENODEV;
+
+	/* Increase use count of device for the added request. */
+	atomic_inc(&device->ref_count);
+	request->device = device;
+
+	if (list_empty(&device->req_queue)) {
+		/* No other requests are on the queue. Start this one. */
+#ifdef CONFIG_S390_TAPE_BLOCK
+		if (request->op == TO_BLOCK)
+			device->discipline->check_locate(device, request);
+#endif
+		rc = ccw_device_start(device->cdev, request->cpaddr,
+				      (unsigned long) request, 0x00,
+				      request->options);
+		if (rc) {
+			DBF_EVENT(1, "tape: DOIO failed with rc = %i\n", rc);
+			return rc;
+		}
+		list_add(&request->list, &device->req_queue);
+		request->status = TAPE_REQUEST_IN_IO;
+	} else {
+		list_add_tail(&request->list, &device->req_queue);
+		request->status = TAPE_REQUEST_QUEUED;
+	}
+	return 0;
+}
+
+/*
+ * Add the request to the request queue, try to start it if the
+ * tape is idle. Return without waiting for end of i/o.
+ */
+int
+tape_do_io_async(struct tape_device *device, struct tape_request *request)
+{
+	int rc;
+
+	spin_lock_irq(get_ccwdev_lock(device->cdev));
+	/* Add request to request queue and try to start it. */
+	rc = __tape_do_io(device, request);
+	spin_unlock_irq(get_ccwdev_lock(device->cdev));
+	return rc;
+}
+
+/*
+ * tape_do_io/__tape_wake_up
+ * Add the request to the request queue, try to start it if the
+ * tape is idle and wait uninterruptible for its completion.
+ */
+static void
+__tape_wake_up(struct tape_request *request, void *data)
+{
+	request->callback = NULL;
+	wake_up((wait_queue_head_t *) data);
+}
+
+int
+tape_do_io(struct tape_device *device, struct tape_request *request)
+{
+	wait_queue_head_t wq;
+	int rc;
+
+	init_waitqueue_head(&wq);
+	spin_lock_irq(get_ccwdev_lock(device->cdev));
+	/* Setup callback */
+	request->callback = __tape_wake_up;
+	request->callback_data = &wq;
+	/* Add request to request queue and try to start it. */
+	rc = __tape_do_io(device, request);
+	spin_unlock_irq(get_ccwdev_lock(device->cdev));
+	if (rc)
+		return rc;
+	/* Request added to the queue. Wait for its completion. */
+	wait_event(wq, (request->callback == NULL));
+	/* Get rc from request */
+	return request->rc;
+}
+
+/*
+ * tape_do_io_interruptible/__tape_wake_up_interruptible
+ * Add the request to the request queue, try to start it if the
+ * tape is idle and wait uninterruptible for its completion.
+ */
+static void
+__tape_wake_up_interruptible(struct tape_request *request, void *data)
+{
+	request->callback = NULL;
+	wake_up_interruptible((wait_queue_head_t *) data);
+}
+
+int
+tape_do_io_interruptible(struct tape_device *device,
+			 struct tape_request *request)
+{
+	wait_queue_head_t wq;
+	int rc;
+
+	init_waitqueue_head(&wq);
+	spin_lock_irq(get_ccwdev_lock(device->cdev));
+	/* Setup callback */
+	request->callback = __tape_wake_up_interruptible;
+	request->callback_data = &wq;
+	rc = __tape_do_io(device, request);
+	spin_unlock_irq(get_ccwdev_lock(device->cdev));
+	if (rc)
+		return rc;
+	/* Request added to the queue. Wait for its completion. */
+	rc = wait_event_interruptible(wq, (request->callback == NULL));
+	if (rc != -ERESTARTSYS)
+		/* Request finished normally. */
+		return request->rc;
+	/* Interrupted by a signal. We have to stop the current request. */
+	spin_lock_irq(get_ccwdev_lock(device->cdev));
+	rc = __tape_halt_io(device, request);
+	if (rc == 0) {
+		DBF_EVENT(3, "IO stopped on %s\n", device->cdev->dev.bus_id);
+		rc = -ERESTARTSYS;
+	}
+	spin_unlock_irq(get_ccwdev_lock(device->cdev));
+	return rc;
+}
+
+static inline void
+__tape_do_io_list(struct tape_device *device)
+{
+	struct list_head *l, *n;
+	struct tape_request *request;
+	int rc;
+
+	if (device->tape_state != TS_IN_USE)
+		return;
+	/*
+	 * Try to start each request on request queue until one is
+	 * started successful.
+	 */
+	list_for_each_safe(l, n, &device->req_queue) {
+		request = list_entry(l, struct tape_request, list);
+#ifdef CONFIG_S390_TAPE_BLOCK
+		if (request->op == TO_BLOCK)
+			device->discipline->check_locate(device, request);
+#endif
+		rc = ccw_device_start(device->cdev, request->cpaddr,
+				      (unsigned long) request, 0x00,
+				      request->options);
+		if (rc == 0) {
+			request->status = TAPE_REQUEST_IN_IO;
+			break;
+		}
+		/* Start failed. Remove request and indicate failure. */
+		DBF_EVENT(1, "tape: DOIO failed with er = %i\n", rc);
+		list_del(&request->list);
+		/* Set ending status and do callback. */
+		request->rc = rc;
+		request->status = TAPE_REQUEST_DONE;
+		if (request->callback != NULL)
+			request->callback(request, request->callback_data);
+	}
+}
+
+/*
+ * Tape interrupt routine, called from the ccw_device layer
+ */
+static void
+tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
+{
+	struct tape_device *device;
+	struct tape_request *request;
+	int final;
+	int rc;
+
+	device = (struct tape_device *) cdev->dev.driver_data;
+	if (device == NULL) {
+		PRINT_ERR("could not get device structure for bus_id %s "
+			  "in interrupt\n", cdev->dev.bus_id);
+		return;
+	}
+	request = (struct tape_request *) intparm;
+
+	/* May be an unsolicited irq */
+	if(request != NULL)
+		request->rescnt = irb->scsw.count;
+
+	if (irb->scsw.dstat != 0x0c){
+		/* Set the 'ONLINE' flag depending on sense byte 1 */
+		if(*(((__u8 *) irb->ecw) + 1) & SENSE_DRIVE_ONLINE)
+			device->tape_generic_status |= GMT_ONLINE(~0);
+		else
+			device->tape_generic_status &= ~GMT_ONLINE(~0);
+
+		/*
+		 * Any request that does not come back with channel end
+		 * and device end is unusual. Log the sense data.
+		 */
+		DBF_EVENT(3,"-- Tape Interrupthandler --\n");
+		tape_dump_sense_dbf(device, request, irb);
+	} else {
+		/* Upon normal completion the device _is_ online */
+		device->tape_generic_status |= GMT_ONLINE(~0);
+	}
+	if (device->tape_state == TS_NOT_OPER) {
+		DBF_EVENT(6, "tape:device is not operational\n");
+		return;
+	}
+	rc = device->discipline->irq(device, request, irb);
+	/*
+	 * rc < 0 : request finished unsuccessfully.
+	 * rc == TAPE_IO_SUCCESS: request finished successfully.
+	 * rc == TAPE_IO_PENDING: request is still running. Ignore rc.
+	 * rc == TAPE_IO_RETRY: request finished but needs another go.
+	 * rc == TAPE_IO_STOP: request needs to get terminated.
+	 */
+	final = 0;
+	switch (rc) {
+	case TAPE_IO_SUCCESS:
+		final = 1;
+		break;
+	case TAPE_IO_PENDING:
+		break;
+	case TAPE_IO_RETRY:
+#ifdef CONFIG_S390_TAPE_BLOCK
+		if (request->op == TO_BLOCK)
+			device->discipline->check_locate(device, request);
+#endif
+		rc = ccw_device_start(cdev, request->cpaddr,
+				      (unsigned long) request, 0x00,
+				      request->options);
+		if (rc) {
+			DBF_EVENT(1, "tape: DOIO failed with er = %i\n", rc);
+			final = 1;
+		}
+		break;
+	case TAPE_IO_STOP:
+		__tape_halt_io(device, request);
+		rc = -EIO;
+		final = 1;
+		break;
+	default:
+		if (rc > 0) {
+			DBF_EVENT(6, "xunknownrc\n");
+			PRINT_ERR("Invalid return code from discipline "
+				  "interrupt function.\n");
+			rc = -EIO;
+		}
+		final = 1;
+		break;
+	}
+	if (final) {
+		/* May be an unsolicited irq */
+		if(request != NULL) {
+			/* Set ending status. */
+			request->rc = rc;
+			request->status = TAPE_REQUEST_DONE;
+			/* Remove from request queue. */
+			list_del(&request->list);
+			/* Do callback. */
+			if (request->callback != NULL)
+				request->callback(request, request->callback_data);
+		}
+		/* Start next request. */
+		__tape_do_io_list(device);
+	}
+}
+
+/*
+ * Lock a shared tape for our exclusive use.
+ */
+int
+tape_assign(struct tape_device *device)
+{
+	int rc;
+
+	rc = device->discipline->assign(device);
+	if (rc) {
+		PRINT_WARN("(%s): assign failed - device might be busy\n",
+			   device->cdev->dev.bus_id);
+		DBF_EVENT(3, "(%s): assign failed - device might be busy\n",
+			  device->cdev->dev.bus_id);
+		return rc;
+	}
+	DBF_EVENT(3, "(%s): assign lpum = %02x\n",
+		  device->cdev->dev.bus_id, 
+		  0 /* FIXME: device->devstat.lpum */ );
+	return 0;
+}
+
+/*
+ * Unlock a shared tape.
+ */
+int
+tape_unassign(struct tape_device *device)
+{
+	int rc;
+
+	rc = device->discipline->unassign(device);
+	if (rc) {
+		PRINT_WARN("(%s): unassign failed\n",
+			   device->cdev->dev.bus_id);
+		DBF_EVENT(3, "(%s): unassign failed\n",
+			  device->cdev->dev.bus_id);
+		return rc;
+	}
+	DBF_EVENT(3, "(%s): unassign lpum = %02x\n",
+		  device->cdev->dev.bus_id,
+		  0 /* FIXME: device->devstat.lpum */ );
+	return 0;
+}
+
+/*
+ * Tape device open function used by tape_char & tape_block frontends.
+ */
+int
+tape_open(struct tape_device *device)
+{
+	int rc;
+
+	spin_lock(get_ccwdev_lock(device->cdev));
+	if (device->tape_state == TS_NOT_OPER) {
+		DBF_EVENT(6, "TAPE:nodev\n");
+		rc = -ENODEV;
+	} else if (device->tape_state == TS_IN_USE) {
+		DBF_EVENT(6, "TAPE:dbusy\n");
+		rc = -EBUSY;
+	} else if (device->discipline != NULL &&
+		   !try_inc_mod_count(device->discipline->owner)) {
+		DBF_EVENT(6, "TAPE:nodisc\n");
+		rc = -ENODEV;
+	} else {
+		tape_state_set(device, TS_IN_USE);
+		rc = 0;
+	}
+	spin_unlock(get_ccwdev_lock(device->cdev));
+	return rc;
+}
+
+/*
+ * Tape device release function used by tape_char & tape_block frontends.
+ */
+int
+tape_release(struct tape_device *device)
+{
+	spin_lock(get_ccwdev_lock(device->cdev));
+	if (device->tape_state == TS_IN_USE)
+		tape_state_set(device, TS_UNUSED);
+	if (device->discipline->owner)
+		__MOD_DEC_USE_COUNT(device->discipline->owner);
+	spin_unlock(get_ccwdev_lock(device->cdev));
+	return 0;
+}
+
+/*
+ * Execute a magnetic tape command a number of times.
+ */
+int
+tape_mtop(struct tape_device *device, int mt_op, int mt_count)
+{
+	tape_mtop_fn fn;
+	int rc;
+
+	DBF_EVENT(6, "TAPE:mtio\n");
+	DBF_EVENT(6, "TAPE:ioop: %x\n", mt_op);
+	DBF_EVENT(6, "TAPE:arg:	 %x\n", mt_count);
+
+	if (mt_op < 0 || mt_op >= TAPE_NR_MTOPS)
+		return -EINVAL;
+	fn = device->discipline->mtop_array[mt_op];
+	if (fn == NULL)
+		return -EINVAL;
+
+	/* We assume that the backends can handle count up to 500. */
+	if (mt_op == MTBSR  || mt_op == MTFSR  || mt_op == MTFSF  ||
+	    mt_op == MTBSR  || mt_op == MTFSFM || mt_op == MTBSFM) {
+		rc = 0;
+		for (; mt_count > 500; mt_count -= 500)
+			if ((rc = fn(device, 500)) != 0)
+				break;
+		if (rc == 0)
+			rc = fn(device, mt_count);
+	} else
+		rc = fn(device, mt_count);
+	return rc;
+
+}
+
+/*
+ * Tape init function.
+ */
+static int
+tape_init (void)
+{
+	tape_dbf_area = debug_register ( "tape", 1, 2, 3*sizeof(long));
+	debug_register_view(tape_dbf_area, &debug_sprintf_view);
+	DBF_EVENT(3, "tape init: ($Revision: 1.21 $)\n");
+	tape_proc_init();
+	tapechar_init ();
+	tapeblock_init ();
+	return 0;
+}
+
+/*
+ * Tape exit function.
+ */
+static void
+tape_exit(void)
+{
+	DBF_EVENT(6, "tape exit\n");
+
+	/* Get rid of the frontends */
+	tapechar_exit();
+	tapeblock_exit();
+	tape_proc_cleanup();
+	debug_unregister (tape_dbf_area);
+}
+
+MODULE_AUTHOR("(C) 2001 IBM Deutschland Entwicklung GmbH by Carsten Otte and "
+	      "Michael Holzheu (cotte@de.ibm.com,holzheu@de.ibm.com)");
+MODULE_DESCRIPTION("Linux on zSeries channel attached "
+		   "tape device driver ($Revision: 1.21 $)");
+
+module_init(tape_init);
+module_exit(tape_exit);
+
+EXPORT_SYMBOL(tape_dbf_area);
+EXPORT_SYMBOL(tape_state_verbose);
+EXPORT_SYMBOL(tape_op_verbose);
+EXPORT_SYMBOL(tape_state_set);
+EXPORT_SYMBOL(tape_med_state_set);
+EXPORT_SYMBOL(tape_alloc_request);
+EXPORT_SYMBOL(tape_free_request);
+EXPORT_SYMBOL(tape_dump_sense);
+EXPORT_SYMBOL(tape_dump_sense_dbf);
+EXPORT_SYMBOL(tape_do_io);
+EXPORT_SYMBOL(tape_do_io_async);
+EXPORT_SYMBOL(tape_do_io_interruptible);
+EXPORT_SYMBOL(tape_mtop);
diff -Nru a/drivers/s390/char/tape_idalbuf.h b/drivers/s390/char/tape_idalbuf.h
--- a/drivers/s390/char/tape_idalbuf.h	Mon Dec  9 18:46:37 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,213 +0,0 @@
-/***************************************************************************
- *
- *  drivers/s390/char/tape_idalbuf.h
- *    functions for idal buffer handling
- *
- *  S390 and zSeries version
- *    Copyright (C) 2001 IBM Corporation
- *    Author(s): Michael Holzheu <holzheu@de.ibm.com>
- *
- ****************************************************************************
- */
-
-#include <linux/kernel.h>
-#include <asm/hardirq.h> // in_interrupt
-
-/*
- * Macros
- */
-
-#ifdef CONFIG_ARCH_S390X
-	// on ESAME each idal entry points to a 4K buffer
-	#define IDALBUF_BLK_SIZE    4096
-#else
-	// on ESA each idal entry points to a 2K buffer
-	#define IDALBUF_BLK_SIZE    2048
-#endif
-
-#define IDALBUF_MAX_ENTRIES 33 // an ida list can have up to 33 entries
-#define IDALBUF_PAGE_ORDER  1  // each chunk has 2exp(1) pages
-
-#define __IDALBUF_CHUNK_SIZE   ((1<<IDALBUF_PAGE_ORDER) * PAGE_SIZE)
-#define __IDALBUF_ENTRIES_PER_CHUNK (__IDALBUF_CHUNK_SIZE/IDALBUF_BLK_SIZE)
-
-// Macro which finds out, if we need idal addressing
-
-#ifdef CONFIG_ARCH_S390X
-#define __IDALBUF_DIRECT_ADDR(idal) \
-	( (idal->size <= __IDALBUF_CHUNK_SIZE) \
-	&& ( ( ((unsigned long)idal->data[0]) >> 31) == 0) )
-#else
-#define __IDALBUF_DIRECT_ADDR(idal) \
-	(idal->size <= __IDALBUF_CHUNK_SIZE)
-#endif
-
-#ifndef MIN
-#define MIN(a,b) (((a)<(b))?(a):(b))
-#endif
-
-/*
- * The idalbuf data structure
- */
-
-typedef struct _idalbuf_t{
-	void*   data[IDALBUF_MAX_ENTRIES];
-	int     size;
-} idalbuf_t;
-
-static inline unsigned int
-__round_up_multiple (unsigned int no, unsigned int mult)
-{
-        int rem = no % mult;
-        return (rem ? no - rem + mult : no);
-}
-
-/*
- * Setup a ccw in a way that the data buf is an idalbuf_mem_t
- */
-
-static inline void
-idalbuf_set_normalized_cda(ccw1_t *ccw, idalbuf_t* idal)
-{
-	if(__IDALBUF_DIRECT_ADDR(idal)){
-		// we do not need idals - use direct addressing
-		ccw->cda = (unsigned long) idal->data[0];
-	} else {
-		// setup idals
-		ccw->flags |= CCW_FLAG_IDA;
-		ccw->cda = (unsigned long) idal->data;
-	}
-	ccw->count = idal->size;
-}
-
-/*
- * Alloc size bytes of memory
- */
-
-static inline idalbuf_t* 
-idalbuf_alloc(size_t size)
-{
-	int i = 0;
-	int count = __round_up_multiple(size,IDALBUF_BLK_SIZE) / IDALBUF_BLK_SIZE;
-	idalbuf_t* rc;
-	char* addr = NULL;
-	int kmalloc_flags;
-	if(in_interrupt())
-		kmalloc_flags = GFP_ATOMIC;
-	else
-		kmalloc_flags = GFP_KERNEL;
-
-	if(size/IDALBUF_BLK_SIZE > IDALBUF_MAX_ENTRIES)
-		BUG();
-	// the ida list must be below 2GB --> GFP_DMA
-	rc = kmalloc(sizeof(idalbuf_t),kmalloc_flags | GFP_DMA);
-	if(!rc)
-		goto error;
-	for(i=0; i< count;i++){
-		if((i % __IDALBUF_ENTRIES_PER_CHUNK) == 0){
-			// data does not need to be below 2GB
-			rc->data[i] = (void*)__get_free_pages(kmalloc_flags ,IDALBUF_PAGE_ORDER);
-			if(!rc->data[i])
-				goto error;
-			addr = (char*)(rc->data[i]);
-		} else {
-			addr+=IDALBUF_BLK_SIZE;
-			rc->data[i] = addr;
-		}
-	}
-	rc->size=size;
-	return rc;
-error:
-	if(rc){
-		int end = i;
-		for(i=end-1;i>=0;i-=__IDALBUF_ENTRIES_PER_CHUNK)
-			free_pages((unsigned long)rc->data[i],IDALBUF_PAGE_ORDER);
-		kfree(rc);
-	}
-	return NULL;
-}
-
-/*
- * Free an idal buffer
- */
-
-static inline void
-idalbuf_free(idalbuf_t* idal)
-{
-	int count = __round_up_multiple(idal->size,__IDALBUF_CHUNK_SIZE)/__IDALBUF_CHUNK_SIZE;
-	int i;
-	for(i = 0; i < count; i++){
-		free_pages((unsigned long)idal->data[i*__IDALBUF_ENTRIES_PER_CHUNK],IDALBUF_PAGE_ORDER);
-	}
-	kfree(idal);
-}
-
-/*
- * Copy count bytes from an idal buffer to contiguous user memory
- */
-
-static inline int
-idalbuf_copy_to_user(void* to, const idalbuf_t* from, size_t count)
-{
-	int i;
-	int rc = 0;
-	if(count > from->size)
-		BUG();
-	for(i = 0; i < count; i+=__IDALBUF_CHUNK_SIZE){
-		rc = copy_to_user(((char*)to) + i,from->data[i/IDALBUF_BLK_SIZE],MIN(__IDALBUF_CHUNK_SIZE,(count-i)));
-		if(rc)
-			goto out;
-	}
-out:
-	return rc;
-}
-
-/*
- * Copy count bytes from contiguous user memory to an idal buffer
- */
-
-static inline int
-idalbuf_copy_from_user(idalbuf_t* to, const void* from, size_t count)
-{
-	int i;
-	int rc = 0;
-	if(count > to->size)
-		BUG();
-	for(i = 0; i < count; i+=__IDALBUF_CHUNK_SIZE){
-		rc = copy_from_user(to->data[i/IDALBUF_BLK_SIZE],((char*)from)+i,MIN(__IDALBUF_CHUNK_SIZE,(count-i)));
-		if(rc)
-			goto out;
-	}
-out:
-	return rc;
-}
-
-/*
- * Copy count bytes from an idal buffer to a contiguous kernel buffer
- */
-
-static inline void
-idalbuf_copy_from_idal(void* to, const idalbuf_t* from, size_t count)
-{
-        int i;
-	if(count > from->size)
-		BUG();
-        for(i = 0; i < count; i+=__IDALBUF_CHUNK_SIZE){
-                memcpy((char*)to + i,(from->data[i/IDALBUF_BLK_SIZE]),MIN(__IDALBUF_CHUNK_SIZE,(count-i)) );
-	}
-}
-
-/*
- * Copy count bytes from a contiguous kernel buffer to an idal buffer
- */
- 
-static inline void 
-idalbuf_copy_to_idal(idalbuf_t* to, const void* from, size_t count)
-{
-        int i;
-	if(count > to->size)
-		BUG();
-        for(i = 0; i < count; i+=__IDALBUF_CHUNK_SIZE){
-                memcpy(to->data[i/IDALBUF_BLK_SIZE],(char*)from+i,MIN(__IDALBUF_CHUNK_SIZE,(count-i)) );
-	}
-}
diff -Nru a/drivers/s390/char/tape_proc.c b/drivers/s390/char/tape_proc.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/char/tape_proc.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,144 @@
+/*
+ *  drivers/s390/char/tape.c
+ *    tape device driver for S/390 and zSeries tapes.
+ *
+ *  S390 and zSeries version
+ *    Copyright (C) 2001 IBM Corporation
+ *    Author(s): Carsten Otte <cotte@de.ibm.com>
+ *		 Michael Holzheu <holzheu@de.ibm.com>
+ *		 Tuan Ngo-Anh <ngoanh@de.ibm.com>
+ *
+ * PROCFS Functions
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+#include <linux/seq_file.h>
+
+#include "tape.h"
+
+#define PRINTK_HEADER "T390:"
+
+static const char *tape_med_st_verbose[MS_SIZE] =
+{
+	[MS_UNKNOWN] = "UNKNOWN ",
+	[MS_LOADED] = "LOADED  ",
+	[MS_UNLOADED] = "UNLOADED"
+};
+
+/* our proc tapedevices entry */
+static struct proc_dir_entry *tape_proc_devices;
+
+/*
+ * Show function for /proc/tapedevices
+ */
+static int tape_proc_show(struct seq_file *m, void *v)
+{
+	struct tape_device *device;
+	struct tape_request *request;
+	const char *str;
+	unsigned long n;
+
+	n = (unsigned long) v - 1;
+	if (!n) {
+		seq_printf(m, "TapeNo\tDevNo\tCuType\tCuModel\tDevType\t"
+			   "DevMod\tBlkSize\tState\tOp\tMedState\n");
+	}
+	device = tape_get_device(n);
+	if (IS_ERR(device))
+		return 0;
+	spin_lock_irq(get_ccwdev_lock(device->cdev));
+	seq_printf(m, "%d\t", (int) n);
+	seq_printf(m, "%s\t", device->cdev->dev.bus_id);
+	seq_printf(m, "%04X\t", device->cdev->id.cu_type);
+	seq_printf(m, "%02X\t", device->cdev->id.cu_model);
+	seq_printf(m, "%04X\t", device->cdev->id.dev_type);
+	seq_printf(m, "%02X\t", device->cdev->id.dev_model);
+	if (device->char_data.block_size == 0)
+		seq_printf(m, "auto\t");
+	else
+		seq_printf(m, "%i\t", device->char_data.block_size);
+	if (device->tape_state >= 0 &&
+	    device->tape_state < TS_SIZE)
+		str = tape_state_verbose[device->tape_state];
+	else
+		str = "UNKNOWN";
+	seq_printf(m, "%s\t", str);
+	if (!list_empty(&device->req_queue)) {
+		request = list_entry(device->req_queue.next,
+				     struct tape_request, list);
+		str = tape_op_verbose[request->op];
+	} else
+		str = "---";
+	seq_printf(m, "%s\t", str);
+	seq_printf(m, "%s\n", tape_med_st_verbose[device->medium_state]);
+	spin_unlock_irq(get_ccwdev_lock(device->cdev));
+	tape_put_device(device);
+        return 0;
+}
+
+static void *tape_proc_start(struct seq_file *m, loff_t *pos)
+{
+	if (*pos >= (1 << KDEV_MINOR_BITS) / TAPE_MINORS_PER_DEV)
+		return NULL;
+	return (void *)((unsigned long) *pos + 1);
+}
+
+static void *tape_proc_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	++*pos;
+	return tape_proc_start(m, pos);
+}
+
+static void tape_proc_stop(struct seq_file *m, void *v)
+{
+}
+
+static struct seq_operations tape_proc_seq = {
+	.start		= tape_proc_start,
+	.next		= tape_proc_next,
+	.stop		= tape_proc_stop,
+	.show		= tape_proc_show,
+};
+
+static int tape_proc_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &tape_proc_seq);
+}
+
+static struct file_operations tape_proc_ops =
+{
+	.open		= tape_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release,
+};
+
+/*
+ * Initialize procfs stuff on startup
+ */
+void
+tape_proc_init(void)
+{
+	tape_proc_devices =
+		create_proc_entry ("tapedevices", S_IFREG | S_IRUGO | S_IWUSR,
+				   &proc_root);
+	if (tape_proc_devices == NULL) {
+		PRINT_WARN("tape: Cannot register procfs entry tapedevices\n");
+		return;
+	}
+	tape_proc_devices->proc_fops = &tape_proc_ops;
+	tape_proc_devices->owner = THIS_MODULE;
+}
+
+/*
+ * Cleanup all stuff registered to the procfs
+ */
+void
+tape_proc_cleanup(void)
+{
+	if (tape_proc_devices != NULL)
+		remove_proc_entry ("tapedevices", &proc_root);
+}
diff -Nru a/drivers/s390/char/tape_std.c b/drivers/s390/char/tape_std.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/char/tape_std.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,657 @@
+/*
+ *  drivers/s390/char/tape_std.c
+ *    standard tape device functions for ibm tapes.
+ *
+ *  S390 and zSeries version
+ *    Copyright (C) 2001,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Author(s): Carsten Otte <cotte@de.ibm.com>
+ *		 Michael Holzheu <holzheu@de.ibm.com>
+ *		 Tuan Ngo-Anh <ngoanh@de.ibm.com>
+ *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/bio.h>
+
+#include <asm/types.h>
+#include <asm/idals.h>
+#include <asm/ebcdic.h>
+#include <asm/tape390.h>
+
+#include "tape.h"
+#include "tape_std.h"
+
+#define PRINTK_HEADER "T3xxx:"
+
+/*
+ * tape_std_assign
+ */
+int
+tape_std_assign(struct tape_device *device)
+{
+	struct tape_request *request;
+
+	request = tape_alloc_request(2, 11);
+	if (IS_ERR(request))
+		return PTR_ERR(request);
+	request->op = TO_ASSIGN;
+	tape_ccw_cc(request->cpaddr, ASSIGN, 11, request->cpdata);
+	tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
+	return tape_do_io_free(device, request);
+}
+
+/*
+ * tape_std_unassign
+ */
+int
+tape_std_unassign (struct tape_device *device)
+{
+	struct tape_request *request;
+
+	request = tape_alloc_request(2, 11);
+	if (IS_ERR(request))
+		return PTR_ERR(request);
+	request->op = TO_UNASSIGN;
+	tape_ccw_cc(request->cpaddr, UNASSIGN, 11, request->cpdata);
+	tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
+	return tape_do_io_free(device, request);
+}
+
+/*
+ * TAPE390_DISPLAY: Show a string on the tape display.
+ */
+int
+tape_std_display(struct tape_device *device, int cmd, unsigned long arg)
+{
+	struct display_struct d_struct;
+	struct tape_request *request;
+	int rc;
+
+	if (copy_from_user(&d_struct, (char *) arg, sizeof(d_struct)) != 0)
+		return -EFAULT;
+
+	request = tape_alloc_request(2, 17);
+	if (IS_ERR(request)) {
+		DBF_EVENT(3, "TAPE: load display failed\n");
+		return PTR_ERR(request);
+	}
+	request->op = TO_DIS;
+
+	*(unsigned char *) request->cpdata = d_struct.cntrl;
+	memcpy(((unsigned char *) request->cpdata) + 1, d_struct.message1, 8);
+	memcpy(((unsigned char *) request->cpdata) + 9, d_struct.message2, 8);
+	ASCEBC(((unsigned char*) request->cpdata) + 1, 16);
+
+	tape_ccw_cc(request->cpaddr, LOAD_DISPLAY, 17, request->cpdata);
+	tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
+
+	rc = tape_do_io_interruptible(device, request);
+	tape_free_request(request);
+	return rc;
+}
+
+/*
+ * Read block id.
+ */
+int
+tape_std_read_block_id(struct tape_device *device, __u64 *id)
+{
+	struct tape_request *request;
+	int rc;
+
+	request = tape_alloc_request(3, 8);
+	if (IS_ERR(request))
+		return PTR_ERR(request);
+	request->op = TO_RBI;
+	/* setup ccws */
+	tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
+	tape_ccw_cc(request->cpaddr + 1, READ_BLOCK_ID, 8, request->cpdata);
+	tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
+	/* execute it */
+	rc = tape_do_io(device, request);
+	if (rc == 0)
+		/* Get result from read buffer. */
+		*id = *(__u64 *) request->cpdata;
+	tape_free_request(request);
+	return rc;
+}
+
+/*
+ * MTLOAD: Loads the tape.
+ * The default implementation just wait until the tape medium state changes
+ * to MS_LOADED.
+ */
+int
+tape_std_mtload(struct tape_device *device, int count)
+{
+	return wait_event_interruptible(device->state_change_wq,
+		(device->medium_state == MS_LOADED));
+}
+
+/*
+ * MTSETBLK: Set block size.
+ */
+int
+tape_std_mtsetblk(struct tape_device *device, int count)
+{
+	struct idal_buffer *new;
+
+	if (count <= 0) {
+		/*
+		 * Just set block_size to 0. tapechar_read/tapechar_write
+		 * will realloc the idal buffer if a bigger one than the
+		 * current is needed.
+		 */
+		device->char_data.block_size = 0;
+		return 0;
+	}
+	if (device->char_data.idal_buf != NULL &&
+	    device->char_data.idal_buf->size == count)
+		/* We already have a idal buffer of that size. */
+		return 0;
+	/* Allocate a new idal buffer. */
+	new = idal_buffer_alloc(count, 0);
+	if (new == NULL)
+		return -ENOMEM;
+	if (device->char_data.idal_buf != NULL)
+		idal_buffer_free(device->char_data.idal_buf);
+	device->char_data.idal_buf = new;
+	device->char_data.block_size = count;
+	return 0;
+}
+
+/*
+ * MTRESET: Set block size to 0.
+ */
+int
+tape_std_mtreset(struct tape_device *device, int count)
+{
+	DBF_EVENT(6, "TCHAR:devreset:\n");
+	device->char_data.block_size = 0;
+	return 0;
+}
+
+/*
+ * MTFSF: Forward space over 'count' file marks. The tape is positioned
+ * at the EOT (End of Tape) side of the file mark.
+ */
+int
+tape_std_mtfsf(struct tape_device *device, int mt_count)
+{
+	struct tape_request *request;
+	struct ccw1 *ccw;
+
+	request = tape_alloc_request(mt_count + 2, 0);
+	if (IS_ERR(request))
+		return PTR_ERR(request);
+	request->op = TO_FSF;
+	/* setup ccws */
+	ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
+			  device->modeset_byte);
+	ccw = tape_ccw_repeat(ccw, FORSPACEFILE, mt_count);
+	ccw = tape_ccw_end(ccw, NOP, 0, NULL);
+	/* execute it */
+	return tape_do_io_free(device, request);
+}
+
+/*
+ * MTFSR: Forward space over 'count' tape blocks (blocksize is set
+ * via MTSETBLK.
+ */
+int
+tape_std_mtfsr(struct tape_device *device, int mt_count)
+{
+	struct tape_request *request;
+	struct ccw1 *ccw;
+
+	request = tape_alloc_request(mt_count + 2, 0);
+	if (IS_ERR(request))
+		return PTR_ERR(request);
+	request->op = TO_FSB;
+	/* setup ccws */
+	ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
+			  device->modeset_byte);
+	ccw = tape_ccw_repeat(ccw, FORSPACEBLOCK, mt_count);
+	ccw = tape_ccw_end(ccw, NOP, 0, NULL);
+	/* execute it */
+	return tape_do_io_free(device, request);
+}
+
+/*
+ * MTBSR: Backward space over 'count' tape blocks.
+ * (blocksize is set via MTSETBLK.
+ */
+int
+tape_std_mtbsr(struct tape_device *device, int mt_count)
+{
+	struct tape_request *request;
+	struct ccw1 *ccw;
+
+	request = tape_alloc_request(mt_count + 2, 0);
+	if (IS_ERR(request))
+		return PTR_ERR(request);
+	request->op = TO_BSB;
+	/* setup ccws */
+	ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
+			  device->modeset_byte);
+	ccw = tape_ccw_repeat(ccw, BACKSPACEBLOCK, mt_count);
+	ccw = tape_ccw_end(ccw, NOP, 0, NULL);
+	/* execute it */
+	return tape_do_io_free(device, request);
+}
+
+/*
+ * MTWEOF: Write 'count' file marks at the current position.
+ */
+int
+tape_std_mtweof(struct tape_device *device, int mt_count)
+{
+	struct tape_request *request;
+	struct ccw1 *ccw;
+
+	request = tape_alloc_request(mt_count + 2, 0);
+	if (IS_ERR(request))
+		return PTR_ERR(request);
+	request->op = TO_WTM;
+	/* setup ccws */
+	ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
+			  device->modeset_byte);
+	ccw = tape_ccw_repeat(ccw, WRITETAPEMARK, mt_count);
+	ccw = tape_ccw_end(ccw, NOP, 0, NULL);
+	/* execute it */
+	return tape_do_io_free(device, request);
+}
+
+/*
+ * MTBSFM: Backward space over 'count' file marks.
+ * The tape is positioned at the BOT (Begin Of Tape) side of the
+ * last skipped file mark.
+ */
+int
+tape_std_mtbsfm(struct tape_device *device, int mt_count)
+{
+	struct tape_request *request;
+	struct ccw1 *ccw;
+
+	request = tape_alloc_request(mt_count + 2, 0);
+	if (IS_ERR(request))
+		return PTR_ERR(request);
+	request->op = TO_BSF;
+	/* setup ccws */
+	ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
+			  device->modeset_byte);
+	ccw = tape_ccw_repeat(ccw, BACKSPACEFILE, mt_count);
+	ccw = tape_ccw_end(ccw, NOP, 0, NULL);
+	/* execute it */
+	return tape_do_io_free(device, request);
+}
+
+/*
+ * MTBSF: Backward space over 'count' file marks. The tape is positioned at
+ * the EOT (End of Tape) side of the last skipped file mark.
+ */
+int
+tape_std_mtbsf(struct tape_device *device, int mt_count)
+{
+	struct tape_request *request;
+	struct ccw1 *ccw;
+	int rc;
+
+	request = tape_alloc_request(mt_count + 2, 0);
+	if (IS_ERR(request))
+		return PTR_ERR(request);
+	request->op = TO_BSF;
+	/* setup ccws */
+	ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
+			  device->modeset_byte);
+	ccw = tape_ccw_repeat(ccw, BACKSPACEFILE, mt_count);
+	ccw = tape_ccw_end(ccw, NOP, 0, NULL);
+	/* execute it */
+	rc = tape_do_io(device, request);
+	if (rc == 0) {
+		request->op = TO_FSF;
+		/* need to skip forward over the filemark. */
+		tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
+			    device->modeset_byte);
+		tape_ccw_cc(request->cpaddr + 1, FORSPACEFILE, 0, NULL);
+		tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
+		/* execute it */
+		rc = tape_do_io(device, request);
+	}
+	tape_free_request(request);
+	return rc;
+}
+
+/*
+ * MTFSFM: Forward space over 'count' file marks.
+ * The tape is positioned at the BOT (Begin Of Tape) side
+ * of the last skipped file mark.
+ */
+int
+tape_std_mtfsfm(struct tape_device *device, int mt_count)
+{
+	struct tape_request *request;
+	struct ccw1 *ccw;
+	int rc;
+
+	request = tape_alloc_request(mt_count + 2, 0);
+	if (IS_ERR(request))
+		return PTR_ERR(request);
+	request->op = TO_FSF;
+	/* setup ccws */
+	ccw = tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
+			  device->modeset_byte);
+	ccw = tape_ccw_repeat(ccw, FORSPACEFILE, mt_count);
+	ccw = tape_ccw_end(ccw, NOP, 0, NULL);
+	/* execute it */
+	rc = tape_do_io(device, request);
+	if (rc == 0) {
+		request->op = TO_BSF;
+		/* need to skip forward over the filemark. */
+		tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
+			    device->modeset_byte);
+		tape_ccw_cc(request->cpaddr + 1, BACKSPACEFILE, 0, NULL);
+		tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
+		/* execute it */
+		rc = tape_do_io(device, request);
+	}
+	tape_free_request(request);
+	return rc;
+}
+
+/*
+ * MTREW: Rewind the tape.
+ */
+int
+tape_std_mtrew(struct tape_device *device, int mt_count)
+{
+	struct tape_request *request;
+
+	request = tape_alloc_request(3, 0);
+	if (IS_ERR(request))
+		return PTR_ERR(request);
+	request->op = TO_REW;
+	/* setup ccws */
+	tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1,
+		    device->modeset_byte);
+	tape_ccw_cc(request->cpaddr + 1, REWIND, 0, NULL);
+	tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
+	/* execute it */
+	return tape_do_io_free(device, request);
+}
+
+/*
+ * MTOFFL: Rewind the tape and put the drive off-line.
+ * Implement 'rewind unload'
+ */
+int
+tape_std_mtoffl(struct tape_device *device, int mt_count)
+{
+	struct tape_request *request;
+
+	request = tape_alloc_request(3, 0);
+	if (IS_ERR(request))
+		return PTR_ERR(request);
+	request->op = TO_RUN;
+	/* setup ccws */
+	tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
+	tape_ccw_cc(request->cpaddr + 1, REWIND_UNLOAD, 0, NULL);
+	tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
+	/* execute it */
+	return tape_do_io_free(device, request);
+}
+
+/*
+ * MTNOP: 'No operation'.
+ */
+int
+tape_std_mtnop(struct tape_device *device, int mt_count)
+{
+	struct tape_request *request;
+
+	request = tape_alloc_request(2, 0);
+	if (IS_ERR(request))
+		return PTR_ERR(request);
+	request->op = TO_NOP;
+	/* setup ccws */
+	tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
+	tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
+	/* execute it */
+	return tape_do_io_free(device, request);
+}
+
+/*
+ * MTEOM: positions at the end of the portion of the tape already used
+ * for recordind data. MTEOM positions after the last file mark, ready for
+ * appending another file.
+ */
+int
+tape_std_mteom(struct tape_device *device, int mt_count)
+{
+	struct tape_request *request;
+
+	request = tape_alloc_request(4, 0);
+	if (IS_ERR(request))
+		return PTR_ERR(request);
+	request->op = TO_FSF;
+	/* setup ccws */
+	tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
+	tape_ccw_cc(request->cpaddr + 1,FORSPACEFILE, 0, NULL);
+	tape_ccw_cc(request->cpaddr + 2, NOP, 0, NULL);
+	tape_ccw_end(request->cpaddr + 3, CCW_CMD_TIC, 0, request->cpaddr);
+	/* execute it */
+	tape_do_io_interruptible(device, request);
+	tape_free_request(request);
+	/* MTEOM/MTRETEN errors get ignored. */
+	return 0;
+}
+
+/*
+ * MTRETEN: Retension the tape, i.e. forward space to end of tape and rewind.
+ */
+int
+tape_std_mtreten(struct tape_device *device, int mt_count)
+{
+	struct tape_request *request;
+	int rc;
+
+	request = tape_alloc_request(4, 0);
+	if (IS_ERR(request))
+		return PTR_ERR(request);
+	request->op = TO_FSF;
+	/* setup ccws */
+	tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
+	tape_ccw_cc(request->cpaddr + 1,FORSPACEFILE, 0, NULL);
+	tape_ccw_cc(request->cpaddr + 2, NOP, 0, NULL);
+	tape_ccw_end(request->cpaddr + 3, CCW_CMD_TIC, 0, request->cpaddr);
+	/* execute it, MTRETEN rc gets ignored */
+	rc = tape_do_io_interruptible(device, request);
+	tape_free_request(request);
+	return tape_std_mtrew(device, 1);
+}
+
+/*
+ * MTERASE: erases the tape.
+ */
+int
+tape_std_mterase(struct tape_device *device, int mt_count)
+{
+	struct tape_request *request;
+
+	request = tape_alloc_request(5, 0);
+	if (IS_ERR(request))
+		return PTR_ERR(request);
+	request->op = TO_DSE;
+	/* setup ccws */
+	tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
+	tape_ccw_cc(request->cpaddr + 1, REWIND, 0, NULL);
+	tape_ccw_cc(request->cpaddr + 2, ERASE_GAP, 0, NULL);
+	tape_ccw_cc(request->cpaddr + 3, DATA_SEC_ERASE, 0, NULL);
+	tape_ccw_end(request->cpaddr + 4, NOP, 0, NULL);
+	/* execute it */
+	return tape_do_io_free(device, request);
+}
+
+/*
+ * MTUNLOAD: Rewind the tape and unload it.
+ */
+int
+tape_std_mtunload(struct tape_device *device, int mt_count)
+{
+	struct tape_request *request;
+
+	request = tape_alloc_request(3, 32);
+	if (IS_ERR(request))
+		return PTR_ERR(request);
+	request->op = TO_RUN;
+	/* setup ccws */
+	tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
+	tape_ccw_cc(request->cpaddr + 1, REWIND_UNLOAD, 0, NULL);
+	tape_ccw_end(request->cpaddr + 2, SENSE, 32, request->cpdata);
+	/* execute it */
+	return tape_do_io_free(device, request);
+}
+
+/*
+ * MTCOMPRESSION: used to enable compression.
+ * Sets the IDRC on/off.
+ */
+int
+tape_std_mtcompression(struct tape_device *device, int mt_count)
+{
+	struct tape_request *request;
+
+	if (mt_count < 0 || mt_count > 1) {
+		DBF_EXCEPTION(6, "xcom parm\n");
+		if (*device->modeset_byte & 0x08)
+			PRINT_INFO("(%s) Compression is currently on\n",
+				   device->cdev->dev.bus_id);
+		else
+			PRINT_INFO("(%s) Compression is currently off\n",
+				   device->cdev->dev.bus_id);
+		PRINT_INFO("Use 1 to switch compression on, 0 to "
+			   "switch it off\n");
+		return -EINVAL;
+	}
+	request = tape_alloc_request(2, 0);
+	if (IS_ERR(request))
+		return PTR_ERR(request);
+	request->op = TO_NOP;
+	/* setup ccws */
+	*device->modeset_byte = (mt_count == 0) ? 0x00 : 0x08;
+	tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
+	tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
+	/* execute it */
+	return tape_do_io_free(device, request);
+}
+
+/*
+ * Read Block
+ */
+struct tape_request *
+tape_std_read_block(struct tape_device *device, size_t count)
+{
+	struct tape_request *request;
+
+	/*
+	 * We have to alloc 4 ccws in order to be able to transform request
+	 * into a read backward request in error case.
+	 */
+	request = tape_alloc_request(4, 0);
+	if (IS_ERR(request)) {
+		DBF_EXCEPTION(6, "xrbl fail");
+		return request;
+	}
+	request->op = TO_RFO;
+	tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
+	tape_ccw_end_idal(request->cpaddr + 1, READ_FORWARD,
+			  device->char_data.idal_buf);
+	DBF_EVENT(6, "xrbl ccwg\n");
+	return request;
+}
+
+/*
+ * Read Block backward transformation function.
+ */
+void
+tape_std_read_backward(struct tape_device *device, struct tape_request *request)
+{
+	/*
+	 * We have allocated 4 ccws in tape_std_read, so we can now
+	 * transform the request to a read backward, followed by a
+	 * forward space block.
+	 */
+	request->op = TO_RBA;
+	tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
+	tape_ccw_cc_idal(request->cpaddr + 1, READ_BACKWARD,
+			 device->char_data.idal_buf);
+	tape_ccw_cc(request->cpaddr + 2, FORSPACEBLOCK, 0, NULL);
+	tape_ccw_end(request->cpaddr + 3, NOP, 0, NULL);
+	DBF_EVENT(6, "xrop ccwg");}
+
+/*
+ * Write Block
+ */
+struct tape_request *
+tape_std_write_block(struct tape_device *device, size_t count)
+{
+	struct tape_request *request;
+
+	request = tape_alloc_request(2, 0);
+	if (IS_ERR(request)) {
+		DBF_EXCEPTION(6, "xwbl fail\n");
+		return request;
+	}
+	request->op = TO_WRI;
+	tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
+	tape_ccw_end_idal(request->cpaddr + 1, WRITE_CMD,
+			  device->char_data.idal_buf);
+	DBF_EVENT(6, "xwbl ccwg\n");
+	return request;
+}
+
+/*
+ * This routine is called by frontend after an ENOSP on write
+ */
+void
+tape_std_process_eov(struct tape_device *device)
+{
+	/*
+	 * End of volume: We have to backspace the last written record, then
+	 * we TRY to write a tapemark and then backspace over the written TM
+	 */
+	if (tape_mtop(device, MTBSR, 1) == 0 &&
+	    tape_mtop(device, MTWEOF, 1) == 0) {
+		tape_mtop(device, MTBSR, 1);
+	}
+}
+
+EXPORT_SYMBOL(tape_std_assign);
+EXPORT_SYMBOL(tape_std_unassign);
+EXPORT_SYMBOL(tape_std_display);
+EXPORT_SYMBOL(tape_std_read_block_id);
+EXPORT_SYMBOL(tape_std_mtload);
+EXPORT_SYMBOL(tape_std_mtsetblk);
+EXPORT_SYMBOL(tape_std_mtreset);
+EXPORT_SYMBOL(tape_std_mtfsf);
+EXPORT_SYMBOL(tape_std_mtfsr);
+EXPORT_SYMBOL(tape_std_mtbsr);
+EXPORT_SYMBOL(tape_std_mtweof);
+EXPORT_SYMBOL(tape_std_mtbsfm);
+EXPORT_SYMBOL(tape_std_mtbsf);
+EXPORT_SYMBOL(tape_std_mtfsfm);
+EXPORT_SYMBOL(tape_std_mtrew);
+EXPORT_SYMBOL(tape_std_mtoffl);
+EXPORT_SYMBOL(tape_std_mtnop);
+EXPORT_SYMBOL(tape_std_mteom);
+EXPORT_SYMBOL(tape_std_mtreten);
+EXPORT_SYMBOL(tape_std_mterase);
+EXPORT_SYMBOL(tape_std_mtunload);
+EXPORT_SYMBOL(tape_std_mtcompression);
+EXPORT_SYMBOL(tape_std_read_block);
+EXPORT_SYMBOL(tape_std_read_backward);
+EXPORT_SYMBOL(tape_std_write_block);
+EXPORT_SYMBOL(tape_std_process_eov);
diff -Nru a/drivers/s390/char/tape_std.h b/drivers/s390/char/tape_std.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/char/tape_std.h	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,144 @@
+/*
+ *  drivers/s390/char/tape_34xx.h
+ *    standard tape device functions for ibm tapes.
+ *
+ *  S390 and zSeries version
+ *    Copyright (C) 2001,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Author(s): Carsten Otte <cotte@de.ibm.com>
+ *		 Tuan Ngo-Anh <ngoanh@de.ibm.com>
+ *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#ifndef _TAPE_STD_H
+
+#define _TAPE_STD_H
+
+/*
+ * The CCW commands for the Tape type of command.
+ */
+#define INVALID_00		0x00	/* Invalid cmd */
+#define BACKSPACEBLOCK		0x27	/* Back Space block */
+#define BACKSPACEFILE		0x2f	/* Back Space file */
+#define DATA_SEC_ERASE		0x97	/* Data security erase */
+#define ERASE_GAP		0x17	/* Erase Gap */
+#define FORSPACEBLOCK		0x37	/* Forward space block */
+#define FORSPACEFILE		0x3F	/* Forward Space file */
+#define FORCE_STREAM_CNT	0xEB	/* Forced streaming count # */
+#define NOP			0x03	/* No operation	*/
+#define READ_FORWARD		0x02	/* Read forward */
+#define REWIND			0x07	/* Rewind */
+#define REWIND_UNLOAD		0x0F	/* Rewind and Unload */
+#define SENSE			0x04	/* Sense */
+#define NEW_MODE_SET		0xEB	/* Guess it is Mode set */
+#define WRITE_CMD		0x01	/* Write */
+#define WRITETAPEMARK		0x1F	/* Write Tape Mark */
+
+#define ASSIGN			0xB7	/* 3420 REJECT,3480 OK	*/
+#define CONTROL_ACCESS		0xE3	/* Set high speed */
+#define DIAG_MODE_SET		0x0B	/* 3420 NOP, 3480 REJECT */
+#define LOAD_DISPLAY		0x9F	/* 3420 REJECT,3480 OK */
+#define LOCATE			0x4F	/* 3420 REJ, 3480 NOP */
+#define LOOP_WRITE_TO_READ	0x8B	/* 3480 REJECT */
+#define MODE_SET_DB		0xDB	/* 3420 REJECT,3480 OK */
+#define MODE_SET_C3		0xC3	/* for 3420 */
+#define MODE_SET_CB		0xCB	/* for 3420 */
+#define MODE_SET_D3		0xD3	/* for 3420 */
+#define READ_BACKWARD		0x0C	/* */
+#define READ_BLOCK_ID		0x22	/* 3420 REJECT,3480 OK */
+#define READ_BUFFER		0x12	/* 3420 REJECT,3480 OK */
+#define READ_BUFF_LOG		0x24	/* 3420 REJECT,3480 OK */
+#define RELEASE			0xD4	/* 3420 NOP, 3480 REJECT */
+#define REQ_TRK_IN_ERROR	0x1B	/* 3420 NOP, 3480 REJECT */
+#define RESERVE			0xF4	/* 3420 NOP, 3480 REJECT */
+#define SENSE_GROUP_ID		0x34	/* 3420 REJECT,3480 OK */
+#define SENSE_ID		0xE4	/* 3420 REJECT,3480 OK */
+#define READ_DEV_CHAR		0x64	/* Read device characteristics */
+#define SET_DIAGNOSE		0x4B	/* 3420 NOP, 3480 REJECT */
+#define SET_GROUP_ID		0xAF	/* 3420 REJECT,3480 OK */
+#define SET_TAPE_WRITE_IMMED	0xC3	/* for 3480 */
+#define SUSPEND			0x5B	/* 3420 REJ, 3480 NOP */
+#define SYNC			0x43	/* Synchronize (flush buffer) */
+#define UNASSIGN		0xC7	/* 3420 REJECT,3480 OK */
+#define PERF_SUBSYS_FUNC	0x77	/* 3490 CMD */
+#define READ_CONFIG_DATA	0xFA	/* 3490 CMD */
+#define READ_MESSAGE_ID		0x4E	/* 3490 CMD */
+#define READ_SUBSYS_DATA	0x3E	/* 3490 CMD */
+#define SET_INTERFACE_ID	0x73	/* 3490 CMD */
+
+#define SENSE_COMMAND_REJECT		0x80
+#define SENSE_INTERVENTION_REQUIRED	0x40
+#define SENSE_BUS_OUT_CHECK		0x20
+#define SENSE_EQUIPMENT_CHECK		0x10
+#define SENSE_DATA_CHECK		0x08
+#define SENSE_OVERRUN			0x04
+#define SENSE_DEFERRED_UNIT_CHECK	0x02
+#define SENSE_ASSIGNED_ELSEWHERE	0x01
+
+#define SENSE_LOCATE_FAILURE		0x80
+#define SENSE_DRIVE_ONLINE		0x40
+#define SENSE_RESERVED			0x20
+#define SENSE_RECORD_SEQUENCE_ERR	0x10
+#define SENSE_BEGINNING_OF_TAPE		0x08
+#define SENSE_WRITE_MODE		0x04
+#define SENSE_WRITE_PROTECT		0x02
+#define SENSE_NOT_CAPABLE		0x01
+
+#define SENSE_CHANNEL_ADAPTER_CODE	0xE0
+#define SENSE_CHANNEL_ADAPTER_LOC	0x10
+#define SENSE_REPORTING_CU		0x08
+#define SENSE_AUTOMATIC_LOADER		0x04
+#define SENSE_TAPE_SYNC_MODE		0x02
+#define SENSE_TAPE_POSITIONING		0x01
+
+/* discipline functions */
+struct tape_request *tape_std_read_block(struct tape_device *, size_t);
+void tape_std_read_backward(struct tape_device *device,
+			    struct tape_request *request);
+struct tape_request *tape_std_write_block(struct tape_device *, size_t);
+struct tape_request *tape_std_bread(struct tape_device *, struct request *);
+void tape_std_free_bread(struct tape_request *);
+void tape_std_check_locate(struct tape_device *, struct tape_request *);
+struct tape_request *tape_std_bwrite(struct request *,
+				     struct tape_device *, int);
+
+/* Some non-mtop commands. */
+int tape_std_assign(struct tape_device *);
+int tape_std_unassign(struct tape_device *);
+int tape_std_read_block_id(struct tape_device *device, __u64 *id);
+int tape_std_display(struct tape_device *, int, unsigned long);
+
+/* Standard magnetic tape commands. */
+int tape_std_mtbsf(struct tape_device *, int);
+int tape_std_mtbsfm(struct tape_device *, int);
+int tape_std_mtbsr(struct tape_device *, int);
+int tape_std_mtcompression(struct tape_device *, int);
+int tape_std_mteom(struct tape_device *, int);
+int tape_std_mterase(struct tape_device *, int);
+int tape_std_mtfsf(struct tape_device *, int);
+int tape_std_mtfsfm(struct tape_device *, int);
+int tape_std_mtfsr(struct tape_device *, int);
+int tape_std_mtload(struct tape_device *, int);
+int tape_std_mtnop(struct tape_device *, int);
+int tape_std_mtoffl(struct tape_device *, int);
+int tape_std_mtreset(struct tape_device *, int);
+int tape_std_mtreten(struct tape_device *, int);
+int tape_std_mtrew(struct tape_device *, int);
+int tape_std_mtsetblk(struct tape_device *, int);
+int tape_std_mtunload(struct tape_device *, int);
+int tape_std_mtweof(struct tape_device *, int);
+
+/* Event handlers */
+void tape_std_default_handler(struct tape_device *);
+void tape_std_unexpect_uchk_handler(struct tape_device *);
+void tape_std_irq(struct tape_device *);
+void tape_std_process_eov(struct tape_device *);
+
+// the error recovery stuff:
+void tape_std_error_recovery(struct tape_device *);
+void tape_std_error_recovery_has_failed(struct tape_device *,int error_id);
+void tape_std_error_recovery_succeded(struct tape_device *);
+void tape_std_error_recovery_do_retry(struct tape_device *);
+void tape_std_error_recovery_read_opposite(struct tape_device *);
+void tape_std_error_recovery_HWBUG(struct tape_device *, int condno);
+
+#endif // _TAPE_STD_H
diff -Nru a/drivers/s390/char/tapeblock.c b/drivers/s390/char/tapeblock.c
--- a/drivers/s390/char/tapeblock.c	Mon Dec  9 18:46:51 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,441 +0,0 @@
-/***************************************************************************
- *
- *  drivers/s390/char/tapeblock.c
- *    block device frontend for tape device driver
- *
- *  S390 and zSeries version
- *    Copyright (C) 2001 IBM Corporation
- *    Author(s): Carsten Otte <cotte@de.ibm.com>
- *               Tuan Ngo-Anh <ngoanh@de.ibm.com>
- *
- *
- ****************************************************************************
- */
-
-#include "tapedefs.h"
-#include <linux/config.h>
-#include <linux/blkdev.h>
-#include <linux/blk.h>
-#include <linux/version.h>
-#include <linux/interrupt.h>
-#include <asm/debug.h>
-#include <asm/s390dyn.h>
-#include <linux/compatmac.h>
-#ifdef MODULE
-#define __NO_VERSION__
-#include <linux/module.h>
-#endif
-#include "tape.h"
-#include "tapeblock.h"
-
-#define PRINTK_HEADER "TBLOCK:"
-
-/*
- * file operation structure for tape devices
- */
-static struct block_device_operations tapeblock_fops = {
-	.owner		= THIS_MODULE,
-	.open		= tapeblock_open,
-	.release	= tapeblock_release,
-};
-
-int    tapeblock_major = 0;
-
-static void tape_request_fn (request_queue_t * queue);
-static request_queue_t* tapeblock_getqueue (kdev_t kdev);
-
-#ifdef CONFIG_DEVFS_FS
-devfs_handle_t
-tapeblock_mkdevfstree (tape_dev_t* td) {
-    devfs_handle_t rc=NULL;
-    rc=td->blk_data.devfs_block_dir=devfs_mk_dir (td->devfs_dir, "block", td);
-    if (rc==NULL) goto out_undo;
-    rc=td->blk_data.devfs_disc=devfs_register(td->blk_data.devfs_block_dir, "disc",DEVFS_FL_DEFAULT,
-				    tapeblock_major, td->first_minor,
-				    TAPEBLOCK_DEVFSMODE, &tapeblock_fops, td);
-    if (rc==NULL) goto out_undo;
-    goto out;
- out_undo:
-    tapeblock_rmdevfstree(td);
- out:
-    return rc;
-}
-
-void
-tapeblock_rmdevfstree (tape_dev_t* td) {
-    if (td->blk_data.devfs_disc)
-            devfs_unregister(td->blk_data.devfs_disc);
-    if (td->blk_data.devfs_block_dir)
-            devfs_unregister(td->blk_data.devfs_block_dir);
-}
-#endif
-
-void 
-tapeblock_setup(tape_dev_t* td) {
-    blk_queue_hardsect_size(&ti->request_queue, 2048);
-    blk_init_queue (&td->blk_data.request_queue, tape_request_fn); 
-#ifdef CONFIG_DEVFS_FS
-    tapeblock_mkdevfstree(td);
-#endif
-    set_device_ro (MKDEV(tapeblock_major, td->first_minor), 1);
-}
-
-int
-tapeblock_init(void) {
-	int result;
-	tape_frontend_t* blkfront,*temp;
-	tape_dev_t* td;
-	tape_init();
-	/* Register the tape major number to the kernel */
-	result = register_blkdev(tapeblock_major, "tBLK", &tapeblock_fops);
-	if (result < 0) {
-		PRINT_WARN(KERN_ERR "tape: can't get major %d for block device\n", tapeblock_major);
-		result=-ENODEV;
-		goto out;
-	}
-	if (tapeblock_major == 0) tapeblock_major = result;   /* accept dynamic major number*/
-	INIT_BLK_DEV(tapeblock_major,tape_request_fn,tapeblock_getqueue,NULL);
-	PRINT_WARN(KERN_ERR " tape gets major %d for block device\n", tapeblock_major);
-	max_sectors[tapeblock_major] = (int*) kmalloc (256*sizeof(int),GFP_KERNEL);
-	if (max_sectors[tapeblock_major]==NULL) goto out_undo_hardsect_size;
-	memset(max_sectors[tapeblock_major],0,256*sizeof(int));
-	blkfront = kmalloc(sizeof(tape_frontend_t),GFP_KERNEL);
-	if (blkfront==NULL) goto out_undo_max_sectors;
-	blkfront->device_setup=(tape_setup_device_t)tapeblock_setup;
-#ifdef CONFIG_DEVFS_FS
-	blkfront->mkdevfstree = tapeblock_mkdevfstree;
-	blkfront->rmdevfstree = tapeblock_rmdevfstree;
-#endif
-	blkfront->next=NULL;
-	if (tape_first_front==NULL) {
-		tape_first_front=blkfront;
-	} else {
-		temp=tape_first_front;
-		while (temp->next!=NULL) 
-			temp=temp->next;
-		temp->next=blkfront;
-	}
-	td=tape_first_dev;
-	while (td!=NULL) {
-		tapeblock_setup(td);
-		td=td->next;
-	}
-	result=0;
-	goto out;
-out_undo_max_sectors:
-	kfree(max_sectors[tapeblock_major]);
-out_undo_hardsect_size:
-out_undo_blk_size:
-out_undo_bdev:
-	unregister_blkdev(tapeblock_major, "tBLK");
-	result=-ENOMEM;
-	max_sectors[tapeblock_major]=NULL;
-	tapeblock_major=-1;    
-out:
-	return result;
-}
-
-
-void 
-tapeblock_uninit(void) {
-	if (tapeblock_major==-1)
-	        goto out; /* init failed so there is nothing to clean up */
-	if (max_sectors[tapeblock_major]!=NULL) {
-		kfree (max_sectors[tapeblock_major]);
-		max_sectors[tapeblock_major]=NULL;
-	}
-
-	unregister_blkdev(tapeblock_major, "tBLK");
-
-out:
-	return;
-}
-
-int
-tapeblock_open(struct inode *inode, struct file *filp) {
-	tape_dev_t *td = NULL;
-	int rc = 0;
-	long lockflags;
-
-
-	tape_sprintf_event (tape_dbf_area,6,"b:open:  %x\n",td->first_minor);
-
-	inode = filp->f_dentry->d_inode;
-
-	td = tape_get_device_by_minor(MINOR (inode->i_rdev));
-	if (td == NULL){
-		rc = -ENODEV;
-		goto error;
-	}
-	s390irq_spin_lock_irqsave (td->devinfo.irq, lockflags);
-	if (tape_state_get(td) == TS_NOT_OPER) {
-		tape_sprintf_event (tape_dbf_area,6,"c:nodev\n");
-		rc = -ENODEV;
-		goto out_rel_lock;
-	}
-	if (tape_state_get (td) != TS_UNUSED) {
-		tape_sprintf_event (tape_dbf_area,6,"b:dbusy\n");
-		rc = -EBUSY;
-		goto out_rel_lock;
-	}
-	tape_state_set (td, TS_IN_USE);
-        td->blk_data.position=-1;
-	s390irq_spin_unlock_irqrestore (td->devinfo.irq, lockflags);
-        rc=tapeblock_mediumdetect(td);
-        if (rc) {
-	    s390irq_spin_lock_irqsave (td->devinfo.irq, lockflags);
-	    tape_state_set (td, TS_UNUSED);
-	    goto out_rel_lock; // in case of errors, we don't have a size of the medium
-	}
-	if ( td->discipline->owner )
-		__MOD_INC_USE_COUNT(td->discipline->owner);
-	s390irq_spin_lock_irqsave (td->devinfo.irq, lockflags);
-	td->filp = filp;
-	filp->private_data = td;/* save the dev.info for later reference */
-out_rel_lock:
-	s390irq_spin_unlock_irqrestore (td->devinfo.irq, lockflags);
-error:
-	if(rc != 0){
-		if (td != NULL)
-			tape_put_device(td);
-	}
-	return rc;
-}
-
-int
-tapeblock_release(struct inode *inode, struct file *filp) {
-	long lockflags;
-	tape_dev_t *td = NULL;
-	int rc = 0;
-	if((!inode) || !(inode->i_rdev)) {
-		rc = -EINVAL;
-		goto out;
-	}
-	td = tape_get_device_by_minor(MINOR (inode->i_rdev));
-	if (td==NULL) {
-		rc = -ENODEV;
-		goto out;
-	}
-	s390irq_spin_lock_irqsave (td->devinfo.irq, lockflags);
-
-	tape_sprintf_event (tape_dbf_area,6,"b:release: %x\n",td->first_minor);
-	if(tape_state_get(td) == TS_IN_USE)
-		tape_state_set (td, TS_UNUSED);
-	else if (tape_state_get(td) != TS_NOT_OPER) 
-		BUG();
-	s390irq_spin_unlock_irqrestore (td->devinfo.irq, lockflags);
-	tape_put_device(td);
-	tape_put_device(td); /* 2x ! */
-	if ( td->discipline->owner )
-		__MOD_DEC_USE_COUNT(td->discipline->owner);
-out:
-	return rc;
-}
-
-static void
-tapeblock_end_request(tape_dev_t* td) {
-    struct buffer_head *bh;
-    int uptodate;
-    tape_ccw_req_t *treq = tape_get_active_ccw_req(td);
-    if(treq == NULL){
-	uptodate = 0;
-    }
-    else
-    	uptodate=(treq->rc == 0); // is the buffer up to date?
-    if (uptodate) {
-	tape_sprintf_event (tape_dbf_area,6,"b:done: %x\n",(unsigned long)treq);
-    } else {
-	tape_sprintf_event (tape_dbf_area,3,"b:failed: %x\n",(unsigned long)treq);
-    }
-    // now inform ll_rw_block about a request status
-    while ((bh = td->blk_data.current_request->bh) != NULL) {
-	td->blk_data.current_request->bh = bh->b_reqnext;
-	bh->b_reqnext = NULL;
-	bh->b_end_io (bh, uptodate);
-    }
-    if (!end_that_request_first (td->blk_data.current_request, uptodate, "tBLK")) {
-#ifndef DEVICE_NO_RANDOM
-	add_blkdev_randomness (MAJOR (td->blk_data.current_request->rq_dev));
-#endif
-	end_that_request_last (td->blk_data.current_request);
-    }
-    if (treq!=NULL) {
-	    tape_remove_ccw_req(td,treq);
-	    td->discipline->free_bread(treq);
-    }
-    td->blk_data.current_request=NULL;
-    return;
-}
-
-static void
-tapeblock_exec_IO (tape_dev_t* td) {
-    int rc;
-    struct request* req;
-    tape_ccw_req_t *treq = tape_get_active_ccw_req(td);
-
-    if (treq) { // process done/failed request
-	while (treq->rc != 0 && td->blk_data.blk_retries>0) {
-	    td->blk_data.blk_retries--;
-	    td->blk_data.position=-1;
-	    td->discipline->bread_enable_locate(treq);
-	    tape_sprintf_event (tape_dbf_area,3,"b:retryreq: %x\n",(unsigned long)treq);
-	    rc = tape_do_io_irq(td,treq,TAPE_SCHED_BLOCK);
-	    if (rc != 0) {
-		tape_sprintf_event (tape_dbf_area,3,"b:doIOfail: %x\n",(unsigned long)treq);
-		continue; // one retry lost 'cause doIO failed
-	    }
-	    return;
-	}
-	tapeblock_end_request (td); // check state, inform user, free mem, dev=idl
-    }
-    if(TAPE_BUSY(td)) BUG(); // tape should be idle now, request should be freed!
-    if (tape_state_get (td) == TS_NOT_OPER) {
-	return;
-    }
-	if (list_empty (&td->blk_data.request_queue.queue_head)) {
-	// nothing more to do or device has dissapeared;)
-	tape_sprintf_event (tape_dbf_area,6,"b:Qempty\n");
-	return;
-    }
-    // queue is not empty, fetch a request and start IO!
-    req=td->blk_data.current_request=tape_next_request(&td->blk_data.request_queue);
-    if (req==NULL) {
-	BUG(); // Yo. The queue was not reported empy, but no request found. This is _bad_.
-    }
-    if (req->cmd!=READ) { // we only support reading
-	tapeblock_end_request (td); // check state, inform user, free mem, dev=idl
-	tapeblock_schedule_exec_io(td);
-	return;
-    }
-    treq=td->discipline->bread(req,td,tapeblock_major); //build channel program from request
-    if (!treq) {
-	// ccw generation failed. we try again later.
-	tape_sprintf_event (tape_dbf_area,3,"b:cqrNULL\n");
-	tapeblock_schedule_exec_io(td);
-	td->blk_data.current_request=NULL;
-	return;
-    }
-    td->blk_data.blk_retries = TAPEBLOCK_RETRIES;
-    rc = tape_do_io_irq(td,treq,TAPE_SCHED_BLOCK);
-    if (rc != 0) {
-	// okay. ssch failed. we try later.
-	tape_sprintf_event (tape_dbf_area,3,"b:doIOfail\n");
-	tape_remove_ccw_req(td,treq);
-	td->discipline->free_bread(treq);
-	td->blk_data.current_request=NULL;
-	tapeblock_schedule_exec_io(td);
-	return;
-    }
-    // our request is in IO. we remove it from the queue and exit
-    tape_dequeue_request (&td->blk_data.request_queue,req);
-}
-
-static void 
-do_tape_request (tape_dev_t * td) {
-    long lockflags;
-    if (td==NULL) BUG();
-    s390irq_spin_lock_irqsave (td->devinfo.irq, lockflags);
-    if (tape_state_get(td)!=TS_IN_USE) {
-	s390irq_spin_unlock_irqrestore(td->devinfo.irq,lockflags);
-	return;
-    }
-    tapeblock_exec_IO(td);
-    s390irq_spin_unlock_irqrestore(td->devinfo.irq,lockflags);
-}
-
-static void
-run_tapeblock_exec_IO (tape_dev_t* td) {
-    long flags_390irq,flags_ior;
-    request_queue_t *q = &tape->request_queue;
-
-    spin_lock_irqsave (&q->queue_lock, flags_ior);
-    s390irq_spin_lock_irqsave(td->devinfo.irq,flags_390irq);
-    atomic_set(&td->blk_data.bh_scheduled,0);
-    tapeblock_exec_IO(td);
-    s390irq_spin_unlock_irqrestore(td->devinfo.irq,flags_390irq);
-    spin_unlock_irqrestore (&q->queue_lock, flags_ior);
-}
-
-void
-tapeblock_schedule_exec_io (tape_dev_t *td)
-{
-	/* Protect against rescheduling, when already running */
-        if (atomic_compare_and_swap(0,1,&td->blk_data.bh_scheduled)) {
-                return;
-        }
-	INIT_LIST_HEAD(&td->blk_data.bh_tq.list);
-	td->blk_data.bh_tq.sync = 0;
-	td->blk_data.bh_tq.routine = (void *) (void *) run_tapeblock_exec_IO;
-	td->blk_data.bh_tq.data = td;
-
-	queue_task (&td->blk_data.bh_tq, &tq_immediate);
-	mark_bh (IMMEDIATE_BH);
-	return;
-}
-
-static void  tape_request_fn (request_queue_t* queue) {
-	tape_dev_t* td=tape_get_device_by_queue(queue);
-	if (td!=NULL) {
-		do_tape_request(td);
-		tape_put_device(td);
-	}		
-}
-
-static request_queue_t* tapeblock_getqueue (kdev_t kdev) {
-	tape_dev_t* td=tape_get_device_by_minor(MINOR(kdev));
-	if (td!=NULL) return &td->blk_data.request_queue;
-	else return NULL;
-}
-
-int tapeblock_mediumdetect(tape_dev_t* td) {
-	tape_ccw_req_t *treq;
-	unsigned int nr_of_blks;
-	int rc;
-	PRINT_INFO("Detecting media size...\n");
-
-	/* Rewind */
-
-	treq = td->discipline->ioctl (td, MTREW, 1, &rc);
-	if (treq == NULL)
-		return rc;
-	rc = tape_do_io_and_wait (td,treq,TAPE_WAIT_INTERRUPTIBLE);
-	TAPE_MERGE_RC(treq,rc);
-	tape_free_ccw_req (treq);
-	if (rc)
-		return rc;
-
-	/* FSF */
-
-	treq=td->discipline->ioctl (td, MTFSF,1,&rc);
-	if (treq == NULL) 
-		return rc;
-	rc = tape_do_io_and_wait (td,treq,TAPE_WAIT_INTERRUPTIBLE);
-	TAPE_MERGE_RC(treq,rc);
-	tape_free_ccw_req (treq);
-	if (rc)
-		return rc;
-
-	/* TELL */
-
-	treq = td->discipline->ioctl (td, MTTELL, 1, &rc);
-	if (treq == NULL) 
-		return rc;
-	rc = tape_do_io_and_wait(td,treq,TAPE_WAIT_INTERRUPTIBLE);
-	TAPE_MERGE_RC(treq,rc);
-	nr_of_blks = *((int*)(treq->kernbuf)) - 1; /* don't count FM */
-	tape_free_ccw_req (treq);
-	if(rc)
-		return rc;
-
-	/* Rewind */
-
-	treq = td->discipline->ioctl (td, MTREW, 1, &rc);
-        if (treq == NULL)
-		return rc;
-        rc = tape_do_io_and_wait(td,treq,TAPE_WAIT_INTERRUPTIBLE);
-	TAPE_MERGE_RC(treq,rc);
-        tape_free_ccw_req (treq);
-	if(rc)	
-		return rc;
-	return 0;
-}
diff -Nru a/drivers/s390/char/tapeblock.h b/drivers/s390/char/tapeblock.h
--- a/drivers/s390/char/tapeblock.h	Mon Dec  9 18:46:51 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,36 +0,0 @@
-
-/***************************************************************************
- *
- *  drivers/s390/char/tapeblock.h
- *    character device frontend for tape device driver
- *
- *  S390 and zSeries version
- *    Copyright (C) 2001 IBM Corporation
- *    Author(s): Carsten Otte <cotte@de.ibm.com>
- *               Tuan Ngo-Anh <ngoanh@de.ibm.com>
- *
- *
- ****************************************************************************
- */
-
-#ifndef TAPEBLOCK_H
-#define TAPEBLOCK_H
-#include <linux/config.h>
-
-#define TAPEBLOCK_READAHEAD 30
-#define TAPEBLOCK_MAJOR 0
-
-#define TAPEBLOCK_DEVFSMODE 0060644 // blkdev, rwx for user, rw for group&others
-
-int tapeblock_open(struct inode *, struct file *);
-int tapeblock_release(struct inode *, struct file *);
-void tapeblock_setup(tape_dev_t* td);
-void tapeblock_schedule_exec_io (tape_dev_t *td);
-int tapeblock_mediumdetect(tape_dev_t* td);
-#ifdef CONFIG_DEVFS_FS
-devfs_handle_t tapeblock_mkdevfstree (tape_dev_t* td);
-void tapeblock_rmdevfstree (tape_dev_t* td);
-#endif
-int tapeblock_init (void);
-void tapeblock_uninit (void);
-#endif
diff -Nru a/drivers/s390/char/tapechar.c b/drivers/s390/char/tapechar.c
--- a/drivers/s390/char/tapechar.c	Mon Dec  9 18:46:36 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,627 +0,0 @@
-/***************************************************************************
- *
- *  drivers/s390/char/tapechar.c
- *    character device frontend for tape device driver
- *
- *  S390 and zSeries version
- *    Copyright (C) 2001 IBM Corporation
- *    Author(s): Carsten Otte <cotte@de.ibm.com>
- *               Michael Holzheu <holzheu@de.ibm.com>
- *               Tuan Ngo-Anh <ngoanh@de.ibm.com>
- *
- *
- ****************************************************************************
- */
-
-#include "tapedefs.h"
-#include <linux/config.h>
-#include <linux/version.h>
-#include <linux/types.h>
-#include <linux/proc_fs.h>
-#include <asm/s390dyn.h>
-#include <linux/mtio.h>
-#include <asm/uaccess.h>
-#include <linux/compatmac.h>
-#ifdef MODULE
-#define __NO_VERSION__
-#include <linux/module.h>
-#endif
-#include "tape.h"
-#include "tapechar.h"
-
-#define PRINTK_HEADER "TCHAR:"
-
-/*******************************************************************
- * GLOBALS
- *******************************************************************/
-
-/*
- * file operation structure for tape devices
- */
-static struct file_operations tape_fops =
-{
-	.owner = THIS_MODULE,
-	.read = tapechar_read,
-	.write = tapechar_write,
-	.ioctl = tapechar_ioctl,
-	.open = tapechar_open,
-	.release = tapechar_release,
-};
-
-int tapechar_major = TAPECHAR_MAJOR;
-
-/*******************************************************************
- * DEVFS Functions
- *******************************************************************/
-
-#ifdef CONFIG_DEVFS_FS
-
-/*
- * Create Char directory with (non)rewinding entries
- */
-
-devfs_handle_t
-tapechar_mkdevfstree (tape_dev_t* td) {
-    devfs_handle_t rc=NULL;
-    rc=td->char_data.devfs_char_dir=devfs_mk_dir (td->devfs_dir, "char", td);
-    if (rc==NULL) goto out_undo;
-    rc=td->char_data.devfs_nonrewinding=devfs_register(td->char_data.devfs_char_dir, 
-						    "nonrewinding",
-						    DEVFS_FL_DEFAULT,tapechar_major, 
-						    TAPECHAR_NOREW_MINOR(td->first_minor), 
-						    TAPECHAR_DEVFSMODE, &tape_fops, td);
-    if (rc==NULL) goto out_undo;
-    rc=td->char_data.devfs_rewinding=devfs_register(td->char_data.devfs_char_dir, 
-						 "rewinding",
-						 DEVFS_FL_DEFAULT, tapechar_major, 
-						 TAPECHAR_REW_MINOR(td->first_minor),
-						 TAPECHAR_DEVFSMODE, &tape_fops, td);
-    if (rc==NULL) goto out_undo;
-    goto out;
- out_undo:
-    tapechar_rmdevfstree (td);
- out:
-    return rc;
-}
-
-/*
- * Remove DEVFS entries
- */
-
-void
-tapechar_rmdevfstree (tape_dev_t* td) {
-    if (td->char_data.devfs_nonrewinding) 
-	    devfs_unregister(td->char_data.devfs_nonrewinding);
-    if (td->char_data.devfs_rewinding)
-	    devfs_unregister(td->char_data.devfs_rewinding);
-    if (td->char_data.devfs_char_dir)
-	    devfs_unregister(td->char_data.devfs_char_dir);
-}
-#endif
-
-/*******************************************************************
- * TAPECHAR Setup Functions
- *******************************************************************/
-
-/*
- * This function is called for every new tapedevice
- */
-
-void
-tapechar_setup (tape_dev_t * td)
-{
-#ifdef CONFIG_DEVFS_FS
-    tapechar_mkdevfstree(td);
-#endif
-}
-
-/*
- * Tapechar init Function
- */
-
-void
-tapechar_init (void)
-{
-	int result;
-	tape_frontend_t *charfront,*temp;
-	tape_dev_t* td;
-
-	tape_init();
-
-	/* Register the tape major number to the kernel */
-	result = register_chrdev (tapechar_major, "tape", &tape_fops);
-	if (result < 0) {
-		PRINT_WARN (KERN_ERR "tape: can't get major %d\n", tapechar_major);
-		tape_sprintf_event (tape_dbf_area,3,"c:initfail\n");
-		goto out;
-	}
-	if (tapechar_major == 0)
-		tapechar_major = result;	/* accept dynamic major number */
-	PRINT_WARN (KERN_ERR " tape gets major %d for character device\n", result);
-	charfront = kmalloc (sizeof (tape_frontend_t), GFP_KERNEL);
-	if (charfront == NULL) {
-	        PRINT_WARN (KERN_ERR "tapechar: cannot alloc memory for the frontend_t structure\n");
-                tape_sprintf_event (tape_dbf_area,3,"c:initfail no mem\n");
-		goto out;
-	}
-	charfront->device_setup = (tape_setup_device_t)tapechar_setup;
-#ifdef CONFIG_DEVFS_FS
-	charfront->mkdevfstree = tapechar_mkdevfstree;
-	charfront->rmdevfstree = tapechar_rmdevfstree;
-#endif
-        tape_sprintf_event (tape_dbf_area,3,"c:init ok\n");
-	charfront->next=NULL;
-	if (tape_first_front==NULL) {
-	    tape_first_front=charfront;
-	} else {
-	    temp=tape_first_front;
-	    while (temp->next!=NULL)
-		temp=temp->next;
-	    temp->next=charfront;
-	}
-	td=tape_first_dev;
-	while (td!=NULL) {
-	    tapechar_setup(td);
-	    td=td->next;
-	}
- out:
-	return;
-}
-
-/*
- * cleanup
- */
-
-void
-tapechar_uninit (void)
-{
-	unregister_chrdev (tapechar_major, "tape");
-}
-
-
-/*******************************************************************
- * TAPECHAR Util functions
- *******************************************************************/
-
-/*
- * Terminate write command (we write two TMs and skip backward over last)
- * This ensures that the tape is always correctly terminated.
- * When the user writes afterwards a new file, he will overwrite the
- * second TM and therefore one TM will remain to seperate the 
- * two files on the tape...
- */
-
-static void
-tapechar_terminate_write(tape_dev_t* td)
-{
-	tape_ccw_req_t *treq;
-	int rc;
-
-	treq = td->discipline->ioctl(td, MTWEOF,1,&rc);
-	if (!treq)
-		goto out;
-	tape_do_io_and_wait(td,treq,TAPE_WAIT);
-	tape_free_ccw_req(treq);
-	treq = td->discipline->ioctl(td, MTWEOF,1,&rc);
-	if (!treq)
-		goto out;
-	tape_do_io_and_wait(td,treq,TAPE_WAIT);
-	tape_free_ccw_req(treq);
-	treq = td->discipline->ioctl(td, MTBSR,1,&rc);
-	if (!treq)
-		goto out;
-	tape_do_io_and_wait(td,treq,TAPE_WAIT);
-	tape_free_ccw_req(treq);
-
-out:
-	return;
-}
-	
-
-/*******************************************************************
- * TAPECHAR Functions:
- * - read
- * - write
- * - open
- * - close
- * - ioctl
- *******************************************************************/
-
-/*
- * Tape device read function
- */
-
-ssize_t
-tapechar_read (struct file *filp, char *data, size_t count, loff_t * ppos)
-{
-	tape_dev_t *td;
-	size_t block_size;
-	tape_ccw_req_t *treq;
-	int rc = 0;
-	size_t cpysize;
-
-        tape_sprintf_event (tape_dbf_area,6,"c:read\n");
-	td = (tape_dev_t*)filp->private_data;
-	
-	if (ppos != &filp->f_pos) {
-		/* "A request was outside the capabilities of the device." */
-		/* This check uses internal knowledge about how pread and */
-		/* read work... */
-	        tape_sprintf_event (tape_dbf_area,6,"c:ppos wrong\n");
-		rc = -EOVERFLOW;      /* errno=75 Value too large for def. data type */
-		goto out;
-	}
-	if (td->char_data.block_size == 0) {
-		block_size = count;
-	} else {
-	        if (count < td->char_data.block_size) {
-		        rc = -EINVAL; // invalid argument+
-			tape_sprintf_event (tape_dbf_area,3,"tapechar:read smaller than block size was requested\n");
-			goto out;
-		}
-		block_size = td->char_data.block_size;
-	}
-	tape_sprintf_event (tape_dbf_area,6,"c:nbytes: %x\n",block_size);
-	treq = td->discipline->read_block (data, block_size, td);
-	if (!treq) {
-		rc = -ENOBUFS;
-		goto out;
-	}
-
-	rc = tape_do_io_and_wait(td,treq,TAPE_WAIT);
-	TAPE_MERGE_RC(treq,rc);
-	if(rc != 0)
-		goto out_free;
-	rc = cpysize = block_size - td->devstat.rescnt;
-	if(idalbuf_copy_to_user(treq->userbuf, treq->idal_buf, cpysize)) {
-		tape_sprintf_exception (tape_dbf_area,6,"xfrb segf.\n");
-		rc = -EFAULT;
-	}
-	tape_sprintf_event (tape_dbf_area,6,"c:rbytes:  %x\n", cpysize);
-	filp->f_pos += cpysize;
-out_free:
-	tape_free_ccw_req(treq);
-out:
-	return rc;
-}
-
-/*
- * Tape device write function
- */
-
-ssize_t
-tapechar_write (struct file *filp, const char *data, size_t count, loff_t * ppos)
-{
-	tape_dev_t *td;
-	size_t block_size;
-	tape_ccw_req_t *treq;
-	int nblocks, i = 0,rc = 0;
-	size_t written = 0;
-	tape_sprintf_event (tape_dbf_area,6,"c:write\n");
-
-	td = (tape_dev_t*)filp->private_data;
-	block_size = count;
-        
-	if (ppos != &filp->f_pos) {
-		/* "A request was outside the capabilities of the device." */
-	        tape_sprintf_event (tape_dbf_area,6,"c:ppos wrong\n");
-		rc = -EOVERFLOW; /* errno=75 Value too large for def. data type */
-		goto out;
-	}
-	if ((td->char_data.block_size != 0) && (count < td->char_data.block_size)){
-		rc = -EIO;
-		goto out;
-	}
-	if (td->char_data.block_size == 0) {
-		block_size = count;
-		nblocks = 1;
-	} else {
-		block_size = td->char_data.block_size;
-		nblocks = count / block_size;
-	}
-	tape_sprintf_event (tape_dbf_area,6,"c:nbytes: %x\n",block_size);
-        tape_sprintf_event (tape_dbf_area,6,"c:nblocks: %x\n",nblocks);
-	for (i = 0; i < nblocks; i++) {
-		treq = td->discipline->write_block (data + i * block_size, block_size, td);
-		if (!treq) {
-			rc = -ENOBUFS;
-			goto out;
-		}
-
-		rc = tape_do_io_and_wait(td,treq,TAPE_WAIT);
-		TAPE_MERGE_RC(treq,rc);
-		tape_free_ccw_req(treq);
-		if(rc < 0)
-			goto out;
-	        tape_sprintf_event (tape_dbf_area,6,"c:wbytes: %x\n",block_size - td->devstat.rescnt); 
-		filp->f_pos += block_size - td->devstat.rescnt;
-		written += block_size - td->devstat.rescnt;
-		rc = written;
-		if (td->devstat.rescnt > 0)
-			goto out;
-	}
-	tape_sprintf_event (tape_dbf_area,6,"c:wtotal: %x\n",written);
-
-out:
-	if (rc==-ENOSPC){
-		if(td->discipline->process_eov)
-			td->discipline->process_eov(td);
-		if(i > 0){
-			rc = i*block_size;
-			printk("write rc = %i\n",rc); /* XXX */
-		}	
-	}
-	return rc;
-}
-
-/*
- * MT IOCTLS
- */
-
-static int
-tapechar_mtioctop (struct file *filp, short mt_op, int mt_count)
-{
-	tape_dev_t *td;
-	tape_ccw_req_t *treq = NULL;
-	int rc = 0;
-
-	td = (tape_dev_t*)filp->private_data; 
-
-	tape_sprintf_event (tape_dbf_area,6,"c:mtio\n");
-	tape_sprintf_event (tape_dbf_area,6,"c:ioop: %x\n",mt_op);
-	tape_sprintf_event (tape_dbf_area,6,"c:arg:  %x\n",mt_count);
-
-	switch (mt_op) {
-		case MTRETEN:		// retension the tape
-			treq = td->discipline->ioctl (td, MTEOM,1,&rc);
-			break;
-		case MTLOAD:
-			treq = td->discipline->ioctl (td, MTLOAD,1,&rc);
-			if (rc != -EINVAL){
-				// the backend driver has an load function
-				break; 
-			} 
-			// if no medium is in, wait until it gets inserted
-			if (td->medium_state != MS_LOADED) {
-				// create dummy request
-				treq = tape_alloc_ccw_req(1,0,0,TO_LOAD);
-				rc = tape_do_wait_req(td,treq,TAPE_WAIT_INTERRUPTIBLE_NOHALTIO);
-			} else {
-				rc = 0; // already loaded
-			}
-			goto out;
-		case MTSETBLK:
-			td->char_data.block_size = mt_count;
-			tape_sprintf_event (tape_dbf_area,6,"c:setblk:\n");
-			goto out;
-		case MTRESET:
-			td->char_data.block_size = 0;
-			tape_sprintf_event (tape_dbf_area,6,"c:devreset:\n");
-			goto out;
-		default:
-			treq = td->discipline->ioctl (td, mt_op,mt_count,&rc);
-	}
-	if (treq == NULL) {
-	        tape_sprintf_event (tape_dbf_area,6,"c:ccwg fail\n");
-		goto out;
-	}
-
-	if(TAPE_INTERRUPTIBLE_OP(mt_op)){
-		rc = tape_do_io_and_wait(td,treq,TAPE_WAIT_INTERRUPTIBLE);
-	} else {
-		rc = tape_do_io_and_wait(td,treq,TAPE_WAIT);
-	}
-	TAPE_MERGE_RC(treq,rc);
-
-	tape_free_ccw_req(treq);
-
-	if ((mt_op == MTEOM) || (mt_op == MTRETEN)){
-		rc = 0; // EOM and RETEN report an error, this is fine...
-	}
-
-	if(rc != 0)
-		goto out; /* IO Failed */
-
-	// if medium was unloaded, update the corresponding variable.
-	switch (mt_op) {
-	        case MTOFFL:
-	        case MTUNLOAD:
-			td->medium_state = MS_UNLOADED;
-			break;
-	        case MTRETEN:		//need to rewind the tape after moving to eom
-			return tapechar_mtioctop (filp, MTREW, 1);
-	        case MTFSFM:		//need to skip back over the filemark
-			return tapechar_mtioctop (filp, MTBSFM, 1);
-	        case MTBSF:		//need to skip forward over the filemark
-			return tapechar_mtioctop (filp, MTFSF, 1);
-	}
-	tape_sprintf_event (tape_dbf_area,6,"c:mtio done\n");
-out:
-	return rc;
-}
-
-/*
- * Tape device io controls.
- */
-
-int
-tapechar_ioctl (struct inode *inode, struct file *filp,
-	    unsigned int cmd, unsigned long arg)
-{
-	tape_dev_t *td;
-	tape_ccw_req_t *treq = NULL;
-	struct mtop op;		/* structure for MTIOCTOP */
-	struct mtpos pos;	/* structure for MTIOCPOS */
-	struct mtget get;
-	int rc;
-
-	tape_sprintf_event (tape_dbf_area,6,"c:ioct\n");
-
-        td = (tape_dev_t*)filp->private_data;
-
-	// check for discipline ioctl overloading
-	if ((rc = td->discipline->discipline_ioctl_overload (td, cmd, arg)) != -EINVAL) {
-		tape_sprintf_event (tape_dbf_area,6,"c:ioverloa\n");
-		goto out;
-	}
-	rc = 0;
-	switch (cmd) {
-	case MTIOCTOP:		/* tape op command */
-		if (copy_from_user (&op, (char *) arg, sizeof (struct mtop))) {
-			rc = -EFAULT;
-			goto out;
-		}
-		if(op.mt_count < 0){
-			rc = -EINVAL;
-			goto out;
-		}
-		if(op.mt_op == MTBSR  || 
-		   op.mt_op == MTFSR  ||
-		   op.mt_op == MTFSF  ||
-		   op.mt_op == MTBSR  ||
-		   op.mt_op == MTFSFM ||
-		   op.mt_op == MTBSFM) 
-		{
-			int i;
-			/* We assume that the backends can handle count up */	
-			/* to 500. */
-			for(i = 0; i < op.mt_count; i+=500){
-				rc = tapechar_mtioctop (filp, op.mt_op, MIN(500,op.mt_count-i)); 
-				if(rc)
-					goto out;
-			}
-		} else {
-			/* Single operations */
-			rc = tapechar_mtioctop (filp, op.mt_op, op.mt_count);
-		}
-		goto out;
-
-	case MTIOCPOS:		/* query tape position */
-		memset (&pos,0,sizeof (struct mtpos));
-		treq = td->discipline->ioctl (td, MTTELL,1,&rc);
-		if(!treq)
-			goto out;
-		rc = tape_do_io_and_wait(td,treq,TAPE_WAIT); 
-		TAPE_MERGE_RC(treq,rc);
-		if(rc == 0){
-			pos.mt_blkno = *((int*)(treq->kernbuf));
-			if (copy_to_user ((char *) arg, &pos, sizeof (struct mtpos)))
-				rc = -EFAULT;
-		}
-		tape_free_ccw_req(treq);
-		goto out;
-
-	case MTIOCGET:
-		memset (&get,0,sizeof (struct mtget));
-		treq = td->discipline->ioctl (td, MTTELL,1,&rc);
-		if(!treq)
-                        goto out;
-		rc = tape_do_io_and_wait(td,treq,TAPE_WAIT);
-		TAPE_MERGE_RC(treq,rc);
-		if(rc == 0){
-			get.mt_erreg = treq->rc;
-			get.mt_blkno = *((int*)(treq->kernbuf));
-			get.mt_type = MT_ISUNKNOWN;
-			get.mt_resid = td->devstat.rescnt;
-			get.mt_dsreg = td->tape_state;
-			if (copy_to_user ((char *) arg, &get, sizeof (struct mtget)))
-				rc = -EFAULT;	
-		}
-		tape_free_ccw_req(treq);
-		goto out;
-	default:
-	        tape_sprintf_event (tape_dbf_area,3,"c:ioct inv\n");
-		rc = -EINVAL;
-		goto out;
-	}
-out:
-	return rc;
-}
-
-/*
- * Tape device open function.
- */
-
-int
-tapechar_open (struct inode *inode, struct file *filp)
-{
-	tape_dev_t *td = NULL;
-	int  rc = 0;
-	long lockflags;
-
-	tape_sprintf_event (tape_dbf_area,6,"c:open: %x\n",td->first_minor); 
-
-	inode = filp->f_dentry->d_inode;
-
-	td = tape_get_device_by_minor(minor (inode->i_rdev));
-	if (td == NULL){
-		rc = -ENODEV;
-		goto error;
-	}
-	s390irq_spin_lock_irqsave(td->devinfo.irq,lockflags);
-	if (tape_state_get(td) == TS_NOT_OPER) {
-		tape_sprintf_event (tape_dbf_area,6,"c:nodev\n");
-		rc = -ENODEV;
-		goto out;
-	}
-
-	if (tape_state_get (td) != TS_UNUSED) {
-		tape_sprintf_event (tape_dbf_area,6,"c:dbusy\n");
-		rc = -EBUSY;
-		goto out;
-	}
-	if ( td->discipline->owner )
-		__MOD_INC_USE_COUNT(td->discipline->owner);
-	tape_state_set (td, TS_IN_USE);
-	td->filp = filp; /* save for later reference     */
-	filp->private_data = td;    /* save the dev.info for later reference */
-out:
-	s390irq_spin_unlock_irqrestore(td->devinfo.irq,lockflags);
-error:
-	if(rc != 0){
-		if (td!=NULL)
-			tape_put_device(td);
-	}
-	return rc;
-
-}
-
-/*
- * Tape device release function.
- */
-
-int
-tapechar_release (struct inode *inode, struct file *filp)
-{
-	tape_dev_t *td = NULL;
-	tape_ccw_req_t *treq = NULL;
-	int rc = 0;
-	long lockflags;
-
-	tape_sprintf_event (tape_dbf_area,6,"c:release: %x\n",td->first_minor);
-
-	td = (tape_dev_t*)filp->private_data;
-
-	if(td->last_op == TO_WRI)
-		tapechar_terminate_write(td);
-
-	if (minor (inode->i_rdev) == TAPECHAR_REW_MINOR(td->first_minor)) {
-		treq = td->discipline->ioctl (td, MTREW,1,&rc);
-		if (treq != NULL) {
-		        tape_sprintf_event (tape_dbf_area,6,"c:rewrelea\n");
-			rc = tape_do_io_and_wait(td, treq, TAPE_WAIT);
-			tape_free_ccw_req (treq);
-		}
-	}
-
-	s390irq_spin_lock_irqsave(td->devinfo.irq,lockflags);
-	if(tape_state_get(td) == TS_IN_USE)
-		tape_state_set (td, TS_UNUSED);
-	else if (tape_state_get(td) != TS_NOT_OPER) 
-		BUG();
-	s390irq_spin_unlock_irqrestore(td->devinfo.irq,lockflags);
-	if ( td->discipline->owner )
-		__MOD_DEC_USE_COUNT(td->discipline->owner);
-	tape_put_device(td);
-	return rc;
-}
diff -Nru a/drivers/s390/char/tapechar.h b/drivers/s390/char/tapechar.h
--- a/drivers/s390/char/tapechar.h	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,40 +0,0 @@
-
-/***************************************************************************
- *
- *  drivers/s390/char/tapechar.h
- *    character device frontend for tape device driver
- *
- *  S390 and zSeries version
- *    Copyright (C) 2001 IBM Corporation
- *    Author(s): Carsten Otte <cotte@de.ibm.com>
- *               Tuan Ngo-Anh <ngoanh@de.ibm.com>
- *
- *
- ****************************************************************************
- */
-
-#ifndef TAPECHAR_H
-#define TAPECHAR_H
-#include <linux/config.h>
-#define TAPECHAR_DEVFSMODE 0020644 // chardev, rwx for user, rw for group&others
-#define TAPECHAR_MAJOR 0  /* get dynamic major since no major officialy defined for tape */
-#define TAPECHAR_NOREW_MINOR(x) x    /* Minor for nonrewinding device */
-#define TAPECHAR_REW_MINOR(x)  (x+1) /* Minor for rewinding device */
-
-/*
- * Prototypes
- */
-
-ssize_t tapechar_read(struct file *, char *, size_t, loff_t *);
-ssize_t tapechar_write(struct file *, const char *, size_t, loff_t *);
-int tapechar_ioctl(struct inode *,struct file *,unsigned int,unsigned long);
-int tapechar_open (struct inode *,struct file *);
-int tapechar_release (struct inode *,struct file *);
-#ifdef CONFIG_DEVFS_FS
-devfs_handle_t tapechar_mkdevfstree (tape_dev_t* td);
-void tapechar_rmdevfstree (tape_dev_t* td);
-#endif
-void tapechar_init (void);
-void tapechar_uninit (void);
-
-#endif /* TAPECHAR_H */
diff -Nru a/drivers/s390/char/tapedefs.h b/drivers/s390/char/tapedefs.h
--- a/drivers/s390/char/tapedefs.h	Mon Dec  9 18:46:34 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,77 +0,0 @@
-/***********************************************************************
- *  drivers/s390/char/tapedefs.h
- *    tape device driver for S/390 and zSeries tapes.
- *
- *  S390 and zSeries version
- *    Copyright (C) 2001 IBM Corporation
- *    Author(s):  Carsten Otte <cotte@de.ibm.com>
- *                Tuan Ngo-Anh <ngoanh@de.ibm.com>
- *
- *
- ***********************************************************************
- */
-
-/* Kernel Version Compatibility section */
-#include <linux/version.h>
-#include <linux/blkdev.h>
-#include <linux/blk.h>
-#include <asm/irq.h>
-#include <linux/compatmac.h>
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,2,17))
-#define TAPE_DEBUG               // use s390 debug feature
-#else
-#undef TAPE_DEBUG                // debug feature not supported by our 2.2.16 code
-static inline void set_normalized_cda ( ccw1_t * cp, unsigned long address ) {
-    cp -> cda = address;
-}
-static inline void clear_normalized_cda ( ccw1_t * ccw ) {
-    ccw -> cda = 0;
-}
-#define BUG() PRINT_FATAL("tape390: CRITICAL INTERNAL ERROR OCCURED. REPORT THIS BACK TO LINUX390@DE.IBM.COM\n")
-#endif
-#define CONFIG_S390_TAPE_DYNAMIC // allow devices to be attached or detached on the fly
-#define TAPEBLOCK_RETRIES 20     // number of retries, when a block-dev request fails.
-
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
-#define INIT_BLK_DEV(d_major,d_request_fn,d_queue_fn,d_current) \
-do { \
-        blk_dev[d_major].queue = d_queue_fn; \
-} while(0)
-static inline struct request * 
-tape_next_request( request_queue_t *queue ) 
-{
-        return elv_next_request(queue);
-}
-static inline void 
-tape_dequeue_request( request_queue_t * q, struct request *req )
-{
-        blkdev_dequeue_request (req);
-}
-#else 
-#define s390_dev_info_t dev_info_t
-typedef struct request *request_queue_t;
-#ifndef init_waitqueue_head
-#define init_waitqueue_head(x) do { *x = NULL; } while(0)
-#endif
-#define blk_init_queue(x,y) do {} while(0)
-#define blk_queue_headactive(x,y) do {} while(0)
-#define INIT_BLK_DEV(d_major,d_request_fn,d_queue_fn,d_current) \
-do { \
-        blk_dev[d_major].request_fn = d_request_fn; \
-        blk_dev[d_major].queue = d_queue_fn; \
-        blk_dev[d_major].current_request = d_current; \
-} while(0)
-static inline struct request *
-tape_next_request( request_queue_t *queue ) 
-{
-    return *queue;
-}
-static inline void 
-tape_dequeue_request( request_queue_t * q, struct request *req )
-{
-        *q = req->next;
-        req->next = NULL;
-}
-#endif 
diff -Nru a/drivers/s390/cio/Makefile b/drivers/s390/cio/Makefile
--- a/drivers/s390/cio/Makefile	Mon Dec  9 18:46:34 2002
+++ b/drivers/s390/cio/Makefile	Mon Dec  9 18:46:34 2002
@@ -2,11 +2,18 @@
 # Makefile for the S/390 common i/o drivers
 #
 
-obj-y := cio_debug.o # make sure this always comes first
-obj-y += airq.o blacklist.o cio.o ioinfo.o misc.o requestirq.o s390io.o chsc.o
+obj-y += airq.o blacklist.o chsc.o cio.o css.o requestirq.o 
+export-objs += airq.o css.o chsc.o cio.o requestirq.o
 
-obj-$(CONFIG_PROC_FS) += proc.o
+ccw_device-objs += device.o device_fsm.o device_ops.o
+ccw_device-objs += device_id.o device_pgid.o device_status.o
+obj-y += ccw_device.o
+export-objs += device.o device_ops.o 
 
-export-objs += airq.o cio.o ioinfo.o requestirq.o s390io.o
+obj-$(CONFIG_CCWGROUP) += ccwgroup.o
+export-objs += ccwgroup.o
+
+obj-$(CONFIG_QDIO) += qdio.o
+export-objs += qdio.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/drivers/s390/cio/airq.c b/drivers/s390/cio/airq.c
--- a/drivers/s390/cio/airq.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/s390/cio/airq.c	Mon Dec  9 18:46:50 2002
@@ -1,28 +1,22 @@
 /*
  *  drivers/s390/cio/airq.c
- *   S/390 common I/O routines -- special interrupt registration
- *   currently used only by qdio
+ *   S/390 common I/O routines -- support for adapter interruptions
  *
- *   $Revision: 1.3 $
+ *   $Revision: 1.10 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
- *                            IBM Corporation
+ *			      IBM Corporation
  *    Author(s): Ingo Adlung (adlung@de.ibm.com)
- *               Cornelia Huck (cohuck@de.ibm.com) 
+ *		 Cornelia Huck (cohuck@de.ibm.com)
  *		 Arnd Bergmann (arndb@de.ibm.com)
- *    ChangeLog: 11/04/2002 Arnd Bergmann Split s390io.c into multiple files,
- *					  see s390io.c for complete list of
- * 					  changes.
  */
 
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <asm/idals.h>
-#include <asm/debug.h>
 
-#include "airq.h"
 #include "cio_debug.h"
+#include "airq.h"
 
 static spinlock_t adapter_lock = SPIN_LOCK_UNLOCKED;
 static adapter_int_handler_t adapter_handler;
@@ -41,7 +35,7 @@
 int
 s390_register_adapter_interrupt (adapter_int_handler_t handler)
 {
-	int ret = 0;
+	int ret;
 	char dbf_txt[15];
 
 	CIO_TRACE_EVENT (4, "rgaint");
@@ -52,21 +46,23 @@
 		ret = -EINVAL;
 	else if (adapter_handler)
 		ret = -EBUSY;
-	else
+	else {
 		adapter_handler = handler;
+		ret = 0;
+	}
 
 	spin_unlock (&adapter_lock);
 
 	sprintf (dbf_txt, "ret:%d", ret);
 	CIO_TRACE_EVENT (4, dbf_txt);
 
-	return ret;
+	return (ret);
 }
 
 int
 s390_unregister_adapter_interrupt (adapter_int_handler_t handler)
 {
-	int ret = 0;
+	int ret;
 	char dbf_txt[15];
 
 	CIO_TRACE_EVENT (4, "urgaint");
@@ -77,15 +73,17 @@
 		ret = -EINVAL;
 	else if (handler != adapter_handler)
 		ret = -EINVAL;
-	else
+	else {
 		adapter_handler = NULL;
+		ret = 0;
+	}
 
 	spin_unlock (&adapter_lock);
 
 	sprintf (dbf_txt, "ret:%d", ret);
 	CIO_TRACE_EVENT (4, dbf_txt);
 
-	return ret;
+	return (ret);
 }
 
 void
diff -Nru a/drivers/s390/cio/airq.h b/drivers/s390/cio/airq.h
--- a/drivers/s390/cio/airq.h	Mon Dec  9 18:46:50 2002
+++ b/drivers/s390/cio/airq.h	Mon Dec  9 18:46:50 2002
@@ -1,5 +1,10 @@
 #ifndef S390_AINTERRUPT_H
 #define S390_AINTERRUPT_H
 
+typedef	int (*adapter_int_handler_t)(__u32 intparm);
+
+extern int s390_register_adapter_interrupt(adapter_int_handler_t handler);
+extern int s390_unregister_adapter_interrupt(adapter_int_handler_t handler);
 extern void do_adapter_IO (__u32 intparm);
+
 #endif
diff -Nru a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c
--- a/drivers/s390/cio/blacklist.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/s390/cio/blacklist.c	Mon Dec  9 18:46:35 2002
@@ -1,40 +1,30 @@
 /*
  *  drivers/s390/cio/blacklist.c
  *   S/390 common I/O routines -- blacklisting of specific devices
- *   $Revision: 1.7 $
+ *   $Revision: 1.22 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
- *                            IBM Corporation
+ *			      IBM Corporation
  *    Author(s): Ingo Adlung (adlung@de.ibm.com)
- *               Cornelia Huck (cohuck@de.ibm.com) 
+ *		 Cornelia Huck (cohuck@de.ibm.com)
  *		 Arnd Bergmann (arndb@de.ibm.com)
- *    ChangeLog: 11/04/2002 Arnd Bergmann Split s390io.c into multiple files,
- *					  see s390io.c for complete list of
- * 					  changes.
- * 		 15/04/2002 Arnd Bergmann check ranges of user input
- * 		 18/04/2002 Arnd Bergmann remove bogus optimization and
- * 		 			  now unnecessary locking
- * 		 19/04/2002 Arnd Bergmann cleanup parameter parsing
  */
+
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/ctype.h>
+#include <linux/device.h>
 
-#include <asm/irq.h>
-#include <asm/s390dyn.h>
 #include <asm/uaccess.h>
-#include <asm/debug.h>
 
 #include "blacklist.h"
 #include "cio_debug.h"
-#include "ioinfo.h"
-#include "proc.h"
-#include "s390io.h"
+#include "css.h"
 
-/* 
+/*
  * "Blacklisting" of certain devices:
  * Device numbers given in the commandline as cio_ignore=... won't be known
  * to Linux.
@@ -42,12 +32,13 @@
  * These can be single devices or ranges of devices
  */
 
-#define max_devno (0xffffUL)
-static uint32_t bl_dev[(max_devno+1) / 32]; /* 65536 bits to indicate if a
-					       devno is blacklisted or not */
+/* 65536 bits to indicate if a devno is blacklisted or not */
+#define __BL_DEV_WORDS (__MAX_SUBCHANNELS + (8*sizeof(long) - 1) / \
+			 (8*sizeof(long)))
+static unsigned long bl_dev[__BL_DEV_WORDS];
 typedef enum {add, free} range_action;
 
-/* 
+/*
  * Function: blacklist_range
  * (Un-)blacklist the devices from-to
  */
@@ -57,47 +48,50 @@
 	if (!to)
 		to = from;
 
-	if ((from > to) || (to > max_devno)) {
+	if (from > to || to > __MAX_SUBCHANNELS) {
 		printk (KERN_WARNING "Invalid blacklist range "
 			"0x%04x to 0x%04x, skipping\n", from, to);
 		return;
 	}
 	for (; from <= to; from++) {
-		(action == add) ? set_bit (from, &bl_dev)
-				: clear_bit (from, &bl_dev);
+		if (action == add)
+			set_bit (from, bl_dev);
+		else
+			clear_bit (from, bl_dev);
 	}
 }
 
-/* 
+/*
  * function: blacklist_strtoul
  * Strip leading '0x' and interpret the values as Hex
  */
 static inline int
 blacklist_strtoul (const char *str, char **stra)
 {
-        if (*str == '0') {
-                if (*(++str) == 'x')  /* strip leading zero */
-                        str++;        /* strip leading x */
-        }
-        return simple_strtoul (str, stra, 16); /* interpret anything as hex */
+	if (*str == '0') {
+		if (*(++str) == 'x')  /* strip leading zero */
+			str++;	      /* strip leading x */
+	}
+	return simple_strtoul (str, stra, 16); /* interpret anything as hex */
 }
 
 static inline int
 blacklist_parse_parameters (char *str, range_action action)
 {
 	unsigned int from, to;
+
 	while (*str != 0 && *str != '\n') {
 		if (!isxdigit(*str)) {
 			printk(KERN_WARNING "blacklist_setup: error parsing "
-					 "\"%s\"\n", str);
+			       "\"%s\"\n", str);
 			return 0;
 		}
 
 		from = blacklist_strtoul (str, &str);
 		to = (*str == '-') ? blacklist_strtoul (str+1, &str) : from;
 
-		printk (KERN_INFO "blacklist_setup: adding range "
-				  "from 0x%04x to 0x%04x\n", from, to);
+		pr_debug("blacklist_setup: adding range "
+			 "from 0x%04x to 0x%04x\n", from, to);
 		blacklist_range (action, from, to);
 
 		if (*str == ',')
@@ -128,13 +122,14 @@
 
 /*
  * Function: is_blacklisted
- * Returns 1 if the given devicenumber can be found in the blacklist, otherwise 0.
- * Used by s390_validate_subchannel()
+ * Returns 1 if the given devicenumber can be found in the blacklist,
+ * otherwise 0.
+ * Used by validate_subchannel()
  */
 int
 is_blacklisted (int devno)
 {
-	return test_bit (devno, &bl_dev);
+	return test_bit (devno, bl_dev);
 }
 
 #ifdef CONFIG_PROC_FS
@@ -150,23 +145,8 @@
 
 	CIO_TRACE_EVENT (0, "redoval");
 
-	for (irq=0; irq <= highest_subchannel; irq++) {
-		if (ioinfo[irq] != INVALID_STORAGE_AREA
-		    || s390_validate_subchannel (irq, 0))
-			continue;
-
-		/* this subchannel has just been unblacklisted, 
-		 * so now try to get it working */
-		s390_device_recognition_irq (irq);
-
-		if (ioinfo[irq]->ui.flags.oper) {
-			devreg_t *pdevreg;
-			pdevreg = s390_search_devreg (ioinfo[irq]);
-			if (pdevreg && pdevreg->oper_func != NULL)
-				pdevreg->oper_func (irq, pdevreg);
-		}
-
-	}
+	for (irq = 0; irq <= highest_subchannel; irq++)
+		css_probe_device(irq);
 }
 
 /*
@@ -178,13 +158,13 @@
 {
 	if (strncmp (buf, "free ", 5) == 0) {
 		if (strstr (buf + 5, "all"))
-			blacklist_range (free, 0, max_devno);
+			blacklist_range (free, 0, __MAX_SUBCHANNELS);
 		else
 			blacklist_parse_parameters (buf + 5, free);
 	} else if (strncmp (buf, "add ", 4) == 0) {
 		/* FIXME: the old code was checking if the new bl'ed
 		 * devices are already known to the system so
-		 * s390_validate_subchannel would still give a working
+		 * validate_subchannel would still give a working
 		 * status. is that necessary? */
 		blacklist_parse_parameters (buf + 4, add);
 	} else {
@@ -202,40 +182,40 @@
 static int cio_ignore_read (char *page, char **start, off_t off,
 			    int count, int *eof, void *data)
 {
-	int len = 0;
 	const unsigned int entry_size = 14; /* "0xABCD-0xEFGH\n" */
-	long devno = off; /* abuse the page variable
-			   * as counter, see fs/proc/generic.c */
+	long devno;
+	int len;
 
-	while ((devno <= max_devno)
-	       && (len + entry_size < count)) {
-		if (test_bit (devno, &bl_dev)) {
-			len += sprintf(page + len, "0x%04lx", devno);
-			devno++;
-			if (test_bit (devno, &bl_dev)) { /* print range */
-				do { devno++; } 
-					while (test_bit (devno, &bl_dev));
-				
-				len += sprintf(page + len, "-0x%04lx", devno-1);
-			}
-			len += sprintf(page + len, "\n");
+	len = 0;
+	for (devno = off; /* abuse the page variable
+			   * as counter, see fs/proc/generic.c */
+	     devno <= __MAX_SUBCHANNELS && len + entry_size < count; devno++) {
+		if (!test_bit(devno, bl_dev))
+			continue;
+		len += sprintf(page + len, "0x%04lx", devno);
+		if (test_bit(devno + 1, bl_dev)) { /* print range */
+			while (++devno < __MAX_SUBCHANNELS)
+				if (!test_bit(devno, bl_dev))
+					break;
+			len += sprintf(page + len, "-0x%04lx", devno);
 		}
-		devno++;
+		len += sprintf(page + len, "\n");
 	}
 
-	if (devno <= max_devno)
+	if (devno <= __MAX_SUBCHANNELS)
 		*eof = 1;
-
 	*start = (char *) (devno - off); /* number of checked entries */
-
 	return len;
 }
 
 static int cio_ignore_write (struct file *file, const char *user_buf,
 			     unsigned long user_len, void *data)
 {
-	char *buf = vmalloc (user_len + 1); /* maybe better use the stack? */
+	char *buf;
 
+	if (user_len > 65536)
+		user_len = 65536;
+	buf = vmalloc (user_len + 1); /* maybe better use the stack? */
 	if (buf == NULL)
 		return -ENOMEM;
 	if (strncpy_from_user (buf, user_buf, user_len) < 0) {
@@ -243,10 +223,7 @@
 		return -EFAULT;
 	}
 	buf[user_len] = '\0';
-#if 0
-	CIO_DEBUG(KERN_DEBUG, 2, 
-		  "/proc/cio_ignore: '%s'\n", buf);
-#endif
+
 	blacklist_parse_proc_parameters (buf);
 
 	vfree (buf);
@@ -257,6 +234,7 @@
 cio_ignore_proc_init (void)
 {
 	struct proc_dir_entry *entry;
+
 	entry = create_proc_entry ("cio_ignore", S_IFREG | S_IRUGO | S_IWUSR,
 				   &proc_root);
 	if (!entry)
diff -Nru a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/cio/ccwgroup.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,305 @@
+/*
+ *  drivers/s390/cio/ccwgroup.c
+ *  bus driver for ccwgroup
+ *   $Revision: 1.5 $
+ *
+ *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
+ *                       IBM Corporation
+ *    Author(s): Arnd Bergmann (arndb@de.ibm.com)
+ */
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/ctype.h>
+
+#include <asm/semaphore.h>
+#include <asm/ccwdev.h>
+#include <asm/ccwgroup.h>
+
+/* In Linux 2.4, we had a channel device layer called "chandev"
+ * that did all sorts of obscure stuff for networking devices.
+ * This is another driver that serves as a replacement for just
+ * one of its functions, namely the translation of single subchannels
+ * to devices that use multiple subchannels.
+ */
+
+/* a device matches a driver if all its slave devices match the same
+ * entry of the driver */
+static int
+ccwgroup_bus_match (struct device * dev, struct device_driver * drv)
+{
+	struct ccwgroup_device *gdev;
+	struct ccwgroup_driver *gdrv;
+
+	gdev = container_of(dev, struct ccwgroup_device, dev);
+	gdrv = container_of(drv, struct ccwgroup_driver, driver);
+
+	if (gdev->creator_id == gdrv->driver_id)
+		return 1;
+
+	return 0;
+}
+static int
+ccwgroup_hotplug (struct device *dev, char **envp, int num_envp, char *buffer,
+		  int buffer_size)
+{
+	/* TODO */
+	return 0;
+}
+
+static struct bus_type ccwgroup_bus_type = {
+	.name    = "ccwgroup",
+	.match   = ccwgroup_bus_match,
+	.hotplug = ccwgroup_hotplug,
+};
+
+static void
+ccwgroup_release (struct device *dev)
+{
+	struct ccwgroup_device *gdev;
+	int i;
+
+	gdev = to_ccwgroupdev(dev);
+
+	for (i = 0; i < gdev->count; i++)
+		put_device(&gdev->cdev[i]->dev);
+	kfree(gdev);
+}
+
+/*
+ * try to add a new ccwgroup device for one driver
+ * argc and argv[] are a list of bus_id's of devices
+ * belonging to the driver.
+ */
+int
+ccwgroup_create(struct device *root,
+		unsigned int creator_id,
+		struct ccw_driver *cdrv,
+		int argc, char *argv[])
+{
+	struct ccwgroup_device *gdev;
+	int i;
+
+	if (argc > 256) /* disallow dumb users */
+		return -EINVAL;
+
+	gdev = kmalloc(sizeof(*gdev) + argc*sizeof(gdev->cdev[0]), GFP_KERNEL);
+	if (!gdev)
+		return -ENOMEM;
+
+	for (i = 0; i < argc; i++) {
+		gdev->cdev[i] = get_ccwdev_by_busid(cdrv, argv[i]);
+
+		/* all devices have to be of the same type in
+		 * order to be grouped */
+		if (!gdev->cdev[i]
+		    || gdev->cdev[i]->id.driver_info !=
+		       gdev->cdev[0]->id.driver_info)
+			goto error;
+	}
+
+	*gdev = (struct ccwgroup_device) {
+		.creator_id = creator_id,
+		.count = argc,
+		.dev = {
+			.bus = &ccwgroup_bus_type,
+			.parent = root,
+			.release = &ccwgroup_release,
+		},
+	};
+
+	snprintf (gdev->dev.bus_id, BUS_ID_SIZE, "%s",
+			gdev->cdev[0]->dev.bus_id);
+
+	/* TODO: make symlinks for sysfs */
+	return device_register(&gdev->dev);
+
+error:
+	for (i = 0; i < argc; i++)
+		if (gdev->cdev[i])
+			put_device(&gdev->cdev[i]->dev);
+
+	kfree(gdev);
+
+	return -EINVAL;
+}
+
+static int __init
+init_ccwgroup (void)
+{
+	return bus_register (&ccwgroup_bus_type);
+}
+
+static void __exit
+cleanup_ccwgroup (void)
+{
+	bus_unregister (&ccwgroup_bus_type);
+}
+
+module_init(init_ccwgroup);
+module_exit(cleanup_ccwgroup);
+
+/************************** driver stuff ******************************/
+
+static int
+ccwgroup_set_online(struct ccwgroup_device *gdev)
+{
+	struct ccwgroup_driver *gdrv;
+	int ret;
+
+	if (gdev->state == CCWGROUP_ONLINE)
+		return 0;
+
+	if (!gdev->dev.driver)
+		return -EINVAL;
+
+	gdrv = to_ccwgroupdrv (gdev->dev.driver);
+	if ((ret = gdrv->set_online(gdev)))
+		return ret;
+
+	gdev->state = CCWGROUP_ONLINE;
+	return 0;
+}
+
+static int
+ccwgroup_set_offline(struct ccwgroup_device *gdev)
+{
+	struct ccwgroup_driver *gdrv;
+	int ret;
+
+	if (gdev->state == CCWGROUP_OFFLINE)
+		return 0;
+
+	if (!gdev->dev.driver)
+		return -EINVAL;
+
+	gdrv = to_ccwgroupdrv (gdev->dev.driver);
+	if ((ret = gdrv->set_offline(gdev)))
+		return ret;
+
+	gdev->state = CCWGROUP_OFFLINE;
+	return 0;
+}
+
+static ssize_t
+ccwgroup_online_store (struct device *dev, const char *buf, size_t count,
+			loff_t off)
+{
+	struct ccwgroup_device *gdev;
+	unsigned int value;
+
+	if (off)
+		return 0;
+
+	gdev = to_ccwgroupdev(dev);
+	if (!dev->driver)
+		return count;
+
+	value = simple_strtoul(buf, 0, 0);
+
+	if (value)
+		ccwgroup_set_online(gdev);
+	else
+		ccwgroup_set_offline(gdev);
+
+	return count;
+}
+
+static ssize_t
+ccwgroup_online_show (struct device *dev, char *buf, size_t count, loff_t off)
+{
+	int online;
+
+	if (off)
+		return 0;
+
+	online = (to_ccwgroupdev(dev)->state == CCWGROUP_ONLINE);
+
+	return snprintf(buf, count, online ? "1\n" : "0\n");
+}
+
+static DEVICE_ATTR(online, 0644, ccwgroup_online_show, ccwgroup_online_store);
+
+static int
+ccwgroup_probe (struct device *dev)
+{
+	struct ccwgroup_device *gdev;
+	struct ccwgroup_driver *gdrv;
+
+	int ret;
+
+	gdev = to_ccwgroupdev(dev);
+	gdrv = to_ccwgroupdrv(dev->driver);
+
+	if ((ret = device_create_file(dev, &dev_attr_online)))
+		return ret;
+
+	pr_debug("%s: device %s\n", __func__, gdev->dev.name);
+	ret = gdrv->probe ? gdrv->probe(gdev) : -ENODEV;
+	if (ret)
+		device_remove_file(dev, &dev_attr_online);
+
+	return ret;
+}
+
+static int
+ccwgroup_remove (struct device *dev)
+{
+	struct ccwgroup_device *gdev;
+	struct ccwgroup_driver *gdrv;
+	int ret;
+
+	gdev = to_ccwgroupdev(dev);
+	gdrv = to_ccwgroupdrv(dev->driver);
+
+	pr_debug("%s: device %s\n", __func__, gdev->dev.name);
+
+	device_remove_file(dev, &dev_attr_online);
+	ccwgroup_set_offline(gdev);
+
+	ret = (gdrv && gdrv->remove) ? gdrv->remove(gdev) : 0;
+
+	return ret;
+}
+
+int
+ccwgroup_driver_register (struct ccwgroup_driver *cdriver)
+{
+	/* register our new driver with the core */
+	cdriver->driver = (struct device_driver) {
+		.bus = &ccwgroup_bus_type,
+		.name = cdriver->name,
+		.probe = ccwgroup_probe,
+		.remove = ccwgroup_remove,
+	};
+
+	return driver_register(&cdriver->driver);
+}
+
+void
+ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver)
+{
+	driver_unregister(&cdriver->driver);
+}
+
+int
+ccwgroup_probe_ccwdev(struct ccw_device *cdev)
+{
+	return 0;
+}
+
+int
+ccwgroup_remove_ccwdev(struct ccw_device *cdev)
+{
+	return 0;
+}
+
+MODULE_LICENSE("GPL");
+EXPORT_SYMBOL(ccwgroup_driver_register);
+EXPORT_SYMBOL(ccwgroup_driver_unregister);
+EXPORT_SYMBOL(ccwgroup_create);
+EXPORT_SYMBOL(ccwgroup_probe_ccwdev);
+EXPORT_SYMBOL(ccwgroup_remove_ccwdev);
diff -Nru a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
--- a/drivers/s390/cio/chsc.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/s390/cio/chsc.c	Mon Dec  9 18:46:38 2002
@@ -1,118 +1,125 @@
 /*
  *  drivers/s390/cio/chsc.c
  *   S/390 common I/O routines -- channel subsystem call
- *   $Revision: 1.12 $
+ *   $Revision: 1.43 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
- *                            IBM Corporation
+ *			      IBM Corporation
  *    Author(s): Ingo Adlung (adlung@de.ibm.com)
- *               Cornelia Huck (cohuck@de.ibm.com) 
+ *		 Cornelia Huck (cohuck@de.ibm.com)
  *		 Arnd Bergmann (arndb@de.ibm.com)
- *    ChangeLog: 11/04/2002 Arnd Bergmann Split s390io.c into multiple files,
- *					  see s390io.c for complete list of
- *					  changes.
  */
 
 #include <linux/module.h>
 #include <linux/config.h>
 #include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/bootmem.h>
 #include <linux/init.h>
+#include <linux/device.h>
 
-#include <asm/idals.h>
-#include <asm/uaccess.h>
-#include <asm/s390io.h>
-#include <asm/debug.h>
+#include <asm/cio.h>
+#include <asm/ccwdev.h> // FIXME: layering violation, remove this
 
+#include "css.h"
+#include "cio.h"
 #include "cio_debug.h"
-#include "s390io.h"
-#include "proc.h"
-#include "ioinfo.h"
+#include "device.h" // FIXME: layering violation, remove this
+#include "ioasm.h"
+#include "chsc.h"
+
+#define CHPID_LONGS (256 / (8 * sizeof(long))) /* 256 chpids */
+static unsigned long chpids[CHPID_LONGS];
+static unsigned long chpids_logical[CHPID_LONGS] = {[0 ... CHPID_LONGS-1] -1};
+static unsigned long chpids_known[CHPID_LONGS];
 
-#ifdef CONFIG_DEBUG_CHSC
-#define DBGC printk
-#else
-#define DBGC(args,...) do {} while (0)
-#endif
-
-#define CHSC_DEBUG(printk_level,event_type,event_level,msg...) ({\
-	if (cio_show_msg) DBGC(printk_level msg); \
-	CIO_ ## event_type ## _EVENT (event_level, msg); \
-})
-static __u64 chpids[4]; /* 256 chpids */
-static __u64 chpids_logical[4] = {-1,-1,-1,-1};
-static __u64 chpids_known[4];
+static struct channel_path *chps[NR_CHPIDS];
 
 static int cio_chsc_desc_avail;
 
+static int new_channel_path(int chpid, int status);
+
 int
-chsc_chpid_logical (int irq, int chp)
+chsc(void *data)
 {
-	return test_bit (ioinfo[irq]->schib.pmcw.chpid[chp], &chpids_logical);
+	void *area;
+	int cc;
+
+	if (!data)
+		return -EINVAL;
+
+	area = (void *)get_zeroed_page(GFP_KERNEL);
+	if (!area)
+		return -ENOMEM;
+	memcpy(area, data, PAGE_SIZE);
+	cc = do_chsc(area);
+	if (cc == 0)
+		memcpy(data, area, PAGE_SIZE);
+	free_page((unsigned long)area);
+	return cc;
 }
 
-static inline void
-chsc_clear_chpid(int irq, int chp)
+static int
+set_chp_status(int chp, int status)
 {
-	clear_bit(ioinfo[irq]->schib.pmcw.chpid[chp], &chpids);
+	if (chps[chp] == NULL)
+		return -EINVAL;
+
+	chps[chp]->state = status;
+	return 0;
 }
 
-void
-chsc_validate_chpids(int irq)
+static inline int
+chsc_chpid_logical (struct subchannel *sch, int chp)
 {
-	int mask, chp;
+	return test_bit (sch->schib.pmcw.chpid[chp], chpids_logical);
+}
 
-	if (ioinfo[irq]->opm) {
-		for (chp=0;chp<=7;chp++) {
-			mask = 0x80 >> chp;
-			if (ioinfo[irq]->opm & mask) {
-				if (!chsc_chpid_logical(irq,chp))
-					/* disable using this path */
-					ioinfo[irq]->opm &= ~mask;
-			} else {
-				/* This chpid is not
-				 * available to us */
-				chsc_clear_chpid(irq,chp);
-			}
-		}
-		
-	}
-	
+static inline void
+chsc_clear_chpid(struct subchannel *sch, int chp)
+{
+	clear_bit(sch->schib.pmcw.chpid[chp], chpids);
 }
 
 void
-switch_off_chpids(int irq, __u8 mask)
+chsc_validate_chpids(struct subchannel *sch)
 {
-	int i;
-	pmcw_t *pmcw = &ioinfo[irq]->schib.pmcw;
+	int mask, chp;
+
+	if (sch->lpm == 0)
+		return;
 
-	for (i=0;i<8;i++)
-		if ((0x80>>i) & mask
-		    & pmcw->pim
-		    & pmcw->pam
-		    & pmcw->pom)
-			clear_bit(pmcw->chpid[i], &chpids);
+	for (chp = 0; chp <= 7; chp++) {
+		mask = 0x80 >> chp;
+		if (sch->lpm & mask) {
+			if (!chsc_chpid_logical(sch, chp))
+				/* disable using this path */
+				sch->lpm &= ~mask;
+		} else {
+			/* This chpid is not
+			 * available to us */
+			chsc_clear_chpid(sch, chp);
+			if (test_bit(chp, chpids_known))
+				set_chp_status(chp, CHP_STANDBY);
+		}
+	}
 }
 
 /* FIXME: this is _always_ called for every subchannel. shouldn't we
- * 	  process more than one at a time?*/
+ *	  process more than one at a time?*/
 static int
 chsc_get_sch_desc_irq(int irq)
 {
-	int j = 0;
-	int ccode;
+	int ccode, chpid, j;
 
 	/* FIXME: chsc_area_sei cannot be on the stack since it needs to
 	 * be page-aligned. Implement proper locking or dynamic
 	 * allocation or prove that this function does not have to be
 	 * reentrant! */
-	static chsc_area_t __attribute__ ((aligned(PAGE_SIZE))) chsc_area_ssd;
+	static struct chsc_area __attribute__ ((aligned(PAGE_SIZE))) chsc_area_ssd;
 
 	typeof (chsc_area_ssd.response_block.response_block_data.ssd_res)
 		*ssd_res = &chsc_area_ssd.response_block.response_block_data.ssd_res;
 
-	chsc_area_ssd = (chsc_area_t) {
+	chsc_area_ssd = (struct chsc_area) {
 		.request_block = {
 			.command_code1 = 0x0010,
 			.command_code2 = 0x0004,
@@ -127,9 +134,7 @@
 
 	ccode = chsc(&chsc_area_ssd);
 	if (ccode > 0) {
-		if (cio_show_msg)
-			DBGC( KERN_DEBUG "chsc returned with ccode = %d\n",
-			     ccode);
+		pr_debug("chsc returned with ccode = %d\n", ccode);
 		if (ccode == 3)
 			return -ENODEV;
 		return -EBUSY;
@@ -139,47 +144,47 @@
 	case 0x0001: /* everything ok */
 		break;
 	case 0x0002:
-		CHSC_DEBUG (KERN_WARNING, CRW, 2, "Invalid command!\n");
+		CIO_CRW_EVENT(2, "Invalid command!\n");
 	case 0x0003:
-		CHSC_DEBUG (KERN_WARNING, CRW, 2, "Error in chsc request block!\n");
+		CIO_CRW_EVENT(2, "Error in chsc request block!\n");
 		return -EINVAL;
 	case 0x0004:
-		CHSC_DEBUG (KERN_WARNING, CRW, 2, "Model does not provide ssd\n");
+		CIO_CRW_EVENT(2, "Model does not provide ssd\n");
 		return -EOPNOTSUPP;
 	default:
-		CHSC_DEBUG (KERN_WARNING, CRW, 2, "Unknown CHSC response %d\n", 
-				chsc_area_ssd.response_block.response_code);
+		CIO_CRW_EVENT(2, "Unknown CHSC response %d\n",
+			      chsc_area_ssd.response_block.response_code);
 		return -EIO;
 	}
 
-	/* ssd_res->st stores the type of the detected
+	/*
+	 * ssd_res->st stores the type of the detected
 	 * subchannel, with the following definitions:
-	 * 
+	 *
 	 * 0: I/O subchannel:	  All fields have meaning
 	 * 1: CHSC subchannel:	  Only sch_val, st and sch
-	 * 			  have meaning
+	 *			  have meaning
 	 * 2: Message subchannel: All fields except unit_addr
-	 * 			  have meaning
+	 *			  have meaning
 	 * 3: ADM subchannel:	  Only sch_val, st and sch
-	 * 			  have meaning
+	 *			  have meaning
 	 *
 	 * Other types are currently undefined.
-	 *
 	 */
 	if (ssd_res->st > 3) { /* uhm, that looks strange... */
-		CHSC_DEBUG (KERN_DEBUG, CRW, 0, "Strange subchannel type %d"
-			    " for sch %x\n", ssd_res->st, irq);
+		CIO_CRW_EVENT(0, "Strange subchannel type %d"
+			      " for sch %x\n", ssd_res->st, irq);
 		/*
-		 * There may have been a new subchannel type defined in the 
+		 * There may have been a new subchannel type defined in the
 		 * time since this code was written; since we don't know which
 		 * fields have meaning and what to do with it we just jump out
 		 */
-		return 0; 
-	} else { 
+		return 0;
+	} else {
 		const char type[4][8] = {"I/O", "chsc", "message", "ADM"};
-		CHSC_DEBUG (KERN_DEBUG, CRW, 6,"ssd: sch %x is %s subchannel\n",
-				irq, type[ssd_res->st]);
-		if (ioinfo[irq] == INVALID_STORAGE_AREA)
+		CIO_CRW_EVENT(6, "ssd: sch %x is %s subchannel\n",
+			      irq, type[ssd_res->st]);
+		if (ioinfo[irq] == NULL)
 			/* FIXME: we should do device rec. here... */
 			return 0;
 
@@ -187,44 +192,37 @@
 		ioinfo[irq]->ssd_info.type = ssd_res->st;
 	}
 
-	switch (ssd_res->st) {
-	case 0: /* fall through */
-	case 2:
-		for (j=0;j<8;j++) {
-			if ((0x80 >> j) & ssd_res->path_mask &
-					  ssd_res->fla_valid_mask) {
-				u8 chpid = ssd_res->chpid[j];
-				if (chpid 
-				    && (!test_and_set_bit (chpid, &chpids_known))
-				    && (test_bit (chpid, &chpids_logical)))
-					set_bit  (chpid, &chpids);
+	if (ssd_res->st == 0 || ssd_res->st == 2) {
+		for (j = 0; j < 8; j++) {
+			if (!((0x80 >> j) & ssd_res->path_mask &
+			      ssd_res->fla_valid_mask))
+				continue;
+			chpid = ssd_res->chpid[j];
+			if (chpid
+			    && (!test_and_set_bit (chpid, chpids_known))
+			    && (test_bit (chpid, chpids_logical)))
+				set_bit	 (chpid, chpids);
 
-				ioinfo[irq]->ssd_info.chpid[j] = chpid;
-				ioinfo[irq]->ssd_info.fla[j]   = ssd_res->fla[j];
-			}
+			ioinfo[irq]->ssd_info.chpid[j] = chpid;
+			ioinfo[irq]->ssd_info.fla[j]   = ssd_res->fla[j];
 		}
-		break;
-	default:
-		break;
 	}
 	return 0;
 }
 
 static int
-chsc_get_sch_descriptions( void )
+chsc_get_sch_descriptions(void)
 {
-	int irq = 0;
-	int err = 0;
+	int irq;
+	int err;
 
 	CIO_TRACE_EVENT( 4, "gsdesc");
 
 	/*
-	 * get information about chpids and link addresses 
+	 * get information about chpids and link addresses
 	 * by executing the chsc command 'store subchannel description'
 	 */
-
-	for (irq=0; irq<=highest_subchannel; irq++) {
-
+	for (irq = 0; irq <= highest_subchannel; irq++) {
 		/*
 		 * retrieve information for each sch
 		 */
@@ -233,12 +231,12 @@
 			static int cio_chsc_err_msg;
 
 			if (!cio_chsc_err_msg) {
-				printk( KERN_ERR
-					"chsc_get_sch_descriptions:"
-					" Error %d while doing chsc; "
-					"processing some machine checks may "
-					"not work\n", err);
-				cio_chsc_err_msg=1;
+				printk(KERN_ERR
+				       "chsc_get_sch_descriptions:"
+				       " Error %d while doing chsc; "
+				       "processing some machine checks may "
+				       "not work\n", err);
+				cio_chsc_err_msg = 1;
 			}
 			return err;
 		}
@@ -250,96 +248,62 @@
 __initcall(chsc_get_sch_descriptions);
 
 
-/* FIXME: don't iterate all subchannels but use the list of known ones*/
 static inline void
-s390_do_chpid_processing( __u8 chpid)
+s390_subchannel_remove_chpid(struct subchannel *sch, __u8 chpid)
 {
-	int irq;
 	int j;
+
+	for (j = 0; j < 8; j++)
+		if (sch->schib.pmcw.chpid[j] == chpid)
+			break;
+	if (j >= 8)
+		return;
+
+	spin_lock(&sch->lock);
+
+	chsc_validate_chpids(sch);
+
+	/* just to be sure... */
+	sch->lpm &= ~(0x80>>j);
+
+	/* trigger path verification. */
+	dev_fsm_event(sch->dev.driver_data, DEV_EVENT_VERIFY);
+
+	spin_unlock(&sch->lock);
+}
+
+/* FIXME: don't iterate all subchannels but use driver_for_each_dev */
+static inline void
+s390_set_chpid_offline( __u8 chpid)
+{
 	char dbf_txt[15];
-	int ccode;
-	int was_oper;
-	int mask2;
+	struct subchannel *sch;
+	int irq;
 
 	sprintf(dbf_txt, "chpr%x", chpid);
-	CIO_TRACE_EVENT( 2, dbf_txt);
+	CIO_TRACE_EVENT(2, dbf_txt);
 
-	/* 
+	/*
 	 * TODO: the chpid may be not the chpid with the link incident,
 	 * but the chpid the report came in through. How to handle???
 	 */
-	clear_bit(chpid, &chpids);
-	if (!test_and_clear_bit(chpid, &chpids_known))
-		return;  /* we didn't know the chpid anyway */
-
-	for (irq=0;irq<=highest_subchannel;irq++) {
-		if (ioinfo[irq] == INVALID_STORAGE_AREA) 
-			continue;  /* we don't know the device anyway */
-		if (ioinfo[irq]->st)
-			continue; /* non-io subchannel */
-		for (j=0; j<8;j++) {
-			if (ioinfo[irq]->schib.pmcw.chpid[j] != chpid)
-				continue;
-
- 			/* 
- 			 * Note: irq spinlock is grabbed several times
- 			 * in here
- 			 */
-			mask2 = 0x80 >> j;
-			s390_send_nop (irq, mask2);
+	clear_bit(chpid, chpids);
+	if (!test_and_clear_bit(chpid, chpids_known))
+		return;	 /* we didn't know the chpid anyway */
 
-			s390irq_spin_lock(irq);
+	set_chp_status(chpid, CHP_OFFLINE);
 
-			/*
-			 * FIXME: is this neccessary?
-			 */				
-			ccode = stsch(irq, &ioinfo[irq]->schib);
-			if (ccode) {
-				CHSC_DEBUG (KERN_WARNING, CRW,2,
-					"do_crw_pending: device on "
-					"sch %x is not operational\n",
-					irq);
-				ioinfo[irq]->ui.flags.oper = 0;
-				break;
-			}
-
-			ioinfo[irq]->opm = ioinfo[irq]->schib.pmcw.pim &
-				ioinfo[irq]->schib.pmcw.pam &
-				ioinfo[irq]->schib.pmcw.pom;
-
-			chsc_validate_chpids(irq);
-
-			if (!ioinfo[irq]->opm) {
-				/*
-				 * sh*t, our last path has gone...
-				 * Set the device status to not operational
-				 * and eventually notify the device driver
-				 */
-				CHSC_DEBUG (KERN_WARNING, CRW, 2,
-					"do_crw_pending: Last path gone"
-					" for device %x, sch %x\n",
-					ioinfo[irq]->devno, irq);
-
-				was_oper = ioinfo[irq]->ui.flags.oper;
-
-				ioinfo[irq]->ui.flags.oper = 0;
-
-				if (was_oper && ioinfo[irq]->ui.flags.ready) {
-
-					not_oper_handler_func_t nopfunc = 
-						ioinfo[irq]->nopfunc;
-
-					free_irq(irq, ioinfo[irq]->irq_desc.dev_id);
-					if (nopfunc)
-						nopfunc(irq, DEVSTAT_DEVICE_GONE);
-				}
-
-			} 
+#if 0
+	driver_for_each_dev(io_subchannel_driver, chpid, s390_subchannel_remove_chpid);
+#else
 
-			s390irq_spin_unlock(irq);
-			break;
-		}
+	for (irq = 0; irq <= highest_subchannel; irq++) {
+		sch = ioinfo[irq];
+		if (sch == NULL)
+			continue;  /* we don't know the device anyway */
+		s390_subchannel_remove_chpid(sch, chpid);
 	}
+#endif
 }
 
 /* this used to be in s390_process_res_acc_*, FIXME: find a better name
@@ -359,20 +323,20 @@
 	 * will we have to do.
 	 */
 
-	if (!cio_chsc_desc_avail) 
+	if (!cio_chsc_desc_avail)
 		chsc_get_sch_descriptions();
 
 	if (!cio_chsc_desc_avail) {
 		/*
 		 * Something went wrong...
 		 */
-		CHSC_DEBUG (KERN_WARNING, CRW, 0, "Error: Could not retrieve "
-			    "subchannel descriptions, will not process css"
-			    "machine check...\n");
+		CIO_CRW_EVENT(0, "Error: Could not retrieve "
+			      "subchannel descriptions, will not process css"
+			      "machine check...\n");
 		return 0;
 	}
 
-	if (!test_bit(chpid, &chpids_logical))
+	if (!test_bit(chpid, chpids_logical))
 		return 0; /* no need to do the rest */
 
 	return 1;
@@ -381,19 +345,22 @@
 static void
 s390_process_res_acc_chpid (u8 chpid)
 {
-	int irq = 0;
+	struct subchannel *sch;
+	int irq;
 	int ccode;
 	int chp;
-	int mask;
 	int ret;
 
 	if (!s390_check_valid_chpid(chpid))
 		return;
-	
-	DBGC( KERN_DEBUG "Looking at chpid %x...\n", chpid);
 
-	for (irq=0; irq<=__MAX_SUBCHANNELS; irq++) {
-		if (ioinfo[irq] == INVALID_STORAGE_AREA) {
+	pr_debug( KERN_DEBUG "Looking at chpid %x...\n", chpid);
+
+	for (irq = 0; irq <= __MAX_SUBCHANNELS; irq++) {
+		int found;
+
+		sch = ioinfo[irq];
+		if (!sch) {
 			/*
 			 * We don't know the device yet, but since a path
 			 * may be available now to the device we'll have
@@ -402,54 +369,56 @@
 			 * that beast may be on we'll have to do a stsch
 			 * on all devices, grr...
 			 */
-			int valret = 0;
-
-			valret = s390_validate_subchannel(irq,0);
-			if (valret == -ENXIO) {
+			ret = css_probe_device(irq);
+			if (ret == -ENXIO)
 				/* We're through */
 				return;
-			}
-			if (irq > highest_subchannel)
-				highest_subchannel = irq;
-			if (valret == 0)
-				s390_device_recognition_irq(irq);
 			continue;
 		}
 
-		if (!ioinfo[irq]->st)
-			continue;
-
-		/*
-		 * Send nops down each path to find out
-		 * which path is there
-		 */
+		spin_lock_irq(&sch->lock);
 
-		for (chp=0;chp<=7;chp++) {
-			mask = 0x80 >> chp;
+		/* Update our ssd_info */
+		if (chsc_get_sch_desc_irq(sch->irq))
+			break;
 
+		found = 0;
+		for (chp = 0; chp <= 7; chp++)
 			/*
-			 * check if chpid is in information
-			 * updated by ssd
+			 * check if chpid is in information updated by ssd
 			 */
-			if ((ioinfo[irq]->ssd_info.valid) &&
-			    (ioinfo[irq]->ssd_info.chpid[chp] == chpid))
-				ret = s390_send_nop (irq, mask);
-		}
+			if (sch->ssd_info.valid &&
+			    (sch->ssd_info.chpid[chp] == chpid)) {
+				found = 1;
+				break;
+			}
 
-		ccode = stsch(irq, &ioinfo[irq]->schib);
+		if (found == 0) {
+			spin_unlock_irq(&sch->lock);
+			continue;
+		}
+		/*
+		 * Do a stsch to update our subchannel structure with the
+		 * new path information and eventually check for logically
+		 * offline chpids.
+		 */
+		ccode = stsch(sch->irq, &sch->schib);
 		if (ccode > 0) {
-			ioinfo[irq]->ui.flags.oper = 0;
+// FIXME:		ccw_device_recognition(cdev);
+			spin_unlock_irq(&sch->lock);
 			continue;
 		}
 
-		ioinfo[irq]->opm = ioinfo[irq]->schib.pmcw.pim &
-				   ioinfo[irq]->schib.pmcw.pam &
-				   ioinfo[irq]->schib.pmcw.pom;
+		sch->lpm = sch->schib.pmcw.pim &
+			sch->schib.pmcw.pam &
+			sch->schib.pmcw.pom;
+
+		chsc_validate_chpids(sch);
 
-		chsc_validate_chpids(irq);
+		sch->lpm |= (0x80 >> chp);
+		dev_fsm_event(sch->dev.driver_data, DEV_EVENT_VERIFY);
 
-		if ((ioinfo[irq]->ui.flags.ready) && (chpid & ioinfo[irq]->opm))
-			s390_DevicePathVerification(irq, chpid);
+		spin_unlock_irq(&sch->lock);
 	}
 }
 
@@ -457,99 +426,95 @@
 s390_process_res_acc_linkaddr ( __u8 chpid, __u16 fla, u32 fla_mask)
 {
 	char dbf_txt[15];
-	int irq = 0;
+	struct subchannel *sch;
+	int irq;
 	int ccode;
-	int mask2;
 	int ret;
 	int j;
 
 	if (!s390_check_valid_chpid(chpid))
 		return;
-	
-		sprintf(dbf_txt, "fla%x", fla);
-		CIO_TRACE_EVENT( 2, dbf_txt);
-	
-	DBGC (KERN_DEBUG "Looking at chpid %x, link addr %x...\n", chpid, fla);
 
-	for (irq=0; irq<=__MAX_SUBCHANNELS; irq++) {
+	sprintf(dbf_txt, "fla%x", fla);
+	CIO_TRACE_EVENT( 2, dbf_txt);
 
-		if (ioinfo[irq] == INVALID_STORAGE_AREA) {
+	pr_debug(KERN_DEBUG "Looking at chpid %x, link addr %x...\n", chpid, fla);
+	for (irq = 0; irq <= __MAX_SUBCHANNELS; irq++) {
+		int found;
+		
+		sch = ioinfo[irq];
+		if (!sch) {
 			/* The full program again (see above), grr... */
-			int valret = 0;
-
-			valret = s390_validate_subchannel(irq,0);
-			if (valret == -ENXIO) {
-				/* We're done */
+			ret = css_probe_device(irq);
+			if (ret == -ENXIO)
+				/* We're through */
 				return;
-			}
-			if (irq > highest_subchannel)
-				highest_subchannel = irq;
-			if (valret == 0)
-				s390_device_recognition_irq(irq);
-			continue;
+			return;
 		}
 
-		if (!ioinfo[irq]->st)
-			continue;
-		
 		/*
 		 * Walk through all subchannels and
-		 * look if our chpid and our (masked) link 
+		 * look if our chpid and our (masked) link
 		 * address are in somewhere
 		 * Do a stsch for the found subchannels and
-		 * perform path grouping  
+		 * perform path grouping
 		 */
 
 		/* Update our ssd_info */
-		if (chsc_get_sch_desc_irq(irq))
+		if (chsc_get_sch_desc_irq(sch->irq))
 			break;
 
-		for (j=0;j<8;j++) {
-			if ((ioinfo[irq]->ssd_info.chpid[j] == chpid) &&
-			    ((ioinfo[irq]->ssd_info.fla[j]&fla_mask) == fla)) {
-
-				mask2 = 0x80 >> j;
-				ret = s390_send_nop (irq, mask2);
-
-				ccode = stsch(irq,&ioinfo[irq]->schib);
-				if (ccode > 0)
-					break;
-
-				ioinfo[irq]->opm = ioinfo[irq]->schib.pmcw.pim &
-						   ioinfo[irq]->schib.pmcw.pam &
-						   ioinfo[irq]->schib.pmcw.pom;
+		found = 0;
+		for (j = 0; j < 8; j++)
+			if (sch->ssd_info.valid &&
+			    sch->ssd_info.chpid[j] == chpid &&
+			    (sch->ssd_info.fla[j] & fla_mask) == fla) {
+				found = 1;
+				break;
+			}
 
-				chsc_validate_chpids(irq);
+		if (found == 0)
+			continue;
 
-				if (ioinfo[irq]->ui.flags.ready)
-					s390_DevicePathVerification(irq, chpid);
+		ccode = stsch(sch->irq, &sch->schib);
+		if (ccode > 0)
+			break;
 
-				break;
-			}
-		}
+		sch->lpm = sch->schib.pmcw.pim &
+			sch->schib.pmcw.pam &
+			sch->schib.pmcw.pom;
+		
+		chsc_validate_chpids(sch);
+		
+		sch->lpm |= (0x80 >> j);
+		dev_fsm_event(sch->dev.driver_data, DEV_EVENT_VERIFY);
+						
+		/* We've found it, get out of here. */
+		break;
 	}
 }
 
-void
-s390_process_css( void )
+static void
+do_process_crw(void *ignore)
 {
 	int ccode;
 
-	/* 
-	 * build the chsc request block for store event information 
-	 * and do the call 
+	/*
+	 * build the chsc request block for store event information
+	 * and do the call
 	 */
 
 	/* FIXME: chsc_area_sei cannot be on the stack since it needs to
 	 * be page-aligned. Implement proper locking or dynamic
 	 * allocation or prove that this function does not have to be
 	 * reentrant! */
-	static chsc_area_t chsc_area_sei __attribute__ ((aligned(PAGE_SIZE))) = {
-		.request_block = {
-			.command_code1 = 0x0010,
-			.command_code2 = 0x000e
-		}
-	};
+	static struct chsc_area chsc_area_sei
+		__attribute__ ((aligned(PAGE_SIZE))) = {
+			.request_block = {
+				.command_code1 = 0x0010,
+				.command_code2 = 0x000e
+			}
+		};
 
 	typeof (chsc_area_sei.response_block.response_block_data.sei_res)
 		*sei_res = &chsc_area_sei.response_block.response_block_data.sei_res;
@@ -558,138 +523,93 @@
 	CIO_TRACE_EVENT( 2, "prcss");
 
 	ccode = chsc(&chsc_area_sei);
-
 	if (ccode > 0)
 		return;
 
-
 	switch (chsc_area_sei.response_block.response_code) {
-	/* for debug purposes, check for problems */
+		/* for debug purposes, check for problems */
 	case 0x0001:
 		break; /* everything ok */
 	case 0x0002:
-		CHSC_DEBUG (KERN_WARNING, CRW, 2, "s390_process_css:"
-			    "invalid command!\n");
+		CIO_CRW_EVENT(2, "chsc_process_crw:invalid command!\n");
 	case 0x0003:
-		CHSC_DEBUG (KERN_WARNING, CRW, 2, "s390_process_css:"
-				" error in chsc request block!\n");
+		CIO_CRW_EVENT(2, "chsc_process_crw: error in chsc "
+			      "request block!\n");
 		return;
 	case 0x0005:
-		CHSC_DEBUG (KERN_WARNING, CRW, 2, "s390_process_css:"
-				" no event information stored\n");
+		CIO_CRW_EVENT(2, "chsc_process_crw: no event information "
+			      "stored\n");
 		return;
 	default:
-		CHSC_DEBUG (KERN_WARNING, CRW, 2, "s390_process_css:"
-				" chsc response %d\n",
-				chsc_area_sei.response_block.response_code);
+		CIO_CRW_EVENT(2, "chsc_process_crw: chsc response %d\n",
+			      chsc_area_sei.response_block.response_code);
 		return;
 	}
 
-	CHSC_DEBUG (KERN_DEBUG, CRW, 4, "s390_process_css: "
-		    "event information successfully stored\n");
+	CIO_CRW_EVENT(4, "chsc_process_crw: event information successfully "
+		      "stored\n");
 
 	if (sei_res->rs != 4) {
-		CHSC_DEBUG (KERN_ERR, CRW, 2, "s390_process_css: "
-			    "reporting source (%04X) isn't a chpid!"
-			    "Aborting processing of machine check...\n",
-			    sei_res->rsid);
+		CIO_CRW_EVENT(2, "chsc_process_crw: "
+			      "reporting source (%04X) isn't a chpid!"
+			      "Aborting processing of machine check...\n",
+			      sei_res->rsid);
 		return;
 	}
 
 	/* which kind of information was stored? */
 	switch (sei_res->cc) {
 	case 1: /* link incident*/
-		CHSC_DEBUG (KERN_DEBUG, CRW, 4, "s390_process_css: "
-			"channel subsystem reports link incident,"
-			" source is chpid %x\n", sei_res->rsid);
+		CIO_CRW_EVENT(4, "chsc_process_crw: "
+			      "channel subsystem reports link incident,"
+			      " source is chpid %x\n", sei_res->rsid);
 
-		s390_do_chpid_processing(sei_res->rsid);
+		s390_set_chpid_offline(sei_res->rsid);
 		break;
 
 	case 2: /* i/o resource accessibiliy */
-		CHSC_DEBUG (KERN_DEBUG, CRW, 4, "s390_process_css: "
-			"channel subsystem " "reports some I/O "
-			"devices may have become accessable\n");
-		DBGC ( KERN_DEBUG "Data received after sei: \n");
-		DBGC ( KERN_DEBUG "Validity flags: %x\n", sei_res->vf);
+		CIO_CRW_EVENT(4, "chsc_process_crw: "
+			      "channel subsystem reports some I/O "
+			      "devices may have become accessable\n");
+		pr_debug( KERN_DEBUG "Data received after sei: \n");
+		pr_debug( KERN_DEBUG "Validity flags: %x\n", sei_res->vf);
+
+		/* allocate a new channel path structure, if needed */
+		if (chps[sei_res->rsid] == NULL)
+			new_channel_path(sei_res->rsid, CHP_ONLINE);
+		else
+			set_chp_status(sei_res->rsid, CHP_ONLINE);
 
 		if ((sei_res->vf & 0x80) == 0) {
-			DBGC ( KERN_DEBUG "chpid: %x\n", sei_res->rsid);
+			pr_debug( KERN_DEBUG "chpid: %x\n", sei_res->rsid);
 			s390_process_res_acc_chpid (sei_res->rsid);
 		} else if ((sei_res->vf & 0xc0) == 0x80) {
-			DBGC ( KERN_DEBUG "chpid: %x link addr: %x\n",
-				sei_res->rsid, sei_res->fla);
-			s390_process_res_acc_linkaddr (sei_res->rsid, 
-					sei_res->fla, 0xff00);
+			pr_debug( KERN_DEBUG "chpid: %x link addr: %x\n",
+			       sei_res->rsid, sei_res->fla);
+			s390_process_res_acc_linkaddr (sei_res->rsid,
+						       sei_res->fla, 0xff00);
 		} else if ((sei_res->vf & 0xc0) == 0xc0) {
-			DBGC ( KERN_DEBUG "chpid: %x full link addr: %x\n",
-				sei_res->rsid, sei_res->fla);
+			pr_debug( KERN_DEBUG "chpid: %x full link addr: %x\n",
+			       sei_res->rsid, sei_res->fla);
 			s390_process_res_acc_linkaddr (sei_res->rsid,
-					sei_res->fla, 0xffff);
+						       sei_res->fla, 0xffff);
 		}
-		DBGC ( KERN_DEBUG "\n");
+		pr_debug( KERN_DEBUG "\n");
 
 		break;
 
 	default: /* other stuff */
-		CHSC_DEBUG (KERN_DEBUG, CRW, 4, "s390_process_css: "
-			    "event %d\n", sei_res->cc);
+		CIO_CRW_EVENT(4, "chsc_process_crw: event %d\n", sei_res->cc);
 		break;
 	}
 }
 
-
-#ifdef CONFIG_PROC_FS
-
-static int s390_vary_chpid( __u8 chpid, int on );
-
-/*
- * Function: cio_parse_chpids_proc_parameters
- * parse the stuff piped to /proc/chpids
- */
-static inline void
-cio_parse_chpids_proc_parameters(char* buf)
+void
+chsc_process_crw(void)
 {
-	int onoff;
-	int cp;
-
-	if (!strncmp (buf, "on ", 3)) {
-		onoff = 1;
-		buf += 3;
-	} else if (!strncmp (buf, "off ", 4)) {
-		onoff = 0;
-		buf += 4;
-	} else {
-		printk(KERN_ERR "/proc/chpids: Parse error; "
-		       "try using '{on,off} <chpid>'\n");
-		return;
-	}
-
-	if (*buf == '0') {
-		if (*(++buf) == 'x') 	/* strip leading zero */
-			buf++;		/* strip leading x */
-	}
-	cp = simple_strtoul (buf, &buf, 16);	/* interpret anything as hex */
-
-	chsc_get_sch_descriptions();
-	if (!cio_chsc_desc_avail) {
-		printk(KERN_ERR "Could not get chpid status, "
-		       "vary on/off not available\n");
-		return;
-	}
+	static DECLARE_WORK(work, do_process_crw, 0);
 
-	if (test_bit(cp, &chpids) != onoff) {
-		if (s390_vary_chpid(cp, onoff))
-			printk(KERN_WARNING "/proc/chpids: "
-			       "Invalid chpid specified\n");
-		else
-			printk(KERN_INFO "/proc/chpids: "
-			       "Varied chpid %x logically %sline\n",
-			       cp, onoff ? "on" : "off");
-	} else {
-		printk(KERN_ERR "/proc/chpids: chpid %x is "
-		       "already %sline\n", cp, onoff ? "on" : "off");
-	}
+	schedule_work(&work);
 }
 
 /*
@@ -697,136 +617,197 @@
  * Varies the specified chpid online or offline
  */
 static int
-s390_vary_chpid( __u8 chpid, int on) 
+s390_vary_chpid( __u8 chpid, int on)
 {
 	char dbf_text[15];
+	struct subchannel *sch;
 	int irq;
 
-	if ((chpid <=0) || (chpid >= NR_CHPIDS))
+	if (chpid <=0 || chpid >= NR_CHPIDS)
 		return -EINVAL;
 
 	sprintf(dbf_text, on?"varyon%x":"varyoff%x", chpid);
 	CIO_TRACE_EVENT( 2, dbf_text);
 
-	if (!test_bit(chpid, &chpids_known)) {
+	chsc_get_sch_descriptions();
+	if (!cio_chsc_desc_avail) {
+		printk(KERN_ERR "Could not get chpid status, "
+		       "vary on/off not available\n");
+		return -EPERM;
+	}
+
+	if (!test_bit(chpid, chpids_known)) {
 		printk(KERN_ERR "Can't vary unknown chpid %02X\n", chpid);
 		return -EINVAL;
 	}
 
+	if (test_bit(chpid, chpids) == on) {
+		printk(KERN_ERR "chpid %x is "
+		       "already %sline\n", chpid, on ? "on" : "off");
+		return -EINVAL;
+	}
+
 	if (on) {
-		set_bit(chpid, &chpids_logical);
-		set_bit(chpid, &chpids);
+		set_bit(chpid, chpids_logical);
+		set_bit(chpid, chpids);
+		set_chp_status(chpid, CHP_ONLINE);
 	} else {
-		clear_bit(chpid, &chpids_logical);
-		clear_bit(chpid, &chpids);
+		clear_bit(chpid, chpids_logical);
+		clear_bit(chpid, chpids);
+		set_chp_status(chpid, CHP_LOGICALLY_OFFLINE);
 	}
 
 	/*
 	 * Redo PathVerification on the devices the chpid connects to
 	 */
-	
-	for (irq=0;irq<=highest_subchannel;irq++) {
+
+	for (irq = 0; irq <= highest_subchannel; irq++) {
 		int chp;
-		/* 
-		 * We don't need to adjust the opm, as this will be done in
+		/*
+		 * We don't need to adjust the lpm, as this will be done in
 		 * DevicePathVerification...
 		 */
-
-		if ((ioinfo[irq] == INVALID_STORAGE_AREA)
-		    || ioinfo[irq]->st
-		    || (!ioinfo[irq]->ssd_info.valid))
+		sch = ioinfo[irq];
+		if (sch == NULL || sch->st || !sch->ssd_info.valid)
 			continue;
 
 		for (chp = 0; chp < 8; chp++) {
-			if (ioinfo[irq]->ssd_info.chpid[chp] == chpid) {
-
-				DBGC (KERN_DEBUG "Calling "
-				     "DevicePathVerification for irq %d\n",
-				     irq);
-
-				s390_DevicePathVerification(irq, 0);
+			if (sch->ssd_info.chpid[chp] == chpid) {
+				if (on)
+					sch->lpm |= (0x80 >> chp);
+				else
+					sch->lpm &= ~(0x80 >> chp);
+				dev_fsm_event(sch->dev.driver_data,
+					      DEV_EVENT_VERIFY);
 				break;
 			}
 		}
 	}
-
 	return 0;
 }
 
 /*
- * /proc/chpids to display available chpids
- * vary chpids on/off by piping to it
+ * Files for the channel path entries.
  */
-
-static int
-cio_chpids_read (char *page, char **start, off_t off,
-		 int count, int *eof, void *data)
+static ssize_t
+chp_status_show(struct device *dev, char *buf, size_t count, loff_t off)
 {
-	int chp = off;
-	int len = 0;
-	const unsigned int entry_size = 23;  /* longest entry is
-						"0xYZ logically offline\n" */
+	struct sys_device *sdev = container_of(dev, struct sys_device, dev);
+	struct channel_path *chp = container_of(sdev, struct channel_path, sdev);
 
-	chsc_get_sch_descriptions();
-	if (!cio_chsc_desc_avail) {
-		return sprintf(page, "no info available\n");
+	if (!chp)
+		return off ? 0 : count;
+
+	switch(chp->state) {
+	case CHP_OFFLINE:
+		return off ? 0 : snprintf(buf, count, "n/a\n");
+	case CHP_LOGICALLY_OFFLINE:
+		return off ? 0 : snprintf(buf, count, "logically offline\n");
+	case CHP_STANDBY:
+		return off ? 0 : snprintf(buf, count, "n/a\n");
+	case CHP_ONLINE:
+		return off ? 0 : snprintf(buf, count, "online\n");
+	default:
+		return off ? 0 : count;
 	}
+}
 
-	while (chp < NR_CHPIDS && len + entry_size < count) {
-		if (test_bit(chp, &chpids_known)) {
+static ssize_t
+chp_status_write(struct device *dev, const char *buf, size_t count, loff_t off)
+{
+	struct sys_device *sdev = container_of(dev, struct sys_device, dev);
+	struct channel_path *cp = container_of(sdev, struct channel_path, sdev);
+	char cmd[10];
+	int num_args;
+	int error;
 
-			if (!test_bit(chp, &chpids))
-				len += sprintf(page+len,
-					       "0x%02X n/a\n", chp);
-			
-			else if (test_bit(chp, &chpids_logical))
-				len += sprintf(page+len,
-					       "0x%02X online\n", chp);
-			else
-				len += sprintf(page+len,
-					       "0x%02X logically offline\n", 
-					       chp);
-		}
-		chp++;
-	}
+	if (off)
+		return 0;
+
+	num_args = sscanf(buf, "%5s", cmd);
+	if (!num_args)
+		return count;
+
+	if (!strnicmp(cmd, "on", 2))
+		error = s390_vary_chpid(cp->id, 1);
+	else if (!strnicmp(cmd, "off", 3))
+		error = s390_vary_chpid(cp->id, 0);
+	else
+		error = -EINVAL;
+
+	return error < 0 ? error : count;
 
-	if (chp < NR_CHPIDS)
-		*eof = 1;
-	
-	*start = (char *) (chp - off);
-	return len;
 }
 
+static DEVICE_ATTR(status, 0644, chp_status_show, chp_status_write);
+
+/*
+ * Entries for chpids on the system bus.
+ * This replaces /proc/chpids.
+ */
 static int
-cio_chpids_write (struct file *file, const char *user_buf,
-			     unsigned long user_len, void *data)
+new_channel_path(int chpid, int status)
 {
-	char buffer[16] = {0,};
+	struct channel_path *chp;
+	int ret;
+
+	chp = kmalloc(sizeof(struct channel_path), GFP_KERNEL);
+	if (!chp)
+		return -ENOMEM;
 
-	if (strncpy_from_user (buffer, user_buf, min(15ul,user_len)) < 0)
-		return -EFAULT;
+	chps[chpid] = chp;
 
-	CHSC_DEBUG (KERN_DEBUG, MSG, 2, "/proc/chpids: '%s'\n", buffer);
+	/* fill in status, etc. */
+	chp->id = chpid;
+	chp->state = status;
 
-	cio_parse_chpids_proc_parameters(buffer);
+	snprintf(chp->sdev.dev.name, DEVICE_NAME_SIZE,
+		 "channel path %x", chpid);
+	chp->sdev.name = "channel_path";
 
-	return user_len;
+	chp->sdev.id = chpid;
+
+	/* make it known to the system */
+	ret = sys_device_register(&chp->sdev);
+	if (ret) {
+		printk(KERN_WARNING "%s: could not register %02x\n",
+		       __func__, chpid);
+		return ret;
+	}
+	ret = device_create_file(&chp->sdev.dev, &dev_attr_status);
+	if (ret)
+		sys_device_unregister(&chp->sdev);
+
+	return ret;
 }
 
-static int
-cio_chpids_proc_init(void)
+static int __init
+register_channel_paths(void)
 {
-	struct proc_dir_entry *entry;
-	entry = create_proc_entry("chpids", S_IFREG|S_IRUGO|S_IWUSR, &proc_root);
+	int i;
+	int ret;
 
-	if (!entry)
-		return 0;
+	/* walk through the chpids arrays */
+	for (i = 0; i < NR_CHPIDS; i++) {
+		/* we are only interested in known chpids */
+		if (!test_bit(i, chpids_known))
+			continue;
+		if (!test_bit(i, chpids))
+			/* standby */
+			ret = new_channel_path(i, CHP_STANDBY);
+
+		else if (test_bit(i, chpids_logical))
+			/* online */
+			ret = new_channel_path(i, CHP_ONLINE);
+		else
+			/* logically offline */
+			ret = new_channel_path(i, CHP_LOGICALLY_OFFLINE);
 
-	entry->read_proc  = &cio_chpids_read;
-	entry->write_proc = &cio_chpids_write;
-	
-	return 1;
+		if (ret)
+			return ret;
+	}
+	return 0;
 }
 
-__initcall(cio_chpids_proc_init);
-#endif /* CONFIG_PROC_FS */
+module_init(register_channel_paths);
+EXPORT_SYMBOL(chsc);
diff -Nru a/drivers/s390/cio/chsc.h b/drivers/s390/cio/chsc.h
--- a/drivers/s390/cio/chsc.h	Mon Dec  9 18:46:50 2002
+++ b/drivers/s390/cio/chsc.h	Mon Dec  9 18:46:50 2002
@@ -1,8 +1,25 @@
 #ifndef S390_CHSC_H
 #define S390_CHSC_H
 
+#define NR_CHPIDS 256
+
+#define CHP_OFFLINE 0
+#define CHP_LOGICALLY_OFFLINE 1
+#define CHP_STANDBY 2
+#define CHP_ONLINE 3
+
+#define CHSC_SEI_ACC_CHPID        1
+#define CHSC_SEI_ACC_LINKADDR     2
+#define CHSC_SEI_ACC_FULLLINKADDR 3
+
+struct channel_path {
+	int id;
+	int state;
+	struct sys_device sdev;
+};
+
+extern struct channel_path *chps[];
+
 extern void s390_process_css( void );
-extern int chsc_chpid_logical (int irq, int chp);
-extern void chsc_validate_chpids(int irq);
-extern void switch_off_chpids(int irq, __u8 mask);
+extern void chsc_validate_chpids(struct subchannel *);
 #endif
diff -Nru a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
--- a/drivers/s390/cio/cio.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/s390/cio/cio.c	Mon Dec  9 18:46:51 2002
@@ -1,1929 +1,764 @@
 /*
  *  drivers/s390/cio/cio.c
  *   S/390 common I/O routines -- low level i/o calls
- *   $Revision: 1.27 $
+ *   $Revision: 1.89 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
- *                            IBM Corporation
+ *			      IBM Corporation
  *    Author(s): Ingo Adlung (adlung@de.ibm.com)
- *               Cornelia Huck (cohuck@de.ibm.com) 
+ *		 Cornelia Huck (cohuck@de.ibm.com)
  *		 Arnd Bergmann (arndb@de.ibm.com)
- *    ChangeLog: 11/04/2002 Arnd Bergmann Split s390io.c into multiple files,
- *					  see s390io.c for complete list of
- * 					  changes.
- *               05/06/2002 Cornelia Huck  some cleanups
+ *		 Martin Schwidefsky (schwidefsky@de.ibm.com)
  */
 
 #include <linux/module.h>
 #include <linux/config.h>
+#include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/device.h>
 
-#include <asm/io.h>
-#include <asm/irq.h>
+#include <asm/hardirq.h>
+#include <asm/cio.h>
 #include <asm/delay.h>
-#include <asm/debug.h>
 
 #include "airq.h"
 #include "cio.h"
-#include "cio_debug.h"
-#include "ioinfo.h"
+#include "css.h"
 #include "chsc.h"
-#include "s390io.h" /* FIXME: try to do without this */
-
-static atomic_t sync_isc = ATOMIC_INIT (-1);
-static int sync_isc_cnt;	/* synchronous irq processing lock */
-
-int cons_dev = -1;	/* identify console device */
+#include "ioasm.h"
+#include "blacklist.h"
+#include "cio_debug.h"
 
-/* FIXME: no signed counters here */
-static void
-s390_displayhex (void *ptr, s32 cnt, int level)
-{
-	s32 cnt1, cnt2, maxcnt2;
-	u32 *currptr = (__u32 *) ptr;
-	char buffer[cnt * 12]; /* FIXME: possible stack overflow? */
-
-	for (cnt1 = 0; cnt1 < cnt; cnt1 += 16) {
-		sprintf (buffer, "%08lX ", (unsigned long) currptr);
-		maxcnt2 = cnt - cnt1;
-		if (maxcnt2 > 16)
-			maxcnt2 = 16;
-		for (cnt2 = 0; cnt2 < maxcnt2; cnt2 += 4)
-			sprintf (buffer, "%08X ", *currptr++);
-	}
-	DBG ("%s\n", buffer);
-	if (cio_debug_initialized) 
-		debug_text_event (cio_debug_msg_id, level, buffer);
+debug_info_t *cio_debug_msg_id;
+debug_info_t *cio_debug_trace_id;
+debug_info_t *cio_debug_crw_id;
+
+int cio_show_msg;
+
+static int __init
+cio_setup (char *parm)
+{
+	if (!strcmp (parm, "yes"))
+		cio_show_msg = 1;
+	else if (!strcmp (parm, "no"))
+		cio_show_msg = 0;
+	else
+		printk (KERN_ERR "cio_setup : invalid cio_msg parameter '%s'",
+			parm);
+	return 1;
 }
 
+__setup ("cio_msg=", cio_setup);
 
-/*
- * used by s390_start_IO
- */
-static inline void
-s390_build_orb(int irq, ccw1_t * cpa,
-	       unsigned long flag, __u8 lpm)
-{
-	ioinfo[irq]->orb.intparm = (__u32) (long) &ioinfo[irq]->u_intparm;
-	ioinfo[irq]->orb.fmt = 1;
-	ioinfo[irq]->orb.sync = 1;
-
-	ioinfo[irq]->orb.pfch = !(flag & DOIO_DENY_PREFETCH);
-	ioinfo[irq]->orb.spnd = (flag & DOIO_ALLOW_SUSPEND ? 1:0);
-	ioinfo[irq]->orb.ssic = ((flag & DOIO_ALLOW_SUSPEND)
-				 && (flag & DOIO_SUPPRESS_INTER));
-
-	if (flag & DOIO_VALID_LPM) {
-		ioinfo[irq]->orb.lpm = lpm;
-	} else {
-		ioinfo[irq]->orb.lpm = ioinfo[irq]->opm;
-
-	}
-
-#ifdef CONFIG_ARCH_S390X
-	/* 
-	 * for 64 bit we always support 64 bit IDAWs with 4k page size only
-	 */
-	ioinfo[irq]->orb.c64 = 1;
-	ioinfo[irq]->orb.i2k = 0;
-#endif
-
-	ioinfo[irq]->orb.cpa = (__u32) virt_to_phys (cpa);
-
-}
 
-/*
- * used by s390_start_IO to wait on sync. requests
- */
-static inline int
-s390_do_sync_wait(int irq, int do_tpi)
+#ifdef CONFIG_PROC_FS
+void
+init_irq_proc(void)
 {
-	unsigned long psw_mask;
-	uint64_t time_start;
-	uint64_t time_curr;
-	
-	int ready = 0;
-	int io_sub = -1;
-	int do_retry = 1;
-
-	int ret = 0;
-
-	/*
-	 * We shouldn't perform a TPI loop, waiting for an
-	 *  interrupt to occur, but should load a WAIT PSW
-	 *  instead. Otherwise we may keep the channel subsystem
-	 *  busy, not able to present the interrupt. When our
-	 *  sync. interrupt arrived we reset the I/O old PSW to
-	 *  its original value.
-	 */
-	psw_mask = PSW_KERNEL_BITS | PSW_MASK_IO | PSW_MASK_WAIT;
-	
-	/*
-	 * Martin didn't like modifying the new PSW, now we take
-	 *  a fast exit in do_IRQ() instead
-	 */
-	*(__u32 *) __LC_SYNC_IO_WORD = 1;
-
-	asm volatile ("STCK %0":"=m" (time_start));
-	
-	time_start = time_start >> 32;
-	
-	do {
-		if (do_tpi) {
-			tpi_info_t tpi_info = { 0, };
-
-			do {
-				if (tpi (&tpi_info) == 1) {
-					io_sub = tpi_info.irq;
-					break;
-				}
-
-				udelay (100);	/* usecs */
-				asm volatile("STCK %0":"=m" (time_curr));
-				
-				if (((time_curr >> 32) - time_start) >= 3)
-					do_retry = 0;
-				
-			} while (do_retry);
-		} else {
-			__load_psw_mask (psw_mask);
-			
-			io_sub = (__u32) * (__u16 *) __LC_SUBCHANNEL_NR;
-
-		}
-
-		if (do_retry)
-			ready = s390_process_IRQ (io_sub);
-		
-		/*
-		 * surrender when retry count's exceeded ...
-		 */
-	} while (!((io_sub == irq) && (ready == 1)) && do_retry);
-
-	*(__u32 *) __LC_SYNC_IO_WORD = 0;
-
-	if (!do_retry)
-		ret = -ETIMEDOUT;
-	
-	return ret;
+	/* For now, nothing... */
 }
+#endif
 
 /*
- * Used by halt_IO and clear_IO to wait on sync. requests
- */
-static void
-s390_do_sync_wait_haltclear(int irq, int halt)
-{
-	int io_sub;
-	__u32 io_parm;
-	unsigned long psw_mask;
-	
-	int ready = 0;
-	
-	/*
-	 * For hsch and csch, we don't do a tpi loop as for ssch,
-	 * but load a wait psw if sync processing is requested.
-	 *
-	 * FIXME: Are there case where we can't rely on an interrupt
-	 *        to occurr? Need to check...
-	 */
-	psw_mask = PSW_KERNEL_BITS | PSW_MASK_IO | PSW_MASK_WAIT;
-	
-	/*
-	 * Martin didn't like modifying the new PSW, now we take
-	 *  a fast exit in do_IRQ() instead
-	 */
-	*(__u32 *) __LC_SYNC_IO_WORD = 1;
-	
-	do {
-		__load_psw_mask (psw_mask);
-		
-		io_parm = *(__u32 *) __LC_IO_INT_PARM;
-		io_sub = (__u32) * (__u16 *) __LC_SUBCHANNEL_NR;
-		
-		ready = s390_process_IRQ (io_sub);
-		
-	} while (!((io_sub == irq) && (ready == 1)));
-	
-	*(__u32 *) __LC_SYNC_IO_WORD = 0;
-	
+ * Function: cio_debug_init
+ * Initializes three debug logs (under /proc/s390dbf) for common I/O:
+ * - cio_msg logs the messages which are printk'ed when CONFIG_DEBUG_IO is on
+ * - cio_trace logs the calling of different functions
+ * - cio_crw logs the messages which are printk'ed when CONFIG_DEBUG_CRW is on
+ * debug levels depend on CONFIG_DEBUG_IO resp. CONFIG_DEBUG_CRW
+ */
+static int __init
+cio_debug_init (void)
+{
+	cio_debug_msg_id = debug_register ("cio_msg", 4, 4, 16*sizeof (long));
+	if (!cio_debug_msg_id)
+		goto out_unregister;
+	debug_register_view (cio_debug_msg_id, &debug_sprintf_view);
+	debug_set_level (cio_debug_msg_id, 6);
+	cio_debug_trace_id = debug_register ("cio_trace", 4, 4, 8);
+	if (!cio_debug_trace_id)
+		goto out_unregister;
+	debug_register_view (cio_debug_trace_id, &debug_hex_ascii_view);
+	debug_set_level (cio_debug_trace_id, 6);
+	cio_debug_crw_id = debug_register ("cio_crw", 2, 4, 16*sizeof (long));
+	if (!cio_debug_crw_id)
+		goto out_unregister;
+	debug_register_view (cio_debug_crw_id, &debug_sprintf_view);
+	debug_set_level (cio_debug_crw_id, 6);
+	pr_debug("debugging initialized\n");
+	return 0;
+
+out_unregister:
+	if (cio_debug_msg_id)
+		debug_unregister (cio_debug_msg_id);
+	if (cio_debug_trace_id)
+		debug_unregister (cio_debug_trace_id);
+	if (cio_debug_crw_id)
+		debug_unregister (cio_debug_crw_id);
+	pr_debug("could not initialize debugging\n");
+	return -1;
+}
+
+arch_initcall (cio_debug_init);
+
+int
+cio_set_options (struct subchannel *sch, int flags)
+{
+       sch->options.suspend = (flags & DOIO_ALLOW_SUSPEND) != 0;
+       sch->options.prefetch = (flags & DOIO_DENY_PREFETCH) != 0;
+       sch->options.inter = (flags & DOIO_SUPPRESS_INTER) != 0;
+       return 0;
+}
+
+/* FIXME: who wants to use this? */
+int
+cio_get_options (struct subchannel *sch)
+{
+       int flags;
+
+       flags = 0;
+       if (sch->options.suspend)
+		flags |= DOIO_ALLOW_SUSPEND;
+       if (sch->options.prefetch)
+		flags |= DOIO_DENY_PREFETCH;
+       if (sch->options.inter)
+		flags |= DOIO_SUPPRESS_INTER;
+       return flags;
 }
 
 /*
- * called from start_IO after deferred cc=3 conditions
- * to print some debug data
+ * Use tpi to get a pending interrupt, call the interrupt handler and
+ * return a pointer to the subchannel structure.
  */
-static inline void
-s390_cc3_print_data(int irq)
+static inline int
+cio_tpi(void)
 {
+	struct tpi_info *tpi_info;
+	struct subchannel *sch;
+	struct irb *irb;
 
-	stsch (irq, &(ioinfo[irq]->schib));
-	
-	CIO_DEBUG(KERN_INFO, 4,
-			 "s390_start_IO(%04X) - irb for "
-			 "device %04X, after status pending:\n",
-			 irq, ioinfo[irq]->devstat.devno);
-	
-	s390_displayhex (&(ioinfo[irq]->devstat.ii.irb),
-			 sizeof (irb_t), 4);
-	
-	CIO_DEBUG(KERN_INFO, 4,	
-			 "s390_start_IO(%04X) - schib for "
-			 "device %04X, after status pending:\n",
-			 irq, ioinfo[irq]->devstat.devno);
-	
-	s390_displayhex (&(ioinfo[irq]->schib),
-			 sizeof (schib_t), 4);
-	
-	if (ioinfo[irq]->devstat.flag & DEVSTAT_FLAG_SENSE_AVAIL) {
-	CIO_DEBUG(KERN_INFO, 4,	
-			 "s390_start_IO(%04X) "
-			 "- sense data for device %04X,"
-			 " after status pending:\n",
-			 irq,
-			 ioinfo[irq]->devstat.devno);
-		
-		s390_displayhex (ioinfo[irq]->irq_desc.
-				 dev_id->ii.sense.data,
-				 ioinfo[irq]->irq_desc.
-				 dev_id->rescnt, 4);
-	}
-
+	tpi_info = (struct tpi_info *) __LC_SUBCHANNEL_ID;
+	if (tpi (NULL) != 1)
+		return 0;
+	irb = (struct irb *) __LC_IRB;
+	/* Store interrupt response block to lowcore. */
+	if (tsch (tpi_info->irq, irb) != 0)
+		/* Not status pending or not operational. */
+		return 1;
+	sch = ioinfo[tpi_info->irq];
+	if (sch)
+		return 1;
+	irq_enter ();
+	spin_lock(&sch->lock);
+	memcpy (&sch->schib.scsw, &irb->scsw, sizeof (struct scsw));
+	if (sch->driver && sch->driver->irq)
+		sch->driver->irq(&sch->dev);
+	spin_unlock(&sch->lock);
+	irq_exit ();
+	return 1;
 }
 
 static inline int
-s390_IO_handle_pending(int irq, int valid_lpm, int halt)
+cio_start_handle_notoper(struct subchannel *sch, __u8 lpm)
 {
-	int ret;
-	
-	if (halt) {
-		ioinfo[irq]->devstat.flag |= DEVSTAT_STATUS_PENDING;
-	} else {
-		ioinfo[irq]->devstat.flag = DEVSTAT_START_FUNCTION
-			| DEVSTAT_STATUS_PENDING;
-	}
-	
-	/*
-	 * initialize the device driver specific devstat irb area
-	 */
-	memset (&((devstat_t *) ioinfo[irq]->irq_desc.dev_id)->ii.irb,
-		'\0', sizeof (irb_t));
-	
-	/*
-	 * Let the common interrupt handler process the pending status.
-	 *  However, we must avoid calling the user action handler, as
-	 *  it won't be prepared to handle a pending status during
-	 *  do_IO() processing inline. This also implies that process_IRQ
-	 *  must terminate synchronously - especially if device sensing
-	 *  is required.
-	 */
-	ioinfo[irq]->ui.flags.s_pend = 1;
-	ioinfo[irq]->ui.flags.busy = 1;
-	ioinfo[irq]->ui.flags.doio = 1;
-	
-	s390_process_IRQ (irq);
-	
-	ioinfo[irq]->ui.flags.s_pend = 0;
-	ioinfo[irq]->ui.flags.busy = 0;
-	ioinfo[irq]->ui.flags.doio = 0;
-	
-	ioinfo[irq]->ui.flags.repall = 0;
-	ioinfo[irq]->ui.flags.w4final = 0;
-	
-	ioinfo[irq]->devstat.flag |= DEVSTAT_FINAL_STATUS;
-	
-	/*
-	 * In multipath mode a condition code 3 implies the last path
-	 *  has gone, except we have previously restricted the I/O to
-	 *  a particular path. A condition code 1 (0 won't occur)
-	 *  results in return code EIO as well as 3 with another path
-	 *  than the one used (i.e. path available mask is non-zero).
-	 */
-	if (ioinfo[irq]->devstat.ii.irb.scsw.cc == 3) {
-		if (!halt) {
-			if (valid_lpm) {
-				ioinfo[irq]->opm &=
-					~(ioinfo[irq]->
-					  devstat.ii.irb.esw.esw1.lpum);
-			} else {
-				ioinfo[irq]->opm = 0;
-				
-			}
-		}
-		
-		if ((halt) || (ioinfo[irq]->opm == 0)) {
-			ret = -ENODEV;
-			ioinfo[irq]->ui.flags.oper = 0;
-		} else {
-			ret = -EIO;
-			
-		}
-		
-		ioinfo[irq]->devstat.flag |= DEVSTAT_NOT_OPER;
-		
-		if (!halt) 
-			s390_cc3_print_data(irq);
-		
-	} else {
-		ret = -EIO;
-		ioinfo[irq]->devstat.flag &= ~DEVSTAT_NOT_OPER;
-		ioinfo[irq]->ui.flags.oper = 1;
-		
-	}
-	
-	return ret;
-}
+	char dbf_text[15];
 
-static inline int
-s390_start_IO_handle_notoper(int irq, 
-			     int valid_lpm,
-			     __u8 lpm)
-{
-	int ret;
+	if (lpm != 0)
+		sch->lpm &= ~lpm;
+	else
+		sch->lpm = 0;
 
-	if (valid_lpm) {
-		ioinfo[irq]->opm &= ~lpm;
-		switch_off_chpids(irq, lpm);
-	} else {
-		ioinfo[irq]->opm = 0;
-		
-	}
-	
-	if (ioinfo[irq]->opm == 0) {
-		ioinfo[irq]->ui.flags.oper = 0;
-		ioinfo[irq]->devstat.flag |= DEVSTAT_NOT_OPER;
-		
-	}
-	
-	ret = -ENODEV;
-	
-	memcpy (ioinfo[irq]->irq_desc.dev_id,
-		&(ioinfo[irq]->devstat), sizeof (devstat_t));
-	
-	stsch (irq, &(ioinfo[irq]->schib));
-	
-	CIO_DEBUG(KERN_WARNING, 0, 
-			 "s390_start_IO(%04X) - schib for "
-			 "device %04X, after 'not oper' status:\n",
-			 irq, ioinfo[irq]->devstat.devno);
-	
-	s390_displayhex (&(ioinfo[irq]->schib), 
-			 sizeof (schib_t), 0);
-	
-	return ret;
+	stsch (sch->irq, &sch->schib);
+
+	CIO_MSG_EVENT(0, "cio_start: 'not oper' status for "
+		      "subchannel %s!\n", sch->dev.bus_id);
+	sprintf(dbf_text, "no%s", sch->dev.bus_id);
+	CIO_TRACE_EVENT(0, dbf_text);
+	CIO_HEX_EVENT(0, &sch->schib, sizeof (struct schib));
+
+	return -ENODEV;
 }
 
 int
-s390_start_IO (int irq,		/* IRQ */
-	       ccw1_t * cpa,	/* logical channel prog addr */
-	       unsigned long user_intparm,	/* interruption parameter */
-	       __u8 lpm,	/* logical path mask */
-	       unsigned long flag)
-{				/* flags */
-	int ccode;
-	int ret = 0;
+cio_start (struct subchannel *sch,	/* subchannel structure */
+	   struct ccw1 * cpa,		/* logical channel prog addr */
+	   unsigned long intparm,	/* interruption parameter */
+	   __u8 lpm)			/* logical path mask */
+{
 	char dbf_txt[15];
+	int ccode;
 
-	/*
-	 * The flag usage is mutal exclusive ...
-	 */
-	if ((flag & DOIO_EARLY_NOTIFICATION)
-	    && (flag & DOIO_REPORT_ALL)) 
-		return -EINVAL;
-
-	sprintf (dbf_txt, "stIO%x", irq);
+	sprintf (dbf_txt, "stIO%x", sch->irq);
 	CIO_TRACE_EVENT (4, dbf_txt);
 
-	s390_build_orb(irq, cpa, flag, lpm);
+	sch->orb.intparm = (__u32) (long) &sch->u_intparm;
+	sch->orb.fmt = 1;
 
+	sch->orb.pfch = sch->options.prefetch == 0;
+	sch->orb.spnd = sch->options.suspend;
+	sch->orb.ssic = sch->options.suspend && sch->options.inter;
+	sch->orb.lpm = (lpm != 0) ? (lpm & sch->lpm) : sch->lpm;
+
+#ifdef CONFIG_ARCH_S390X
 	/*
-	 * If sync processing was requested we lock the sync ISC, modify the
-	 *  device to present interrupts for this ISC only and switch the
-	 *  CPU to handle this ISC exclusively.
+	 * for 64 bit we always support 64 bit IDAWs with 4k page size only
 	 */
-	if (flag & DOIO_WAIT_FOR_INTERRUPT) {
-		ret = enable_cpu_sync_isc (irq);
-
-		if (ret) 
-			return ret;
-
-	}
-
-	if (flag & DOIO_DONT_CALL_INTHDLR) 
-		ioinfo[irq]->ui.flags.repnone = 1;
+	sch->orb.c64 = 1;
+	sch->orb.i2k = 0;
+#endif
+	sch->orb.cpa = (__u32) __pa (cpa);
 
 	/*
 	 * Issue "Start subchannel" and process condition code
 	 */
-	ccode = ssch (irq, &(ioinfo[irq]->orb));
-
+	ccode = ssch (sch->irq, &sch->orb);
 	sprintf (dbf_txt, "ccode:%d", ccode);
 	CIO_TRACE_EVENT (4, dbf_txt);
 
 	switch (ccode) {
 	case 0:
-
-		if (!ioinfo[irq]->ui.flags.w4sense) {
-			/*
-			 * init the device driver specific devstat irb area
-			 *
-			 * Note : don´t clear saved irb info in case of sense !
-			 */
-			memset (&((devstat_t *) ioinfo[irq]->irq_desc.dev_id)->
-				ii.irb, '\0', sizeof (irb_t));
-		}
-
-		memset (&ioinfo[irq]->devstat.ii.irb, '\0', sizeof (irb_t));
-
 		/*
 		 * initialize device status information
 		 */
-		ioinfo[irq]->ui.flags.busy = 1;
-		ioinfo[irq]->ui.flags.doio = 1;
-
-		ioinfo[irq]->u_intparm = user_intparm;
-		ioinfo[irq]->devstat.cstat = 0;
-		ioinfo[irq]->devstat.dstat = 0;
-		ioinfo[irq]->devstat.lpum = 0;
-		ioinfo[irq]->devstat.flag = DEVSTAT_START_FUNCTION;
-		ioinfo[irq]->devstat.scnt = 0;
-
-		ioinfo[irq]->ui.flags.fast = 0;
-		ioinfo[irq]->ui.flags.repall = 0;
-
-		/*
-		 * Check for either early (FAST) notification requests
-		 *  or if we are to return all interrupt info.
-		 * Default is to call IRQ handler at secondary status only
-		 */
-		if (flag & DOIO_EARLY_NOTIFICATION) {
-			ioinfo[irq]->ui.flags.fast = 1;
-		} else if (flag & DOIO_REPORT_ALL) {
-			ioinfo[irq]->ui.flags.repall = 1;
-
-		}
-
-		ioinfo[irq]->ulpm = ioinfo[irq]->orb.lpm;
-
-		/*
-		 * If synchronous I/O processing is requested, we have
-		 *  to wait for the corresponding interrupt to occur by
-		 *  polling the interrupt condition. However, as multiple
-		 *  interrupts may be outstanding, we must not just wait
-		 *  for the first interrupt, but must poll until ours
-		 *  pops up.
-		 */
-		if (flag & DOIO_WAIT_FOR_INTERRUPT) 
-			ret = s390_do_sync_wait(irq, flag&DOIO_TIMEOUT);
-
-		break;
-
+		sch->u_intparm = intparm;
+		sch->schib.scsw.actl |= SCSW_ACTL_START_PEND;
+		return 0;
 	case 1:		/* status pending */
-
-		ret = s390_IO_handle_pending(irq, 
-					     flag & DOIO_VALID_LPM,
-					     0);
-		break;
-
 	case 2:		/* busy */
-
-		ret = -EBUSY;
-		break;
-
+		return -EBUSY;
 	default:		/* device/path not operational */
-
-		ret = s390_start_IO_handle_notoper(irq, 
-						   flag & DOIO_VALID_LPM,
-						   lpm);
-		break;
-
+		return cio_start_handle_notoper(sch, lpm);
 	}
-
-	if (flag & DOIO_WAIT_FOR_INTERRUPT) 
-		disable_cpu_sync_isc (irq);
-
-	if (flag & DOIO_DONT_CALL_INTHDLR) 
-		ioinfo[irq]->ui.flags.repnone = 0;
-
-	return ret;
-}
-
-int
-do_IO (int irq,			/* IRQ */
-       ccw1_t * cpa,		/* channel program address */
-       unsigned long user_intparm,	/* interruption parameter */
-       __u8 lpm,		/* logical path mask */
-       unsigned long flag)
-{				/* flags : see above */
-	int ret = 0;
-	char dbf_txt[15];
-
-	SANITY_CHECK (irq);
-
-	/* handler registered ? or free_irq() in process already ? */
-	if (!ioinfo[irq]->ui.flags.ready || ioinfo[irq]->ui.flags.unready) 
-		return -ENODEV;
-
-	sprintf (dbf_txt, "doIO%x", irq);
-	CIO_TRACE_EVENT (4, dbf_txt);
-
-	/*
-	 * Note: We ignore the device operational status - if not operational,
-	 *        the SSCH will lead to an -ENODEV condition ...
-	 */
-	if (!ioinfo[irq]->ui.flags.busy) {	/* last I/O completed ? */
-		ret = s390_start_IO (irq, cpa, user_intparm, lpm, flag);
-		if ((ret == -ETIMEDOUT) && (flag & DOIO_CANCEL_ON_TIMEOUT)) {
-			/*
-			 * We should better cancel the io request here
-			 * or we might not be able to do io on this sch
-			 * again
-			 */
-			cancel_IO (irq);
-		}
-
-	} else if (ioinfo[irq]->ui.flags.fast) {
-		/*
-		 * If primary status was received and ending status is missing,
-		 *  the device driver won't be notified on the ending status
-		 *  if early (fast) interrupt notification was requested.
-		 *  Therefore we have to queue the next incoming request. If
-		 *  halt_IO() is issued while there is a request queued, a HSCH
-		 *  needs to be issued and the queued request must be deleted
-		 *  but its intparm must be returned (see halt_IO() processing)
-		 */
-		if (ioinfo[irq]->ui.flags.w4final
-		    && !ioinfo[irq]->ui.flags.doio_q) {
-			ioinfo[irq]->qflag = flag;
-			ioinfo[irq]->qcpa = cpa;
-			ioinfo[irq]->qintparm = user_intparm;
-			ioinfo[irq]->qlpm = lpm;
-		} else {
-			ret = -EBUSY;
-
-		}
-	} else {
-		ret = -EBUSY;
-
-	}
-
-	return ret;
-
 }
 
 /*
  * resume suspended I/O operation
  */
 int
-resume_IO (int irq)
+cio_resume (struct subchannel *sch)
 {
-	int ret = 0;
 	char dbf_txt[15];
+	int ccode;
 
-	SANITY_CHECK (irq);
-
-	sprintf (dbf_txt, "resIO%x", irq);
+	sprintf (dbf_txt, "resIO%x", sch->irq);
 	CIO_TRACE_EVENT (4, dbf_txt);
 
-	/*
-	 * We allow for 'resume' requests only for active I/O operations
-	 */
-	if (ioinfo[irq]->ui.flags.busy) {
-		int ccode;
-
-		ccode = rsch (irq);
-
-		sprintf (dbf_txt, "ccode:%d", ccode);
-		CIO_TRACE_EVENT (4, dbf_txt);
-
-		switch (ccode) {
-		case 0:
-			break;
-
-		case 1:
-			s390_process_IRQ (irq);
-			ret = -EBUSY;
-			break;
+	ccode = rsch (sch->irq);
 
-		case 2:
-			ret = -EINVAL;
-			break;
-
-		case 3:
-			/*
-			 * useless to wait for request completion
-			 *  as device is no longer operational !
-			 */
-			ioinfo[irq]->ui.flags.oper = 0;
-			ioinfo[irq]->ui.flags.busy = 0;
-			ret = -ENODEV;
-			break;
-
-		}
-
-	} else {
-		ret = -ENOTCONN;
+	sprintf (dbf_txt, "ccode:%d", ccode);
+	CIO_TRACE_EVENT (4, dbf_txt);
 
+	switch (ccode) {
+	case 0:
+		sch->schib.scsw.actl |= SCSW_ACTL_RESUME_PEND;
+		return 0;
+	case 1:
+		return -EBUSY;
+	case 2:
+		return -EINVAL;
+	default:
+		/*
+		 * useless to wait for request completion
+		 *  as device is no longer operational !
+		 */
+		return -ENODEV;
 	}
-
-	return ret;
 }
 
 /*
  * Note: The "intparm" parameter is not used by the halt_IO() function
- *       itself, as no ORB is built for the HSCH instruction. However,
- *       it allows the device interrupt handler to associate the upcoming
- *       interrupt with the halt_IO() request.
+ *	 itself, as no ORB is built for the HSCH instruction. However,
+ *	 it allows the device interrupt handler to associate the upcoming
+ *	 interrupt with the halt_IO() request.
  */
 int
-halt_IO (int irq, unsigned long user_intparm, unsigned long flag)
-{				/* possible DOIO_WAIT_FOR_INTERRUPT */
-	int ret;
-	int ccode;
+cio_halt(struct subchannel *sch, unsigned long intparm)
+{
 	char dbf_txt[15];
+	int ccode;
 
-	SANITY_CHECK (irq);
-
-	/*
-	 * we only allow for halt_IO if the device has an I/O handler associated
-	 */
-	if (!ioinfo[irq]->ui.flags.ready) 
+	if (!sch)
 		return -ENODEV;
 
 	/*
 	 * we ignore the halt_io() request if ending_status was received but
 	 *  a SENSE operation is waiting for completion.
 	 */
-	if (ioinfo[irq]->ui.flags.w4sense) 
-		return 0;
 
-	sprintf (dbf_txt, "haltIO%x", irq);
+	sprintf (dbf_txt, "haltIO%x", sch->irq);
 	CIO_TRACE_EVENT (2, dbf_txt);
 
 	/*
-	 * If sync processing was requested we lock the sync ISC,
-	 *  modify the device to present interrupts for this ISC only
-	 *  and switch the CPU to handle this ISC exclusively.
-	 */
-	if (flag & DOIO_WAIT_FOR_INTERRUPT) {
-		ret = enable_cpu_sync_isc (irq);
-
-		if (ret)
-			return ret;
-	}
-
-	/*
 	 * Issue "Halt subchannel" and process condition code
 	 */
-	ccode = hsch (irq);
+	ccode = hsch (sch->irq);
 
 	sprintf (dbf_txt, "ccode:%d", ccode);
 	CIO_TRACE_EVENT (2, dbf_txt);
 
 	switch (ccode) {
 	case 0:
-
-		ioinfo[irq]->ui.flags.haltio = 1;
-
-		if (!ioinfo[irq]->ui.flags.doio) {
-			ioinfo[irq]->ui.flags.busy = 1;
-			ioinfo[irq]->u_intparm = user_intparm;
-			ioinfo[irq]->devstat.cstat = 0;
-			ioinfo[irq]->devstat.dstat = 0;
-			ioinfo[irq]->devstat.lpum = 0;
-			ioinfo[irq]->devstat.flag = DEVSTAT_HALT_FUNCTION;
-			ioinfo[irq]->devstat.scnt = 0;
-
-		} else {
-			ioinfo[irq]->devstat.flag |= DEVSTAT_HALT_FUNCTION;
-
-		}
-
-		/*
-		 * If synchronous I/O processing is requested, we have
-		 *  to wait for the corresponding interrupt to occur by
-		 *  polling the interrupt condition. However, as multiple
-		 *  interrupts may be outstanding, we must not just wait
-		 *  for the first interrupt, but must poll until ours
-		 *  pops up.
-		 */
-		if (flag & DOIO_WAIT_FOR_INTERRUPT) 
-			s390_do_sync_wait_haltclear(irq, 1);
-
-		ret = 0;
-		break;
-
+		sch->u_intparm = intparm;
+		sch->schib.scsw.actl |= SCSW_ACTL_HALT_PEND;
+		return 0;
 	case 1:		/* status pending */
-
-		ret = s390_IO_handle_pending(irq, 0, 1);
-		break;
-
 	case 2:		/* busy */
-
-		ret = -EBUSY;
-		break;
-
+		return -EBUSY;
 	default:		/* device not operational */
-
-		ret = -ENODEV;
-		break;
-
+		return -ENODEV;
 	}
-
-	if (flag & DOIO_WAIT_FOR_INTERRUPT) 
-		disable_cpu_sync_isc (irq);
-
-	return ret;
 }
 
 /*
  * Note: The "intparm" parameter is not used by the clear_IO() function
- *       itself, as no ORB is built for the CSCH instruction. However,
- *       it allows the device interrupt handler to associate the upcoming
- *       interrupt with the clear_IO() request.
+ *	 itself, as no ORB is built for the CSCH instruction. However,
+ *	 it allows the device interrupt handler to associate the upcoming
+ *	 interrupt with the clear_IO() request.
  */
 int
-clear_IO (int irq, unsigned long user_intparm, unsigned long flag)
-{				/* possible DOIO_WAIT_FOR_INTERRUPT */
-	int ret = 0;
-	int ccode;
+cio_clear(struct subchannel *sch, unsigned long intparm)
+{
 	char dbf_txt[15];
+	int ccode;
 
-	SANITY_CHECK (irq);
-
-	if (ioinfo[irq] == INVALID_STORAGE_AREA)
-		return -ENODEV;
-
-	/*
-	 * we only allow for clear_IO if the device has an I/O handler associated
-	 */
-	if (!ioinfo[irq]->ui.flags.ready)
+	if (!sch)
 		return -ENODEV;
 	/*
 	 * we ignore the clear_io() request if ending_status was received but
 	 *  a SENSE operation is waiting for completion.
 	 */
-	if (ioinfo[irq]->ui.flags.w4sense)
-		return 0;
 
-	sprintf (dbf_txt, "clearIO%x", irq);
+	sprintf (dbf_txt, "clearIO%x", sch->irq);
 	CIO_TRACE_EVENT (2, dbf_txt);
 
 	/*
-	 * If sync processing was requested we lock the sync ISC,
-	 *  modify the device to present interrupts for this ISC only
-	 *  and switch the CPU to handle this ISC exclusively.
-	 */
-	if (flag & DOIO_WAIT_FOR_INTERRUPT) {
-		ret = enable_cpu_sync_isc (irq);
-
-		if (ret)
-			return ret;
-	}
-
-	/*
 	 * Issue "Clear subchannel" and process condition code
 	 */
-	ccode = csch (irq);
+	ccode = csch (sch->irq);
 
 	sprintf (dbf_txt, "ccode:%d", ccode);
 	CIO_TRACE_EVENT (2, dbf_txt);
 
 	switch (ccode) {
 	case 0:
-
-		ioinfo[irq]->ui.flags.haltio = 1;
-
-		if (!ioinfo[irq]->ui.flags.doio) {
-			ioinfo[irq]->ui.flags.busy = 1;
-			ioinfo[irq]->u_intparm = user_intparm;
-			ioinfo[irq]->devstat.cstat = 0;
-			ioinfo[irq]->devstat.dstat = 0;
-			ioinfo[irq]->devstat.lpum = 0;
-			ioinfo[irq]->devstat.flag = DEVSTAT_CLEAR_FUNCTION;
-			ioinfo[irq]->devstat.scnt = 0;
-
-		} else {
-			ioinfo[irq]->devstat.flag |= DEVSTAT_CLEAR_FUNCTION;
-
-		}
-
-		/*
-		 * If synchronous I/O processing is requested, we have
-		 *  to wait for the corresponding interrupt to occur by
-		 *  polling the interrupt condition. However, as multiple
-		 *  interrupts may be outstanding, we must not just wait
-		 *  for the first interrupt, but must poll until ours
-		 *  pops up.
-		 */
-		if (flag & DOIO_WAIT_FOR_INTERRUPT) 
-			s390_do_sync_wait_haltclear(irq, 0);
-
-		ret = 0;
-		break;
-
-	case 1:		/* no status pending for csh */
-		BUG ();
-		break;
-
-	case 2:		/* no busy for csh */
-		BUG ();
-		break;
-
+		sch->u_intparm = intparm;
+		sch->schib.scsw.actl |= SCSW_ACTL_CLEAR_PEND;
+		return 0;
 	default:		/* device not operational */
-
-		ret = -ENODEV;
-		break;
-
+		return -ENODEV;
 	}
-
-	if (flag & DOIO_WAIT_FOR_INTERRUPT) 
-		disable_cpu_sync_isc (irq);
-
-	return ret;
 }
 
 /*
- * Function: cancel_IO
+ * Function: cio_cancel
  * Issues a "Cancel Subchannel" on the specified subchannel
  * Note: We don't need any fancy intparms and flags here
- *       since xsch is executed synchronously.
+ *	 since xsch is executed synchronously.
  * Only for common I/O internal use as for now.
  */
 int
-cancel_IO (int irq)
+cio_cancel (struct subchannel *sch)
 {
-	int ccode;
 	char dbf_txt[15];
-	int ret = 0;
+	int ccode;
+
+	if (!sch)
+		return -ENODEV;
 
-	sprintf (dbf_txt, "cancelIO%x", irq);
+	sprintf (dbf_txt, "cancelIO%x", sch->irq);
 	CIO_TRACE_EVENT (2, dbf_txt);
 
-	ccode = xsch (irq);
+	ccode = xsch (sch->irq);
 
 	sprintf (dbf_txt, "ccode:%d", ccode);
 	CIO_TRACE_EVENT (2, dbf_txt);
 
 	switch (ccode) {
-
 	case 0:		/* success */
-		ret = 0;
-		break;
-
+		return 0;
 	case 1:		/* status pending */
-
-		/* process the pending irq... */
-		s390_process_IRQ (irq);
-		ret = -EBUSY;
-		break;
-
+		return -EBUSY;
 	case 2:		/* not applicable */
-		ret = -EINVAL;
-		break;
-
-	default:		/* not oper */
-		ret = -ENODEV;
+		return -EINVAL;
+	default:	/* not oper */
+		return -ENODEV;
 	}
-
-	return ret;
 }
 
 /*
- * do_IRQ() handles all normal I/O device IRQ's (the special
- *          SMP cross-CPU interrupts have their own specific
- *          handlers).
- *
+ * Function: cio_cancel
+ * Issues a "Modify Subchannel" on the specified subchannel
  */
-asmlinkage void
-do_IRQ (struct pt_regs regs)
+static int
+cio_modify (struct subchannel *sch)
 {
-	/*
-	 * Get interrupt info from lowcore
-	 */
-	volatile tpi_info_t *tpi_info = (tpi_info_t *) (__LC_SUBCHANNEL_ID);
-
-	/*
-	 * take fast exit if CPU is in sync. I/O state
-	 *
-	 * Note: we have to turn off the WAIT bit and re-disable
-	 *       interrupts prior to return as this was the initial
-	 *       entry condition to synchronous I/O.
-	 */
-	if (*(__u32 *) __LC_SYNC_IO_WORD) {
-		regs.psw.mask &= ~(PSW_MASK_WAIT | PSW_MASK_IO);
-		return;
-	}
-	/* endif */
-	do {
-		/*
-		 * Non I/O-subchannel thin interrupts are processed differently
-		 */
-		if (tpi_info->adapter_IO == 1 &&
-		    tpi_info->int_type == IO_INTERRUPT_TYPE) {
-			irq_enter ();
-			do_adapter_IO (tpi_info->intparm);
-			irq_exit ();
-		} else {
-			unsigned int irq = tpi_info->irq;
-
-			/*
-			 * fix me !!!
-			 *
-			 * instead of boxing the device, we need to schedule device
-			 * recognition, the interrupt stays pending. We need to
-			 * dynamically allocate an ioinfo structure, etc..
-			 */
-			if (ioinfo[irq] == INVALID_STORAGE_AREA) 
-				return;	/* this keeps the device boxed ... */
+	int ccode, retry, ret;
 
-			if (ioinfo[irq]->st) {
-				/* How can that be? */
-				printk(KERN_WARNING "Received interrupt on "
-				       "non-IO subchannel %x!\n", irq);
-				return;
-			}
-
-			irq_enter ();
-			s390irq_spin_lock (irq);
-			s390_process_IRQ (irq);
-			s390irq_spin_unlock (irq);
-			irq_exit ();
+	ret = 0;
+	for (retry = 0; retry < 5; retry++) {
+		ccode = msch_err (sch->irq, &sch->schib);
+		if (ccode < 0)	/* -EIO if msch gets a program check. */
+			return ccode;
+		switch (ccode) {
+		case 0: /* successfull */
+			return 0;
+		case 1:	/* status pending */
+			return -EBUSY;
+		case 2:	/* busy */
+			udelay (100);	/* allow for recovery */
+			ret = -EBUSY;
+			break;
+		case 3:	/* not operational */
+			return -ENODEV;
 		}
-
-		/*
-		 * Are more interrupts pending?
-		 * If so, the tpi instruction will update the lowcore 
-		 * to hold the info for the next interrupt.
-		 * We don't do this for VM because a tpi drops the cpu
-		 * out of the sie which costs more cycles than it saves.
-		 */
-	} while (!MACHINE_IS_VM && tpi (NULL) != 0);
-
-	return;
+	}
+	return ret;
 }
 
 /*
- * used by s390_process_irq to start queued channel programs
+ * Enable subchannel.
  */
-static inline void
-s390_start_queued_io(int irq, devstat_t *udp)
+int
+cio_enable_subchannel (struct subchannel *sch, unsigned int isc)
 {
+	char dbf_txt[15];
+	int ccode;
+	int retry;
 	int ret;
-	int do_cancel = ioinfo[irq]->qflag & DOIO_CANCEL_ON_TIMEOUT;
-	
-	ret = s390_start_IO (irq,
-			     ioinfo[irq]->qcpa,
-			     ioinfo[irq]->qintparm,
-			     ioinfo[irq]->qlpm,
-			     ioinfo[irq]->qflag);
-	
-	ioinfo[irq]->ui.flags.doio_q = 0;
-	
-	/*
-	 * If s390_start_IO() failed call the device's interrupt
-	 *  handler, the IRQ related devstat area was setup by
-	 *  s390_start_IO() accordingly already (status pending
-	 *  condition).
-	 */
-	if (ret) 
-		ioinfo[irq]->irq_desc.handler (irq, udp, NULL);
-		
-	/* 
-	 * better cancel the io when we time out...
-	 */
-	if ((ret == -ETIMEDOUT) && do_cancel) 
-		cancel_IO (irq);
-
-}
-
-/*
- * used by s390_process_irq to issue a sense ccw
- */
-static inline void
-s390_issue_sense(unsigned int irq, devstat_t *dp)
-{
-	int ret_io;
-	ccw1_t *s_ccw = &ioinfo[irq]->senseccw;
-	unsigned long s_flag = 0;
-
-	s_ccw->cmd_code = CCW_CMD_BASIC_SENSE;
-	s_ccw->cda = (__u32) virt_to_phys (ioinfo[irq]->sense_data);
-	s_ccw->count = SENSE_MAX_COUNT;
-	s_ccw->flags = CCW_FLAG_SLI;
-	
-	/*
-	 * If free_irq() or a sync do_IO/s390_start_IO() is in
-	 *  process we have to sense synchronously
-	 */
-	if (ioinfo[irq]->ui.flags.unready || ioinfo[irq]->ui.flags.syncio) 
-		s_flag = DOIO_WAIT_FOR_INTERRUPT;
-	
-	/*
-	 * Reset status info
-	 *
-	 * It does not matter whether this is a sync. or async.
-	 *  SENSE request, but we have to assure we don't call
-	 *  the irq handler now, but keep the irq in busy state.
-	 *  In sync. mode s390_process_IRQ() is called recursively,
-	 *  while in async. mode we re-enter do_IRQ() with the
-	 *  next interrupt.
-	 *
-	 * Note : this may be a delayed sense request !
-	 */
-	ioinfo[irq]->ui.flags.fast = 0;
-	ioinfo[irq]->ui.flags.repall = 0;
-	ioinfo[irq]->ui.flags.w4final = 0;
-	ioinfo[irq]->ui.flags.delsense = 0;
-	
-	dp->cstat = 0;
-	dp->dstat = 0;
-	dp->rescnt = SENSE_MAX_COUNT;
-	
-	ioinfo[irq]->ui.flags.w4sense = 1;
-	
-	ret_io = s390_start_IO (irq, s_ccw, 0xE2C5D5E2,	/* = SENSe */
-				0,	/* n/a */
-				s_flag);
-	
-}
-
-static inline void
-s390_reset_flags_after_ending_status(int irq)
-{
-	ioinfo[irq]->ui.flags.busy = 0;
-	ioinfo[irq]->ui.flags.doio = 0;
-	ioinfo[irq]->ui.flags.haltio = 0;
-	ioinfo[irq]->ui.flags.fast = 0;
-	ioinfo[irq]->ui.flags.repall = 0;
-	ioinfo[irq]->ui.flags.w4final = 0;
-
-	ioinfo[irq]->devstat.flag |= DEVSTAT_FINAL_STATUS;
-	ioinfo[irq]->irq_desc.dev_id->flag |= DEVSTAT_FINAL_STATUS;
-	
-}
-
-/*
- * for cc=0 and cc=1 after tsch
- */
-static inline int
-s390_process_IRQ_normal(unsigned int irq)
-{
-	int ending_status;
-	unsigned int fctl;	/* function control */
-	unsigned int stctl;	/* status   control */
-	unsigned int actl;	/* activity control */
-	scsw_t *scsw;
-	int allow4handler = 1;
-	devstat_t *dp;
-	devstat_t *udp;
-	
-	dp = &ioinfo[irq]->devstat;
-	udp = ioinfo[irq]->irq_desc.dev_id;
 
-	scsw = &dp->ii.irb.scsw;
-	
-	fctl = scsw->fctl;
-	stctl = scsw->stctl;
-	actl = scsw->actl;
-	
-	ioinfo[irq]->stctl |= stctl;
-	
-	ending_status = (stctl & SCSW_STCTL_SEC_STATUS)
-		|| (stctl == (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND))
-		|| (stctl == SCSW_STCTL_STATUS_PEND);
-	
-	/*
-	 * Check for unsolicited interrupts - for debug purposes only
-	 *
-	 * We only consider an interrupt as unsolicited, if the device was not
-	 *  actively in use (busy) and an interrupt other than an ALERT status
-	 *  was received.
-	 *
-	 * Note: We must not issue a message to the console, if the
-	 *       unsolicited interrupt applies to the console device
-	 *       itself !
-	 */
-	if (!(stctl & SCSW_STCTL_ALERT_STATUS)
-	    && (ioinfo[irq]->ui.flags.busy == 0)) {
-		
-		CIO_DEBUG_NOCONS(irq, KERN_INFO, DBG, 2,
-				 "Unsolicited interrupt "
-				 "received for device %04X "
-				 "on subchannel %04X\n"
-				 " ... device status : %02X "
-				 "subchannel status : %02X\n",
-				 dp->devno,
-				 irq, dp->dstat, dp->cstat);
-		
-		CIO_DEBUG_NOCONS(irq, KERN_INFO, DBG, 2,
-				 "s390_process_IRQ(%04X) - irb for "
-				 "device %04X, ending_status %d:\n", 
-				 irq, dp->devno, ending_status);
-		
-		s390_displayhex (&(dp->ii.irb),
-				 sizeof (irb_t), 2);
-	}
-	
-	/*
-	 * take fast exit if no handler is available
-	 */
-	if (!ioinfo[irq]->ui.flags.ready)
-		return ending_status;
-	
-	/*
-	 * Check whether we must issue a SENSE CCW ourselves if there is no
-	 *  concurrent sense facility installed for the subchannel.
-	 *
-	 * Note: We should check for ioinfo[irq]->ui.flags.consns but VM
-	 *       violates the ESA/390 architecture and doesn't present an
-	 *       operand exception for virtual devices without concurrent
-	 *       sense facility available/supported when enabling the
-	 *       concurrent sense facility.
-	 */
-	if (((scsw->dstat & DEV_STAT_UNIT_CHECK) 
-	     && (!dp->flag & DEVSTAT_FLAG_SENSE_AVAIL))
-	    || (ioinfo[irq]->ui.flags.delsense && ending_status)) {
-		
-		allow4handler = 0;
-		
-		if (ending_status) {
-			/*
-			 * We copy the current status information into the device driver
-			 *  status area. Then we can use the local devstat area for device
-			 *  sensing. When finally calling the IRQ handler we must not overlay
-			 *  the original device status but copy the sense data only.
-			 */
-			memcpy (udp, dp, sizeof (devstat_t));
-			
-			s390_issue_sense(irq, dp);
-			
-		} else {
-			/*
-			 * we received an Unit Check but we have no final
-			 *  status yet, therefore we must delay the SENSE
-			 *  processing. However, we must not report this
-			 *  intermediate status to the device interrupt
-			 *  handler.
-			 */
-			ioinfo[irq]->ui.flags.fast = 0;
-			ioinfo[irq]->ui.flags.repall = 0;
-			
-			ioinfo[irq]->ui.flags.delsense = 1;
-			
-		}
-		
-	}
-	
-	/*
-	 * we allow for the device action handler if .
-	 *  - we received ending status
-	 *  - the action handler requested to see all interrupts
-	 *  - we received an intermediate status
-	 *  - fast notification was requested (primary status)
-	 *  - unsolicited interrupts
-	 *
-	 */
-	if (allow4handler) {
-		allow4handler = ending_status
-			|| (ioinfo[irq]->ui.flags.repall)
-			|| (stctl & SCSW_STCTL_INTER_STATUS)
-			|| ((ioinfo[irq]->ui.flags.fast)
-			    && (stctl & SCSW_STCTL_PRIM_STATUS))
-			|| (ioinfo[irq]->ui.flags.oper == 0);
-		
-	}
-	
-	/*
-	 * We used to copy the device status information right before
-	 *  calling the device action handler. However, in status
-	 *  pending situations during do_IO() or halt_IO(), as well as
-	 *  enable_subchannel/disable_subchannel processing we must
-	 *  synchronously return the status information and must not
-	 *  call the device action handler.
-	 *
-	 */
-	if (allow4handler) {
-		/*
-		 * if we were waiting for sense data we copy the sense
-		 *  bytes only as the original status information was
-		 *  saved prior to sense already.
-		 */
-		if (ioinfo[irq]->ui.flags.w4sense) {
-			int sense_count =
-				SENSE_MAX_COUNT - ioinfo[irq]->devstat.rescnt;
-			
-			CIO_DEBUG_NOCONS(irq, KERN_DEBUG, DBG, 4,
-					 "s390_process_IRQ( %04X ): "
-					 "BASIC SENSE bytes avail %d\n",
-					 irq, sense_count);
-
-			ioinfo[irq]->ui.flags.w4sense = 0;
-			udp->flag |= DEVSTAT_FLAG_SENSE_AVAIL;
-			udp->scnt = sense_count;
-
-			if (sense_count >= 0) {
-				memcpy (udp->ii.sense.data,
-					ioinfo[irq]->sense_data,
-					sense_count);
-			} else {
-				panic ("s390_process_IRQ(%04x) encountered "
-				       "negative sense count\n", irq);
-
-			}
-		} else {
-			memcpy (udp, dp, 
-				sizeof(devstat_t) - 
-				(dp->flag & DEVSTAT_FLAG_SENSE_AVAIL ?  
-				 0 : SENSE_MAX_COUNT));
-			
-		}
-
-	}
-
-	/*
-	 * for status pending situations other than deferred interrupt
-	 *  conditions detected by s390_process_IRQ() itself we must not
-	 *  call the handler. This will synchronously be reported back
-	 *  to the caller instead, e.g. when detected during do_IO().
-	 */
-	if (ioinfo[irq]->ui.flags.s_pend
-	    || ioinfo[irq]->ui.flags.unready
-	    || ioinfo[irq]->ui.flags.repnone) {
-
-		if (ending_status) 
-			s390_reset_flags_after_ending_status(irq);
-
-		allow4handler = 0;
-
-	}
-
-	/*
-	 * Call device action handler if applicable
-	 */
-	if (allow4handler) {
-
-		/*
-		 *  We only reset the busy condition when we are sure that no further
-		 *   interrupt is pending for the current I/O request (ending_status).
-		 */
-		if (ending_status || !ioinfo[irq]->ui.flags.oper) {
-			ioinfo[irq]->ui.flags.oper = 1;	/* dev IS oper */
-
-			s390_reset_flags_after_ending_status(irq);
-			
-			ioinfo[irq]->irq_desc.handler (irq, udp, NULL);
-
-			/*
-			 * reset intparm after final status or we will badly present unsolicited
-			 *  interrupts with a intparm value possibly no longer valid.
-			 */
-			dp->intparm = 0;
+	sprintf (dbf_txt, "ensch%x", sch->irq);
+	CIO_TRACE_EVENT (2, dbf_txt);
 
-			/*
-			 * Was there anything queued ? Start the pending channel program
-			 *  if there is one.
-			 */
-			if (ioinfo[irq]->ui.flags.doio_q) 
-				s390_start_queued_io(irq, udp);
+	ccode = stsch (sch->irq, &sch->schib);
+	if (ccode)
+		return -ENODEV;
 
-		} else {
-			ioinfo[irq]->ui.flags.w4final = 1;
-			
+	sch->schib.pmcw.ena = 1;
+	sch->schib.pmcw.isc = isc;
+	for (retry = 5, ret = 0; retry > 0; retry--) {
+		ret = cio_modify(sch);
+		if (ret == -ENODEV)
+			break;
+		if (ret == -EIO)
 			/*
-			 * Eventually reset subchannel PCI status and
-			 *  set the PCI or SUSPENDED flag in the user
-			 *  device status block if appropriate.
+			 * Got a program check in cio_modify. Try without
+			 * the concurrent sense bit the next time.
 			 */
-			if (dp->cstat & SCHN_STAT_PCI) {
-				udp->flag |= DEVSTAT_PCI;
-				dp->cstat &= ~SCHN_STAT_PCI;
-			}
-
-			if (actl & SCSW_ACTL_SUSPENDED) 
-				udp->flag |= DEVSTAT_SUSPENDED;
-
-			ioinfo[irq]->irq_desc.handler (irq, udp, NULL);
-
+			sch->schib.pmcw.csense = 0;
+		if (ret == 0) {
+			stsch (sch->irq, &sch->schib);
+			if (sch->schib.pmcw.ena)
+				break;
 		}
-
 	}
-
-	return ending_status;
-
+	sprintf (dbf_txt, "ret:%d", ret);
+	CIO_TRACE_EVENT (2, dbf_txt);
+	return ret;
 }
 
 /*
- * for cc=3 after tsch
+ * Disable subchannel.
  */
-static inline int
-s390_process_IRQ_notoper(unsigned int irq)
+int
+cio_disable_subchannel (struct subchannel *sch)
 {
-	devstat_t *dp;
-	devstat_t *udp;
-
-	ioinfo[irq]->ui.flags.busy = 0;
-	ioinfo[irq]->ui.flags.doio = 0;
-	ioinfo[irq]->ui.flags.haltio = 0;
-	
-	dp = &ioinfo[irq]->devstat;
-	udp = ioinfo[irq]->irq_desc.dev_id;
+	char dbf_txt[15];
+	int ccode;
+	int retry;
+	int ret;
 
-	dp->cstat = 0;
-	dp->dstat = 0;
-	
-	if (ioinfo[irq]->ulpm != ioinfo[irq]->opm) 
-		/*
-		 * either it was the only path or it was restricted ...
-		 */
-		ioinfo[irq]->opm &=
-			~(ioinfo[irq]->devstat.ii.irb.esw.esw1.lpum);
-	else 
-		ioinfo[irq]->opm = 0;
-	
-	if (ioinfo[irq]->opm == 0) 
-		ioinfo[irq]->ui.flags.oper = 0;
+	sprintf (dbf_txt, "dissch%x", sch->irq);
+	CIO_TRACE_EVENT (2, dbf_txt);
 
-	
-	ioinfo[irq]->devstat.flag |= DEVSTAT_NOT_OPER;
-	ioinfo[irq]->devstat.flag |= DEVSTAT_FINAL_STATUS;
-	
 	/*
-	 * When we find a device "not oper" we save the status
-	 *  information into the device status area and call the
-	 *  device specific interrupt handler.
-	 *
-	 * Note: currently we don't have any way to reenable
-	 *       the device unless an unsolicited interrupt
-	 *       is presented. We don't check for spurious
-	 *       interrupts on "not oper" conditions.
+	 * If device isn't operational we have to perform delayed
+	 *  disabling when the next interrupt occurs - unless the
+	 *  irq is re-requested prior to the interrupt to occur.
 	 */
-	
-	if ((ioinfo[irq]->ui.flags.fast)
-	    && (ioinfo[irq]->ui.flags.w4final)) {
+	ccode = stsch (sch->irq, &sch->schib);
+	if (ccode == 3)		/* Not operational. */
+		return -ENODEV;
+
+	if (sch->schib.scsw.actl != 0)
 		/*
-		 * If a new request was queued already, we have
-		 *  to simulate the "not oper" status for the
-		 *  queued request by switching the "intparm" value
-		 *  and notify the interrupt handler.
+		 * the disable function must not be called while there are
+		 *  requests pending for completion !
 		 */
-		if (ioinfo[irq]->ui.flags.doio_q) 
-			ioinfo[irq]->devstat.intparm = ioinfo[irq]->qintparm;
-			
-	}
-	
-	ioinfo[irq]->ui.flags.fast = 0;
-	ioinfo[irq]->ui.flags.repall = 0;
-	ioinfo[irq]->ui.flags.w4final = 0;
-	
-	/*
-	 * take fast exit if no handler is available
-	 */
-	if (!ioinfo[irq]->ui.flags.ready)
-		return 0;
-	
-	memcpy (udp, &(ioinfo[irq]->devstat), 
-		sizeof(devstat_t) - 
-		(dp->flag & DEVSTAT_FLAG_SENSE_AVAIL ?  0 : SENSE_MAX_COUNT));
-	
-	ioinfo[irq]->devstat.intparm = 0;
-	
-	if (!(ioinfo[irq]->ui.flags.s_pend || ioinfo[irq]->ui.flags.repnone))
-		ioinfo[irq]->irq_desc.handler (irq, udp, NULL);
-	
-	return 1;
+		return -EBUSY;
 
-}
 
+	sch->schib.pmcw.ena = 0;
+	for (retry = 5, ret = 0; retry > 0; retry--) {
+		ret = cio_modify(sch);
+		if (ret == -ENODEV)
+			break;
+		if (ret == 0) {
+			stsch (sch->irq, &sch->schib);
+			if (!sch->schib.pmcw.ena)
+				break;
+		}
+	}
+	sprintf (dbf_txt, "ret:%d", ret);
+	CIO_TRACE_EVENT (2, dbf_txt);
+	return ret;
+}
 
-/* FIXME:  help!!!! */
 /*
- * s390_process_IRQ() handles status pending situations and interrupts
- *
- * Called by : do_IRQ()             - for "real" interrupts
- *             s390_start_IO, halt_IO()
- *                                  - status pending cond. after SSCH, or HSCH
- *             cancel_IO(), clear_IO(), resume_IO()
- *             s390_set_isc5()
- *             s390_validate_subchannel(),
- *             {en,dis}able_subchannel() - status pending conditions (after MSCH)
+ * cio_validate_subchannel()
  *
- * Returns: 0 - no ending status received, no further action taken
- *          1 - interrupt handler was called with ending status
+ * Find out subchannel type and initialize struct subchannel.
+ * Return codes:
+ *   SUBCHANNEL_TYPE_IO for a normal io subchannel
+ *   SUBCHANNEL_TYPE_CHSC for a chsc subchannel
+ *   SUBCHANNEL_TYPE_MESSAGE for a messaging subchannel
+ *   SUBCHANNEL_TYPE_ADM for a adm(?) subchannel
+ *   -ENXIO for non-defined subchannels
+ *   -ENODEV for subchannels with invalid device number or blacklisted devices
  */
 int
-s390_process_IRQ (unsigned int irq)
+cio_validate_subchannel (struct subchannel *sch, unsigned int irq)
 {
-	int ccode;		/* cond code from tsch() operation */
-	int irb_cc;		/* cond code from irb */
-
-	int issense = 0;
-	devstat_t *dp;
-	devstat_t *udp;
-	scsw_t *scsw;
-
 	char dbf_txt[15];
+	int ccode;
 
-	if (cio_count_irqs) {
-		int cpu = smp_processor_id ();
-		s390_irq_count[cpu]++;
-	}
-
-	CIO_TRACE_EVENT (3, "procIRQ");
-	sprintf (dbf_txt, "%x", irq);
-	CIO_TRACE_EVENT (3, dbf_txt);
-
-	if (ioinfo[irq] == INVALID_STORAGE_AREA) {
-		static irb_t p_init_irb; /* FIXME: could this be on the stack? */
-		/* we can't properly process the interrupt ... */
-
-		CIO_DEBUG(KERN_CRIT, 0, 
-			  "s390_process_IRQ(%04X) - got interrupt "
-			  "for non-initialized subchannel!\n", irq);
-
-		tsch (irq, &p_init_irb);
-		return 1;
-
-	}
-
-	dp = &ioinfo[irq]->devstat;
-	udp = ioinfo[irq]->irq_desc.dev_id;
-
-	/*
-	 * It might be possible that a device was not-oper. at the time
-	 *  of free_irq() processing. This means the handler is no longer
-	 *  available when the device possibly becomes ready again. In
-	 *  this case we perform delayed disable_subchannel() processing.
-	 */
-	if ((!ioinfo[irq]->ui.flags.ready) 
-	    &&  (!ioinfo[irq]->ui.flags.d_disable)) 
+	sprintf (dbf_txt, "valsch%x", irq);
+	CIO_TRACE_EVENT (4, dbf_txt);
 
-		CIO_DEBUG (KERN_CRIT, 0, 
-			   "s390_process_IRQ(%04X) "
-			   "- no interrupt handler registered "
-			   "for device %04X !\n",
-			   irq, ioinfo[irq]->devstat.devno);
+	/* Nuke all fields. */
+	memset(sch, 0, sizeof(struct subchannel));
 
 	/*
-	 * retrieve the i/o interrupt information (irb),
-	 *  update the device specific status information
-	 *  and possibly call the interrupt handler.
-	 *
-	 * Note 1: At this time we don't process the resulting
-	 *         condition code (ccode) from tsch(), although
-	 *         we probably should.
-	 *
-	 * Note 2: Here we will have to check for channel
-	 *         check conditions and call a channel check
-	 *         handler.
-	 *
-	 * Note 3: If a start function was issued, the interruption
-	 *         parameter relates to it. If a halt function was
-	 *         issued for an idle device, the intparm must not
-	 *         be taken from lowcore, but from the devstat area.
+	 * The first subchannel that is not-operational (ccode==3)
+	 *  indicates that there aren't any more devices available.
 	 */
-	ccode = tsch (irq, &(dp->ii.irb));
-
-	sprintf (dbf_txt, "ccode:%d", ccode);
-	CIO_TRACE_EVENT (3, dbf_txt);
+	sch->irq = irq;
+	ccode = stsch (irq, &sch->schib);
+	if (ccode)
+		return -ENXIO;
 
-	if (ccode == 3) 
-		CIO_DEBUG (KERN_WARNING, 0, 
-			   "s390_process_IRQ(%04X) - subchannel "
-			   "is not operational!\n",
-			   irq);
+	/* Copy subchannel type from path management control word. */
+	sch->st = sch->schib.pmcw.st;
 
 	/*
-	 * We must only accumulate the status if the device is busy already
+	 * ... just being curious we check for non I/O subchannels
 	 */
-
-	scsw = &dp->ii.irb.scsw;
-
-	if (ioinfo[irq]->ui.flags.busy) {
-		dp->dstat |= scsw->dstat;
-		dp->cstat |= scsw->cstat;
-		dp->intparm = ioinfo[irq]->u_intparm;
-
-	} else {
-		dp->dstat = scsw->dstat;
-		dp->cstat = scsw->cstat;
-
-		dp->flag = 0;	/* reset status flags */
-		dp->intparm = 0;
-
+	if (sch->st != 0) {
+		CIO_DEBUG(KERN_INFO, 0,
+			  "Subchannel %04X reports "
+			  "non-I/O subchannel type %04X\n",
+			  sch->irq, sch->st);
+		/* We stop here for non-io subchannels. */
+		return sch->st;
 	}
 
-	dp->lpum = dp->ii.irb.esw.esw1.lpum;
-
-	/*
-	 * reset device-busy bit if no longer set in irb
-	 */
-	if ((dp->dstat & DEV_STAT_BUSY)
-	    && ((scsw->dstat & DEV_STAT_BUSY) == 0)) 
-		dp->dstat &= ~DEV_STAT_BUSY;
-
-	/*
-	 * Save residual count and CCW information in case primary and
-	 *  secondary status are presented with different interrupts.
-	 */
-	if (scsw->stctl
-	    & (SCSW_STCTL_PRIM_STATUS | SCSW_STCTL_INTER_STATUS)) {
+	/* Initialization for io subchannels. */
+	if (!sch->schib.pmcw.dnv)
+		/* io subchannel but device number is invalid. */
+		return -ENODEV;
 
+	/* Devno is valid. */
+	if (is_blacklisted (sch->schib.pmcw.dev)) {
 		/*
-		 * If the subchannel status shows status pending
-		 * and we received a check condition, the count
-		 * information is not meaningful.
+		 * This device must not be known to Linux. So we simply
+		 * say that there is no device and return ENODEV.
 		 */
-
-		if (!((scsw->stctl & SCSW_STCTL_STATUS_PEND)
-		      && (scsw->cstat
-			  & (SCHN_STAT_CHN_DATA_CHK
-			     | SCHN_STAT_CHN_CTRL_CHK
-			     | SCHN_STAT_INTF_CTRL_CHK
-			     | SCHN_STAT_PROG_CHECK
-			     | SCHN_STAT_PROT_CHECK
-			     | SCHN_STAT_CHAIN_CHECK)))) {
-
-			dp->rescnt = scsw->count;
-		} else {
-			dp->rescnt = SENSE_MAX_COUNT;
-		}
-
-		dp->cpa = scsw->cpa;
-		
-	}
-	irb_cc = scsw->cc;
-
-	/*
-	 * check for any kind of channel or interface control check but don't
-	 * issue the message for the console device
-	 */
-	if ((scsw->cstat
-	     & (SCHN_STAT_CHN_DATA_CHK
-		| SCHN_STAT_CHN_CTRL_CHK | SCHN_STAT_INTF_CTRL_CHK))) {
-
-		CIO_DEBUG_NOCONS (irq, KERN_WARNING, printk, 0,
-				  "Channel-Check or Interface-Control-Check "
-				  "received\n"
-				  " ... device %04X on subchannel %04X, dev_stat "
-				  ": %02X sch_stat : %02X\n",
-				  ioinfo[irq]->devstat.devno, irq, dp->dstat,
-				  dp->cstat);
-
-		if (irb_cc != 3) {
-
-			CIO_DEBUG_NOCONS(irq, KERN_WARNING, printk, 0, 
-					 "s390_process_IRQ(%04X) - irb for "
-					 "device %04X after channel check "
-					 "or interface control check:\n",
-					 irq, dp->devno);
-			
-			s390_displayhex (&(dp->ii.irb), 
-					 sizeof (irb_t), 0);
-		}
-		
-	}
-
-	if (scsw->ectl == 0) {
-		issense = 0;
-	} else if ((scsw->stctl == SCSW_STCTL_STATUS_PEND)
-		   && (scsw->eswf == 0)) {
-		issense = 0;
-	} else if ((scsw->stctl ==
-		    (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_INTER_STATUS))
-		   && ((scsw->actl & SCSW_ACTL_SUSPENDED) == 0)) {
-		issense = 0;
-	} else {
-		issense = dp->ii.irb.esw.esw0.erw.cons;
-
-	}
-
-	if (issense) {
-		dp->scnt = dp->ii.irb.esw.esw0.erw.scnt;
-		dp->flag |= DEVSTAT_FLAG_SENSE_AVAIL;
-
-		CIO_DEBUG_NOCONS (irq, KERN_DEBUG, DBG, 4,
-				  "s390_process_IRQ( %04X ): "
-				  "concurrent sense bytes avail %d\n",
-				  irq, dp->scnt);
+		CIO_MSG_EVENT(0, "Blacklisted device detected "
+			      "at devno %04X\n", sch->schib.pmcw.dev);
+		return -ENODEV;
 	}
 
-	switch (irb_cc) {
-	case 1:		/* status pending */
-		dp->flag |= DEVSTAT_STATUS_PENDING;
-
-	case 0:		/* normal i/o interruption */
-		return s390_process_IRQ_normal(irq);
-
-	default:	/* device/path not operational */
-		return s390_process_IRQ_notoper(irq);
-	}
+	sch->lpm = sch->schib.pmcw.pim &
+		sch->schib.pmcw.pam &
+		sch->schib.pmcw.pom;
+
+	chsc_validate_chpids(sch);
+
+	CIO_DEBUG(KERN_INFO, 0,
+		  "Detected device %04X on subchannel %s"
+		  " - PIM = %02X, PAM = %02X, POM = %02X\n",
+		  sch->schib.pmcw.dev, sch->dev.bus_id, sch->schib.pmcw.pim,
+		  sch->schib.pmcw.pam, sch->schib.pmcw.pom);
+
+	/*
+	 * We now have to initially ...
+	 *  ... set "interruption subclass"
+	 *  ... enable "concurrent sense"
+	 *  ... enable "multipath mode" if more than one
+	 *	  CHPID is available. This is done regardless
+	 *	  whether multiple paths are available for us.
+	 */
+	sch->schib.pmcw.isc = 3;	/* could be smth. else */
+	sch->schib.pmcw.csense = 1;	/* concurrent sense */
+	sch->schib.pmcw.ena = 0;
+	sch->schib.pmcw.intparm = sch->schib.pmcw.dev;
+	if ((sch->lpm & (sch->lpm - 1)) != 0)
+		sch->schib.pmcw.mp = 1;	/* multipath mode */
+	return 0;
 }
 
 /*
- * Set the special i/o-interruption subclass 7 for the
- *  device specified by parameter irq. There can only
- *  be a single device been operated on this special
- *  isc. This function is aimed being able to check
- *  on special device interrupts in disabled state,
- *  without having to delay I/O processing (by queueing)
- *  for non-console devices.
+ * do_IRQ() handles all normal I/O device IRQ's (the special
+ *	    SMP cross-CPU interrupts have their own specific
+ *	    handlers).
  *
- * Setting of this isc is done by set_cons_dev(), while
- *  wait_cons_dev() allows to actively wait on an interrupt
- *  for this device in disabed state. When the interrupt 
- *  condition is encountered, wait_cons_dev() calls do_IRQ()
- *  to have the console device driver processing the
- *  interrupt.
  */
-int
-set_cons_dev (int irq)
-{
-	int ccode;
-	int rc = 0;
-	char dbf_txt[15];
-
-	if (cons_dev != -1)
-		return -EBUSY;
-
-	sprintf (dbf_txt, "scons%x", irq);
-	CIO_TRACE_EVENT (4, dbf_txt);
-
-	/*
-	 * modify the indicated console device to operate
-	 *  on special console interrupt subclass 7
-	 */
-	ccode = stsch (irq, &(ioinfo[irq]->schib));
-
-	if (ccode) {
-		rc = -ENODEV;
-		ioinfo[irq]->devstat.flag |= DEVSTAT_NOT_OPER;
-	} else {
-		ioinfo[irq]->schib.pmcw.isc = 7;
-
-		ccode = msch (irq, &(ioinfo[irq]->schib));
-
-		if (ccode) {
-			rc = -EIO;
-		} else {
-			cons_dev = irq;
-
-			/*
-			 * enable console I/O-interrupt subclass 7
-			 */
-			ctl_set_bit(6, 24);
-
-		}
-	}
-
-	return rc;
-}
-
-int
-wait_cons_dev (int irq)
+void
+do_IRQ (struct pt_regs regs)
 {
-	int rc = 0;
-	long save_cr6;
-	char dbf_txt[15];
-
-	if (irq != cons_dev)
-		return -EINVAL;
-
-	sprintf (dbf_txt, "wcons%x", irq);
-	CIO_TRACE_EVENT (4, dbf_txt);
+	struct tpi_info *tpi_info;
+	struct subchannel *sch;
+	struct irb *irb;
 
 	/*
-	 * before entering the spinlock we may already have
-	 *  processed the interrupt on a different CPU ...
+	 * Get interrupt information from lowcore
 	 */
-	if (ioinfo[irq]->ui.flags.busy == 1) {
-		long cr6 __attribute__ ((aligned (8)));
-
+	tpi_info = (struct tpi_info *) __LC_SUBCHANNEL_ID;
+	irb = (struct irb *) __LC_IRB;
+	do {
 		/*
-		 * disable all, but isc 7 (console device)
+		 * Non I/O-subchannel thin interrupts are processed differently
 		 */
-		__ctl_store (cr6, 6, 6);
-		save_cr6 = cr6;
-		cr6 = 0x01000000;
-		__ctl_load (cr6, 6, 6);
-
-		do {
-			tpi_info_t tpi_info = { 0, };
-			if (tpi (&tpi_info) == 1) {
-				s390_process_IRQ (tpi_info.irq);
-			} else {
-				s390irq_spin_unlock (irq);
-				udelay (100);
-				s390irq_spin_lock (irq);
-			}
-			eieio ();
-		} while (ioinfo[irq]->ui.flags.busy == 1);
+		if (tpi_info->adapter_IO == 1 &&
+		    tpi_info->int_type == IO_INTERRUPT_TYPE) {
+			irq_enter ();
+			do_adapter_IO (tpi_info->intparm);
+			irq_exit ();
+			continue;
+		}
+		/* Store interrupt response block to lowcore. */
+		if (tsch (tpi_info->irq, irb) != 0)
+			/* Not status pending or not operational. */
+			continue;
+
+		sch = ioinfo[tpi_info->irq];
+		if (!sch)
+			continue;
+
+		irq_enter ();
+		spin_lock(&sch->lock);
+		memcpy (&sch->schib.scsw, &irb->scsw, sizeof (irb->scsw));
+		if (sch->driver && sch->driver->irq)
+			sch->driver->irq(&sch->dev);
+		spin_unlock(&sch->lock);
+		irq_exit ();
 
 		/*
-		 * restore previous isc value
+		 * Are more interrupts pending?
+		 * If so, the tpi instruction will update the lowcore
+		 * to hold the info for the next interrupt.
+		 * We don't do this for VM because a tpi drops the cpu
+		 * out of the sie which costs more cycles than it saves.
 		 */
-		cr6 = save_cr6;
-		__ctl_load (cr6, 6, 6);
-
-	}
-
-	return rc;
+	} while (!MACHINE_IS_VM && tpi (NULL) != 0);
 }
 
+#ifdef CONFIG_CCW_CONSOLE
+static struct subchannel console_subchannel;
+static int console_subchannel_in_use;
+
 /*
- * used by {en,dis}able_cpu_sync_isc
+ * busy wait for the next interrupt on the console
  */
-static inline int
-s390_set_isc5(int irq, int reset)
+void
+wait_cons_dev (void)
 {
-	int ccode;
-	int rc = 0;
-	int retry1 = 5;
-	int retry2 = 5;
-	int clear_pend = 0;
-	long cr6 __attribute__ ((aligned (8)));
+	unsigned long cr6      __attribute__ ((aligned (8)));
+	unsigned long save_cr6 __attribute__ ((aligned (8)));
 
-	do {
-		if (reset)
-			retry2 = 5;
-		else
-			retry2 = 3;
-		do {
-			ccode = msch (irq, &(ioinfo[irq]->schib));
-
-			switch (ccode) {
-			case 0:
-				/*
-				 * disable special interrupt subclass in CPU
-				 */
-				__ctl_store (cr6, 6, 6);
-				if (reset) {
-					/* disable sync isc 5 */
-					cr6 &= 0xFBFFFFFF;
-					/* enable standard isc 3 */
-					cr6 |= 0x10000000;
-					/* enable console isc 7, if neccessary */
-					if (cons_dev != -1)
-						cr6 |= 0x01000000;
-				} else {
-					/* enable sync isc 5 */
-					cr6 |= 0x04000000;
-					/* disable standard isc 3 */
-					cr6 &= 0xEFFFFFFF;
-					/* disable console isc 7, if neccessary */
-					if (cons_dev != -1)
-						cr6 &= 0xFEFFFFFF;
-				}
-				__ctl_load (cr6, 6, 6);
-				
-				retry2 = 0;
-				rc = 0;
-				break;
-				
-			case 1:	/* status pending */
-				ioinfo[irq]->ui.flags.s_pend = 1;
-				s390_process_IRQ (irq);
-				ioinfo[irq]->ui.flags.s_pend = 0;
+	/* 
+	 * before entering the spinlock we may already have
+	 * processed the interrupt on a different CPU...
+	 */
+	if (!console_subchannel_in_use ||
+	    console_subchannel.schib.scsw.actl == 0)
+		return;
 
-				retry2--;
-				rc = -EIO;
-				break;
-				
-			case 2:	/* busy */
-				if (reset) {
-					retry2--;
-					udelay (100);	/* give it time */
-				} else {
-					retry2 = 0;
-				}
-				rc = -EBUSY;
+	/* disable all but isc 7 (console device) */
+	__ctl_store (save_cr6, 6, 6);
+	cr6 = 0x01000000;
+	__ctl_load (cr6, 6, 6);
+
+	do {
+		spin_unlock(&console_subchannel.lock);
+		if (!cio_tpi())
+			udelay (100);
+		spin_lock(&console_subchannel.lock);
+	} while (console_subchannel.schib.scsw.actl != 0);
+	/*
+	 * restore previous isc value
+	 */
+	__ctl_load (save_cr6, 6, 6);
+}
+
+static int
+cio_console_irq(void)
+{
+	int irq;
+	
+	if (console_irq != -1) {
+		/* VM provided us with the irq number of the console. */
+		if (stsch(console_irq, &console_subchannel.schib) != 0 ||
+		    !console_subchannel.schib.pmcw.dnv)
+			return -1;
+		console_device = console_subchannel.schib.pmcw.dev;
+	} else if (console_device != -1) {
+		/* At least the console device number is known. */
+		for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) {
+			if (stsch(irq, &console_subchannel.schib) != 0)
 				break;
-				
-			default:	/* not oper */
-				retry2 = 0;
-				rc = -ENODEV;
+			if (console_subchannel.schib.pmcw.dnv &&
+			    console_subchannel.schib.pmcw.dev ==
+			    console_device) {
+				console_irq = irq;
 				break;
 			}
-			
-		} while (retry2);
-
-
-		if ((rc == 0) || (rc == -ENODEV) || (!reset))
-			retry1 = 0;
-		else
-			retry1--;
-		
-		if (retry1) {
-			/* try stopping it ... */
-			if (!clear_pend) {
-				clear_IO (irq, 0x00004711, 0);
-				clear_pend = 1;
-			
-			}
-		
-		udelay (100);
-
 		}
-
-		
-	} while (retry1 && ccode);
-	
-	return rc;
+		if (console_irq == -1)
+			return -1;
+	} else {
+		/* unlike in 2.4, we cannot autoprobe here, since
+		 * the channel subsystem is not fully initialized.
+		 * With some luck, the HWC console can take over */
+		printk(KERN_WARNING "No ccw console found!\n");
+		return -1;
+	}
+	return console_irq;
 }
 
-
-int
-enable_cpu_sync_isc (int irq)
+struct subchannel *
+cio_probe_console(void)
 {
-	int ccode;
-	int rc = 0;
-	char dbf_txt[15];
-
-	sprintf (dbf_txt, "enisc%x", irq);
-	CIO_TRACE_EVENT (4, dbf_txt);
+	int irq, ret;
 
-	/* This one spins until it can get the sync_isc lock for irq# irq */
-
-	if (atomic_read (&sync_isc) != irq)
-		atomic_compare_and_swap_spin (-1, irq, &sync_isc);
-	
-	sync_isc_cnt++;
-	
-	if (sync_isc_cnt > 255) {	/* fixme : magic number */
-		panic ("Too many recursive calls to enable_sync_isc");
-		
+	if (xchg(&console_subchannel_in_use, 1) != 0)
+		return ERR_PTR(-EBUSY);
+	irq = cio_console_irq();
+	if (irq == -1) {
+		console_subchannel_in_use = 0;
+		return ERR_PTR(-ENODEV);
 	}
-	/*
-	 * we only run the STSCH/MSCH path for the first enablement
-	 */
-	else if (sync_isc_cnt == 1) {
-		ioinfo[irq]->ui.flags.syncio = 1;
-		
-		ccode = stsch (irq, &(ioinfo[irq]->schib));
-		
-		if (!ccode) {
-			ioinfo[irq]->schib.pmcw.isc = 5;
-			rc = s390_set_isc5(irq, 0);
-			
-		} else {
-			rc = -ENODEV;	/* device is not-operational */
-			
-		}
+	memset(&console_subchannel, 0, sizeof(struct subchannel));
+	ret = cio_validate_subchannel(&console_subchannel, irq);
+	if (ret) {
+		console_subchannel_in_use = 0;
+		return ERR_PTR(-ENODEV);
 	}
-	
-	if (rc) {	/* can only happen if stsch/msch fails */
-		sync_isc_cnt = 0;
-		atomic_set (&sync_isc, -1);
-	}
-
-	return rc;
-}
-
-
-int
-disable_cpu_sync_isc (int irq)
-{
-	int rc = 0;
-	int ccode;
-
-	char dbf_txt[15];
-
-	sprintf (dbf_txt, "disisc%x", irq);
-	CIO_TRACE_EVENT (4, dbf_txt);
 
 	/*
-	 * We disable if we're the top user only, as we may
-	 *  run recursively ... 
-	 * We must not decrease the count immediately; during
-	 *  msch() processing we may face another pending
-	 *  status we have to process recursively (sync).
+	 * enable console I/O-interrupt subclass 7
 	 */
-	
-	if (sync_isc_cnt == 1) {
-		ccode = stsch (irq, &(ioinfo[irq]->schib));
-		
-		if (!ccode) {
-			
-			ioinfo[irq]->schib.pmcw.isc = 3;
-			rc = s390_set_isc5(irq, 1);
-		} else {
-			rc = -ENODEV;
-		}
-		
-		ioinfo[irq]->ui.flags.syncio = 0;
-		
-		sync_isc_cnt = 0;
-		atomic_set (&sync_isc, -1);
-		
-	} else {
-		sync_isc_cnt--;
-		
-	}
+	ctl_set_bit(6, 24);
+	console_subchannel.schib.pmcw.isc = 7;
+	ioinfo[irq] = &console_subchannel;
+	return &console_subchannel;
+}
 
-	return rc;
+void
+cio_release_console(void)
+{
+	ioinfo[console_subchannel.irq] = NULL;
+	ctl_clear_bit(6, 24);
+	console_subchannel_in_use = 0;
 }
 
-EXPORT_SYMBOL (halt_IO);
-EXPORT_SYMBOL (clear_IO);
-EXPORT_SYMBOL (do_IO);
-EXPORT_SYMBOL (resume_IO);
+#endif
diff -Nru a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h
--- a/drivers/s390/cio/cio.h	Mon Dec  9 18:46:34 2002
+++ b/drivers/s390/cio/cio.h	Mon Dec  9 18:46:34 2002
@@ -1,18 +1,136 @@
 #ifndef S390_CIO_H
 #define S390_CIO_H
 
-extern int
-s390_start_IO (int irq,         /* IRQ */
-               ccw1_t * cpa,    /* logical channel prog addr */
-               unsigned long user_intparm,      /* interruption parameter */
-               __u8 lpm,        /* logical path mask */
-               unsigned long flag);
-
-extern int cancel_IO (int irq);
-
-extern int enable_cpu_sync_isc (int irq);
-extern int disable_cpu_sync_isc (int irq);
-extern int cons_dev;
-extern int s390_process_IRQ (unsigned int irq);
+/*
+ * where we put the ssd info
+ */
+struct ssd_info {
+	__u8  valid:1;
+	__u8  type:7;		/* subchannel type */
+	__u8  chpid[8];		/* chpids */
+	__u16 fla[8];		/* full link addresses */
+} __attribute__ ((packed));
+
+/*
+ * path management control word
+ */
+struct pmcw {
+	__u32 intparm;		/* interruption parameter */
+	__u32 qf   : 1;		/* qdio facility */
+	__u32 res0 : 1;		/* reserved zeros */
+	__u32 isc  : 3;		/* interruption sublass */
+	__u32 res5 : 3;		/* reserved zeros */
+	__u32 ena  : 1;		/* enabled */
+	__u32 lm   : 2;		/* limit mode */
+	__u32 mme  : 2;		/* measurement-mode enable */
+	__u32 mp   : 1;		/* multipath mode */
+	__u32 tf   : 1;		/* timing facility */
+	__u32 dnv  : 1;		/* device number valid */
+	__u32 dev  : 16;	/* device number */
+	__u8  lpm;		/* logical path mask */
+	__u8  pnom;		/* path not operational mask */
+	__u8  lpum;		/* last path used mask */
+	__u8  pim;		/* path installed mask */
+	__u16 mbi;		/* measurement-block index */
+	__u8  pom;		/* path operational mask */
+	__u8  pam;		/* path available mask */
+	__u8  chpid[8];		/* CHPID 0-7 (if available) */
+	__u32 unused1 : 8;	/* reserved zeros */
+	__u32 st      : 3;	/* subchannel type */
+	__u32 unused2 : 20;	/* reserved zeros */
+	__u32 csense  : 1;	/* concurrent sense; can be enabled ...*/
+				/*  ... per MSCH, however, if facility */
+				/*  ... is not installed, this results */
+				/*  ... in an operand exception.       */
+} __attribute__ ((packed));
+
+/*
+ * subchannel information block
+ */
+struct schib {
+	struct pmcw pmcw;	 /* path management control word */
+	struct scsw scsw;	 /* subchannel status word */
+	__u8 mda[12];		 /* model dependent area */
+} __attribute__ ((packed,aligned(4)));
+
+/*
+ * operation request block
+ */
+struct orb {
+	__u32 intparm;		/* interruption parameter */
+	__u32 key  : 4; 	/* flags, like key, suspend control, etc. */
+	__u32 spnd : 1; 	/* suspend control */
+	__u32 res1 : 1; 	/* reserved */
+	__u32 mod  : 1; 	/* modification control */
+	__u32 sync : 1; 	/* synchronize control */
+	__u32 fmt  : 1; 	/* format control */
+	__u32 pfch : 1; 	/* prefetch control */
+	__u32 isic : 1; 	/* initial-status-interruption control */
+	__u32 alcc : 1; 	/* address-limit-checking control */
+	__u32 ssic : 1; 	/* suppress-suspended-interr. control */
+	__u32 res2 : 1; 	/* reserved */
+	__u32 c64  : 1; 	/* IDAW/QDIO 64 bit control  */
+	__u32 i2k  : 1; 	/* IDAW 2/4kB block size control */
+	__u32 lpm  : 8; 	/* logical path mask */
+	__u32 ils  : 1; 	/* incorrect length */
+	__u32 zero : 6; 	/* reserved zeros */
+	__u32 orbx : 1; 	/* ORB extension control */
+	__u32 cpa;		/* channel program address */
+}  __attribute__ ((packed,aligned(4)));
+
+/* subchannel data structure used by I/O subroutines */
+struct subchannel {
+	unsigned int irq;	/* aka. subchannel number */
+	spinlock_t lock;	/* subchannel lock */
+
+	enum {
+		SUBCHANNEL_TYPE_IO = 0,
+		SUBCHANNEL_TYPE_CHSC = 1,
+		SUBCHANNEL_TYPE_MESSAGE = 2,
+		SUBCHANNEL_TYPE_ADM = 3,
+	} st;			/* subchannel type */
+
+	struct {
+		unsigned int suspend:1; /* allow suspend */
+		unsigned int prefetch:1;/* deny prefetch */
+		unsigned int inter:1;   /* suppress intermediate interrupts */
+	} __attribute__ ((packed)) options;
+
+	__u8 vpm;		/* verified path mask */
+	__u8 lpm;		/* logical path mask */
+	// TODO: intparm for second start i/o
+	unsigned long u_intparm;	/* user interruption parameter */
+	struct schib schib;	/* subchannel information block */
+	struct orb orb;		/* operation request block */
+	struct ccw1 sense_ccw;	/* static ccw for sense command */
+	struct ssd_info ssd_info;	/* subchannel description */
+	struct device dev;	/* entry in device tree */
+	struct css_driver *driver;
+} __attribute__ ((aligned(8)));
+
+#define IO_INTERRUPT_TYPE	   0 /* I/O interrupt type */
+
+#define to_subchannel(n) container_of(n, struct subchannel, dev)
+
+extern int cio_validate_subchannel (struct subchannel *, unsigned int);
+extern int cio_modify (struct subchannel *);
+extern int cio_enable_subchannel (struct subchannel *, unsigned int);
+extern int cio_disable_subchannel (struct subchannel *);
+extern int cio_cancel (struct subchannel *);
+extern int cio_clear (struct subchannel *, unsigned long);
+extern int cio_do_io (struct subchannel *, struct ccw1 *, unsigned long, __u8);
+extern int cio_resume (struct subchannel *);
+extern int cio_halt (struct subchannel *, unsigned long);
+extern int cio_start (struct subchannel *, struct ccw1 *, unsigned long, __u8);
+extern int cio_cancel (struct subchannel *);
+extern int cio_set_options (struct subchannel *, int);
+extern int cio_get_options (struct subchannel *);
+
+/* Use with care. */
+extern int cio_tpi (void);
+extern struct subchannel *cio_probe_console(void);
+extern void cio_release_console(void);
+
+extern int cio_show_msg;
 
 #endif
diff -Nru a/drivers/s390/cio/cio_debug.c b/drivers/s390/cio/cio_debug.c
--- a/drivers/s390/cio/cio_debug.c	Mon Dec  9 18:46:36 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,72 +0,0 @@
-/*
- *  drivers/s390/cio/cio_debug.c
- *   S/390 common I/O routines -- message ids for debugging
- *   $Revision: 1.5 $
- *
- *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
- *                            IBM Corporation
- *    Author(s): Ingo Adlung (adlung@de.ibm.com)
- *               Cornelia Huck (cohuck@de.ibm.com) 
- *		 Arnd Bergmann (arndb@de.ibm.com)
- *    ChangeLog: 11/04/2002 Arnd Bergmann Split s390io.c into multiple files,
- *					  see s390io.c for complete list of
- * 					  changes.
- */
-
-
-#include <linux/init.h>
-#include <linux/slab.h>
-
-#include <asm/debug.h>
-
-#include "cio_debug.h"
-
-debug_info_t *cio_debug_msg_id;
-debug_info_t *cio_debug_trace_id;
-debug_info_t *cio_debug_crw_id;
-int cio_debug_initialized;
-
-/*
- * Function: cio_debug_init
- * Initializes three debug logs (under /proc/s390dbf) for common I/O:
- * - cio_msg logs the messages which are printk'ed when CONFIG_DEBUG_IO is on
- * - cio_trace logs the calling of different functions
- * - cio_crw logs the messages which are printk'ed when CONFIG_DEBUG_CRW is on
- * debug levels depend on CONFIG_DEBUG_IO resp. CONFIG_DEBUG_CRW
- */
-static int __init
-cio_debug_init (void)
-{
-	int ret = 0;
-
-	cio_debug_msg_id = debug_register ("cio_msg", 4, 4, 16 * sizeof (long));
-	if (cio_debug_msg_id != NULL) {
-		debug_register_view (cio_debug_msg_id, &debug_sprintf_view);
-		debug_set_level (cio_debug_msg_id, 6);
-	} else {
-		ret = -1;
-	}
-	cio_debug_trace_id = debug_register ("cio_trace", 4, 4, 8);
-	if (cio_debug_trace_id != NULL) {
-		debug_register_view (cio_debug_trace_id, &debug_hex_ascii_view);
-		debug_set_level (cio_debug_trace_id, 6);
-	} else {
-		ret = -1;
-	}
-	cio_debug_crw_id = debug_register ("cio_crw", 2, 4, 16 * sizeof (long));
-	if (cio_debug_crw_id != NULL) {
-		debug_register_view (cio_debug_crw_id, &debug_sprintf_view);
-		debug_set_level (cio_debug_crw_id, 6);
-	} else {
-		ret = -1;
-	}
-	if (ret){
-		printk ("could not initialize debugging\n");
-	} else {
-		printk ("debugging initialized\n");
-		cio_debug_initialized = 1;
-	}
-	return ret;
-}
-
-arch_initcall (cio_debug_init);
diff -Nru a/drivers/s390/cio/cio_debug.h b/drivers/s390/cio/cio_debug.h
--- a/drivers/s390/cio/cio_debug.h	Mon Dec  9 18:46:50 2002
+++ b/drivers/s390/cio/cio_debug.h	Mon Dec  9 18:46:50 2002
@@ -1,70 +1,32 @@
-#ifndef S390_DEBUG_H
-#define S390_DEBUG_H
+#ifndef CIO_DEBUG_H
+#define CIO_DEBUG_H
 
-#define SANITY_CHECK(irq) do { \
-if (irq > highest_subchannel || irq < 0) \
-		return -ENODEV; \
-	if (ioinfo[irq] == INVALID_STORAGE_AREA) \
-		return -ENODEV; \
-        if (ioinfo[irq]->st) \
-                return -ENODEV; \
-	} while(0)
+#include <asm/debug.h>
 
 #define CIO_TRACE_EVENT(imp, txt) do { \
-	if (cio_debug_initialized) \
-		debug_text_event(cio_debug_trace_id, \
-				 imp, \
-				 txt); \
-        }while (0)
+		debug_text_event(cio_debug_trace_id, imp, txt); \
+	} while (0)
 
 #define CIO_MSG_EVENT(imp, args...) do { \
-        if (cio_debug_initialized) \
-                debug_sprintf_event(cio_debug_msg_id, \
-                                    imp , \
-                                    ##args); \
-        } while (0)
+		debug_sprintf_event(cio_debug_msg_id, imp , ##args); \
+	} while (0)
 
 #define CIO_CRW_EVENT(imp, args...) do { \
-        if (cio_debug_initialized) \
-                debug_sprintf_event(cio_debug_crw_id, \
-                                    imp , \
-                                    ##args); \
-        } while (0)
-
-#undef  CONFIG_DEBUG_IO
-#define CONFIG_DEBUG_CRW
-#define CONFIG_DEBUG_CHSC
-
-#ifdef CONFIG_DEBUG_IO
-#define DBG printk
-#else /* CONFIG_DEBUG_IO */
-#define DBG(args,...)  do {} while (0) 
-#endif /* CONFIG_DEBUG_IO */
+		debug_sprintf_event(cio_debug_crw_id, imp , ##args); \
+	} while (0)
 
-#define CIO_DEBUG(printk_level,event_level,msg...) ({\
-	DBG(printk_level msg); \
-	CIO_MSG_EVENT (event_level, msg); \
-})
+#define CIO_HEX_EVENT(imp, args...) do { \
+                debug_event(cio_debug_trace_id, imp, ##args); \
+        } while (0)
 
-#define CIO_DEBUG_IFMSG(printk_level,event_level,msg...) ({\
+#define CIO_DEBUG(printk_level,event_level,msg...) ({ \
 	if (cio_show_msg) printk(printk_level msg); \
 	CIO_MSG_EVENT (event_level, msg); \
 })
 
-#define CIO_DEBUG_ALWAYS(printk_level,event_level,msg...) ({\
-	printk(printk_level msg); \
-	CIO_MSG_EVENT (event_level, msg); \
-})
-
-#define CIO_DEBUG_NOCONS(irq,printk_level,func,event_level,msg...) ({\
-	if (irq != cons_dev) func(printk_level msg); \
-	CIO_MSG_EVENT (event_level, msg); \
-})
-
 /* for use of debug feature */
 extern debug_info_t *cio_debug_msg_id;
 extern debug_info_t *cio_debug_trace_id;
 extern debug_info_t *cio_debug_crw_id;
-extern int cio_debug_initialized;
 
 #endif
diff -Nru a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/cio/css.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,248 @@
+/*
+ *  drivers/s390/cio/css.c
+ *  driver for channel subsystem
+ *   $Revision: 1.39 $
+ *
+ *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
+ *			 IBM Corporation
+ *    Author(s): Arnd Bergmann (arndb@de.ibm.com)
+ *		 Cornelia Huck (cohuck@de.ibm.com)
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+
+#include <asm/ccwdev.h> // FIXME: layering violation, remove this
+
+#include "css.h"
+#include "cio.h"
+#include "cio_debug.h"
+#include "device.h" // FIXME: dito
+
+struct subchannel *ioinfo[__MAX_SUBCHANNELS];
+unsigned int highest_subchannel;
+int css_init_done = 0;
+
+struct device css_bus_device = {
+	.name	= "Channel Subsystem 0",
+	.bus_id = "css0",
+};
+
+static int
+css_alloc_subchannel(int irq)
+{
+	struct subchannel *sch;
+	int ret;
+
+	if (ioinfo[irq])
+		/* There already is a struct subchannel for this irq. */
+		return -EBUSY;
+
+	sch = kmalloc (sizeof (*sch), GFP_DMA);
+	if (sch == NULL)
+		return -ENOMEM;
+	ret = cio_validate_subchannel (sch, irq);
+	if (ret < 0) {
+		kfree(sch);
+		return ret;
+	}
+	if (irq > highest_subchannel)
+		highest_subchannel = irq;
+
+	if (sch->st != SUBCHANNEL_TYPE_IO) {
+		/* For now we ignore all non-io subchannels. */
+		kfree(sch);
+		return -EINVAL;
+	}
+
+	ioinfo[irq] = sch;
+
+	return 0;
+}
+
+static void
+css_free_subchannel(int irq)
+{
+	struct subchannel *sch;
+
+	sch = ioinfo[irq];
+	if (sch) {
+		ioinfo[irq] = NULL;
+		kfree(sch);
+	}
+	
+}
+
+static int
+css_register_subchannel(struct subchannel *sch)
+{
+	static const char *subchannel_types[] = {
+		"I/O Subchannel",
+		"CHSC Subchannel",
+		"Message Subchannel",
+		"ADM Subchannel",
+		"undefined subchannel type 4",
+		"undefined subchannel type 5",
+		"undefined subchannel type 6",
+		"undefined subchannel type 7",
+		"undefined subchannel type 8",
+	};
+	int ret;
+
+	/* Initialize the subchannel structure */
+	sch->dev.parent = &css_bus_device;
+	sch->dev.bus = &css_bus_type;
+
+	/* Set a name for the subchannel */
+	strncpy (sch->dev.name, subchannel_types[sch->st], DEVICE_NAME_SIZE);
+	snprintf (sch->dev.bus_id, DEVICE_ID_SIZE, "0:%04x", sch->irq);
+
+	/* make it known to the system */
+	ret = device_register(&sch->dev);
+	if (ret)
+		printk (KERN_WARNING "%s: could not register %s\n",
+			__func__, sch->dev.bus_id);
+	return ret;
+}
+
+int
+css_probe_device(int irq)
+{
+	int ret;
+
+	ret = css_alloc_subchannel(irq);
+	if (ret)
+		return ret;
+	ret = css_register_subchannel(ioinfo[irq]);
+	if (ret)
+		css_free_subchannel(irq);
+	return ret;
+}
+
+/*
+ * Rescan for new devices. FIXME: This is slow.
+ */
+static void
+do_process_crw(void *ignore)
+{
+	int irq, ret;
+
+	for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) {
+		if (ioinfo[irq])
+			continue;
+		ret = css_probe_device(irq);
+		/* No more memory. It doesn't make sense to continue. No
+		 * panic because this can happen in midflight and just
+		 * because we can't use a new device is no reason to crash
+		 * the system. */
+		if (ret == -ENOMEM)
+			break;
+		/* -ENXIO indicates that there are no more subchannels. */
+		if (ret == -ENXIO)
+			break;
+	}
+}
+
+/*
+ * Called from the machine check handler for subchannel report words.
+ * Note: this is called disabled from the machine check handler itself.
+ */
+void
+css_process_crw(int irq)
+{
+	static DECLARE_WORK(work, do_process_crw, 0);
+	struct subchannel *sch;
+
+	CIO_CRW_EVENT(2, "source is subchannel %04X\n", irq);
+
+	sch = ioinfo[irq];
+	if (sch == NULL) {
+		schedule_work(&work);
+		return;
+	}
+	if (!sch->dev.driver_data)
+		return;
+	/* FIXME: css_process_crw must not know about ccw_device */
+	dev_fsm_event(sch->dev.driver_data, DEV_EVENT_NOTOPER);
+	// FIXME: revalidate machine checks?
+}
+
+/*
+ * some of the initialization has already been done from init_IRQ(),
+ * here we do the rest now that the driver core is running.
+ * Currently, this functions scans all the subchannel structures for
+ * devices. The long term plan is to remove ioinfo[] and then the
+ * struct subchannel's will be created during probing. 
+ */
+static int __init
+init_channel_subsystem (void)
+{
+	int ret, irq;
+
+	if ((ret = bus_register(&css_bus_type)))
+		goto out;
+	if ((ret = device_register (&css_bus_device)))
+		goto out_bus;
+
+	css_init_done = 1;
+
+	ctl_set_bit(6, 28);
+
+	for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) {
+		if (!ioinfo[irq]) {
+			ret = css_alloc_subchannel(irq);
+			if (ret == -ENOMEM)
+				panic("Out of memory in "
+				      "init_channel_subsystem\n");
+			/* -ENXIO: no more subchannels. */
+			if (ret == -ENXIO)
+				break;
+			if (ret)
+				continue;
+		}
+		/*
+		 * We register ALL valid subchannels in ioinfo, even those
+		 * that have been present before init_channel_subsystem.
+		 * These subchannels can't have been registered yet (kmalloc
+		 * not working) so we do it now. This is true e.g. for the
+		 * console subchannel.
+		 */
+		css_register_subchannel(ioinfo[irq]);
+	}
+	return 0;
+
+out_bus:
+	bus_unregister(&css_bus_type);
+out:
+	return ret;
+}
+
+/*
+ * find a driver for a subchannel. They identify by the subchannel
+ * type with the exception that the console subchannel driver has its own
+ * subchannel type although the device is an i/o subchannel
+ */
+static int
+css_bus_match (struct device *dev, struct device_driver *drv)
+{
+	struct subchannel *sch = container_of (dev, struct subchannel, dev);
+	struct css_driver *driver = container_of (drv, struct css_driver, drv);
+
+	if (sch->st == driver->subchannel_type)
+		return 1;
+
+	return 0;
+}
+
+struct bus_type css_bus_type = {
+	.name  = "css",
+	.match = &css_bus_match,
+};
+
+subsys_initcall(init_channel_subsystem);
+
+MODULE_LICENSE("GPL");
+EXPORT_SYMBOL(css_bus_type);
+
diff -Nru a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/cio/css.h	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,119 @@
+#ifndef _CSS_H
+#define _CSS_H
+
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+
+#include <asm/cio.h>
+
+/*
+ * path grouping stuff
+ */
+#define SPID_FUNC_SINGLE_PATH	   0x00
+#define SPID_FUNC_MULTI_PATH	   0x80
+#define SPID_FUNC_ESTABLISH	   0x00
+#define SPID_FUNC_RESIGN	   0x40
+#define SPID_FUNC_DISBAND	   0x20
+
+#define SNID_STATE1_RESET	   0
+#define SNID_STATE1_UNGROUPED	   2
+#define SNID_STATE1_GROUPED	   3
+
+#define SNID_STATE2_NOT_RESVD	   0
+#define SNID_STATE2_RESVD_ELSE	   2
+#define SNID_STATE2_RESVD_SELF	   3
+
+#define SNID_STATE3_MULTI_PATH	   1
+#define SNID_STATE3_SINGLE_PATH	   0
+
+struct path_state {
+	__u8  state1 : 2;	/* path state value 1 */
+	__u8  state2 : 2;	/* path state value 2 */
+	__u8  state3 : 1;	/* path state value 3 */
+	__u8  resvd  : 3;	/* reserved */
+} __attribute__ ((packed));
+
+struct pgid {
+	union {
+		__u8 fc;   	/* SPID function code */
+		struct path_state ps;	/* SNID path state */
+	} inf;
+	__u32 cpu_addr	: 16;	/* CPU address */
+	__u32 cpu_id	: 24;	/* CPU identification */
+	__u32 cpu_model : 16;	/* CPU model */
+	__u32 tod_high;		/* high word TOD clock */
+} __attribute__ ((packed));
+
+extern struct pgid global_pgid;
+
+#define MAX_CIWS 8
+
+/*
+ * sense-id response buffer layout
+ */
+struct senseid {
+	/* common part */
+	__u8  reserved;     	/* always 0x'FF' */
+	__u16 cu_type;	     	/* control unit type */
+	__u8  cu_model;     	/* control unit model */
+	__u16 dev_type;     	/* device type */
+	__u8  dev_model;    	/* device model */
+	__u8  unused;	     	/* padding byte */
+	/* extended part */
+	struct ciw ciw[MAX_CIWS];	/* variable # of CIWs */
+}  __attribute__ ((packed,aligned(4)));
+
+struct ccw_device_private {
+	int state;		/* device state */
+	__u16 devno;		/* device number */
+	__u16 irq;		/* subchannel number */
+	__u8 imask;		/* lpm mask for SNID/SID/SPGID */
+	int iretry;		/* retry counter SNID/SID/SPGID */
+	struct {
+		unsigned int fast:1;	/* post with "channel end" */
+		unsigned int repall:1;	/* report every interrupt status */
+	} __attribute__ ((packed)) options;
+	struct {
+		unsigned int pgid_supp:1;   /* "path group ID" supported */
+		unsigned int pgid_single:1; /* use single path for Set PGID */
+		unsigned int esid:1;        /* Ext. SenseID supported by HW */
+		unsigned int dosense:1;	    /* delayed SENSE required */
+	} __attribute__((packed)) flags;
+	struct qdio_irq *qdio_data;
+	struct irb irb;		/* device status */
+	struct senseid senseid;	/* SenseID info */
+	struct pgid pgid;	/* path group ID */
+	struct ccw1 iccws[2];	/* ccws for SNID/SID/SPGID commands */
+	struct work_struct kick_work;
+	wait_queue_head_t wait_q;
+	struct timer_list timer;
+};
+
+/*
+ * A css driver handles all subchannels of one type.
+ * Currently, we only care about I/O subchannels (type 0), these
+ * have a ccw_device connected to them.
+ */
+struct css_driver {
+	unsigned int subchannel_type;
+	struct device_driver drv;
+	void (*irq)(struct device *);
+};
+
+/*
+ * all css_drivers have the css_bus_type
+ */
+extern struct bus_type css_bus_type;
+
+int css_probe_device(int irq);
+
+extern unsigned int highest_subchannel;
+extern int css_init_done;
+
+#define __MAX_SUBCHANNELS 65536
+extern struct subchannel *ioinfo[__MAX_SUBCHANNELS];
+
+extern struct bus_type css_bus_type;
+extern struct device css_bus_device;
+
+#endif
diff -Nru a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/cio/device.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,598 @@
+/*
+ *  drivers/s390/cio/device.c
+ *  bus driver for ccw devices
+ *   $Revision: 1.44 $
+ *
+ *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
+ *			 IBM Corporation
+ *    Author(s): Arnd Bergmann (arndb@de.ibm.com)
+ *		 Cornelia Huck (cohuck@de.ibm.com)
+ *		 Martin Schwidefsky (schwidefsky@de.ibm.com)
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/device.h>
+
+#include <asm/ccwdev.h>
+#include <asm/cio.h>
+
+#include "cio.h"
+#include "css.h"
+#include "device.h"
+
+/******************* bus type handling ***********************/
+
+/* The Linux driver model distinguishes between a bus type and
+ * the bus itself. Of course we only have one channel
+ * subsystem driver and one channel system per machine, but
+ * we still use the abstraction. T.R. says it's a good idea. */
+static int
+ccw_bus_match (struct device * dev, struct device_driver * drv)
+{
+	struct ccw_device *cdev = to_ccwdev(dev);
+	struct ccw_driver *cdrv = to_ccwdrv(drv);
+	const struct ccw_device_id *ids = cdrv->ids, *found;
+
+	if (!ids)
+		return 0;
+
+	found = ccw_device_id_match(ids, &cdev->id);
+	if (!found)
+		return 0;
+
+	cdev->id.driver_info = found->driver_info;
+
+	return 1;
+}
+
+/*
+ * Hotplugging interface for ccw devices.
+ * Heavily modeled on pci and usb hotplug.
+ */
+static int
+ccw_hotplug (struct device *dev, char **envp, int num_envp,
+	     char *buffer, int buffer_size)
+{
+	struct ccw_device *cdev = to_ccwdev(dev);
+	int i = 0;
+	int length = 0;
+
+	if (!cdev)
+		return -ENODEV;
+
+	if (cdev->private->state == DEV_STATE_NOT_OPER)
+		return -ENODEV;
+
+	/* what we want to pass to /sbin/hotplug */
+
+	envp[i++] = buffer;
+	length += snprintf(buffer, buffer_size - length, "CU_TYPE=%04X",
+			   cdev->id.cu_type);
+	if ((buffer_size - length <= 0) || (i >= num_envp))
+		return -ENOMEM;
+	++length;
+	buffer += length;
+
+	envp[i++] = buffer;
+	length += snprintf(buffer, buffer_size - length, "CU_MODEL=%02X",
+			   cdev->id.cu_model);
+	if ((buffer_size - length <= 0) || (i >= num_envp))
+		return -ENOMEM;
+	++length;
+	buffer += length;
+
+	/* The next two can be zero, that's ok for us */
+	envp[i++] = buffer;
+	length += snprintf(buffer, buffer_size - length, "DEV_TYPE=%04X",
+			   cdev->id.dev_type);
+	if ((buffer_size - length <= 0) || (i >= num_envp))
+		return -ENOMEM;
+	++length;
+	buffer += length;
+
+	envp[i++] = buffer;
+	length += snprintf(buffer, buffer_size - length, "DEV_MODEL=%02X",
+			   cdev->id.dev_model);
+	if ((buffer_size - length <= 0) || (i >= num_envp))
+		return -ENOMEM;
+
+	envp[i] = 0;
+
+	return 0;
+}
+
+struct bus_type ccw_bus_type = {
+	.name  = "ccw",
+	.match = &ccw_bus_match,
+	.hotplug = &ccw_hotplug,
+};
+
+static int io_subchannel_probe (struct device *);
+void io_subchannel_irq (struct device *);
+
+static struct css_driver io_subchannel_driver = {
+	.subchannel_type = SUBCHANNEL_TYPE_IO,
+	.drv = {
+		.name = "io_subchannel",
+		.bus  = &css_bus_type,
+		.probe = &io_subchannel_probe,
+	},
+	.irq = io_subchannel_irq,
+};
+
+static int __init
+init_ccw_bus_type (void)
+{
+	int ret;
+	if ((ret = bus_register (&ccw_bus_type)))
+		return ret;
+
+	return driver_register(&io_subchannel_driver.drv);
+}
+
+static void __exit
+cleanup_ccw_bus_type (void)
+{
+	driver_unregister(&io_subchannel_driver.drv);
+	bus_unregister(&ccw_bus_type);
+}
+
+subsys_initcall(init_ccw_bus_type);
+module_exit(cleanup_ccw_bus_type);
+
+/************************ device handling **************************/
+
+/*
+ * A ccw_device has some interfaces in sysfs in addition to the
+ * standard ones.
+ * The following entries are designed to export the information which
+ * resided in 2.4 in /proc/subchannels. Subchannel and device number
+ * are obvious, so they don't have an entry :)
+ * TODO: Split chpids and pimpampom up? Where is "in use" in the tree?
+ */
+static ssize_t
+chpids_show (struct device * dev, char * buf, size_t count, loff_t off)
+{
+	struct subchannel *sch = to_subchannel(dev);
+	struct ssd_info *ssd = &sch->ssd_info;
+	ssize_t ret = 0;
+	int chp;
+
+	for (chp = 0; chp < 8; chp++)
+		ret += sprintf (buf+ret, "%02x ", ssd->chpid[chp]);
+
+	ret += sprintf (buf+ret, "\n");
+	return off ? 0 : min((ssize_t)count, ret);
+}
+
+static ssize_t
+pimpampom_show (struct device * dev, char * buf, size_t count, loff_t off)
+{
+	struct subchannel *sch = to_subchannel(dev);
+	struct pmcw *pmcw = &sch->schib.pmcw;
+
+	return off ? 0 : snprintf (buf, count, "%02x %02x %02x\n",
+				   pmcw->pim, pmcw->pam, pmcw->pom);
+}
+
+static ssize_t
+devtype_show (struct device *dev, char *buf, size_t count, loff_t off)
+{
+	struct ccw_device *cdev = to_ccwdev(dev);
+	struct ccw_device_id *id = &(cdev->id);
+
+	if (id->dev_type != 0)
+		return off ? 0 : snprintf(buf, count, "%04x/%02x\n",
+					  id->dev_type, id->dev_model);
+	else
+		return off ? 0 : snprintf(buf, count, "n/a\n");
+}
+
+static ssize_t
+cutype_show (struct device *dev, char *buf, size_t count, loff_t off)
+{
+	struct ccw_device *cdev = to_ccwdev(dev);
+	struct ccw_device_id *id = &(cdev->id);
+
+	return off ? 0 : snprintf(buf, count, "%04x/%02x\n",
+				  id->cu_type, id->cu_model);
+}
+
+static ssize_t
+online_show (struct device *dev, char *buf, size_t count, loff_t off)
+{
+	struct ccw_device *cdev = to_ccwdev(dev);
+
+	return off ? 0 : snprintf(buf, count, cdev->online ? "yes\n" : "no\n");
+}
+
+void
+ccw_device_set_offline(struct ccw_device *cdev)
+{
+	if (!cdev)
+		return;
+	if (!cdev->online || !cdev->drv)
+		return;
+
+	if (cdev->drv->set_offline)
+		if (cdev->drv->set_offline(cdev) != 0)
+			return;
+
+	cdev->online = 0;
+	spin_lock_irq(cdev->ccwlock);
+	ccw_device_offline(cdev);
+	spin_unlock_irq(cdev->ccwlock);
+	wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
+}
+
+void
+ccw_device_set_online(struct ccw_device *cdev)
+{
+	if (!cdev || !cdev->handler)
+		return;
+	if (cdev->online || !cdev->drv)
+		return;
+
+	spin_lock_irq(cdev->ccwlock);
+	ccw_device_online(cdev);
+	spin_unlock_irq(cdev->ccwlock);
+	wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
+	if (cdev->private->state != DEV_STATE_ONLINE)
+		return;
+	if (!cdev->drv->set_online || cdev->drv->set_online(cdev) == 0) {
+		cdev->online = 1;
+		return;
+	}
+	spin_lock_irq(cdev->ccwlock);
+	ccw_device_offline(cdev);
+	spin_unlock_irq(cdev->ccwlock);
+	wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
+}
+
+static ssize_t
+online_store (struct device *dev, const char *buf, size_t count, loff_t off)
+{
+	struct ccw_device *cdev = to_ccwdev(dev);
+	unsigned int value;
+
+	if (off)
+		return 0;
+
+	if (!cdev->drv)
+		return count;
+
+	sscanf(buf, "%u", &value);
+
+	if (value) {
+		if (cdev->drv->set_online)
+			ccw_device_set_online(cdev);
+	} else {
+		if (cdev->drv->set_offline)
+			ccw_device_set_offline(cdev);
+	}
+
+	return count;
+}
+
+static DEVICE_ATTR(chpids, 0444, chpids_show, NULL);
+static DEVICE_ATTR(pimpampom, 0444, pimpampom_show, NULL);
+static DEVICE_ATTR(devtype, 0444, devtype_show, NULL);
+static DEVICE_ATTR(cutype, 0444, cutype_show, NULL);
+static DEVICE_ATTR(online, 0644, online_show, online_store);
+
+static inline int
+subchannel_add_files (struct device *dev)
+{
+	int ret;
+
+	if ((ret = device_create_file(dev, &dev_attr_chpids)) ||
+	    (ret = device_create_file(dev, &dev_attr_pimpampom))) {
+		device_remove_file(dev, &dev_attr_chpids);
+	}
+	return ret;
+}
+
+static inline int
+device_add_files (struct device *dev)
+{
+	int ret;
+
+	if ((ret = device_create_file(dev, &dev_attr_devtype)) ||
+	    (ret = device_create_file(dev, &dev_attr_cutype))  ||
+	    (ret = device_create_file(dev, &dev_attr_online))) {
+		device_remove_file(dev, &dev_attr_cutype);
+		device_remove_file(dev, &dev_attr_devtype);
+	}
+	return ret;
+}
+
+/* this is a simple abstraction for device_register that sets the
+ * correct bus type and adds the bus specific files */
+static int
+ccw_device_register(struct ccw_device *cdev)
+{
+	struct device *dev = &cdev->dev;
+	int ret;
+
+	dev->bus = &ccw_bus_type;
+
+	if ((ret = device_add(dev)))
+		return ret;
+
+	if ((ret = device_add_files(dev)))
+		device_unregister(dev);
+
+	return ret;
+}
+
+static void
+ccw_device_release(struct device *dev)
+{
+	struct ccw_device *cdev;
+
+	cdev = to_ccwdev(dev);
+	kfree(cdev->private);
+	kfree(cdev);
+}
+
+/*
+ * Register recognized device.
+ */
+void
+io_subchannel_register(void *data)
+{
+	struct ccw_device *cdev;
+	struct subchannel *sch;
+	int ret;
+
+	cdev = (struct ccw_device *) data;
+	sch = to_subchannel(cdev->dev.parent);
+
+	/* make it known to the system */
+	ret = ccw_device_register(cdev);
+	if (ret) {
+		printk (KERN_WARNING "%s: could not register %s\n",
+			__func__, cdev->dev.bus_id);
+		sch->dev.driver_data = 0;
+		kfree (cdev->private);
+		kfree (cdev);
+		return;
+	}
+
+	ret = subchannel_add_files(cdev->dev.parent);
+	if (ret)
+		printk(KERN_WARNING "%s: could not add attributes to %04x\n",
+		       __func__, sch->irq);
+}
+
+static void
+io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch)
+{
+	sch->dev.driver_data = cdev;
+	sch->driver = &io_subchannel_driver;
+	cdev->ccwlock = &sch->lock;
+	*cdev->private = (struct ccw_device_private) {
+		.devno	= sch->schib.pmcw.dev,
+		.irq	= sch->irq,
+		.state	= DEV_STATE_NOT_OPER,
+	};
+	init_waitqueue_head(&cdev->private->wait_q);
+	init_timer(&cdev->private->timer);
+
+	/* Set an initial name for the device. */
+	snprintf (cdev->dev.name, DEVICE_NAME_SIZE,"ccw device");
+	snprintf (cdev->dev.bus_id, DEVICE_ID_SIZE, "0:%04x",
+		  sch->schib.pmcw.dev);
+
+	/* Do first half of device_register. */
+	device_initialize(&cdev->dev);
+	get_device(&sch->dev);	/* keep parent refcount in sync. */
+
+	/* Start async. device sensing. */
+	spin_lock_irq(cdev->ccwlock);
+	ccw_device_recognition(cdev);
+	spin_unlock_irq(cdev->ccwlock);
+}
+
+static int
+io_subchannel_probe (struct device *pdev)
+{
+	struct subchannel *sch;
+	struct ccw_device *cdev;
+
+	sch = to_subchannel(pdev);
+	if (sch->dev.driver_data) {
+		/*
+		 * This subchannel already has an associated ccw_device.
+		 * Register it and exit. This happens for all early
+		 * device, e.g. the console.
+		 */
+		ccw_device_register(sch->dev.driver_data);
+		subchannel_add_files(&sch->dev);
+		return 0;
+	}
+	cdev  = kmalloc (sizeof(*cdev), GFP_KERNEL);
+	if (!cdev)
+		return -ENOMEM;
+	memset(cdev, 0, sizeof(struct ccw_device));
+	cdev->private = kmalloc(sizeof(struct ccw_device_private), GFP_DMA);
+	if (!cdev->private) {
+		kfree(cdev);
+		return -ENOMEM;
+	}
+	memset(cdev->private, 0, sizeof(struct ccw_device_private));
+	cdev->dev = (struct device) {
+		.parent = pdev,
+		.release = ccw_device_release,
+	};
+	io_subchannel_recog(cdev, to_subchannel(pdev));
+	return 0;
+}
+
+#ifdef CONFIG_CCW_CONSOLE
+static struct ccw_device console_cdev;
+static struct ccw_device_private console_private;
+static int console_cdev_in_use;
+
+static int
+ccw_device_console_enable (struct ccw_device *cdev, struct subchannel *sch)
+{
+	/* Initialize the ccw_device structure. */
+	cdev->dev = (struct device) {
+		.parent = &sch->dev,
+	};
+	/* Initialize the subchannel structure */
+	sch->dev = (struct device) {
+		.parent = &css_bus_device,
+		.bus	= &css_bus_type,
+	};
+	io_subchannel_recog(cdev, sch);
+	/* Now wait for the async. recognition to come to an end. */
+	while (!dev_fsm_final_state(cdev))
+		wait_cons_dev();
+	if (cdev->private->state != DEV_STATE_OFFLINE)
+		return -EIO;
+	ccw_device_online(cdev);
+	while (!dev_fsm_final_state(cdev))
+		wait_cons_dev();
+	if (cdev->private->state != DEV_STATE_ONLINE)
+		return -EIO;
+	return 0;
+}
+
+struct ccw_device *
+ccw_device_probe_console(void)
+{
+	struct subchannel *sch;
+	int ret;
+
+	if (xchg(&console_cdev_in_use, 1) != 0)
+		return NULL;
+	sch = cio_probe_console();
+	if (IS_ERR(sch)) {
+		console_cdev_in_use = 0;
+		return (void *) sch;
+	}
+	memset(&console_cdev, 0, sizeof(struct ccw_device));
+	memset(&console_private, 0, sizeof(struct ccw_device_private));
+	console_cdev.private = &console_private;
+	ret = ccw_device_console_enable(&console_cdev, sch);
+	if (ret) {
+		cio_release_console();
+		console_cdev_in_use = 0;
+		return ERR_PTR(ret);
+	}
+	return &console_cdev;
+}
+#endif
+
+/*
+ * get ccw_device matching the busid, but only if owned by cdrv
+ */
+struct ccw_device *
+get_ccwdev_by_busid(struct ccw_driver *cdrv, const char *bus_id)
+{
+	struct device *d, *dev;
+	struct device_driver *drv;
+
+	drv = get_driver(&cdrv->driver);
+	if (!drv)
+		return 0;
+
+	down_read(&drv->bus->subsys.rwsem);
+
+	dev = NULL;
+	list_for_each_entry(d, &drv->devices, driver_list) {
+		dev = get_device(d);
+
+		if (dev && !strncmp(bus_id, dev->bus_id, DEVICE_ID_SIZE))
+			break;
+		else
+			put_device(dev);
+	}
+	up_read(&drv->bus->subsys.rwsem);
+	put_driver(drv);
+
+	return dev ? to_ccwdev(dev) : 0;
+}
+
+/************************** device driver handling ************************/
+
+/* This is the implementation of the ccw_driver class. The probe, remove
+ * and release methods are initially very similar to the device_driver
+ * implementations, with the difference that they have ccw_device
+ * arguments.
+ *
+ * A ccw driver also contains the information that is needed for
+ * device matching.
+ */
+static int
+ccw_device_probe (struct device *dev)
+{
+	struct ccw_device *cdev = to_ccwdev(dev);
+	struct ccw_driver *cdrv = to_ccwdrv(dev->driver);
+	int ret;
+
+	cdev->drv = cdrv; /* to let the driver call _set_online */
+
+	ret = cdrv->probe ? cdrv->probe(cdev) : -ENODEV;
+
+	if (ret) {
+		cdev->drv = 0;
+		return ret;
+	}
+
+	return 0;
+}
+
+static int
+ccw_device_remove (struct device *dev)
+{
+	struct ccw_device *cdev = to_ccwdev(dev);
+	struct ccw_driver *cdrv = cdev->drv;
+
+	/*
+	 * Set device offline, so device drivers don't end up with
+	 * doubled code.
+	 * This is safe because of the checks in ccw_device_set_offline.
+	 */
+	pr_debug(KERN_INFO "removing device %s, sch %d, devno %x\n",
+		 cdev->dev.name,
+		 cdev->private->irq,
+		 cdev->private->devno);
+	ccw_device_set_offline(cdev);
+	return cdrv->remove ? cdrv->remove(cdev) : 0;
+}
+
+int
+ccw_driver_register (struct ccw_driver *cdriver)
+{
+	struct device_driver *drv = &cdriver->driver;
+
+	drv->bus = &ccw_bus_type;
+	drv->name = cdriver->name;
+	drv->probe = ccw_device_probe;
+	drv->remove = ccw_device_remove;
+
+	return driver_register(drv);
+}
+
+void
+ccw_driver_unregister (struct ccw_driver *cdriver)
+{
+	driver_unregister(&cdriver->driver);
+}
+
+MODULE_LICENSE("GPL");
+EXPORT_SYMBOL(ccw_device_set_online);
+EXPORT_SYMBOL(ccw_device_set_offline);
+EXPORT_SYMBOL(ccw_driver_register);
+EXPORT_SYMBOL(ccw_driver_unregister);
+EXPORT_SYMBOL(get_ccwdev_by_busid);
+EXPORT_SYMBOL(ccw_bus_type);
diff -Nru a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/cio/device.h	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,100 @@
+#ifndef S390_DEVICE_H
+#define S390_DEVICE_H
+
+/*
+ * states of the device statemachine
+ */
+enum dev_state {
+	DEV_STATE_NOT_OPER,
+	DEV_STATE_SENSE_PGID,
+	DEV_STATE_SENSE_ID,
+	DEV_STATE_OFFLINE,
+	DEV_STATE_VERIFY,
+	DEV_STATE_ONLINE,
+	DEV_STATE_W4SENSE,
+	DEV_STATE_DISBAND_PGID,
+	DEV_STATE_BOXED,
+	/* special states for qdio */
+	DEV_STATE_QDIO_INIT,
+	DEV_STATE_QDIO_ACTIVE,
+	DEV_STATE_QDIO_CLEANUP,
+	/* states to wait for i/o completion before doing something */
+	DEV_STATE_ONLINE_VERIFY,
+	DEV_STATE_W4SENSE_VERIFY,
+	/* last element! */
+	NR_DEV_STATES
+};
+
+/*
+ * asynchronous events of the device statemachine
+ */
+enum dev_event {
+	DEV_EVENT_NOTOPER,
+	DEV_EVENT_INTERRUPT,
+	DEV_EVENT_TIMEOUT,
+	DEV_EVENT_VERIFY,
+	/* last element! */
+	NR_DEV_EVENTS
+};
+
+struct ccw_device;
+
+/*
+ * action called through jumptable
+ */
+typedef void (fsm_func_t)(struct ccw_device *, enum dev_event);
+extern fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS];
+
+static inline void
+dev_fsm_event(struct ccw_device *cdev, enum dev_event dev_event)
+{
+	dev_jumptable[cdev->private->state][dev_event](cdev, dev_event);
+}
+
+/*
+ * Delivers 1 if the device state is final.
+ */
+static inline int
+dev_fsm_final_state(struct ccw_device *cdev)
+{
+	return (cdev->private->state == DEV_STATE_NOT_OPER ||
+		cdev->private->state == DEV_STATE_OFFLINE ||
+		cdev->private->state == DEV_STATE_ONLINE ||
+		cdev->private->state == DEV_STATE_BOXED);
+}
+
+void io_subchannel_register(void *data);
+
+int ccw_device_recognition(struct ccw_device *);
+int ccw_device_online(struct ccw_device *);
+int ccw_device_offline(struct ccw_device *);
+
+/* Function prototypes for device status and basic sense stuff. */
+void ccw_device_accumulate_irb(struct ccw_device *, struct irb *);
+void ccw_device_accumulate_basic_sense(struct ccw_device *, struct irb *);
+int ccw_device_accumulate_and_sense(struct ccw_device *, struct irb *);
+int ccw_device_do_sense(struct ccw_device *, struct irb *);
+
+/* Function prototypes for sense id stuff. */
+void ccw_device_sense_id_start(struct ccw_device *);
+void ccw_device_sense_id_irq(struct ccw_device *, enum dev_event);
+void ccw_device_sense_id_done(struct ccw_device *, int);
+
+/* Function prototypes for path grouping stuff. */
+void ccw_device_sense_pgid_start(struct ccw_device *);
+void ccw_device_sense_pgid_irq(struct ccw_device *, enum dev_event);
+void ccw_device_sense_pgid_done(struct ccw_device *, int);
+
+void ccw_device_verify_start(struct ccw_device *);
+void ccw_device_verify_irq(struct ccw_device *, enum dev_event);
+void ccw_device_verify_done(struct ccw_device *, int);
+
+void ccw_device_disband_start(struct ccw_device *);
+void ccw_device_disband_irq(struct ccw_device *, enum dev_event);
+void ccw_device_disband_done(struct ccw_device *, int);
+
+void ccw_device_call_handler(struct ccw_device *);
+
+/* qdio needs this. */
+void ccw_device_set_timeout(struct ccw_device *, int);
+#endif
diff -Nru a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/cio/device_fsm.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,732 @@
+/*
+ * drivers/s390/cio/device_fsm.c
+ * finite state machine for device handling
+ *
+ *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
+ *			 IBM Corporation
+ *    Author(s): Cornelia Huck(cohuck@de.ibm.com)
+ *		 Martin Schwidefsky (schwidefsky@de.ibm.com)
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/ccwdev.h>
+#include <asm/qdio.h>
+
+#include "cio.h"
+#include "cio_debug.h"
+#include "css.h"
+#include "device.h"
+#include "qdio.h"
+
+/*
+ * Timeout function. It just triggers a DEV_EVENT_TIMEOUT.
+ */
+static void
+ccw_device_timeout(unsigned long data)
+{
+	struct ccw_device *cdev;
+
+	cdev = (struct ccw_device *) data;
+	spin_lock_irq(cdev->ccwlock);
+	dev_fsm_event(cdev, DEV_EVENT_TIMEOUT);
+	spin_unlock_irq(cdev->ccwlock);
+}
+
+/*
+ * Set timeout
+ */
+void
+ccw_device_set_timeout(struct ccw_device *cdev, int expires)
+{
+	if (expires == 0) {
+		if (timer_pending(&cdev->private->timer))
+			del_timer(&cdev->private->timer);
+		return;
+	}
+	if (timer_pending(&cdev->private->timer)) {
+		if (mod_timer(&cdev->private->timer, jiffies + expires))
+			return;
+	}
+	cdev->private->timer.function = ccw_device_timeout;
+	cdev->private->timer.data = (unsigned long) cdev;
+	cdev->private->timer.expires = jiffies + expires;
+	add_timer(&cdev->private->timer);
+}
+
+/*
+ * Cancel running i/o. This is called repeatedly since halt/clear are
+ * asynchronous operations. We do one try with cio_cancel, two tries
+ * with cio_halt, 255 tries with cio_clear. If everythings fails panic.
+ */
+static int
+ccw_device_cancel_halt_clear(struct ccw_device *cdev)
+{
+	struct subchannel *sch;
+
+	sch = to_subchannel(cdev->dev.parent);
+	if (sch->schib.scsw.actl == 0)
+		/* Not operational or no activity -> done. */
+		return 0;
+	/* Stage 1: cancel io. */
+	if (!(sch->schib.scsw.actl & SCSW_ACTL_HALT_PEND) &&
+	    !(sch->schib.scsw.actl & SCSW_ACTL_CLEAR_PEND)) {
+		if (cio_cancel (sch) == 0)
+			return 0;
+		/* cancel io unsuccessful. From now on it is asynchronous. */
+		cdev->private->iretry = 3;	/* 3 halt retries. */
+	}
+	if (!(sch->schib.scsw.actl & SCSW_ACTL_CLEAR_PEND)) {
+		/* Stage 2: halt io. */
+		while (cdev->private->iretry-- > 0)
+			if (cio_halt (sch, 0xC8C1D3E3) == 0)
+				return -EBUSY;
+		/* halt io unsuccessful. */
+		cdev->private->iretry = 255;	/* 255 clear retries. */
+	}
+	/* Stage 3: clear io. */
+	while (cdev->private->iretry-- > 0)
+		if (cio_clear (sch, 0x40C3D3D9) == 0)
+			return -EBUSY;
+	panic("Can't stop i/o on subchannel.\n");
+}
+
+/*
+ * Stop device recognition.
+ */
+static void
+ccw_device_recog_done(struct ccw_device *cdev, int state)
+{
+	struct subchannel *sch;
+
+	sch = to_subchannel(cdev->dev.parent);
+
+	ccw_device_set_timeout(cdev, 0);
+	cio_disable_subchannel(sch);
+	cdev->private->state = state;
+
+	switch (state) {
+	case DEV_STATE_NOT_OPER:
+		CIO_DEBUG(KERN_WARNING, 2,
+			  "SenseID : unknown device %04X on subchannel %04X\n",
+			  sch->schib.pmcw.dev, sch->irq);
+		device_unregister(&cdev->dev);
+		break;
+	case DEV_STATE_OFFLINE:
+		/* fill out sense information */
+		cdev->id = (struct ccw_device_id) {
+			.cu_type   = cdev->private->senseid.cu_type,
+			.cu_model  = cdev->private->senseid.cu_model,
+			.dev_type  = cdev->private->senseid.dev_type,
+			.dev_model = cdev->private->senseid.dev_model,
+		};
+		/* Issue device info message. */
+		CIO_DEBUG(KERN_INFO, 2, "SenseID : device %04X reports: "
+			  "CU  Type/Mod = %04X/%02X, Dev Type/Mod = "
+			  "%04X/%02X\n", sch->schib.pmcw.dev,
+			  cdev->id.cu_type, cdev->id.cu_model,
+			  cdev->id.dev_type, cdev->id.dev_model);
+		if (css_init_done == 0)
+			break;
+		INIT_WORK(&cdev->private->kick_work,
+			  io_subchannel_register, (void *) cdev);
+		schedule_work(&cdev->private->kick_work);
+		break;
+	case DEV_STATE_BOXED:
+		CIO_DEBUG(KERN_WARNING, 2,
+			  "SenseID : boxed device %04X on subchannel %04X\n",
+			  sch->schib.pmcw.dev, sch->irq);
+		break;
+	}
+	wake_up(&cdev->private->wait_q);
+}
+
+/*
+ * Function called from device_id.c after sense id has completed.
+ */
+void
+ccw_device_sense_id_done(struct ccw_device *cdev, int err)
+{
+	switch (err) {
+	case 0:
+		ccw_device_recog_done(cdev, DEV_STATE_OFFLINE);
+		break;
+	case -ETIME:		/* Sense id stopped by timeout. */
+		ccw_device_recog_done(cdev, DEV_STATE_BOXED);
+		break;
+	default:
+		ccw_device_recog_done(cdev, DEV_STATE_NOT_OPER);
+		break;
+	}
+}
+
+/*
+ * Function called from device_pgid.c after sense path ground has completed.
+ */
+void
+ccw_device_sense_pgid_done(struct ccw_device *cdev, int err)
+{
+	switch (err) {
+	case 0:
+		cdev->private->state = DEV_STATE_SENSE_ID;
+		ccw_device_sense_id_start(cdev);
+		break;
+	case -ETIME:		/* Sense path group id stopped by timeout. */
+	case -EUSERS:		/* device is reserved for someone else. */
+		ccw_device_recog_done(cdev, DEV_STATE_BOXED);
+		break;
+	default:
+		ccw_device_recog_done(cdev, DEV_STATE_NOT_OPER);
+		break;
+	}
+}
+
+/*
+ * Start device recognition.
+ */
+int
+ccw_device_recognition(struct ccw_device *cdev)
+{
+	struct subchannel *sch;
+
+	if (cdev->private->state != DEV_STATE_NOT_OPER)
+		return -EINVAL;
+	sch = to_subchannel(cdev->dev.parent);
+	if (cio_enable_subchannel(sch, sch->schib.pmcw.isc) != 0)
+		/* Couldn't enable the subchannel for i/o. Sick device. */
+		return -ENODEV;
+
+	/* After 60s the device recognition is considered to have failed. */
+	ccw_device_set_timeout(cdev, 60*HZ);
+
+	/*
+	 * First thing we should do is a sensePGID in order to find out how
+	 * we can proceed with the recognition process.
+	 */
+	cdev->private->state = DEV_STATE_SENSE_PGID;
+	ccw_device_sense_pgid_start(cdev);
+	return 0;
+}
+
+/*
+ * Handle timeout in device recognition.
+ */
+static void
+ccw_device_recog_timeout(struct ccw_device *cdev, enum dev_event dev_event)
+{
+	struct subchannel *sch;
+
+	sch = to_subchannel(cdev->dev.parent);
+	if (ccw_device_cancel_halt_clear(cdev) == 0)
+		ccw_device_recog_done(cdev, DEV_STATE_BOXED);
+	else
+		ccw_device_set_timeout(cdev, 3*HZ);
+}
+
+/*
+ * Finished with online/offline processing.
+ */
+static void
+ccw_device_done(struct ccw_device *cdev, int state)
+{
+	struct subchannel *sch;
+
+	sch = to_subchannel(cdev->dev.parent);
+
+	if (state != DEV_STATE_ONLINE) {
+		cio_disable_subchannel(sch);
+		device_unregister(&cdev->dev);
+	}
+
+	/* Reset device status. */
+	memset(&cdev->private->irb, 0, sizeof(struct irb));
+
+	cdev->private->state = state;
+
+	wake_up(&cdev->private->wait_q);
+}
+
+void
+ccw_device_verify_done(struct ccw_device *cdev, int err)
+{
+	switch (err) {
+	case 0:
+		ccw_device_done(cdev, DEV_STATE_ONLINE);
+		break;
+	case -ETIME:
+		ccw_device_done(cdev, DEV_STATE_BOXED);
+		break;
+	default:
+		ccw_device_done(cdev, DEV_STATE_NOT_OPER);
+		break;
+	}
+}
+
+/*
+ * Get device online.
+ */
+int
+ccw_device_online(struct ccw_device *cdev)
+{
+	struct subchannel *sch;
+
+	if (cdev->private->state != DEV_STATE_OFFLINE)
+		return -EINVAL;
+	sch = to_subchannel(cdev->dev.parent);
+	if (cio_enable_subchannel(sch, sch->schib.pmcw.isc) != 0) {
+		/* Couldn't enable the subchannel for i/o. Sick device. */
+		dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
+		return -ENODEV;
+	}
+	/* Is Set Path Group supported? */
+	if (!cdev->private->flags.pgid_supp) {
+		/* No, set state online immediatly. */
+		ccw_device_done(cdev, DEV_STATE_ONLINE);
+		return 0;
+	}
+	/* Start Path Group verification. */
+	sch->vpm = 0;	/* Start with no path groups set. */
+	cdev->private->state = DEV_STATE_VERIFY;
+	ccw_device_verify_start(cdev);
+	return 0;
+}
+
+void
+ccw_device_disband_done(struct ccw_device *cdev, int err)
+{
+	switch (err) {
+	case 0:
+		ccw_device_done(cdev, DEV_STATE_OFFLINE);
+		break;
+	case -ETIME:
+		ccw_device_done(cdev, DEV_STATE_BOXED);
+		break;
+	default:
+		ccw_device_done(cdev, DEV_STATE_NOT_OPER);
+		break;
+	}
+}
+
+/*
+ * Shutdown device.
+ */
+int
+ccw_device_offline(struct ccw_device *cdev)
+{
+	struct subchannel *sch;
+
+	sch = to_subchannel(cdev->dev.parent);
+	if (cdev->private->state != DEV_STATE_ONLINE) {
+		if (sch->schib.scsw.actl != 0)
+			return -EBUSY;
+		return -EINVAL;
+	}
+	if (sch->schib.scsw.actl != 0)
+		return -EBUSY;
+	/* Is Set Path Group supported? */
+	if (!cdev->private->flags.pgid_supp) {
+		/* No, set state offline immediatly. */
+		ccw_device_done(cdev, DEV_STATE_OFFLINE);
+		return 0;
+	}
+	/* Start Set Path Group commands. */
+	cdev->private->state = DEV_STATE_DISBAND_PGID;
+	ccw_device_disband_start(cdev);
+	return 0;
+}
+
+/*
+ * Handle timeout in device online/offline process.
+ */
+static void
+ccw_device_onoff_timeout(struct ccw_device *cdev, enum dev_event dev_event)
+{
+	struct subchannel *sch;
+
+	sch = to_subchannel(cdev->dev.parent);
+	if (ccw_device_cancel_halt_clear(cdev) == 0)
+		ccw_device_done(cdev, DEV_STATE_BOXED);
+	else
+		ccw_device_set_timeout(cdev, 3*HZ);
+}
+
+/*
+ * Handle not oper event in device recognition.
+ */
+static void
+ccw_device_recog_notoper(struct ccw_device *cdev, enum dev_event dev_event)
+{
+	ccw_device_recog_done(cdev, DEV_STATE_NOT_OPER);
+}
+
+/*
+ * Handle not operational event while offline.
+ */
+static void
+ccw_device_offline_notoper(struct ccw_device *cdev, enum dev_event dev_event)
+{
+	cdev->private->state = DEV_STATE_NOT_OPER;
+	device_unregister(&cdev->dev);
+	wake_up(&cdev->private->wait_q);
+}
+
+/*
+ * Handle not operational event while online.
+ */
+static void
+ccw_device_online_notoper(struct ccw_device *cdev, enum dev_event dev_event)
+{
+	struct subchannel *sch;
+
+	sch = to_subchannel(cdev->dev.parent);
+	cdev->private->state = DEV_STATE_NOT_OPER;
+	cio_disable_subchannel(sch);
+	if (sch->schib.scsw.actl != 0) {
+		// FIXME: not-oper indication to device driver ?
+		ccw_device_call_handler(cdev);
+	}
+	device_unregister(&cdev->dev);
+	wake_up(&cdev->private->wait_q);
+}
+
+/*
+ * Handle path verification event.
+ */
+static void
+ccw_device_online_verify(struct ccw_device *cdev, enum dev_event dev_event)
+{
+	struct subchannel *sch;
+
+	sch = to_subchannel(cdev->dev.parent);
+	if (cdev->private->state == DEV_STATE_W4SENSE) {
+		cdev->private->state = DEV_STATE_W4SENSE_VERIFY;
+		return;
+	}
+	if (sch->schib.scsw.actl != 0) {
+		cdev->private->state = DEV_STATE_ONLINE_VERIFY;
+		return;
+	}
+	/* Device is idle, we can do the path verification. */
+	cdev->private->state = DEV_STATE_VERIFY;
+	ccw_device_verify_start(cdev);
+}
+
+/*
+ * Got an interrupt for a normal io (state online).
+ */
+static void
+ccw_device_irq(struct ccw_device *cdev, enum dev_event dev_event)
+{
+	struct irb *irb;
+
+	irb = (struct irb *) __LC_IRB;
+	/* Check for unsolicited interrupt. */
+	if (irb->scsw.stctl ==
+	    		(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
+		if (cdev->handler)
+			cdev->handler (cdev, 0, irb);
+		return;
+	}
+	/* Accumulate status and find out if a basic sense is needed. */
+	ccw_device_accumulate_irb(cdev, irb);
+	if (cdev->private->flags.dosense) {
+		if (ccw_device_do_sense(cdev, irb) == 0)
+			cdev->private->state = DEV_STATE_W4SENSE;
+		return;
+	}
+	/* No basic sense required, call the handler. */
+	ccw_device_call_handler(cdev);
+}
+
+static void
+ccw_device_irq_verify(struct ccw_device *cdev, enum dev_event dev_event)
+{
+	struct irb *irb;
+
+	irb = (struct irb *) __LC_IRB;
+	/* Check for unsolicited interrupt. */
+	if (irb->scsw.stctl ==
+	    		(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
+		if (cdev->handler)
+			cdev->handler (cdev, 0, irb);
+		return;
+	}
+	/* Accumulate status and find out if a basic sense is needed. */
+	ccw_device_accumulate_irb(cdev, irb);
+	if (cdev->private->flags.dosense) {
+		if (ccw_device_do_sense(cdev, irb) == 0)
+			cdev->private->state = DEV_STATE_W4SENSE_VERIFY;
+		return;
+	}
+	/* Try to start delayed device verification. */
+	ccw_device_online_verify(cdev, 0);
+	/* No basic sense required, call the handler. */
+	ccw_device_call_handler(cdev);
+}
+
+/*
+ * Got an interrupt for a basic sense.
+ */
+void
+ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event)
+{
+	struct irb *irb;
+
+	irb = (struct irb *) __LC_IRB;
+	/* Check for unsolicited interrupt. */
+	if (irb->scsw.stctl ==
+	    		(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
+		if (cdev->handler)
+			cdev->handler (cdev, 0, irb);
+		return;
+	}
+	/* Add basic sense info to irb. */
+	ccw_device_accumulate_basic_sense(cdev, irb);
+	if (cdev->private->flags.dosense) {
+		/* Another basic sense is needed. */
+		ccw_device_do_sense(cdev, irb);
+		return;
+	}
+	cdev->private->state = DEV_STATE_ONLINE;
+	/* Call the handler. */
+	ccw_device_call_handler(cdev);
+}
+
+static void
+ccw_device_w4sense_verify(struct ccw_device *cdev, enum dev_event dev_event)
+{
+	struct irb *irb;
+
+	irb = (struct irb *) __LC_IRB;
+	/* Check for unsolicited interrupt. */
+	if (irb->scsw.stctl ==
+	    		(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
+		if (cdev->handler)
+			cdev->handler (cdev, 0, irb);
+		return;
+	}
+	/* Add basic sense info to irb. */
+	ccw_device_accumulate_basic_sense(cdev, irb);
+	if (cdev->private->flags.dosense) {
+		/* Another basic sense is needed. */
+		ccw_device_do_sense(cdev, irb);
+		return;
+	}
+	cdev->private->state = DEV_STATE_ONLINE_VERIFY;
+	/* Start delayed device verification. */
+	ccw_device_online_verify(cdev, 0);
+	/* Call the handler. */
+	ccw_device_call_handler(cdev);
+}
+
+/*
+ * No operation action. This is used e.g. to ignore a timeout event in
+ * state offline.
+ */
+static void
+ccw_device_nop(struct ccw_device *cdev, enum dev_event dev_event)
+{
+}
+
+/*
+ * Bug operation action. 
+ */
+static void
+ccw_device_bug(struct ccw_device *cdev, enum dev_event dev_event)
+{
+	printk(KERN_EMERG "dev_jumptable[%i][%i] == NULL\n",
+	       cdev->private->state, dev_event);
+	BUG();
+}
+
+/*
+ * We've got an interrupt on establish queues. Check for errors and
+ * accordingly retry or move on.
+ */
+static void
+ccw_device_qdio_init_irq(struct ccw_device *cdev, enum dev_event dev_event)
+{
+	struct irb *irb;
+	struct subchannel *sch;
+
+	irb = (struct irb *) __LC_IRB;
+	/* Check for unsolicited interrupt. */
+	if (irb->scsw.stctl ==
+	    		(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
+		if (cdev->private->qdio_data && 
+		    cdev->private->qdio_data->establish_irq)
+			cdev->private->qdio_data->establish_irq(cdev, 0, irb);
+		wake_up(&cdev->private->wait_q);
+		return;
+	}
+	ccw_device_accumulate_irb(cdev, irb);
+	//FIXME: Basic sense?
+	sch = to_subchannel(cdev->dev.parent);
+	if (cdev->private->qdio_data && cdev->private->qdio_data->establish_irq)
+		cdev->private->qdio_data->establish_irq(cdev, sch->u_intparm,
+							&cdev->private->irb);
+	wake_up(&cdev->private->wait_q);
+}
+
+/*
+ * Run into a timeout after establish queues, retry if needed.
+ */
+static void
+ccw_device_qdio_init_timeout(struct ccw_device *cdev, enum dev_event dev_event)
+{
+	ccw_device_set_timeout(cdev, 0);
+	if (cdev->private->qdio_data &&
+	    cdev->private->qdio_data->establish_timeout)
+		cdev->private->qdio_data->establish_timeout(cdev);
+	wake_up(&cdev->private->wait_q);
+}
+
+static void
+ccw_device_qdio_cleanup_irq(struct ccw_device *cdev,
+			    enum dev_event dev_event)
+{
+	struct irb *irb;
+	struct subchannel *sch;
+
+	irb = (struct irb *) __LC_IRB;
+	/* Check for unsolicited interrupt. */
+	if (irb->scsw.stctl ==
+	    		(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
+		if (cdev->private->qdio_data && 
+		    cdev->private->qdio_data->cleanup_irq)
+			cdev->private->qdio_data->cleanup_irq(cdev, 0, irb);
+		wake_up(&cdev->private->wait_q);
+		return;
+	}
+	ccw_device_accumulate_irb(cdev, irb);
+	//FIXME: Basic sense?
+	sch = to_subchannel(cdev->dev.parent);
+	if (cdev->private->qdio_data && cdev->private->qdio_data->cleanup_irq)
+		cdev->private->qdio_data->cleanup_irq(cdev, sch->u_intparm,
+						      &cdev->private->irb);
+	wake_up(&cdev->private->wait_q);
+}
+
+static void
+ccw_device_qdio_cleanup_timeout(struct ccw_device *cdev,
+				enum dev_event dev_event)
+{
+	ccw_device_set_timeout(cdev, 0);
+	if (cdev->private->qdio_data &&
+	    cdev->private->qdio_data->cleanup_timeout)
+		cdev->private->qdio_data->cleanup_timeout(cdev);
+	wake_up(&cdev->private->wait_q);
+}
+
+/*
+ * device statemachine
+ */
+fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = {
+	[DEV_STATE_NOT_OPER] {
+		[DEV_EVENT_NOTOPER]	ccw_device_nop,
+		[DEV_EVENT_INTERRUPT]	ccw_device_bug,
+		[DEV_EVENT_TIMEOUT]	ccw_device_nop,
+		[DEV_EVENT_VERIFY]	ccw_device_nop,
+	},
+	[DEV_STATE_SENSE_PGID] {
+		[DEV_EVENT_NOTOPER]	ccw_device_recog_notoper,
+		[DEV_EVENT_INTERRUPT]	ccw_device_sense_pgid_irq,
+		[DEV_EVENT_TIMEOUT]	ccw_device_recog_timeout,
+		[DEV_EVENT_VERIFY]	ccw_device_nop,
+	},
+	[DEV_STATE_SENSE_ID] {
+		[DEV_EVENT_NOTOPER]	ccw_device_recog_notoper,
+		[DEV_EVENT_INTERRUPT]	ccw_device_sense_id_irq,
+		[DEV_EVENT_TIMEOUT]	ccw_device_recog_timeout,
+		[DEV_EVENT_VERIFY]	ccw_device_nop,
+	},
+	[DEV_STATE_OFFLINE] {
+		[DEV_EVENT_NOTOPER]	ccw_device_offline_notoper,
+		[DEV_EVENT_INTERRUPT]	ccw_device_bug,
+		[DEV_EVENT_TIMEOUT]	ccw_device_nop,
+		[DEV_EVENT_VERIFY]	ccw_device_nop,
+	},
+	[DEV_STATE_VERIFY] {
+		[DEV_EVENT_NOTOPER]	ccw_device_online_notoper,
+		[DEV_EVENT_INTERRUPT]	ccw_device_verify_irq,
+		[DEV_EVENT_TIMEOUT]	ccw_device_onoff_timeout,
+		[DEV_EVENT_VERIFY]	ccw_device_nop,
+	},
+	[DEV_STATE_ONLINE] {
+		[DEV_EVENT_NOTOPER]	ccw_device_online_notoper,
+		[DEV_EVENT_INTERRUPT]	ccw_device_irq,
+		[DEV_EVENT_TIMEOUT]	ccw_device_nop,
+		[DEV_EVENT_VERIFY]	ccw_device_online_verify,
+	},
+	[DEV_STATE_W4SENSE] {
+		[DEV_EVENT_NOTOPER]	ccw_device_online_notoper,
+		[DEV_EVENT_INTERRUPT]	ccw_device_w4sense,
+		[DEV_EVENT_TIMEOUT]	ccw_device_nop,
+		[DEV_EVENT_VERIFY]	ccw_device_online_verify,
+	},
+	[DEV_STATE_DISBAND_PGID] {
+		[DEV_EVENT_NOTOPER]	ccw_device_online_notoper,
+		[DEV_EVENT_INTERRUPT]	ccw_device_disband_irq,
+		[DEV_EVENT_TIMEOUT]	ccw_device_onoff_timeout,
+		[DEV_EVENT_VERIFY]	ccw_device_nop,
+	},
+	[DEV_STATE_BOXED] {
+		[DEV_EVENT_NOTOPER]	ccw_device_offline_notoper,
+		[DEV_EVENT_INTERRUPT]	ccw_device_bug,
+		[DEV_EVENT_TIMEOUT]	ccw_device_nop,
+		[DEV_EVENT_VERIFY]	ccw_device_nop,
+	},
+	/* special states for qdio */
+	[DEV_STATE_QDIO_INIT] {
+		[DEV_EVENT_NOTOPER]     ccw_device_online_notoper,
+		[DEV_EVENT_INTERRUPT]   ccw_device_qdio_init_irq,
+		[DEV_EVENT_TIMEOUT]     ccw_device_qdio_init_timeout,
+		[DEV_EVENT_VERIFY]      ccw_device_nop, //FIXME
+	},
+	[DEV_STATE_QDIO_ACTIVE] {
+		[DEV_EVENT_NOTOPER]     ccw_device_online_notoper,
+		[DEV_EVENT_INTERRUPT]   ccw_device_irq,
+		[DEV_EVENT_TIMEOUT]     ccw_device_nop,
+		[DEV_EVENT_VERIFY]      ccw_device_nop, //FIXME
+	},
+	[DEV_STATE_QDIO_CLEANUP] {
+		[DEV_EVENT_NOTOPER]     ccw_device_online_notoper,
+		[DEV_EVENT_INTERRUPT]   ccw_device_qdio_cleanup_irq,
+		[DEV_EVENT_TIMEOUT]     ccw_device_qdio_cleanup_timeout,
+		[DEV_EVENT_VERIFY]      ccw_device_nop, //FIXME
+	},
+	/* states to wait for i/o completion before doing something */
+	[DEV_STATE_ONLINE_VERIFY] {
+		[DEV_EVENT_NOTOPER]	ccw_device_online_notoper,
+		[DEV_EVENT_INTERRUPT]	ccw_device_irq_verify,
+		[DEV_EVENT_TIMEOUT]	ccw_device_nop,
+		[DEV_EVENT_VERIFY]	ccw_device_nop,
+	},
+	[DEV_STATE_W4SENSE_VERIFY] {
+		[DEV_EVENT_NOTOPER]	ccw_device_online_notoper,
+		[DEV_EVENT_INTERRUPT]	ccw_device_w4sense_verify,
+		[DEV_EVENT_TIMEOUT]	ccw_device_nop,
+		[DEV_EVENT_VERIFY]	ccw_device_nop,
+	},
+};
+
+/*
+ * io_subchannel_irq is called for "real" interrupts or for status
+ * pending conditions on msch.
+ */
+void
+io_subchannel_irq (struct device *pdev)
+{
+	char dbf_txt[15];
+	struct ccw_device *cdev;
+
+	cdev = to_subchannel(pdev)->dev.driver_data;
+
+	sprintf (dbf_txt, "IRQ%04x", cdev->private->irq);
+	CIO_TRACE_EVENT (3, dbf_txt);
+
+	dev_fsm_event(cdev, DEV_EVENT_INTERRUPT);
+}
+
diff -Nru a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/cio/device_id.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,341 @@
+/*
+ * drivers/s390/cio/device_id.c
+ *
+ *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
+ *			 IBM Corporation
+ *    Author(s): Cornelia Huck(cohuck@de.ibm.com)
+ *		 Martin Schwidefsky (schwidefsky@de.ibm.com)
+ *
+ * Sense ID functions.
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/ccwdev.h>
+#include <asm/delay.h>
+#include <asm/cio.h>
+
+#include "cio.h"
+#include "cio_debug.h"
+#include "css.h"
+#include "device.h"
+
+/*
+ * diag210 is used under VM to get information about a virtual device
+ */
+#ifdef CONFIG_ARCH_S390X
+int
+diag210(struct diag210 * addr)
+{
+	/*
+	 * diag 210 needs its data below the 2GB border, so we
+	 * use a static data area to be sure
+	 */
+	static struct diag210 diag210_tmp;
+	static spinlock_t diag210_lock = SPIN_LOCK_UNLOCKED;
+	unsigned long flags;
+	int ccode;
+
+	spin_lock_irqsave(&diag210_lock, flags);
+	diag210_tmp = *addr;
+
+	asm volatile (
+		"   lhi	  %0,-1\n"
+		"   sam31\n"
+		"   diag  %1,0,0x210\n"
+		"0: ipm	  %0\n"
+		"   srl	  %0,28\n"
+		"1: sam64\n"
+		".section __ex_table,\"a\"\n"
+		"    .align 8\n"
+		"    .quad 0b,1b\n"
+		".previous"
+		: "=&d" (ccode) : "a" (__pa(&diag210_tmp)) : "cc", "memory" );
+
+	*addr = diag210_tmp;
+	spin_unlock_irqrestore(&diag210_lock, flags);
+
+	return ccode;
+}
+#else
+int
+diag210(struct diag210 * addr)
+{
+	int ccode;
+
+	asm volatile (
+		"   lhi	  %0,-1\n"
+		"   diag  %1,0,0x210\n"
+		"0: ipm	  %0\n"
+		"   srl	  %0,28\n"
+		"1:\n"
+		".section __ex_table,\"a\"\n"
+		"    .align 4\n"
+		"    .long 0b,1b\n"
+		".previous"
+		: "=&d" (ccode) : "a" (__pa(addr)) : "cc", "memory" );
+
+	return ccode;
+}
+#endif
+
+/*
+ * Input :
+ *   devno - device number
+ *   ps	   - pointer to sense ID data area
+ * Output : none
+ */
+static void
+VM_virtual_device_info (__u16 devno, struct senseid *ps)
+{
+	static struct {
+		int vrdcvcla, vrdcvtyp, cu_type;
+	} vm_devices[] = {
+		{ 0x08, 0x01, 0x3480 },
+		{ 0x08, 0x02, 0x3430 },
+		{ 0x08, 0x10, 0x3420 },
+		{ 0x08, 0x42, 0x3424 },
+		{ 0x08, 0x44, 0x9348 },
+		{ 0x08, 0x81, 0x3490 },
+		{ 0x08, 0x82, 0x3422 },
+		{ 0x10, 0x41, 0x1403 },
+		{ 0x10, 0x42, 0x3211 },
+		{ 0x10, 0x43, 0x3203 },
+		{ 0x10, 0x45, 0x3800 },
+		{ 0x10, 0x47, 0x3262 },
+		{ 0x10, 0x48, 0x3820 },
+		{ 0x10, 0x49, 0x3800 },
+		{ 0x10, 0x4a, 0x4245 },
+		{ 0x10, 0x4b, 0x4248 },
+		{ 0x10, 0x4d, 0x3800 },
+		{ 0x10, 0x4e, 0x3820 },
+		{ 0x10, 0x4f, 0x3820 },
+		{ 0x10, 0x82, 0x2540 },
+		{ 0x10, 0x84, 0x3525 },
+		{ 0x20, 0x81, 0x2501 },
+		{ 0x20, 0x82, 0x2540 },
+		{ 0x20, 0x84, 0x3505 },
+		{ 0x40, 0x01, 0x3278 },
+		{ 0x40, 0x04, 0x3277 },
+		{ 0x40, 0x80, 0x2250 },
+		{ 0x40, 0xc0, 0x5080 },
+		{ 0x80, 0x00, 0x3215 },
+	};
+	struct diag210 diag_data;
+	int ccode, i;
+
+	CIO_TRACE_EVENT (4, "VMvdinf");
+
+	diag_data = (struct diag210) {
+		.vrdcdvno = devno,
+		.vrdclen = sizeof (diag_data),
+	};
+
+	ccode = diag210 (&diag_data);
+	ps->reserved = 0xff;
+
+	/* Special case for bloddy osa devices. */
+	if (diag_data.vrdcvcla == 0x02 &&
+	    diag_data.vrdcvtyp == 0x20) {
+		ps->cu_type = 0x3088;
+		ps->cu_model = 0x60;
+		return;
+	}
+	for (i = 0; i < sizeof(vm_devices) / sizeof(vm_devices[0]); i++)
+		if (diag_data.vrdcvcla == vm_devices[i].vrdcvcla &&
+		    diag_data.vrdcvtyp == vm_devices[i].vrdcvtyp) {
+			ps->cu_type = vm_devices[i].cu_type;
+			return;
+		}
+	CIO_MSG_EVENT(0, "DIAG X'210' for device %04X returned (cc = %d):"
+		      "vdev class : %02X, vdev type : %04X \n ...  "
+		      "rdev class : %02X, rdev type : %04X, "
+		      "rdev model: %02X\n",
+		      devno, ccode,
+		      diag_data.vrdcvcla, diag_data.vrdcvtyp,
+		      diag_data.vrdcrccl, diag_data.vrdccrty,
+		      diag_data.vrdccrmd);
+}
+
+/*
+ * Start Sense ID helper function.
+ * Try to obtain the 'control unit'/'device type' information
+ *  associated with the subchannel.
+ */
+static int
+__ccw_device_sense_id_start(struct ccw_device *cdev)
+{
+	struct subchannel *sch;
+	struct ccw1 *ccw;
+	int ret;
+
+	sch = to_subchannel(cdev->dev.parent);
+	/* Setup sense channel program. */
+	ccw = cdev->private->iccws;
+	if (sch->schib.pmcw.pim != 0x80) {
+		/* more than one path installed. */
+		ccw->cmd_code = CCW_CMD_SUSPEND_RECONN;
+		ccw->cda = 0;
+		ccw->count = 0;
+		ccw->flags = CCW_FLAG_SLI | CCW_FLAG_CC;
+		ccw++;
+	}
+	ccw->cmd_code = CCW_CMD_SENSE_ID;
+	ccw->cda = (__u32) __pa (&cdev->private->senseid);
+	ccw->count = sizeof (struct senseid);
+	ccw->flags = CCW_FLAG_SLI;
+
+	/* Reset device status. */
+	memset(&cdev->private->irb, 0, sizeof(struct irb));
+
+	/* Try on every path. */
+	ret = -ENODEV;
+	while (cdev->private->imask != 0) {
+		if ((sch->lpm & cdev->private->imask) != 0 &&
+		    cdev->private->iretry-- > 0) {
+			/* 0x00E2C9C4 == ebcdic "SID" */
+			ret = cio_start (sch, cdev->private->iccws,
+					 0x00E2C9C4, cdev->private->imask);
+			/* ret is 0, -EBUSY or -ENODEV */
+			if (ret != -EBUSY)
+				return ret;
+			udelay(100);
+			continue;
+		}
+		cdev->private->imask >>= 1;
+		cdev->private->iretry = 5;
+	}
+	return ret;
+}
+
+void
+ccw_device_sense_id_start(struct ccw_device *cdev)
+{
+	int ret;
+
+	memset (&cdev->private->senseid, 0, sizeof (struct senseid));
+	cdev->private->senseid.cu_type = 0xFFFF;
+	cdev->private->imask = 0x80;
+	cdev->private->iretry = 5;
+	ret = __ccw_device_sense_id_start(cdev);
+	if (ret)
+		ccw_device_sense_id_done(cdev, ret);
+}
+
+/*
+ * Called from interrupt context to check if a valid answer
+ * to Sense ID was received.
+ */
+static int
+ccw_device_check_sense_id(struct ccw_device *cdev)
+{
+	struct subchannel *sch;
+	struct irb *irb;
+
+	sch = to_subchannel(cdev->dev.parent);
+	irb = &cdev->private->irb;
+	/* Did we get a proper answer ? */
+	if (cdev->private->senseid.cu_type != 0xFFFF && 
+	    cdev->private->senseid.reserved == 0xFF) {
+		if (irb->scsw.count < sizeof (struct senseid) - 8)
+			cdev->private->flags.esid = 1;
+		return 0; /* Success */
+	}
+	/* Check the error cases. */
+	if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC))
+		return -ETIME;
+	if (irb->esw.esw0.erw.cons &&
+	    (irb->ecw[0] & (SNS0_CMD_REJECT | SNS0_INTERVENTION_REQ))) {
+		/*
+		 * if the device doesn't support the SenseID
+		 *  command further retries wouldn't help ...
+		 */
+		CIO_MSG_EVENT(2, "SenseID : device %04X on Subchannel %04X "
+			      "reports cmd reject or intervention required\n",
+			      sch->schib.pmcw.dev, sch->irq);
+		return -EOPNOTSUPP;
+	}
+	if (irb->esw.esw0.erw.cons) {
+		CIO_MSG_EVENT(2, "SenseID : UC on dev %04X, "
+			      "lpum %02X, cnt %02d, sns :"
+			      " %02X%02X%02X%02X %02X%02X%02X%02X ...\n",
+			      sch->schib.pmcw.dev,
+			      irb->esw.esw0.sublog.lpum,
+			      irb->esw.esw0.erw.scnt,
+			      irb->ecw[0], irb->ecw[1],
+			      irb->ecw[2], irb->ecw[3],
+			      irb->ecw[4], irb->ecw[5],
+			      irb->ecw[6], irb->ecw[7]);
+		return -EAGAIN;
+	}
+	if (irb->scsw.cc == 3) {
+		CIO_MSG_EVENT(2, "SenseID : path %02X for device %04X on "
+			      "subchannel %04X is 'not operational'\n",
+			      sch->orb.lpm, sch->schib.pmcw.dev, sch->irq);
+		return -EACCES;
+	}
+	/* Hmm, whatever happened, try again. */
+	CIO_MSG_EVENT(2, "SenseID : start_IO() for device %04X on "
+		      "subchannel %04X returns status %02X%02X\n",
+		      sch->schib.pmcw.dev, sch->irq,
+		      irb->scsw.dstat, irb->scsw.cstat);
+	return -EAGAIN;
+}
+
+/*
+ * Got interrupt for Sense ID.
+ */
+void
+ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event)
+{
+	struct subchannel *sch;
+	struct irb *irb;
+	int ret;
+
+	sch = to_subchannel(cdev->dev.parent);
+	irb = (struct irb *) __LC_IRB;
+	/* Ignore unsolicited interrupts. */
+	if (irb->scsw.stctl ==
+	    		(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS))
+		return;
+
+	if (ccw_device_accumulate_and_sense(cdev, irb) != 0)
+		return;
+	ret = ccw_device_check_sense_id(cdev);
+	switch (ret) {
+	/* 0, -ETIME, -EOPNOTSUPP, -EAGAIN or -EACCES */
+	case 0:			/* Sense id succeeded. */
+	case -ETIME:		/* Sense id stopped by timeout. */
+		ccw_device_sense_id_done(cdev, ret);
+		break;
+	case -EACCES:		/* channel is not operational. */
+		sch->lpm &= ~cdev->private->imask;
+		cdev->private->imask >>= 1;
+		cdev->private->iretry = 5;
+		/* fall through. */
+	case -EAGAIN:		/* try again. */
+		ret = __ccw_device_sense_id_start(cdev);
+		if (ret == 0 || ret == -EBUSY)
+			break;
+		/* fall through. */
+	default:		/* Sense ID failed. Try asking VM. */
+		if (MACHINE_IS_VM) {
+			VM_virtual_device_info (cdev->private->devno,
+						&cdev->private->senseid);
+			if (cdev->private->senseid.cu_type != 0xFFFF) {
+				/* Got the device information from VM. */
+				ccw_device_sense_id_done(cdev, 0);
+				return;
+			}
+		}
+		/*
+		 * If we can't couldn't identify the device type we
+		 *  consider the device "not operational".
+		 */
+		ccw_device_sense_id_done(cdev, -ENODEV);
+		break;
+	}
+}
+
diff -Nru a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/cio/device_ops.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,365 @@
+/*
+ *  drivers/s390/cio/device_ops.c
+ *
+ *   $Revision: 1.34 $
+ *
+ *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
+ *			 IBM Corporation
+ *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/device.h>
+
+#include <asm/ccwdev.h>
+#include <asm/idals.h>
+#include <asm/qdio.h>
+
+#include "cio.h"
+#include "cio_debug.h"
+#include "css.h"
+#include "device.h"
+#include "qdio.h"
+
+int
+ccw_device_set_options(struct ccw_device *cdev, unsigned long flags)
+{
+       /*
+	* The flag usage is mutal exclusive ...
+	*/
+	if ((flags & CCWDEV_EARLY_NOTIFICATION) &&
+	    (flags & CCWDEV_REPORT_ALL))
+		return -EINVAL;
+	cdev->private->options.fast = (flags & CCWDEV_EARLY_NOTIFICATION) != 0;
+	cdev->private->options.repall = (flags & CCWDEV_REPORT_ALL) != 0;
+	return 0;
+}
+
+int
+ccw_device_clear(struct ccw_device *cdev, unsigned long intparm)
+{
+	struct subchannel *sch;
+	int ret;
+
+	if (!cdev)
+		return -ENODEV;
+	if (cdev->private->state != DEV_STATE_ONLINE &&
+	    cdev->private->state != DEV_STATE_W4SENSE)
+		return -EINVAL;
+	sch = to_subchannel(cdev->dev.parent);
+	if (!sch)
+		return -ENODEV;
+	ret = cio_clear(sch, intparm);
+	return ret;
+}
+
+int
+ccw_device_start(struct ccw_device *cdev, struct ccw1 *cpa,
+		 unsigned long intparm, __u8 lpm, unsigned long flags)
+{
+	struct subchannel *sch;
+	int ret;
+
+	if (!cdev)
+		return -ENODEV;
+	if (cdev->private->state != DEV_STATE_ONLINE &&
+	    cdev->private->state != DEV_STATE_W4SENSE &&
+	    cdev->private->state != DEV_STATE_QDIO_INIT)
+		return -EINVAL;
+	sch = to_subchannel(cdev->dev.parent);
+	if (!sch)
+		return -ENODEV;
+	ret = cio_set_options (sch, flags);
+	if (ret)
+		return ret;
+	ret = cio_start (sch, cpa, intparm, lpm);
+	return ret;
+}
+
+int
+ccw_device_halt(struct ccw_device *cdev, unsigned long intparm)
+{
+	struct subchannel *sch;
+	int ret;
+
+	if (!cdev)
+		return -ENODEV;
+	if (cdev->private->state != DEV_STATE_ONLINE &&
+	    cdev->private->state != DEV_STATE_W4SENSE)
+		return -EINVAL;
+	sch = to_subchannel(cdev->dev.parent);
+	if (!sch)
+		return -ENODEV;
+	ret = cio_halt(sch, intparm);
+	return ret;
+}
+
+int
+ccw_device_resume(struct ccw_device *cdev)
+{
+	struct subchannel *sch;
+
+	if (!cdev)
+		return -ENODEV;
+	if (cdev->private->state != DEV_STATE_ONLINE &&
+	    cdev->private->state != DEV_STATE_W4SENSE)
+		return -EINVAL;
+	sch = to_subchannel(cdev->dev.parent);
+	if (!sch)
+		return -ENODEV;
+	return cio_resume(sch);
+}
+
+/*
+ * Pass interrupt to device driver.
+ */
+void
+ccw_device_call_handler(struct ccw_device *cdev)
+{
+	struct subchannel *sch;
+	unsigned int stctl;
+
+	sch = to_subchannel(cdev->dev.parent);
+
+	/*
+	 * we allow for the device action handler if .
+	 *  - we received ending status
+	 *  - the action handler requested to see all interrupts
+	 *  - we received an intermediate status
+	 *  - fast notification was requested (primary status)
+	 *  - unsolicited interrupts
+	 */
+	stctl = cdev->private->irb.scsw.stctl;
+	if (sch->schib.scsw.actl != 0 &&
+	    !cdev->private->options.repall &&
+	    !(stctl & SCSW_STCTL_INTER_STATUS) &&
+	    !(cdev->private->options.fast &&
+	      (stctl & SCSW_STCTL_PRIM_STATUS)))
+		return;
+
+	/*
+	 * Now we are ready to call the device driver interrupt handler.
+	 */
+	if (cdev->private->state == DEV_STATE_QDIO_ACTIVE) {
+		if (cdev->private->qdio_data &&
+		    cdev->private->qdio_data->handler)
+			cdev->private->qdio_data->handler(cdev, sch->u_intparm,
+							  &cdev->private->irb);
+	} else
+		cdev->handler (cdev, sch->u_intparm, &cdev->private->irb);
+	/*
+	 * Clear the old and now useless interrupt response block.
+	 */
+	memset(&cdev->private->irb, 0, sizeof(struct irb));
+}
+
+/*
+ * Search for CIW command in extended sense data.
+ */
+struct ciw *
+ccw_device_get_ciw(struct ccw_device *cdev, __u32 ct)
+{
+	int ciw_cnt;
+
+	for (ciw_cnt = 0; ciw_cnt < MAX_CIWS; ciw_cnt++)
+		if (cdev->private->senseid.ciw[ciw_cnt].ct == ct)
+			return cdev->private->senseid.ciw + ciw_cnt;
+	return NULL;
+}
+
+__u8
+ccw_device_get_path_mask(struct ccw_device *cdev)
+{
+	struct subchannel *sch;
+
+	sch = to_subchannel(cdev->dev.parent);
+	if (!sch)
+		return 0;
+	else
+		return sch->vpm;
+}
+
+static void
+ccw_device_wake_up(struct ccw_device *cdev, unsigned long ip, struct irb *irb)
+{
+	wake_up(&cdev->private->wait_q);
+}
+
+/*
+ * This routine returns the characteristics for the device
+ *  specified. Some old devices might not provide the necessary
+ *  command code information during SenseID processing. In this
+ *  case the function returns -EINVAL. Otherwise the function
+ *  allocates a decice specific data buffer and provides the
+ *  device characteristics together with the buffer size. Its
+ *  the callers responability to release the kernel memory if
+ *  not longer needed. In case of persistent I/O problems -EBUSY
+ *  is returned.
+ */
+int
+read_dev_chars (struct ccw_device *cdev, void **buffer, int length)
+{
+	void (*handler)(struct ccw_device *, unsigned long, struct irb *);
+	char dbf_txt[15];
+	unsigned long flags;
+	struct subchannel *sch;
+	int retry;
+	int ret;
+
+	if (!cdev)
+		return -ENODEV;
+	if (cdev->private->state != DEV_STATE_ONLINE &&
+	    cdev->private->state != DEV_STATE_W4SENSE)
+		return -EINVAL;
+	if (!buffer || !length)
+		return -EINVAL;
+	sch = to_subchannel(cdev->dev.parent);
+
+	sprintf (dbf_txt, "rddevch%x", sch->irq);
+	CIO_TRACE_EVENT (4, dbf_txt);
+
+	cdev->private->iccws[0].cmd_code = CCW_CMD_RDC;
+	cdev->private->iccws[0].count = length;
+	cdev->private->iccws[0].flags = CCW_FLAG_SLI;
+	ret = set_normalized_cda (cdev->private->iccws, (*buffer));
+	if (ret != 0)
+		return ret;
+
+	spin_lock_irqsave(&sch->lock, flags);
+	/* Save interrupt handler. */
+	handler = cdev->handler;
+	/* Temporarily install own handler. */
+	cdev->handler = ccw_device_wake_up;
+	for (retry = 5; retry > 0; retry--) {
+		/* 0x00524443 == ebcdic "RDC" */
+		ret = cio_start (sch, cdev->private->iccws, 0x00524443, 0);
+		if (ret == -ENODEV)
+			break;
+		if (ret == 0) {
+			/* Wait for end of request. */
+			spin_unlock_irqrestore(&sch->lock, flags);
+			wait_event(cdev->private->wait_q,
+				   sch->schib.scsw.actl == 0);
+			spin_lock_irqsave(&sch->lock, flags);
+		}
+	}
+	/* Restore interrupt handler. */
+	cdev->handler = handler;
+	spin_unlock_irqrestore(&sch->lock, flags);
+
+	clear_normalized_cda (cdev->private->iccws);
+
+	return ret;
+}
+
+/*
+ *  Read Configuration data
+ */
+int
+read_conf_data (struct ccw_device *cdev, void **buffer, int *length)
+{
+	void (*handler)(struct ccw_device *, unsigned long, struct irb *);
+	char dbf_txt[15];
+	struct subchannel *sch;
+	struct ciw *ciw;
+	unsigned long flags;
+	char *rcd_buf;
+	int retry;
+	int ret;
+
+	if (!cdev)
+		return -ENODEV;
+	if (cdev->private->state != DEV_STATE_ONLINE &&
+	    cdev->private->state != DEV_STATE_W4SENSE)
+		return -EINVAL;
+	if (cdev->private->flags.esid == 0)
+		return -EOPNOTSUPP;
+	if (!buffer || !length)
+		return -EINVAL;
+	sch = to_subchannel(cdev->dev.parent);
+
+	sprintf (dbf_txt, "rdconf%x", sch->irq);
+	CIO_TRACE_EVENT (4, dbf_txt);
+
+	/*
+	 * scan for RCD command in extended SenseID data
+	 */
+	ciw = ccw_device_get_ciw(cdev, CIW_TYPE_RCD);
+	if (!ciw || ciw->cmd == 0)
+		return -EOPNOTSUPP;
+
+	rcd_buf = kmalloc(ciw->count, GFP_DMA);
+ 	if (!rcd_buf)
+		return -ENOMEM;
+ 	memset (rcd_buf, 0, ciw->count);
+	cdev->private->iccws[0].cmd_code = ciw->cmd;
+	cdev->private->iccws[0].cda = (__u32) __pa (rcd_buf);
+	cdev->private->iccws[0].count = ciw->count;
+	cdev->private->iccws[0].flags = CCW_FLAG_SLI;
+
+	spin_lock_irqsave(&sch->lock, flags);
+	/* Save interrupt handler. */
+	handler = cdev->handler;
+	/* Temporarily install own handler. */
+	cdev->handler = ccw_device_wake_up;
+	for (ret = 0, retry = 5; retry > 0; retry--) {
+		/* 0x00524344 == ebcdic "RCD" */
+		ret = cio_start (sch, cdev->private->iccws, 0x00524344, 0);
+		if (ret == -ENODEV)
+			break;
+		if (ret)
+			continue;
+		/* Wait for end of request. */
+		spin_unlock_irqrestore(&sch->lock, flags);
+		wait_event(cdev->private->wait_q, sch->schib.scsw.actl == 0);
+		spin_lock_irqsave(&sch->lock, flags);
+	}
+	/* Restore interrupt handler. */
+	cdev->handler = handler;
+	spin_unlock_irqrestore(&sch->lock, flags);
+
+ 	/*
+ 	 * on success we update the user input parms
+ 	 */
+ 	if (ret) {
+ 		kfree (rcd_buf);
+ 		*buffer = NULL;
+ 		*length = 0;
+ 	} else {
+		*length = ciw->count;
+		*buffer = rcd_buf;
+	}
+
+	return ret;
+}
+
+// FIXME: these have to go:
+
+int
+_ccw_device_get_subchannel_number(struct ccw_device *cdev)
+{
+	return cdev->private->irq;
+}
+
+int
+_ccw_device_get_device_number(struct ccw_device *cdev)
+{
+	return cdev->private->devno;
+}
+
+
+MODULE_LICENSE("GPL");
+EXPORT_SYMBOL(ccw_device_clear);
+EXPORT_SYMBOL(ccw_device_halt);
+EXPORT_SYMBOL(ccw_device_resume);
+EXPORT_SYMBOL(ccw_device_start);
+EXPORT_SYMBOL(ccw_device_get_ciw);
+EXPORT_SYMBOL(ccw_device_get_path_mask);
+EXPORT_SYMBOL (read_conf_data);
+EXPORT_SYMBOL (read_dev_chars);
+EXPORT_SYMBOL(_ccw_device_get_subchannel_number);
+EXPORT_SYMBOL(_ccw_device_get_device_number);
diff -Nru a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/cio/device_pgid.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,431 @@
+/*
+ * drivers/s390/cio/device_pgid.c
+ *
+ *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
+ *			 IBM Corporation
+ *    Author(s): Cornelia Huck(cohuck@de.ibm.com)
+ *		 Martin Schwidefsky (schwidefsky@de.ibm.com)
+ *
+ * Path Group ID functions.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <asm/ccwdev.h>
+#include <asm/cio.h>
+#include <asm/delay.h>
+
+#include "cio.h"
+#include "cio_debug.h"
+#include "css.h"
+#include "device.h"
+
+/*
+ * Start Sense Path Group ID helper function. Used in ccw_device_recog
+ * and ccw_device_sense_pgid.
+ */
+static int
+__ccw_device_sense_pgid_start(struct ccw_device *cdev)
+{
+	struct subchannel *sch;
+	struct ccw1 *ccw;
+	int ret;
+
+	sch = to_subchannel(cdev->dev.parent);
+	/* Setup sense path group id channel program. */
+	ccw = cdev->private->iccws;
+	ccw->cmd_code = CCW_CMD_SENSE_PGID;
+	ccw->cda = (__u32) __pa (&cdev->private->pgid);
+	ccw->count = sizeof (struct pgid);
+	ccw->flags = CCW_FLAG_SLI;
+
+	/* Reset device status. */
+	memset(&cdev->private->irb, 0, sizeof(struct irb));
+	/* Try on every path. */
+	ret = -ENODEV;
+	while (cdev->private->imask != 0) {
+		/* Try every path multiple times. */
+		if (cdev->private->iretry-- > 0) {
+			/* 0xe2d5c9c4 == ebcdic "SNID" */
+			ret = cio_start (sch, cdev->private->iccws, 
+					 0xE2D5C9C4, cdev->private->imask);
+			/* ret is 0, -EBUSY or -ENODEV */
+			if (ret != -EBUSY)
+				return ret;
+			CIO_MSG_EVENT(2, "SNID - device %04X, start_io() "
+				      "reports rc : %d, retrying ...\n",
+				      sch->schib.pmcw.dev, ret);
+			udelay(100);
+			continue;
+		}
+		cdev->private->imask >>= 1;
+		cdev->private->iretry = 5;
+	}
+	return ret;
+}
+
+void
+ccw_device_sense_pgid_start(struct ccw_device *cdev)
+{
+	int ret;
+
+	cdev->private->state = DEV_STATE_SENSE_PGID;
+	cdev->private->imask = 0x80;
+	cdev->private->iretry = 5;
+	cdev->private->flags.pgid_supp = 0;
+	memset (&cdev->private->pgid, 0, sizeof (struct pgid));
+	ret = __ccw_device_sense_pgid_start(cdev);
+	if (ret)
+		ccw_device_sense_pgid_done(cdev, ret);
+}
+
+/*
+ * Called from interrupt context to check if a valid answer
+ * to Sense Path Group ID was received.
+ */
+static int
+__ccw_device_check_sense_pgid(struct ccw_device *cdev)
+{
+	struct subchannel *sch;
+	struct irb *irb;
+
+	sch = to_subchannel(cdev->dev.parent);
+	irb = &cdev->private->irb;
+	if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC))
+		return -ETIME;
+	if (irb->esw.esw0.erw.cons &&
+	    (irb->ecw[0]&(SNS0_CMD_REJECT|SNS0_INTERVENTION_REQ))) {
+		/*
+		 * If the device doesn't support the Sense Path Group ID
+		 *  command further retries wouldn't help ...
+		 */
+		return -EOPNOTSUPP;
+	}
+	if (irb->esw.esw0.erw.cons) {
+		CIO_MSG_EVENT(2, "SNID - device %04X, unit check, "
+			      "lpum %02X, cnt %02d, sns : "
+			      "%02X%02X%02X%02X %02X%02X%02X%02X ...\n",
+			      sch->schib.pmcw.dev,
+			      irb->esw.esw0.sublog.lpum,
+			      irb->esw.esw0.erw.scnt,
+			      irb->ecw[0], irb->ecw[1],
+			      irb->ecw[2], irb->ecw[3],
+			      irb->ecw[4], irb->ecw[5],
+			      irb->ecw[6], irb->ecw[7]);
+		return -EAGAIN;
+	}
+	if (irb->scsw.cc == 3) {
+		CIO_MSG_EVENT(2, "SNID - Device %04X on Subchannel "
+			      "%04X, lpm %02X, became 'not "
+			      "operational'\n",
+			      sch->schib.pmcw.dev, sch->irq, sch->orb.lpm);
+		return -EACCES;
+	}
+	if (cdev->private->pgid.inf.ps.state2 == SNID_STATE2_RESVD_ELSE) {
+		CIO_MSG_EVENT(2, "SNID - Device %04X on Subchannel %04X "
+			      "is reserved by someone else\n",
+			      sch->schib.pmcw.dev, sch->irq);
+		return -EUSERS;
+	}
+	return 0;
+}
+
+/*
+ * Got interrupt for Sense Path Group ID.
+ */
+void
+ccw_device_sense_pgid_irq(struct ccw_device *cdev, enum dev_event dev_event)
+{
+	struct subchannel *sch;
+	struct irb *irb;
+	int ret;
+
+	irb = (struct irb *) __LC_IRB;
+	/* Ignore unsolicited interrupts. */
+	if (irb->scsw.stctl ==
+	    		(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS))
+		return;
+	if (ccw_device_accumulate_and_sense(cdev, irb) != 0)
+		return;
+	sch = to_subchannel(cdev->dev.parent);
+	switch (__ccw_device_check_sense_pgid(cdev)) {
+	/* 0, -ETIME, -EOPNOTSUPP, -EAGAIN, -EACCES or -EUSERS */
+	case 0:			/* Sense Path Group ID successful. */
+		cdev->private->flags.pgid_supp = 1;
+		if (cdev->private->pgid.inf.ps.state1 == SNID_STATE1_RESET)
+			memcpy(&cdev->private->pgid, &global_pgid,
+			       sizeof(struct pgid));
+		/* fall through. */
+	case -EOPNOTSUPP:	/* Sense Path Group ID not supported */
+		ccw_device_sense_pgid_done(cdev, 0);
+		break;
+	case -ETIME:		/* Sense path group id stopped by timeout. */
+		ccw_device_sense_pgid_done(cdev, -ETIME);
+		break;
+	case -EACCES:		/* channel is not operational. */
+		sch->lpm &= ~cdev->private->imask;
+		cdev->private->imask >>= 1;
+		cdev->private->iretry = 5;
+		/* Fall through. */
+	case -EAGAIN:		/* Try again. */
+		ret = __ccw_device_sense_pgid_start(cdev);
+		if (ret != 0 && ret != -EBUSY)
+			ccw_device_sense_pgid_done(cdev, -ENODEV);
+		break;
+	case -EUSERS:		/* device is reserved for someone else. */
+		ccw_device_sense_pgid_done(cdev, -EUSERS);
+		break;
+	}
+}
+
+/*
+ * Path Group ID helper function.
+ */
+static int
+__ccw_device_do_pgid(struct ccw_device *cdev, __u8 func)
+{
+	struct subchannel *sch;
+	struct ccw1 *ccw;
+	int ret;
+
+	sch = to_subchannel(cdev->dev.parent);
+
+	/* Setup sense path group id channel program. */
+	cdev->private->pgid.inf.fc = func;
+	ccw = cdev->private->iccws;
+	if (!cdev->private->flags.pgid_single) {
+		cdev->private->pgid.inf.fc |= SPID_FUNC_MULTI_PATH;
+		ccw->cmd_code = CCW_CMD_SUSPEND_RECONN;
+		ccw->cda = 0;
+		ccw->count = 0;
+		ccw->flags = CCW_FLAG_SLI | CCW_FLAG_CC;
+		ccw++;
+	} else
+		cdev->private->pgid.inf.fc |= SPID_FUNC_SINGLE_PATH;
+
+	ccw->cmd_code = CCW_CMD_SET_PGID;
+	ccw->cda = (__u32) __pa (&cdev->private->pgid);
+	ccw->count = sizeof (struct pgid);
+	ccw->flags = CCW_FLAG_SLI;
+
+	/* Reset device status. */
+	memset(&cdev->private->irb, 0, sizeof(struct irb));
+
+	/* Try multiple times. */
+	ret = -ENODEV;
+	while (cdev->private->iretry-- > 0) {
+		/* 0xE2D7C9C4 == ebcdic "SPID" */
+		ret = cio_start (sch, cdev->private->iccws,
+				 0xE2D7C9C4, cdev->private->imask);
+		/* ret is 0, -EBUSY or -ENODEV */
+		if (ret != -EBUSY)
+			return ret;
+		udelay(100);
+		continue;
+	}
+	/* PGID command failed on this path. Switch it off. */
+	sch->lpm &= ~cdev->private->imask;
+	sch->vpm &= ~cdev->private->imask;
+	CIO_MSG_EVENT(2, "SPID - Device %04X on Subchannel "
+		      "%04X, lpm %02X, became 'not "
+		      "operational'\n",
+		      sch->schib.pmcw.dev, sch->irq,
+		      cdev->private->imask);
+	return ret;
+}
+
+/*
+ * Called from interrupt context to check if a valid answer
+ * to Set Path Group ID was received.
+ */
+static int
+__ccw_device_check_pgid(struct ccw_device *cdev)
+{
+	struct subchannel *sch;
+	struct irb *irb;
+
+	sch = to_subchannel(cdev->dev.parent);
+	irb = &cdev->private->irb;
+	if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC))
+		return -ETIME;
+	if (irb->esw.esw0.erw.cons) {
+		if (irb->ecw[0] & SNS0_CMD_REJECT)
+			return -EOPNOTSUPP;
+		/* Hmm, whatever happened, try again. */
+		CIO_MSG_EVENT(2, "SPID - device %04X, unit check, cnt %02d, "
+			      "sns : %02X%02X%02X%02X %02X%02X%02X%02X ...\n",
+			      sch->schib.pmcw.dev, irb->esw.esw0.erw.scnt,
+			      irb->ecw[0], irb->ecw[1],
+			      irb->ecw[2], irb->ecw[3],
+			      irb->ecw[4], irb->ecw[5],
+			      irb->ecw[6], irb->ecw[7]);
+		return -EAGAIN;
+	}
+	if (irb->scsw.cc == 3) {
+		CIO_MSG_EVENT(2, "SPID - Device %04X on Subchannel "
+			      "%04X, lpm %02X, became 'not "
+			      "operational'\n",
+			      sch->schib.pmcw.dev, sch->irq,
+			      cdev->private->imask);
+		return -EACCES;
+	}
+	return 0;
+}
+
+static void
+__ccw_device_verify_start(struct ccw_device *cdev)
+{
+	struct subchannel *sch;
+	__u8 imask, func;
+	int ret;
+
+	sch = to_subchannel(cdev->dev.parent);
+	while (sch->vpm != sch->lpm) {
+		/* Find first unequal bit in vpm vs. lpm */
+		for (imask = 0x80; imask != 0; imask >>= 1)
+			if ((sch->vpm & imask) != (sch->lpm & imask))
+				break;
+		cdev->private->imask = imask;
+		func = (sch->vpm & imask) ?
+			SPID_FUNC_RESIGN : SPID_FUNC_ESTABLISH;
+		ret = __ccw_device_do_pgid(cdev, func);
+		if (ret == 0)
+			return;
+		cdev->private->iretry = 5;
+	}
+	ccw_device_verify_done(cdev, (sch->lpm != 0) ? 0 : -ENODEV);
+}
+		
+/*
+ * Got interrupt for Set Path Group ID.
+ */
+void
+ccw_device_verify_irq(struct ccw_device *cdev, enum dev_event dev_event)
+{
+	struct subchannel *sch;
+	struct irb *irb;
+
+	irb = (struct irb *) __LC_IRB;
+	/* Ignore unsolicited interrupts. */
+	if (irb->scsw.stctl ==
+	    		(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS))
+		return;
+	if (ccw_device_accumulate_and_sense(cdev, irb) != 0)
+		return;
+	sch = to_subchannel(cdev->dev.parent);
+	switch (__ccw_device_check_pgid(cdev)) {
+	/* 0, -ETIME, -EAGAIN, -EOPNOTSUPP or -EACCES */
+	case 0:
+		/* Establish or Resign Path Group done. Update vpm. */
+		if ((sch->lpm & cdev->private->imask) != 0)
+			sch->vpm |= cdev->private->imask;
+		else
+			sch->vpm &= ~cdev->private->imask;
+		cdev->private->iretry = 5;
+		__ccw_device_verify_start(cdev);
+		break;
+	case -EOPNOTSUPP:
+		/*
+		 * One of those strange devices which claim to be able
+		 * to do multipathing but not for Set Path Group ID.
+		 */
+		cdev->private->flags.pgid_single = 1;
+		/* fall through. */
+	case -EAGAIN:		/* Try again. */
+		__ccw_device_verify_start(cdev);
+		break;
+	case -ETIME:		/* Set path group id stopped by timeout. */
+		ccw_device_verify_done(cdev, -ETIME);
+		break;
+	case -EACCES:		/* channel is not operational. */
+		sch->lpm &= ~cdev->private->imask;
+		sch->vpm &= ~cdev->private->imask;
+		cdev->private->iretry = 5;
+		__ccw_device_verify_start(cdev);
+		break;
+	}
+}
+
+void
+ccw_device_verify_start(struct ccw_device *cdev)
+{
+	cdev->private->flags.pgid_single = 0;
+	cdev->private->iretry = 5;
+	__ccw_device_verify_start(cdev);
+}
+
+static void
+__ccw_device_disband_start(struct ccw_device *cdev)
+{
+	struct subchannel *sch;
+	int ret;
+
+	sch = to_subchannel(cdev->dev.parent);
+	while (cdev->private->imask != 0) {
+		if (sch->lpm & cdev->private->imask) {
+			ret = __ccw_device_do_pgid(cdev, SPID_FUNC_DISBAND);
+			if (ret == 0)
+				return;
+		}
+		cdev->private->iretry = 5;
+		cdev->private->imask >>= 1;
+	}
+	ccw_device_verify_done(cdev, (sch->lpm != 0) ? 0 : -ENODEV);
+}
+
+/*
+ * Got interrupt for Unset Path Group ID.
+ */
+void
+ccw_device_disband_irq(struct ccw_device *cdev, enum dev_event dev_event)
+{
+	struct subchannel *sch;
+	struct irb *irb;
+	int ret;
+
+	irb = (struct irb *) __LC_IRB;
+	/* Ignore unsolicited interrupts. */
+	if (irb->scsw.stctl ==
+	    		(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS))
+		return;
+	if (ccw_device_accumulate_and_sense(cdev, irb) != 0)
+		return;
+	sch = to_subchannel(cdev->dev.parent);
+	ret = __ccw_device_check_pgid(cdev);
+	switch (ret) {
+	/* 0, -ETIME, -EAGAIN, -EOPNOTSUPP or -EACCES */
+	case 0:			/* disband successful. */
+		sch->vpm = 0;
+		ccw_device_disband_done(cdev, ret);
+		break;
+	case -EOPNOTSUPP:
+		/*
+		 * One of those strange devices which claim to be able
+		 * to do multipathing but not for Unset Path Group ID.
+		 */
+		cdev->private->flags.pgid_single = 1;
+		/* fall through. */
+	case -EAGAIN:		/* Try again. */
+		__ccw_device_disband_start(cdev);
+		break;
+	case -ETIME:		/* Set path group id stopped by timeout. */
+		ccw_device_disband_done(cdev, -ETIME);
+		break;
+	case -EACCES:		/* channel is not operational. */
+		cdev->private->imask >>= 1;
+		cdev->private->iretry = 5;
+		__ccw_device_disband_start(cdev);
+		break;
+	}
+}
+
+void
+ccw_device_disband_start(struct ccw_device *cdev)
+{
+	cdev->private->flags.pgid_single = 0;
+	cdev->private->iretry = 5;
+	cdev->private->imask = 0x80;
+	__ccw_device_disband_start(cdev);
+}
diff -Nru a/drivers/s390/cio/device_status.c b/drivers/s390/cio/device_status.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/cio/device_status.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,366 @@
+/*
+ * drivers/s390/cio/device_status.c
+ *
+ *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
+ *			 IBM Corporation
+ *    Author(s): Cornelia Huck(cohuck@de.ibm.com)
+ *		 Martin Schwidefsky (schwidefsky@de.ibm.com)
+ *
+ * Status accumulation and basic sense functions.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <asm/ccwdev.h>
+#include <asm/cio.h>
+
+#include "cio.h"
+#include "cio_debug.h"
+#include "css.h"
+#include "device.h"
+#include "ioasm.h"
+
+/*
+ * Check for any kind of channel or interface control check but don't
+ * issue the message for the console device
+ */
+static inline void
+ccw_device_msg_control_check(struct ccw_device *cdev, struct irb *irb)
+{
+	if (!(irb->scsw.cstat & (SCHN_STAT_CHN_DATA_CHK |
+				 SCHN_STAT_CHN_CTRL_CHK |
+				 SCHN_STAT_INTF_CTRL_CHK)))
+		return;
+		
+	CIO_MSG_EVENT(0, "Channel-Check or Interface-Control-Check "
+		      "received\n"
+		      " ... device %04X on subchannel %04X, dev_stat "
+		      ": %02X sch_stat : %02X\n",
+		      cdev->private->devno, cdev->private->irq,
+		      cdev->private->irb.scsw.dstat,
+		      cdev->private->irb.scsw.cstat);
+
+	if (irb->scsw.cc != 3) {
+		char dbf_text[15];
+
+		sprintf(dbf_text, "chk%x", cdev->private->irq);
+		CIO_TRACE_EVENT(0, dbf_text);
+		CIO_HEX_EVENT(0, &cdev->private->irb, sizeof (struct irb));
+	}
+}
+
+/*
+ * Some paths became not operational (pno bit in scsw is set).
+ */
+static void
+ccw_device_path_notoper(struct ccw_device *cdev)
+{
+	struct subchannel *sch;
+
+	sch = to_subchannel(cdev->dev.parent);
+	stsch (sch->irq, &sch->schib);
+
+	CIO_MSG_EVENT(0, "cio_process_irq(%04X) - path(s) %02x are "
+		      "not operational ", sch->irq, sch->schib.pmcw.pnom);
+
+	sch->lpm &= ~sch->schib.pmcw.pnom;
+	dev_fsm_event(cdev, DEV_EVENT_VERIFY);
+}
+
+/*
+ * Copy valid bits from the extended control word to device irb.
+ */
+static inline void
+ccw_device_accumulate_ecw(struct ccw_device *cdev, struct irb *irb)
+{
+	/*
+	 * Copy extended control bit if it is valid... yes there
+	 * are condition that have to be met for the extended control
+	 * bit to have meaning. Sick.
+	 */
+	cdev->private->irb.scsw.ectl = 0;
+	if ((irb->scsw.stctl & SCSW_STCTL_ALERT_STATUS) &&
+	    !(irb->scsw.stctl & SCSW_STCTL_INTER_STATUS))
+		cdev->private->irb.scsw.ectl = irb->scsw.ectl;
+	/* Check if extended control word is valid. */
+	if (!cdev->private->irb.scsw.ectl)
+		return;
+	/* Copy concurrent sense / model dependent information. */
+	memcpy (&cdev->private->irb.ecw, irb->ecw, sizeof (irb->ecw));
+}
+
+/*
+ * Copy valid bits from the extended status word to device irb.
+ */
+static inline void
+ccw_device_accumulate_esw(struct ccw_device *cdev, struct irb *irb)
+{
+	struct irb *cdev_irb;
+	struct sublog *cdev_sublog, *sublog;
+
+	/* Check if extended status word is valid. */
+	if (irb->scsw.eswf && irb->scsw.stctl == SCSW_STCTL_STATUS_PEND)
+		return;
+	if (irb->scsw.stctl == 
+	    		(SCSW_STCTL_INTER_STATUS|SCSW_STCTL_STATUS_PEND) &&
+	    !(irb->scsw.actl & SCSW_ACTL_SUSPENDED))
+		return;
+
+	cdev_irb = &cdev->private->irb;
+
+	/* Copy last path used mask. */
+	cdev_irb->esw.esw1.lpum = irb->esw.esw1.lpum;
+
+	/* Copy subchannel logout information if esw is of format 0. */
+	if (irb->scsw.eswf) {
+		cdev_sublog = &cdev_irb->esw.esw0.sublog;
+		sublog = &irb->esw.esw0.sublog;
+		/* Copy extended status flags. */
+		cdev_sublog->esf = sublog->esf;
+		/*
+		 * Copy fields that have a meaning for channel data check
+		 * channel control check and interface control check.
+		 */
+		if (irb->scsw.cstat & (SCHN_STAT_CHN_DATA_CHK |
+				       SCHN_STAT_CHN_CTRL_CHK |
+				       SCHN_STAT_INTF_CTRL_CHK)) {
+			/* Copy ancillary report bit. */
+			cdev_sublog->arep = sublog->arep;
+			/* Copy field-validity-flags. */
+			cdev_sublog->fvf = sublog->fvf;
+			/* Copy storage access code. */
+			cdev_sublog->sacc = sublog->sacc;
+			/* Copy termination code. */
+			cdev_sublog->termc = sublog->termc;
+			/* Copy sequence code. */
+			cdev_sublog->seqc = sublog->seqc;
+		}
+		/* Copy device status check. */
+		cdev_sublog->devsc = sublog->devsc;
+		/* Copy secondary error. */
+		cdev_sublog->serr = sublog->serr;
+		/* Copy i/o-error alert. */
+		cdev_sublog->ioerr = sublog->ioerr;
+		/* Copy channel path timeout bit. */
+		if (irb->scsw.cstat & SCHN_STAT_INTF_CTRL_CHK)
+			cdev_irb->esw.esw0.erw.cpt = irb->esw.esw0.erw.cpt;
+		/* Copy failing storage address validity flag. */
+		cdev_irb->esw.esw0.erw.fsavf = irb->esw.esw0.erw.fsavf;
+		if (cdev_irb->esw.esw0.erw.fsavf) {
+			/* ... and copy the failing storage address. */
+			memcpy(cdev_irb->esw.esw0.faddr, irb->esw.esw0.faddr,
+			       sizeof (irb->esw.esw0.faddr));
+			/* ... and copy the failing storage address format. */
+			cdev_irb->esw.esw0.erw.fsaf = irb->esw.esw0.erw.fsaf;
+		}
+		/* Copy secondary ccw address validity bit. */
+		cdev_irb->esw.esw0.erw.scavf = irb->esw.esw0.erw.scavf;
+		if (irb->esw.esw0.erw.scavf)
+			/* ... and copy the secondary ccw address. */
+			cdev_irb->esw.esw0.saddr = irb->esw.esw0.saddr;
+		
+	}
+	/* FIXME: DCTI for format 2? */
+
+	/* Copy authorization bit. */
+	cdev_irb->esw.esw0.erw.auth = irb->esw.esw0.erw.auth;
+	/* Copy path verification required flag. FIXME: how to verify ?? */
+	cdev_irb->esw.esw0.erw.pvrf = irb->esw.esw0.erw.pvrf;
+	/* Copy concurrent sense bit. */
+	cdev_irb->esw.esw0.erw.cons = irb->esw.esw0.erw.cons;
+	if (irb->esw.esw0.erw.cons)
+		cdev_irb->esw.esw0.erw.scnt = irb->esw.esw0.erw.scnt;
+}
+
+/*
+ * Accumulate status from irb to devstat.
+ */
+void
+ccw_device_accumulate_irb(struct ccw_device *cdev, struct irb *irb)
+{
+	struct irb *cdev_irb;
+
+	/*
+	 * Check if the status pending bit is set in stctl.
+	 * If not, the remaining bit have no meaning and we must ignore them.
+	 * The esw is not meaningful as well...
+	 */
+	if (!(irb->scsw.stctl & SCSW_STCTL_STATUS_PEND))
+		return;
+
+	/* Check for channel checks and interface control checks. */
+	ccw_device_msg_control_check(cdev, irb);
+
+	/* Check for path not operational. */
+	if (irb->scsw.pno && irb->scsw.fctl != 0 &&
+	    (!(irb->scsw.stctl & SCSW_STCTL_INTER_STATUS) ||
+	     (irb->scsw.actl & SCSW_ACTL_SUSPENDED)))
+		ccw_device_path_notoper(cdev);
+
+	/*
+	 * Don't accumulate unsolicited interrupts.
+	 */
+	if (irb->scsw.stctl ==
+	    (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS))
+		return;
+
+	cdev_irb = &cdev->private->irb;
+
+	/* Copy bits which are valid only for the start function. */
+	if (irb->scsw.fctl & SCSW_FCTL_START_FUNC) {
+		/* Copy key. */
+		cdev_irb->scsw.key = irb->scsw.key;
+		/* Copy suspend control bit. */
+		cdev_irb->scsw.sctl = irb->scsw.sctl;
+		/* Copy deferred condition code. */
+		cdev_irb->scsw.cc = irb->scsw.cc;
+		/* Copy ccw format bit. */
+		cdev_irb->scsw.fmt = irb->scsw.fmt;
+		/* Copy prefetch bit. */
+		cdev_irb->scsw.pfch = irb->scsw.pfch;
+		/* Copy initial-status-interruption-control. */
+		cdev_irb->scsw.isic = irb->scsw.isic;
+		/* Copy address limit checking control. */
+		cdev_irb->scsw.alcc = irb->scsw.alcc;
+		/* Copy suppress suspend bit. */
+		cdev_irb->scsw.ssi = irb->scsw.ssi;
+	}
+
+	/* Take care of the extended control bit and extended control word. */
+	ccw_device_accumulate_ecw(cdev, irb);
+	    
+	/* Accumulate function control. */
+	cdev_irb->scsw.fctl |= irb->scsw.fctl;
+	/* Copy activity control. */
+	cdev_irb->scsw.actl= irb->scsw.actl;
+	/* Accumulate status control. */
+	cdev_irb->scsw.stctl |= irb->scsw.stctl;
+	/*
+	 * Copy ccw address if it is valid. This is a bit simplified
+	 * but should be close enough for all practical purposes.
+	 */
+	if ((irb->scsw.stctl & SCSW_STCTL_PRIM_STATUS) ||
+	    ((irb->scsw.stctl == 
+	      (SCSW_STCTL_INTER_STATUS|SCSW_STCTL_STATUS_PEND)) &&
+	     (irb->scsw.actl & SCSW_ACTL_DEVACT) &&
+	     (irb->scsw.actl & SCSW_ACTL_SCHACT)) ||
+	    (irb->scsw.actl & SCSW_ACTL_SUSPENDED))
+		cdev_irb->scsw.cpa = irb->scsw.cpa;
+	/* Accumulate device status, but not the device busy flag. */
+	cdev_irb->scsw.dstat &= ~DEV_STAT_BUSY;
+	cdev_irb->scsw.dstat |= irb->scsw.dstat;
+	/* Accumulate subchannel status. */
+	cdev_irb->scsw.cstat |= irb->scsw.cstat;
+	/* Copy residual count if it is valid. */
+	if ((irb->scsw.stctl & SCSW_STCTL_PRIM_STATUS) &&
+	    (irb->scsw.cstat & ~(SCHN_STAT_PCI | SCHN_STAT_INCORR_LEN)) == 0)
+		cdev_irb->scsw.count = irb->scsw.count;
+
+	/* Take care of bits in the extended status word. */
+	ccw_device_accumulate_esw(cdev, irb);
+
+	/*
+	 * Check whether we must issue a SENSE CCW ourselves if there is no
+	 * concurrent sense facility installed for the subchannel.
+	 * No sense is required if no delayed sense is pending
+	 * and we did not get a unit check without sense information.
+	 *
+	 * Note: We should check for ioinfo[irq]->flags.consns but VM
+	 *	 violates the ESA/390 architecture and doesn't present an
+	 *	 operand exception for virtual devices without concurrent
+	 *	 sense facility available/supported when enabling the
+	 *	 concurrent sense facility.
+	 */
+	if ((cdev_irb->scsw.dstat & DEV_STAT_UNIT_CHECK) &&
+	    !(cdev_irb->esw.esw0.erw.cons))
+		cdev->private->flags.dosense = 1;
+}
+
+/*
+ * Do a basic sense.
+ */
+int
+ccw_device_do_sense(struct ccw_device *cdev, struct irb *irb)
+{
+	struct subchannel *sch;
+
+	sch = to_subchannel(cdev->dev.parent);
+
+	/* A sense is required, can we do it now ? */
+	if (irb->scsw.actl != 0)
+		/*
+		 * we received an Unit Check but we have no final
+		 *  status yet, therefore we must delay the SENSE
+		 *  processing. We must not report this intermediate
+		 *  status to the device interrupt handler.
+		 */
+		return -EBUSY;
+
+	/*
+	 * We have ending status but no sense information. Do a basic sense.
+	 */
+	sch = to_subchannel(cdev->dev.parent);
+	sch->sense_ccw.cmd_code = CCW_CMD_BASIC_SENSE;
+	sch->sense_ccw.cda = (__u32) __pa(cdev->private->irb.ecw);
+	sch->sense_ccw.count = SENSE_MAX_COUNT;
+	sch->sense_ccw.flags = CCW_FLAG_SLI;
+
+	/* 0xe2C5D5E2 == "SENS" in ebcdic */
+	return cio_start (sch, &sch->sense_ccw, 0xE2C5D5E2, 0);
+}
+
+/*
+ * Add information from basic sense to devstat.
+ */
+void
+ccw_device_accumulate_basic_sense(struct ccw_device *cdev, struct irb *irb)
+{
+	/*
+	 * Check if the status pending bit is set in stctl.
+	 * If not, the remaining bit have no meaning and we must ignore them.
+	 * The esw is not meaningful as well...
+	 */
+	if (!(irb->scsw.stctl & SCSW_STCTL_STATUS_PEND))
+		return;
+
+	/* Check for channel checks and interface control checks. */
+	ccw_device_msg_control_check(cdev, irb);
+
+	/* Check for path not operational. */
+	if (irb->scsw.pno && irb->scsw.fctl != 0 &&
+	    (!(irb->scsw.stctl & SCSW_STCTL_INTER_STATUS) ||
+	     (irb->scsw.actl & SCSW_ACTL_SUSPENDED)))
+		ccw_device_path_notoper(cdev);
+
+	if (!(irb->scsw.dstat & DEV_STAT_UNIT_CHECK)) {
+		cdev->private->irb.esw.esw0.erw.cons = 1;
+		cdev->private->flags.dosense = 0;
+	}
+}
+
+/*
+ * This function accumulates the status into the private devstat and
+ * starts a basic sense if one is needed.
+ */
+int
+ccw_device_accumulate_and_sense(struct ccw_device *cdev, struct irb *irb)
+{
+	ccw_device_accumulate_irb(cdev, irb);
+	if (irb->scsw.actl != 0)
+		return -EBUSY;
+	/* Check for basic sense. */
+	if (cdev->private->flags.dosense &&
+	    !(irb->scsw.dstat & DEV_STAT_UNIT_CHECK)) {
+		cdev->private->irb.esw.esw0.erw.cons = 1;
+		cdev->private->flags.dosense = 0;
+		return 0;
+	}
+	if (cdev->private->flags.dosense) {
+		ccw_device_do_sense(cdev, irb);
+		return -EBUSY;
+	}
+	return 0;
+}
+
diff -Nru a/drivers/s390/cio/ioasm.h b/drivers/s390/cio/ioasm.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/cio/ioasm.h	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,305 @@
+#ifndef S390_CIO_IOASM_H
+#define S390_CIO_IOASM_H
+
+/*
+ * area for channel subsystem call
+ */
+struct chsc_area {
+	struct {
+		/* word 0 */
+		__u16 command_code1;
+		__u16 command_code2;
+		union {
+			struct {
+				/* word 1 */
+				__u32 reserved1;
+				/* word 2 */
+				__u32 reserved2;
+			} __attribute__ ((packed,aligned(8))) sei_req;
+			struct {
+				/* word 1 */
+				__u16 reserved1;
+				__u16 f_sch;	 /* first subchannel */
+				/* word 2 */
+				__u16 reserved2;
+				__u16 l_sch;	/* last subchannel */
+			} __attribute__ ((packed,aligned(8))) ssd_req;
+		} request_block_data;
+		/* word 3 */
+		__u32 reserved3;
+	} __attribute__ ((packed,aligned(8))) request_block;
+	struct {
+		/* word 0 */
+		__u16 length;
+		__u16 response_code;
+		/* word 1 */
+		__u32 reserved1;
+		union {
+			struct {
+				/* word 2 */
+				__u8  flags;
+				__u8  vf;	  /* validity flags */
+				__u8  rs;	  /* reporting source */
+				__u8  cc;	  /* content code */
+				/* word 3 */
+				__u16 fla;	  /* full link address */
+				__u16 rsid;	  /* reporting source id */
+				/* word 4 */
+				__u32 reserved2;
+				/* word 5 */
+				__u32 reserved3;
+				/* word 6 */
+				__u32 ccdf;	  /* content-code dependent field */
+				/* word 7 */
+				__u32 reserved4;
+				/* word 8 */
+				__u32 reserved5;
+				/* word 9 */
+				__u32 reserved6;
+			} __attribute__ ((packed,aligned(8))) sei_res;
+			struct {
+				/* word 2 */
+				__u8 sch_valid : 1;
+				__u8 dev_valid : 1;
+				__u8 st	       : 3; /* subchannel type */
+				__u8 zeroes    : 3;
+				__u8  unit_addr;  /* unit address */
+				__u16 devno;	  /* device number */
+				/* word 3 */
+				__u8 path_mask;
+				__u8 fla_valid_mask;
+				__u16 sch;	  /* subchannel */
+				/* words 4-5 */
+				__u8 chpid[8];	  /* chpids 0-7 */
+				/* words 6-9 */
+				__u16 fla[8];	  /* full link addresses 0-7 */
+			} __attribute__ ((packed,aligned(8))) ssd_res;
+		} response_block_data;
+	} __attribute__ ((packed,aligned(8))) response_block;
+} __attribute__ ((packed,aligned(PAGE_SIZE)));
+
+/*
+ * TPI info structure
+ */
+struct tpi_info {
+	__u32 reserved1	 : 16;	 /* reserved 0x00000001 */
+	__u32 irq	 : 16;	 /* aka. subchannel number */
+	__u32 intparm;		 /* interruption parameter */
+	__u32 adapter_IO : 1;
+	__u32 reserved2	 : 1;
+	__u32 isc	 : 3;
+	__u32 reserved3	 : 12;
+	__u32 int_type	 : 3;
+	__u32 reserved4	 : 12;
+} __attribute__ ((packed));
+
+
+/*
+ * Some S390 specific IO instructions as inline
+ */
+
+extern __inline__ int stsch(int irq, volatile struct schib *addr)
+{
+	int ccode;
+
+	__asm__ __volatile__(
+		"   lr	  1,%1\n"
+		"   stsch 0(%2)\n"
+		"   ipm	  %0\n"
+		"   srl	  %0,28"
+		: "=d" (ccode)
+		: "d" (irq | 0x10000), "a" (addr)
+		: "cc", "1" );
+	return ccode;
+}
+
+extern __inline__ int msch(int irq, volatile struct schib *addr)
+{
+	int ccode;
+
+	__asm__ __volatile__(
+		"   lr	  1,%1\n"
+		"   msch  0(%2)\n"
+		"   ipm	  %0\n"
+		"   srl	  %0,28"
+		: "=d" (ccode)
+		: "d" (irq | 0x10000L), "a" (addr)
+		: "cc", "1" );
+	return ccode;
+}
+
+extern __inline__ int msch_err(int irq, volatile struct schib *addr)
+{
+	int ccode;
+
+	__asm__ __volatile__(
+		"    lhi  %0,%3\n"
+		"    lr	  1,%1\n"
+		"    msch 0(%2)\n"
+		"0:  ipm  %0\n"
+		"    srl  %0,28\n"
+		"1:\n"
+#ifdef CONFIG_ARCH_S390X
+		".section __ex_table,\"a\"\n"
+		"   .align 8\n"
+		"   .quad 0b,1b\n"
+		".previous"
+#else
+		".section __ex_table,\"a\"\n"
+		"   .align 4\n"
+		"   .long 0b,1b\n"
+		".previous"
+#endif
+		: "=&d" (ccode)
+		: "d" (irq | 0x10000L), "a" (addr), "K" (-EIO)
+		: "cc", "1" );
+	return ccode;
+}
+
+extern __inline__ int tsch(int irq, volatile struct irb *addr)
+{
+	int ccode;
+
+	__asm__ __volatile__(
+		"   lr	  1,%1\n"
+		"   tsch  0(%2)\n"
+		"   ipm	  %0\n"
+		"   srl	  %0,28"
+		: "=d" (ccode)
+		: "d" (irq | 0x10000L), "a" (addr)
+		: "cc", "1" );
+	return ccode;
+}
+
+extern __inline__ int tpi( volatile struct tpi_info *addr)
+{
+	int ccode;
+
+	__asm__ __volatile__(
+		"   tpi	  0(%1)\n"
+		"   ipm	  %0\n"
+		"   srl	  %0,28"
+		: "=d" (ccode)
+		: "a" (addr)
+		: "cc", "1" );
+	return ccode;
+}
+
+extern __inline__ int ssch(int irq, volatile struct orb *addr)
+{
+	int ccode;
+
+	__asm__ __volatile__(
+		"   lr	  1,%1\n"
+		"   ssch  0(%2)\n"
+		"   ipm	  %0\n"
+		"   srl	  %0,28"
+		: "=d" (ccode)
+		: "d" (irq | 0x10000L), "a" (addr)
+		: "cc", "1" );
+	return ccode;
+}
+
+extern __inline__ int rsch(int irq)
+{
+	int ccode;
+
+	__asm__ __volatile__(
+		"   lr	  1,%1\n"
+		"   rsch\n"
+		"   ipm	  %0\n"
+		"   srl	  %0,28"
+		: "=d" (ccode)
+		: "d" (irq | 0x10000L)
+		: "cc", "1" );
+	return ccode;
+}
+
+extern __inline__ int csch(int irq)
+{
+	int ccode;
+
+	__asm__ __volatile__(
+		"   lr	  1,%1\n"
+		"   csch\n"
+		"   ipm	  %0\n"
+		"   srl	  %0,28"
+		: "=d" (ccode)
+		: "d" (irq | 0x10000L)
+		: "cc", "1" );
+	return ccode;
+}
+
+extern __inline__ int hsch(int irq)
+{
+	int ccode;
+
+	__asm__ __volatile__(
+		"   lr	  1,%1\n"
+		"   hsch\n"
+		"   ipm	  %0\n"
+		"   srl	  %0,28"
+		: "=d" (ccode)
+		: "d" (irq | 0x10000L)
+		: "cc", "1" );
+	return ccode;
+}
+
+extern __inline__ int xsch(int irq)
+{
+	int ccode;
+
+	__asm__ __volatile__(
+		"   lr	  1,%1\n"
+		"   .insn rre,0xb2760000,%1,0\n"
+		"   ipm	  %0\n"
+		"   srl	  %0,28"
+		: "=d" (ccode)
+		: "d" (irq | 0x10000L)
+		: "cc", "1" );
+	return ccode;
+}
+
+extern __inline__ int do_chsc(void *chsc_area)
+{
+	int cc;
+
+	__asm__ __volatile__ (
+		".insn	rre,0xb25f0000,%1,0	\n\t"
+		"ipm	%0	\n\t"
+		"srl	%0,28	\n\t"
+		: "=d" (cc)
+		: "d" (chsc_area)
+		: "cc" );
+
+	return cc;
+}
+
+extern __inline__ int iac( void)
+{
+	int ccode;
+
+	__asm__ __volatile__(
+		"   iac	  1\n"
+		"   ipm	  %0\n"
+		"   srl	  %0,28"
+		: "=d" (ccode) : : "cc", "1" );
+	return ccode;
+}
+
+extern __inline__ int rchp(int chpid)
+{
+	int ccode;
+
+	__asm__ __volatile__(
+		"   lr	  1,%1\n"
+		"   rchp\n"
+		"   ipm	  %0\n"
+		"   srl	  %0,28"
+		: "=d" (ccode)
+		: "d" (chpid)
+		: "cc", "1" );
+	return ccode;
+}
+
+#endif
diff -Nru a/drivers/s390/cio/ioinfo.c b/drivers/s390/cio/ioinfo.c
--- a/drivers/s390/cio/ioinfo.c	Mon Dec  9 18:46:34 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,292 +0,0 @@
-/*
- *  drivers/s390/cio/ioinfo.c
- *   S/390 common I/O routines -- the ioinfo structure
- *   $Revision: 1.4 $
- *
- *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
- *                            IBM Corporation
- *    Author(s): Ingo Adlung (adlung@de.ibm.com)
- *               Cornelia Huck (cohuck@de.ibm.com) 
- *		 Arnd Bergmann (arndb@de.ibm.com)
- *    ChangeLog: 11/04/2002 Arnd Bergmann Split s390io.c into multiple files,
- *					  see s390io.c for complete list of
- * 					  changes.
- */
-
-#include <linux/module.h>
-#include <linux/config.h>
-
-#include <asm/irq.h>
-#include <asm/debug.h>
-
-#include "ioinfo.h"
-
-unsigned int highest_subchannel;
-
-ioinfo_t *ioinfo_head;
-ioinfo_t *ioinfo_tail;
-ioinfo_t *ioinfo[__MAX_SUBCHANNELS]
-#if 1
-= { [0 ... (__MAX_SUBCHANNELS - 1)] = INVALID_STORAGE_AREA} /*FIXME: define this to 0 */
-#endif
-;
-
-static inline int
-get_next_available_irq (ioinfo_t * pi)
-{
-	int ret_val = -ENODEV;
-
-	while (pi != NULL) {
-		if ((!pi->st) && (pi->ui.flags.oper)) {
-			ret_val = pi->irq;
-			break;
-		} else {
-			pi = pi->next;
-		}
-	}
-
-	return ret_val;
-}
-
-int
-get_irq_first (void)
-{
-	int ret_irq;
-
-	if (ioinfo_head) {
-		if ((ioinfo_head->ui.flags.oper) && 
-		    (!ioinfo_head->st)) {
-			ret_irq = ioinfo_head->irq;
-		} else if (ioinfo_head->next) {
-			ret_irq = get_next_available_irq (ioinfo_head->next);
-
-		} else {
-			ret_irq = -ENODEV;
-
-		}
-	} else {
-		ret_irq = -ENODEV;
-
-	}
-
-	return ret_irq;
-}
-
-int
-get_irq_next (int irq)
-{
-	int ret_irq;
-
-	if (ioinfo[irq] != INVALID_STORAGE_AREA) {
-		if (ioinfo[irq]->next) {
-			if ((ioinfo[irq]->next->ui.flags.oper) &&
-			    (!ioinfo[irq]->next->st)) {
-				ret_irq = ioinfo[irq]->next->irq;
-			} else {
-				ret_irq =
-				    get_next_available_irq (ioinfo[irq]->next);
-
-			}
-		} else {
-			ret_irq = -ENODEV;
-
-		}
-	} else {
-		ret_irq = -EINVAL;
-
-	}
-
-	return ret_irq;
-}
-
-int
-get_dev_info_by_irq (int irq, s390_dev_info_t * pdi)
-{
-	if (irq > highest_subchannel || irq < 0) 
-		return -ENODEV; 
-	if (ioinfo[irq] == INVALID_STORAGE_AREA) 
-		return -ENODEV; 
-        if (ioinfo[irq]->st) 
-                return -ENODEV; 
-
-	if (pdi == NULL)
-		return -EINVAL;
-
-	pdi->devno = ioinfo[irq]->schib.pmcw.dev;
-	pdi->irq = irq;
-
-	if (ioinfo[irq]->ui.flags.oper && !ioinfo[irq]->ui.flags.unknown) {
-		pdi->status = 0;
-		memcpy (&(pdi->sid_data),
-			&ioinfo[irq]->senseid, sizeof (senseid_t));
-	} else if (ioinfo[irq]->ui.flags.unknown) {
-		pdi->status = DEVSTAT_UNKNOWN_DEV;
-		memset (&(pdi->sid_data), '\0', sizeof (senseid_t));
-		pdi->sid_data.cu_type = 0xFFFF;
-
-	} else {
-		pdi->status = DEVSTAT_NOT_OPER;
-		memset (&(pdi->sid_data), '\0', sizeof (senseid_t));
-		pdi->sid_data.cu_type = 0xFFFF;
-
-	}
-
-	if (ioinfo[irq]->ui.flags.ready)
-		pdi->status |= DEVSTAT_DEVICE_OWNED;
-
-	return 0;
-}
-
-int
-get_dev_info_by_devno (__u16 devno, s390_dev_info_t * pdi)
-{
-	int i;
-	int rc = -ENODEV;
-
-	if (devno > 0x0000ffff)
-		return -ENODEV;
-	if (pdi == NULL)
-		return -EINVAL;
-
-	for (i = 0; i <= highest_subchannel; i++) {
-
-		if ((ioinfo[i] != INVALID_STORAGE_AREA) &&
-		    (!ioinfo[i]->st) &&
-		    (ioinfo[i]->schib.pmcw.dev == devno)) {
-
-			pdi->irq = i;
-			pdi->devno = devno;
-
-			if (ioinfo[i]->ui.flags.oper
-			    && !ioinfo[i]->ui.flags.unknown) {
-				pdi->status = 0;
-				memcpy (&(pdi->sid_data),
-					&ioinfo[i]->senseid,
-					sizeof (senseid_t));
-			} else if (ioinfo[i]->ui.flags.unknown) {
-				pdi->status = DEVSTAT_UNKNOWN_DEV;
-
-				memset (&(pdi->sid_data),
-					'\0', sizeof (senseid_t));
-
-				pdi->sid_data.cu_type = 0xFFFF;
-			} else {
-				pdi->status = DEVSTAT_NOT_OPER;
-
-				memset (&(pdi->sid_data),
-					'\0', sizeof (senseid_t));
-
-				pdi->sid_data.cu_type = 0xFFFF;
-
-			}
-
-			if (ioinfo[i]->ui.flags.ready)
-				pdi->status |= DEVSTAT_DEVICE_OWNED;
-
-			rc = 0;	/* found */
-			break;
-
-		}
-	}
-
-	return rc;
-
-}
-
-int
-get_irq_by_devno (__u16 devno)
-{
-	int i;
-	int rc = -1;
-
-	if (devno <= 0x0000ffff) {
-		for (i = 0; i <= highest_subchannel; i++) {
-			if ((ioinfo[i] != INVALID_STORAGE_AREA)
-			    && (!ioinfo[i]->st)
-			    && (ioinfo[i]->schib.pmcw.dev == devno)
-			    && (ioinfo[i]->schib.pmcw.dnv == 1)) {
-				rc = i;
-				break;
-			}
-		}
-	}
-
-	return rc;
-}
-
-unsigned int
-get_devno_by_irq (int irq)
-{
-	if ((irq > highest_subchannel)
-	    || (irq < 0)
-	    || (ioinfo[irq] == INVALID_STORAGE_AREA)) {
-		return -1;
-
-	}
-
-	if (ioinfo[irq]->st) 
-		return -1;
-
-	/*
-	 * we don't need to check for the device be operational
-	 *  as the initial STSCH will always present the device
-	 *  number defined by the IOCDS regardless of the device
-	 *  existing or not. However, there could be subchannels
-	 *  defined who's device number isn't valid ...
-	 */
-	if (ioinfo[irq]->schib.pmcw.dnv)
-		return ioinfo[irq]->schib.pmcw.dev;
-	else
-		return -1;
-}
-
-schib_t *
-s390_get_schib (int irq)
-{
-	if ((irq > highest_subchannel) || (irq < 0))
-		return NULL;
-	if (ioinfo[irq] == INVALID_STORAGE_AREA)
-		return NULL;
-	if (ioinfo[irq]->st)
-		return NULL;
-	return &ioinfo[irq]->schib;
-}
-
-/* these are used only by the tape driver to store per subchannel 
- * private data */
-int
-s390_set_private_data(int irq, void *data)
-{
-	if (irq > highest_subchannel || irq < 0)
-		return -ENODEV;
-	if (ioinfo[irq] == INVALID_STORAGE_AREA)
-		return -ENODEV;
-        if (ioinfo[irq]->st)
-                return -ENODEV;
-	ioinfo[irq]->private_data = data;
-	return 0;
-}
-
-void *
-s390_get_private_data(int irq)
-{
-	if ((irq > highest_subchannel) || (irq < 0))
-		return NULL;
-	if (ioinfo[irq] == INVALID_STORAGE_AREA)
-		return NULL;
-	if (ioinfo[irq]->st)
-		return NULL;
-	return ioinfo[irq]->private_data;
-}
-
-
-EXPORT_SYMBOL (ioinfo);
-EXPORT_SYMBOL (get_dev_info_by_irq);
-EXPORT_SYMBOL (get_dev_info_by_devno);
-EXPORT_SYMBOL (get_irq_by_devno);
-EXPORT_SYMBOL (get_devno_by_irq);
-EXPORT_SYMBOL (get_irq_first);
-EXPORT_SYMBOL (get_irq_next);
-EXPORT_SYMBOL (s390_get_schib);
-EXPORT_SYMBOL (s390_set_private_data);
-EXPORT_SYMBOL (s390_get_private_data);
diff -Nru a/drivers/s390/cio/ioinfo.h b/drivers/s390/cio/ioinfo.h
--- a/drivers/s390/cio/ioinfo.h	Mon Dec  9 18:46:38 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,10 +0,0 @@
-#ifndef S390_IOINFO_H
-#define S390_IOINFO_H
-
-extern unsigned int highest_subchannel;
-
-extern ioinfo_t *ioinfo_head;
-extern ioinfo_t *ioinfo_tail;
-extern ioinfo_t *ioinfo[__MAX_SUBCHANNELS];
-
-#endif
diff -Nru a/drivers/s390/cio/misc.c b/drivers/s390/cio/misc.c
--- a/drivers/s390/cio/misc.c	Mon Dec  9 18:46:36 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,235 +0,0 @@
-/*
- *  drivers/s390/s390io.c
- *   S/390 common I/O routines
- *   $Revision: 1.5 $
- *
- *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
- *                            IBM Corporation
- *    Author(s): Ingo Adlung (adlung@de.ibm.com)
- *               Cornelia Huck (cohuck@de.ibm.com) 
- *		 Arnd Bergmann (arndb@de.ibm.com)
- *    ChangeLog: 11/04/2002 Arnd Bergmann Split s390io.c into multiple files,
- *					  see s390io.c for complete list of
- * 					  changes.
- *               05/03/2002 Cornelia Huck  debug cleanup
- */
-#include <linux/module.h>
-#include <linux/config.h>
-#ifdef CONFIG_PROC_FS
-#include <linux/proc_fs.h>
-#endif
-#include <asm/delay.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-
-#include <asm/s390io.h>
-#include <asm/s390dyn.h>
-#include <asm/s390mach.h>
-#include <asm/debug.h>
-
-#include "s390io.h"
-#include "cio_debug.h"
-#include "ioinfo.h"
-#include "proc.h"
-#include "chsc.h"
-
-#ifdef CONFIG_DEBUG_CRW
-#define DBGW printk
-#else
-#define DBGW(args,...) do {} while (0)
-#endif
-
-#define CRW_DEBUG(printk_level,event_level,msg...) ({\
-	DBGW(printk_level msg); \
-	CIO_CRW_EVENT (event_level, msg); \
-})
-
-static void
-s390_process_subchannel_source (int irq)
-{
-	int dev_oper = 0;
-	int dev_no = -1;
-	int lock = 0;
-	int is_owned = 0;
-
-	/*
-	 * If the device isn't known yet
-	 *   we can't lock it ...
-	 */
-	if (ioinfo[irq] != INVALID_STORAGE_AREA) {
-		s390irq_spin_lock (irq);
-		lock = 1;
-
-		if (!ioinfo[irq]->st) {
-			dev_oper = ioinfo[irq]->ui.flags.oper;
-			
-			if (ioinfo[irq]->ui.flags.dval)
-				dev_no = ioinfo[irq]->devno;
-			
-			is_owned = ioinfo[irq]->ui.flags.ready;
-		}
-
-	}
-	CRW_DEBUG(KERN_DEBUG, 4, 
-		  "subchannel validation - start\n");
-	s390_validate_subchannel (irq, is_owned);
-
-	if (irq > highest_subchannel)
-		highest_subchannel = irq;
-
-	CRW_DEBUG(KERN_DEBUG, 4, 
-		  "subchannel validation - done\n");
-	/*
-	 * After the validate processing
-	 *   the ioinfo control block
-	 *   should be allocated ...
-	 */
-	if (lock) {
-		s390irq_spin_unlock (irq);
-	}
-
-	if (ioinfo[irq] != INVALID_STORAGE_AREA) {
-
-#ifdef CONFIG_ARCH_S390X
-		CRW_DEBUG(KERN_DEBUG, 4, 
-			  "ioinfo at %08lX\n", 
-			  (unsigned long)ioinfo[irq]);
-#else				/* CONFIG_ARCH_S390X */
-		CRW_DEBUG(KERN_DEBUG, 4, 
-			  "ioinfo at %08X\n", 
-			  (unsigned)ioinfo[irq]);
-#endif				/* CONFIG_ARCH_S390X */
-
-		if (ioinfo[irq]->st)
-			return;
-
-		if (ioinfo[irq]->ui.flags.oper == 0) {
-			not_oper_handler_func_t nopfunc = ioinfo[irq]->nopfunc;
-
-			/*
-			 * If the device has gone
-			 *  call not oper handler               
-			 */
-			if ((dev_oper == 1)
-			    && (nopfunc != NULL)) {
-
-				free_irq (irq, ioinfo[irq]->irq_desc.dev_id);
-				nopfunc (irq, DEVSTAT_DEVICE_GONE);
-
-			}
-		} else {
-			CRW_DEBUG(KERN_DEBUG, 4,
-				  "device recognition - start\n");
-	
-			s390_device_recognition_irq (irq);
-
-			CRW_DEBUG(KERN_DEBUG, 4,
-				  "device recognition - done\n");
-			/*
-			 * the device became operational
-			 */
-			if (dev_oper == 0) {
-				devreg_t *pdevreg;
-
-				pdevreg = s390_search_devreg (ioinfo[irq]);
-
-				if (pdevreg != NULL) {
-					if (pdevreg->oper_func != NULL)
-						pdevreg->
-						    oper_func (irq, pdevreg);
-
-				}
-
-			}
-			/*
-			 * ... it is and was operational, but
-			 *      the devno may have changed
-			 */
-			else if ((ioinfo[irq]->devno != dev_no)
-				 && (ioinfo[irq]->nopfunc != NULL)) {
-
-				ioinfo[irq]->nopfunc (irq, DEVSTAT_REVALIDATE);
-
-			}
-		}
-	}
-}
-
-/*
- * s390_do_crw_pending
- *
- * Called by the machine check handler to process CRW pending
- *  conditions. It may be a single CRW, or CRWs may be chained.
- *
- * Note : we currently process CRWs for subchannel source only
- */
-void
-s390_do_crw_pending (crwe_t * pcrwe)
-{
-	int irq;
-	int chpid;
-	
-	CRW_DEBUG(KERN_DEBUG, 2, 
-		  "do_crw_pending: starting\n");
-
-	while (pcrwe != NULL) {
-
-		switch (pcrwe->crw.rsc) {
-		case CRW_RSC_SCH:
-			
-			irq = pcrwe->crw.rsid;
-			
-			CRW_DEBUG(KERN_NOTICE, 2, 
-				  "source is subchannel %04X\n",
-				  irq);
-
-			s390_process_subchannel_source (irq);
-
-			break;
-
-		case CRW_RSC_MONITOR:
-
-			CRW_DEBUG(KERN_NOTICE, 2, 
-				  "source is monitoring facility\n");
-			break;
-
-		case CRW_RSC_CPATH:
-
-			chpid = pcrwe->crw.rsid;
-
-			CRW_DEBUG(KERN_NOTICE, 2, 
-				  "source is channel path %02X\n",
-				  chpid);
-			break;
-
-		case CRW_RSC_CONFIG:
-
-			CRW_DEBUG(KERN_NOTICE, 2, 
-				  "source is configuration-alert facility\n");
-			break;
-
-		case CRW_RSC_CSS:
-
-			CRW_DEBUG(KERN_NOTICE, 2, 
-				  "source is channel subsystem\n");
-			s390_process_css();
-			break;
-
-		default:
-
-			CRW_DEBUG(KERN_NOTICE, 2, 
-				  "unknown source\n");
-			break;
-
-		}
-
-		pcrwe = pcrwe->crwe_next;
-
-	}
-
-	CRW_DEBUG(KERN_DEBUG, 2, 
-		  "do_crw_pending: done\n");
-	return;
-}
-
-
diff -Nru a/drivers/s390/cio/misc.h b/drivers/s390/cio/misc.h
--- a/drivers/s390/cio/misc.h	Mon Dec  9 18:46:37 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,4 +0,0 @@
-#ifndef S390_MISC_H
-#define S390_MISC_H
-
-#endif
diff -Nru a/drivers/s390/cio/proc.c b/drivers/s390/cio/proc.c
--- a/drivers/s390/cio/proc.c	Mon Dec  9 18:46:34 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,275 +0,0 @@
-/*
- *  drivers/s390/cio/proc.c
- *   S/390 common I/O routines -- proc file system entries
- *   $Revision: 1.5 $
- *
- *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
- *                            IBM Corporation
- *    Author(s): Ingo Adlung (adlung@de.ibm.com)
- *               Cornelia Huck (cohuck@de.ibm.com) 
- *		 Arnd Bergmann (arndb@de.ibm.com)
- *    ChangeLog: 11/04/2002 Arnd Bergmann Split s390io.c into multiple files,
- *					  see s390io.c for complete list of
- * 					  changes.
- *               05/03/2002 Cornelia Huck  removed /proc/deviceinfo/
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/proc_fs.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/s390io.h>
-#include <asm/debug.h>
-
-#include "ioinfo.h"
-#include "s390io.h"
-#include "cio_debug.h"
-
-static int chan_proc_init (void);
-
-/* 
- * Display info on subchannels in /proc/subchannels. 
- * Adapted from procfs stuff in dasd.c by Cornelia Huck, 02/28/01.      
- */
-
-typedef struct {
-	char *data;
-	int len;
-} tempinfo_t;
-
-static struct proc_dir_entry *chan_subch_entry;
-
-static int
-chan_subch_open (struct inode *inode, struct file *file)
-{
-	int rc = 0;
-	int size = 1;
-	int len = 0;
-	int i = 0;
-	int j = 0;
-	tempinfo_t *info;
-
-	info = (tempinfo_t *) vmalloc (sizeof (tempinfo_t));
-	if (info == NULL) {
-		printk (KERN_WARNING "No memory available for data\n");
-		return -ENOMEM;
-	} else {
-		file->private_data = (void *) info;
-	}
-
-	size += (highest_subchannel + 1) * 128;
-	info->data = (char *) vmalloc (size);
-
-	if (size && info->data == NULL) {
-		printk (KERN_WARNING "No memory available for data\n");
-		vfree (info);
-		return -ENOMEM;
-	}
-
-	len += sprintf (info->data + len,
-			"Device sch.  Dev Type/Model CU  in use  PIM PAM POM CHPIDs\n");
-	len += sprintf (info->data + len,
-			"---------------------------------------------------------------------\n");
-
-	for (i = 0; i <= highest_subchannel; i++) {
-		if (!((ioinfo[i] == NULL) || (ioinfo[i] == INVALID_STORAGE_AREA)
-		      || (ioinfo[i]->st )|| !(ioinfo[i]->ui.flags.oper))) {
-			len +=
-			    sprintf (info->data + len, "%04X   %04X  ",
-				     ioinfo[i]->schib.pmcw.dev, i);
-			if (ioinfo[i]->senseid.dev_type != 0) {
-				len += sprintf (info->data + len,
-						"%04X/%02X   %04X/%02X",
-						ioinfo[i]->senseid.dev_type,
-						ioinfo[i]->senseid.dev_model,
-						ioinfo[i]->senseid.cu_type,
-						ioinfo[i]->senseid.cu_model);
-			} else {
-				len += sprintf (info->data + len,
-						"          %04X/%02X",
-						ioinfo[i]->senseid.cu_type,
-						ioinfo[i]->senseid.cu_model);
-			}
-			if (ioinfo[i]->ui.flags.ready) {
-				len += sprintf (info->data + len, "  yes ");
-			} else {
-				len += sprintf (info->data + len, "      ");
-			}
-			len += sprintf (info->data + len,
-					"    %02X  %02X  %02X  ",
-					ioinfo[i]->schib.pmcw.pim,
-					ioinfo[i]->schib.pmcw.pam,
-					ioinfo[i]->schib.pmcw.pom);
-			for (j = 0; j < 8; j++) {
-				len += sprintf (info->data + len,
-						"%02X",
-						ioinfo[i]->schib.pmcw.chpid[j]);
-				if (j == 3) {
-					len += sprintf (info->data + len, " ");
-				}
-			}
-			len += sprintf (info->data + len, "\n");
-		}
-	}
-	info->len = len;
-
-	return rc;
-}
-
-static int
-chan_subch_close (struct inode *inode, struct file *file)
-{
-	int rc = 0;
-	tempinfo_t *p_info = (tempinfo_t *) file->private_data;
-
-	if (p_info) {
-		if (p_info->data)
-			vfree (p_info->data);
-		vfree (p_info);
-	}
-
-	return rc;
-}
-
-static ssize_t
-chan_subch_read (struct file *file, char *user_buf, size_t user_len,
-		 loff_t * offset)
-{
-	loff_t len;
-	tempinfo_t *p_info = (tempinfo_t *) file->private_data;
-
-	if (*offset >= p_info->len) {
-		return 0;
-	} else {
-		len = min ((size_t) user_len, 
-			   (size_t) (p_info->len - *offset));
-		if (copy_to_user (user_buf, &(p_info->data[*offset]), len))
-			return -EFAULT;
-		(*offset) += len;
-		return len;
-	}
-}
-
-static struct file_operations chan_subch_file_ops = {
-	.read = chan_subch_read, .open = chan_subch_open, .release = chan_subch_close,
-};
-
-static int
-chan_proc_init (void)
-{
-	chan_subch_entry =
-	    create_proc_entry ("subchannels", S_IFREG | S_IRUGO, &proc_root);
-	chan_subch_entry->proc_fops = &chan_subch_file_ops;
-
-	return 1;
-}
-
-__initcall (chan_proc_init);
-
-/*
- * Entry /proc/irq_count
- * display how many irqs have occured per cpu...
- */
-
-static struct proc_dir_entry *cio_irq_proc_entry;
-
-static int
-cio_irq_proc_open (struct inode *inode, struct file *file)
-{
-	int rc = 0;
-	int size = 1;
-	int len = 0;
-	tempinfo_t *info;
-	int i;
-
-	info = (tempinfo_t *) vmalloc (sizeof (tempinfo_t));
-	if (info == NULL) {
-		printk (KERN_WARNING "No memory available for data\n");
-		rc = -ENOMEM;
-	} else {
-		file->private_data = (void *) info;
-		size += NR_CPUS * 16;
-		info->data = (char *) vmalloc (size);
-		if (size && info->data == NULL) {
-			printk (KERN_WARNING "No memory available for data\n");
-			vfree (info);
-			rc = -ENOMEM;
-		} else {
-			for (i = 0; i < NR_CPUS; i++) {
-				if (s390_irq_count[i] != 0)
-					len +=
-					    sprintf (info->data + len, "%lx\n",
-						     s390_irq_count[i]);
-			}
-			info->len = len;
-		}
-	}
-	return rc;
-}
-
-static int
-cio_irq_proc_close (struct inode *inode, struct file *file)
-{
-	int rc = 0;
-	tempinfo_t *p_info = (tempinfo_t *) file->private_data;
-
-	if (p_info) {
-		if (p_info->data)
-			vfree (p_info->data);
-		vfree (p_info);
-	}
-
-	return rc;
-}
-
-static ssize_t
-cio_irq_proc_read (struct file *file, char *user_buf, size_t user_len,
-		   loff_t * offset)
-{
-	loff_t len;
-	tempinfo_t *p_info = (tempinfo_t *) file->private_data;
-
-	if (*offset >= p_info->len) {
-		return 0;
-	} else {
-		len = min ((size_t) user_len, 
-			   (size_t) (p_info->len - *offset));
-		if (copy_to_user (user_buf, &(p_info->data[*offset]), len))
-			return -EFAULT;
-		(*offset) += len;
-		return len;
-	}
-}
-
-static struct file_operations cio_irq_proc_file_ops = {
-	.read = cio_irq_proc_read, .open = cio_irq_proc_open,
-	.release = cio_irq_proc_close,
-};
-
-static int
-cio_irq_proc_init (void)
-{
-	int i;
-
-	if (cio_count_irqs) {
-		for (i = 0; i < NR_CPUS; i++)
-			s390_irq_count[i] = 0;
-		cio_irq_proc_entry =
-		    create_proc_entry ("irq_count", S_IFREG | S_IRUGO,
-				       &proc_root);
-		cio_irq_proc_entry->proc_fops = &cio_irq_proc_file_ops;
-	}
-
-	return 1;
-}
-
-__initcall (cio_irq_proc_init);
-
-void
-init_irq_proc(void)
-{
-	/* For now, nothing... */
-}
diff -Nru a/drivers/s390/cio/proc.h b/drivers/s390/cio/proc.h
--- a/drivers/s390/cio/proc.h	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,19 +0,0 @@
-#ifndef S390_PROC_H
-#define S390_PROC_H
-
-extern int cio_procfs_device_purge (void);
-extern int cio_procfs_device_create (int devno);
-extern int cio_procfs_device_remove (int devno);
-
-//FIXME: shouldn`t this be 'struct{unsigned int len; char data[0]};' ?
-/*
- * Display info on subchannels in /proc/subchannels.
- * Adapted from procfs stuff in dasd.c by Cornelia Huck, 02/28/01.
- */
-typedef struct {
-        char *data;
-        int len;
-} tempinfo_t;
-
-
-#endif
diff -Nru a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/cio/qdio.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,3056 @@
+/*
+ *
+ * linux/drivers/s390/cio/qdio.c
+ *
+ * Linux for S/390 QDIO base support, Hipersocket base support
+ * version 2
+ *
+ * Copyright 2000,2002 IBM Corporation
+ * Author(s): Utz Bacher <utz.bacher@de.ibm.com>
+ *            Cornelia Huck <cohuck@de.ibm.com>
+ *
+ * Restriction: only 63 iqdio subchannels would have its own indicator,
+ * after that, subsequent subchannels share one indicator
+ *
+ *
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/version.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/proc_fs.h>
+#include <linux/timer.h>
+
+#include <asm/ccwdev.h>
+#include <asm/io.h>
+#include <asm/atomic.h>
+#include <asm/semaphore.h>
+
+#include <asm/debug.h>
+#include <asm/qdio.h>
+
+#include "cio.h"
+#include "css.h"
+#include "device.h"
+#include "airq.h"
+#include "qdio.h"
+
+#define VERSION_QDIO_C "$Revision: 1.16 $"
+
+/****************** MODULE PARAMETER VARIABLES ********************/
+MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
+MODULE_DESCRIPTION("QDIO base support version 2, " \
+		   "Copyright 2000 IBM Corporation");
+MODULE_LICENSE("GPL");
+
+/******************** HERE WE GO ***********************************/
+
+static const char *version="QDIO base support version 2 ("
+	VERSION_QDIO_C "/" VERSION_QDIO_H  "/" VERSION_CIO_QDIO_H ")";
+
+#ifdef QDIO_PERFORMANCE_STATS
+static int proc_perf_file_registration;
+static unsigned long i_p_c, i_p_nc, o_p_c, o_p_nc, ii_p_c, ii_p_nc;
+static struct qdio_perf_stats perf_stats;
+#endif /* QDIO_PERFORMANCE_STATS */
+
+static int indicator_used[INDICATORS_PER_CACHELINE];
+static __u32 * volatile indicators;
+static __u32 volatile spare_indicator;
+
+static debug_info_t *qdio_dbf_setup;
+static debug_info_t *qdio_dbf_sbal;
+static debug_info_t *qdio_dbf_trace;
+static debug_info_t *qdio_dbf_sense;
+#ifdef QDIO_DBF_LIKE_HELL
+static debug_info_t *qdio_dbf_slsb_out;
+static debug_info_t *qdio_dbf_slsb_in;
+#endif /* QDIO_DBF_LIKE_HELL */
+
+static struct semaphore init_sema;
+
+static struct qdio_chsc_area *chsc_area;
+/* iQDIO stuff: */
+static volatile struct qdio_q *iq_list=NULL; /* volatile as it could change
+						  during a while loop */
+static spinlock_t iq_list_lock=SPIN_LOCK_UNLOCKED;
+static int register_thinint_result;
+static void iqdio_tl(unsigned long);
+static DECLARE_TASKLET(iqdio_tasklet,iqdio_tl,0);
+
+/* not a macro, as one of the arguments is atomic_read */
+static inline int 
+qdio_min(int a,int b)
+{
+	if (a<b)
+		return a;
+	else
+		return b;
+}
+
+/***************** SCRUBBER HELPER ROUTINES **********************/
+
+static inline volatile __u64 
+qdio_get_micros(void)
+{
+        __u64 time;
+
+        asm volatile ("STCK %0" : "=m" (time));
+        return time>>12; /* time>>12 is microseconds*/
+}
+static inline unsigned long 
+qdio_get_millis(void)
+{
+	return (unsigned long)(qdio_get_micros()>>12);
+}
+
+static __inline__ int 
+atomic_return_add (int i, atomic_t *v)
+{
+	int old, new;
+	__CS_LOOP(old, new, v, i, "ar");
+	return old;
+}
+
+static void 
+qdio_wait_nonbusy(unsigned int timeout)
+{
+        unsigned int start;
+        char dbf_text[15];
+
+	sprintf(dbf_text,"wtnb%4x",timeout);
+	QDIO_DBF_TEXT3(0,trace,dbf_text);
+
+	start=qdio_get_millis();
+	for (;;) {
+		set_task_state(current,TASK_INTERRUPTIBLE);
+		if (qdio_get_millis()-start>timeout) {
+			goto out;
+		}
+		schedule_timeout(((start+timeout-qdio_get_millis())>>10)*HZ);
+	}
+out:
+	set_task_state(current,TASK_RUNNING);
+}
+
+static int 
+qdio_wait_for_no_use_count(atomic_t *use_count)
+{
+	unsigned long start;
+
+	QDIO_DBF_TEXT3(0,trace,"wtnousec");
+	start=qdio_get_millis();
+	for (;;) {
+		if (qdio_get_millis()-start>QDIO_NO_USE_COUNT_TIMEOUT) {
+			QDIO_DBF_TEXT1(1,trace,"WTNOUSTO");
+			return -ETIME;
+		}
+		if (!atomic_read(use_count)) {
+			QDIO_DBF_TEXT3(0,trace,"wtnoused");
+			return 0;
+		}
+		qdio_wait_nonbusy(QDIO_NO_USE_COUNT_TIME);
+	}
+}
+
+/* 
+ * unfortunately, we can't just xchg the values; in do_QDIO we want to reserve
+ * the q in any case, so that we'll not be interrupted when we are in
+ * qdio_mark_iq... shouldn't have a really bad impact, as reserving almost
+ * ever works (last famous words) 
+ */
+static inline int 
+qdio_reserve_q(struct qdio_q *q)
+{
+	return atomic_return_add(1,&q->use_count);
+}
+
+static inline void 
+qdio_release_q(struct qdio_q *q)
+{
+	atomic_dec(&q->use_count);
+}
+
+static volatile inline void 
+qdio_set_slsb(volatile char *slsb, unsigned char value)
+{
+	xchg((char*)slsb,value);
+}
+
+static inline int 
+qdio_siga_sync(struct qdio_q *q)
+{
+	int cc;
+
+	QDIO_DBF_TEXT4(0,trace,"sigasync");
+	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+
+#ifdef QDIO_PERFORMANCE_STATS
+	perf_stats.siga_syncs++;
+#endif /* QDIO_PERFORMANCE_STATS */
+
+	if (q->is_input_q)
+		cc = do_siga_sync(q->irq, 0, q->mask);
+	else
+		cc = do_siga_sync(q->irq, q->mask, 0);
+
+	if (cc)
+		QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*));
+
+	return cc;
+}
+
+/* 
+ * returns QDIO_SIGA_ERROR_ACCESS_EXCEPTION as cc, when SIGA returns
+ * an access exception 
+ */
+static inline int 
+qdio_siga_output(struct qdio_q *q)
+{
+	int cc;
+	__u32 busy_bit;
+	__u64 start_time=0;
+
+#ifdef QDIO_PERFORMANCE_STATS
+	perf_stats.siga_outs++;
+#endif /* QDIO_PERFORMANCE_STATS */
+
+	QDIO_DBF_TEXT4(0,trace,"sigaout");
+	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+
+	for (;;) {
+		cc = do_siga_output(q->irq, q->mask, &busy_bit);
+//QDIO_PRINT_ERR("cc=%x, busy=%x\n",cc,busy_bit);
+		if ((cc==2) && (busy_bit) && (q->is_iqdio_q)) {
+			if (!start_time) 
+				start_time=NOW;
+			if ((NOW-start_time)>QDIO_BUSY_BIT_PATIENCE)
+				break;
+		} else
+			break;
+	}
+	
+	if ((cc==2) && (busy_bit)) 
+		cc |= QDIO_SIGA_ERROR_B_BIT_SET;
+
+	if (cc)
+		QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*));
+
+	return cc;
+}
+
+static inline int 
+qdio_siga_input(struct qdio_q *q)
+{
+	int cc;
+
+	QDIO_DBF_TEXT4(0,trace,"sigain");
+	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+
+#ifdef QDIO_PERFORMANCE_STATS
+	perf_stats.siga_ins++;
+#endif /* QDIO_PERFORMANCE_STATS */
+
+	cc = do_siga_input(q->irq, q->mask);
+	
+	if (cc)
+		QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*));
+
+	return cc;
+}
+
+/* locked by the locks in qdio_activate and qdio_cleanup */
+static __u32 * volatile 
+qdio_get_indicator(void)
+{
+	int i;
+
+	for (i=1;i<INDICATORS_PER_CACHELINE;i++)
+		if (!indicator_used[i]) {
+			indicator_used[i]=1;
+			return indicators+i;
+		}
+
+	return (__u32 * volatile) &spare_indicator;
+}
+
+/* locked by the locks in qdio_activate and qdio_cleanup */
+static void 
+qdio_put_indicator(__u32 *addr)
+{
+	int i;
+
+	if ( (addr) && (addr!=&spare_indicator) ) {
+		i=addr-indicators;
+		indicator_used[i]=0;
+	}
+}
+
+static inline volatile void 
+iqdio_clear_summary_bit(__u32 *location)
+{
+	QDIO_DBF_TEXT5(0,trace,"clrsummb");
+	QDIO_DBF_HEX5(0,trace,&location,sizeof(void*));
+
+	xchg(location,0);
+}
+
+static inline volatile void
+iqdio_set_summary_bit(__u32 *location)
+{
+	QDIO_DBF_TEXT5(0,trace,"setsummb");
+	QDIO_DBF_HEX5(0,trace,&location,sizeof(void*));
+
+	xchg(location,-1);
+}
+
+static inline void 
+iqdio_sched_tl(void)
+{
+	tasklet_hi_schedule(&iqdio_tasklet);
+}
+
+static inline void
+qdio_mark_iq(struct qdio_q *q)
+{
+	unsigned long flags;
+
+	QDIO_DBF_TEXT4(0,trace,"mark iq");
+	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+
+	spin_lock_irqsave(&iq_list_lock,flags);
+	if (atomic_read(&q->is_in_shutdown)) 
+		goto out_unlock;
+
+	if (!q->is_input_q)
+		goto out_unlock;
+
+	if ((q->list_prev) || (q->list_next)) 
+		goto out_unlock;
+
+	if (!iq_list) {
+		iq_list=q;
+		q->list_prev=q;
+		q->list_next=q;
+	} else {
+		q->list_next=iq_list;
+		q->list_prev=iq_list->list_prev;
+		iq_list->list_prev->list_next=q;
+		iq_list->list_prev=q;
+	}
+	spin_unlock_irqrestore(&iq_list_lock,flags);
+
+	iqdio_set_summary_bit((__u32*)q->dev_st_chg_ind);
+	iqdio_sched_tl();
+	return;
+out_unlock:
+	spin_unlock_irqrestore(&iq_list_lock,flags);
+	return;
+}
+
+static inline void
+qdio_mark_q(struct qdio_q *q)
+{
+	QDIO_DBF_TEXT4(0,trace,"mark q");
+	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+
+	if (atomic_read(&q->is_in_shutdown))
+		return;
+
+	tasklet_schedule(&q->tasklet);
+}
+
+static inline int
+qdio_stop_polling(struct qdio_q *q)
+{
+#ifdef QDIO_USE_PROCESSING_STATE
+	int gsf;
+
+	if (!atomic_swap(&q->polling,0)) 
+		return 1;
+
+	QDIO_DBF_TEXT4(0,trace,"stoppoll");
+	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+
+	/* show the card that we are not polling anymore */
+	if (!q->is_input_q)
+		return 1;
+
+	gsf=GET_SAVED_FRONTIER(q);
+	set_slsb(&q->slsb.acc.val[(gsf+QDIO_MAX_BUFFERS_PER_Q-1)&
+				  (QDIO_MAX_BUFFERS_PER_Q-1)],
+		 SLSB_P_INPUT_NOT_INIT);
+	/* 
+	 * we don't issue this SYNC_MEMORY, as we trust Rick T and
+	 * moreover will not use the PROCESSING state, so q->polling was 0
+	 */
+	/*SYNC_MEMORY;*/
+	if (q->slsb.acc.val[gsf]!=SLSB_P_INPUT_PRIMED)
+		return 1;
+	/* 
+	 * set our summary bit again, as otherwise there is a
+	 * small window we can miss between resetting it and
+	 * checking for PRIMED state 
+	 */
+	if (q->is_iqdio_q)
+		iqdio_set_summary_bit((__u32*)q->dev_st_chg_ind);
+	return 0;
+
+#else /* QDIO_USE_PROCESSING_STATE */
+	return 1;
+#endif /* QDIO_USE_PROCESSING_STATE */
+}
+
+/* 
+ * see the comment in do_QDIO and before qdio_reserve_q about the
+ * sophisticated locking outside of unmark_q, so that we don't need to
+ * disable the interrupts :-) 
+*/
+static inline void
+qdio_unmark_q(struct qdio_q *q)
+{
+	unsigned long flags;
+
+	QDIO_DBF_TEXT4(0,trace,"unmark q");
+	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+
+	if ((!q->list_prev)||(!q->list_next))
+		return;
+
+	if ((q->is_iqdio_q)&&(q->is_input_q)) {
+		/* iQDIO */
+		spin_lock_irqsave(&iq_list_lock,flags);
+		if (q->list_next==q) {
+			/* q was the only interesting q */
+			iq_list=NULL;
+			q->list_next=NULL;
+			q->list_prev=NULL;
+		} else {
+			q->list_next->list_prev=q->list_prev;
+			q->list_prev->list_next=q->list_next;
+			iq_list=q->list_next;
+			q->list_next=NULL;
+			q->list_prev=NULL;
+		}
+		spin_unlock_irqrestore(&iq_list_lock,flags);
+	}
+}
+
+static inline unsigned long 
+iqdio_clear_global_summary(void)
+{
+	unsigned long time;
+
+	QDIO_DBF_TEXT5(0,trace,"clrglobl");
+	
+	time = do_clear_global_summary();
+
+	QDIO_DBF_HEX5(0,trace,&time,sizeof(unsigned long));
+
+	return time;
+}
+
+/************************* INBOUND ROUTINES *******************************/
+
+
+inline static int
+qdio_get_inbound_buffer_frontier(struct qdio_q *q)
+{
+	int f,f_mod_no;
+	volatile char *slsb;
+	int first_not_to_check;
+	char dbf_text[15];
+
+	QDIO_DBF_TEXT4(0,trace,"getibfro");
+	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+
+	slsb=&q->slsb.acc.val[0];
+	f_mod_no=f=q->first_to_check;
+	/* 
+	 * we don't check 128 buffers, as otherwise qdio_has_inbound_q_moved
+	 * would return 0 
+	 */
+	first_not_to_check=f+qdio_min(atomic_read(&q->number_of_buffers_used),
+				      (QDIO_MAX_BUFFERS_PER_Q-1));
+
+	/* 
+	 * we don't use this one, as a PCI or we after a thin interrupt
+	 * will sync the queues
+	 */
+	/* SYNC_MEMORY;*/
+
+check_next:
+	f_mod_no=f&(QDIO_MAX_BUFFERS_PER_Q-1);
+	if (f==first_not_to_check) 
+		goto out;
+	switch (slsb[f_mod_no]) {
+
+	/* CU_EMPTY means frontier is reached */
+	case SLSB_CU_INPUT_EMPTY:
+		QDIO_DBF_TEXT5(0,trace,"inptempt");
+		break;
+
+	/* P_PRIMED means set slsb to P_PROCESSING and move on */
+	case SLSB_P_INPUT_PRIMED:
+		QDIO_DBF_TEXT5(0,trace,"inptprim");
+
+#ifdef QDIO_USE_PROCESSING_STATE
+		/* 
+		 * as soon as running under VM, polling the input queues will
+		 * kill VM in terms of CP overhead 
+		 */
+		if (q->siga_sync) {
+			set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT);
+		} else {
+			set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_PROCESSING);
+			atomic_set(&q->polling,1);
+		}
+#else /* QDIO_USE_PROCESSING_STATE */
+		set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT);
+#endif /* QDIO_USE_PROCESSING_STATE */
+		/* 
+		 * not needed, as the inbound queue will be synced on the next
+		 * siga-r
+		 */
+		/*SYNC_MEMORY;*/
+		f++;
+		atomic_dec(&q->number_of_buffers_used);
+		goto check_next;
+
+	case SLSB_P_INPUT_NOT_INIT:
+	case SLSB_P_INPUT_PROCESSING:
+		QDIO_DBF_TEXT5(0,trace,"inpnipro");
+		break;
+
+	/* P_ERROR means frontier is reached, break and report error */
+	case SLSB_P_INPUT_ERROR:
+		sprintf(dbf_text,"inperr%2x",f_mod_no);
+		QDIO_DBF_TEXT3(1,trace,dbf_text);
+		QDIO_DBF_HEX2(1,sbal,q->sbal[f_mod_no],256);
+
+		/* kind of process the buffer */
+		set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT);
+
+		if (q->qdio_error)
+			q->error_status_flags|=
+				QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR;
+		q->qdio_error=SLSB_P_INPUT_ERROR;
+		q->error_status_flags|=QDIO_STATUS_LOOK_FOR_ERROR;
+
+		/* we increment the frontier, as this buffer
+		 * was processed obviously */
+		f_mod_no=(f_mod_no+1)&(QDIO_MAX_BUFFERS_PER_Q-1);
+		atomic_dec(&q->number_of_buffers_used);
+
+		break;
+
+	/* everything else means frontier not changed (HALTED or so) */
+	default: 
+		break;
+	}
+out:
+	q->first_to_check=f_mod_no;
+
+	QDIO_DBF_HEX4(0,trace,&q->first_to_check,sizeof(int));
+
+	return q->first_to_check;
+}
+
+inline static int
+qdio_has_inbound_q_moved(struct qdio_q *q)
+{
+	int i;
+
+#ifdef QDIO_PERFORMANCE_STATS
+	static int old_pcis=0;
+	static int old_thinints=0;
+
+	if ((old_pcis==perf_stats.pcis)&&(old_thinints==perf_stats.thinints))
+		perf_stats.start_time_inbound=NOW;
+	else
+		old_pcis=perf_stats.pcis;
+#endif /* QDIO_PERFORMANCE_STATS */
+
+	i=qdio_get_inbound_buffer_frontier(q);
+	if ( (i!=GET_SAVED_FRONTIER(q)) ||
+	     (q->error_status_flags&QDIO_STATUS_LOOK_FOR_ERROR) ) {
+		SAVE_FRONTIER(q,i);
+		if ((!q->siga_sync)&&(!q->hydra_gives_outbound_pcis))
+			SAVE_TIMESTAMP(q);
+
+		QDIO_DBF_TEXT4(0,trace,"inhasmvd");
+		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+		return 1;
+	} else {
+		QDIO_DBF_TEXT4(0,trace,"inhsntmv");
+		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+		return 0;
+	}
+}
+
+/* means, no more buffers to be filled */
+inline static int
+iqdio_is_inbound_q_done(struct qdio_q *q)
+{
+	int no_used;
+#ifdef QDIO_DBF_LIKE_HELL
+	char dbf_text[15];
+#endif /* QDIO_DBF_LIKE_HELL */
+
+	no_used=atomic_read(&q->number_of_buffers_used);
+
+	/* propagate the change from 82 to 80 through VM */
+	SYNC_MEMORY;
+
+#ifdef QDIO_DBF_LIKE_HELL
+	if (no_used) {
+		sprintf(dbf_text,"iqisnt%02x",no_used);
+		QDIO_DBF_TEXT4(0,trace,dbf_text);
+	} else {
+		QDIO_DBF_TEXT4(0,trace,"iniqisdo");
+	}
+	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+#endif /* QDIO_DBF_LIKE_HELL */
+
+	if (!no_used)
+		return 1;
+
+	if (!q->siga_sync)
+		/* we'll check for more primed buffers in qeth_stop_polling */
+		return 0;
+
+	if (q->slsb.acc.val[q->first_to_check]!=SLSB_P_INPUT_PRIMED)
+		/* 
+		 * nothing more to do, if next buffer is not PRIMED.
+		 * note that we did a SYNC_MEMORY before, that there
+		 * has been a sychnronization.
+		 * we will return 0 below, as there is nothing to do
+		 * (stop_polling not necessary, as we have not been
+		 * using the PROCESSING state 
+		 */
+		return 0;
+
+	/* 
+	 * ok, the next input buffer is primed. that means, that device state 
+	 * change indicator and adapter local summary are set, so we will find
+	 * it next time.
+	 * we will return 0 below, as there is nothing to do, except scheduling
+	 * ourselves for the next time. 
+	 */
+	iqdio_set_summary_bit((__u32*)q->dev_st_chg_ind);
+	iqdio_sched_tl();
+	return 0;
+}
+
+inline static int
+qdio_is_inbound_q_done(struct qdio_q *q)
+{
+	int no_used;
+#ifdef QDIO_DBF_LIKE_HELL
+	char dbf_text[15];
+#endif /* QDIO_DBF_LIKE_HELL */
+
+	no_used=atomic_read(&q->number_of_buffers_used);
+
+	/* 
+	 * we need that one for synchronization with Hydra, as Hydra
+	 * does a kind of PCI avoidance 
+	 */
+	SYNC_MEMORY;
+
+	if (!no_used) {
+#ifdef QDIO_DBF_LIKE_HELL
+		QDIO_DBF_TEXT4(0,trace,"inqisdnA");
+		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+		QDIO_DBF_TEXT4(0,trace,dbf_text);
+#endif /* QDIO_DBF_LIKE_HELL */
+		return 1;
+	}
+
+	if (q->slsb.acc.val[q->first_to_check]==SLSB_P_INPUT_PRIMED) {
+		/* we got something to do */
+		QDIO_DBF_TEXT4(0,trace,"inqisntA");
+		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+		return 0;
+	}
+
+	/* on VM, we don't poll, so the q is always done here */
+	if (q->siga_sync)
+		return 1;
+	if (q->hydra_gives_outbound_pcis)
+		return 1;
+
+	/* 
+	 * at this point we know, that inbound first_to_check
+	 * has (probably) not moved (see qdio_inbound_processing) 
+	 */
+	if (NOW>GET_SAVED_TIMESTAMP(q)+q->timing.threshold) {
+#ifdef QDIO_DBF_LIKE_HELL
+		QDIO_DBF_TEXT4(0,trace,"inqisdon");
+		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+		sprintf(dbf_text,"pf%02xcn%02x",q->first_to_check,no_used);
+		QDIO_DBF_TEXT4(0,trace,dbf_text);
+#endif /* QDIO_DBF_LIKE_HELL */
+		return 1;
+	} else {
+#ifdef QDIO_DBF_LIKE_HELL
+		QDIO_DBF_TEXT4(0,trace,"inqisntd");
+		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+		sprintf(dbf_text,"pf%02xcn%02x",q->first_to_check,no_used);
+		QDIO_DBF_TEXT4(0,trace,dbf_text);
+#endif /* QDIO_DBF_LIKE_HELL */
+		return 0;
+	}
+}
+
+inline static void
+qdio_kick_inbound_handler(struct qdio_q *q)
+{
+	int count, start, end, real_end, i;
+#ifdef QDIO_DBF_LIKE_HELL
+	char dbf_text[15];
+
+	QDIO_DBF_TEXT4(0,trace,"kickinh");
+	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+#endif /* QDIO_DBF_LIKE_HELL */
+
+  	start=q->first_element_to_kick;
+ 	real_end=q->first_to_check;
+ 	end=(real_end+QDIO_MAX_BUFFERS_PER_Q-1)&(QDIO_MAX_BUFFERS_PER_Q-1);
+ 
+ 	i=start;
+	count=0;
+ 	while (1) {
+ 		count++;
+ 		if (i==end) break;
+ 		i=(i+1)&(QDIO_MAX_BUFFERS_PER_Q-1);
+ 	}
+
+#ifdef QDIO_DBF_LIKE_HELL
+	sprintf(dbf_text,"s=%2xc=%2x",start,count);
+	QDIO_DBF_TEXT4(0,trace,dbf_text);
+#endif /* QDIO_DBF_LIKE_HELL */
+
+	if (q->state==QDIO_IRQ_STATE_ACTIVE)
+		q->handler(q->irq,
+			   QDIO_STATUS_INBOUND_INT|q->error_status_flags,
+			   q->qdio_error,q->siga_error,q->q_no,start,count,
+			   q->int_parm);
+
+	/* for the next time: */
+	q->first_element_to_kick=real_end;
+	q->qdio_error=0;
+	q->siga_error=0;
+	q->error_status_flags=0;
+
+#ifdef QDIO_PERFORMANCE_STATS
+	perf_stats.inbound_time+=NOW-perf_stats.start_time_inbound;
+	perf_stats.inbound_cnt++;
+#endif /* QDIO_PERFORMANCE_STATS */
+}
+
+static inline void
+iqdio_inbound_processing(struct qdio_q *q)
+{
+	QDIO_DBF_TEXT4(0,trace,"iqinproc");
+	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+
+	/* 
+	 * we first want to reserve the q, so that we know, that we don't
+	 * interrupt ourselves and call qdio_unmark_q, as is_in_shutdown might
+	 * be set 
+	 */
+	if (qdio_reserve_q(q)) {
+		qdio_release_q(q);
+#ifdef QDIO_PERFORMANCE_STATS
+		ii_p_c++;
+#endif /* QDIO_PERFORMANCE_STATS */
+		/* 
+		 * as we might just be about to stop polling, we make
+		 * sure that we check again at least once more 
+		 */
+		iqdio_sched_tl();
+		return;
+	}
+#ifdef QDIO_PERFORMANCE_STATS
+	ii_p_nc++;
+#endif /* QDIO_PERFORMANCE_STATS */
+	if (atomic_read(&q->is_in_shutdown)) {
+		qdio_unmark_q(q);
+		goto out;
+	}
+
+	if (!(*(q->dev_st_chg_ind)))
+		goto out;
+
+	iqdio_clear_summary_bit((__u32*)q->dev_st_chg_ind);
+
+	if (!q->siga_sync_done_on_thinints)
+			SYNC_MEMORY;
+
+	if (!qdio_has_inbound_q_moved(q))
+		goto out;
+
+	qdio_kick_inbound_handler(q);
+	if (iqdio_is_inbound_q_done(q))
+		if (!qdio_stop_polling(q)) {
+			/* 
+			 * we set the flags to get into the stuff next time,
+			 * see also comment in qdio_stop_polling 
+			 */
+			iqdio_set_summary_bit((__u32*)q->dev_st_chg_ind);
+			iqdio_sched_tl();
+		}
+out:
+	qdio_release_q(q);
+}
+
+static void
+qdio_inbound_processing(struct qdio_q *q)
+{
+	int q_laps=0;
+
+	QDIO_DBF_TEXT4(0,trace,"qinproc");
+	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+
+	if (qdio_reserve_q(q)) {
+		qdio_release_q(q);
+#ifdef QDIO_PERFORMANCE_STATS
+		i_p_c++;
+#endif /* QDIO_PERFORMANCE_STATS */
+		/* as we're sissies, we'll check next time */
+		if (!atomic_read(&q->is_in_shutdown)) {
+			qdio_mark_q(q);
+			QDIO_DBF_TEXT4(0,trace,"busy,agn");
+		}
+		return;
+	}
+#ifdef QDIO_PERFORMANCE_STATS
+	i_p_nc++;
+	perf_stats.tl_runs++;
+#endif /* QDIO_PERFORMANCE_STATS */
+
+again:
+	if (qdio_has_inbound_q_moved(q)) {
+		qdio_kick_inbound_handler(q);
+		if (!qdio_stop_polling(q)) {
+			q_laps++;
+			if (q_laps<QDIO_Q_LAPS) 
+				goto again;
+		}
+		qdio_mark_q(q);
+	} else {
+		if (!qdio_is_inbound_q_done(q)) 
+                        /* means poll time is not yet over */
+			qdio_mark_q(q);
+	}
+
+	qdio_release_q(q);
+}
+
+/************************* OUTBOUND ROUTINES *******************************/
+
+inline static int
+qdio_get_outbound_buffer_frontier(struct qdio_q *q)
+{
+	int f,f_mod_no;
+	volatile char *slsb;
+	int first_not_to_check;
+	char dbf_text[15];
+
+	QDIO_DBF_TEXT4(0,trace,"getobfro");
+	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+
+	slsb=&q->slsb.acc.val[0];
+	f_mod_no=f=q->first_to_check;
+	/* 
+	 * f points to already processed elements, so f+no_used is correct...
+	 * ... but: we don't check 128 buffers, as otherwise
+	 * qdio_has_outbound_q_moved would return 0 
+	 */
+	first_not_to_check=f+qdio_min(atomic_read(&q->number_of_buffers_used),
+				      (QDIO_MAX_BUFFERS_PER_Q-1));
+
+	if ((!q->is_iqdio_q)&&(!q->hydra_gives_outbound_pcis))
+		SYNC_MEMORY;
+
+check_next:
+	if (f==first_not_to_check) 
+		goto out;
+
+	switch(slsb[f_mod_no]) {
+
+        /* the hydra has not fetched the output yet */
+	case SLSB_CU_OUTPUT_PRIMED:
+		QDIO_DBF_TEXT5(0,trace,"outpprim");
+		break;
+
+	/* the hydra got it */
+	case SLSB_P_OUTPUT_EMPTY:
+		atomic_dec(&q->number_of_buffers_used);
+		f++;
+		f_mod_no=f&(QDIO_MAX_BUFFERS_PER_Q-1);
+		QDIO_DBF_TEXT5(0,trace,"outpempt");
+		goto check_next;
+
+	case SLSB_P_OUTPUT_ERROR:
+		QDIO_DBF_TEXT3(0,trace,"outperr");
+		sprintf(dbf_text,"%x-%x-%x",f_mod_no,
+			q->sbal[f_mod_no]->element[14].sbalf.value,
+			q->sbal[f_mod_no]->element[15].sbalf.value);
+		QDIO_DBF_TEXT3(1,trace,dbf_text);
+		QDIO_DBF_HEX2(1,sbal,q->sbal[f_mod_no],256);
+
+		/* kind of process the buffer */
+		set_slsb(&q->slsb.acc.val[f_mod_no], SLSB_P_OUTPUT_NOT_INIT);
+
+		/* 
+		 * we increment the frontier, as this buffer
+		 * was processed obviously 
+		 */
+		atomic_dec(&q->number_of_buffers_used);
+		f_mod_no=(f_mod_no+1)&(QDIO_MAX_BUFFERS_PER_Q-1);
+
+		if (q->qdio_error)
+			q->error_status_flags|=
+				QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR;
+		q->qdio_error=SLSB_P_OUTPUT_ERROR;
+		q->error_status_flags|=QDIO_STATUS_LOOK_FOR_ERROR;
+
+		break;
+
+	/* no new buffers */
+	default:
+		QDIO_DBF_TEXT5(0,trace,"outpni");
+	}
+out:
+	return (q->first_to_check=f_mod_no);
+}
+
+/* all buffers are processed */
+inline static int
+qdio_is_outbound_q_done(struct qdio_q *q)
+{
+	int no_used;
+#ifdef QDIO_DBF_LIKE_HELL
+	char dbf_text[15];
+#endif /* QDIO_DBF_LIKE_HELL */
+
+	no_used=atomic_read(&q->number_of_buffers_used);
+
+#ifdef QDIO_DBF_LIKE_HELL
+	if (no_used) {
+		sprintf(dbf_text,"oqisnt%02x",no_used);
+		QDIO_DBF_TEXT4(0,trace,dbf_text);
+	} else {
+		QDIO_DBF_TEXT4(0,trace,"oqisdone");
+	}
+	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+#endif /* QDIO_DBF_LIKE_HELL */
+	return (no_used==0);
+}
+
+inline static int
+qdio_has_outbound_q_moved(struct qdio_q *q)
+{
+	int i;
+
+	i=qdio_get_outbound_buffer_frontier(q);
+
+	if ( (i!=GET_SAVED_FRONTIER(q)) ||
+	     (q->error_status_flags&QDIO_STATUS_LOOK_FOR_ERROR) ) {
+		SAVE_FRONTIER(q,i);
+		SAVE_TIMESTAMP(q);
+		QDIO_DBF_TEXT4(0,trace,"oqhasmvd");
+		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+		return 1;
+	} else {
+		QDIO_DBF_TEXT4(0,trace,"oqhsntmv");
+		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+		return 0;
+	}
+}
+
+inline static void
+qdio_kick_outbound_q(struct qdio_q *q)
+{
+	int result;
+
+	QDIO_DBF_TEXT4(0,trace,"kickoutq");
+	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+
+	if (!q->siga_out)
+		return;
+
+	result=qdio_siga_output(q);
+
+	if (!result)
+		return;
+
+	if (q->siga_error)
+		q->error_status_flags|=QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR;
+	q->error_status_flags |= QDIO_STATUS_LOOK_FOR_ERROR;
+	q->siga_error=result;
+}
+
+inline static void
+qdio_kick_outbound_handler(struct qdio_q *q)
+{
+	int start, end, real_end, count;
+	
+#ifdef QDIO_DBF_LIKE_HELL
+	char dbf_text[15];
+#endif /* QDIO_DBF_LIKE_HELL */
+
+	start = q->first_element_to_kick;
+	/* last_move_ftc was just updated */
+	real_end = GET_SAVED_FRONTIER(q);
+	end = (real_end+QDIO_MAX_BUFFERS_PER_Q-1)&
+		(QDIO_MAX_BUFFERS_PER_Q-1);
+	count = (end+QDIO_MAX_BUFFERS_PER_Q+1-start)&
+		(QDIO_MAX_BUFFERS_PER_Q-1);
+
+	QDIO_DBF_TEXT4(0,trace,"kickouth");
+	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+
+#ifdef QDIO_DBF_LIKE_HELL
+	sprintf(dbf_text,"s=%2xc=%2x",start,count);
+	QDIO_DBF_TEXT4(0,trace,dbf_text);
+#endif /* QDIO_DBF_LIKE_HELL */
+
+	if (q->state==QDIO_IRQ_STATE_ACTIVE)
+		q->handler(q->irq,QDIO_STATUS_OUTBOUND_INT|
+			   q->error_status_flags,
+			   q->qdio_error,q->siga_error,q->q_no,start,count,
+			   q->int_parm);
+
+	/* for the next time: */
+	q->first_element_to_kick=real_end;
+	q->qdio_error=0;
+	q->siga_error=0;
+	q->error_status_flags=0;
+}
+
+static void qdio_outbound_processing(struct qdio_q *q)
+{
+	QDIO_DBF_TEXT4(0,trace,"qoutproc");
+	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
+
+	if (qdio_reserve_q(q)) {
+		qdio_release_q(q);
+#ifdef QDIO_PERFORMANCE_STATS
+		o_p_c++;
+#endif /* QDIO_PERFORMANCE_STATS */
+		/* as we're sissies, we'll check next time */
+		if (!atomic_read(&q->is_in_shutdown)) {
+			qdio_mark_q(q);
+			QDIO_DBF_TEXT4(0,trace,"busy,agn");
+		}
+		return;
+	}
+#ifdef QDIO_PERFORMANCE_STATS
+	o_p_nc++;
+	perf_stats.tl_runs++;
+#endif /* QDIO_PERFORMANCE_STATS */
+
+	if (qdio_has_outbound_q_moved(q))
+		qdio_kick_outbound_handler(q);
+
+	if (q->is_iqdio_q) {
+		/* 
+		 * for asynchronous queues, we better check, if the fill
+		 * level is too high 
+		 */
+		if (atomic_read(&q->number_of_buffers_used)>
+		    IQDIO_FILL_LEVEL_TO_POLL)
+			qdio_mark_q(q);
+
+	} else if (!q->hydra_gives_outbound_pcis)
+		if (!qdio_is_outbound_q_done(q))
+			qdio_mark_q(q);
+
+	qdio_release_q(q);
+}
+
+/************************* MAIN ROUTINES *******************************/
+
+#ifdef QDIO_USE_PROCESSING_STATE
+static inline int
+iqdio_do_inbound_checks(struct qdio_q *q, int q_laps)
+{
+	if (!q) {
+		iqdio_sched_tl();
+		return 0;
+	}
+
+	/* 
+	 * under VM, we have not used the PROCESSING state, so no
+	 * need to stop polling 
+	 */
+	if (q->siga_sync)
+		return 2;
+
+	if (qdio_reserve_q(q)) {
+		qdio_release_q(q);
+#ifdef QDIO_PERFORMANCE_STATS
+		ii_p_c++;
+#endif /* QDIO_PERFORMANCE_STATS */
+		/* 
+		 * as we might just be about to stop polling, we make
+		 * sure that we check again at least once more 
+		 */
+		
+		/* 
+		 * sanity -- we'd get here without setting the
+		 * dev st chg ind 
+		 */
+		iqdio_set_summary_bit((__u32*)q->dev_st_chg_ind);
+		iqdio_sched_tl();
+		return 0;
+	}
+	if (qdio_stop_polling(q)) {
+		qdio_release_q(q);
+		return 2;
+	}		
+	if (q_laps<QDIO_Q_LAPS-1) {
+		qdio_release_q(q);
+		return 3;
+	}
+	/* 
+	 * we set the flags to get into the stuff
+	 * next time, see also comment in qdio_stop_polling 
+	 */
+	iqdio_set_summary_bit((__u32*)q->dev_st_chg_ind);
+	iqdio_sched_tl();
+	qdio_release_q(q);
+	return 1;
+	
+}
+#endif /* QDIO_USE_PROCESSING_STATE */
+
+static inline void
+iqdio_inbound_checks(void)
+{
+	struct qdio_q *q;
+#ifdef QDIO_USE_PROCESSING_STATE
+	int q_laps=0;
+#endif /* QDIO_USE_PROCESSING_STATE */
+
+	QDIO_DBF_TEXT4(0,trace,"iqdinbck");
+	QDIO_DBF_TEXT5(0,trace,"iqlocsum");
+
+#ifdef QDIO_USE_PROCESSING_STATE
+again:
+#endif /* QDIO_USE_PROCESSING_STATE */
+
+	q=(struct qdio_q*)iq_list;
+	do {
+		if (!q)
+			break;
+		iqdio_inbound_processing(q);
+		q=(struct qdio_q*)q->list_next;
+	} while (q!=(struct qdio_q*)iq_list);
+
+#ifdef QDIO_USE_PROCESSING_STATE
+	q=(struct qdio_q*)iq_list;
+	do {
+		int ret;
+
+		ret = iqdio_do_inbound_checks(q, q_laps);
+		switch (ret) {
+		case 0:
+			return;
+		case 1:
+			q_laps++;
+		case 2:
+			q = (struct qdio_q*)q->list_next;
+			break;
+		default:
+			q_laps++;
+			goto again;
+		}
+	} while (q!=(struct qdio_q*)iq_list);
+#endif /* QDIO_USE_PROCESSING_STATE */
+}
+
+static void
+iqdio_check_for_polling(void)
+{
+}
+
+static void
+iqdio_tl(unsigned long data)
+{
+	QDIO_DBF_TEXT4(0,trace,"iqdio_tl");
+
+#ifdef QDIO_PERFORMANCE_STATS
+	perf_stats.tl_runs++;
+#endif /* QDIO_PERFORMANCE_STATS */
+
+	iqdio_inbound_checks();
+	iqdio_check_for_polling();
+}
+
+/********************* GENERAL HELPER_ROUTINES ***********************/
+
+static void
+qdio_release_irq_memory(struct qdio_irq *irq_ptr)
+{
+	int i;
+	int available;
+
+	for (i=0;i<QDIO_MAX_QUEUES_PER_IRQ;i++) {
+		if (!irq_ptr->input_qs[i])
+			goto next;
+		available=0;
+
+		if (irq_ptr->input_qs[i]->slib)
+			kfree(irq_ptr->input_qs[i]->slib);
+			kfree(irq_ptr->input_qs[i]);
+
+next:
+		if (!irq_ptr->output_qs[i])
+			continue;
+		available=0;
+
+		if (irq_ptr->output_qs[i]->slib)
+			kfree(irq_ptr->output_qs[i]->slib);
+		kfree(irq_ptr->output_qs[i]);
+
+	}
+	if (irq_ptr->qdr)
+		kfree(irq_ptr->qdr);
+	kfree(irq_ptr);
+	QDIO_DBF_TEXT3(0,setup,"MOD_DEC_");
+	MOD_DEC_USE_COUNT;
+}
+
+static void
+qdio_set_impl_params(struct qdio_irq *irq_ptr,
+		     unsigned int qib_param_field_format,
+		     /* pointer to 128 bytes or NULL, if no param field */
+		     unsigned char *qib_param_field,
+		     /* pointer to no_queues*128 words of data or NULL */
+		     unsigned int no_input_qs,
+		     unsigned int no_output_qs,
+		     unsigned long *input_slib_elements,
+		     unsigned long *output_slib_elements)
+{
+	int i,j;
+
+	if (!irq_ptr)
+		return;
+
+	irq_ptr->qib.pfmt=qib_param_field_format;
+	if (qib_param_field)
+		memcpy(irq_ptr->qib.parm,qib_param_field,
+		       QDIO_MAX_BUFFERS_PER_Q);
+
+	if (input_slib_elements)
+		for (i=0;i<no_input_qs;i++) {
+			for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++)
+				irq_ptr->input_qs[i]->slib->slibe[j].parms=
+					input_slib_elements[
+						i*QDIO_MAX_BUFFERS_PER_Q+j];
+		}
+	if (output_slib_elements)
+		for (i=0;i<no_output_qs;i++) {
+			for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++)
+				irq_ptr->output_qs[i]->slib->slibe[j].parms=
+					output_slib_elements[
+						i*QDIO_MAX_BUFFERS_PER_Q+j];
+		}
+}
+
+static int
+qdio_alloc_qs(struct qdio_irq *irq_ptr, int no_input_qs, int no_output_qs,
+	      qdio_handler_t *input_handler,
+	      qdio_handler_t *output_handler,
+	      unsigned long int_parm,int q_format,
+	      unsigned long flags,
+	      void **inbound_sbals_array,
+	      void **outbound_sbals_array)
+{
+	struct qdio_q *q;
+	int i,j,result=0;
+	char dbf_text[20]; /* see qdio_initialize */
+	void *ptr;
+	int available;
+
+	for (i=0;i<no_input_qs;i++) {
+		q=kmalloc(sizeof(struct qdio_q),GFP_KERNEL);
+
+		if (!q) {
+			QDIO_PRINT_ERR("kmalloc of q failed!\n");
+			goto out;
+		}
+		memset(q,0,sizeof(struct qdio_q));
+
+		sprintf(dbf_text,"in-q%4x",i);
+		QDIO_DBF_TEXT0(0,setup,dbf_text);
+		QDIO_DBF_HEX0(0,setup,&q,sizeof(void*));
+
+		q->slib=kmalloc(PAGE_SIZE,GFP_KERNEL);
+		if (!q->slib) {
+			QDIO_PRINT_ERR("kmalloc of slib failed!\n");
+			goto out;
+		}
+		memset(q->slib,0,PAGE_SIZE);
+		q->sl=(struct sl*)(((char*)q->slib)+PAGE_SIZE/2);
+
+		available=0;
+
+		for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++)
+			q->sbal[j]=*(inbound_sbals_array++);
+
+                q->queue_type=q_format;
+		q->int_parm=int_parm;
+		irq_ptr->input_qs[i]=q;
+		q->irq=irq_ptr->irq;
+		q->mask=1<<(31-i);
+		q->q_no=i;
+		q->is_input_q=1;
+		q->first_to_check=0;
+		q->last_move_ftc=0;
+		q->handler=input_handler;
+		q->dev_st_chg_ind=irq_ptr->dev_st_chg_ind;
+
+		q->tasklet.data=(unsigned long)q;
+		q->tasklet.func=(void(*)(unsigned long))
+			(
+			(q_format==QDIO_IQDIO_QFMT)?&iqdio_inbound_processing:
+			&qdio_inbound_processing);
+
+/*		for (j=0;j<QDIO_STATS_NUMBER;j++)
+			q->timing.last_transfer_times[j]=(qdio_get_micros()/
+							  QDIO_STATS_NUMBER)*j;
+		q->timing.last_transfer_index=QDIO_STATS_NUMBER-1;
+*/
+
+		/* fill in slib */
+		if (i>0) irq_ptr->input_qs[i-1]->slib->nsliba=
+				 (unsigned long)(q->slib);
+		q->slib->sla=(unsigned long)(q->sl);
+		q->slib->slsba=(unsigned long)(&q->slsb.acc.val[0]);
+
+		/* fill in sl */
+		for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++)
+			q->sl->element[j].sbal=(unsigned long)(q->sbal[j]);
+
+		QDIO_DBF_TEXT2(0,setup,"sl-sb-b0");
+		ptr=(void*)q->sl;
+		QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*));
+		ptr=(void*)&q->slsb;
+		QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*));
+		ptr=(void*)q->sbal[0];
+		QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*));
+
+		/* fill in slsb */
+		for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
+			set_slsb(&q->slsb.acc.val[j],
+		   		 SLSB_P_INPUT_NOT_INIT);
+/*			q->sbal[j]->element[1].sbalf.i1.key=QDIO_STORAGE_KEY;*/
+		}
+	}
+
+	for (i=0;i<no_output_qs;i++) {
+		q=kmalloc(sizeof(struct qdio_q),GFP_KERNEL);
+
+		if (!q) {
+			goto out;
+		}
+		memset(q,0,sizeof(struct qdio_q));
+
+		sprintf(dbf_text,"outq%4x",i);
+		QDIO_DBF_TEXT0(0,setup,dbf_text);
+		QDIO_DBF_HEX0(0,setup,&q,sizeof(void*));
+
+		q->slib=kmalloc(PAGE_SIZE,GFP_KERNEL);
+		if (!q->slib) {
+			QDIO_PRINT_ERR("kmalloc of slib failed!\n");
+			goto out;
+		}
+		memset(q->slib,0,PAGE_SIZE);
+		q->sl=(struct sl*)(((char*)q->slib)+PAGE_SIZE/2);
+
+		available=0;
+		
+		for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++)
+			q->sbal[j]=*(outbound_sbals_array++);
+
+                q->queue_type=q_format;
+		q->int_parm=int_parm;
+		irq_ptr->output_qs[i]=q;
+		q->is_input_q=0;
+		q->irq=irq_ptr->irq;
+		q->mask=1<<(31-i);
+		q->q_no=i;
+		q->first_to_check=0;
+		q->last_move_ftc=0;
+		q->handler=output_handler;
+
+		q->tasklet.data=(unsigned long)q;
+		q->tasklet.func=(void(*)(unsigned long))
+			&qdio_outbound_processing;
+
+		/* fill in slib */
+		if (i>0) irq_ptr->output_qs[i-1]->slib->nsliba=
+				 (unsigned long)(q->slib);
+		q->slib->sla=(unsigned long)(q->sl);
+		q->slib->slsba=(unsigned long)(&q->slsb.acc.val[0]);
+
+		/* fill in sl */
+		for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++)
+			q->sl->element[j].sbal=(unsigned long)(q->sbal[j]);
+
+		QDIO_DBF_TEXT2(0,setup,"sl-sb-b0");
+		ptr=(void*)q->sl;
+		QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*));
+		ptr=(void*)&q->slsb;
+		QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*));
+		ptr=(void*)q->sbal[0];
+		QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*));
+
+		/* fill in slsb */
+		for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
+			set_slsb(&q->slsb.acc.val[j],
+		   		 SLSB_P_OUTPUT_NOT_INIT);
+/*			q->sbal[j]->element[1].sbalf.i1.key=QDIO_STORAGE_KEY;*/
+		}
+	}
+
+	result=1;
+out:
+	return result;
+}
+
+static void
+qdio_fill_thresholds(struct qdio_irq *irq_ptr,
+		     unsigned int no_input_qs,
+		     unsigned int no_output_qs,
+		     unsigned int min_input_threshold,
+		     unsigned int max_input_threshold,
+		     unsigned int min_output_threshold,
+		     unsigned int max_output_threshold)
+{
+	int i;
+	struct qdio_q *q;
+
+	for (i=0;i<no_input_qs;i++) {
+		q=irq_ptr->input_qs[i];
+		q->timing.threshold=max_input_threshold;
+/*		for (j=0;j<QDIO_STATS_CLASSES;j++) {
+			q->threshold_classes[j].threshold=
+				min_input_threshold+
+				(max_input_threshold-min_input_threshold)/
+				QDIO_STATS_CLASSES;
+		}
+		qdio_use_thresholds(q,QDIO_STATS_CLASSES/2);*/
+	}
+	for (i=0;i<no_output_qs;i++) {
+		q=irq_ptr->output_qs[i];
+		q->timing.threshold=max_output_threshold;
+/*		for (j=0;j<QDIO_STATS_CLASSES;j++) {
+			q->threshold_classes[j].threshold=
+				min_output_threshold+
+				(max_output_threshold-min_output_threshold)/
+				QDIO_STATS_CLASSES;
+		}
+		qdio_use_thresholds(q,QDIO_STATS_CLASSES/2);*/
+	}
+}
+
+static int
+iqdio_thinint_handler(__u32 intparm)
+{
+	QDIO_DBF_TEXT4(0,trace,"thin_int");
+
+#ifdef QDIO_PERFORMANCE_STATS
+	perf_stats.thinints++;
+	perf_stats.start_time_inbound=NOW;
+#endif /* QDIO_PERFORMANCE_STATS */
+	/* VM will do the SVS for us */
+	if (!MACHINE_IS_VM)
+		iqdio_clear_global_summary();
+
+	iqdio_inbound_checks();
+	iqdio_check_for_polling();
+	return 0;
+}
+
+static void
+qdio_set_state(struct qdio_irq *irq_ptr,int state)
+{
+	int i;
+	char dbf_text[15];
+
+	QDIO_DBF_TEXT5(0,trace,"newstate");
+	sprintf(dbf_text,"%4x%4x",irq_ptr->irq,state);
+	QDIO_DBF_TEXT5(0,trace,dbf_text);
+
+	irq_ptr->state=state;
+	for (i=0;i<irq_ptr->no_input_qs;i++)
+		irq_ptr->input_qs[i]->state=state;
+	for (i=0;i<irq_ptr->no_output_qs;i++)
+		irq_ptr->output_qs[i]->state=state;
+	mb();
+}
+
+static inline void
+qdio_irq_check_sense(int irq, struct irb *irb)
+{
+	char dbf_text[15];
+
+	if (irb->esw.esw0.erw.cons) {
+		sprintf(dbf_text,"sens%4x",irq);
+		QDIO_DBF_TEXT2(1,trace,dbf_text);
+		QDIO_DBF_HEX0(0,sense,irb,QDIO_DBF_SENSE_LEN);
+
+		QDIO_PRINT_WARN("sense data available on qdio channel.\n");
+		HEXDUMP16(WARN,"irb: ",irb);
+		HEXDUMP16(WARN,"sense data: ",irb->ecw);
+	}
+		
+}
+
+static inline void
+qdio_handle_pci(struct qdio_irq *irq_ptr)
+{
+	int i;
+	struct qdio_q *q;
+
+#ifdef QDIO_PERFORMANCE_STATS
+	perf_stats.pcis++;
+	perf_stats.start_time_inbound=NOW;
+#endif /* QDIO_PERFORMANCE_STATS */
+	for (i=0;i<irq_ptr->no_input_qs;i++) {
+		q=irq_ptr->input_qs[i];
+		if (q->is_input_q&QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT)
+			qdio_mark_q(q);
+		else {
+#ifdef QDIO_PERFORMANCE_STATS
+			perf_stats.tl_runs--;
+#endif /* QDIO_PERFORMANCE_STATS */
+			qdio_inbound_processing(q);
+		}
+	}
+	if (!irq_ptr->hydra_gives_outbound_pcis)
+		return;
+	for (i=0;i<irq_ptr->no_output_qs;i++) {
+		q=irq_ptr->output_qs[i];
+#ifdef QDIO_PERFORMANCE_STATS
+		perf_stats.tl_runs--;
+#endif /* QDIO_PERFORMANCE_STATS */
+		if (qdio_is_outbound_q_done(q))
+			continue;
+		if (!irq_ptr->sync_done_on_outb_pcis)
+			SYNC_MEMORY;
+		qdio_outbound_processing(q);
+	}
+}
+
+static void
+qdio_handler(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
+{
+	struct qdio_irq *irq_ptr;
+	struct qdio_q *q;
+	int irq;
+	int cstat,dstat;
+	char dbf_text[15]="qintXXXX";
+
+	irq = cdev->private->irq; /* FIXME: use different dbg */
+        cstat = irb->scsw.cstat;
+        dstat = irb->scsw.dstat;
+
+	*((int*)(&dbf_text[4]))=irq;
+	QDIO_DBF_HEX4(0,trace,dbf_text,QDIO_DBF_TRACE_LEN);
+	
+	if (!intparm || !cdev) {
+		QDIO_PRINT_STUPID("got unsolicited interrupt in qdio " \
+				  "handler, irq 0x%x\n",irq);
+		return;
+	}
+
+	irq_ptr = cdev->private->qdio_data;
+	if (!irq_ptr) {
+		sprintf(dbf_text,"uint%4x",irq);
+		QDIO_DBF_TEXT2(1,trace,dbf_text);
+		QDIO_PRINT_ERR("received interrupt on unused irq 0x%04x!\n",
+			       irq);
+		return;
+	}
+
+	qdio_irq_check_sense(irq, irb);
+
+	if (cstat & SCHN_STAT_PCI) {
+		qdio_handle_pci(irq_ptr);
+		return;
+	}
+
+	if ((cstat&~SCHN_STAT_PCI)||dstat) {
+		sprintf(dbf_text,"ick2%4x",irq);
+		QDIO_DBF_TEXT2(1,trace,dbf_text);
+		QDIO_DBF_HEX2(0,trace,&intparm,sizeof(int));
+		QDIO_DBF_HEX2(0,trace,&dstat,sizeof(int));
+		QDIO_DBF_HEX2(0,trace,&cstat,sizeof(int));
+		QDIO_PRINT_ERR("received check condition on activate " \
+			       "queues on irq 0x%x (cs=x%x, ds=x%x).\n",
+			       irq,cstat,dstat);
+		if (irq_ptr->no_input_qs) {
+			q=irq_ptr->input_qs[0];
+		} else if (irq_ptr->no_output_qs) {
+			q=irq_ptr->output_qs[0];
+		} else {
+			QDIO_PRINT_ERR("oops... no queue registered on irq " \
+				  "0x%x!?\n",irq);
+			goto omit_handler_call;
+		}
+		q->handler(q->irq,QDIO_STATUS_ACTIVATE_CHECK_CONDITION|
+			   QDIO_STATUS_LOOK_FOR_ERROR,
+			   0,0,0,-1,-1,q->int_parm);
+	omit_handler_call:
+		qdio_set_state(irq_ptr,QDIO_IRQ_STATE_STOPPED);
+		return;
+	}
+
+}
+
+/* this is for mp3 */
+int
+qdio_synchronize(struct ccw_device *cdev, unsigned int flags,
+		 unsigned int queue_number)
+{
+	int cc;
+	struct qdio_q *q;
+	struct qdio_irq *irq_ptr;
+	char dbf_text[15]="SyncXXXX";
+	void *ptr;
+
+	irq_ptr = cdev->private->qdio_data;
+	if (!irq_ptr)
+		return -ENODEV;
+
+	*((int*)(&dbf_text[4])) = irq_ptr->irq;
+	QDIO_DBF_HEX4(0,trace,dbf_text,QDIO_DBF_TRACE_LEN);
+	*((int*)(&dbf_text[0]))=flags;
+	*((int*)(&dbf_text[4]))=queue_number;
+	QDIO_DBF_HEX4(0,trace,dbf_text,QDIO_DBF_TRACE_LEN);
+
+	if (flags&QDIO_FLAG_SYNC_INPUT) {
+		q=irq_ptr->input_qs[queue_number];
+		if (!q)
+			return -EINVAL;
+		cc = do_siga_sync(q->irq, 0, q->mask);
+	} else if (flags&QDIO_FLAG_SYNC_OUTPUT) {
+		q=irq_ptr->output_qs[queue_number];
+		if (!q)
+			return -EINVAL;
+		cc = do_siga_sync(q->irq, q->mask, 0);
+	} else 
+		return -EINVAL;
+
+	ptr=&cc;
+	if (cc)
+		QDIO_DBF_HEX3(0,trace,&ptr,sizeof(int));
+
+	return cc;
+}
+
+static unsigned char
+qdio_check_siga_needs(int sch)
+{
+	int resp_code,result;
+
+	memset(chsc_area,0,sizeof(struct qdio_chsc_area));
+	chsc_area->request_block.command_code1=0x0010; /* length */
+	chsc_area->request_block.command_code2=0x0024; /* op code */
+	chsc_area->request_block.first_sch=sch;
+	chsc_area->request_block.last_sch=sch;
+
+	result=chsc(chsc_area);
+
+	if (result) {
+		QDIO_PRINT_WARN("CHSC returned cc %i. Using all " \
+				"SIGAs for sch x%x.\n",
+				result,sch);
+		return -1; /* all flags set */
+	}
+
+	resp_code=chsc_area->request_block.operation_data_area.
+		store_qdio_data_response.response_code;
+	if (resp_code!=QDIO_CHSC_RESPONSE_CODE_OK) {
+		QDIO_PRINT_WARN("response upon checking SIGA needs " \
+				"is 0x%x. Using all SIGAs for sch x%x.\n",
+				resp_code,sch);
+		return -1; /* all flags set */
+	}
+	if (
+	    (!(chsc_area->request_block.operation_data_area.
+	       store_qdio_data_response.flags&CHSC_FLAG_QDIO_CAPABILITY)) ||
+	    (!(chsc_area->request_block.operation_data_area.
+	       store_qdio_data_response.flags&CHSC_FLAG_VALIDITY)) ||
+	    (chsc_area->request_block.operation_data_area.
+	     store_qdio_data_response.sch!=sch)
+	    ) {
+		QDIO_PRINT_WARN("huh? problems checking out sch x%x... " \
+				"using all SIGAs.\n",sch);
+		return CHSC_FLAG_SIGA_INPUT_NECESSARY |
+			CHSC_FLAG_SIGA_OUTPUT_NECESSARY |
+			CHSC_FLAG_SIGA_SYNC_NECESSARY; /* worst case */
+	}
+
+	return chsc_area->request_block.operation_data_area.
+		store_qdio_data_response.qdioac;
+}
+
+/* the chsc_area is locked by the lock in qdio_activate */
+static unsigned int
+iqdio_check_chsc_availability(void) {
+	int result;
+	int i;
+
+	memset(chsc_area,0,sizeof(struct qdio_chsc_area));
+	chsc_area->request_block.command_code1=0x0010;
+	chsc_area->request_block.command_code2=0x0010;
+	result=chsc(chsc_area);
+	if (result) {
+		QDIO_PRINT_WARN("Was not able to determine " \
+				"available CHSCs, cc=%i.\n",
+				result);
+		result=-EIO;
+		goto exit;
+	}
+	result=0;
+	i=chsc_area->request_block.operation_data_area.
+		store_qdio_data_response.response_code;
+	if (i!=1) {
+		QDIO_PRINT_WARN("Was not able to determine " \
+				"available CHSCs.\n");
+		result=-EIO;
+		goto exit;
+	}
+	/* 4: request block
+	 * 2: general char
+	 * 512: chsc char */
+	if ( (*(((unsigned int*)(chsc_area))+4+2+1)&0x00800000)!=0x00800000) {
+		QDIO_PRINT_WARN("Adapter interruption facility not " \
+				"installed.\n");
+		result=-ENOENT;
+		goto exit;
+	}
+	if ( (*(((unsigned int*)(chsc_area))+4+512+3)&0x00180000)!=
+	     0x00180000 ) {
+		QDIO_PRINT_WARN("Set Chan Subsys. Char. & Fast-CHSCs " \
+				"not available.\n");
+		result=-ENOENT;
+		goto exit;
+	}
+exit:
+	return result;
+}
+
+/* the chsc_area is locked by the lock in qdio_activate */
+static unsigned int
+iqdio_set_subchannel_ind(struct qdio_irq *irq_ptr, int reset_to_zero)
+{
+	unsigned long real_addr_local_summary_bit;
+	unsigned long real_addr_dev_st_chg_ind;
+	void *ptr;
+	char dbf_text[15];
+
+	unsigned int resp_code;
+	int result;
+
+	if (!irq_ptr->is_iqdio_irq) return -ENODEV;
+
+	if (reset_to_zero) {
+		real_addr_local_summary_bit=0;
+		real_addr_dev_st_chg_ind=0;
+	} else {
+		real_addr_local_summary_bit=
+			virt_to_phys((volatile void *)indicators);
+		real_addr_dev_st_chg_ind=
+			virt_to_phys((volatile void *)irq_ptr->dev_st_chg_ind);
+	}
+
+	memset(chsc_area,0,sizeof(struct qdio_chsc_area));
+	chsc_area->request_block.command_code1=0x0fe0;
+	chsc_area->request_block.command_code2=0x0021;
+	chsc_area->request_block.operation_code=0;
+	chsc_area->request_block.image_id=0;
+
+	chsc_area->request_block.operation_data_area.set_chsc.
+		summary_indicator_addr=real_addr_local_summary_bit;
+	chsc_area->request_block.operation_data_area.set_chsc.
+		subchannel_indicator_addr=real_addr_dev_st_chg_ind;
+	chsc_area->request_block.operation_data_area.set_chsc.
+		ks=QDIO_STORAGE_KEY;
+	chsc_area->request_block.operation_data_area.set_chsc.
+		kc=QDIO_STORAGE_KEY;
+	chsc_area->request_block.operation_data_area.set_chsc.
+		isc=IQDIO_THININT_ISC;
+	chsc_area->request_block.operation_data_area.set_chsc.
+		subsystem_id=(1<<16)+irq_ptr->irq;
+
+	result=chsc(chsc_area);
+	if (result) {
+		QDIO_PRINT_WARN("could not set indicators on irq x%x, " \
+				"cc=%i.\n",irq_ptr->irq,result);
+		return -EIO;
+	}
+
+	resp_code=chsc_area->response_block.response_code;
+	if (resp_code!=QDIO_CHSC_RESPONSE_CODE_OK) {
+		QDIO_PRINT_WARN("response upon setting indicators " \
+				"is 0x%x.\n",resp_code);
+		sprintf(dbf_text,"sidR%4x",resp_code);
+		QDIO_DBF_TEXT1(0,trace,dbf_text);
+		QDIO_DBF_TEXT1(0,setup,dbf_text);
+		ptr=&chsc_area->response_block;
+		QDIO_DBF_HEX2(1,setup,&ptr,QDIO_DBF_SETUP_LEN);
+		return -EIO;
+	}
+
+	QDIO_DBF_TEXT2(0,setup,"setscind");
+	QDIO_DBF_HEX2(0,setup,&real_addr_local_summary_bit,
+		      sizeof(unsigned long));
+	QDIO_DBF_HEX2(0,setup,&real_addr_dev_st_chg_ind,sizeof(unsigned long));
+	return 0;
+}
+
+/* chsc_area would have to be locked if called from outside qdio_activate */
+static unsigned int
+iqdio_set_delay_target(struct qdio_irq *irq_ptr, unsigned long delay_target)
+{
+	unsigned int resp_code;
+	int result;
+	void *ptr;
+	char dbf_text[15];
+
+	if (!irq_ptr->is_iqdio_irq) return -ENODEV;
+
+	memset(chsc_area,0,sizeof(struct qdio_chsc_area));
+	chsc_area->request_block.command_code1=0x0fe0;
+	chsc_area->request_block.command_code2=0x1027;
+	chsc_area->request_block.operation_data_area.set_chsc_fast.
+		delay_target=delay_target<<16;
+
+	result=chsc(chsc_area);
+	if (result) {
+		QDIO_PRINT_WARN("could not set delay target on irq x%x, " \
+				"cc=%i. Continuing.\n",irq_ptr->irq,result);
+		return -EIO;
+	}
+
+	resp_code=chsc_area->response_block.response_code;
+	if (resp_code!=QDIO_CHSC_RESPONSE_CODE_OK) {
+		QDIO_PRINT_WARN("response upon setting delay target " \
+				"is 0x%x. Continuing.\n",resp_code);
+		sprintf(dbf_text,"sdtR%4x",resp_code);
+		QDIO_DBF_TEXT1(0,trace,dbf_text);
+		QDIO_DBF_TEXT1(0,setup,dbf_text);
+		ptr=&chsc_area->response_block;
+		QDIO_DBF_HEX2(1,trace,&ptr,QDIO_DBF_TRACE_LEN);
+	}
+	QDIO_DBF_TEXT2(0,trace,"delytrgt");
+	QDIO_DBF_HEX2(0,trace,&delay_target,sizeof(unsigned long));
+	return 0;
+}
+
+int
+qdio_cleanup(struct ccw_device *cdev, int how)
+{
+	struct qdio_irq *irq_ptr;
+	int i,result;
+	unsigned long flags;
+	int timeout;
+	char dbf_text[15]="12345678";
+
+	irq_ptr = cdev->private->qdio_data;
+	if (!irq_ptr)
+		return -ENODEV;
+
+	sprintf(dbf_text,"qcln%4x",irq_ptr->irq);
+	QDIO_DBF_TEXT1(0,trace,dbf_text);
+	QDIO_DBF_TEXT0(0,setup,dbf_text);
+
+	spin_lock(&irq_ptr->setting_up_lock);
+
+	result=0;
+
+	/* mark all qs as uninteresting */
+	for (i=0;i<irq_ptr->no_input_qs;i++)
+		atomic_set(&irq_ptr->input_qs[i]->is_in_shutdown,1);
+
+	for (i=0;i<irq_ptr->no_output_qs;i++)
+		atomic_set(&irq_ptr->output_qs[i]->is_in_shutdown,1);
+
+	tasklet_kill(&iqdio_tasklet);
+
+	for (i=0;i<irq_ptr->no_input_qs;i++) {
+		qdio_unmark_q(irq_ptr->input_qs[i]);
+		tasklet_kill(&irq_ptr->input_qs[i]->tasklet);
+		if (qdio_wait_for_no_use_count(&irq_ptr->input_qs[i]->
+					       use_count))
+			result=-EINPROGRESS;
+	}
+
+	for (i=0;i<irq_ptr->no_output_qs;i++) {
+		tasklet_kill(&irq_ptr->output_qs[i]->tasklet);
+		if (qdio_wait_for_no_use_count(&irq_ptr->output_qs[i]->
+					       use_count))
+			result=-EINPROGRESS;
+	}
+
+	/* cleanup subchannel */
+	spin_lock_irqsave(get_ccwdev_lock(cdev),flags);
+	if (how&QDIO_FLAG_CLEANUP_USING_CLEAR) {
+		ccw_device_clear(cdev, QDIO_DOING_CLEANUP);
+		timeout=QDIO_CLEANUP_CLEAR_TIMEOUT;
+	} else if (how&QDIO_FLAG_CLEANUP_USING_HALT) {
+		ccw_device_halt(cdev, QDIO_DOING_CLEANUP);
+		timeout=QDIO_CLEANUP_HALT_TIMEOUT;
+	} else { /* default behaviour */
+		ccw_device_halt(cdev, QDIO_DOING_CLEANUP);
+		timeout=QDIO_CLEANUP_HALT_TIMEOUT;
+	}
+	cdev->private->state = DEV_STATE_QDIO_CLEANUP;
+	ccw_device_set_timeout(cdev, timeout);
+	spin_unlock_irqrestore(get_ccwdev_lock(cdev),flags);
+
+	wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
+	return 0;
+}
+
+static inline void
+qdio_cleanup_finish(struct qdio_irq *irq_ptr)
+{
+	if (irq_ptr->is_iqdio_irq) {
+		qdio_put_indicator((__u32*)irq_ptr->dev_st_chg_ind);
+		iqdio_set_subchannel_ind(irq_ptr,1); 
+                /* reset adapter interrupt indicators */
+	}
+
+	qdio_set_state(irq_ptr,QDIO_IRQ_STATE_INACTIVE);
+}
+
+static void
+qdio_cleanup_handle_timeout(struct ccw_device *cdev)
+{
+	unsigned long flags;
+	struct qdio_irq *irq_ptr;
+
+	irq_ptr = cdev->private->qdio_data;
+
+	spin_lock_irqsave(get_ccwdev_lock(cdev),flags);
+	QDIO_PRINT_INFO("Did not get interrupt on cleanup, irq=0x%x.\n",
+			irq_ptr->irq);
+
+	qdio_cleanup_finish(irq_ptr);
+
+	spin_unlock_irqrestore(get_ccwdev_lock(cdev),flags);
+
+	spin_unlock(&irq_ptr->setting_up_lock);
+
+	cdev->private->qdio_data = 0;
+	qdio_release_irq_memory(irq_ptr);
+	cdev->private->state = DEV_STATE_ONLINE;
+	wake_up(&cdev->private->wait_q);
+}
+
+static void
+qdio_cleanup_handle_irq(struct ccw_device *cdev, unsigned long intparm,
+			struct irb *irb)
+{
+	struct qdio_irq *irq_ptr;
+	int cstat,dstat;
+
+	cstat = irb->scsw.cstat;
+        dstat = irb->scsw.dstat;
+
+	if (intparm == 0)
+		QDIO_PRINT_WARN("Got unsolicited interrupt on cleanup "
+				"(irq 0x%x).\n", cdev->private->irq);
+
+	irq_ptr = cdev->private->qdio_data;
+
+	qdio_irq_check_sense(irq_ptr->irq, irb);
+
+	qdio_cleanup_finish(irq_ptr);
+
+	spin_unlock(&irq_ptr->setting_up_lock);
+
+	cdev->private->qdio_data = 0;
+	qdio_release_irq_memory(irq_ptr);
+	cdev->private->state = DEV_STATE_ONLINE;
+	wake_up(&cdev->private->wait_q);
+}
+
+static inline void
+qdio_initialize_do_dbf(struct qdio_initialize *init_data)
+{
+	char dbf_text[20]; /* if a printf would print out more than 8 chars */
+
+	sprintf(dbf_text,"qini%4x",init_data->cdev->private->irq);
+	QDIO_DBF_TEXT0(0,setup,dbf_text);
+	QDIO_DBF_TEXT0(0,trace,dbf_text);
+	sprintf(dbf_text,"qfmt:%x",init_data->q_format);
+	QDIO_DBF_TEXT0(0,setup,dbf_text);
+	QDIO_DBF_TEXT0(0,setup,init_data->adapter_name);
+	QDIO_DBF_HEX0(0,setup,init_data->adapter_name,8);
+	sprintf(dbf_text,"qpff%4x",init_data->qib_param_field_format);
+	QDIO_DBF_TEXT0(0,setup,dbf_text);
+	QDIO_DBF_HEX0(0,setup,&init_data->qib_param_field,sizeof(char*));
+	QDIO_DBF_HEX0(0,setup,&init_data->input_slib_elements,sizeof(long*));
+	QDIO_DBF_HEX0(0,setup,&init_data->output_slib_elements,sizeof(long*));
+	sprintf(dbf_text,"miit%4x",init_data->min_input_threshold);
+	QDIO_DBF_TEXT0(0,setup,dbf_text);
+	sprintf(dbf_text,"mait%4x",init_data->max_input_threshold);
+	QDIO_DBF_TEXT0(0,setup,dbf_text);
+	sprintf(dbf_text,"miot%4x",init_data->min_output_threshold);
+	QDIO_DBF_TEXT0(0,setup,dbf_text);
+	sprintf(dbf_text,"maot%4x",init_data->max_output_threshold);
+	QDIO_DBF_TEXT0(0,setup,dbf_text);
+	sprintf(dbf_text,"niq:%4x",init_data->no_input_qs);
+	QDIO_DBF_TEXT0(0,setup,dbf_text);
+	sprintf(dbf_text,"noq:%4x",init_data->no_output_qs);
+	QDIO_DBF_TEXT0(0,setup,dbf_text);
+	QDIO_DBF_HEX0(0,setup,&init_data->input_handler,sizeof(void*));
+	QDIO_DBF_HEX0(0,setup,&init_data->output_handler,sizeof(void*));
+	QDIO_DBF_HEX0(0,setup,&init_data->int_parm,sizeof(long));
+	QDIO_DBF_HEX0(0,setup,&init_data->flags,sizeof(long));
+	QDIO_DBF_HEX0(0,setup,&init_data->input_sbal_addr_array,sizeof(void*));
+	QDIO_DBF_HEX0(0,setup,&init_data->output_sbal_addr_array,sizeof(void*));
+}
+
+static inline void
+qdio_initialize_fill_input_desc(struct qdio_irq *irq_ptr, int i, int iqfmt)
+{
+	irq_ptr->input_qs[i]->is_iqdio_q = iqfmt;
+
+	irq_ptr->qdr->qdf0[i].sliba=(unsigned long)(irq_ptr->input_qs[i]->slib);
+
+	irq_ptr->qdr->qdf0[i].sla=(unsigned long)(irq_ptr->input_qs[i]->sl);
+
+	irq_ptr->qdr->qdf0[i].slsba=
+			(unsigned long)(&irq_ptr->input_qs[i]->slsb.acc.val[0]);
+
+	irq_ptr->qdr->qdf0[i].akey=QDIO_STORAGE_KEY;
+	irq_ptr->qdr->qdf0[i].bkey=QDIO_STORAGE_KEY;
+	irq_ptr->qdr->qdf0[i].ckey=QDIO_STORAGE_KEY;
+	irq_ptr->qdr->qdf0[i].dkey=QDIO_STORAGE_KEY;
+}
+
+static inline void
+qdio_initialize_fill_output_desc(struct qdio_irq *irq_ptr, int i, 
+				 int j, int iqfmt)
+{
+	irq_ptr->output_qs[i]->is_iqdio_q = iqfmt;
+
+	irq_ptr->qdr->qdf0[i+j].sliba=
+		(unsigned long)(irq_ptr->output_qs[i]->slib);
+
+	irq_ptr->qdr->qdf0[i+j].sla=(unsigned long)(irq_ptr->output_qs[i]->sl);
+
+	irq_ptr->qdr->qdf0[i+j].slsba=
+		(unsigned long)(&irq_ptr->output_qs[i]->slsb.acc.val[0]);
+
+	irq_ptr->qdr->qdf0[i+j].akey=QDIO_STORAGE_KEY;
+	irq_ptr->qdr->qdf0[i+j].bkey=QDIO_STORAGE_KEY;
+	irq_ptr->qdr->qdf0[i+j].ckey=QDIO_STORAGE_KEY;
+	irq_ptr->qdr->qdf0[i+j].dkey=QDIO_STORAGE_KEY;
+}
+
+void
+qdio_establish_handle_timeout(struct ccw_device *cdev)
+{
+	struct qdio_irq *irq_ptr;
+
+	irq_ptr = cdev->private->qdio_data;
+
+	QDIO_PRINT_ERR("establish queues on irq %04x: timed out\n",
+		       irq_ptr->irq);
+	QDIO_DBF_TEXT2(1,setup,"eq:timeo");
+	spin_unlock(&irq_ptr->setting_up_lock);
+	qdio_cleanup(cdev,QDIO_FLAG_CLEANUP_USING_CLEAR);
+
+	up(&init_sema);
+}
+
+static inline void
+qdio_initialize_set_siga_flags_input(struct qdio_irq *irq_ptr)
+{
+	int i;
+
+	for (i=0;i<irq_ptr->no_input_qs;i++) {
+		irq_ptr->input_qs[i]->siga_sync=
+			irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_NECESSARY;
+		irq_ptr->input_qs[i]->siga_in=
+			irq_ptr->qdioac&CHSC_FLAG_SIGA_INPUT_NECESSARY;
+		irq_ptr->input_qs[i]->siga_out=
+			irq_ptr->qdioac&CHSC_FLAG_SIGA_OUTPUT_NECESSARY;
+		irq_ptr->input_qs[i]->siga_sync_done_on_thinints=
+			irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS;
+		irq_ptr->input_qs[i]->hydra_gives_outbound_pcis=
+			irq_ptr->hydra_gives_outbound_pcis;
+	}
+}
+
+static inline void
+qdio_initialize_set_siga_flags_output(struct qdio_irq *irq_ptr)
+{
+	int i;
+
+	for (i=0;i<irq_ptr->no_output_qs;i++) {
+		irq_ptr->output_qs[i]->siga_sync=
+			irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_NECESSARY;
+		irq_ptr->output_qs[i]->siga_in=
+			irq_ptr->qdioac&CHSC_FLAG_SIGA_INPUT_NECESSARY;
+		irq_ptr->output_qs[i]->siga_out=
+			irq_ptr->qdioac&CHSC_FLAG_SIGA_OUTPUT_NECESSARY;
+		irq_ptr->output_qs[i]->siga_sync_done_on_thinints=
+			irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS;
+		irq_ptr->output_qs[i]->hydra_gives_outbound_pcis=
+			irq_ptr->hydra_gives_outbound_pcis;
+	}
+}
+
+static inline int
+qdio_establish_irq_check_for_errors(struct ccw_device *cdev, int cstat,
+				    int dstat)
+{
+	char dbf_text[15];
+	struct qdio_irq *irq_ptr;
+
+	irq_ptr = cdev->private->qdio_data;
+
+	if (cstat || (dstat & ~(DEV_STAT_CHN_END|DEV_STAT_DEV_END))) {
+		sprintf(dbf_text,"ick1%4x",irq_ptr->irq);
+		QDIO_DBF_TEXT2(1,trace,dbf_text);
+		QDIO_DBF_HEX2(0,trace,&dstat,sizeof(int));
+		QDIO_DBF_HEX2(0,trace,&cstat,sizeof(int));
+		QDIO_PRINT_ERR("received check condition on establish " \
+			       "queues on irq 0x%x (cs=x%x, ds=x%x).\n",
+			       irq_ptr->irq,cstat,dstat);
+		qdio_set_state(irq_ptr,QDIO_IRQ_STATE_STOPPED);
+	}
+	
+	if (!(dstat & DEV_STAT_DEV_END)) {
+		QDIO_DBF_TEXT2(1,setup,"eq:no de");
+		QDIO_DBF_HEX2(0,setup,&dstat, sizeof(dstat));
+		QDIO_DBF_HEX2(0,setup,&cstat, sizeof(cstat));
+		QDIO_PRINT_ERR("establish queues on irq %04x: didn't get "
+			       "device end: dstat=%02x, cstat=%02x\n",
+			       irq_ptr->irq, dstat, cstat);
+		spin_unlock(&irq_ptr->setting_up_lock);
+		qdio_cleanup(cdev,QDIO_FLAG_CLEANUP_USING_CLEAR);
+		up(&init_sema);
+		return 1;
+	}
+
+	if (dstat & ~(DEV_STAT_CHN_END|DEV_STAT_DEV_END)) {
+		QDIO_DBF_TEXT2(1,setup,"eq:badio");
+		QDIO_DBF_HEX2(0,setup,&dstat, sizeof(dstat));
+		QDIO_DBF_HEX2(0,setup,&cstat, sizeof(cstat));
+		QDIO_PRINT_ERR("establish queues on irq %04x: got "
+			       "the following devstat: dstat=%02x, "
+			       "cstat=%02x\n",
+			       irq_ptr->irq, dstat, cstat);
+		cdev->private->state = DEV_STATE_ONLINE;
+		spin_unlock(&irq_ptr->setting_up_lock);
+
+		up(&init_sema);
+		return 1;
+	}
+	return 0;
+}
+
+static void
+qdio_establish_handle_irq(struct ccw_device *cdev, unsigned long intparm,
+			  struct irb *irb)
+{
+	struct qdio_irq *irq_ptr;
+	int cstat, dstat;
+	char dbf_text[15];
+
+        cstat = irb->scsw.cstat;
+        dstat = irb->scsw.dstat;
+
+	irq_ptr = cdev->private->qdio_data;
+
+	if (intparm == 0) {
+		QDIO_PRINT_WARN("Got unsolicited interrupt on establish "
+				"queues (irq 0x%x).\n", cdev->private->irq);
+		goto out;
+	}
+
+	qdio_irq_check_sense(irq_ptr->irq, irb);
+
+	if (qdio_establish_irq_check_for_errors(cdev, cstat, dstat))
+		return;
+
+	if (MACHINE_IS_VM)
+		irq_ptr->qdioac=qdio_check_siga_needs(irq_ptr->irq);
+	else
+                irq_ptr->qdioac=CHSC_FLAG_SIGA_INPUT_NECESSARY
+                        | CHSC_FLAG_SIGA_OUTPUT_NECESSARY;
+
+	sprintf(dbf_text,"qdioac%2x",irq_ptr->qdioac);
+	QDIO_DBF_TEXT2(0,setup,dbf_text);
+
+	sprintf(dbf_text,"qib ac%2x",irq_ptr->qib.ac);
+	QDIO_DBF_TEXT2(0,setup,dbf_text);
+
+	irq_ptr->hydra_gives_outbound_pcis=
+		irq_ptr->qib.ac&QIB_AC_OUTBOUND_PCI_SUPPORTED;
+	irq_ptr->sync_done_on_outb_pcis=
+		irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS;
+
+	qdio_initialize_set_siga_flags_input(irq_ptr);
+	qdio_initialize_set_siga_flags_output(irq_ptr);
+
+	qdio_set_state(irq_ptr,QDIO_IRQ_STATE_ESTABLISHED);
+
+ out:
+	if (irq_ptr)
+		spin_unlock(&irq_ptr->setting_up_lock);
+
+	up(&init_sema);
+
+}
+
+int
+qdio_initialize(struct qdio_initialize *init_data)
+{
+	int i;
+	unsigned long saveflags;
+	struct qdio_irq *irq_ptr;
+	struct ciw *ciw;
+	int result,result2;
+	int is_iqdio;
+	char dbf_text[20]; /* if a printf would print out more than 8 chars */
+
+	down_interruptible(&init_sema);
+
+	if ( (init_data->no_input_qs>QDIO_MAX_QUEUES_PER_IRQ) ||
+	     (init_data->no_output_qs>QDIO_MAX_QUEUES_PER_IRQ) ||
+	     ((init_data->no_input_qs) && (!init_data->input_handler)) ||
+	     ((init_data->no_output_qs) && (!init_data->output_handler)) ) {
+		result=-EINVAL;
+		goto out;
+	}
+
+	if (!init_data->input_sbal_addr_array) {
+		result=-EINVAL;
+		goto out;
+	}
+	if (!init_data->output_sbal_addr_array) {
+		result=-EINVAL;
+		goto out;
+	}
+
+	qdio_initialize_do_dbf(init_data);
+
+	/* create irq */
+	irq_ptr=kmalloc(sizeof(struct qdio_irq),GFP_DMA);
+
+	QDIO_DBF_TEXT0(0,setup,"irq_ptr:");
+	QDIO_DBF_HEX0(0,setup,&irq_ptr,sizeof(void*));
+
+	if (!irq_ptr) {
+		QDIO_PRINT_ERR("kmalloc of irq_ptr failed!\n");
+		result=-ENOMEM;
+		goto out;
+	}
+
+	memset(irq_ptr,0,sizeof(struct qdio_irq));
+        /* wipes qib.ac, required by ar7063 */
+
+	irq_ptr->qdr=kmalloc(sizeof(struct qdr),GFP_DMA);
+  	if (!(irq_ptr->qdr)) {
+   		kfree(irq_ptr->qdr);
+   		kfree(irq_ptr);
+    		QDIO_PRINT_ERR("kmalloc of irq_ptr->qdr failed!\n");
+     		result=-ENOMEM;
+      		goto out;
+       	}
+	memset(irq_ptr->qdr,0,sizeof(struct qdr));
+	QDIO_DBF_TEXT0(0,setup,"qdr:");
+	QDIO_DBF_HEX0(0,setup,&irq_ptr->qdr,sizeof(void*));
+
+	irq_ptr->int_parm=init_data->int_parm;
+
+	irq_ptr->irq = init_data->cdev->private->irq;
+	irq_ptr->no_input_qs=init_data->no_input_qs;
+	irq_ptr->no_output_qs=init_data->no_output_qs;
+
+	irq_ptr->is_iqdio_irq=(init_data->q_format==QDIO_IQDIO_QFMT)?1:0;
+
+	if (irq_ptr->is_iqdio_irq) {
+		irq_ptr->dev_st_chg_ind=qdio_get_indicator();
+		QDIO_DBF_HEX1(0,setup,&irq_ptr->dev_st_chg_ind,sizeof(void*));
+		if (!irq_ptr->dev_st_chg_ind) {
+			QDIO_PRINT_WARN("no indicator location available " \
+					"for irq 0x%x\n",irq_ptr->irq);
+			qdio_release_irq_memory(irq_ptr);
+			result=-ENOBUFS;
+			goto out;
+		}
+	}
+
+	/* defaults */
+	irq_ptr->equeue.cmd=DEFAULT_ESTABLISH_QS_CMD;
+	irq_ptr->equeue.count=DEFAULT_ESTABLISH_QS_COUNT;
+	irq_ptr->aqueue.cmd=DEFAULT_ACTIVATE_QS_CMD;
+	irq_ptr->aqueue.count=DEFAULT_ACTIVATE_QS_COUNT;
+
+	if (!qdio_alloc_qs(irq_ptr,init_data->no_input_qs,
+			   init_data->no_output_qs,
+			   init_data->input_handler,
+			   init_data->output_handler,init_data->int_parm,
+			   init_data->q_format,init_data->flags,
+			   init_data->input_sbal_addr_array,
+			   init_data->output_sbal_addr_array)) {
+		qdio_release_irq_memory(irq_ptr);
+		result=-ENOMEM;
+		goto out;
+	}
+
+	qdio_set_state(irq_ptr,QDIO_IRQ_STATE_INACTIVE);
+
+	irq_ptr->setting_up_lock=SPIN_LOCK_UNLOCKED;
+
+	MOD_INC_USE_COUNT;
+	QDIO_DBF_TEXT3(0,setup,"MOD_INC_");
+
+	spin_lock(&irq_ptr->setting_up_lock);
+
+	init_data->cdev->private->qdio_data = irq_ptr;
+
+	qdio_fill_thresholds(irq_ptr,init_data->no_input_qs,
+			     init_data->no_output_qs,
+			     init_data->min_input_threshold,
+			     init_data->max_input_threshold,
+			     init_data->min_output_threshold,
+			     init_data->max_output_threshold);
+
+	/* fill in qdr */
+	irq_ptr->qdr->qfmt=init_data->q_format;
+	irq_ptr->qdr->iqdcnt=init_data->no_input_qs;
+	irq_ptr->qdr->oqdcnt=init_data->no_output_qs;
+	irq_ptr->qdr->iqdsz=sizeof(struct qdesfmt0)/4; /* size in words */
+	irq_ptr->qdr->oqdsz=sizeof(struct qdesfmt0)/4;
+
+	irq_ptr->qdr->qiba=(unsigned long)&irq_ptr->qib;
+	irq_ptr->qdr->qkey=QDIO_STORAGE_KEY;
+
+	/* fill in qib */
+	irq_ptr->qib.qfmt=init_data->q_format;
+	if (init_data->no_input_qs) irq_ptr->qib.isliba=
+				 (unsigned long)(irq_ptr->input_qs[0]->slib);
+	if (init_data->no_output_qs) irq_ptr->qib.osliba=(unsigned long)
+				  (irq_ptr->output_qs[0]->slib);
+	memcpy(irq_ptr->qib.ebcnam,init_data->adapter_name,8);
+
+	qdio_set_impl_params(irq_ptr,init_data->qib_param_field_format,
+			     init_data->qib_param_field,
+			     init_data->no_input_qs,
+			     init_data->no_output_qs,
+			     init_data->input_slib_elements,
+			     init_data->output_slib_elements);
+
+	/* first input descriptors, then output descriptors */
+	is_iqdio = (init_data->q_format == QDIO_IQDIO_QFMT) ? 1 : 0;
+	for (i=0;i<init_data->no_input_qs;i++)
+		qdio_initialize_fill_input_desc(irq_ptr, i, is_iqdio);
+
+	for (i=0;i<init_data->no_output_qs;i++)
+		qdio_initialize_fill_output_desc(irq_ptr, i,
+						 init_data->no_input_qs,
+						 is_iqdio);
+
+	/* qdr, qib, sls, slsbs, slibs, sbales filled. */
+
+	/* get qdio commands */
+	ciw = ccw_device_get_ciw(init_data->cdev, CIW_TYPE_EQUEUE);
+	if (!ciw) {
+		QDIO_DBF_TEXT2(1,setup,"no eq");
+		QDIO_PRINT_INFO("No equeue CIW found for QDIO commands. "
+				"Trying to use default.\n");
+	} else
+		irq_ptr->equeue = *ciw;
+	ciw = ccw_device_get_ciw(init_data->cdev, CIW_TYPE_AQUEUE);
+	if (!ciw) {
+		QDIO_DBF_TEXT2(1,setup,"no aq");
+		QDIO_PRINT_INFO("No aqueue CIW found for QDIO commands. "
+				"Trying to use default.\n");
+	} else
+		irq_ptr->aqueue = *ciw;
+
+	/* the iqdio CHSC stuff */
+	if (irq_ptr->is_iqdio_irq) {
+/*		iqdio_enable_adapter_int_facility(irq_ptr);*/
+
+		if (iqdio_check_chsc_availability()) {
+			QDIO_PRINT_ERR("Not all CHSCs supported. " \
+				       "Continuing.\n");
+		}
+		result=iqdio_set_subchannel_ind(irq_ptr,0);
+		if (result) {
+			spin_unlock(&irq_ptr->setting_up_lock);
+			qdio_cleanup(init_data->cdev, QDIO_FLAG_CLEANUP_USING_CLEAR);
+			goto out2;
+		}
+		iqdio_set_delay_target(irq_ptr,IQDIO_DELAY_TARGET);
+	}
+
+	/* Set callback functions. */
+	irq_ptr->cleanup_irq = qdio_cleanup_handle_irq;
+	irq_ptr->cleanup_timeout = qdio_cleanup_handle_timeout;
+	irq_ptr->establish_irq = qdio_establish_handle_irq;
+	irq_ptr->establish_timeout = qdio_establish_handle_timeout;
+	irq_ptr->handler = qdio_handler;
+
+	/* establish q */
+	irq_ptr->ccw.cmd_code=irq_ptr->equeue.cmd;
+	irq_ptr->ccw.flags=CCW_FLAG_SLI;
+	irq_ptr->ccw.count=irq_ptr->equeue.count;
+	irq_ptr->ccw.cda=QDIO_GET_ADDR(irq_ptr->qdr);
+
+	spin_lock_irqsave(get_ccwdev_lock(init_data->cdev),saveflags);
+
+	ccw_device_set_timeout(init_data->cdev, QDIO_ESTABLISH_TIMEOUT);
+	ccw_device_set_options(init_data->cdev, 0);
+	result=ccw_device_start(init_data->cdev,&irq_ptr->ccw,
+				QDIO_DOING_ESTABLISH,0,0);
+	if (result) {
+		result2=ccw_device_start(init_data->cdev,&irq_ptr->ccw,
+					 QDIO_DOING_ESTABLISH,0,0);
+		sprintf(dbf_text,"eq:io%4x",result);
+		QDIO_DBF_TEXT2(1,setup,dbf_text);
+		if (result2) {
+			sprintf(dbf_text,"eq:io%4x",result);
+			QDIO_DBF_TEXT2(1,setup,dbf_text);
+		}
+		QDIO_PRINT_WARN("establish queues on irq %04x: do_IO " \
+                           "returned %i, next try returned %i\n",
+                           irq_ptr->irq,result,result2);
+		result=result2;
+	}
+	if (result == 0)
+		init_data->cdev->private->state = DEV_STATE_QDIO_INIT;
+	spin_unlock_irqrestore(get_ccwdev_lock(init_data->cdev),saveflags);
+
+	if (result) {
+		spin_unlock(&irq_ptr->setting_up_lock);
+		qdio_cleanup(init_data->cdev,QDIO_FLAG_CLEANUP_USING_CLEAR);
+		goto out2;
+	}
+	
+	wait_event(init_data->cdev->private->wait_q,
+		   dev_fsm_final_state(init_data->cdev) ||
+		   (irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED));
+
+	if (init_data->cdev->private->state == DEV_STATE_QDIO_INIT)
+		return 0;
+
+	result = -EIO;
+ out:
+	if (irq_ptr)
+		spin_unlock(&irq_ptr->setting_up_lock);
+ out2:
+	up(&init_sema);
+
+	return result;
+	
+}
+
+int
+qdio_activate(struct ccw_device *cdev, int flags)
+{
+	struct qdio_irq *irq_ptr;
+	int i,result=0,result2;
+	unsigned long saveflags;
+	char dbf_text[20]; /* see qdio_initialize */
+
+	irq_ptr = cdev->private->qdio_data;
+	if (!irq_ptr)
+		return -ENODEV;
+
+	if (cdev->private->state != DEV_STATE_QDIO_INIT)
+		return -EINVAL;
+
+	spin_lock(&irq_ptr->setting_up_lock);
+	if (irq_ptr->state==QDIO_IRQ_STATE_INACTIVE) {
+		result=-EBUSY;
+		goto out;
+	}
+
+	sprintf(dbf_text,"qact%4x", irq_ptr->irq);
+	QDIO_DBF_TEXT2(0,setup,dbf_text);
+	QDIO_DBF_TEXT2(0,trace,dbf_text);
+
+	/* activate q */
+	irq_ptr->ccw.cmd_code=irq_ptr->aqueue.cmd;
+	irq_ptr->ccw.flags=CCW_FLAG_SLI;
+	irq_ptr->ccw.count=irq_ptr->aqueue.count;
+	irq_ptr->ccw.cda=QDIO_GET_ADDR(0);
+
+	spin_lock_irqsave(get_ccwdev_lock(cdev),saveflags);
+
+	ccw_device_set_timeout(cdev, 0);
+	ccw_device_set_options(cdev, CCWDEV_REPORT_ALL);
+	result=ccw_device_start(cdev,&irq_ptr->ccw,QDIO_DOING_ACTIVATE,
+				0, DOIO_DENY_PREFETCH);
+	if (result) {
+		result2=ccw_device_start(cdev,&irq_ptr->ccw,
+					 QDIO_DOING_ACTIVATE,0,0);
+		sprintf(dbf_text,"aq:io%4x",result);
+		QDIO_DBF_TEXT2(1,setup,dbf_text);
+		if (result2) {
+			sprintf(dbf_text,"aq:io%4x",result);
+			QDIO_DBF_TEXT2(1,setup,dbf_text);
+		}
+		QDIO_PRINT_WARN("activate queues on irq %04x: do_IO " \
+                           "returned %i, next try returned %i\n",
+                           irq_ptr->irq,result,result2);
+		result=result2;
+	}
+
+	spin_unlock_irqrestore(get_ccwdev_lock(cdev),saveflags);
+	if (result)
+		goto out;
+
+	cdev->private->state = DEV_STATE_QDIO_ACTIVE;
+
+	for (i=0;i<irq_ptr->no_input_qs;i++) {
+		if (irq_ptr->is_iqdio_irq) {
+			/* 
+			 * that way we know, that, if we will get interrupted
+			 * by iqdio_inbound_processing, qdio_unmark_q will
+			 * not be called 
+			 */
+			qdio_reserve_q(irq_ptr->input_qs[i]);
+			qdio_mark_iq(irq_ptr->input_qs[i]);
+			qdio_release_q(irq_ptr->input_qs[i]);
+		}
+	}
+
+	if (flags&QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT) {
+		for (i=0;i<irq_ptr->no_input_qs;i++) {
+			irq_ptr->input_qs[i]->is_input_q|=
+				QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT;
+		}
+	}
+
+	qdio_set_state(irq_ptr,QDIO_IRQ_STATE_ACTIVE);
+
+ out:
+	spin_unlock(&irq_ptr->setting_up_lock);
+
+	return result;
+}
+
+/* buffers filled forwards again to make Rick happy */
+static void
+qdio_do_qdio_fill_input(struct qdio_q *q, unsigned int qidx,
+			unsigned int count, struct qdio_buffer *buffers)
+{
+	for (;;) {
+		set_slsb(&q->slsb.acc.val[qidx],SLSB_CU_INPUT_EMPTY);
+		count--;
+		if (!count) break;
+		qidx=(qidx+1)&(QDIO_MAX_BUFFERS_PER_Q-1);
+	}
+
+	/* not necessary, as the queues are synced during the SIGA read */
+	/*SYNC_MEMORY;*/
+}
+
+static inline void
+qdio_do_qdio_fill_output(struct qdio_q *q, unsigned int qidx,
+			 unsigned int count, struct qdio_buffer *buffers)
+{
+	for (;;) {
+		set_slsb(&q->slsb.acc.val[qidx],SLSB_CU_OUTPUT_PRIMED);
+		count--;
+		if (!count) break;
+		qidx=(qidx+1)&(QDIO_MAX_BUFFERS_PER_Q-1);
+	}
+
+	/* SIGA write will sync the queues */
+	/*SYNC_MEMORY;*/
+}
+
+static inline void
+do_qdio_handle_inbound(struct qdio_q *q, unsigned int callflags,
+		       unsigned int qidx, unsigned int count,
+		       struct qdio_buffer *buffers)
+{
+	int used_elements;
+
+        /* This is the inbound handling of queues */
+	used_elements=atomic_return_add(count, &q->number_of_buffers_used);
+	
+	qdio_do_qdio_fill_input(q,qidx,count,buffers);
+	
+	if ((used_elements+count==QDIO_MAX_BUFFERS_PER_Q)&&
+	    (callflags&QDIO_FLAG_UNDER_INTERRUPT))
+		atomic_swap(&q->polling,0);
+	
+	if (used_elements) 
+		return;
+	if (callflags&QDIO_FLAG_DONT_SIGA)
+		return;
+	if (q->siga_in) {
+		int result;
+		
+		result=qdio_siga_input(q);
+		if (result) {
+			if (q->siga_error)
+				q->error_status_flags|=
+					QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR;
+			q->error_status_flags|=QDIO_STATUS_LOOK_FOR_ERROR;
+			q->siga_error=result;
+		}
+	}
+		
+	qdio_mark_q(q);
+}
+
+static inline void
+do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags,
+			unsigned int qidx, unsigned int count,
+			struct qdio_buffer *buffers)
+{
+	int used_elements;
+
+	/* This is the outbound handling of queues */
+#ifdef QDIO_PERFORMANCE_STATS
+	perf_stats.start_time_outbound=NOW;
+#endif /* QDIO_PERFORMANCE_STATS */
+
+	qdio_do_qdio_fill_output(q,qidx,count,buffers);
+
+	used_elements=atomic_return_add(count, &q->number_of_buffers_used);
+
+	if (callflags&QDIO_FLAG_DONT_SIGA) {
+#ifdef QDIO_PERFORMANCE_STATS
+		perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound;
+		perf_stats.outbound_cnt++;
+#endif /* QDIO_PERFORMANCE_STATS */
+		return;
+	}
+	if (q->is_iqdio_q) {
+		/* one siga for every sbal */
+		while (count--)
+			qdio_kick_outbound_q(q);
+			
+		qdio_outbound_processing(q);
+	} else {
+		/* under VM, we do a SIGA sync unconditionally */
+		SYNC_MEMORY;
+		else {
+			/* 
+			 * w/o shadow queues (else branch of
+			 * SYNC_MEMORY :-/ ), we try to
+			 * fast-requeue buffers 
+			 */
+			if (q->slsb.acc.val[(qidx+QDIO_MAX_BUFFERS_PER_Q-1)
+					    &(QDIO_MAX_BUFFERS_PER_Q-1)]!=
+			    SLSB_CU_OUTPUT_PRIMED) {
+				qdio_kick_outbound_q(q);
+			} else {
+				QDIO_DBF_TEXT3(0,trace, "fast-req");
+#ifdef QDIO_PERFORMANCE_STATS
+				perf_stats.fast_reqs++;
+#endif /* QDIO_PERFORMANCE_STATS */
+			}
+		}
+		/* 
+		 * only marking the q could take too long,
+		 * the upper layer module could do a lot of
+		 * traffic in that time 
+		 */
+		qdio_outbound_processing(q);
+	}
+
+#ifdef QDIO_PERFORMANCE_STATS
+	perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound;
+	perf_stats.outbound_cnt++;
+#endif /* QDIO_PERFORMANCE_STATS */
+}
+
+/* count must be 1 in iqdio */
+int
+do_QDIO(struct ccw_device *cdev,unsigned int callflags,
+	unsigned int queue_number, unsigned int qidx,
+	unsigned int count,struct qdio_buffer *buffers)
+{
+	struct qdio_irq *irq_ptr;
+
+#ifdef QDIO_DBF_LIKE_HELL
+	char dbf_text[20];
+
+	sprintf(dbf_text,"doQD%04x",irq);
+	QDIO_DBF_TEXT3(0,trace,dbf_text);
+#endif /* QDIO_DBF_LIKE_HELL */
+
+	if ( (qidx>QDIO_MAX_BUFFERS_PER_Q) ||
+	     (count>QDIO_MAX_BUFFERS_PER_Q) ||
+	     (queue_number>QDIO_MAX_QUEUES_PER_IRQ) )
+		return -EINVAL;
+
+	if (count==0)
+		return 0;
+
+	irq_ptr = cdev->private->qdio_data;
+	if (!irq_ptr)
+		return -ENODEV;
+
+#ifdef QDIO_DBF_LIKE_HELL
+	if (callflags&QDIO_FLAG_SYNC_INPUT)
+		QDIO_DBF_HEX3(0,trace,&irq_ptr->input_qs[queue_number],
+			      sizeof(void*));
+	else
+		QDIO_DBF_HEX3(0,trace,&irq_ptr->output_qs[queue_number],
+			      sizeof(void*));
+	sprintf(dbf_text,"flag%04x",callflags);
+	QDIO_DBF_TEXT3(0,trace,dbf_text);
+	sprintf(dbf_text,"qi%02xct%02x",qidx,count);
+	QDIO_DBF_TEXT3(0,trace,dbf_text);
+#endif /* QDIO_DBF_LIKE_HELL */
+
+	if (irq_ptr->state!=QDIO_IRQ_STATE_ACTIVE)
+		return -EBUSY;
+
+	if (callflags&QDIO_FLAG_SYNC_INPUT)
+		do_qdio_handle_inbound(irq_ptr->input_qs[queue_number],
+				       callflags, qidx, count, buffers);
+	else if (callflags&QDIO_FLAG_SYNC_OUTPUT)
+		do_qdio_handle_outbound(irq_ptr->output_qs[queue_number],
+					callflags, qidx, count, buffers);
+	else {
+		QDIO_DBF_TEXT3(1,trace,"doQD:inv");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+#ifdef QDIO_PERFORMANCE_STATS
+static int
+qdio_perf_procfile_read(char *buffer, char **buffer_location, off_t offset,
+			int buffer_length, int *eof, void *data)
+{
+        int c=0;
+	int irq;
+
+        /* we are always called with buffer_length=4k, so we all
+           deliver on the first read */
+        if (offset>0)
+		return 0;
+
+#define _OUTP_IT(x...) c+=sprintf(buffer+c,x)
+	_OUTP_IT("i_p_nc/c=%lu/%lu\n",i_p_nc,i_p_c);
+	_OUTP_IT("ii_p_nc/c=%lu/%lu\n",ii_p_nc,ii_p_c);
+	_OUTP_IT("o_p_nc/c=%lu/%lu\n",o_p_nc,o_p_c);
+	_OUTP_IT("Number of tasklet runs (total)                  : %u\n",
+		 perf_stats.tl_runs);
+	_OUTP_IT("\n");
+	_OUTP_IT("Number of SIGA sync's issued                    : %u\n",
+		 perf_stats.siga_syncs);
+	_OUTP_IT("Number of SIGA in's issued                      : %u\n",
+		 perf_stats.siga_ins);
+	_OUTP_IT("Number of SIGA out's issued                     : %u\n",
+		 perf_stats.siga_outs);
+	_OUTP_IT("Number of PCI's caught                          : %u\n",
+		 perf_stats.pcis);
+	_OUTP_IT("Number of adapter interrupts caught             : %u\n",
+		 perf_stats.thinints);
+	_OUTP_IT("Number of fast requeues (outg. SBALs w/o SIGA)  : %u\n",
+		 perf_stats.fast_reqs);
+	_OUTP_IT("\n");
+	_OUTP_IT("Total time of all inbound actions (us) incl. UL : %u\n",
+		 perf_stats.inbound_time);
+	_OUTP_IT("Number of inbound transfers                     : %u\n",
+		 perf_stats.inbound_cnt);
+	_OUTP_IT("Total time of all outbound do_QDIOs (us)        : %u\n",
+		 perf_stats.outbound_time);
+	_OUTP_IT("Number of do_QDIOs outbound                     : %u\n",
+		 perf_stats.outbound_cnt);
+	_OUTP_IT("\n");
+
+	/* 
+	 * FIXME: Rather use driver_for_each_dev, if we had it. 
+	 * I know this loop destroys our layering, but at least gets the 
+	 * performance stats out...
+	 */
+	for (irq=0;irq <= highest_subchannel; irq++) {
+		struct qdio_irq *irq_ptr;
+		struct ccw_device *cdev;
+
+		if (!ioinfo[irq])
+			continue;
+		cdev = ioinfo[irq]->dev.driver_data;
+		if (!cdev)
+			continue;
+		irq_ptr = cdev->private->qdio_data;
+		if (!irq_ptr)
+			continue;
+		_OUTP_IT("Polling time on irq %4x                        " \
+			 ": %u\n",
+			 irq_ptr->irq,irq_ptr->input_qs[0]->timing.threshold);
+	}
+        return c;
+}
+
+static struct proc_dir_entry *qdio_perf_proc_file;
+#endif /* QDIO_PERFORMANCE_STATS */
+
+static void
+qdio_add_procfs_entry(void)
+{
+#ifdef QDIO_PERFORMANCE_STATS
+        proc_perf_file_registration=0;
+	qdio_perf_proc_file=create_proc_entry(QDIO_PERF,
+					      S_IFREG|0444,&proc_root);
+	if (qdio_perf_proc_file) {
+		qdio_perf_proc_file->read_proc=&qdio_perf_procfile_read;
+	} else proc_perf_file_registration=-1;
+
+        if (proc_perf_file_registration)
+                QDIO_PRINT_WARN("was not able to register perf. " \
+				"proc-file (%i).\n",
+				proc_perf_file_registration);
+#endif /* QDIO_PERFORMANCE_STATS */
+}
+
+static void
+qdio_remove_procfs_entry(void)
+{
+#ifdef QDIO_PERFORMANCE_STATS
+	perf_stats.tl_runs=0;
+
+        if (!proc_perf_file_registration) /* means if it went ok earlier */
+		remove_proc_entry(QDIO_PERF,&proc_root);
+#endif /* QDIO_PERFORMANCE_STATS */
+}
+
+static void
+iqdio_register_thinints(void)
+{
+	char dbf_text[20];
+	register_thinint_result=
+		s390_register_adapter_interrupt(&iqdio_thinint_handler);
+	if (register_thinint_result) {
+		sprintf(dbf_text,"regthn%x",(register_thinint_result&0xff));
+		QDIO_DBF_TEXT0(0,setup,dbf_text);
+		QDIO_PRINT_ERR("failed to register adapter handler " \
+			       "(rc=%i).\nAdapter interrupts might " \
+			       "not work. Continuing.\n",
+			       register_thinint_result);
+	}
+}
+
+static void
+iqdio_unregister_thinints(void)
+{
+	if (!register_thinint_result)
+		s390_unregister_adapter_interrupt(&iqdio_thinint_handler);
+}
+
+static int
+qdio_get_qdio_memory(void)
+{
+	int i;
+	indicator_used[0]=1;
+
+	for (i=1;i<INDICATORS_PER_CACHELINE;i++)
+		indicator_used[i]=0;
+	indicators=(__u32*)kmalloc(sizeof(__u32)*(INDICATORS_PER_CACHELINE),
+				   GFP_KERNEL);
+       	if (!indicators) return -ENOMEM;
+	memset(indicators,0,sizeof(__u32)*(INDICATORS_PER_CACHELINE));
+
+	chsc_area=(struct qdio_chsc_area *)
+		kmalloc(sizeof(struct qdio_chsc_area),GFP_KERNEL);
+	QDIO_DBF_TEXT3(0,trace,"chscarea"); \
+	QDIO_DBF_HEX3(0,trace,&chsc_area,sizeof(void*)); \
+	if (!chsc_area) {
+		QDIO_PRINT_ERR("not enough memory for chsc area. Cannot " \
+			       "initialize QDIO.\n");
+		kfree(indicators);
+		return -ENOMEM;
+	}
+	memset(chsc_area,0,sizeof(struct qdio_chsc_area));
+	return 0;
+}
+
+static void
+qdio_release_qdio_memory(void)
+{
+	kfree(chsc_area);
+	if (indicators)
+		kfree(indicators);
+}
+
+static void
+qdio_unregister_dbf_views(void)
+{
+	if (qdio_dbf_setup)
+		debug_unregister(qdio_dbf_setup);
+	if (qdio_dbf_sbal)
+		debug_unregister(qdio_dbf_sbal);
+	if (qdio_dbf_sense)
+		debug_unregister(qdio_dbf_sense);
+	if (qdio_dbf_trace)
+		debug_unregister(qdio_dbf_trace);
+#ifdef QDIO_DBF_LIKE_HELL
+        if (qdio_dbf_slsb_out)
+                debug_unregister(qdio_dbf_slsb_out);
+        if (qdio_dbf_slsb_in)
+                debug_unregister(qdio_dbf_slsb_in);
+#endif /* QDIO_DBF_LIKE_HELL */
+}
+
+static int
+qdio_register_dbf_views(void)
+{
+	qdio_dbf_setup=debug_register(QDIO_DBF_SETUP_NAME,
+				      QDIO_DBF_SETUP_INDEX,
+				      QDIO_DBF_SETUP_NR_AREAS,
+				      QDIO_DBF_SETUP_LEN);
+	if (!qdio_dbf_setup)
+		goto oom;
+	debug_register_view(qdio_dbf_setup,&debug_hex_ascii_view);
+	debug_set_level(qdio_dbf_setup,QDIO_DBF_SETUP_LEVEL);
+
+	qdio_dbf_sbal=debug_register(QDIO_DBF_SBAL_NAME,
+				     QDIO_DBF_SBAL_INDEX,
+				     QDIO_DBF_SBAL_NR_AREAS,
+				     QDIO_DBF_SBAL_LEN);
+	if (!qdio_dbf_sbal)
+		goto oom;
+
+	debug_register_view(qdio_dbf_sbal,&debug_hex_ascii_view);
+	debug_set_level(qdio_dbf_sbal,QDIO_DBF_SBAL_LEVEL);
+
+	qdio_dbf_sense=debug_register(QDIO_DBF_SENSE_NAME,
+				      QDIO_DBF_SENSE_INDEX,
+				      QDIO_DBF_SENSE_NR_AREAS,
+				      QDIO_DBF_SENSE_LEN);
+	if (!qdio_dbf_sense)
+		goto oom;
+
+	debug_register_view(qdio_dbf_sense,&debug_hex_ascii_view);
+	debug_set_level(qdio_dbf_sense,QDIO_DBF_SENSE_LEVEL);
+
+	qdio_dbf_trace=debug_register(QDIO_DBF_TRACE_NAME,
+				      QDIO_DBF_TRACE_INDEX,
+				      QDIO_DBF_TRACE_NR_AREAS,
+				      QDIO_DBF_TRACE_LEN);
+	if (!qdio_dbf_trace)
+		goto oom;
+
+	debug_register_view(qdio_dbf_trace,&debug_hex_ascii_view);
+	debug_set_level(qdio_dbf_trace,QDIO_DBF_TRACE_LEVEL);
+
+#ifdef QDIO_DBF_LIKE_HELL
+        qdio_dbf_slsb_out=debug_register(QDIO_DBF_SLSB_OUT_NAME,
+                                         QDIO_DBF_SLSB_OUT_INDEX,
+                                         QDIO_DBF_SLSB_OUT_NR_AREAS,
+                                         QDIO_DBF_SLSB_OUT_LEN);
+        if (!qdio_dbf_slsb_out)
+		goto oom;
+        debug_register_view(qdio_dbf_slsb_out,&debug_hex_ascii_view);
+        debug_set_level(qdio_dbf_slsb_out,QDIO_DBF_SLSB_OUT_LEVEL);
+
+        qdio_dbf_slsb_in=debug_register(QDIO_DBF_SLSB_IN_NAME,
+                                        QDIO_DBF_SLSB_IN_INDEX,
+                                        QDIO_DBF_SLSB_IN_NR_AREAS,
+                                        QDIO_DBF_SLSB_IN_LEN);
+        if (!qdio_dbf_slsb_in)
+		goto oom;
+        debug_register_view(qdio_dbf_slsb_in,&debug_hex_ascii_view);
+        debug_set_level(qdio_dbf_slsb_in,QDIO_DBF_SLSB_IN_LEVEL);
+#endif /* QDIO_DBF_LIKE_HELL */
+	return 0;
+oom:
+	QDIO_PRINT_ERR("not enough memory for dbf.\n");
+	qdio_unregister_dbf_views();
+	return -ENOMEM;
+}
+
+static int __init
+init_QDIO(void)
+{
+	int res;
+#ifdef QDIO_PERFORMANCE_STATS
+	void *ptr;
+#endif /* QDIO_PERFORMANCE_STATS */
+
+	printk("qdio: loading %s\n",version);
+
+	res=qdio_get_qdio_memory();
+	if (res)
+		return res;
+
+	sema_init(&init_sema,1);
+
+	res = qdio_register_dbf_views();
+	if (res)
+		return res;
+
+	QDIO_DBF_TEXT0(0,setup,"initQDIO");
+
+#ifdef QDIO_PERFORMANCE_STATS
+       	memset((void*)&perf_stats,0,sizeof(perf_stats));
+	QDIO_DBF_TEXT0(0,setup,"perfstat");
+	ptr=&perf_stats;
+	QDIO_DBF_HEX0(0,setup,&ptr,sizeof(void*));
+#endif /* QDIO_PERFORMANCE_STATS */
+
+	qdio_add_procfs_entry();
+	iqdio_register_thinints();
+
+	return 0;
+ }
+
+static void __exit
+cleanup_QDIO(void)
+{
+	iqdio_unregister_thinints();
+	qdio_remove_procfs_entry();
+	qdio_release_qdio_memory();
+	qdio_unregister_dbf_views();
+
+  	printk("qdio: %s: module removed\n",version);
+}
+
+module_init(init_QDIO);
+module_exit(cleanup_QDIO);
+
+EXPORT_SYMBOL(qdio_initialize);
+EXPORT_SYMBOL(qdio_activate);
+EXPORT_SYMBOL(do_QDIO);
+EXPORT_SYMBOL(qdio_cleanup);
+EXPORT_SYMBOL(qdio_synchronize);
diff -Nru a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/cio/qdio.h	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,701 @@
+#ifndef _CIO_QDIO_H
+#define _CIO_QDIO_H
+
+#define VERSION_CIO_QDIO_H "$Revision: 1.8 $"
+
+//#define QDIO_DBF_LIKE_HELL
+
+#ifdef QDIO_DBF_LIKE_HELL
+#define QDIO_VERBOSE_LEVEL 9
+#else /* QDIO_DBF_LIKE_HELL */
+#define QDIO_VERBOSE_LEVEL 5
+#endif /* QDIO_DBF_LIKE_HELL */
+
+#define QDIO_USE_PROCESSING_STATE
+
+#ifdef CONFIG_QDIO_PERF_STATS
+#define QDIO_PERFORMANCE_STATS
+#endif /* CONFIG_QDIO_PERF_STATS */
+
+#define QDIO_MINIMAL_BH_RELIEF_TIME 16
+#define QDIO_TIMER_POLL_VALUE 1
+#define IQDIO_TIMER_POLL_VALUE 1
+
+#define IQDIO_FILL_LEVEL_TO_POLL (QDIO_MAX_BUFFERS_PER_Q*4/3)
+
+#define IQDIO_THININT_ISC 3
+#define IQDIO_DELAY_TARGET 0
+#define QDIO_BUSY_BIT_PATIENCE 2000 /* in microsecs */
+#define IQDIO_GLOBAL_LAPS 2 /* GLOBAL_LAPS are not used as we */
+#define IQDIO_GLOBAL_LAPS_INT 1 /* dont global summary */
+#define IQDIO_LOCAL_LAPS 4
+#define IQDIO_LOCAL_LAPS_INT 1
+#define IQDIO_GLOBAL_SUMMARY_CC_MASK 2
+/*#define IQDIO_IQDC_INT_PARM 0x1234*/
+
+#define QDIO_Q_LAPS 5
+
+#define QDIO_STORAGE_KEY 0
+
+#define L2_CACHELINE_SIZE 256
+#define INDICATORS_PER_CACHELINE (L2_CACHELINE_SIZE/sizeof(__u32))
+
+#define QDIO_PERF "qdio_perf"
+
+/* must be a power of 2 */
+/*#define QDIO_STATS_NUMBER 4
+
+#define QDIO_STATS_CLASSES 2
+#define QDIO_STATS_COUNT_NEEDED 2*/
+
+#define QDIO_NO_USE_COUNT_TIME 10
+#define QDIO_NO_USE_COUNT_TIMEOUT 1000 /* wait for 1 sec on each q before
+					  exiting without having use_count
+					  of the queue to 0 */
+
+#define QDIO_ESTABLISH_TIMEOUT 1000
+#define QDIO_ACTIVATE_TIMEOUT 100
+#define QDIO_CLEANUP_CLEAR_TIMEOUT 20000
+#define QDIO_CLEANUP_HALT_TIMEOUT 10000
+
+#define QDIO_IRQ_STATE_FRESH 0 /* must be 0 -> memset has set it to 0 */
+#define QDIO_IRQ_STATE_INACTIVE 1
+#define QDIO_IRQ_STATE_ESTABLISHED 2
+#define QDIO_IRQ_STATE_ACTIVE 3
+#define QDIO_IRQ_STATE_STOPPED 4
+
+/* used as intparm in do_IO: */
+#define QDIO_DOING_SENSEID 0
+#define QDIO_DOING_ESTABLISH 1
+#define QDIO_DOING_ACTIVATE 2
+#define QDIO_DOING_CLEANUP 3
+
+/************************* DEBUG FACILITY STUFF *********************/
+
+#define QDIO_DBF_HEX(ex,name,level,addr,len) \
+	do { \
+	if (ex) \
+		debug_exception(qdio_dbf_##name,level,(void*)(addr),len); \
+	else \
+		debug_event(qdio_dbf_##name,level,(void*)(addr),len); \
+	} while (0)
+#define QDIO_DBF_TEXT(ex,name,level,text) \
+	do { \
+	if (ex) \
+		debug_text_exception(qdio_dbf_##name,level,text); \
+	else \
+		debug_text_event(qdio_dbf_##name,level,text); \
+	} while (0)
+
+
+#define QDIO_DBF_HEX0(ex,name,addr,len) QDIO_DBF_HEX(ex,name,0,addr,len)
+#define QDIO_DBF_HEX1(ex,name,addr,len) QDIO_DBF_HEX(ex,name,1,addr,len)
+#define QDIO_DBF_HEX2(ex,name,addr,len) QDIO_DBF_HEX(ex,name,2,addr,len)
+#ifdef QDIO_DBF_LIKE_HELL
+#define QDIO_DBF_HEX3(ex,name,addr,len) QDIO_DBF_HEX(ex,name,3,addr,len)
+#define QDIO_DBF_HEX4(ex,name,addr,len) QDIO_DBF_HEX(ex,name,4,addr,len)
+#define QDIO_DBF_HEX5(ex,name,addr,len) QDIO_DBF_HEX(ex,name,5,addr,len)
+#define QDIO_DBF_HEX6(ex,name,addr,len) QDIO_DBF_HEX(ex,name,6,addr,len)
+#else /* QDIO_DBF_LIKE_HELL */
+#define QDIO_DBF_HEX3(ex,name,addr,len) do {} while (0)
+#define QDIO_DBF_HEX4(ex,name,addr,len) do {} while (0)
+#define QDIO_DBF_HEX5(ex,name,addr,len) do {} while (0)
+#define QDIO_DBF_HEX6(ex,name,addr,len) do {} while (0)
+#endif /* QDIO_DBF_LIKE_HELL */
+
+#define QDIO_DBF_TEXT0(ex,name,text) QDIO_DBF_TEXT(ex,name,0,text)
+#define QDIO_DBF_TEXT1(ex,name,text) QDIO_DBF_TEXT(ex,name,1,text)
+#define QDIO_DBF_TEXT2(ex,name,text) QDIO_DBF_TEXT(ex,name,2,text)
+#ifdef QDIO_DBF_LIKE_HELL
+#define QDIO_DBF_TEXT3(ex,name,text) QDIO_DBF_TEXT(ex,name,3,text)
+#define QDIO_DBF_TEXT4(ex,name,text) QDIO_DBF_TEXT(ex,name,4,text)
+#define QDIO_DBF_TEXT5(ex,name,text) QDIO_DBF_TEXT(ex,name,5,text)
+#define QDIO_DBF_TEXT6(ex,name,text) QDIO_DBF_TEXT(ex,name,6,text)
+#else /* QDIO_DBF_LIKE_HELL */
+#define QDIO_DBF_TEXT3(ex,name,text) do {} while (0)
+#define QDIO_DBF_TEXT4(ex,name,text) do {} while (0)
+#define QDIO_DBF_TEXT5(ex,name,text) do {} while (0)
+#define QDIO_DBF_TEXT6(ex,name,text) do {} while (0)
+#endif /* QDIO_DBF_LIKE_HELL */
+
+#define QDIO_DBF_SETUP_NAME "qdio_setup"
+#define QDIO_DBF_SETUP_LEN 8
+#define QDIO_DBF_SETUP_INDEX 2
+#define QDIO_DBF_SETUP_NR_AREAS 1
+#ifdef QDIO_DBF_LIKE_HELL
+#define QDIO_DBF_SETUP_LEVEL 6
+#else /* QDIO_DBF_LIKE_HELL */
+#define QDIO_DBF_SETUP_LEVEL 2
+#endif /* QDIO_DBF_LIKE_HELL */
+
+#define QDIO_DBF_SBAL_NAME "qdio_labs" /* sbal */
+#define QDIO_DBF_SBAL_LEN 256
+#define QDIO_DBF_SBAL_INDEX 2
+#define QDIO_DBF_SBAL_NR_AREAS 2
+#ifdef QDIO_DBF_LIKE_HELL
+#define QDIO_DBF_SBAL_LEVEL 6
+#else /* QDIO_DBF_LIKE_HELL */
+#define QDIO_DBF_SBAL_LEVEL 2
+#endif /* QDIO_DBF_LIKE_HELL */
+
+#define QDIO_DBF_TRACE_NAME "qdio_trace"
+#define QDIO_DBF_TRACE_LEN 8
+#define QDIO_DBF_TRACE_NR_AREAS 2
+#ifdef QDIO_DBF_LIKE_HELL
+#define QDIO_DBF_TRACE_INDEX 4
+#define QDIO_DBF_TRACE_LEVEL 4 /* -------- could be even more verbose here */
+#else /* QDIO_DBF_LIKE_HELL */
+#define QDIO_DBF_TRACE_INDEX 2
+#define QDIO_DBF_TRACE_LEVEL 2
+#endif /* QDIO_DBF_LIKE_HELL */
+
+#define QDIO_DBF_SENSE_NAME "qdio_sense"
+#define QDIO_DBF_SENSE_LEN 64
+#define QDIO_DBF_SENSE_INDEX 1
+#define QDIO_DBF_SENSE_NR_AREAS 1
+#ifdef QDIO_DBF_LIKE_HELL
+#define QDIO_DBF_SENSE_LEVEL 6
+#else /* QDIO_DBF_LIKE_HELL */
+#define QDIO_DBF_SENSE_LEVEL 2
+#endif /* QDIO_DBF_LIKE_HELL */
+
+#ifdef QDIO_DBF_LIKE_HELL
+#define QDIO_TRACE_QTYPE QDIO_ZFCP_QFMT
+
+#define QDIO_DBF_SLSB_OUT_NAME "qdio_slsb_out"
+#define QDIO_DBF_SLSB_OUT_LEN QDIO_MAX_BUFFERS_PER_Q
+#define QDIO_DBF_SLSB_OUT_INDEX 8
+#define QDIO_DBF_SLSB_OUT_NR_AREAS 1
+#define QDIO_DBF_SLSB_OUT_LEVEL 6
+
+#define QDIO_DBF_SLSB_IN_NAME "qdio_slsb_in"
+#define QDIO_DBF_SLSB_IN_LEN QDIO_MAX_BUFFERS_PER_Q
+#define QDIO_DBF_SLSB_IN_INDEX 8
+#define QDIO_DBF_SLSB_IN_NR_AREAS 1
+#define QDIO_DBF_SLSB_IN_LEVEL 6
+#endif /* QDIO_DBF_LIKE_HELL */
+
+#define QDIO_PRINTK_HEADER QDIO_NAME ": "
+
+#if QDIO_VERBOSE_LEVEL>8
+#define QDIO_PRINT_STUPID(x...) printk( KERN_DEBUG QDIO_PRINTK_HEADER x)
+#else
+#define QDIO_PRINT_STUPID(x...)
+#endif
+
+#if QDIO_VERBOSE_LEVEL>7
+#define QDIO_PRINT_ALL(x...) printk( QDIO_PRINTK_HEADER x)
+#else
+#define QDIO_PRINT_ALL(x...)
+#endif
+
+#if QDIO_VERBOSE_LEVEL>6
+#define QDIO_PRINT_INFO(x...) printk( QDIO_PRINTK_HEADER x)
+#else
+#define QDIO_PRINT_INFO(x...)
+#endif
+
+#if QDIO_VERBOSE_LEVEL>5
+#define QDIO_PRINT_WARN(x...) printk( QDIO_PRINTK_HEADER x)
+#else
+#define QDIO_PRINT_WARN(x...)
+#endif
+
+#if QDIO_VERBOSE_LEVEL>4
+#define QDIO_PRINT_ERR(x...) printk( QDIO_PRINTK_HEADER x)
+#else
+#define QDIO_PRINT_ERR(x...)
+#endif
+
+#if QDIO_VERBOSE_LEVEL>3
+#define QDIO_PRINT_CRIT(x...) printk( QDIO_PRINTK_HEADER x)
+#else
+#define QDIO_PRINT_CRIT(x...)
+#endif
+
+#if QDIO_VERBOSE_LEVEL>2
+#define QDIO_PRINT_ALERT(x...) printk( QDIO_PRINTK_HEADER x)
+#else
+#define QDIO_PRINT_ALERT(x...)
+#endif
+
+#if QDIO_VERBOSE_LEVEL>1
+#define QDIO_PRINT_EMERG(x...) printk( QDIO_PRINTK_HEADER x)
+#else
+#define QDIO_PRINT_EMERG(x...)
+#endif
+
+#define HEXDUMP16(importance,header,ptr) \
+QDIO_PRINT_##importance(header "%02x %02x %02x %02x  " \
+			"%02x %02x %02x %02x  %02x %02x %02x %02x  " \
+			"%02x %02x %02x %02x\n",*(((char*)ptr)), \
+			*(((char*)ptr)+1),*(((char*)ptr)+2), \
+			*(((char*)ptr)+3),*(((char*)ptr)+4), \
+			*(((char*)ptr)+5),*(((char*)ptr)+6), \
+			*(((char*)ptr)+7),*(((char*)ptr)+8), \
+			*(((char*)ptr)+9),*(((char*)ptr)+10), \
+			*(((char*)ptr)+11),*(((char*)ptr)+12), \
+			*(((char*)ptr)+13),*(((char*)ptr)+14), \
+			*(((char*)ptr)+15)); \
+QDIO_PRINT_##importance(header "%02x %02x %02x %02x  %02x %02x %02x %02x  " \
+			"%02x %02x %02x %02x  %02x %02x %02x %02x\n", \
+			*(((char*)ptr)+16),*(((char*)ptr)+17), \
+			*(((char*)ptr)+18),*(((char*)ptr)+19), \
+			*(((char*)ptr)+20),*(((char*)ptr)+21), \
+			*(((char*)ptr)+22),*(((char*)ptr)+23), \
+			*(((char*)ptr)+24),*(((char*)ptr)+25), \
+			*(((char*)ptr)+26),*(((char*)ptr)+27), \
+			*(((char*)ptr)+28),*(((char*)ptr)+29), \
+			*(((char*)ptr)+30),*(((char*)ptr)+31));
+
+/****************** END OF DEBUG FACILITY STUFF *********************/
+
+/*
+ * Some instructions as assembly
+ */
+extern __inline__ int 
+do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2)
+{
+	int cc;
+
+#ifndef CONFIG_ARCH_S390X
+	asm volatile (
+		"lhi	0,2	\n\t"
+		"lr	1,%1	\n\t"
+		"lr	2,%2	\n\t"
+		"lr	3,%3	\n\t"
+		"siga   0	\n\t"
+		"ipm	%0	\n\t"
+		"srl	%0,28	\n\t"
+		: "=d" (cc)
+		: "d" (0x10000|irq), "d" (mask1), "d" (mask2)
+		: "cc", "0", "1", "2", "3"
+		);
+#else /* CONFIG_ARCH_S390X */
+	asm volatile (
+		"lghi	0,2	\n\t"
+		"llgfr	1,%1	\n\t"
+		"llgfr	2,%2	\n\t"
+		"llgfr	3,%3	\n\t"
+		"siga   0	\n\t"
+		"ipm	%0	\n\t"
+		"srl	%0,28	\n\t"
+		: "=d" (cc)
+		: "d" (0x10000|irq), "d" (mask1), "d" (mask2)
+		: "cc", "0", "1", "2", "3"
+		);
+#endif /* CONFIG_ARCH_S390X */
+	return cc;
+}
+
+extern __inline__ int
+do_siga_input(unsigned int irq, unsigned int mask)
+{
+	int cc;
+
+#ifndef CONFIG_ARCH_S390X
+	asm volatile (
+		"lhi	0,1	\n\t"
+		"lr	1,%1	\n\t"
+		"lr	2,%2	\n\t"
+		"siga   0	\n\t"
+		"ipm	%0	\n\t"
+		"srl	%0,28	\n\t"
+		: "=d" (cc)
+		: "d" (0x10000|irq), "d" (mask)
+		: "cc", "0", "1", "2", "memory"
+		);
+#else /* CONFIG_ARCH_S390X */
+	asm volatile (
+		"lghi	0,1	\n\t"
+		"llgfr	1,%1	\n\t"
+		"llgfr	2,%2	\n\t"
+		"siga   0	\n\t"
+		"ipm	%0	\n\t"
+		"srl	%0,28	\n\t"
+		: "=d" (cc)
+		: "d" (0x10000|irq), "d" (mask)
+		: "cc", "0", "1", "2", "memory"
+		);
+#endif /* CONFIG_ARCH_S390X */
+	
+	return cc;
+}
+
+extern __inline__ int
+do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb)
+{
+	int cc;
+	__u32 busy_bit;
+
+#ifndef CONFIG_ARCH_S390X
+	asm volatile (
+		"lhi	0,0	\n\t"
+		"lr	1,%2	\n\t"
+		"lr	2,%3	\n\t"
+		"siga	0	\n\t"
+		"0:"
+		"ipm	%0	\n\t"
+		"srl	%0,28	\n\t"
+		"srl	0,31	\n\t"
+		"lr	%1,0	\n\t"
+		"1:	\n\t"
+		".section .fixup,\"ax\"\n\t"
+		"2:	\n\t"
+		"lhi	%0,%4	\n\t"
+		"bras	1,3f	\n\t"
+		".long 1b	\n\t"
+		"3:	\n\t"
+		"l	1,0(1)	\n\t"
+		"br	1	\n\t"
+		".previous	\n\t"
+		".section __ex_table,\"a\"\n\t"
+		".align 4	\n\t"
+		".long	0b,2b	\n\t"
+		".previous	\n\t"
+		: "=d" (cc), "=d" (busy_bit)
+		: "d" (0x10000|irq), "d" (mask),
+		"i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION)
+		: "cc", "0", "1", "2", "memory"
+		);
+#else /* CONFIG_ARCH_S390X */
+	asm volatile (
+		"lghi	0,0	\n\t"
+		"llgfr	1,%2	\n\t"
+		"llgfr	2,%3	\n\t"
+		"siga	0	\n\t"
+		"0:"
+		"ipm	%0	\n\t"
+		"srl	%0,28	\n\t"
+		"srl	0,31	\n\t"
+		"llgfr	%1,0	\n\t"
+		"1:	\n\t"
+		".section .fixup,\"ax\"\n\t"
+		"lghi	%0,%4	\n\t"
+		"jg	1b	\n\t"
+		".previous\n\t"
+		".section __ex_table,\"a\"\n\t"
+		".align 8	\n\t"
+		".quad	0b,1b	\n\t"
+		".previous	\n\t"
+		: "=d" (cc), "=d" (busy_bit)
+		: "d" (0x10000|irq), "d" (mask),
+		"i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION)
+		: "cc", "0", "1", "2", "memory"
+		);
+#endif /* CONFIG_ARCH_S390X */
+	
+	(*bb) = busy_bit;
+	return cc;
+}
+
+extern __inline__ unsigned long
+do_clear_global_summary(void)
+{
+
+	unsigned long time;
+
+#ifndef CONFIG_ARCH_S390X
+	asm volatile (
+		"lhi	1,3	\n\t"
+		".insn	rre,0xb2650000,2,0	\n\t"
+		"lr	%0,3	\n\t"
+		: "=d" (time) : : "cc", "1", "2", "3"
+		);
+#else /* CONFIG_ARCH_S390X */
+	asm volatile (
+		"lghi	1,3	\n\t"
+		".insn	rre,0xb2650000,2,0	\n\t"
+		"lgr	%0,3	\n\t"
+		: "=d" (time) : : "cc", "1", "2", "3"
+		);
+#endif /* CONFIG_ARCH_S390X */
+	
+	return time;
+}
+	
+/*
+ * QDIO device commands returned by extended Sense-ID
+ */
+#define DEFAULT_ESTABLISH_QS_CMD 0x1b
+#define DEFAULT_ESTABLISH_QS_COUNT 0x1000
+#define DEFAULT_ACTIVATE_QS_CMD 0x1f
+#define DEFAULT_ACTIVATE_QS_COUNT 0
+
+/*
+ * additional CIWs returned by extended Sense-ID
+ */
+#define CIW_TYPE_EQUEUE 0x3       /* establish QDIO queues */
+#define CIW_TYPE_AQUEUE 0x4       /* activate QDIO queues */
+
+#define QDIO_CHSC_RESPONSE_CODE_OK 1
+/* flags for st qdio sch data */
+#define CHSC_FLAG_QDIO_CAPABILITY 0x80
+#define CHSC_FLAG_VALIDITY 0x40
+
+#define CHSC_FLAG_SIGA_INPUT_NECESSARY 0x40
+#define CHSC_FLAG_SIGA_OUTPUT_NECESSARY 0x20
+#define CHSC_FLAG_SIGA_SYNC_NECESSARY 0x10
+#define CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS 0x08
+#define CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS 0x04
+
+struct qdio_chsc_area {
+	struct {
+		/* word 0 */
+		__u16 command_code1;
+		__u16 command_code2;
+		/* word 1 */
+		__u16 operation_code;
+		__u16 first_sch;
+		/* word 2 */
+		__u8 reserved1;
+		__u8 image_id;
+		__u16 last_sch;
+		/* word 3 */
+		__u32 reserved2;
+
+		/* word 4 */
+		union {
+			struct {
+				/* word 4&5 */
+				__u64 summary_indicator_addr;
+				/* word 6&7 */
+				__u64 subchannel_indicator_addr;
+				/* word 8 */
+				int ks:4;
+				int kc:4;
+				int reserved1:21;
+				int isc:3;
+				/* word 9&10 */
+				__u32 reserved2[2];
+				/* word 11 */
+				__u32 subsystem_id;
+				/* word 12-1015 */
+				__u32 reserved3[1004];
+			} __attribute__ ((packed,aligned(4))) set_chsc;
+			struct {
+				/* word 4&5 */
+				__u32 reserved1[2];	
+				/* word 6 */
+				__u32 delay_target;
+				/* word 7-1015 */
+				__u32 reserved4[1009];
+			} __attribute__ ((packed,aligned(4))) set_chsc_fast;
+			struct {
+				/* word 0 */
+				__u16 length;
+				__u16 response_code;
+				/* word 1 */
+				__u32 reserved1;
+				/* words 2 to 9 for st sch qdio data */
+				__u8 flags;
+				__u8 reserved2;
+				__u16 sch;
+				__u8 qfmt;
+				__u8 reserved3;
+				__u8 qdioac;
+				__u8 sch_class;
+				__u8 reserved4;
+				__u8 icnt;
+				__u8 reserved5;
+				__u8 ocnt;
+				/* plus 5 words of reserved fields */
+			} __attribute__ ((packed,aligned(8)))
+			store_qdio_data_response;
+		} operation_data_area;
+	} __attribute__ ((packed,aligned(8))) request_block;
+	struct {
+		/* word 0 */
+		__u16 length;
+		__u16 response_code;
+		/* word 1 */
+		__u32 reserved1;
+	} __attribute__ ((packed,aligned(8))) response_block;
+} __attribute__ ((packed,aligned(PAGE_SIZE)));
+
+
+#ifdef QDIO_PERFORMANCE_STATS
+struct qdio_perf_stats {
+	unsigned int tl_runs;
+
+	unsigned int siga_outs;
+	unsigned int siga_ins;
+	unsigned int siga_syncs;
+	unsigned int pcis;
+	unsigned int thinints;
+	unsigned int fast_reqs;
+
+	__u64 start_time_outbound;
+	unsigned int outbound_cnt;
+	unsigned int outbound_time;
+	__u64 start_time_inbound;
+	unsigned int inbound_cnt;
+	unsigned int inbound_time;
+};
+#endif /* QDIO_PERFORMANCE_STATS */
+
+#define atomic_swap(a,b) xchg((int*)a.counter,b)
+
+#define SYNC_MEMORY if (q->siga_sync) qdio_siga_sync(q)
+#define NOW qdio_get_micros()
+#define SAVE_TIMESTAMP(q) q->timing.last_transfer_time=NOW
+#define GET_SAVED_TIMESTAMP(q) (q->timing.last_transfer_time)
+#define SAVE_FRONTIER(q,val) q->last_move_ftc=val
+#define GET_SAVED_FRONTIER(q) (q->last_move_ftc)
+
+#define MY_MODULE_STRING(x) #x
+
+#ifdef CONFIG_ARCH_S390X
+#define QDIO_GET_ADDR(x) ((__u32)(unsigned long)x)
+#else /* CONFIG_ARCH_S390X */
+#define QDIO_GET_ADDR(x) ((__u32)(long)x)
+#endif /* CONFIG_ARCH_S390X */
+
+#ifdef QDIO_DBF_LIKE_HELL 
+#define set_slsb(x,y) \
+  if(q->queue_type==QDIO_TRACE_QTYPE) { \
+        if(q->is_input_q) { \
+            QDIO_DBF_HEX2(0,slsb_in,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \
+        } else { \
+            QDIO_DBF_HEX2(0,slsb_out,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \
+        } \
+  } \
+  qdio_set_slsb(x,y); \
+  if(q->queue_type==QDIO_TRACE_QTYPE) { \
+        if(q->is_input_q) { \
+            QDIO_DBF_HEX2(0,slsb_in,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \
+        } else { \
+            QDIO_DBF_HEX2(0,slsb_out,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \
+        } \
+  }
+#else /* QDIO_DBF_LIKE_HELL */
+#define set_slsb(x,y) qdio_set_slsb(x,y)
+#endif /* QDIO_DBF_LIKE_HELL */
+
+struct qdio_q {
+	volatile struct slsb slsb;
+
+	__u32 * volatile dev_st_chg_ind;
+
+	int is_input_q;
+	int irq;
+
+	unsigned int is_iqdio_q;
+
+	/* bit 0 means queue 0, bit 1 means queue 1, ... */
+	unsigned int mask;
+	unsigned int q_no;
+
+	qdio_handler_t (*handler);
+
+	/* points to the next buffer to be checked for having
+	 * been processed by the card (outbound)
+	 * or to the next buffer the program should check for (inbound) */
+	volatile int first_to_check;
+	/* and the last time it was: */
+	volatile int last_move_ftc;
+
+	atomic_t number_of_buffers_used;
+	atomic_t polling;
+
+	unsigned int siga_in;
+	unsigned int siga_out;
+	unsigned int siga_sync;
+	unsigned int siga_sync_done_on_thinints;
+	unsigned int hydra_gives_outbound_pcis;
+
+	/* used to save beginning position when calling dd_handlers */
+	int first_element_to_kick;
+
+	atomic_t use_count;
+	atomic_t is_in_shutdown;
+
+#ifdef QDIO_USE_TIMERS_FOR_POLLING
+	struct timer_list timer;
+	atomic_t timer_already_set;
+	spinlock_t timer_lock;
+#else /* QDIO_USE_TIMERS_FOR_POLLING */
+	struct tasklet_struct tasklet;
+#endif /* QDIO_USE_TIMERS_FOR_POLLING */
+
+	unsigned int state;
+
+	/* used to store the error condition during a data transfer */
+	unsigned int qdio_error;
+	unsigned int siga_error;
+	unsigned int error_status_flags;
+
+	/* list of interesting queues */
+	volatile struct qdio_q *list_next;
+	volatile struct qdio_q *list_prev;
+
+	struct slib *slib; /* a page is allocated under this pointer,
+			      sl points into this page, offset PAGE_SIZE/2
+			      (after slib) */
+	struct sl *sl;
+	volatile struct sbal *sbal[QDIO_MAX_BUFFERS_PER_Q];
+
+	struct qdio_buffer *qdio_buffers[QDIO_MAX_BUFFERS_PER_Q];
+
+	unsigned long int_parm;
+
+	/*struct {
+		int in_bh_check_limit;
+		int threshold;
+	} threshold_classes[QDIO_STATS_CLASSES];*/
+
+	struct {
+		/* inbound: the time to stop polling
+		   outbound: the time to kick peer */
+		int threshold; /* the real value */
+
+		/* outbound: last time of do_QDIO
+		   inbound: last time of noticing incoming data */
+		/*__u64 last_transfer_times[QDIO_STATS_NUMBER];
+		int last_transfer_index; */
+
+		__u64 last_transfer_time;
+	} timing;
+        unsigned int queue_type;
+} __attribute__ ((aligned(256)));
+
+struct qdio_irq {
+	__u32 * volatile dev_st_chg_ind;
+
+	unsigned long int_parm;
+	int irq;
+
+	unsigned int is_iqdio_irq;
+	unsigned int hydra_gives_outbound_pcis;
+	unsigned int sync_done_on_outb_pcis;
+
+	unsigned int state;
+	spinlock_t setting_up_lock;
+
+	unsigned int no_input_qs;
+	unsigned int no_output_qs;
+
+	unsigned char qdioac;
+
+	struct qdio_q *input_qs[QDIO_MAX_QUEUES_PER_IRQ];
+	struct qdio_q *output_qs[QDIO_MAX_QUEUES_PER_IRQ];
+
+	struct ccw1 ccw;
+
+	struct qdr *qdr;
+
+	struct ciw equeue;
+	struct ciw aqueue;
+
+	struct qib qib;
+	
+	/* Functions called via the generic cio layer */
+	void (*cleanup_irq) (struct ccw_device *, unsigned long, struct irb *);
+	void (*cleanup_timeout) (struct ccw_device *);
+	void (*establish_irq) (struct ccw_device *, unsigned long,
+			       struct irb *);
+	void (*establish_timeout) (struct ccw_device *);
+	void (*handler) (struct ccw_device *, unsigned long, struct irb *);
+
+};
+#endif
diff -Nru a/drivers/s390/cio/requestirq.c b/drivers/s390/cio/requestirq.c
--- a/drivers/s390/cio/requestirq.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/s390/cio/requestirq.c	Mon Dec  9 18:46:50 2002
@@ -1,477 +1,51 @@
 /*
  *  drivers/s390/cio/requestirq.c
- *   S/390 common I/O routines -- 
- *   $Revision: 1.12 $
+ *   S/390 common I/O routines -- enabling and disabling of devices
+ *   $Revision: 1.42 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
- *                            IBM Corporation
+ *			      IBM Corporation
  *    Author(s): Ingo Adlung (adlung@de.ibm.com)
- *               Cornelia Huck (cohuck@de.ibm.com) 
+ *		 Cornelia Huck (cohuck@de.ibm.com)
  *		 Arnd Bergmann (arndb@de.ibm.com)
- *    ChangeLog: 11/04/2002 Arnd Bergmann Split s390io.c into multiple files,
- *					  see s390io.c for complete list of
- * 					  changes.
  */
 
 #include <linux/module.h>
 #include <linux/config.h>
-#include <asm/irq.h>
+#include <linux/device.h>
+#include <linux/init.h>
 
-#include <asm/delay.h>
-#include <asm/debug.h>
-#include <asm/cpcmd.h>
-
-#include "cio.h"
-#include "cio_debug.h"
-#include "ioinfo.h"
-#include "s390io.h"
-
-static int enable_subchannel (unsigned int irq);
-static int disable_subchannel (unsigned int irq);
-
-/*
- * Note : internal use of irqflags SA_PROBE for NOT path grouping 
- *
- */
-int
-s390_request_irq_special (int irq,
-			  io_handler_func_t io_handler,
-			  not_oper_handler_func_t not_oper_handler,
-			  unsigned long irqflags,
-			  const char *devname, void *dev_id)
-{
-	int retval = 0;
-	unsigned long flags;
-	char dbf_txt[15];
-	int retry;
-
-	if (irq >= __MAX_SUBCHANNELS)
-		return -EINVAL;
-
-	if (!io_handler || !dev_id)
-		return -EINVAL;
-
-	if (ioinfo[irq] == INVALID_STORAGE_AREA)
-		return -ENODEV;
-	
-	if (ioinfo[irq]->st)
-		return -ENODEV;
-
-	sprintf (dbf_txt, "reqsp%x", irq);
-	CIO_TRACE_EVENT (4, dbf_txt);
-
-	/*
-	 * The following block of code has to be executed atomically
-	 */
-	s390irq_spin_lock_irqsave (irq, flags);
-
-	if (!ioinfo[irq]->ui.flags.ready) {
-		retry = 5;
-
-		ioinfo[irq]->irq_desc.handler = io_handler;
-		ioinfo[irq]->irq_desc.name = devname;
-		ioinfo[irq]->irq_desc.dev_id = dev_id;
-		ioinfo[irq]->ui.flags.ready = 1;
-
-		do {
-			retval = enable_subchannel (irq);
-			if (retval) {
-				ioinfo[irq]->ui.flags.ready = 0;
-				break;
-			}
-
-			stsch (irq, &ioinfo[irq]->schib);
-			if (ioinfo[irq]->schib.pmcw.ena)
-				retry = 0;
-			else
-				retry--;
-
-		} while (retry);
-	} else {
-		/*
-		 *  interrupt already owned, and shared interrupts
-		 *   aren't supported on S/390.
-		 */
-		retval = -EBUSY;
-
-	}
-
-	s390irq_spin_unlock_irqrestore (irq, flags);
-
-	if (retval == 0) {
-		if (!(irqflags & SA_PROBE)) 
-			s390_DevicePathVerification (irq, 0);
-
-		ioinfo[irq]->nopfunc = not_oper_handler;
-	}
-
-	if (cio_debug_initialized)
-		debug_int_event (cio_debug_trace_id, 4, retval);
-
-	return retval;
-}
+#include "css.h"
 
+/* for compatiblity only... */
 int
-s390_request_irq (unsigned int irq,
-		  void (*handler) (int, void *, struct pt_regs *),
-		  unsigned long irqflags, const char *devname, void *dev_id)
+request_irq (unsigned int irq,
+	     void (*handler) (int, void *, struct pt_regs *),
+	     unsigned long irqflags, const char *devname, void *dev_id)
 {
-
-	return s390_request_irq_special (irq,
-					 (io_handler_func_t) handler,
-					 NULL, irqflags, devname, dev_id);
-}
-
-int
-s390_request_console_irq (int irq,
-			  void (*handler) (int, void *, struct pt_regs *),
-			  unsigned long irqflags,
-			  const char *devname,
-			  void *dev_id)
-{
-	int ret;
-	unsigned long flags;
-
-	s390_device_recognition_irq (irq);
-
-	ret = s390_request_irq_special (irq, (io_handler_func_t) handler,
-					NULL, irqflags, devname, dev_id);
-
-	if (ret)
-		goto out;
-
-	s390irq_spin_lock_irqsave(irq, flags);
-	ret = set_cons_dev(irq);
-	s390irq_spin_unlock_irqrestore(irq, flags);
-
-	if (ret)
-		free_irq(irq, dev_id);
-out:
-	return ret;
-}
-
-/*
- * request_irq wrapper
- */
-int
-request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
-	    unsigned long irqflags, const char *devname, void *dev_id)
-{
-	return s390_request_irq(irq, handler, irqflags, devname, dev_id);
+	return -EINVAL;
 }
 
+/* for compatiblity only... */
 void
-s390_free_irq (unsigned int irq, void *dev_id)
+free_irq (unsigned int irq, void *dev_id)
 {
-	unsigned long flags;
-	int ret;
-
-	char dbf_txt[15];
-
-	if (irq >= __MAX_SUBCHANNELS || ioinfo[irq] == INVALID_STORAGE_AREA)
-		return;
-
-	if (ioinfo[irq]->st)
-		return;
-
-	sprintf (dbf_txt, "free%x", irq);
-	CIO_TRACE_EVENT (2, dbf_txt);
-
-	s390irq_spin_lock_irqsave (irq, flags);
-
-	CIO_DEBUG_NOCONS(irq,KERN_DEBUG, DBG, 2, 
-			 "Trying to free IRQ %d\n", 
-			 irq);
-
-	/*
-	 * disable the device and reset all IRQ info if
-	 *  the IRQ is actually owned by the handler ...
-	 */
-	if (ioinfo[irq]->ui.flags.ready) {
-		if (dev_id == ioinfo[irq]->irq_desc.dev_id) {
-			/* start deregister */
-			ioinfo[irq]->ui.flags.unready = 1;
-
-			ret = disable_subchannel (irq);
-
-			if (ret == -EBUSY) {
-
-				/*
-				 * kill it !
-				 * We try to terminate the I/O by halt_IO first,
-				 * then clear_IO.
-				 * Because the device may be gone (machine 
-				 * check handling), we can't use sync I/O.
-				 */
-
-				halt_IO (irq, 0xC8C1D3E3, 0);
-				s390irq_spin_unlock_irqrestore (irq, flags);
-				udelay (200000);	/* 200 ms */
-				s390irq_spin_lock_irqsave (irq, flags);
-
-				ret = disable_subchannel (irq);
-
-				if (ret == -EBUSY) {
-
-					clear_IO (irq, 0x40C3D3D9, 0);
-					s390irq_spin_unlock_irqrestore (irq,
-									flags);
-					udelay (1000000);	/* 1000 ms */
-					s390irq_spin_lock_irqsave (irq, flags);
-
-					/* give it a very last try ... */
-					disable_subchannel (irq);
-
-					if (ioinfo[irq]->ui.flags.busy) {
-						CIO_DEBUG_ALWAYS(KERN_CRIT, 0,
-								 "free_irq(%04X) - "
-								 "device %04X busy, "
-								 "retry count exceeded\n",
-								 irq,
-								 ioinfo[irq]->
-								 devstat.devno);
-						
-					}
-				}
-			}
-
-			ioinfo[irq]->ui.flags.ready = 0;
-			ioinfo[irq]->ui.flags.unready = 0;	/* deregister ended */
-
-			ioinfo[irq]->nopfunc = NULL;
-
-			s390irq_spin_unlock_irqrestore (irq, flags);
-		} else {
-			s390irq_spin_unlock_irqrestore (irq, flags);
-
-			CIO_DEBUG_ALWAYS(KERN_ERR, 0,
-					 "free_irq(%04X) : error, "
-					 "dev_id does not match !\n",
-					 irq);
-
-		}
-	} else {
-		s390irq_spin_unlock_irqrestore (irq, flags);
-
-		CIO_DEBUG_ALWAYS(KERN_ERR, 0,
-				 "free_irq(%04X) : error, "
-				 "no action block ... !\n", 
-				 irq);
-
-	}
 }
 
-/*
- * free_irq wrapper.
- */
-void
-free_irq(unsigned int irq, void *dev_id)
-{
-	s390_free_irq(irq, dev_id);
-}
+struct pgid global_pgid;
+EXPORT_SYMBOL_GPL(global_pgid);
 
 /*
- * Enable IRQ by modifying the subchannel
+ * init_IRQ is now only used to set the pgid as early as possible
  */
-static int
-enable_subchannel (unsigned int irq)
+void __init
+init_IRQ(void)
 {
-	int ret = 0;
-	int ccode;
-	int retry = 5;
-	char dbf_txt[15];
-
-	sprintf (dbf_txt, "ensch%x", irq);
-	CIO_TRACE_EVENT (2, dbf_txt);
-
 	/*
-	 * If a previous disable request is pending we reset it. However, this
-	 *  status implies that the device may (still) be not-operational.
+	 * Let's build our path group ID here.
 	 */
-	if (ioinfo[irq]->ui.flags.d_disable) {
-		ioinfo[irq]->ui.flags.d_disable = 0;
-		ret = 0;
-	} else {
-		ccode = stsch (irq, &(ioinfo[irq]->schib));
-
-		if (ccode) {
-			ret = -ENODEV;
-		} else {
-			ioinfo[irq]->schib.pmcw.ena = 1;
-
-			if (irq == cons_dev) {
-				ioinfo[irq]->schib.pmcw.isc = 7;
-			} else {
-				ioinfo[irq]->schib.pmcw.isc = 3;
-
-			}
-
-			do {
-				ccode = msch (irq, &(ioinfo[irq]->schib));
-
-				switch (ccode) {
-				case 0:	/* ok */
-					ret = 0;
-					retry = 0;
-					break;
-
-				case 1:	/* status pending */
-
-					ioinfo[irq]->ui.flags.s_pend = 1;
-					s390_process_IRQ (irq);
-					ioinfo[irq]->ui.flags.s_pend = 0;
-
-					ret = -EIO;
-					/* 
-					 * might be overwritten on re-driving 
-					 * the msch()       
-					 */
-					retry--;
-					break;
-
-				case 2:	/* busy */
-					udelay (100);	/* allow for recovery */
-					ret = -EBUSY;
-					retry--;
-					break;
-
-				case 3:	/* not oper */
-					ioinfo[irq]->ui.flags.oper = 0;
-					retry = 0;
-					ret = -ENODEV;
-					break;
-				}
-
-			} while (retry);
-
-		}
-	}
-
-	sprintf (dbf_txt, "ret:%d", ret);
-	CIO_TRACE_EVENT (2, dbf_txt);
-
-	return ret;
+	global_pgid.cpu_addr = *(__u16 *) __LC_CPUADDR;
+	global_pgid.cpu_id = ((cpuid_t *) __LC_CPUID)->ident;
+	global_pgid.cpu_model = ((cpuid_t *) __LC_CPUID)->machine;
+	global_pgid.tod_high = (__u32) (get_clock() >> 32);
 }
-
-/*
- * Disable IRQ by modifying the subchannel
- */
-static int
-disable_subchannel (unsigned int irq)
-{
-	int cc;			/* condition code */
-	int ret = 0;		/* function return value */
-	int retry = 5;
-	char dbf_txt[15];
-
-	sprintf (dbf_txt, "dissch%x", irq);
-	CIO_TRACE_EVENT (2, dbf_txt);
-
-	if (ioinfo[irq]->ui.flags.busy) {
-		/*
-		 * the disable function must not be called while there are
-		 *  requests pending for completion !
-		 */
-		ret = -EBUSY;
-	} else {
-
-		/*
-		 * If device isn't operational we have to perform delayed
-		 *  disabling when the next interrupt occurs - unless the
-		 *  irq is re-requested prior to the interrupt to occur.
-		 */
-		cc = stsch (irq, &(ioinfo[irq]->schib));
-
-		if (cc == 3) {
-			ioinfo[irq]->ui.flags.oper = 0;
-			ioinfo[irq]->ui.flags.d_disable = 1;
-
-			ret = 0;
-		} else {	/* cc == 0 */
-
-			ioinfo[irq]->schib.pmcw.ena = 0;
-
-			do {
-				cc = msch (irq, &(ioinfo[irq]->schib));
-
-				switch (cc) {
-				case 0:	/* ok */
-					retry = 0;
-					ret = 0;
-					break;
-
-				case 1:	/* status pending */
-					ioinfo[irq]->ui.flags.s_pend = 1;
-					s390_process_IRQ (irq);
-					ioinfo[irq]->ui.flags.s_pend = 0;
-
-					ret = -EIO;
-					/* 
-					 * might be overwritten on re-driving 
-					 * the msch() call       
-					 */
-					retry--;
-					break;
-
-				case 2:	/* busy; this should not happen! */
-					CIO_DEBUG_ALWAYS(KERN_CRIT, 0,
-							 "disable_subchannel"
-							 "(%04X) - unexpected "
-							 "busy condition for "
-							 "device %04X received!\n",
-							 irq,
-							 ioinfo[irq]->devstat.
-							 devno);
-					retry = 0;
-					ret = -EBUSY;
-					break;
-
-				case 3:	/* not oper */
-					/*
-					 * should hardly occur ?!
-					 */
-					ioinfo[irq]->ui.flags.oper = 0;
-					ioinfo[irq]->ui.flags.d_disable = 1;
-					retry = 0;
-
-					ret = 0;
-					/* 
-					 * if the device has gone, we don't need 
-					 * to disable it anymore !          
-					 */
-					break;
-
-				}
-
-			} while (retry);
-
-		}
-	}
-
-	sprintf (dbf_txt, "ret:%d", ret);
-	CIO_TRACE_EVENT (2, dbf_txt);
-
-	return ret;
-}
-
-/* FIXME: there must be a cleaner way to express what happens */
-extern void do_reipl (int);
-void
-reipl (int sch)
-{
-	int i;
-	s390_dev_info_t dev_info;
-
-	for (i = 0; i <= highest_subchannel; i++) {
-		if (get_dev_info_by_irq (i, &dev_info) == 0
-		    && (dev_info.status & DEVSTAT_DEVICE_OWNED)) {
-			free_irq (i, ioinfo[i]->irq_desc.dev_id);
-		}
-	}
-	if (MACHINE_IS_VM)
-		cpcmd ("IPL", NULL, 0);
-	else
-		do_reipl (0x10000 | sch);
-}
-
-EXPORT_SYMBOL (s390_request_irq_special);
diff -Nru a/drivers/s390/cio/s390io.c b/drivers/s390/cio/s390io.c
--- a/drivers/s390/cio/s390io.c	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,2408 +0,0 @@
-/*
- *  drivers/s390/cio/s390io.c
- *   S/390 common I/O routines
- *   $Revision: 1.33 $
- *
- *  S390 version
- *    Copyright (C) 1999, 2000 IBM Deutschland Entwicklung GmbH,
- *                             IBM Corporation
- *    Author(s): Ingo Adlung (adlung@de.ibm.com)
- *               Cornelia Huck (cohuck@de.ibm.com) 
- *               Arnd Bergmann (arndb@de.ibm.com)
- *    ChangeLog: 01/07/2001 Blacklist cleanup (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
- *               01/04/2001 Holger Smolinski (smolinsk@de.ibm.com)
- *                          Fixed lost interrupts and do_adapter_IO
- *               xx/xx/xxxx nnn          multiple changes not reflected
- *               03/12/2001 Ingo Adlung  blacklist= - changed to cio_ignore=  
- *               03/14/2001 Ingo Adlung  disable interrupts before start_IO
- *                                        in Path Group processing 
- *                                       decrease retry2 on busy while 
- *                                        disabling sync_isc; reset isc_cnt
- *                                        on io error during sync_isc enablement
- *               05/09/2001 Cornelia Huck added exploitation of debug feature
- *               05/16/2001 Cornelia Huck added /proc/deviceinfo/<devno>/
- *               05/22/2001 Cornelia Huck added /proc/cio_ignore
- *                                        un-ignore blacklisted devices by piping 
- *                                        to /proc/cio_ignore
- *               xx/xx/xxxx some bugfixes & cleanups
- *               08/02/2001 Cornelia Huck not already known devices can be blacklisted
- *                                        by piping to /proc/cio_ignore
- *               09/xx/2001 couple more fixes
- *               10/15/2001 Cornelia Huck xsch - internal only for now
- *               10/29/2001 Cornelia Huck Blacklisting reworked again
- *               10/29/2001 Cornelia Huck improved utilization of debug feature
- *               10/29/2001 Cornelia Huck more work on cancel_IO - use the flag
- *                                        DOIO_CANCEL_ON_TIMEOUT in do_IO to get
- *                                        io cancelled
- *               11/15/2001 Cornelia Huck proper behaviour with procfs off
- *               12/10/2001 Cornelia Huck added private_data + functions to 
- *                                        ioinfo_t
- *               11-12/2001 Cornelia Huck various cleanups
- *               01/09/2002 Cornelia Huck PGID fixes
- *                                        process css machine checks 
- *               01/10/2002 Cornelia Huck added /proc/chpids
- * 		 02/11/2002 Arnd Bergmann split this file into many smaller pieces 
- * 		 			  in drivers/s39/cio/
- *               05/03/2002 Cornelia Huck debug cleanup
- */
-#include <linux/module.h>
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/bootmem.h>
-#include <linux/proc_fs.h>
-#include <asm/delay.h>
-#include <asm/idals.h>
-#include <asm/cpcmd.h>
-
-#include <asm/irq.h>
-#include <asm/s390io.h>
-#include <asm/s390dyn.h>
-#include <asm/s390mach.h>
-#include <asm/debug.h>
-
-#include "s390io.h"
-#include "ioinfo.h"
-#include "cio.h"
-#include "cio_debug.h"
-#include "blacklist.h"
-#include "proc.h"
-#include "chsc.h"
-
-static int init_IRQ_complete; 
-
-static pgid_t global_pgid;
-static schib_t p_init_schib;
-static __u64 irq_IPL_TOD; // FIXME: can be on stack
-
-static void s390_process_subchannels (void);
-static int s390_SenseID (int irq, senseid_t * sid, __u8 lpm);
-static int s390_SetPGID (int irq, __u8 lpm);
-static int s390_SensePGID (int irq, __u8 lpm, pgid_t * pgid);
-
-/* FIXME: intermixed with proc.c */
-int cio_count_irqs = 1;			/* toggle use here... */
-unsigned long s390_irq_count[NR_CPUS];	/* trace how many irqs have occured per cpu... */
-
-int cio_show_msg;
-static int cio_notoper_msg = 1;
-
-static int __init
-cio_setup (char *parm)
-{
-	if (!strcmp (parm, "yes")) {
-		cio_show_msg = 1;
-	} else if (!strcmp (parm, "no")) {
-		cio_show_msg = 0;
-	} else {
-		printk (KERN_ERR "cio_setup : invalid cio_msg parameter '%s'",
-			parm);
-
-	}
-
-	return 1;
-}
-
-__setup ("cio_msg=", cio_setup);
-
-
-static int __init
-cio_notoper_setup (char *parm)
-{
-	if (!strcmp (parm, "yes")) {
-		cio_notoper_msg = 1;
-	} else if (!strcmp (parm, "no")) {
-		cio_notoper_msg = 0;
-	} else {
-		printk (KERN_ERR
-			"cio_notoper_setup: "
-			"invalid cio_notoper_msg parameter '%s'", parm);
-	}
-
-	return 1;
-}
-
-__setup ("cio_notoper_msg=", cio_notoper_setup);
-
-/* This function is replacing the init_IRQ function in
- * arch/s390(x)/kernel/irq.c and is called early during
- * bootup. Anything called from here must be careful 
- * about memory allocations */
-void __init
-s390_init_IRQ (void)
-{
-	unsigned long flags;	/* PSW flags */
-	long cr6 __attribute__ ((aligned (8)));
-
-	asm volatile ("STCK %0":"=m" (irq_IPL_TOD));
-
-
-	/*
-	 * As we don't know about the calling environment
-	 *  we assure running disabled. Before leaving the
-	 *  function we resestablish the old environment.
-	 *
-	 * Note : as we don't need a system wide lock, therefore
-	 *        we shouldn't use cli(), but local_irq_save() as this
-	 *        affects the current CPU only.
-	 */
-	local_irq_save(flags);
-
-	/*
-	 * disable all interrupts
-	 */
-	cr6 = 0;
-	__ctl_load (cr6, 6, 6);
-
-	s390_process_subchannels ();
-
-	if (cio_count_irqs) {
-		int i;
-		for (i = 0; i < NR_CPUS; i++)
-			s390_irq_count[i] = 0;
-	}
-
-	
-	/*
-	 * Let's build our path group ID here.
-	 */
-	
-	global_pgid.cpu_addr = *(__u16 *) __LC_CPUADDR;
-	global_pgid.cpu_id = ((cpuid_t *) __LC_CPUID)->ident;
-	global_pgid.cpu_model = ((cpuid_t *) __LC_CPUID)->machine;
-	global_pgid.tod_high = *(__u32 *) & irq_IPL_TOD;
-
-
-	/*
-	 * enable default I/O-interrupt subclass 3
-	 */
-	cr6 = 0x10000000;
-	__ctl_load (cr6, 6, 6);
-
-	init_IRQ_complete = 1;
-
-	local_irq_restore (flags);
-
-	return;
-}
-
-/*
- * init_IRQ wrapper
- */
-void __init
-init_IRQ(void)
-{
-	s390_init_IRQ();
-}
-
-/*
- * dummy handler, used during init_IRQ() processing for compatibility only
- */
-static void
-init_IRQ_handler (int irq, void *dev_id, struct pt_regs *regs)
-{
-	/* this is a dummy handler only ... */
-}
-
-/* 
- * diag210 is used under VM to get information about a virtual device
- */
-#ifdef CONFIG_ARCH_S390X
-int diag210(diag210_t * addr)
-{
-	/*
-	 * diag 210 needs its data below the 2GB border, so we
-	 * use a static data area to be sure
-	 */
-	static diag210_t diag210_tmp;
-	static spinlock_t diag210_lock = SPIN_LOCK_UNLOCKED;
-	unsigned long flags;
-	int ccode;
-
-	spin_lock_irqsave(&diag210_lock, flags);
-	diag210_tmp = *addr;
-
-	asm volatile (
-		"   sam31\n"
-		"   diag  %1,0,0x210\n"
-		"   sam64\n"
-		"   ipm   %0\n"
-		"   srl   %0,28"
-		: "=d" (ccode) : "a" (__pa(&diag210_tmp)) : "cc", "memory" );
-	
-	*addr = diag210_tmp;
-	spin_unlock_irqrestore(&diag210_lock, flags);
-
-	return ccode;
-}
-#else
-int diag210(diag210_t * addr)
-{
-	int ccode;
-
-	asm volatile (
-		"   diag  %1,0,0x210\n"
-		"   ipm   %0\n"
-		"   srl   %0,28"
-		: "=d" (ccode) : "a" (__pa(addr)) : "cc", "memory" );
-
-	return ccode;
-}
-#endif
-
-/*
- * Input :
- *   devno - device number
- *   ps    - pointer to sense ID data area
- * Output : none
- */
-static inline void
-VM_virtual_device_info (__u16 devno, senseid_t * ps)
-{
-	diag210_t diag_data;
-	int ccode;
-
-	int error = 0;
-
-	CIO_TRACE_EVENT (4, "VMvdinf");
-
-	diag_data = (diag210_t) {
-		.vrdcdvno = devno,
-		.vrdclen = sizeof (diag_data),
-	};
-
-	ccode = diag210 (&diag_data);
-	ps->reserved = 0xff;
-
-	/* FIXME: this would be much nicer if it were table driven */
-	switch (diag_data.vrdcvcla) {
-	case 0x80:
-
-		switch (diag_data.vrdcvtyp) {
-		case 00:
-
-			ps->cu_type = 0x3215;
-
-			break;
-
-		default:
-
-			error = 1;
-
-			break;
-
-		}
-
-		break;
-
-	case 0x40:
-
-		switch (diag_data.vrdcvtyp) {
-		case 0xC0:
-
-			ps->cu_type = 0x5080;
-
-			break;
-
-		case 0x80:
-
-			ps->cu_type = 0x2250;
-
-			break;
-
-		case 0x04:
-
-			ps->cu_type = 0x3277;
-
-			break;
-
-		case 0x01:
-
-			ps->cu_type = 0x3278;
-
-			break;
-
-		default:
-
-			error = 1;
-
-			break;
-
-		}
-
-		break;
-
-	case 0x20:
-
-		switch (diag_data.vrdcvtyp) {
-		case 0x84:
-
-			ps->cu_type = 0x3505;
-
-			break;
-
-		case 0x82:
-
-			ps->cu_type = 0x2540;
-
-			break;
-
-		case 0x81:
-
-			ps->cu_type = 0x2501;
-
-			break;
-
-		default:
-
-			error = 1;
-
-			break;
-
-		}
-
-		break;
-
-	case 0x10:
-
-		switch (diag_data.vrdcvtyp) {
-		case 0x84:
-
-			ps->cu_type = 0x3525;
-
-			break;
-
-		case 0x82:
-
-			ps->cu_type = 0x2540;
-
-			break;
-
-		case 0x4F:
-		case 0x4E:
-		case 0x48:
-
-			ps->cu_type = 0x3820;
-
-			break;
-
-		case 0x4D:
-		case 0x49:
-		case 0x45:
-
-			ps->cu_type = 0x3800;
-
-			break;
-
-		case 0x4B:
-
-			ps->cu_type = 0x4248;
-
-			break;
-
-		case 0x4A:
-
-			ps->cu_type = 0x4245;
-
-			break;
-
-		case 0x47:
-
-			ps->cu_type = 0x3262;
-
-			break;
-
-		case 0x43:
-
-			ps->cu_type = 0x3203;
-
-			break;
-
-		case 0x42:
-
-			ps->cu_type = 0x3211;
-
-			break;
-
-		case 0x41:
-
-			ps->cu_type = 0x1403;
-
-			break;
-
-		default:
-
-			error = 1;
-
-			break;
-
-		}
-
-		break;
-
-	case 0x08:
-
-		switch (diag_data.vrdcvtyp) {
-		case 0x82:
-
-			ps->cu_type = 0x3422;
-
-			break;
-
-		case 0x81:
-
-			ps->cu_type = 0x3490;
-
-			break;
-
-		case 0x10:
-
-			ps->cu_type = 0x3420;
-
-			break;
-
-		case 0x02:
-
-			ps->cu_type = 0x3430;
-
-			break;
-
-		case 0x01:
-
-			ps->cu_type = 0x3480;
-
-			break;
-
-		case 0x42:
-
-			ps->cu_type = 0x3424;
-
-			break;
-
-		case 0x44:
-
-			ps->cu_type = 0x9348;
-
-			break;
-
-		default:
-
-			error = 1;
-
-			break;
-
-		}
-
-		break;
-
-	case 02:		/* special device class ... */
-
-		switch (diag_data.vrdcvtyp) {
-		case 0x20:	/* OSA */
-
-			ps->cu_type = 0x3088;
-			ps->cu_model = 0x60;
-
-			break;
-
-		default:
-
-			error = 1;
-			break;
-
-		}
-
-		break;
-
-	default:
-
-		error = 1;
-
-		break;
-
-	}
-
-	if (error) 
-		CIO_DEBUG_ALWAYS(KERN_ERR, 0,
-				 "DIAG X'210' for "
-				 "device %04X returned "
-				 "(cc = %d): vdev class : %02X, "
-				 "vdev type : %04X \n ...  "
-				 "rdev class : %02X, rdev type : %04X, "
-				 "rdev model: %02X\n",
-				 devno,
-				 ccode,
-				 diag_data.vrdcvcla,
-				 diag_data.vrdcvtyp,
-				 diag_data.vrdcrccl,
-				 diag_data.vrdccrty,
-				 diag_data.vrdccrmd);
-}
-
-/*
- * This routine returns the characteristics for the device
- *  specified. Some old devices might not provide the necessary
- *  command code information during SenseID processing. In this
- *  case the function returns -EINVAL. Otherwise the function
- *  allocates a decice specific data buffer and provides the
- *  device characteristics together with the buffer size. Its
- *  the callers responability to release the kernel memory if
- *  not longer needed. In case of persistent I/O problems -EBUSY
- *  is returned.
- *
- *  The function may be called enabled or disabled. However, the
- *   caller must have locked the irq it is requesting data for.
- *
- * Note : It would have been nice to collect this information
- *         during init_IRQ() processing but this is not possible
- *
- *         a) without statically pre-allocation fixed size buffers
- *            as virtual memory management isn't available yet.
- *
- *         b) without unnecessarily increase system startup by
- *            evaluating devices eventually not used at all.
- */
-int
-read_dev_chars (int irq, void **buffer, int length)
-{
-	unsigned long flags;
-	ccw1_t *rdc_ccw;
-	devstat_t devstat;
-	char *rdc_buf;
-	int devflag = 0;
-
-	int ret = 0;
-	int emulated = 0;
-	int retry = 5;
-
-	char dbf_txt[15];
-
-	if (!buffer || !length) 
-		return -EINVAL;
-
-	SANITY_CHECK (irq);
-
-	if (ioinfo[irq]->ui.flags.oper == 0) 
-		return -ENODEV;
-
-	sprintf (dbf_txt, "rddevch%x", irq);
-	CIO_TRACE_EVENT (4, dbf_txt);
-
-	/*
-	 * Before playing around with irq locks we should assure
-	 *   running disabled on (just) our CPU. Sync. I/O requests
-	 *   also require to run disabled.
-	 *
-	 * Note : as no global lock is required, we must not use
-	 *        cli(), but local_irq_save() instead.   
-	 */
-	local_irq_save(flags);
-
-	rdc_ccw = &ioinfo[irq]->senseccw;
-
-	if (!ioinfo[irq]->ui.flags.ready) {
-		ret = request_irq (irq,
-				   init_IRQ_handler, SA_PROBE, "RDC", &devstat);
-
-		if (!ret) {
-			emulated = 1;
-
-		}
-
-	}
-
-	if (!ret) {
-		if (!*buffer) {
-			rdc_buf = kmalloc (length, GFP_KERNEL);
-		} else {
-			rdc_buf = *buffer;
-
-		}
-
-		if (!rdc_buf) {
-			ret = -ENOMEM;
-		} else {
-			do {
-				rdc_ccw->cmd_code = CCW_CMD_RDC;
-				rdc_ccw->count = length;
-				rdc_ccw->flags = CCW_FLAG_SLI;
-				ret = set_normalized_cda (rdc_ccw, rdc_buf);
-				if (!ret) {
-
-					memset (ioinfo[irq]->irq_desc.dev_id,
-						'\0', sizeof (devstat_t));
-
-					ret = s390_start_IO (irq, rdc_ccw, 0x00524443,	/* RDC */
-							     0,	/* n/a */
-							     DOIO_WAIT_FOR_INTERRUPT
-							     |
-							     DOIO_DONT_CALL_INTHDLR);
-					retry--;
-					devflag =
-					    ioinfo[irq]->irq_desc.dev_id->flag;
-
-					clear_normalized_cda (rdc_ccw);
-				} else {
-					udelay (100);	/* wait for recovery */
-					retry--;
-				}
-
-			} while ((retry)
-				 && (ret
-				     || (devflag & DEVSTAT_STATUS_PENDING)));
-
-		}
-
-		if (!retry) {
-			ret = (ret == -ENOMEM) ? -ENOMEM : -EBUSY;
-
-		}
-
-		local_irq_restore (flags);
-
-		/*
-		 * on success we update the user input parms
-		 */
-		if (!ret) {
-			*buffer = rdc_buf;
-
-		}
-
-		if (emulated) {
-			free_irq (irq, &devstat);
-
-		}
-
-	} else {
-		local_irq_restore(flags);
-	}
-
-	return ret;
-}
-
-/*
- *  Read Configuration data
- */
-int
-read_conf_data (int irq, void **buffer, int *length, __u8 lpm)
-{
-	unsigned long flags;
-	int ciw_cnt;
-
-	int found = 0;		/* RCD CIW found */
-	int ret = 0;		/* return code */
-
-	char dbf_txt[15];
-
-	SANITY_CHECK (irq);
-
-	if (!buffer || !length) {
-		return -EINVAL;
-	} else if (ioinfo[irq]->ui.flags.oper == 0) {
-		return -ENODEV;
-	} else if (ioinfo[irq]->ui.flags.esid == 0) {
-		return -EOPNOTSUPP;
-
-	}
-
-	sprintf (dbf_txt, "rdconf%x", irq);
-	CIO_TRACE_EVENT (4, dbf_txt);
-
-	/*
-	 * scan for RCD command in extended SenseID data
-	 */
-
-	for (ciw_cnt = 0; (found == 0) && (ciw_cnt < MAX_CIWS); ciw_cnt++) {
-		if (ioinfo[irq]->senseid.ciw[ciw_cnt].ct == CIW_TYPE_RCD) {
-			/*
-			 * paranoia check ...
-			 */
-			if (ioinfo[irq]->senseid.ciw[ciw_cnt].cmd != 0) {
-				found = 1;
-
-			}
-
-			break;
-
-		}
-	}
-
-	if (found) {
-		devstat_t devstat;	/* inline device status area */
-		devstat_t *pdevstat;
-		int ioflags;
-
-		ccw1_t *rcd_ccw = &ioinfo[irq]->senseccw;
-		char *rcd_buf = NULL;
-		int emulated = 0;	/* no i/O handler installed */
-		int retry = 5;	/* retry count */
-
-		local_irq_save(flags);
-
-		if (!ioinfo[irq]->ui.flags.ready) {
-			pdevstat = &devstat;
-			ret = request_irq (irq,
-					   init_IRQ_handler,
-					   SA_PROBE, "RCD", pdevstat);
-
-			if (!ret) {
-				emulated = 1;
-
-			}	/* endif */
-		} else {
-			pdevstat = ioinfo[irq]->irq_desc.dev_id;
-
-		}		/* endif */
-
-		if (!ret) {
-			if (init_IRQ_complete) {
-				rcd_buf =
-				    kmalloc (ioinfo[irq]->senseid.ciw[ciw_cnt].
-					     count, GFP_DMA);
-			} else {
-				rcd_buf =
-				    alloc_bootmem_low (ioinfo[irq]->senseid.
-						       ciw[ciw_cnt].count);
-
-			}
-
-			if (rcd_buf == NULL) {
-				ret = -ENOMEM;
-
-			}
-			if (!ret) {
-				memset (rcd_buf,
-					'\0',
-					ioinfo[irq]->senseid.ciw[ciw_cnt].
-					count);
-
-				do {
-					rcd_ccw->cmd_code =
-					    ioinfo[irq]->senseid.ciw[ciw_cnt].
-					    cmd;
-					rcd_ccw->cda =
-					    (__u32) virt_to_phys (rcd_buf);
-					rcd_ccw->count =
-					    ioinfo[irq]->senseid.ciw[ciw_cnt].
-					    count;
-					rcd_ccw->flags = CCW_FLAG_SLI;
-
-					memset (pdevstat, '\0',
-						sizeof (devstat_t));
-
-					if (lpm) {
-						ioflags =
-						    DOIO_WAIT_FOR_INTERRUPT |
-						    DOIO_VALID_LPM |
-						    DOIO_DONT_CALL_INTHDLR;
-					} else {
-						ioflags =
-						    DOIO_WAIT_FOR_INTERRUPT |
-						    DOIO_DONT_CALL_INTHDLR;
-
-					}
-
-					ret = s390_start_IO (irq, rcd_ccw, 0x00524344,	/* == RCD */
-							     lpm, ioflags);
-					switch (ret) {
-					case 0:
-					case -EIO:
-
-						if (!
-						    (pdevstat->
-						     flag &
-						     (DEVSTAT_STATUS_PENDING |
-						      DEVSTAT_NOT_OPER |
-						      DEVSTAT_FLAG_SENSE_AVAIL)))
-						{
-							retry = 0;	/* we got it ... */
-						} else {
-							retry--;	/* try again ... */
-
-						}
-
-						break;
-
-					default:	/* -EBUSY, -ENODEV, ??? */
-						retry = 0;
-
-					}
-
-				} while (retry);
-
-			}
-		}
-
-		local_irq_restore(flags);
-
-		/*
-		 * on success we update the user input parms
-		 */
-		if (ret == 0) {
-			*length = ioinfo[irq]->senseid.ciw[ciw_cnt].count;
-			*buffer = rcd_buf;
-		} else {
-			if (rcd_buf != NULL) {
-				if (init_IRQ_complete) {
-					kfree (rcd_buf);
-				} else {
-					free_bootmem ((unsigned long) rcd_buf,
-						      ioinfo[irq]->senseid.
-						      ciw[ciw_cnt].count);
-
-				}
-
-			}
-
-			*buffer = NULL;
-			*length = 0;
-
-		}
-
-		if (emulated)
-			free_irq (irq, pdevstat);
-	} else {
-		ret = -EOPNOTSUPP;
-
-	}
-
-	return ret;
-
-}
-
-/*
- * s390_device_recognition_irq
- *
- * Used for individual device recognition. Issues the device
- *  independant SenseID command to obtain info the device type.
- *
- */
-void
-s390_device_recognition_irq (int irq)
-{
-	char dbf_txt[15];
-	devstat_t devstat;
-
-	sprintf (dbf_txt, "devrec%x", irq);
-	CIO_TRACE_EVENT (4, dbf_txt);
-
-	/*
-	 * We issue the SenseID command on I/O subchannels we think are
-	 *  operational only.
-	 */
-	if ((ioinfo[irq]->st) || (!ioinfo[irq]->ui.flags.oper))
-		goto out;
-
-	if (request_irq (irq, init_IRQ_handler, SA_PROBE, "INIT", &devstat))
-		goto out;
-
-	if (enable_cpu_sync_isc(irq))
-		goto out_freeirq;
-
-	ioinfo[irq]->ui.flags.unknown = 0;
-
-	memset (&ioinfo[irq]->senseid, '\0', sizeof (senseid_t));
-
-	s390_SenseID (irq, &ioinfo[irq]->senseid, 0xff);
-
-	disable_cpu_sync_isc(irq);
-out_freeirq:
-	free_irq (irq, &devstat);
-out:
-	return;
-}
-
-static int
-css_bus_match (struct device *dev, struct device_driver *drv)
-{
-	struct subchannel *ioinfo;
-	struct subchannel_driver *sdrv;
-
-	ioinfo = list_entry (dev, struct subchannel, dev);
-	sdrv   = list_entry (drv, struct subchannel_driver, drv);
-
-	return (ioinfo->st == sdrv->st);
-}
-
-struct bus_type css_bus_type = {
-	.name  = "css",
-	.match = &css_bus_match,
-};
-
-static struct device css_bus_device = {
-	.name   = "Channel Subsystem",
-	.bus_id = "css0",
-};
-
-/*
- * s390_register_subchannel
- *
- * initializes the struct device member of a subchannel and gives it to
- * the device driver core
- */
-static __devinit void
-s390_register_subchannel (struct subchannel *ioinfo)
-{
-	static const char *subchannel_types[] = {
-		"I/O Subchannel",
-		"CHSC Subchannel",
-		"Message Subchannel",
-		"ADM Subchannel",
-		"undefined subchannel type 4",
-		"undefined subchannel type 5",
-		"undefined subchannel type 6",
-		"undefined subchannel type 7",
-	};
-
-	strncpy (ioinfo->dev.name, subchannel_types[ioinfo->st], DEVICE_NAME_SIZE);
-	snprintf (ioinfo->dev.bus_id, DEVICE_ID_SIZE, "0:%04x", ioinfo->irq);
-
-	ioinfo->dev.bus    = &css_bus_type;
-	ioinfo->dev.parent = &css_bus_device;
-
-	if (device_register(&ioinfo->dev))
-		printk(KERN_WARNING "failed to register subchannel %04x\n", ioinfo->irq);
-}
-
-/*
- * s390_device_recognition_all
- *
- * Used for system wide device recognition.
- *
- */
-static int __init
-s390_probe_css (void)
-{
-	int ret;
-	int irq;
-
-	printk (KERN_INFO "probing %d subchannels...\n", highest_subchannel+1);
-
-	if ((ret = bus_register(&css_bus_type)))
-		goto out;
-
-	if ((ret = device_register(&css_bus_device)))
-		goto out_unregister;
-
-	for (irq = 0; irq <= highest_subchannel; irq++) {
-		if (ioinfo[irq] == INVALID_STORAGE_AREA)
-			continue;
-
-		printk(KERN_INFO "subchannel %04x: devno %04x, ",
-				irq, ioinfo[irq]->devno);
-
-		if (irq != cons_dev) /* console has already been probed */
-			s390_device_recognition_irq (irq);
-
-		s390_register_subchannel(ioinfo[irq]);
-		printk("control unit type %04x\n", ioinfo[irq]->senseid.cu_type);
-	}
-
-out_unregister:
-	if (ret)
-		put_bus(&css_bus_type);
-out:
-	return ret;
-}
-
-subsys_initcall(s390_probe_css);
-
-/*
- * s390_process_subchannels
- *
- * Determines all subchannels available to the system.
- * Only called early during startup by s390_init_IRQ
- */
-static void __init
-s390_process_subchannels (void)
-{
-	int ret;
-	int irq = 0;		/* Evaluate all subchannels starting with 0 ... */
-
-	do {
-		ret = s390_validate_subchannel (irq, 0);
-
-		if (ret != -ENXIO)
-			irq++;
-
-	} while ((ret != -ENXIO) && (irq < __MAX_SUBCHANNELS));
-
-	highest_subchannel = (--irq);
-
-	CIO_DEBUG_ALWAYS(KERN_INFO, 0,
-			 "Highest subchannel number detected "
-			 "(hex) : %04X\n", highest_subchannel);
-}
-
-/*
- * s390_validate_subchannel()
- *
- * Process the subchannel for the requested irq. 
- * Return codes:
- * * 0 for valid subchannels
- * * -ENXIO for non-defined subchannels 
- *   (indicates highest available subchannel + 1)
- * * -ENODEV for non-IO subchannels and not operational conditions
- * * -EIO and -EBUSY for error conditions during msch
- */
-int
-s390_validate_subchannel (int irq, int enable)
-{
-
-	int retry;		/* retry count for status pending conditions */
-	int ccode;		/* condition code for stsch() only */
-	int ccode2;		/* condition code for other I/O routines */
-	schib_t *p_schib;
-	int ret;
-	char dbf_txt[15];
-
-	sprintf (dbf_txt, "valsch%x", irq);
-	CIO_TRACE_EVENT (4, dbf_txt);
-
-	/*
-	 * The first subchannel that is not-operational (ccode==3)
-	 *  indicates that there aren't any more devices available.
-	 */
-	if ((init_IRQ_complete)
-	    && (ioinfo[irq] != INVALID_STORAGE_AREA)) {
-		p_schib = &ioinfo[irq]->schib;
-	} else {
-		p_schib = &p_init_schib;
-
-	}
-
-	/*
-	 * If we knew the device before we assume the worst case ...    
-	 */
-	if (ioinfo[irq] != INVALID_STORAGE_AREA) {
-		ioinfo[irq]->ui.flags.oper = 0;
-		ioinfo[irq]->ui.flags.dval = 0;
-
-	}
-
-	ccode = stsch (irq, p_schib);
-
-	if (ccode) {
-		return -ENXIO;
-	}
-	/*
-	 * ... just being curious we check for non I/O subchannels
-	 */
-	if (p_schib->pmcw.st) {
-
-		CIO_DEBUG_IFMSG(KERN_INFO, 0,
-				"Subchannel %04X reports "
-				"non-I/O subchannel type %04X\n",
-				irq, p_schib->pmcw.st);
-
-		if (ioinfo[irq] != INVALID_STORAGE_AREA)
-			ioinfo[irq]->ui.flags.oper = 0;
-
-	}
-
-	if ((!p_schib->pmcw.dnv) && (!p_schib->pmcw.st)) {
-		return -ENODEV;
-	}
-	if (!p_schib->pmcw.st) {
-		if (ioinfo[irq] == INVALID_STORAGE_AREA
-		    && is_blacklisted (p_schib->pmcw.dev)) {
-			/* 
-			 * This device must not be known to Linux. So we simply say that 
-			 * there is no device and return ENODEV.
-			 */
-			CIO_DEBUG(KERN_DEBUG, 0,
-				  "Blacklisted device detected at devno %04X\n",
-				      p_schib->pmcw.dev);
-			return -ENODEV;
-		}
-	}
-	
-	if (ioinfo[irq] == INVALID_STORAGE_AREA) {
-		if (!init_IRQ_complete) {
-			ioinfo[irq] = (ioinfo_t *)
-			    alloc_bootmem_low (sizeof (ioinfo_t));
-		} else {
-			ioinfo[irq] = (ioinfo_t *)
-			    kmalloc (sizeof (ioinfo_t), GFP_DMA);
-
-		}
-
-		memset (ioinfo[irq], '\0', sizeof (ioinfo_t));
-		memcpy (&ioinfo[irq]->schib, &p_init_schib, sizeof (schib_t));
-
-		/*
-		 * We have to insert the new ioinfo element
-		 *  into the linked list, either at its head,
-		 *  its tail or insert it.
-		 */
-		if (ioinfo_head == NULL) {	/* first element */
-			ioinfo_head = ioinfo[irq];
-			ioinfo_tail = ioinfo[irq];
-		} else if (irq < ioinfo_head->irq) {	/* new head */
-			ioinfo[irq]->next = ioinfo_head;
-			ioinfo_head->prev = ioinfo[irq];
-			ioinfo_head = ioinfo[irq];
-		} else if (irq > ioinfo_tail->irq) {	/* new tail */
-			ioinfo_tail->next = ioinfo[irq];
-			ioinfo[irq]->prev = ioinfo_tail;
-			ioinfo_tail = ioinfo[irq];
-		} else {	/* insert element */
-
-			ioinfo_t *pi = ioinfo_head;
-
-			for (pi = ioinfo_head; pi != NULL; pi = pi->next) {
-
-				if (irq < pi->next->irq) {
-					ioinfo[irq]->next = pi->next;
-					ioinfo[irq]->prev = pi;
-					pi->next->prev = ioinfo[irq];
-					pi->next = ioinfo[irq];
-					break;
-
-				}
-			}
-		}
-	}
-
-	/* initialize some values ... */
-	ioinfo[irq]->irq = irq;
-	ioinfo[irq]->st = ioinfo[irq]->schib.pmcw.st;
-	if (ioinfo[irq]->st)
-		return -ENODEV;
-
-	ioinfo[irq]->ui.flags.pgid_supp = 1;
-
-	ioinfo[irq]->opm = ioinfo[irq]->schib.pmcw.pim
-	    & ioinfo[irq]->schib.pmcw.pam & ioinfo[irq]->schib.pmcw.pom;
-
-	chsc_validate_chpids(irq);
-
-	CIO_DEBUG_IFMSG(KERN_INFO, 0,
-			"Detected device %04X "
-			"on subchannel %04X"
-			" - PIM = %02X, "
-			"PAM = %02X, POM = %02X\n",
-			ioinfo[irq]->schib.pmcw.dev, 
-			irq,
-			ioinfo[irq]->schib.pmcw.pim,
-			ioinfo[irq]->schib.pmcw.pam, 
-			ioinfo[irq]->schib.pmcw.pom);
-
-	/*
-	 * initialize ioinfo structure
-	 */
-	if (!ioinfo[irq]->ui.flags.ready) {
-		ioinfo[irq]->nopfunc = NULL;
-		ioinfo[irq]->ui.flags.busy = 0;
-		ioinfo[irq]->ui.flags.dval = 1;
-		ioinfo[irq]->devstat.intparm = 0;
-
-	}
-	ioinfo[irq]->devstat.devno = ioinfo[irq]->schib.pmcw.dev;
-	ioinfo[irq]->devno = ioinfo[irq]->schib.pmcw.dev;
-
-	/*
-	 * We should have at least one CHPID ...
-	 */
-	if (ioinfo[irq]->opm) {
-		/*
-		 * We now have to initially ...
-		 *  ... set "interruption subclass"
-		 *  ... enable "concurrent sense"
-		 *  ... enable "multipath mode" if more than one
-		 *        CHPID is available. This is done regardless
-		 *        whether multiple paths are available for us.
-		 *
-		 * Note : we don't enable the device here, this is temporarily
-		 *        done during device sensing below.
-		 */
-		ioinfo[irq]->schib.pmcw.isc = 3;	/* could be smth. else */
-		ioinfo[irq]->schib.pmcw.csense = 1;	/* concurrent sense */
-		ioinfo[irq]->schib.pmcw.ena = enable;
-		ioinfo[irq]->schib.pmcw.intparm = ioinfo[irq]->schib.pmcw.dev;
-
-		if ((ioinfo[irq]->opm != 0x80)
-		    && (ioinfo[irq]->opm != 0x40)
-		    && (ioinfo[irq]->opm != 0x20)
-		    && (ioinfo[irq]->opm != 0x10)
-		    && (ioinfo[irq]->opm != 0x08)
-		    && (ioinfo[irq]->opm != 0x04)
-		    && (ioinfo[irq]->opm != 0x02)
-		    && (ioinfo[irq]->opm != 0x01)) {
-			ioinfo[irq]->schib.pmcw.mp = 1;	/* multipath mode */
-
-		}
-
-		retry = 5;
-
-		do {
-			ccode2 = msch_err (irq, &ioinfo[irq]->schib);
-
-			switch (ccode2) {
-			case 0:
-				/*
-				 * successful completion
-				 *
-				 * concurrent sense facility available
-				 */
-				ioinfo[irq]->ui.flags.oper = 1;
-				ioinfo[irq]->ui.flags.consns = 1;
-				ret = 0;
-				break;
-
-			case 1:
-				/*
-				 * status pending
-				 *
-				 * How can we have a pending status 
-				 * as the device is disabled for 
-				 * interrupts ?
-				 * Anyway, process it ...
-				 */
-				ioinfo[irq]->ui.flags.s_pend = 1;
-				s390_process_IRQ (irq);
-				ioinfo[irq]->ui.flags.s_pend = 0;
-				retry--;
-				ret = -EIO;
-				break;
-
-			case 2:
-				/*
-				 * busy
-				 *
-				 * we mark it not-oper as we can't 
-				 * properly operate it !
-				 */
-				ioinfo[irq]->ui.flags.oper = 0;
-				udelay (100);	/* allow for recovery */
-				retry--;
-				ret = -EBUSY;
-				break;
-
-			case 3:	/* not operational */
-				ioinfo[irq]->ui.flags.oper = 0;
-				retry = 0;
-				ret = -ENODEV;
-				break;
-
-			default:
-#define PGMCHK_OPERAND_EXC      0x15
-
-				if ((ccode2 & PGMCHK_OPERAND_EXC)
-				    == PGMCHK_OPERAND_EXC) {
-					/*
-					 * re-issue the modify subchannel without trying to
-					 *  enable the concurrent sense facility
-					 */
-					ioinfo[irq]->schib.pmcw.csense = 0;
-
-					ccode2 =
-					    msch_err (irq, &ioinfo[irq]->schib);
-
-					if (ccode2 != 0) {
-						CIO_DEBUG_ALWAYS(KERN_ERR, 0,
-								 "msch() (2) failed"
-								 " with CC=%X\n",
-								 ccode2);
-						ioinfo[irq]->ui.flags.oper = 0;
-						ret = -EIO;
-					} else {
-						ioinfo[irq]->ui.flags.oper = 1;
-						ioinfo[irq]->ui.
-						    flags.consns = 0;
-						ret = 0;
-
-					}
-
-				} else {
-					CIO_DEBUG_ALWAYS(KERN_ERR, 0,
-							 "msch() (1) failed with "
-							 "CC = %X\n", ccode2);
-					ioinfo[irq]->ui.flags.oper = 0;
-					ret = -EIO;
-
-				}
-
-				retry = 0;
-				break;
-
-			}
-
-		} while (ccode2 && retry);
-
-		if ((ccode2 != 0) && (ccode2 != 3)
-		    && (!retry)) {
-			CIO_DEBUG_ALWAYS(KERN_ERR, 0,
-					 " ... msch() retry count for "
-					 "subchannel %04X exceeded, CC = %d\n",
-					 irq, ccode2);
-
-		}
-	} else {
-		/* no path available ... */
-		ioinfo[irq]->ui.flags.oper = 0;
-		ret = -ENODEV;
-
-	}
-
-	return ret;
-}
-
-/*
- * s390_SenseID
- *
- * Try to obtain the 'control unit'/'device type' information
- *  associated with the subchannel.
- *
- * The function is primarily meant to be called without irq
- *  action handler in place. However, it also allows for
- *  use with an action handler in place. If there is already
- *  an action handler registered assure it can handle the
- *  s390_SenseID() related device interrupts - interruption
- *  parameter used is 0x00E2C9C4 ( SID ).
- */
-static int
-s390_SenseID (int irq, senseid_t * sid, __u8 lpm)
-{
-	/* SenseID may be called during console initialization,
-	 * before we have a working kmalloc, using a static
-	 * ccw area is the least evil workaround */
-	static ccw1_t sense_ccw[2];	/* ccw area for SenseID command */
-	static spinlock_t sid_lock	/* lock to protect sense_ccw */
-		= SPIN_LOCK_UNLOCKED;
-
-	senseid_t isid;		/* internal sid */
-	devstat_t devstat;	/* required by request_irq() */
-	__u8 pathmask;		/* calulate path mask */
-	__u8 domask;		/* path mask to use */
-	int inlreq;		/* inline request_irq() */
-	int irq_ret;		/* return code */
-	devstat_t *pdevstat;	/* ptr to devstat in use */
-	int retry;		/* retry count */
-	int io_retry;		/* retry indicator */
-
-	senseid_t *psid = sid;	/* start with the external buffer */
-	int sbuffer = 0;	/* switch SID data buffer */
-
-	char dbf_txt[15];
-	int i;
-	int failure = 0;	/* nothing went wrong yet */
-	unsigned long flags;
-
-	if (ioinfo[irq]->ui.flags.oper == 0) {
-		return -ENODEV;
-
-	}
-
-	sprintf (dbf_txt, "snsID%x", irq);
-	CIO_TRACE_EVENT (4, dbf_txt);
-
-	if (!ioinfo[irq]->ui.flags.ready) {
-		inlreq = 1;
-		/*
-		 * Perform SENSE ID command processing. We have to request device
-		 *  ownership and provide a dummy I/O handler. We issue sync. I/O
-		 *  requests and evaluate the devstat area on return therefore
-		 *  we don't need a real I/O handler in place.
-		 */
-		if ((irq_ret = request_irq (irq, init_IRQ_handler,
-						SA_PROBE, "SID", &devstat)))
-				return irq_ret;
-
-	} else {
-		inlreq = 0;
-	}
-
-	pdevstat = ioinfo[irq]->irq_desc.dev_id;
-
-	spin_lock_irqsave(&sid_lock, flags);
-	s390irq_spin_lock (irq);
-
-	/* more than one path installed ? */
-	if (ioinfo[irq]->schib.pmcw.pim != 0x80) {
-		sense_ccw[0].cmd_code = CCW_CMD_SUSPEND_RECONN;
-		sense_ccw[0].cda = 0;
-		sense_ccw[0].count = 0;
-		sense_ccw[0].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
-
-		sense_ccw[1].cmd_code = CCW_CMD_SENSE_ID;
-		sense_ccw[1].cda = (__u32) virt_to_phys (sid);
-		sense_ccw[1].count = sizeof (senseid_t);
-		sense_ccw[1].flags = CCW_FLAG_SLI;
-	} else {
-		sense_ccw[0].cmd_code = CCW_CMD_SENSE_ID;
-		sense_ccw[0].cda = (__u32) virt_to_phys (sid);
-		sense_ccw[0].count = sizeof (senseid_t);
-		sense_ccw[0].flags = CCW_FLAG_SLI;
-
-	}
-
-	for (i = 0; (i < 8); i++) {
-		pathmask = 0x80 >> i;
-
-		domask = ioinfo[irq]->opm & pathmask;
-
-		if (lpm)
-			domask &= lpm;
-
-		if (!domask)
-			continue;
-
-		failure = 0;
-
-		psid->reserved = 0;
-		psid->cu_type = 0xFFFF;	/* initialize fields ... */
-		psid->cu_model = 0;
-		psid->dev_type = 0;
-		psid->dev_model = 0;
-
-		retry = 5;	/* retry count    */
-		io_retry = 1;	/* enable retries */
-
-		/*
-		 * We now issue a SenseID request. In case of BUSY,
-		 *  STATUS PENDING or non-CMD_REJECT error conditions
-		 *  we run simple retries.
-		 */
-		do {
-			memset (pdevstat, '\0', sizeof (devstat_t));
-
-			irq_ret = s390_start_IO (irq, sense_ccw, 0x00E2C9C4,	/* == SID */
-						 domask,
-						 DOIO_WAIT_FOR_INTERRUPT
-						 | DOIO_TIMEOUT
-						 | DOIO_VALID_LPM
-						 | DOIO_DONT_CALL_INTHDLR);
-
-			if ((psid->cu_type != 0xFFFF)
-			    && (psid->reserved == 0xFF)) {
-				if (!sbuffer) {	/* switch buffers */
-					/*
-					 * we report back the
-					 *  first hit only
-					 */
-					psid = &isid;
-
-					if (ioinfo[irq]->schib.pmcw.pim != 0x80) {
-						sense_ccw[1].cda = (__u32)
-						    virt_to_phys (psid);
-					} else {
-						sense_ccw[0].cda = (__u32)
-						    virt_to_phys (psid);
-
-					}
-
-					/*
-					 * if just the very first
-					 *  was requested to be
-					 *  sensed disable further
-					 *  scans.
-					 */
-					if (!lpm)
-						lpm = domask;
-
-					sbuffer = 1;
-
-				}
-
-				if (pdevstat->rescnt < (sizeof (senseid_t) - 8)) {
-					ioinfo[irq]->ui.flags.esid = 1;
-
-				}
-
-				io_retry = 0;
-
-				break;
-			}
-
-			failure = 1;
-
-			if (pdevstat->flag & DEVSTAT_STATUS_PENDING) {
-
-				CIO_DEBUG (KERN_DEBUG, 2,
-					   "SenseID : device %04X on "
-					   "Subchannel %04X "
-					   "reports pending status, "
-					   "retry : %d\n",
-					   ioinfo
-					   [irq]->schib.pmcw.dev, irq, retry);
-			
-			} else if (pdevstat->flag & DEVSTAT_FLAG_SENSE_AVAIL) {
-				/*
-				 * if the device doesn't support the SenseID
-				 *  command further retries wouldn't help ...
-				 */
-				if (pdevstat->ii.sense.data[0]
-				    & (SNS0_CMD_REJECT | SNS0_INTERVENTION_REQ)) {
-
-					CIO_DEBUG(KERN_ERR, 2,
-						  "SenseID : device %04X on "
-						  "Subchannel %04X "
-						  "reports cmd reject or "
-						  "intervention required\n",
-						  ioinfo[irq]->schib.pmcw.dev, 
-						  irq);
-
-					io_retry = 0;
-				} else {
-
-					CIO_DEBUG(KERN_WARNING, 2,
-						  "SenseID : UC on "
-						  "dev %04X, retry %d, "
-						  "lpum %02X, "
-						  "cnt %02d, sns :"
-						  " %02X%02X%02X%02X "
-						  "%02X%02X%02X%02X ...\n",
-						  ioinfo[irq]->schib.pmcw.dev,
-						  retry,
-						  pdevstat->lpum,
-						  pdevstat->scnt,
-						  pdevstat->ii.sense.data[0],
-						  pdevstat->ii.sense.data[1],
-						  pdevstat->ii.sense.data[2],
-						  pdevstat->ii.sense.data[3],
-						  pdevstat->ii.sense.data[4],
-						  pdevstat->ii.sense.data[5],
-						  pdevstat->ii.sense.data[6],
-						  pdevstat->ii.sense.data[7]);
-					
-				}
-
-			} else if ((pdevstat->flag & DEVSTAT_NOT_OPER)
-				   || (irq_ret == -ENODEV)) {
-
-				CIO_DEBUG(KERN_ERR, 2,
-					  "SenseID : path %02X for "
-					  "device %04X on "
-					  "subchannel %04X "
-					  "is 'not operational'\n",
-					  domask,
-					  ioinfo[irq]->schib.pmcw.dev, irq);
-				
-				io_retry = 0;
-				ioinfo[irq]->opm &= ~domask;
-
-			} else {
-
-				CIO_DEBUG(KERN_INFO, 2,
-					  "SenseID : start_IO() for "
-					  "device %04X on "
-					  "subchannel %04X "
-					  "returns %d, retry %d, "
-					  "status %04X\n",
-					  ioinfo[irq]->schib.pmcw.dev, irq,
-					  irq_ret, retry, pdevstat->flag);
-
-				if (irq_ret == -ETIMEDOUT) {
-					int xret;
-
-					/*
-					 * Seems we need to cancel the first ssch sometimes...
-					 * On the next try, the ssch will usually be fine.
-					 */
-
-					xret = cancel_IO (irq);
-
-					if (!xret)
-						CIO_MSG_EVENT(4,
-							      "SenseID: sch canceled "
-							      "successfully for irq %x\n",
-							      irq);
-				}
-
-			}
-
-			if (io_retry) {
-				retry--;
-
-				if (retry == 0) {
-					io_retry = 0;
-
-				}
-			}
-
-			if ((failure) && (io_retry)) {
-				/* reset fields... */
-
-				failure = 0;
-
-				psid->reserved = 0;
-				psid->cu_type = 0xFFFF;
-				psid->cu_model = 0;
-				psid->dev_type = 0;
-				psid->dev_model = 0;
-			}
-
-		} while ((io_retry));
-
-	}
-
-	s390irq_spin_unlock (irq);
-	spin_unlock_irqrestore(&sid_lock, flags);
-
-	/*
-	 * If we installed the irq action handler we have to
-	 *  release it too.
-	 */
-	if (inlreq)
-		free_irq (irq, pdevstat);
-
-	/*
-	 * if running under VM check there ... perhaps we should do
-	 *  only if we suffered a command reject, but it doesn't harm
-	 */
-	if ((sid->cu_type == 0xFFFF)
-	    && (MACHINE_IS_VM)) {
-		VM_virtual_device_info (ioinfo[irq]->schib.pmcw.dev, sid);
-	}
-
-	if (sid->cu_type == 0xFFFF) {
-		/*
-		 * SenseID CU-type of 0xffff indicates that no device
-		 *  information could be retrieved (pre-init value).
-		 *
-		 * If we can't couldn't identify the device type we
-		 *  consider the device "not operational".
-		 */
-		CIO_DEBUG(KERN_WARNING, 2,
-			  "SenseID : unknown device %04X on subchannel %04X\n",
-			  ioinfo[irq]->schib.pmcw.dev, irq);
-
-		ioinfo[irq]->ui.flags.unknown = 1;
-		return -ENODEV;
-	}
-
-	/*
-	 * Issue device info message if unit was operational .
-	 */
-	CIO_DEBUG_IFMSG(KERN_INFO, 2, "SenseID : device %04X reports: "
-		"CU  Type/Mod = %04X/%02X, Dev Type/Mod = %04X/%02X\n",
-		ioinfo[irq]->schib.pmcw.dev, sid->cu_type, sid->cu_model,
-		sid->dev_type, sid->dev_model);
-
-	return 0;
-}
-
-/*
- * Device Path Verification
- *
- * Path verification is accomplished by checking which paths (CHPIDs) are
- *  available. Further, a path group ID is set, if possible in multipath
- *  mode, otherwise in single path mode.
- *
- * Note : This function must not be called during normal device recognition,
- *         but during device driver initiated request_irq() processing only.
- */
-int
-s390_DevicePathVerification (int irq, __u8 usermask)
-{
-	int ccode;
-	__u8 pathmask;
-	__u8 domask;
-	int old_opm = 0;
-
-	int ret = 0;
-	int i;
-	pgid_t pgid;
-	__u8 dev_path;
-
-	char dbf_txt[15];
-
-	sprintf (dbf_txt, "dpver%x", irq);
-	CIO_TRACE_EVENT (4, dbf_txt);
-
-	if (ioinfo[irq]->st) 
-		return -ENODEV;
-
-	old_opm = ioinfo[irq]->opm;
-	ccode = stsch (irq, &(ioinfo[irq]->schib));
-
-	if (ccode) {
-		return -ENODEV;
-	}
-	if (ioinfo[irq]->schib.pmcw.pim == 0x80) {
-		/*
-		 * no error, just not required for single path only devices
-		 */
-		ioinfo[irq]->ui.flags.pgid_supp = 0;
-		ret = 0;
-
-		/*
-		 * disable if chpid is logically offline
-		 */
-		if (!chsc_chpid_logical(irq, 0)) {
-			not_oper_handler_func_t nopfunc=ioinfo[irq]->nopfunc;
-			int was_oper = ioinfo[irq]->ui.flags.oper;
-
-			ioinfo[irq]->opm = 0;
-			ioinfo[irq]->ui.flags.oper = 0;
-			CIO_DEBUG_ALWAYS(KERN_WARNING, 0,
-					 "No logical path for sch %d...\n",
-					 irq);
-			if (old_opm && 
-			    was_oper && 
-			    ioinfo[irq]->ui.flags.ready) {
-
-				free_irq( irq, ioinfo[irq]->irq_desc.dev_id);
-				if (nopfunc)
-					nopfunc( irq, DEVSTAT_DEVICE_GONE);
-			}
-			ret = -ENODEV;
-		} else if (!old_opm) {
-
-			/*
-			 * check for opm...
-			 */
-			ioinfo[irq]->opm = ioinfo[irq]->schib.pmcw.pim
-				& ioinfo[irq]->schib.pmcw.pam
-				& ioinfo[irq]->schib.pmcw.pom;
-				
-			if (ioinfo[irq]->opm) {
-				devreg_t *pdevreg;
-
-				ioinfo[irq]->ui.flags.oper = 1;
-				pdevreg = s390_search_devreg( ioinfo[irq] );
-
-				if (pdevreg) 
-					if (pdevreg->oper_func)
-						pdevreg->oper_func
-							( irq, pdevreg);
-			}
-			ret = 0;
-		} else {
-			ret = 0;
-		}
-		return ret;
-	}
-
-	ioinfo[irq]->opm = ioinfo[irq]->schib.pmcw.pim
-	    & ioinfo[irq]->schib.pmcw.pam & ioinfo[irq]->schib.pmcw.pom;
-
-	chsc_validate_chpids(irq);
-	
-	if ((ioinfo[irq]->opm == 0) && (old_opm)) {
-		not_oper_handler_func_t nopfunc=ioinfo[irq]->nopfunc;
-		int was_oper = ioinfo[irq]->ui.flags.ready;
-
-		ioinfo[irq]->ui.flags.oper = 0;
-		CIO_DEBUG_ALWAYS(KERN_WARNING, 0, 
-				 "No logical path for sch %d...\n",
-				 irq);
-		if (was_oper && ioinfo[irq]->ui.flags.oper) {
-
-				free_irq( irq, ioinfo[irq]->irq_desc.dev_id);
-				if (nopfunc)
-					nopfunc( irq, DEVSTAT_DEVICE_GONE);
-		}
-		return -ENODEV;
-	}
-
-	if (!old_opm) {
-		/* Hey, we have a new logical path... */
-		devreg_t *pdevreg;
-		
-		ioinfo[irq]->ui.flags.oper = 1;
-		pdevreg = s390_search_devreg( ioinfo[irq] );
-		
-		if (pdevreg) 
-			if (pdevreg->oper_func)
-				pdevreg->oper_func( irq, pdevreg);
-
-	}
-
-	if ( ioinfo[irq]->ui.flags.pgid_supp == 0 )
-		return 0;	/* just exit ... */
-
-	if (usermask) {
-		dev_path = usermask;
-	} else {
-		dev_path = ioinfo[irq]->opm;
-
-	}
-
-	if (ioinfo[irq]->ui.flags.pgid == 0) {
-		memcpy (&ioinfo[irq]->pgid, &global_pgid, sizeof (pgid_t));
-		ioinfo[irq]->ui.flags.pgid = 1;
-	}
-
-	for (i = 0; i < 8 && !ret; i++) {
-		pathmask = 0x80 >> i;
-
-		domask = dev_path & pathmask;
-
-		if (domask) {
-			if (MACHINE_IS_VM) {
-				/*
-				 * If we are running under VM, try to obtain
-				 * VM's PGID by SensePGID
-				 */
-				*(int *) &pgid = 0;
-				
-				if (!s390_SensePGID (irq, domask, &pgid)) 
-					/*
-					 * Check whether we retrieved
-					 *  a reasonable PGID ...
-					 */
-					if (pgid.inf.ps.state1 ==
-					    SNID_STATE1_GROUPED) 
-						memcpy (&ioinfo[irq]->pgid,
-							&pgid, sizeof (pgid_t));
-
-			}
-			
-			ret = s390_SetPGID (irq, domask);
-
-			if (ret == -EOPNOTSUPP) {
-
-				ioinfo[irq]->ui.flags.pgid_supp = 0;
-				
-				CIO_DEBUG(KERN_WARNING, 2,
-					  "PathVerification(%04X) "
-					  "- Device %04X doesn't "
-					  " support path grouping\n",
-					  irq,
-					  ioinfo[irq]->schib.pmcw.dev);
-				
-			} else if (ret == -EIO) {
-
-				CIO_DEBUG(KERN_ERR, 2,
-					  "PathVerification(%04X) - I/O error "
-					  "on device %04X\n", irq,
-					  ioinfo[irq]->schib.pmcw.dev);
-				
-				ioinfo[irq]->ui.flags.pgid_supp = 0;
-
-			} else if (ret == -ETIMEDOUT) {
-
-				CIO_DEBUG(KERN_ERR, 2,
-					  "PathVerification(%04X) - I/O timed "
-					  "out on device %04X\n", irq,
-					  ioinfo[irq]->schib.pmcw.dev);
-				
-				ioinfo[irq]->ui.flags.pgid_supp = 0;
-
-			} else if (ret == -EAGAIN) {
-
-				ret = 0;
-
-			} else if (ret == -ENODEV) {
-
-				CIO_DEBUG(KERN_ERR, 2,
-					  "PathVerification(%04X) "
-					  "- Device %04X is no longer there?!?\n",
-					  irq, ioinfo[irq]->schib.pmcw.dev);
-
-			} else if (ret) {
-
-				CIO_DEBUG(KERN_ERR, 2,
-					  "PathVerification(%04X) - "
-					  "Unexpected error %d on device %04X\n",
-					  irq, ret, ioinfo[irq]->schib.pmcw.dev);
-				
-				ioinfo[irq]->ui.flags.pgid_supp = 0;
-			}
-		}
-	}
-	return ret;
-
-}
-
-/*
- * s390_SetPGID
- *
- * Set Path Group ID
- *
- */
-static int
-s390_SetPGID (int irq, __u8 lpm)
-{
-	ccw1_t *spid_ccw;	/* ccw area for SPID command */
-	devstat_t devstat;	/* required by request_irq() */
-	devstat_t *pdevstat = &devstat;
-	unsigned long flags;
-	char dbf_txt[15];
-
-	int irq_ret = 0;	/* return code */
-	int retry = 5;		/* retry count */
-	int inlreq = 0;		/* inline request_irq() */
-	int mpath = 1;		/* try multi-path first */
-
-	if (ioinfo[irq]->ui.flags.oper == 0) {
-		return -ENODEV;
-
-	}
-
-	sprintf (dbf_txt, "SPID%x", irq);
-	CIO_TRACE_EVENT (4, dbf_txt);
-
-	if (!ioinfo[irq]->ui.flags.ready) {
-		/*
-		 * Perform SetPGID command processing. We have to request device
-		 *  ownership and provide a dummy I/O handler. We issue sync. I/O
-		 *  requests and evaluate the devstat area on return therefore
-		 *  we don't need a real I/O handler in place.
-		 */
-		irq_ret = request_irq (irq,
-				       init_IRQ_handler,
-				       SA_PROBE, "SPID", pdevstat);
-
-		if (irq_ret == 0)
-			inlreq = 1;
-	} else {
-		pdevstat = ioinfo[irq]->irq_desc.dev_id;
-
-	}
-
-	if (irq_ret) {
-		return irq_ret;
-	}
-
-	s390irq_spin_lock_irqsave (irq, flags);
-
-	if (init_IRQ_complete) {
-		spid_ccw = kmalloc (2 * sizeof (ccw1_t), GFP_DMA);
-	} else {
-		spid_ccw = alloc_bootmem_low (2 * sizeof (ccw1_t));
-
-	}
-
-	spid_ccw[0].cmd_code = CCW_CMD_SUSPEND_RECONN;
-	spid_ccw[0].cda = 0;
-	spid_ccw[0].count = 0;
-	spid_ccw[0].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
-
-	spid_ccw[1].cmd_code = CCW_CMD_SET_PGID;
-	spid_ccw[1].cda = (__u32) virt_to_phys (&ioinfo[irq]->pgid);
-	spid_ccw[1].count = sizeof (pgid_t);
-	spid_ccw[1].flags = CCW_FLAG_SLI;
-
-	ioinfo[irq]->pgid.inf.fc = SPID_FUNC_MULTI_PATH | SPID_FUNC_ESTABLISH;
-
-	/*
-	 * We now issue a SetPGID request. In case of BUSY
-	 *  or STATUS PENDING conditions we retry 5 times.
-	 */
-	do {
-		memset (pdevstat, '\0', sizeof (devstat_t));
-
-		irq_ret = s390_start_IO (irq, spid_ccw, 0xE2D7C9C4,	/* == SPID */
-					 lpm,	/* n/a */
-					 DOIO_WAIT_FOR_INTERRUPT
-					 | DOIO_VALID_LPM
-					 | DOIO_DONT_CALL_INTHDLR
-					 | DOIO_TIMEOUT);
-
-		if (!irq_ret) {
-			if (pdevstat->flag & DEVSTAT_STATUS_PENDING) {
-
-				CIO_DEBUG(KERN_DEBUG, 2,
-					  "SPID - Device %04X "
-					  "on Subchannel %04X "
-					  "reports pending status, "
-					  "retry : %d\n",
-					  ioinfo[irq]->schib.pmcw.dev, 
-					  irq, retry);
-
-				retry--;
-				irq_ret = -EIO;
-			}
-
-			if (pdevstat->flag == (DEVSTAT_START_FUNCTION
-					       | DEVSTAT_FINAL_STATUS)) {
-				retry = 0;	/* successfully set ... */
-				irq_ret = 0;
-			} else if (pdevstat->flag & DEVSTAT_FLAG_SENSE_AVAIL) {
-				/*
-				 * If the device doesn't support the
-				 *  Sense Path Group ID command
-				 *  further retries wouldn't help ...
-				 */
-				if (pdevstat->ii.sense.
-				    data[0] & SNS0_CMD_REJECT) {
-					if (mpath) {
-						/*
-						 * We now try single path mode.
-						 * Note we must not issue the suspend
-						 * multipath reconnect, or we will get
-						 * a command reject by tapes.
-						 */
-
-						spid_ccw[0].cmd_code =
-						    CCW_CMD_SET_PGID;
-						spid_ccw[0].cda = (__u32)
-						    virt_to_phys (&ioinfo[irq]->pgid);
-						spid_ccw[0].count =
-						    sizeof (pgid_t);
-						spid_ccw[0].flags =
-						    CCW_FLAG_SLI;
-
-						ioinfo[irq]->pgid.inf.fc =
-						    SPID_FUNC_SINGLE_PATH
-						    | SPID_FUNC_ESTABLISH;
-						mpath = 0;
-						retry--;
-						irq_ret = -EIO;
-					} else {
-						irq_ret = -EOPNOTSUPP;
-						retry = 0;
-
-					}
-				} else {
-
-					CIO_DEBUG(KERN_WARNING, 2,
-						  "SPID - device %04X,"
-						  " unit check,"
-						  " retry %d, cnt %02d,"
-						  " sns :"
-						  " %02X%02X%02X%02X "
-						  "%02X%02X%02X%02X ...\n",
-						  ioinfo[irq]->schib.pmcw.dev, 
-						  retry,
-						  pdevstat->scnt,
-						  pdevstat->ii.sense.data[0],
-						  pdevstat->ii.sense.data[1],
-						  pdevstat->ii.sense.data[2],
-						  pdevstat->ii.sense.data[3],
-						  pdevstat->ii.sense.data[4],
-						  pdevstat->ii.sense.data[5],
-						  pdevstat->ii.sense.data[6],
-						  pdevstat->ii.sense.data[7]);
-
-					retry--;
-					irq_ret = -EIO;
-
-				}
-
-			} else if (pdevstat->flag & DEVSTAT_NOT_OPER) {
-				/* don't issue warnings during startup unless requested */
-				if (init_IRQ_complete || cio_notoper_msg) {
-
-					CIO_DEBUG_ALWAYS(KERN_WARNING, 2,
-							 "SPID - Device %04X "
-							 "on Subchannel %04X, "
-							 "lpm %02X, "
-							 "became 'not "
-							 "operational'\n",
-							 ioinfo[irq]->schib.
-							 pmcw.dev, 
-							 irq, lpm);
-				}
-
-				retry = 0;
-				ioinfo[irq]->opm &= ~lpm;
-				switch_off_chpids(irq, lpm);
-				irq_ret = -EAGAIN;
-
-			}
-		} else if (irq_ret == -ETIMEDOUT) {
-			/* 
-			 * SetPGID timed out, so we cancel it before
-			 * we retry
-			 */
-			int xret;
-
-			xret = cancel_IO(irq);
-
-			if (!xret) 
-				CIO_MSG_EVENT(2,
-					      "SetPGID: sch canceled "
-					      "successfully for irq %x\n",
-					      irq);
-			retry--;
-			
-		} else if (irq_ret != -ENODEV) {
-			retry--;
-			irq_ret = -EIO;
-		} else {
-			retry = 0;
-			irq_ret = -ENODEV;
-
-		}
-
-	} while (retry > 0);
-
-	if (init_IRQ_complete) {
-		kfree (spid_ccw);
-	} else {
-		free_bootmem ((unsigned long) spid_ccw, 2 * sizeof (ccw1_t));
-
-	}
-
-	s390irq_spin_unlock_irqrestore (irq, flags);
-
-	/*
-	 * If we installed the irq action handler we have to
-	 *  release it too.
-	 */
-	if (inlreq)
-		free_irq (irq, pdevstat);
-
-	return irq_ret;
-}
-
-/*
- * s390_SensePGID
- *
- * Sense Path Group ID
- *
- */
-static int
-s390_SensePGID (int irq, __u8 lpm, pgid_t * pgid)
-{
-	ccw1_t *snid_ccw;	/* ccw area for SNID command */
-	devstat_t devstat;	/* required by request_irq() */
-	devstat_t *pdevstat = &devstat;
-	char dbf_txt[15];
-	pgid_t * tmp_pgid;
-
-	int irq_ret = 0;	/* return code */
-	int retry = 5;		/* retry count */
-	int inlreq = 0;		/* inline request_irq() */
-	unsigned long flags;
-
-	if (ioinfo[irq]->ui.flags.oper == 0) {
-		return -ENODEV;
-
-	}
-
-	sprintf (dbf_txt, "SNID%x", irq);
-	CIO_TRACE_EVENT (4, dbf_txt);
-
-	if (!ioinfo[irq]->ui.flags.ready) {
-		/*
-		 * Perform SENSE PGID command processing. We have to request device
-		 *  ownership and provide a dummy I/O handler. We issue sync. I/O
-		 *  requests and evaluate the devstat area on return therefore
-		 *  we don't need a real I/O handler in place.
-		 */
-		irq_ret = request_irq (irq,
-				       init_IRQ_handler,
-				       SA_PROBE, "SNID", pdevstat);
-
-		if (irq_ret == 0)
-			inlreq = 1;
-
-	} else {
-		pdevstat = ioinfo[irq]->irq_desc.dev_id;
-
-	}
-
-	if (irq_ret) {
-		return irq_ret;
-	}
-
-	s390irq_spin_lock_irqsave (irq, flags);
-
-	if (init_IRQ_complete) {
-		snid_ccw = kmalloc (sizeof (ccw1_t), GFP_DMA);
-		tmp_pgid = kmalloc (sizeof (pgid_t), GFP_DMA);
-	} else {
-		snid_ccw = alloc_bootmem_low (sizeof (ccw1_t));
-		tmp_pgid = alloc_bootmem_low (sizeof (pgid_t));
-	}
-
-	snid_ccw->cmd_code = CCW_CMD_SENSE_PGID;
-	snid_ccw->cda = (__u32) virt_to_phys (tmp_pgid);
-	snid_ccw->count = sizeof (pgid_t);
-	snid_ccw->flags = CCW_FLAG_SLI;
-
-	/*
-	 * We now issue a SensePGID request. In case of BUSY
-	 *  or STATUS PENDING conditions we retry 5 times.
-	 */
-	do {
-		memset (pdevstat, '\0', sizeof (devstat_t));
-
-		irq_ret = s390_start_IO (irq, snid_ccw, 0xE2D5C9C4,	/* == SNID */
-					 lpm,	/* n/a */
-					 DOIO_WAIT_FOR_INTERRUPT
-					 | DOIO_VALID_LPM
-					 | DOIO_DONT_CALL_INTHDLR);
-
-		if (irq_ret == 0) {
-			if (pdevstat->flag & DEVSTAT_FLAG_SENSE_AVAIL) {
-				/*
-				 * If the device doesn't support the
-				 *  Sense Path Group ID command
-				 *  further retries wouldn't help ...
-				 */
-				if (pdevstat->ii.sense.data[0] & 
-				    (SNS0_CMD_REJECT | SNS0_INTERVENTION_REQ)) {
-					retry = 0;
-					irq_ret = -EOPNOTSUPP;
-				} else {
-
-					CIO_DEBUG(KERN_WARNING, 2,
-						  "SNID - device %04X,"
-						  " unit check,"
-						  " flag %04X, "
-						  " retry %d, cnt %02d,"
-						  " sns :"
-						  " %02X%02X%02X%02X "
-						  "%02X%02X%02X%02X ...\n",
-						  ioinfo[irq]->schib.pmcw.dev,
-						  pdevstat->flag,
-						  retry,
-						  pdevstat->scnt,
-						  pdevstat->ii.sense.data[0],
-						  pdevstat->ii.sense.data[1],
-						  pdevstat->ii.sense.data[2],
-						  pdevstat->ii.sense.data[3],
-						  pdevstat->ii.sense.data[4],
-						  pdevstat->ii.sense.data[5],
-						  pdevstat->ii.sense.data[6],
-						  pdevstat->ii.sense.data[7]);
-
-					retry--;
-					irq_ret = -EIO;
-
-				}
-			} else if (pdevstat->flag & DEVSTAT_NOT_OPER) {
-				/* don't issue warnings during startup unless requested */
-				if (init_IRQ_complete || cio_notoper_msg) {
-
-					CIO_DEBUG_ALWAYS(KERN_WARNING, 2,
-							 "SNID - Device %04X "
-							 "on Subchannel %04X, "
-							 "lpm %02X, "
-							 "became 'not "
-							 "operational'\n",
-							 ioinfo[irq]->schib.
-							 pmcw.dev, 
-							 irq, lpm);
-				}
-
-				retry = 0;
-				irq_ret = -EIO;
-
-			} else {
-				retry = 0;	/* success ... */
-				irq_ret = 0;
-				memcpy(pgid, tmp_pgid, sizeof(pgid_t));
-
-			}
-		} else if (irq_ret != -ENODEV) {	/* -EIO, or -EBUSY */
-
-			if (pdevstat->flag & DEVSTAT_STATUS_PENDING) {
-
-				CIO_DEBUG(KERN_INFO, 2,
-					  "SNID - Device %04X "
-					  "on Subchannel %04X "
-					  "reports pending status, "
-					  "retry : %d\n",
-					  ioinfo[irq]->schib.pmcw.dev, 
-					  irq, retry);
-			}
-
-			CIO_DEBUG_ALWAYS(KERN_INFO, 2,
-					 "SNID - device %04X,"
-					 " start_io() reports rc : %d,"
-					 " retrying ...\n",
-					 ioinfo[irq]->schib.pmcw.dev, 
-					 irq_ret);
-			retry--;
-			irq_ret = -EIO;
-		} else {	/* -ENODEV ... */
-
-			retry = 0;
-			irq_ret = -ENODEV;
-
-		}
-
-	} while (retry > 0);
-
-	if (init_IRQ_complete) {
-		kfree (snid_ccw);
-		kfree (tmp_pgid);
-	} else {
-		free_bootmem ((unsigned long) snid_ccw, sizeof (ccw1_t));
-		free_bootmem ((unsigned long) tmp_pgid, sizeof (tmp_pgid));
-	}
-
-	s390irq_spin_unlock_irqrestore (irq, flags);
-
-	/*
-	 * If we installed the irq action handler we have to
-	 *  release it too.
-	 */
-	if (inlreq)
-		free_irq (irq, pdevstat);
-
-	return irq_ret;
-}
-
-/*
- * Function: s390_send_nop
- * 
- * sends a nop CCW to the specified subchannel down the given path(s)
- */
-int
-s390_send_nop(int irq, __u8 lpm)
-{
- 	char dbf_txt[15];
- 	devstat_t devstat;
- 	devstat_t *pdevstat = &devstat;
- 	unsigned long flags;
-	
- 	int irq_ret = 0;
- 	int inlreq = 0;
-	
-	/* static allocation is necessary because nop_ccw has to be below
-	 * the 2GB border. locking is not required since it nop_ccw is
-	 * never modified */
-	static ccw1_t nop_ccw = {
-		.cmd_code  = CCW_CMD_NOOP,
-		.flags	   = CCW_FLAG_SLI,
-	};
-
- 	if (!ioinfo[irq]->ui.flags.oper)
- 		/* no sense in trying */
- 		return -ENODEV;
-	
- 	sprintf(dbf_txt, "snop%x", irq);
- 	CIO_TRACE_EVENT(5, dbf_txt);
- 
- 	if (!ioinfo[irq]->ui.flags.ready) {
- 		/*
- 		 * If there's no handler, use our dummy handler.
- 		 */
- 		irq_ret = request_irq (irq,
- 				       init_IRQ_handler,
- 				       SA_PROBE,
- 				       "SNOP",
- 				       pdevstat);
- 		if (!irq_ret)
- 			inlreq = 1;
- 	} else {
- 		pdevstat = ioinfo[irq]->irq_desc.dev_id;
- 	}
- 	
- 	if (irq_ret)
- 		return irq_ret;
- 
- 	s390irq_spin_lock_irqsave (irq, flags);
- 
- 	memset (pdevstat, '\0', sizeof (devstat_t));
- 	
- 	irq_ret = s390_start_IO (irq, &nop_ccw, 0xE2D5D6D7, lpm,
- 				 DOIO_WAIT_FOR_INTERRUPT
- 				 | DOIO_TIMEOUT
- 				 | DOIO_DONT_CALL_INTHDLR
- 				 | DOIO_VALID_LPM);
- 	
- 	if (irq_ret == -ETIMEDOUT) {
- 
- 		/* better cancel... */
- 		cancel_IO(irq);
- 	}
- 
- 	s390irq_spin_unlock_irqrestore (irq, flags);
- 
- 	if (inlreq)
- 		free_irq (irq, pdevstat);
- 
- 	return irq_ret;
- 
-}
-
-EXPORT_SYMBOL (read_conf_data);
-EXPORT_SYMBOL (read_dev_chars);
diff -Nru a/drivers/s390/cio/s390io.h b/drivers/s390/cio/s390io.h
--- a/drivers/s390/cio/s390io.h	Mon Dec  9 18:46:35 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,20 +0,0 @@
-#ifndef S390_S390IO_H
-#define S390_S390IO_H
-
-extern __u64 chpids_logical[4];
-
-/* cio_show_msg is needed in chsc.c */
-extern int cio_show_msg;
-
-/* cio_count_irqs is used in proc.c and cio.c */
-extern int cio_count_irqs;
-extern unsigned long s390_irq_count[NR_CPUS];
-extern irb_t p_init_irb;
-
-extern void s390_device_recognition_irq (int irq);
-extern int s390_validate_subchannel (int irq, int enable);
-extern int s390_DevicePathVerification (int irq, __u8 usermask);
-
-extern int s390_send_nop(int irq, __u8 lpm);
-
-#endif
diff -Nru a/drivers/s390/misc/Makefile b/drivers/s390/misc/Makefile
--- a/drivers/s390/misc/Makefile	Mon Dec  9 18:46:51 2002
+++ b/drivers/s390/misc/Makefile	Mon Dec  9 18:46:51 2002
@@ -2,7 +2,6 @@
 # S/390 miscellaneous devices
 #
 
-obj-$(CONFIG_CHANDEV) += chandev.o
-export-objs += chandev.o
+# placeholder for stuff to come...
 
 include $(TOPDIR)/Rules.make
diff -Nru a/drivers/s390/misc/chandev.c b/drivers/s390/misc/chandev.c
--- a/drivers/s390/misc/chandev.c	Mon Dec  9 18:46:36 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,3304 +0,0 @@
-/*
- *  drivers/s390/misc/chandev.c
- *
- *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
- * 
- *  Generic channel device initialisation support. 
- */
-#define TRUE 1
-#define FALSE 0
-#define __KERNEL_SYSCALLS__
-#include <linux/module.h>
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/ctype.h>
-#include <asm/uaccess.h>
-#include <linux/slab.h>
-#include <asm/irq.h>
-#include <linux/init.h>
-#include <linux/unistd.h>
-#include <asm/chandev.h>
-#include <linux/proc_fs.h>
-#include <linux/vmalloc.h>
-#include <asm/s390dyn.h>
-#include <asm/queue.h>
-#include <linux/kmod.h>
-#include <linux/workqueue.h>
-#ifndef MIN
-#define MIN(a,b) ((a<b)?a:b)
-#endif
-#ifndef MAX
-#define MAX(a,b) ((a>b)?a:b)
-#endif
-
-
-
-typedef struct chandev_model_info chandev_model_info;
-struct chandev_model_info
-{
-	struct chandev_model_info *next;
-	chandev_type chan_type;
-	s32 cu_type;      /* control unit type  -1 = don't care */
-	s16 cu_model;     /* control unit model -1 = don't care */
-	s32 dev_type;     /* device type -1 = don't care */
-	s16 dev_model;    /* device model -1 = don't care */
-	u8  max_port_no;
-	int auto_msck_recovery;
-	u8  default_checksum_received_ip_pkts;
-	u8  default_use_hw_stats; /* where available e.g. lcs */
-	devreg_t drinfo;
-};
-
-typedef struct chandev chandev;
-struct chandev
-{
-	struct chandev *next;
-	chandev_model_info *model_info;
-	chandev_subchannel_info sch;
-	int owned;
-};
-
-typedef struct chandev_noauto_range chandev_noauto_range;
-struct chandev_noauto_range
-{
-	struct chandev_noauto_range *next;
-	u16     lo_devno;
-	u16     hi_devno;
-};
-
-typedef struct chandev_force chandev_force;
-struct chandev_force
-{
-	struct chandev_force *next;
-	chandev_type chan_type;
-	s32     devif_num; /* -1 don't care, -2 we are forcing a range e.g. tr0 implies 0 */
-        u16     read_lo_devno;
-	u16     write_hi_devno;
-	u16     data_devno; /* only used by gigabit ethernet */
-	s32     memory_usage_in_k;
-        s16     port_protocol_no; /* where available e.g. lcs,-1 don't care */
-	u8      checksum_received_ip_pkts;
-	u8      use_hw_stats; /* where available e.g. lcs */
-	/* claw specific stuff */
-	chandev_claw_info  claw;
-};
-
-typedef struct chandev_probelist chandev_probelist;
-struct chandev_probelist
-{
-	struct chandev_probelist            *next;
-	chandev_probefunc                   probefunc;
-	chandev_shutdownfunc                shutdownfunc;
-	chandev_msck_notification_func      msck_notfunc;
-	chandev_type                        chan_type;
-	int                                 devices_found;
-};
-
-
-
-#define default_msck_bits ((1<<(chandev_status_not_oper-1))|(1<<(chandev_status_no_path-1))|(1<<(chandev_status_revalidate-1))|(1<<(chandev_status_gone-1)))
-
-
-static char *msck_status_strs[]=
-{
-	"good",
-	"not_operational",
-	"no_path",
-	"revalidate",
-	"device_gone"
-};
-
-typedef struct chandev_msck_range chandev_msck_range;
-struct chandev_msck_range
-{
-	struct chandev_msck_range *next;
-	u16     lo_devno;
-	u16     hi_devno;
-	int      auto_msck_recovery;
-};
-
-static chandev_msck_range *chandev_msck_range_head=NULL;
-
-typedef struct chandev_irqinfo chandev_irqinfo;
-struct chandev_irqinfo
-{
-	chandev_irqinfo         *next;
-	chandev_subchannel_info sch;
-	chandev_msck_status     msck_status;
-	void                    (*handler)(int, void *, struct pt_regs *);
-	unsigned long           irqflags;
-	void                    *dev_id;
-	char                    devname[0];
-};
-
-
-static chandev_irqinfo *chandev_irqinfo_head=NULL;
-
-typedef struct chandev_parms chandev_parms;
-struct chandev_parms
-{
-	chandev_parms      *next;
-	chandev_type       chan_type;
-	u16                lo_devno;
-	u16                hi_devno;
-	char               parmstr[0];
-};
-
-static chandev_type chandev_persistent=0; 
-
-static chandev_parms *chandev_parms_head=NULL;
-
-
-typedef struct chandev_activelist chandev_activelist;
-struct chandev_activelist
-{
-	struct chandev_activelist        *next;
-	chandev_irqinfo                  *read_irqinfo;
-	chandev_irqinfo                  *write_irqinfo;
-	chandev_irqinfo                  *data_irqinfo;
-	chandev_probefunc                probefunc;
-	chandev_shutdownfunc             shutdownfunc;
-	chandev_msck_notification_func   msck_notfunc;
-	chandev_unregfunc                unreg_dev;
-	chandev_type                     chan_type;
-	u8                               port_no;
-	chandev_category                 category;
-	s32                              memory_usage_in_k;
-	void                             *dev_ptr;
-	char                             devname[0];
-};
-
-
-
-static chandev_model_info *chandev_models_head=NULL;
-/* The only reason chandev_head is a queue is so that net devices */
-/* will be by default named in the order of their irqs */
-static qheader chandev_head={NULL,NULL};
-static chandev_noauto_range *chandev_noauto_head=NULL;
-static chandev_force *chandev_force_head=NULL;
-static chandev_probelist *chandev_probelist_head=NULL;
-static chandev_activelist *chandev_activelist_head=NULL;
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-/* not static, see comment in chandev.h */
-int chandev_use_devno_names=FALSE;
-#endif
-static int chandev_cautious_auto_detect=TRUE;
-static atomic_t chandev_conf_read=ATOMIC_INIT(FALSE);
-static atomic_t chandev_initialised=ATOMIC_INIT(FALSE);
-
-
-static unsigned long chandev_last_machine_check;
-
-static void chandev_msck_task(void *unused);
-static DECLARE_WORK(chandev_msck_work, chandev_msck_task, 0);
-static atomic_t chandev_msck_thread_lock;
-static atomic_t chandev_new_msck;
-static unsigned long chandev_last_startmsck_list_update;
-
-
-typedef enum
-{
-	chandev_start,
-	chandev_first_tag=chandev_start,
-	chandev_msck,
-	chandev_num_notify_tags
-} chandev_userland_notify_tag;
-
-static char *userland_notify_strs[]=
-{
-	"start",
-	"machine_check"
-};
-
-typedef struct chandev_userland_notify_list chandev_userland_notify_list;
-struct chandev_userland_notify_list
-{
-	chandev_userland_notify_list    *next;
-	chandev_userland_notify_tag      tag;
-	chandev_msck_status              prev_status;
-	chandev_msck_status              curr_status;
-	char                      devname[0];
-};
-
-
-static chandev_userland_notify_list *chandev_userland_notify_head=NULL;
-
-
-
-
-static void chandev_read_conf_if_necessary(void);
-static void chandev_read_conf(void);
-
-#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,3,0)
-typedef struct net_device  net_device;
-#else
-typedef struct device  net_device;
-
-static inline void init_waitqueue_head(wait_queue_head_t *q)
-{
-	*q=NULL;
-}
-#endif
-
-#if LINUX_VERSION_CODE<KERNEL_VERSION(2,3,45)
-static __inline__ void netif_stop_queue(net_device *dev)
-{
-	dev->tbusy=1;
-}
-
-static __inline__ void netif_start_queue(net_device *dev)
-{
-	dev->tbusy=0;
-}
-#endif
-
-
-
-#define CHANDEV_INVALID_LOCK_OWNER            -1
-static long                 chandev_lock_owner;
-static int                  chandev_lock_cnt; 
-static spinlock_t           chandev_spinlock;
-#define CHANDEV_LOCK_DEBUG 0
-#if CHANDEV_LOCK_DEBUG && !defined(CONFIG_ARCH_S390X)
-#define CHANDEV_BACKTRACE_LOOPCNT 10
-void                        *chandev_first_lock_addr[CHANDEV_BACKTRACE_LOOPCNT],
-	                    *chandev_last_lock_addr[CHANDEV_BACKTRACE_LOOPCNT],
-	                    *chandev_last_unlock_addr[CHANDEV_BACKTRACE_LOOPCNT];
-#define CHANDEV_BACKTRACE(variable) \
-memset((variable),0,sizeof(void *)*CHANDEV_BACKTRACE_LOOPCNT); \
-(variable)[0]=__builtin_return_address(0); \
-if(((long)variable[0])&0x80000000)         \
-{                                          \
-(variable)[1]=__builtin_return_address(1); \
-if(((long)variable[1])&0x80000000)         \
-{                                          \
-(variable)[2]=__builtin_return_address(2); \
-if(((long)variable[2])&0x80000000)         \
-{                                          \
-(variable)[3]=__builtin_return_address(3); \
-if(((long)variable[3])&0x80000000)         \
-{                                          \
-(variable)[4]=__builtin_return_address(4); \
-if(((long)variable[4])&0x80000000)         \
-{                                          \
-(variable)[5]=__builtin_return_address(5); \
-if(((long)variable[5])&0x80000000)         \
-{                                          \
-(variable)[6]=__builtin_return_address(6); \
-if(((long)variable[6])&0x80000000)         \
-{                                          \
-(variable)[7]=__builtin_return_address(7); \
-if(((long)variable[7])&0x80000000)         \
-{                                          \
-(variable)[8]=__builtin_return_address(8); \
-if(((long)variable[8])&0x80000000)         \
-{                                          \
-(variable)[9]=__builtin_return_address(9); \
-} \
-} \
-} \
-} \
-} \
-} \
-} \
-} \
-}
-#else
-#define CHANDEV_BACKTRACE(variable)
-#endif
-
-
-
-typedef struct chandev_not_oper_struct chandev_not_oper_struct;
-
-struct  chandev_not_oper_struct
-{
-	chandev_not_oper_struct *next;
-	int irq;
-	int status;
-};
-
-
-/* May as well try to keep machine checks in the order they happen so
- * we use qheader for chandev_not_oper_head instead of list.
- */
-static qheader chandev_not_oper_head={NULL,NULL};
-static spinlock_t           chandev_not_oper_spinlock;
-
-#define chandev_interrupt_check(name) \
-if(in_interrupt())                \
-     printk(KERN_WARNING name " called under interrupt this shouldn't happen\n")
-
-
-#define for_each(variable,head) \
-for((variable)=(head);(variable)!=NULL;(variable)=(variable)->next)
-
-#define for_each_allow_delete(variable,nextmember,head) \
-for((variable)=(head),(nextmember)=((head) ? (head)->next:NULL); \
-(variable)!=NULL; (variable)=(nextmember),(nextmember)=((nextmember) ? (nextmember->next) : NULL))
-
-#define for_each_allow_delete2(variable,nextmember,head) \
-for((variable)=(head);(variable)!=NULL;(variable)=(nextmember))
-
-
-static void chandev_lock(void)
-{
-	eieio();
-	chandev_interrupt_check("chandev_lock");
-	if(chandev_lock_owner!=(long)current)
-	{
-		while(!spin_trylock(&chandev_spinlock))
-			schedule();
-		chandev_lock_cnt=1;
-		chandev_lock_owner=(long)current;
-		CHANDEV_BACKTRACE(chandev_first_lock_addr)
-	}
-	else
-	{
-		chandev_lock_cnt++;
-		CHANDEV_BACKTRACE(chandev_last_lock_addr)
-	}
-	if(chandev_lock_cnt<0||chandev_lock_cnt>100)
-	{
-		printk("odd lock_cnt %d lcs_chan_lock",chandev_lock_cnt);
-		chandev_lock_cnt=1;
-	}
-}
-
-static int chandev_full_unlock(void)
-{
-	int ret_lock_cnt=chandev_lock_cnt;
-	chandev_lock_cnt=0;
-	chandev_lock_owner=CHANDEV_INVALID_LOCK_OWNER;
-	spin_unlock(&chandev_spinlock);
-	return(ret_lock_cnt);
-}
-
-static void chandev_unlock(void)
-{
-	if(chandev_lock_owner!=(long)current)
-		printk("chandev_unlock: current=%lx"
-		      " chandev_lock_owner=%lx chandev_lock_cnt=%d\n",
-		      (long)current,
-		      chandev_lock_owner,
-		      chandev_lock_cnt);
-	CHANDEV_BACKTRACE(chandev_last_unlock_addr)
-	if(--chandev_lock_cnt==0)
-	{
-		chandev_lock_owner=CHANDEV_INVALID_LOCK_OWNER;
-		spin_unlock(&chandev_spinlock);
-	}
-	if(chandev_lock_cnt<0)
-	{
-		printk("odd lock_cnt=%d in chan_unlock",chandev_lock_cnt);
-		chandev_full_unlock();
-	}
-
-}
-
-
-
-static void *chandev_alloc(size_t size)
-{
-	void *mem=kmalloc(size,GFP_ATOMIC);
-	if(mem)
-		memset(mem,0,size);
-	return(mem);
-}
-
-static void chandev_add_to_list(list **listhead,void *member)
-{
-	chandev_lock();
-	add_to_list(listhead,member);
-	chandev_unlock();
-}
-
-static void chandev_queuemember(qheader *qhead,void *member)
-{
-	chandev_lock();
-	enqueue_tail(qhead,(queue *)member);
-	chandev_unlock();
-}
-
-static int chandev_remove_from_list(list **listhead,list *member)
-{
-	int retval;
-
-	chandev_lock();
-	retval=remove_from_list(listhead,member);
-	chandev_unlock();
-	return(retval);
-}
-
-static int chandev_remove_from_queue(qheader *qhead,queue *member)
-{
-	int retval;
-	
-	chandev_lock();
-	retval=remove_from_queue(qhead,member);
-	chandev_unlock();
-	return(retval);
-}
-
-
-
-static void chandev_free_listmember(list **listhead,list *member)
-{
-	chandev_lock();
-	if(member)
-	{
-		if(chandev_remove_from_list(listhead,member))
-			kfree(member);
-		else
-			printk(KERN_CRIT"chandev_free_listmember detected nonexistant"
-			       "listmember listhead=%p member %p\n",listhead,member);
-	}
-	chandev_unlock();
-}
-
-static void chandev_free_queuemember(qheader *qhead,queue *member)
-{
-	chandev_lock();
-	if(member)
-	{
-		if(chandev_remove_from_queue(qhead,member))
-			kfree(member);
-		else
-			printk(KERN_CRIT"chandev_free_queuemember detected nonexistant"
-			       "queuemember qhead=%p member %p\n",qhead,member);
-	}
-	chandev_unlock();
-}
-
-
-
-static void chandev_free_all_list(list **listhead)
-{
-	list *head;
-
-	chandev_lock();
-	while((head=remove_listhead(listhead)))
-		kfree(head);
-	chandev_unlock();
-}
-
-static void chandev_free_all_queue(qheader *qhead)
-{
-	chandev_lock();
-	while(qhead->head)
-		chandev_free_queuemember(qhead,qhead->head);
-	chandev_unlock();
-}
-
-static void chandev_wait_for_root_fs(void)
-{
-	wait_queue_head_t      wait;
-
-	init_waitqueue_head(&wait);
-	/* We need to wait till there is a root filesystem */
-	while(init_task.fs->root==NULL)
-	{
-		sleep_on_timeout(&wait,HZ);
-	}
-}
-
-/* We are now hotplug compliant i.e. */
-/* we typically get called in /sbin/hotplug chandev our parameters */
-static int chandev_exec_start_script(void *unused)
-{
-	
-	char **argv,*tempname;
-	int retval=-ENOMEM;
-	int argc,loopcnt;
-	size_t allocsize;
-	chandev_userland_notify_list *member;
-	wait_queue_head_t      wait;
-	int                    have_tag[chandev_num_notify_tags]={FALSE,};
-	chandev_userland_notify_tag tagidx;
-	static char * envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
-	
-	init_waitqueue_head(&wait);
-	strcpy(current->comm,"chandev_script");
-
-	for(loopcnt=0;loopcnt<10&&(jiffies-chandev_last_startmsck_list_update)<HZ;loopcnt++)
-	{
-		sleep_on_timeout(&wait,HZ);
-	}
-	if(!chandev_userland_notify_head)
-		return(0);
-	chandev_lock();
-	argc=2;
-	for(tagidx=chandev_first_tag;tagidx<chandev_num_notify_tags;tagidx++)
-	{
-		for_each(member,chandev_userland_notify_head)
-		{
-			if(member->tag==tagidx)
-			{
-				switch(tagidx)
-				{
-				case chandev_start:
-					argc++;
-					break;
-				case chandev_msck:
-					argc+=3;
-					break;
-				default:
-					break;
-				}
-				if(have_tag[tagidx]==FALSE)
-					argc++;
-				have_tag[tagidx]=TRUE;
-
-			}
-		}
-	}
-	allocsize=(argc+1)*sizeof(char *);
-        /* Warning possible stack overflow */
-	/* We can't kmalloc the parameters here as execve will */
-	/* not return if successful */
-	argv=alloca(allocsize);
-	if(argv)
-	{
-		memset(argv,0,allocsize);
-		argv[0]=hotplug_path;
-		argv[1]="chandev";
-		argc=2;
-		for(tagidx=chandev_first_tag;tagidx<chandev_num_notify_tags;tagidx++)
-		{
-			if(have_tag[tagidx])
-			{
-				argv[argc++]=userland_notify_strs[tagidx];
-				for_each(member,chandev_userland_notify_head)
-				{
-					if(member->tag==tagidx)
-					{
-						tempname=alloca(strlen(member->devname)+1);
-						if(tempname)
-						{
-							strcpy(tempname,member->devname);
-							argv[argc++]=tempname;
-						}
-						else
-							goto Fail;
-						if(member->tag==chandev_msck)
-						{
-							argv[argc++]=msck_status_strs[member->prev_status];
-							argv[argc++]=msck_status_strs[member->curr_status];
-						}
-					}
-				}
-			}
-		}
-		chandev_free_all_list((list **)&chandev_userland_notify_head);
-		chandev_unlock();
-		chandev_wait_for_root_fs();
-		/* We are basically execve'ing here there normally is no */
-		/* return */
-		retval=exec_usermodehelper(hotplug_path, argv, envp);
-		goto Fail2;
-	}
- Fail:
-	
-	chandev_unlock();
- Fail2:
-	return(retval);
-}
-
-
-static void *chandev_allocstr(const char *str,size_t offset)
-{
-	char *member;
-
-	if((member=chandev_alloc(offset+strlen(str)+1)))
-	{
-		strcpy(&member[offset],str);
-	}
-	return((void *)member);
-}
-
-
-static int chandev_add_to_userland_notify_list(chandev_userland_notify_tag tag,
-char *devname, chandev_msck_status prev_status,chandev_msck_status curr_status)
-{
-	chandev_userland_notify_list *member,*nextmember;
-	int pid;
-	
-	chandev_lock();
-	/* remove operations still outstanding for this device */
-	for_each_allow_delete(member,nextmember,chandev_userland_notify_head)
-		if(strcmp(member->devname,devname)==0)
-			chandev_free_listmember((list **)&chandev_userland_notify_head,(list *)member);
-	
-
-	if((member=chandev_allocstr(devname,offsetof(chandev_userland_notify_list,devname))))
-	{
-		member->tag=tag;
-		member->prev_status=prev_status;
-		member->curr_status=curr_status;
-		add_to_list((list **)&chandev_userland_notify_head,(list *)member);
-		chandev_last_startmsck_list_update=jiffies;
-		chandev_unlock();
-		pid = kernel_thread(chandev_exec_start_script,NULL,SIGCHLD);
-		if(pid<0)
-		{
-			printk("error making kernel thread for chandev_exec_start_script\n");
-			return(pid);
-		}
-		else
-			return(0);
-
-	}
-	else
-	{
-		chandev_unlock();
-		printk("chandev_add_to_startmscklist memory allocation failed devname=%s\n",devname);
-		return(-ENOMEM);
-	}
-}
-
-
-
-
-
-static int chandev_oper_func(int irq,devreg_t *dreg)
-{
-	chandev_last_machine_check=jiffies;
-	if(atomic_dec_and_test(&chandev_msck_thread_lock))
-	{
-		schedule_work(&chandev_msck_work);
-	}
-	atomic_set(&chandev_new_msck,TRUE);
-	return(0);
-}
-
-static void chandev_not_oper_handler(int irq,int status )
-{
-	chandev_not_oper_struct *new_not_oper;
-
-	chandev_last_machine_check=jiffies;
-	if((new_not_oper=kmalloc(sizeof(chandev_not_oper_struct),GFP_ATOMIC)))
-	{
-		new_not_oper->irq=irq;
-		new_not_oper->status=status;
-		spin_lock(&chandev_not_oper_spinlock);
-		enqueue_tail(&chandev_not_oper_head,(queue *)new_not_oper);
-		spin_unlock(&chandev_not_oper_spinlock);
-		if(atomic_dec_and_test(&chandev_msck_thread_lock))
-		{
-			schedule_work(&chandev_msck_work);
-		}
-	}
-	else
-		printk("chandev_not_oper_handler failed to allocate memory & "
-		       "lost a not operational interrupt %d %x",
-		       irq,status);
-}
-
-static chandev_irqinfo *chandev_get_irqinfo_by_irq(int irq)
-{
-	chandev_irqinfo *curr_irqinfo;
-	for_each(curr_irqinfo,chandev_irqinfo_head)
-		if(irq==curr_irqinfo->sch.irq)
-			return(curr_irqinfo);
-	return(NULL);
-}
-
-static chandev *chandev_get_by_irq(int irq)
-{
-	chandev *curr_chandev;
-
-	for_each(curr_chandev,(chandev *)chandev_head.head)
-		if(curr_chandev->sch.irq==irq)
-		{
-			return(curr_chandev);
-		}
-	return(NULL);
-}
-
-static chandev_activelist *chandev_get_activelist_by_irq(int irq)
-{
-	chandev_activelist *curr_device;
-
-	for_each(curr_device,chandev_activelist_head)
-	{
-			if(curr_device->read_irqinfo->sch.irq==irq||
-			   curr_device->write_irqinfo->sch.irq==irq||
-			   (curr_device->data_irqinfo&&curr_device->data_irqinfo->sch.irq==irq))
-				return(curr_device);
-	}
-	return(NULL);
-}
-
-
-static void chandev_remove_irqinfo_by_irq(unsigned int irq)
-{
-	chandev_irqinfo *remove_irqinfo;
-	chandev_activelist *curr_device;
-
-	chandev_lock();
-	/* remove any orphan irqinfo left lying around. */
-        if((remove_irqinfo=chandev_get_irqinfo_by_irq(irq)))
-	{
-		for_each(curr_device,chandev_activelist_head)
-		{
-			if(curr_device->read_irqinfo==remove_irqinfo)
-			{
-				curr_device->read_irqinfo=NULL;
-				break;
-			}
-			if(curr_device->write_irqinfo==remove_irqinfo)
-			{
-				curr_device->write_irqinfo=NULL;
-				break;
-			}
-			if(curr_device->data_irqinfo&&curr_device->data_irqinfo==remove_irqinfo)
-			{
-				curr_device->data_irqinfo=NULL;
-				break;
-			}
-		}
-		chandev_free_listmember((list **)&chandev_irqinfo_head,
-					 (list *)remove_irqinfo);
-	}
-	chandev_unlock();
-	
-}
-
-static int chandev_add_schib_info(int irq,chandev_subchannel_info *sch)
-{
-	schib_t *new_schib;
-	
-	if((new_schib=s390_get_schib(irq)))
-	{
-		sch->pim=new_schib->pmcw.pim;
-		memcpy(&sch->chpid,&new_schib->pmcw.chpid,sizeof(sch->chpid));
-		return(0);
-	}
-	return(-ENODEV);
-}
-
-int chandev_request_irq(unsigned int   irq,
-                      void           (*handler)(int, void *, struct pt_regs *),
-                      unsigned long  irqflags,
-                      const char    *devname,
-                      void          *dev_id)
-{
-	chandev_irqinfo *new_irqinfo;
-	chandev_activelist *curr_device;
-	s390_dev_info_t         devinfo;
-	int          retval;
-	
-
-	chandev_lock();
-	if((curr_device=chandev_get_activelist_by_irq(irq)))
-	{
-		printk("chandev_request_irq failed devname=%s irq=%d "
-		       "it already belongs to %s shutdown this device first.\n",
-		       devname,irq,curr_device->devname);
-		chandev_unlock();
-		return(-EPERM);
-	}
-	/* remove any orphan irqinfo left lying around. */
-	chandev_remove_irqinfo_by_irq(irq);
-	chandev_unlock();
-	if((new_irqinfo=chandev_allocstr(devname,offsetof(chandev_irqinfo,devname))))
-	{
-		
-		if((retval=get_dev_info_by_irq(irq,&devinfo))||
-		   (retval=s390_request_irq_special(irq,handler,
-						chandev_not_oper_handler,
-						irqflags,devname,dev_id)))
-			kfree(new_irqinfo);
-		else
-		{
-			new_irqinfo->msck_status=chandev_status_good;
-			new_irqinfo->sch.devno=devinfo.devno;
-			new_irqinfo->sch.irq=irq;
-			new_irqinfo->sch.cu_type=devinfo.sid_data.cu_type; /* control unit type */
-			new_irqinfo->sch.cu_model=devinfo.sid_data.cu_model; /* control unit model */
-			new_irqinfo->sch.dev_type=devinfo.sid_data.dev_type; /* device type */
-			new_irqinfo->sch.dev_model=devinfo.sid_data.dev_model; /* device model */
-			chandev_add_schib_info(irq,&new_irqinfo->sch);
-			new_irqinfo->handler=handler;
-			new_irqinfo->dev_id=dev_id;
-			chandev_add_to_list((list **)&chandev_irqinfo_head,new_irqinfo);
-		}
-	}
-	else
-	{
-		printk("chandev_request_irq memory allocation failed devname=%s irq=%d\n",devname,irq);
-		retval=-ENOMEM;
-	}
-	return(retval);
-}
-
-/* This should be safe to call even multiple times. */
-void chandev_free_irq(unsigned int irq, void *dev_id)
-{
-	s390_dev_info_t devinfo;
-	int err;
-	
-	/* remove any orphan irqinfo left lying around. */
-	chandev_remove_irqinfo_by_irq(irq);
-	if((err=get_dev_info_by_irq(irq,&devinfo)))
-	{
-		printk("chandev_free_irq get_dev_info_by_irq reported err=%X on irq %d\n"
-		       "should not happen\n",err,irq);
-		return;
-	 }
-	if(devinfo.status&DEVSTAT_DEVICE_OWNED)
-	   free_irq(irq,dev_id);
-}
-
-/* This should be safe even if chandev_free_irq is already called by the device */
-static void chandev_free_irq_by_irqinfo(chandev_irqinfo *irqinfo)
-{
-	if(irqinfo)
-		chandev_free_irq(irqinfo->sch.irq,irqinfo->dev_id);
-}
-
-
-
-static void chandev_sprint_type_model(char *buff,s32 type,s16 model)
-{
-	if(type==-1)
-		strcpy(buff,"    *    ");
-	else
-		sprintf(buff," 0x%04x  ",(int)type);
-	buff+=strlen(buff);
-	if(model==-1)
-		strcpy(buff,"    *   ");
-	else
-		sprintf(buff," 0x%02x  ",(int)model);
-}
-
-static void chandev_sprint_devinfo(char *buff,s32 cu_type,s16 cu_model,s32 dev_type,s16 dev_model)
-{
-	chandev_sprint_type_model(buff,cu_type,cu_model);
-	chandev_sprint_type_model(&buff[strlen(buff)],dev_type,dev_model);
-}
-
-static void chandev_remove_parms(chandev_type chan_type,int exact_match,int lo_devno)
-{
-	chandev_parms      *curr_parms,*next_parms;
-
-	chandev_lock();
-	for_each_allow_delete(curr_parms,next_parms,chandev_parms_head)
-	{
-		if(((chan_type&(curr_parms->chan_type)&&!exact_match)||
-		   (chan_type==(curr_parms->chan_type)&&exact_match))&&
-		   (lo_devno==-1||lo_devno==curr_parms->lo_devno))
-			chandev_free_listmember((list **)&chandev_parms_head,(list *)curr_parms);
-	}
-	chandev_unlock();
-}
-
-
-static void chandev_add_parms(chandev_type chan_type,u16 lo_devno,u16 hi_devno,char *parmstr)
-{
-	chandev_parms      *parms;
-
-	if(lo_devno>hi_devno)
-	{
-		printk("chandev_add_parms detected bad device range lo_devno=0x%04x  hi_devno=0x%04x\n,",
-		       (int)lo_devno,(int)hi_devno);
-		return;
-	}
-	chandev_lock();
-	for_each(parms,chandev_parms_head)
-	{
-		if(chan_type&(parms->chan_type))
-		{
-			u16 lomax=MAX(parms->lo_devno,lo_devno),
-				himin=MIN(parms->hi_devno,lo_devno);
-			if(lomax<=himin)
-			{
-				chandev_unlock();
-				printk("chandev_add_parms detected overlapping "
-				       "parameter definitions for chan_type=0x%02x"
-				       " lo_devno=0x%04x  hi_devno=0x%04x\n,"
-				       " do a del_parms.",chan_type,(int)lo_devno,(int)hi_devno);
-				return;
-			}
-		}
-	}
-	chandev_unlock();
-	if((parms=chandev_allocstr(parmstr,offsetof(chandev_parms,parmstr))))
-	{
-		parms->chan_type=chan_type;
-		parms->lo_devno=lo_devno;
-		parms->hi_devno=hi_devno;
-		chandev_add_to_list((list **)&chandev_parms_head,(void *)parms);
-	}
-	else
-		printk("chandev_add_parms memory request failed\n");
-}
-
-
-void chandev_add_model(chandev_type chan_type,s32 cu_type,s16 cu_model,
-		       s32 dev_type,s16 dev_model,u8 max_port_no,int auto_msck_recovery,
-		       u8 default_checksum_received_ip_pkts,u8 default_use_hw_stats)
-{
-	chandev_model_info *newmodel;
-	int                err;
-	char buff[40];
-
-	if((newmodel=chandev_alloc(sizeof(chandev_model_info))))
-	{
-		devreg_t *drinfo=&newmodel->drinfo;
-		newmodel->chan_type=chan_type;
-		newmodel->cu_type=cu_type;
-		newmodel->cu_model=cu_model;
-		newmodel->dev_type=dev_type;
-		newmodel->dev_model=dev_model;
-		newmodel->max_port_no=max_port_no;
-		newmodel->auto_msck_recovery=auto_msck_recovery;
-		newmodel->default_checksum_received_ip_pkts=default_checksum_received_ip_pkts;
-		newmodel->default_use_hw_stats=default_use_hw_stats; /* where available e.g. lcs */
-		if(cu_type==-1&&dev_type==-1)
-		{
-			chandev_sprint_devinfo(buff,newmodel->cu_type,newmodel->cu_model,
-					       newmodel->dev_type,newmodel->dev_model);
-			printk(KERN_INFO"can't call s390_device_register for this device chan_type/chan_model/dev_type/dev_model %s\n",buff);
-			kfree(newmodel);
-			return;
-		}
-		drinfo->flag=DEVREG_TYPE_DEVCHARS;
-		if(cu_type!=-1)
-			drinfo->flag|=DEVREG_MATCH_CU_TYPE;
-		if(cu_model!=-1)
-			drinfo->flag|=DEVREG_MATCH_CU_MODEL;
-		if(dev_type!=-1)
-			drinfo->flag|=DEVREG_MATCH_DEV_TYPE;
-		if(dev_model!=-1)
-			drinfo->flag|=DEVREG_MATCH_DEV_MODEL;
-		drinfo->ci.hc.ctype=cu_type;
-		drinfo->ci.hc.cmode=cu_model;
-		drinfo->ci.hc.dtype=dev_type;
-		drinfo->ci.hc.dmode=dev_model;
-		drinfo->oper_func=chandev_oper_func;
-		if((err=s390_device_register(&newmodel->drinfo)))
-		{
-			chandev_sprint_devinfo(buff,newmodel->cu_type,newmodel->cu_model,
-					       newmodel->dev_type,newmodel->dev_model);
-			printk("s390_device_register failed in chandev_add_model"
-			       " this is nothing to worry about chan_type/chan_model/dev_type/dev_model %s\n",buff);
-			drinfo->oper_func=NULL;
-		}
-		chandev_add_to_list((list **)&chandev_models_head,newmodel);
-	}
-}
-
-
-static void chandev_remove(chandev *member)
-{
-	chandev_free_queuemember(&chandev_head,(queue *)member);
-}
-
-
-static void chandev_remove_all(void)
-{
-	chandev_free_all_queue(&chandev_head);
-}
-
-static void chandev_remove_model(chandev_model_info *model)
-{
-	chandev *curr_chandev,*next_chandev;
-
-	chandev_lock();
-	for_each_allow_delete(curr_chandev,next_chandev,(chandev *)chandev_head.head)
-		if(curr_chandev->model_info==model)
-			chandev_remove(curr_chandev);
-	if(model->drinfo.oper_func)
-		s390_device_unregister(&model->drinfo);
-	chandev_free_listmember((list **)&chandev_models_head,(list *)model);
-	chandev_unlock();
-}
-
-static void chandev_remove_all_models(void)
-{
-	chandev_lock();
-	while(chandev_models_head)
-		chandev_remove_model(chandev_models_head);
-	chandev_unlock();
-}
-
-void chandev_del_model(s32 cu_type,s16 cu_model,s32 dev_type,s16 dev_model)
-{
-	chandev_model_info *curr_model,*next_model;
-	
-	chandev_lock();
-	for_each_allow_delete(curr_model,next_model,chandev_models_head)
-		if((curr_model->cu_type==cu_type||cu_type==-1)&&
-		   (curr_model->cu_model==cu_model||cu_model==-1)&&
-		   (curr_model->dev_type==dev_type||dev_type==-1)&&
-		   (curr_model->dev_model==dev_model||dev_model==-1))
-			chandev_remove_model(curr_model);			
-	chandev_unlock();
-}
-
-static void chandev_init_default_models(void)
-{
-	/* Usually P390/Planter 3172 emulation assume maximum 16 to be safe. */
-	chandev_add_model(chandev_type_lcs,0x3088,0x1,-1,-1,15,default_msck_bits,FALSE,FALSE);	
-
-	/* 3172/2216 Paralell the 2216 allows 16 ports per card the */
-	/* the original 3172 only allows 4 we will assume the max of 16 */
-	chandev_add_model(chandev_type_lcs|chandev_type_ctc,0x3088,0x8,-1,-1,15,default_msck_bits,FALSE,FALSE);
-
-	/* 3172/2216 Escon serial the 2216 allows 16 ports per card the */
-	/* the original 3172 only allows 4 we will assume the max of 16 */
-	chandev_add_model(chandev_type_lcs|chandev_type_escon,0x3088,0x1F,-1,-1,15,default_msck_bits,FALSE,FALSE);
-
-	/* Only 2 ports allowed on OSA2 cards model 0x60 */
-	chandev_add_model(chandev_type_lcs,0x3088,0x60,-1,-1,1,default_msck_bits,FALSE,FALSE);
-	/* qeth gigabit ethernet */
-	chandev_add_model(chandev_type_qeth,0x1731,0x1,0x1732,0x1,0,default_msck_bits,FALSE,FALSE);
-	chandev_add_model(chandev_type_qeth,0x1731,0x5,0x1732,0x5,0,default_msck_bits,FALSE,FALSE);
-	/* Osa-D we currently aren't too emotionally involved with this */
-	chandev_add_model(chandev_type_osad,0x3088,0x62,-1,-1,0,default_msck_bits,FALSE,FALSE);
-	/* claw */
-	chandev_add_model(chandev_type_claw,0x3088,0x61,-1,-1,0,default_msck_bits,FALSE,FALSE);
-
-	/* ficon attached ctc */
-	chandev_add_model(chandev_type_escon,0x3088,0x1E,-1,-1,0,default_msck_bits,FALSE,FALSE);
-}
-
-
-static void chandev_del_noauto(u16 devno)
-{
-	chandev_noauto_range *curr_noauto,*next_noauto;
-	chandev_lock();
-	for_each_allow_delete(curr_noauto,next_noauto,chandev_noauto_head)
-		if(curr_noauto->lo_devno<=devno&&curr_noauto->hi_devno>=devno)
-			chandev_free_listmember((list **)&chandev_noauto_head,(list *)curr_noauto); 
-	chandev_unlock();
-}
-
-static void chandev_del_msck(u16 devno)
-{
-	chandev_msck_range *curr_msck_range,*next_msck_range;
-	chandev_lock();
-	for_each_allow_delete(curr_msck_range,next_msck_range,chandev_msck_range_head)
-		if(curr_msck_range->lo_devno<=devno&&curr_msck_range->hi_devno>=devno)
-			chandev_free_listmember((list **)&chandev_msck_range_head,(list *)curr_msck_range); 
-	chandev_unlock();
-}
-
-
-static void chandev_add(s390_dev_info_t  *newdevinfo,
-			chandev_model_info *newmodelinfo)
-{
-	chandev *new_chandev=NULL;
-
-	if((new_chandev=chandev_alloc(sizeof(chandev))))
-	{
-		new_chandev->model_info=newmodelinfo;
-		new_chandev->sch.devno=newdevinfo->devno;
-		new_chandev->sch.irq=newdevinfo->irq;
-		new_chandev->sch.cu_type=newdevinfo->sid_data.cu_type; /* control unit type */
-		new_chandev->sch.cu_model=newdevinfo->sid_data.cu_model; /* control unit model */
-		new_chandev->sch.dev_type=newdevinfo->sid_data.dev_type; /* device type */
-		new_chandev->sch.dev_model=newdevinfo->sid_data.dev_model; /* device model */
-		chandev_add_schib_info(newdevinfo->irq,&new_chandev->sch);
-		new_chandev->owned=(newdevinfo->status&DEVSTAT_DEVICE_OWNED ? TRUE:FALSE);
-		chandev_queuemember(&chandev_head,new_chandev);
-	}
-}
-
-static void chandev_unregister_probe(chandev_probefunc probefunc)
-{
-	chandev_probelist *curr_probe,*next_probe;
-
-	chandev_lock();
-	for_each_allow_delete(curr_probe,next_probe,chandev_probelist_head)
-		if(curr_probe->probefunc==probefunc)
-			chandev_free_listmember((list **)&chandev_probelist_head,
-						(list *)curr_probe);
-	chandev_unlock();
-}
-
-static void chandev_unregister_probe_by_chan_type(chandev_type chan_type)
-{
-	chandev_probelist *curr_probe,*next_probe;
-
-	chandev_lock();
-	for_each_allow_delete(curr_probe,next_probe,chandev_probelist_head)
-		if(curr_probe->chan_type==chan_type)
-			chandev_free_listmember((list **)&chandev_probelist_head,
-						(list *)curr_probe);
-	chandev_unlock();
-}
-
-
-
-static void chandev_reset(void)
-{
-	chandev_lock();
-	chandev_remove_all_models();
-	chandev_free_all_list((list **)&chandev_noauto_head);
-	chandev_free_all_list((list **)&chandev_msck_range_head);
-	chandev_free_all_list((list **)&chandev_force_head);
-	chandev_remove_parms(-1,FALSE,-1);
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-	chandev_use_devno_names=FALSE;
-#endif
-	chandev_persistent=0;
-	chandev_unlock();
-}
-
-
-static int chandev_is_chandev(int irq,s390_dev_info_t *devinfo,
-		chandev_force **forceinfo,chandev_model_info **ret_model)
-{
-	chandev_force *curr_force;
-	chandev_model_info *curr_model=NULL;
-	int err;
-	int retval=FALSE;
-
-	if(forceinfo)
-		*forceinfo=NULL;
-	if(ret_model)
-		*ret_model=NULL;
-	if((err=get_dev_info_by_irq(irq,devinfo)))
-	{
-		printk("chandev_is_chandev get_dev_info_by_irq reported err=%X on irq %d\n"
-		       "should not happen\n",err,irq);
-			return FALSE;
-	}
-	chandev_lock();
-	
-	for_each(curr_model,chandev_models_head)
-	{
-		if(((curr_model->cu_type==devinfo->sid_data.cu_type)||(curr_model->cu_type==-1))&&
-		   ((curr_model->cu_model==devinfo->sid_data.cu_model)||(curr_model->cu_model==-1))&&
-		   ((curr_model->dev_type==devinfo->sid_data.dev_type)||(curr_model->dev_type==-1))&&
-		   ((curr_model->dev_model==devinfo->sid_data.dev_model)||(curr_model->dev_model==-1)))
-		{
-			retval=TRUE;
-			if(ret_model)
-				*ret_model=curr_model;
-			break;
-		}
-	}
-	for_each(curr_force,chandev_force_head)
-	{
-		if(((curr_force->read_lo_devno==devinfo->devno)&&
-		   (curr_force->write_hi_devno==devinfo->devno)&&
-		    (curr_force->devif_num!=-2))||
-		   ((curr_force->read_lo_devno>=devinfo->devno)&&
-		    (curr_force->write_hi_devno<=devinfo->devno)&&
-		    (curr_force->devif_num==-2)))
-		{
-			if(forceinfo)
-				*forceinfo=curr_force;
-			break;
-		}
-	}
-	chandev_unlock();
-	return(retval);
-}
-
-static void chandev_collect_devices(void)
-{
-	int curr_irq,loopcnt=0;
-	s390_dev_info_t   curr_devinfo;
-	chandev_model_info *curr_model;
-     
-
-	for(curr_irq=get_irq_first();curr_irq>=0; curr_irq=get_irq_next(curr_irq))
-	{
-		/* check read chandev
-		 * we had to do the cu_model check also because ctc devices
-		 * have the same cutype & after asking some people
-		 * the model numbers are given out pseudo randomly so
-		 * we can't just take a range of them also the dev_type & models are 0
-		 */
-		loopcnt++;
-		if(loopcnt>0x10000)
-		{
-			printk(KERN_ERR"chandev_collect_devices detected infinite loop bug in get_irq_next\n");
-			break;
-		}
-		chandev_lock();
-		if(chandev_is_chandev(curr_irq,&curr_devinfo,NULL,&curr_model))
-			chandev_add(&curr_devinfo,curr_model);
-		chandev_unlock();
-	}
-}
-
-static int chandev_add_force(chandev_type chan_type, s32 devif_num,
-			     u16 read_lo_devno, u16 write_hi_devno,
-			     u16 data_devno,s32 memory_usage_in_k,
-			     s16 port_protocol_no,u8 checksum_received_ip_pkts,
-			     u8 use_hw_stats,char *host_name,
-			     char *adapter_name,char *api_type)
-{
-	chandev_force *new_chandev_force;
-	
-	if(devif_num==-2&&read_lo_devno>write_hi_devno)
-	{
-		printk("chandev_add_force detected bad device range lo_devno=0x%04x  hi_devno=0x%04x\n,",
-		       (int)read_lo_devno,(int)write_hi_devno);
-		return(-1);
-	}
-	if(memory_usage_in_k<0)
-	{
-		printk("chandev_add_force memory_usage_in_k is bad\n");
-		return(-1);
-	}
-	if(chan_type==chandev_type_claw)
-	{
-		int host_name_len=strlen(host_name),
-			adapter_name_len=strlen(adapter_name),
-			api_type_len=strlen(api_type);
-		if(host_name_len>=CLAW_NAMELEN||host_name_len==0||
-		   adapter_name_len>=CLAW_NAMELEN||adapter_name_len==0||
-		   api_type_len>=CLAW_NAMELEN||api_type_len==0)
-			return(-1);
-	}
-	if((new_chandev_force=chandev_alloc(sizeof(chandev_force))))
-	{
-		new_chandev_force->chan_type=chan_type;
-		new_chandev_force->devif_num=devif_num;
-		new_chandev_force->read_lo_devno=read_lo_devno;
-		new_chandev_force->write_hi_devno=write_hi_devno;
-		new_chandev_force->data_devno=data_devno;
-		new_chandev_force->memory_usage_in_k=memory_usage_in_k;
-		new_chandev_force->port_protocol_no=port_protocol_no;
-		new_chandev_force->checksum_received_ip_pkts=checksum_received_ip_pkts;
-		new_chandev_force->use_hw_stats=use_hw_stats;
-		
-		if(chan_type==chandev_type_claw)
-		{
-			strcpy(new_chandev_force->claw.host_name,host_name);
-			strcpy(new_chandev_force->claw.adapter_name,adapter_name);
-			strcpy(new_chandev_force->claw.api_type,api_type);
-		}
-		chandev_add_to_list((list **)&chandev_force_head,new_chandev_force);
-	}
-	return(0);
-}
-
-static void chandev_del_force(int read_lo_devno)
-{
-	chandev_force *curr_force,*next_force;
-	
-	chandev_lock();
-	for_each_allow_delete(curr_force,next_force,chandev_force_head)
-	{
-		if(curr_force->read_lo_devno==read_lo_devno||read_lo_devno==-1)
-			chandev_free_listmember((list **)&chandev_force_head,
-						(list *)curr_force);
-	}
-	chandev_unlock();
-}
-
-
-static void chandev_shutdown(chandev_activelist *curr_device)
-{
-	int err=0;
-	chandev_lock();
-
-
-	/* unregister_netdev calls the dev->close so we shouldn't do this */
-	/* this otherwise we crash */
-	if(curr_device->unreg_dev)
-	{
-		curr_device->unreg_dev(curr_device->dev_ptr);
-		curr_device->unreg_dev=NULL;
-	}
-	if(curr_device->shutdownfunc)
-	{
-		err=curr_device->shutdownfunc(curr_device->dev_ptr);
-	}
-	if(err)
-		printk("chandev_shutdown unable to fully shutdown & unload %s err=%d\n"
-		       "probably some upper layer still requires the device to exist\n",
-		       curr_device->devname,err);
-	else
-	{
-		
-		chandev_free_irq_by_irqinfo(curr_device->read_irqinfo);
-		chandev_free_irq_by_irqinfo(curr_device->write_irqinfo);
-		if(curr_device->data_irqinfo)
-			chandev_free_irq_by_irqinfo(curr_device->data_irqinfo);
-		chandev_free_listmember((list **)&chandev_activelist_head,
-				(list *)curr_device);
-	}
-	chandev_unlock();
-}
-
-static void chandev_shutdown_all(void)
-{
-	while(chandev_activelist_head)
-		chandev_shutdown(chandev_activelist_head);
-}
-static void chandev_shutdown_by_name(char *devname)
-{
-	chandev_activelist *curr_device;
-
-	chandev_lock();
-	for_each(curr_device,chandev_activelist_head)
-		if(strcmp(devname,curr_device->devname)==0)
-		{
-			chandev_shutdown(curr_device);
-			break;
-		}
-	chandev_unlock();
-}
-
-static chandev_activelist *chandev_active(u16 devno)
-{
-	chandev_activelist *curr_device;
-
-	for_each(curr_device,chandev_activelist_head)
-		if(curr_device->read_irqinfo->sch.devno==devno||
-		   curr_device->write_irqinfo->sch.devno==devno||
-		   (curr_device->data_irqinfo&&curr_device->data_irqinfo->sch.devno==devno))
-		{
-			return(curr_device);
-		}
-	return(NULL);
-}
-
-static void chandev_shutdown_by_devno(u16 devno)
-{
-	chandev_activelist *curr_device;
-
-	chandev_lock();
-	curr_device=chandev_active(devno);
-	if(curr_device)
-		chandev_shutdown(curr_device);
-	chandev_unlock();
-}
-
-
-static int chandev_pack_args(char *str)
-{
-	char *newstr=str,*next;
-	int strcnt=1;
-
-	while(*str)
-	{
-		next=str+1;
-		/*remove dead spaces */
-		if(isspace(*str)&&isspace(*next))
-		{
-			str++;
-			continue;
-		}
-		if(isspace(*str))
-		{
-			*str=',';
-			goto pack_dn;
-		}
-		if(((*str)==';')&&(*next))
-		{
-			strcnt++;
-			*str=0;
-		}
-	pack_dn:
-		*newstr++=*str++;
-		
-	}
-	*newstr=0;
-	return(strcnt);
-}
-
-typedef enum
-{ 
-	isnull=0,
-	isstr=1,
-	isnum=2,
-	iscomma=4,
-} chandev_strval;
-
-static chandev_strval chandev_strcmp(char *teststr,char **str,long *endlong)
-{
-	char *cur;
-	chandev_strval  retval=isnull;
-
-	int len=strlen(teststr);
-	if(strncmp(teststr,*str,len)==0)
-	{
-		*str+=len;
-		retval=isstr;
-		cur=*str;
-		*endlong=simple_strtol(cur,str,0);
-		if(cur!=*str)
-			retval|=isnum;
-		if(**str==',')
-		{
-			retval|=iscomma;
-			*str+=1;
-		}
-		else if(**str!=0)
-			retval=isnull;
-	}
-	return(retval);
-}
-
-
-int chandev_initdevice(chandev_probeinfo *probeinfo,void *dev_ptr,u8 port_no,char *devname,chandev_category category,chandev_unregfunc unreg_dev)
-{
-	chandev_activelist *newdevice,*curr_device;
-
-	chandev_interrupt_check("chandev_initdevice");
-	if(probeinfo->newdevice!=NULL)
-	{
-		printk("probeinfo->newdevice!=NULL in chandev_initdevice for %s",devname);
-		return(-EPERM);
-	}
-
-
-	chandev_lock();
-	for_each(curr_device,chandev_activelist_head)
-	{
-		if(strcmp(curr_device->devname,devname)==0)
-		{
-			printk("chandev_initdevice detected duplicate devicename %s\n",devname);
-			chandev_unlock();
-			return(-EPERM);
-		}
-	}
-	if((newdevice=chandev_allocstr(devname,offsetof(chandev_activelist,devname))))
-	{
-		newdevice->read_irqinfo=chandev_get_irqinfo_by_irq(probeinfo->read.irq);
-		newdevice->write_irqinfo=chandev_get_irqinfo_by_irq(probeinfo->write.irq);
-		if(probeinfo->data_exists)
-			newdevice->data_irqinfo=chandev_get_irqinfo_by_irq(probeinfo->data.irq);
-		chandev_unlock();
-		if(newdevice->read_irqinfo==NULL||newdevice->write_irqinfo==NULL||
-		   (probeinfo->data_exists&&newdevice->data_irqinfo==NULL))
-		{
-			printk("chandev_initdevice, it appears that chandev_request_irq was not "
-			       "called for devname=%s read_irq=%d write_irq=%d data_irq=%d\n",
-			       devname,probeinfo->read.irq,probeinfo->write.irq,probeinfo->data.irq);
-			kfree(newdevice);
-			return(-EPERM);
-		}
-		newdevice->chan_type=probeinfo->chan_type;		
-		newdevice->dev_ptr=dev_ptr;
-		newdevice->port_no=port_no;
-		newdevice->memory_usage_in_k=probeinfo->memory_usage_in_k;
-		newdevice->category=category;
-		newdevice->unreg_dev=unreg_dev;
-		probeinfo->newdevice=newdevice;
-		return(0);
-	}
-	chandev_unlock();
-	return(-ENOMEM);
-}
-
-
-char *chandev_build_device_name(chandev_probeinfo *probeinfo,char *destnamebuff,char *basename,int buildfullname)
-{
-	if (chandev_use_devno_names&&(!probeinfo->device_forced||probeinfo->devif_num==-1)) 
-		sprintf(destnamebuff,"%s%04x",basename,(int)probeinfo->read.devno);
-	else
-	{
-		if(probeinfo->devif_num==-1)
-		{
-			if(buildfullname)
-			{
-				int idx,len=strlen(basename);
-				
-				chandev_activelist *curr_device;
-				for(idx=0;idx<0xffff;idx++)
-				{
-					for_each(curr_device,chandev_activelist_head)
-					{
-						if(strncmp(curr_device->devname,basename,len)==0)
-						{
-							char numbuff[10];
-							sprintf(numbuff,"%d",idx);
-							if(strcmp(&curr_device->devname[len],numbuff)==0)
-								continue;
-						}
-					}
-					sprintf(destnamebuff,"%s%d",basename,idx);
-					return(destnamebuff);
-				}
-				printk("chandev_build_device_name was usable to build a unique name for %s\n",basename);
-				return(NULL);
-			}
-			else
-				sprintf(destnamebuff,"%s%%d",basename);
-		}
-		else
-		{
-			sprintf(destnamebuff,"%s%d",basename,(int)probeinfo->devif_num);
-		}
-	}
-	return(destnamebuff);
-}
-
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-struct net_device *chandev_init_netdev(chandev_probeinfo *probeinfo,
-			char *basename, struct net_device *dev, int sizeof_priv,
-			struct net_device *(*init_netdevfunc)
-				(struct net_device *dev, int sizeof_priv))
-#else
-struct device *chandev_init_netdev(chandev_probeinfo *probeinfo,
-			char *basename, struct device *dev, int sizeof_priv,
-			struct device *(*init_netdevfunc)
-				(struct device *dev, int sizeof_priv))
-#endif
-{
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-	struct net_device *retdevice=NULL;
-	int new_device = FALSE;
-#else
-	struct device *retdevice=NULL;
-#endif
-	
-
-	chandev_interrupt_check("chandev_init_netdev");
-	if (!init_netdevfunc) 
-	{
-		printk("init_netdevfunc=NULL in chandev_init_netdev, it should not be valid.\n");
-		return NULL;
-	}
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-	/* Allocate a device if one is not provided. */
-        if (dev == NULL) 
-	{
-		/* ensure 32-byte alignment of the private area */
-		int alloc_size = sizeof (*dev) + sizeof_priv + 31;
-
-		dev = (struct net_device *) kmalloc (alloc_size, GFP_KERNEL);
-		if (dev == NULL) 
-		{
-			printk(KERN_ERR "chandev_initnetdevice: Unable to allocate device memory.\n");
-			return NULL;
-		}
-
-		memset(dev, 0, alloc_size);
-
-		if (sizeof_priv)
-			dev->priv = (void *) (((long)(dev + 1) + 31) & ~31);
-		new_device=TRUE;
-	}
-	chandev_build_device_name(probeinfo,dev->name,basename,FALSE);
-#endif
-	retdevice=init_netdevfunc(dev,sizeof_priv);
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-	/* Register device if necessary */
-	/* we need to do this as init_netdev doesn't call register_netdevice */
-	/* for already allocated devices */
-	if (retdevice && new_device)
-		register_netdev(retdevice);
-#endif
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-	/* We allocated it, so we should free it on error */
-	if (!retdevice && new_device) 
-		kfree(dev);
-#endif
-	return retdevice;
-}
-
-
-
-
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-struct net_device *chandev_initnetdevice(chandev_probeinfo *probeinfo,u8 port_no,
-struct net_device *dev, int sizeof_priv, char *basename, 
-struct net_device *(*init_netdevfunc)(struct net_device *dev, int sizeof_priv),
-void (*unreg_netdevfunc)(struct net_device *dev))
-#else
-struct device *chandev_initnetdevice(chandev_probeinfo *probeinfo,u8 port_no,
-struct device *dev, int sizeof_priv, char *basename,
-struct device *(*init_netdevfunc)(struct device *dev, int sizeof_priv),
-void (*unreg_netdevfunc)(struct device *dev))
-#endif
-{
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-	struct net_device *retdevice=NULL;
-	int new_device=(dev==NULL);
-#else
-	struct device *retdevice=NULL;
-#endif
-
-	if (!unreg_netdevfunc) 
-	{
-		printk("unreg_netdevfunc=NULL in chandev_initnetdevice, it should not be valid.\n");
-		return NULL;
-	}
-	chandev_interrupt_check("chandev_initnetdevice");
-	retdevice=chandev_init_netdev(probeinfo,basename,dev,sizeof_priv,init_netdevfunc);
-	if (retdevice) 
-	{
-		if (chandev_initdevice(probeinfo,retdevice,port_no,retdevice->name,
-				      chandev_category_network_device,(chandev_unregfunc)unreg_netdevfunc)) 
-		{
-			unreg_netdevfunc(retdevice);
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-			/* We allocated it, so we should free it on error */
-			if(new_device)
-				kfree(dev);
-#endif
-
-			retdevice = NULL;
-		}
-	}
-	return retdevice;
-}
-
-
-static int chandev_compare_chpid_info(chandev_subchannel_info *chan1,
-				      chandev_subchannel_info *chan2)
-{
-	return (chan1->pim!=chan2->pim || *chan1->chpid!=*chan2->chpid);
-}
-
-static int chandev_compare_cu_dev_info(chandev_subchannel_info *chan1,
-					chandev_subchannel_info *chan2)
-{
-	return ((chan1->cu_type != chan2->cu_type)||
-		(chan1->cu_model != chan2->cu_model)||
-		(chan1->dev_type != chan2->dev_type)||
-		(chan1->dev_model != chan2->dev_model));
-}
-
-static int chandev_compare_subchannel_info(chandev_subchannel_info *chan1,
-					   chandev_subchannel_info *chan2)
-{
-	return((chan1->devno == chan2->devno) &&
-	       (chan1->cu_type == chan2->cu_type) &&
-	       (chan1->cu_model == chan2->cu_model) &&
-	       (chan1->dev_type == chan2->dev_type) &&
-	       (chan1->dev_model == chan2->dev_model) &&
-	       (chan1->pim == chan2->pim) &&
-	       (*chan1->chpid == *chan2->chpid));
-}
-
-
-static int chandev_doprobe(chandev_force *force,chandev *read,
-			   chandev *write,chandev *data)
-{
-	chandev_probelist *probe;
-	chandev_model_info *model_info;
-	chandev_probeinfo probeinfo;
-	int               rc=-1,hint=-1;
-	chandev_activelist *newdevice;
-	chandev_probefunc  probefunc;
-	chandev_parms      *curr_parms;
-	chandev_model_info dummy_model_info;
-
-	memset(&probeinfo,0,sizeof(probeinfo));
-	memset(&dummy_model_info,0,sizeof(dummy_model_info));
-	probeinfo.device_forced=(force!=NULL);
-	probeinfo.chpid_info_inconsistent=chandev_compare_chpid_info(&read->sch,&write->sch)||
-		 (data&&chandev_compare_chpid_info(&read->sch,&data->sch));
-	probeinfo.cu_dev_info_inconsistent=chandev_compare_cu_dev_info(&read->sch,&write->sch)||
-		 (data&&chandev_compare_cu_dev_info(&read->sch,&data->sch));
-	if(read->model_info)
-		model_info=read->model_info;
-	else
-	{
-		dummy_model_info.chan_type=chandev_type_none;
-		dummy_model_info.max_port_no=16;
-		model_info=&dummy_model_info;
-	}
-	for_each(probe,chandev_probelist_head)
-	{
-		if(force)
-			probeinfo.chan_type = ( probe->chan_type & force->chan_type );
-		else
-		{
-			if(chandev_cautious_auto_detect)
-				probeinfo.chan_type = ( probe->chan_type == model_info->chan_type ? 
-						       probe->chan_type : chandev_type_none );
-			else
-				probeinfo.chan_type = ( probe->chan_type & model_info->chan_type );
-		}
-		if(probeinfo.chan_type && (force || ( !probeinfo.cu_dev_info_inconsistent &&
-		  ((probe->chan_type&(chandev_type_ctc|chandev_type_escon)) ||
-		   !probeinfo.chpid_info_inconsistent))))
-		{
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-			if(chandev_use_devno_names)
-				probeinfo.devif_num=read->sch.devno;
-			else
-#endif
-				probeinfo.devif_num=-1;
-			probeinfo.read=read->sch;
-			probeinfo.write=write->sch;
-			if(data)
-			{
-				probeinfo.data=data->sch;
-				probeinfo.data_exists=TRUE;
-			}
-			probeinfo.max_port_no=(force&&(force->port_protocol_no!=-1) ? 
-			      force->port_protocol_no : model_info->max_port_no);
-			for_each(curr_parms,chandev_parms_head)
-			{
-				if(probe->chan_type==curr_parms->chan_type&&
-				   read->sch.devno>=curr_parms->lo_devno&&
-					read->sch.devno<=curr_parms->hi_devno)
-				{
-					probeinfo.parmstr=curr_parms->parmstr;
-					break;
-				}
-			}
-			if(force)
-			{
-				if(force->chan_type==chandev_type_claw)
-					memcpy(&probeinfo.claw,&force->claw,sizeof(chandev_claw_info));
-				probeinfo.port_protocol_no=force->port_protocol_no;
-				if(force->devif_num==-1&&force->devif_num==-2)
-					probeinfo.devif_num=-1;
-				else
-					probeinfo.devif_num=force->devif_num;
-				probeinfo.memory_usage_in_k=force->memory_usage_in_k;
-				probeinfo.checksum_received_ip_pkts=force->checksum_received_ip_pkts;
-				probeinfo.use_hw_stats=force->use_hw_stats;
-			}
-			else
-			{
-				probeinfo.port_protocol_no=0;
-				probeinfo.checksum_received_ip_pkts=model_info->default_checksum_received_ip_pkts;
-				probeinfo.use_hw_stats=model_info->default_use_hw_stats;
-				probeinfo.memory_usage_in_k=0;
-				if(probe->chan_type&chandev_type_lcs)
-				{
-					hint=(read->sch.devno&0xFF)>>1;
-					if(hint>model_info->max_port_no)
-					{
-				/* The card is possibly emulated e.g P/390 */
-				/* or possibly configured to use a shared */
-				/* port configured by osa-sf. */
-						hint=0;
-					}
-				}
-			}
-			probeinfo.hint_port_no=hint;
-			probefunc=probe->probefunc;
-			rc=probefunc(&probeinfo);
-			if(rc==0)
-			{
-				newdevice=probeinfo.newdevice;
-				if(newdevice)
-				{
-					newdevice->probefunc=probe->probefunc;
-					newdevice->shutdownfunc=probe->shutdownfunc;
-					newdevice->msck_notfunc=probe->msck_notfunc;
-					probe->devices_found++;
-					chandev_add_to_list((list **)&chandev_activelist_head,
-							    newdevice);
-					chandev_add_to_userland_notify_list(chandev_start,
-								      newdevice->devname,chandev_status_good,chandev_status_good);
-				}
-				else
-				{
-					printk("chandev_initdevice either failed or wasn't called for device read_irq=0x%04x\n",probeinfo.read.irq);
-				}
-				break;
-				
-			}
-		}
-	}
-	chandev_remove(read);
-	chandev_remove(write);
-	if(data)
-		chandev_remove(data);
-	return(rc);
-}
-
-
-static int chandev_request_irq_from_irqinfo(chandev_irqinfo *irqinfo,chandev *this_chandev)
-{
-	int retval=s390_request_irq_special(irqinfo->sch.irq,
-				   irqinfo->handler,
-				   chandev_not_oper_handler,
-				   irqinfo->irqflags,
-				   irqinfo->devname,
-				   irqinfo->dev_id);
-	if(retval==0)
-	{
-		irqinfo->msck_status=chandev_status_good;
-		this_chandev->owned=TRUE;
-	}
-	return(retval);
-}
-
-static void chandev_irqallocerr(chandev_irqinfo *irqinfo,int err)
-{
-	printk("chandev_probe failed to realloc irq=%d for %s err=%d\n",irqinfo->sch.irq,irqinfo->devname,err);
-}
-
-
-static void chandev_call_notification_func(chandev_activelist *curr_device,
-					   chandev_irqinfo *curr_irqinfo,
-					   chandev_msck_status prevstatus)
-{
-	if(curr_irqinfo->msck_status!=prevstatus)
-	{
-		chandev_msck_status new_msck_status=curr_irqinfo->msck_status;
-		if(curr_irqinfo->msck_status==chandev_status_good)
-		{
-			if(curr_device->read_irqinfo->msck_status==chandev_status_good&&
-			   curr_device->write_irqinfo->msck_status==chandev_status_good)
-			{
-				if(curr_device->data_irqinfo)
-				{
-					if(curr_device->data_irqinfo->msck_status==chandev_status_good)
-						new_msck_status=chandev_status_all_chans_good;
-				}
-				else
-					new_msck_status=chandev_status_all_chans_good;
-			}
-		}
-		if(curr_device->msck_notfunc)
-		{
-			curr_device->msck_notfunc(curr_device->dev_ptr,
-					      curr_irqinfo->sch.irq,
-					      prevstatus,new_msck_status);
-		}
-		if(new_msck_status!=chandev_status_good)
-		{
-			/* No point in sending a machine check if only one channel is good */
-			chandev_add_to_userland_notify_list(chandev_msck,curr_device->devname,
-						      prevstatus,curr_irqinfo->msck_status);
-		}
-	}
-}
-
-static int chandev_find_eligible_channels(chandev *first_chandev_to_check,
-				       chandev **read,chandev **write,
-				       chandev **data,chandev **next,
-				       chandev_type chan_type)
-{
-	chandev *curr_chandev;
-	int eligible_found=FALSE,changed;
-	
-	*next=first_chandev_to_check->next;
-	*read=*write=*data=NULL;
-	for_each(curr_chandev,first_chandev_to_check)
-		if((curr_chandev->sch.devno&1)==0&&curr_chandev->model_info->chan_type!=chandev_type_claw)
-		{
-			*read=curr_chandev;
-			if(chan_type==chandev_type_none)
-				chan_type=(*read)->model_info->chan_type;
-			break;
-		}
-	if(*read)
-	{
-		for_each(curr_chandev,(chandev *)chandev_head.head)
-			if((((*read)->sch.devno|1)==curr_chandev->sch.devno)&&
-			   (chandev_compare_cu_dev_info(&(*read)->sch,&curr_chandev->sch)==0)&&
-			   ((chan_type&(chandev_type_ctc|chandev_type_escon))||
-			    chandev_compare_chpid_info(&(*read)->sch,&curr_chandev->sch)==0))
-			{
-				*write=curr_chandev;
-				break;
-			}
-	}
-	if((chan_type&chandev_type_qeth))
-	{
-		if(*write)
-		{
-			for_each(curr_chandev,(chandev *)chandev_head.head)
-				if((curr_chandev!=*read&&curr_chandev!=*write)&&
-				   (chandev_compare_cu_dev_info(&(*read)->sch,&curr_chandev->sch)==0)&&
-				   (chandev_compare_chpid_info(&(*read)->sch,&curr_chandev->sch)==0))
-				{
-					*data=curr_chandev;
-					break;
-				}
-			if(*data)
-				eligible_found=TRUE;
-		}
-		
-	}
-	else
-		if(*write)
-			eligible_found=TRUE;
-	if(eligible_found)
-	{
-		do
-		{
-			changed=FALSE;
-			if(*next&&
-			   ((*read&&(*read==*next))||
-			   (*write&&(*write==*next))||
-			   (*data&&(*data==*next))))
-			{
-				*next=(*next)->next;
-				changed=TRUE;
-			}
-		}while(changed==TRUE);
-	}
-	return(eligible_found);
-}
-
-static chandev *chandev_get_free_chandev_by_devno(int devno)
-{
-	chandev *curr_chandev;
-	if(devno==-1)
-		return(NULL);
-	for_each(curr_chandev,(chandev *)chandev_head.head)
-		if(curr_chandev->sch.devno==devno)
-		{
-			if(chandev_active(devno))
-				return(NULL);
-			else
-				return(curr_chandev);
-		}
-	return(NULL);
-
-}
-
-static void chandev_probe(void)
-{
-	chandev *read_chandev,*write_chandev,*data_chandev,*curr_chandev,*next_chandev;
-	chandev_force *curr_force;
-	chandev_noauto_range *curr_noauto;
-	chandev_activelist *curr_device;
-	chandev_irqinfo *curr_irqinfo;
-	s390_dev_info_t curr_devinfo;
-	int  err;
-	int auto_msck_recovery;
-	chandev_msck_status prevstatus;
-	chandev_msck_range *curr_msck_range;
-
-
-	chandev_interrupt_check("chandev_probe");
-	chandev_read_conf_if_necessary();
-	chandev_collect_devices();
-	chandev_lock();
-	for_each(curr_irqinfo,chandev_irqinfo_head)
-	{
-		if((curr_device=chandev_get_activelist_by_irq(curr_irqinfo->sch.irq)))
-		{
-			prevstatus=curr_irqinfo->msck_status;
-			if(curr_irqinfo->msck_status!=chandev_status_good)
-			{
-				curr_chandev=chandev_get_by_irq(curr_irqinfo->sch.irq);
-				if(curr_chandev)
-				{
-					auto_msck_recovery=curr_chandev->model_info->
-						auto_msck_recovery;
-				}
-				else
-					goto remove;
-				for_each(curr_msck_range,chandev_msck_range_head)
-				{
-					if(curr_msck_range->lo_devno<=
-					   curr_irqinfo->sch.devno&&
-					   curr_msck_range->hi_devno>=
-					   curr_irqinfo->sch.devno)
-					{
-						auto_msck_recovery=
-							curr_msck_range->
-							auto_msck_recovery;
-						break;
-					}
-				}
-				if((1<<(curr_irqinfo->msck_status-1))&auto_msck_recovery)
-				{
-					if(curr_irqinfo->msck_status==chandev_status_revalidate)
-					{
-						if((get_dev_info_by_irq(curr_irqinfo->sch.irq,&curr_devinfo)==0))
-						{
-							curr_irqinfo->sch.devno=curr_devinfo.devno;
-							curr_irqinfo->msck_status=chandev_status_good;
-						}
-					}
-					else
-					{
-						if(curr_chandev)
-						{
-							/* Has the device reappeared */
-							if(chandev_compare_subchannel_info(
-								&curr_chandev->sch,
-								&curr_device->read_irqinfo->sch)||
-							   chandev_compare_subchannel_info(
-								&curr_chandev->sch,
-								&curr_device->write_irqinfo->sch)||
-							   (curr_device->data_irqinfo&&
-							    chandev_compare_subchannel_info(
-								    &curr_chandev->sch,
-								    &curr_device->data_irqinfo->sch)))
-							{
-								if((err=chandev_request_irq_from_irqinfo(curr_irqinfo,curr_chandev))==0)
-									curr_irqinfo->msck_status=chandev_status_good;
-								else
-									chandev_irqallocerr(curr_irqinfo,err);
-							}
-					
-						}
-					}
-				}
-			}
-			chandev_call_notification_func(curr_device,curr_irqinfo,prevstatus);
-		}
-		/* This is required because the device can go & come back */
-                /* even before we realize it is gone owing to the waits in our kernel threads */
-		/* & the device will be marked as not owned but its status will be good */
-                /* & an attempt to accidentally reprobe it may be done. */ 
-		remove:
-		chandev_remove(chandev_get_by_irq(curr_irqinfo->sch.irq));
-		
-	}
-	/* extra sanity */
-	for_each_allow_delete(curr_chandev,next_chandev,(chandev *)chandev_head.head)
-		if(curr_chandev->owned)
-			chandev_remove(curr_chandev);
-	for_each(curr_force,chandev_force_head)
-	{
-		if(curr_force->devif_num==-2)
-		{
-			for_each_allow_delete2(curr_chandev,next_chandev,(chandev *)chandev_head.head)
-			{
-				if(chandev_find_eligible_channels(curr_chandev,&read_chandev,
-								  &write_chandev,&data_chandev,
-								  &next_chandev,
-								  curr_force->chan_type));
-				{
-					if((curr_force->read_lo_devno>=read_chandev->sch.devno)&&
-					   (curr_force->write_hi_devno<=read_chandev->sch.devno)&&
-					   (curr_force->read_lo_devno>=write_chandev->sch.devno)&&
-					   (curr_force->write_hi_devno<=write_chandev->sch.devno)&&
-					   (!data_chandev||(data_chandev&&
-					   (curr_force->read_lo_devno>=data_chandev->sch.devno)&&
-					   (curr_force->write_hi_devno<=data_chandev->sch.devno))))
-						chandev_doprobe(curr_force,read_chandev,write_chandev,
-								data_chandev);
-				}
-			}
-		}
-		else
-		{
-			read_chandev=chandev_get_free_chandev_by_devno(curr_force->read_lo_devno);
-			if(read_chandev)
-			{
-				write_chandev=chandev_get_free_chandev_by_devno(curr_force->write_hi_devno);
-				if(write_chandev)
-				{
-					if(curr_force->chan_type==chandev_type_qeth)
-					{
-
-						data_chandev=chandev_get_free_chandev_by_devno(curr_force->data_devno);
-						if(data_chandev==NULL)
-							printk("chandev_probe unable to force gigabit_ethernet driver invalid device  no 0x%04x given\n",curr_force->data_devno);
-					}
-					else
-						data_chandev=NULL;
-					chandev_doprobe(curr_force,read_chandev,write_chandev,
-							data_chandev);
-				}
-			}
-		}
-	}
-	for_each_allow_delete(curr_chandev,next_chandev,(chandev *)chandev_head.head)
-	{
-		for_each(curr_noauto,chandev_noauto_head)
-		{
-			if(curr_chandev->sch.devno>=curr_noauto->lo_devno&&
-			   curr_chandev->sch.devno<=curr_noauto->hi_devno)
-			{
-				chandev_remove(curr_chandev);
-				break;
-			}
-		}
-	}
-	for_each_allow_delete2(curr_chandev,next_chandev,(chandev *)chandev_head.head)
-	{
-		if(chandev_find_eligible_channels(curr_chandev,&read_chandev,
-						  &write_chandev,&data_chandev,
-						  &next_chandev,
-						  chandev_type_none))
-			chandev_doprobe(NULL,read_chandev,write_chandev,
-					data_chandev);
-	}
-	chandev_remove_all();
-	chandev_unlock();
-}
-
-static void chandev_not_oper_func(int irq,int status)
-{
-	chandev_irqinfo *curr_irqinfo;
-	chandev_activelist *curr_device;
-	
-	chandev_lock();
-	for_each(curr_irqinfo,chandev_irqinfo_head)
-		if(curr_irqinfo->sch.irq==irq)
-		{
-			chandev_msck_status prevstatus=curr_irqinfo->msck_status;
-			switch(status)
-			{
-				/* Currently defined but not used in kernel */
-				/* Despite being in specs */
-			case DEVSTAT_NOT_OPER:
-				curr_irqinfo->msck_status=chandev_status_not_oper;
-				break;
-#ifdef DEVSTAT_NO_PATH
-				/* Kernel hasn't this defined currently. */
-				/* Despite being in specs */
-			case DEVSTAT_NO_PATH:
-				curr_irqinfo->msck_status=chandev_status_no_path;
-				break;
-#endif
-			case DEVSTAT_REVALIDATE:
-				curr_irqinfo->msck_status=chandev_status_revalidate;
-				break;
-			case DEVSTAT_DEVICE_GONE:
-				curr_irqinfo->msck_status=chandev_status_gone;
-				break;
-                        }
-                        if((curr_device=chandev_get_activelist_by_irq(irq)))
-					chandev_call_notification_func(curr_device,curr_irqinfo,prevstatus);
- 			else
-				printk("chandev_not_oper_func received channel check for unowned irq %d",irq);
-		}
-	chandev_unlock();
-}
-
-
-static int chandev_msck_thread(void *unused)
-{
-	int loopcnt,not_oper_probe_required=FALSE;
-	wait_queue_head_t    wait;
-	chandev_not_oper_struct *new_not_oper;
-
-	/* This loop exists because machine checks tend to come in groups & we have
-           to wait for the other devnos to appear also */
-	init_waitqueue_head(&wait);
-	for(loopcnt=0;loopcnt<10||(jiffies-chandev_last_machine_check)<HZ;loopcnt++)
-	{
-		sleep_on_timeout(&wait,HZ);
-	}
-	atomic_set(&chandev_msck_thread_lock,1);
-	while(!atomic_compare_and_swap(TRUE,FALSE,&chandev_new_msck));
-	{
-		chandev_probe();
-	}
-	while(TRUE)
-	{
-		
-		unsigned long        flags; 
-		spin_lock_irqsave(&chandev_not_oper_spinlock,flags);
-		new_not_oper=(chandev_not_oper_struct *)dequeue_head(&chandev_not_oper_head);
-		spin_unlock_irqrestore(&chandev_not_oper_spinlock,flags);
-		if(new_not_oper)
-		{
-			chandev_not_oper_func(new_not_oper->irq,new_not_oper->status);
-			not_oper_probe_required=TRUE;
-			kfree(new_not_oper);
-		}
-		else
-			break;
-	}
-	if(not_oper_probe_required)
-		chandev_probe();
-	return(0);
-}
-
-static void chandev_msck_task(void *unused)
-{
-	if(kernel_thread(chandev_msck_thread,NULL,SIGCHLD)<0)
-	{
-		atomic_set(&chandev_msck_thread_lock,1);
-		printk("error making chandev_msck_thread kernel thread\n");
-	}
-}
-
-
-
-static char *argstrs[]=
-{
-	"noauto",
-	"del_noauto",
-	"ctc",
-	"escon",
-	"lcs",
-	"osad",
-	"qeth",
-	"claw",
-	"add_parms",
-	"del_parms",
-	"del_force",
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-	"use_devno_names",
-	"dont_use_devno_names",
-#endif
-	"cautious_auto_detect",
-	"non_cautious_auto_detect",
-	"add_model",
-	"del_model",
-	"auto_msck",
-	"del_auto_msck",
-	"del_all_models",
-	"reset_conf_clean",
-	"reset_conf",
-	"shutdown",
-	"reprobe",
-	"unregister_probe",
-	"unregister_probe_by_chan_type",
-	"read_conf",
-	"dont_read_conf",
-	"persist"
-};
-
-typedef enum
-{
-	stridx_mult=256,
-	first_stridx=0,
-	noauto_stridx=first_stridx,
-	del_noauto_stridx,
-	ctc_stridx,
-	escon_stridx,
-	lcs_stridx,
-	osad_stridx,
-        qeth_stridx,
-	claw_stridx,
-	add_parms_stridx,
-	del_parms_stridx,
-	del_force_stridx,
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-	use_devno_names_stridx,
-	dont_use_devno_names_stridx,
-#endif
-	cautious_auto_detect_stridx,
-	non_cautious_auto_detect_stridx,
-	add_model_stridx,
-	del_model_stridx,
-	auto_msck_stridx,
-	del_auto_msck_stridx,
-	del_all_models_stridx,
-	reset_conf_clean_stridx,
-	reset_conf_stridx,
-	shutdown_stridx,
-	reprobe_stridx,
-	unregister_probe_stridx,
-	unregister_probe_by_chan_type_stridx,
-	read_conf_stridx,
-	dont_read_conf_stridx,
-	persist_stridx,
-	last_stridx,
-} chandev_str_enum;
-
-static void chandev_add_noauto(u16 lo_devno,u16 hi_devno)
-{
-	chandev_noauto_range *new_range;
-
-	if((new_range=chandev_alloc(sizeof(chandev_noauto_range))))
-	{
-		new_range->lo_devno=lo_devno;
-		new_range->hi_devno=hi_devno;
-		chandev_add_to_list((list **)&chandev_noauto_head,new_range);
-	}
-}
-
-
-static void chandev_add_msck_range(u16 lo_devno,u16 hi_devno,
-				   int auto_msck_recovery)
-{
-	chandev_msck_range *new_range;
-
-	if((new_range=chandev_alloc(sizeof(chandev_msck_range))))
-	{
-		new_range->lo_devno=lo_devno;
-		new_range->hi_devno=hi_devno;
-		new_range->auto_msck_recovery=auto_msck_recovery;
-		chandev_add_to_list((list **)&chandev_msck_range_head,new_range);
-	}
-}
-
-
-
-static char chandev_keydescript[]=
-"\nchan_type key bitfield ctc=0x1,escon=0x2,lcs=0x4,osad=0x8,qeth=0x10,claw=0x20\n";
-
-
-#if  CONFIG_ARCH_S390X
-/* We need this as we sometimes use this to evaluate pointers */
-typedef long chandev_int; 
-#else
-typedef int chandev_int;
-#endif
-
-
-#if (LINUX_VERSION_CODE<KERNEL_VERSION(2,3,0)) || (CONFIG_ARCH_S390X)
-/*
- * Read an int from an option string; if available accept a subsequent
- * comma as well.
- *
- * Return values:
- * 0 : no int in string
- * 1 : int found, no subsequent comma
- * 2 : int found including a subsequent comma
- */
-static chandev_int chandev_get_option(char **str,chandev_int *pint)
-{
-    char *cur = *str;
-
-    if (!cur || !(*cur)) return 0;
-    *pint = simple_strtol(cur,str,0);
-    if (cur==*str) return 0;
-    if (**str==',') {
-        (*str)++;
-        return 2;
-    }
-
-    return 1;
-}
-
-
-static char *chandev_get_options(char *str, int nints, chandev_int *ints)
-{
-	int res,i=1;
-
-	while (i<nints) 
-	{
-		res = chandev_get_option(&str, ints+i);
-		if (res==0) break;
-		i++;
-		if (res==1) break;
-	}
-	ints[0] = i-1;
-	return(str);
-}
-#else
-#define chandev_get_option get_option
-#define chandev_get_options get_options
-#endif
-/*
- * Read an string from an option string; if available accept a subsequent
- * comma as well & set this comma to a null character when returning the string.
- *
- * Return values:
- * 0 : no string found
- * 1 : string found, no subsequent comma
- * 2 : string found including a subsequent comma
- */
-static int chandev_get_string(char **instr,char **outstr)
-{
-	char *cur = *instr;
-
-	if (!cur ||*cur==0)
-	{
-		*outstr=NULL;
-		return 0;
-	}
-	*outstr=*instr;
-	for(;;)
-	{
-		if(*(++cur)==',')
-		{
-			*cur=0;
-			*instr=cur+1;
-			return 2;
-		}
-		else if(*cur==0)
-		{
-			*instr=cur+1;
-			return 1;
-		}
-	}
-}
-
-
-
-
-static int chandev_setup(int in_read_conf,char *instr,char *errstr,int lineno)
-{
-	chandev_strval   val=isnull;
-	chandev_str_enum stridx;
-	long             endlong;
-	chandev_type     chan_type;
-	char             *str,*currstr,*interpretstr=NULL;
-	int              cnt,strcnt;
-	int              retval=0;
-#define CHANDEV_MAX_EXTRA_INTS 12
-	chandev_int ints[CHANDEV_MAX_EXTRA_INTS+1];
-	currstr=alloca(strlen(instr)+1);
-	strcpy(currstr,instr);
-	strcnt=chandev_pack_args(currstr);
-	for(cnt=1;cnt<=strcnt;cnt++)
-	{
-		interpretstr=currstr;
-		memset(ints,0,sizeof(ints));
-		for(stridx=first_stridx;stridx<last_stridx;stridx++)
-		{
-			str=currstr;
-			if((val=chandev_strcmp(argstrs[stridx],&str,&endlong)))
-				break;
-		}
-		currstr=str;
-		if(val)
-		{
-			val=(((chandev_strval)stridx)*stridx_mult)+(val&~isstr);
-			switch(val)
-			{
-			case (add_parms_stridx*stridx_mult)|iscomma:
-				currstr=chandev_get_options(currstr,4,ints);
-				if(*currstr&&ints[0]>=1)
-				{
-					if(ints[0]==1)
-					{
-						ints[2]=0;
-						ints[3]=0xffff;
-					}
-					else if(ints[0]==2)
-						ints[3]=ints[2];
-					chandev_add_parms(ints[1],ints[2],ints[3],currstr);
-					goto NextOption;
-				}
-				else
-					goto BadArgs;
-				break;
-			case (claw_stridx*stridx_mult)|isnum|iscomma:
-			case (claw_stridx*stridx_mult)|iscomma:
-				currstr=chandev_get_options(str,6,ints);
-				break;
-			default:
-				if(val&iscomma)
-					currstr=chandev_get_options(str,CHANDEV_MAX_EXTRA_INTS,ints);
-				break;
-			}
-			switch(val)
-			{
-			case noauto_stridx*stridx_mult:
-			case (noauto_stridx*stridx_mult)|iscomma:
-				switch(ints[0])
-				{
-				case 0: 
-					chandev_free_all_list((list **)&chandev_noauto_head);
-					chandev_add_noauto(0,0xffff);
-					break;
-				case 1:
-					ints[2]=ints[1];
-				case 2:
-					chandev_add_noauto(ints[1],ints[2]);
-					break;
-				default:
-					goto BadArgs;
-				}
-				break;
-			case (auto_msck_stridx*stridx_mult)|iscomma:
-				switch(ints[0])
-				{
-				case 1:
-					chandev_free_all_list((list **)&chandev_msck_range_head);
-					chandev_add_msck_range(0,0xffff,ints[1]);
-					break;
-				case 2:
-					chandev_add_msck_range(ints[1],ints[1],ints[2]);
-					break;
-				case 3:
-					chandev_add_msck_range(ints[1],ints[2],ints[3]);
-					break;
-				default:
-					goto BadArgs;
-					
-				}
-			case del_auto_msck_stridx*stridx_mult:
-			case (del_auto_msck_stridx*stridx_mult)|iscomma:
-				switch(ints[0])
-				{
-				case 0:
-					chandev_free_all_list((list **)&chandev_msck_range_head);
-					break;
-				case 1:
-					chandev_del_msck(ints[1]);
-				default:
-					goto BadArgs;
-				}
-			case del_noauto_stridx*stridx_mult:
-				chandev_free_all_list((list **)&chandev_noauto_head);
-				break;
-			case (del_noauto_stridx*stridx_mult)|iscomma:
-				if(ints[0]==1)
-					chandev_del_noauto(ints[1]);
-				else
-					goto BadArgs;
-				break;
-			case (qeth_stridx*stridx_mult)|isnum|iscomma:
-				if(ints[0]<3||ints[0]>7)
-					goto BadArgs;
-				chandev_add_force(chandev_type_qeth,endlong,ints[1],ints[2],
-						  ints[3],ints[4],ints[5],ints[6],ints[7],
-						  NULL,NULL,NULL);
-				break;
-			case (ctc_stridx*stridx_mult)|isnum|iscomma:
-			case (escon_stridx*stridx_mult)|isnum|iscomma:
-			case (lcs_stridx*stridx_mult)|isnum|iscomma:
-			case (osad_stridx*stridx_mult)|isnum|iscomma:
-			case (ctc_stridx*stridx_mult)|iscomma:
-			case (escon_stridx*stridx_mult)|iscomma:
-			case (lcs_stridx*stridx_mult)|iscomma:
-			case (osad_stridx*stridx_mult)|iscomma:
-				switch(val&~(isnum|iscomma))
-				{
-				case (ctc_stridx*stridx_mult):
-					chan_type=chandev_type_ctc;
-					break;
-				case (escon_stridx*stridx_mult):
-					chan_type=chandev_type_escon;
-					break;
-				case (lcs_stridx*stridx_mult):
-					chan_type=chandev_type_lcs;
-					break;
-				case (osad_stridx*stridx_mult):
-					chan_type=chandev_type_osad;
-					break;
-				case (qeth_stridx*stridx_mult):
-					chan_type=chandev_type_qeth;
-					break;
-				default:
-					goto BadArgs;
-				}
-				if((val&isnum)==0)
-					endlong=-2;
-				if(ints[0]<2||ints[0]>6)
-					goto BadArgs;
-				chandev_add_force(chan_type,endlong,ints[1],ints[2],
-						  0,ints[3],ints[4],ints[5],ints[6],
-						  NULL,NULL,NULL);
-				break;
-			case (claw_stridx*stridx_mult)|isnum|iscomma:
-			case (claw_stridx*stridx_mult)|iscomma:
-				if(ints[0]>=2&&ints[0]<=5)
-				{
-					char    *host_name,*adapter_name,*api_type;
-					char    *clawstr=alloca(strlen(currstr)+1);
-					
-					strcpy(clawstr,currstr);
-					if(!(chandev_get_string(&clawstr,&host_name)==2&&
-					     chandev_get_string(&clawstr,&adapter_name)==2&&
-					     chandev_get_string(&clawstr,&api_type)==1&&
-					     chandev_add_force(chandev_type_claw,
-							       endlong,ints[1],ints[2],0,
-							       ints[3],0,ints[4],ints[5],
-							       host_name,adapter_name,api_type)==0))
-						goto BadArgs;
-						
-				}
-				else
-					goto BadArgs;
-				break;
-			case (del_parms_stridx*stridx_mult):
-				ints[1]=-1;
-			case (del_parms_stridx*stridx_mult)|iscomma:
-				if(ints[0]==0)
-					ints[1]=-1;
-				if(ints[0]<=1)
-					ints[2]=FALSE;
-				if(ints[0]<=2)
-					ints[3]=-1;
-				if(ints[0]>3)
-					goto BadArgs;
-				chandev_remove_parms(ints[1],ints[2],ints[3]);
-				break;
-			case (del_force_stridx*stridx_mult)|iscomma:
-				if(ints[0]!=1)
-					goto BadArgs;
-				chandev_del_force(ints[1]);
-				break;
-			case (del_force_stridx*stridx_mult):
-				chandev_del_force(-1);
-				break;
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-			case (use_devno_names_stridx*stridx_mult):
-				chandev_use_devno_names=TRUE;
-				break;
-			case (dont_use_devno_names_stridx*stridx_mult):
-				chandev_use_devno_names=FALSE;
-				break;
-#endif
-			case (cautious_auto_detect_stridx*stridx_mult):
-				chandev_cautious_auto_detect=TRUE;
-				break;
-			case (non_cautious_auto_detect_stridx*stridx_mult):
-				chandev_cautious_auto_detect=FALSE;
-				break;
-			case (add_model_stridx*stridx_mult)|iscomma:
-				if(ints[0]<3)
-					goto BadArgs;
-				if(ints[0]==3)
-					ints[4]=-1;
-				if(ints[0]<=4)
-					ints[5]=-1;
-				if(ints[0]<=5)
-					ints[6]=-1;
-				if(ints[0]<=6)
-					ints[7]=default_msck_bits;
-				if(ints[0]<=7)
-					ints[8]=FALSE;
-				if(ints[0]<=8)
-					ints[9]=FALSE;
-				ints[0]=7;
-				chandev_add_model(ints[1],ints[2],ints[3],
-						  ints[4],ints[5],ints[6],ints[7],ints[8],ints[9]);
-				break;
-			case (del_model_stridx*stridx_mult)|iscomma:
-				if(ints[0]<2||ints[0]>4)
-					goto BadArgs;
-				if(ints[0]<3)
-					ints[3]=-2;
-				if(ints[0]<4)
-					ints[4]=-2;
-				ints[0]=4;
-				chandev_del_model(ints[1],ints[2],ints[3],ints[4]);
-				break;
-			case del_all_models_stridx*stridx_mult:
-				chandev_remove_all_models();
-				break;
-			case reset_conf_stridx*stridx_mult:
-				chandev_reset();
-				chandev_init_default_models();
-				break;
-			case reset_conf_clean_stridx*stridx_mult:
-				chandev_reset();
-				break;
-			case shutdown_stridx*stridx_mult:
-				chandev_shutdown_all();
-				break;
-			case (shutdown_stridx*stridx_mult)|iscomma:
-				switch(ints[0])
-				{
-				case 0:
-					if(strlen(str))
-						chandev_shutdown_by_name(str);
-					else
-						goto BadArgs;
-					break;
-				case 1:
-					chandev_shutdown_by_devno(ints[1]);
-					break;
-				default:
-					goto BadArgs;
-				}
-				break;
-			case reprobe_stridx*stridx_mult:
-				chandev_probe();
-				break;
-			case unregister_probe_stridx*stridx_mult:
-				chandev_free_all_list((list **)&chandev_probelist_head);
-				break;
-			case (unregister_probe_stridx*stridx_mult)|iscomma:
-				if(ints[0]!=1)
-					goto BadArgs;
-				chandev_unregister_probe((chandev_probefunc)ints[1]);
-				break;
-			case (unregister_probe_by_chan_type_stridx*stridx_mult)|iscomma:
-				if(ints[0]!=1)
-					goto BadArgs;
-				chandev_unregister_probe_by_chan_type((chandev_type)ints[1]);
-				break;
-			case read_conf_stridx*stridx_mult:
-				if(in_read_conf)
-				{
-					printk("attempt to recursively call read_conf\n");
-					goto BadArgs;
-				}
-				chandev_read_conf();
-				break;
-			case dont_read_conf_stridx*stridx_mult:
-				atomic_set(&chandev_conf_read,TRUE);
-				break;
-			case (persist_stridx*stridx_mult)|iscomma:
-				if(ints[0]==1)
-					chandev_persistent=ints[1];
-				else
-					goto BadArgs;
-				break;
-			default:
-				goto BadArgs;
-			}
-		}
-		else
-			goto BadArgs;
-	NextOption:
-		if(cnt<strcnt)
-		{
-			/* eat up stuff till next string */
-			while(*(currstr++));
-		}
-	}
-	retval=1;
- BadArgs:
-	if(!retval)
-	{
-		printk("chandev_setup %s %s",(val==0 ? "unknown verb":"bad argument"),instr);
-		if(errstr)
-		{
-			printk("%s %d interpreted as %s",errstr,lineno,interpretstr);
-			if(strcnt>1)
-			{
-				if(cnt==strcnt)
-					printk(" after the last semicolon\n");
-				else
-					printk(" before semicolon no %d",cnt);
-			}
-		}
-		printk(".\n Type man chandev for more info.\n\n");
-	}
-	return(retval);
-}
-#define CHANDEV_KEYWORD "chandev="
-static int chandev_setup_bootargs(char *str,int paramno)
-{
-	int len;
-
-	char *copystr;
-	for(len=0;str[len]!=0&&!isspace(str[len]);len++);
-	copystr=alloca(len+1);
-	strncpy(copystr,str,len);
-	copystr[len]=0;
-	if(chandev_setup(FALSE,copystr,"at "CHANDEV_KEYWORD" bootparam no",paramno)==0)
-		return(0);
-	return(len);
-
-}
-
-/*
-  We can't parse using a __setup function as kmalloc isn't available
-  at this time.
- */
-static void __init chandev_parse_args(void)
-{
-#define CHANDEV_KEYWORD "chandev="
-	extern char saved_command_line[];
-	int cnt,len,paramno=1;
-
-	len=strlen(saved_command_line)-sizeof(CHANDEV_KEYWORD);
-	for(cnt=0;cnt<len;cnt++)
-	{
-		if(strncmp(&saved_command_line[cnt],CHANDEV_KEYWORD,
-			   sizeof(CHANDEV_KEYWORD)-1)==0)
-		{
-			cnt+=(sizeof(CHANDEV_KEYWORD)-1);	
-			cnt+=chandev_setup_bootargs(&saved_command_line[cnt],paramno);
-			paramno++;
-		}
-	}
-}
-
-static int chandev_do_setup(int in_read_conf,char *buff,int size)
-{
-	int curr,comment=FALSE,newline=FALSE,oldnewline=TRUE;
-	char *startline=NULL,*endbuff=&buff[size];
-
-	int lineno=0;
-
-	*endbuff=0;
-	for(;buff<=endbuff;curr++,buff++)
-	{
-		if(*buff==0xa||*buff==0xc||*buff==0)
-		{
-			if(*buff==0xa||*buff==0)
-				lineno++;
-			*buff=0;
-			newline=TRUE;
-		}
-		else
-		{ 
-			newline=FALSE;
-			if(*buff=='#')
-				comment=TRUE;
-		}
-		if(comment==TRUE)
-			*buff=0;
-		if(startline==NULL&&isalpha(*buff))
-			startline=buff;
-		if(startline&&(buff>startline)&&(oldnewline==FALSE)&&(newline==TRUE))
-		{
-			if((chandev_setup(in_read_conf,startline," on line no",lineno))==0)
-				return(-EINVAL);
-			startline=NULL;
-		}
-		if(newline)
-			comment=FALSE;
-	        oldnewline=newline;
-	}
-	return(0);
-}
-
-
-static void chandev_read_conf(void)
-{
-#define CHANDEV_FILE "/etc/chandev.conf"
-	struct stat statbuf;
-	char        *buff;
-	int         curr,left,len,fd;
-	mm_segment_t oldfs;
-
-	/* if called from chandev_register_and_probe & 
-	   the driver is compiled into the kernel the
-	   parameters will need to be passed in from
-	   the kernel boot parameter line as the root
-	   fs is not mounted yet, we can't wait here.
-	*/
-	if(in_interrupt()||current->fs->root==NULL)
-		return;
-	atomic_set(&chandev_conf_read,TRUE);
-	oldfs = get_fs();
-	set_fs(KERNEL_DS);
-	if(stat(CHANDEV_FILE,&statbuf)==0)
-	{
-		set_fs(USER_DS);
-		buff=vmalloc(statbuf.st_size+1);
-		if(buff)
-		{
-			set_fs(KERNEL_DS);
-			if((fd=open(CHANDEV_FILE,O_RDONLY,0))!=-1)
-			{
-				curr=0;
-				left=statbuf.st_size;
-				while((len=read(fd,&buff[curr],left))>0)
-				{
-					curr+=len;
-					left-=len;
-				}
-				close(fd);
-			}
-			set_fs(USER_DS);
-			chandev_do_setup(TRUE,buff,statbuf.st_size);
-			vfree(buff);
-		}
-	}
-	set_fs(oldfs);
-}
-
-static void chandev_read_conf_if_necessary(void)
-{
-	if(in_interrupt()||current->fs->root==NULL)
-		return;
-	if(!atomic_compare_and_swap(FALSE,TRUE,&chandev_conf_read))
-		chandev_read_conf();
-}
-
-#ifdef CONFIG_PROC_FS
-#define chandev_printf(exitchan,args...)     \
-splen=sprintf(spbuff,##args);                \
-spoffset+=splen;                             \
-if(spoffset>offset) {                        \
-       spbuff+=splen;                        \
-       currlen+=splen;                       \
-}                                            \
-if(currlen>=length)                          \
-       goto exitchan;
-
-static void sprintf_msck(char *buff,int auto_msck_recovery)
-{
-	chandev_msck_status idx;
-	int first_time=TRUE;
-	buff[0]=0;
-	for(idx=chandev_status_first_msck;idx<chandev_status_last_msck;idx++)
-	{
-		if((1<<(idx-1))&auto_msck_recovery)
-		{
-			buff+=sprintf(buff,"%s%s",(first_time ? "":","),
-				      msck_status_strs[idx]);
-			first_time=FALSE;
-		}
-	}
-}
-
-static int chandev_read_proc(char *page, char **start, off_t offset,
-			  int length, int *eof, void *data)
-{
-	char *spbuff=*start=page;
-	int    currlen=0,splen=0;
-	off_t  spoffset=0;
-	chandev_model_info *curr_model;
-	chandev_noauto_range *curr_noauto;
-	chandev_force *curr_force;
-	chandev_activelist *curr_device;
-	chandev_probelist  *curr_probe;
-	chandev_msck_range *curr_msck_range;
-	s390_dev_info_t   curr_devinfo;
-	int pass,chandevs_detected,curr_irq,loopcnt;
-	chandev_irqinfo *read_irqinfo,*write_irqinfo,*data_irqinfo;
-	char buff[3][80];    
-
-	chandev_lock();
-	chandev_printf(chan_exit,"\n%s\n"
-		       "*'s for cu/dev type/models indicate don't cares\n",chandev_keydescript);
-	chandev_printf(chan_exit,"\ncautious_auto_detect: %s\n",chandev_cautious_auto_detect ? "on":"off");
-	chandev_printf(chan_exit,"\npersist = 0x%02x\n",chandev_persistent);
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-	chandev_printf(chan_exit,"\nuse_devno_names: %s\n\n",chandev_use_devno_names ? "on":"off");
-#endif
-	
-	if(chandev_models_head)
-	{
-		chandev_printf(chan_exit,"Channels enabled for detection\n");      
-		chandev_printf(chan_exit,"  chan     cu      cu     dev   dev    max     checksum  use hw  auto recovery\n");
-		chandev_printf(chan_exit,"  type    type    model  type  model  port_no. received   stats      type\n");
-		chandev_printf(chan_exit,"==============================================================================\n");
-		for_each(curr_model,chandev_models_head)
-		{
-			
-			
-			chandev_sprint_devinfo(buff[0],curr_model->cu_type,
-					       curr_model->cu_model,
-					       curr_model->dev_type,
-					       curr_model->dev_model);
-			sprintf_msck(buff[1],curr_model->auto_msck_recovery);
-			chandev_printf(chan_exit,"  0x%02x  %s%3d %s     %s     %s\n",
-				       curr_model->chan_type,buff[0],
-				       (int)curr_model->max_port_no,
-				       curr_model->default_checksum_received_ip_pkts ? "yes":"no ",
-				       curr_model->default_use_hw_stats ? "yes":"no ",
-				       buff[1]);         
-		}
-	}
-        
-	if(chandev_noauto_head)
-	{
-		chandev_printf(chan_exit,"\nNo auto devno ranges\n");
-		chandev_printf(chan_exit,"   From        To   \n");
-		chandev_printf(chan_exit,"====================\n");
-		for_each(curr_noauto,chandev_noauto_head)
-		{
-			chandev_printf(chan_exit,"  0x%04x     0x%04x\n",
-				       curr_noauto->lo_devno,
-				       curr_noauto->hi_devno);
-		}
-	}
-	if(chandev_msck_range_head)
-	{
-		
-		chandev_printf(chan_exit,"\nAutomatic machine check recovery devno ranges\n");
-		chandev_printf(chan_exit,"   From        To   automatic recovery type\n");
-		chandev_printf(chan_exit,"===========================================\n");
-		for_each(curr_msck_range,chandev_msck_range_head)
-		{
-			sprintf_msck(buff[0],curr_msck_range->auto_msck_recovery);
-			chandev_printf(chan_exit,"  0x%04x     0x%04x %s\n",
-				       curr_msck_range->lo_devno,
-				       curr_msck_range->hi_devno,buff[0])
-		}
-	}
-	if(chandev_force_head)
-	{
-		chandev_printf(chan_exit,"\nForced devices\n");
-		chandev_printf(chan_exit,"  chan defif read   write  data   memory      port         ip    hw   host       adapter   api\n");
-		chandev_printf(chan_exit,"  type  num  devno  devno  devno  usage(k) protocol no.  chksum stats name        name     name\n");
-		chandev_printf(chan_exit,"===============================================================================================\n");
-		for_each(curr_force,chandev_force_head)
-		{
-			if(curr_force->memory_usage_in_k==0)
-				strcpy(buff[0],"default");
-			else
-				sprintf(buff[0],"%6d",curr_force->memory_usage_in_k);
-			chandev_printf(chan_exit,"  0x%02x  %3d  0x%04x 0x%04x 0x%04x %7s       %3d       %1d    %1d%s",
-				       (int)curr_force->chan_type,(int)curr_force->devif_num,
-				       (int)curr_force->read_lo_devno,(int)curr_force->write_hi_devno,
-				       (int)curr_force->data_devno,buff[0],
-				       (int)curr_force->port_protocol_no,(int)curr_force->checksum_received_ip_pkts,
-				       (int)curr_force->use_hw_stats,curr_force->chan_type==chandev_type_claw ? "":"\n");
-			if(curr_force->chan_type==chandev_type_claw)
-			{
-				chandev_printf(chan_exit," %9s %9s %9s\n",
-					       curr_force->claw.host_name,
-					       curr_force->claw.adapter_name,
-					       curr_force->claw.api_type);
-			}
-
-		}
-	}
-	if(chandev_probelist_head)
-	{
-#if CONFIG_ARCH_S390X
-		chandev_printf(chan_exit,"\nRegistered probe functions\n"
-			       		 "probefunc            shutdownfunc        msck_notfunc        chan  devices devices\n"
-                                         "                                                             type   found  active\n"
-			                 "==================================================================================\n");
-#else
-		chandev_printf(chan_exit,"\nRegistered probe functions\n"
-			                 "probefunc   shutdownfunc   msck_notfunc   chan  devices devices\n"
-                                         "                                          type   found  active\n"
-			                 "===============================================================\n");
-#endif
-		for_each(curr_probe,chandev_probelist_head)
-		{
-			int devices_active=0;
-			for_each(curr_device,chandev_activelist_head)
-			{
-				if(curr_device->probefunc==curr_probe->probefunc)
-					devices_active++;
-			}
-			chandev_printf(chan_exit,"0x%p   0x%p   0x%p       0x%02x     %d      %d\n",
-				       curr_probe->probefunc,
-				       curr_probe->shutdownfunc,
-				       curr_probe->msck_notfunc,
-				       curr_probe->chan_type,
-				       curr_probe->devices_found,
-				       devices_active);
-		}
-	}
-	if(chandev_activelist_head)
-	{
-		unsigned long long total_memory_usage_in_k=0;
-		chandev_printf(chan_exit,
-			       "\nInitialised Devices\n"
-			       " read   write  data  read   write  data  chan port  dev     dev         memory   read msck    write msck    data msck\n"
-			       " irq     irq    irq  devno  devno  devno type no.   ptr     name        usage(k)  status       status        status\n"
-			       "=====================================================================================================================\n");
-		/* We print this list backwards for cosmetic reasons */
-		for(curr_device=chandev_activelist_head;
-		    curr_device->next!=NULL;curr_device=curr_device->next);
-		while(curr_device)
-		{
-			read_irqinfo=curr_device->read_irqinfo;
-			write_irqinfo=curr_device->write_irqinfo;
-			data_irqinfo=curr_device->data_irqinfo;
-			if(data_irqinfo)
-			{
-				sprintf(buff[0],"0x%04x",data_irqinfo->sch.irq);
-				sprintf(buff[1],"0x%04x",(int)data_irqinfo->sch.devno);
-			}
-			else
-			{
-				strcpy(buff[0],"  n/a ");
-				strcpy(buff[1],"  n/a ");
-			}
-			if(curr_device->memory_usage_in_k<0)
-			{
-				sprintf(buff[2],"%d",(int)-curr_device->memory_usage_in_k);
-				total_memory_usage_in_k-=curr_device->memory_usage_in_k;
-			}
-			else
-				strcpy(buff[2],"  n/a ");
-			chandev_printf(chan_exit,
-				       "0x%04x 0x%04x %s 0x%04x 0x%04x %s 0x%02x %2d 0x%p %-10s  %6s   %-12s %-12s %-12s\n",
-				       read_irqinfo->sch.irq,
-				       write_irqinfo->sch.irq,
-				       buff[0],
-				       (int)read_irqinfo->sch.devno,
-				       (int)write_irqinfo->sch.devno,
-				       buff[1],
-				       curr_device->chan_type,(int)curr_device->port_no,
-				       curr_device->dev_ptr,curr_device->devname,
-				       buff[2],
-				       msck_status_strs[read_irqinfo->msck_status],
-				       msck_status_strs[write_irqinfo->msck_status],
-				       data_irqinfo ? msck_status_strs[data_irqinfo->msck_status] :
-				       "not applicable");
-			get_prev((list *)chandev_activelist_head,
-				 (list *)curr_device,
-				 (list **)&curr_device);
-		}
-		chandev_printf(chan_exit,"\nTotal device memory usage %Luk.\n",total_memory_usage_in_k);
-	}
-	chandevs_detected=FALSE;
-	for(pass=FALSE;pass<=TRUE;pass++)
-	{
-		if(pass&&chandevs_detected)
-		{
-			chandev_printf(chan_exit,"\nchannels detected\n");
-			chandev_printf(chan_exit,"              chan    cu    cu   dev    dev                          in chandev\n");
-			chandev_printf(chan_exit,"  irq  devno  type   type  model type  model pim      chpids         use  reg.\n");
-			chandev_printf(chan_exit,"===============================================================================\n");
-		}
-		for(curr_irq=get_irq_first(),loopcnt=0;curr_irq>=0; curr_irq=get_irq_next(curr_irq),loopcnt++)
-		{
-			if(loopcnt>0x10000)
-			{
-				printk(KERN_ERR"chandev_read_proc detected infinite loop bug in get_irq_next\n");
-				goto chan_error;
-			}
-			if(chandev_is_chandev(curr_irq,&curr_devinfo,&curr_force,&curr_model))
-			{
-				schib_t *curr_schib;
-				curr_schib=s390_get_schib(curr_irq);
-				chandevs_detected=TRUE;
-				if(pass)
-				{
-					chandev_printf(chan_exit,"0x%04x 0x%04x 0x%02x  0x%04x 0x%02x  0x%04x 0x%02x 0x%02x 0x%016Lx  %-5s%-5s\n",
-						       curr_irq,curr_devinfo.devno,
-						       ( curr_force ? curr_force->chan_type : 
-						       ( curr_model ? curr_model->chan_type : 
-							 chandev_type_none )),
-						       (int)curr_devinfo.sid_data.cu_type,
-						       (int)curr_devinfo.sid_data.cu_model,
-						       (int)curr_devinfo.sid_data.dev_type,
-						       (int)curr_devinfo.sid_data.dev_model,
-						       (int)(curr_schib ? curr_schib->pmcw.pim : 0),
-						       *(long long *)(curr_schib ? &curr_schib->pmcw.chpid[0] : 0),
-						       (curr_devinfo.status&DEVSTAT_DEVICE_OWNED) ? "yes":"no ",
-						       (chandev_get_irqinfo_by_irq(curr_irq) ? "yes":"no "));
-						       
-						       
-				}
-					
-			}
-
-		}
-	}
-	if(chandev_parms_head)
-	{
-		chandev_parms      *curr_parms;
-
-		chandev_printf(chan_exit,"\n driver specific parameters\n");
-		chandev_printf(chan_exit,"chan    lo    hi      driver\n");
-		chandev_printf(chan_exit,"type  devno  devno  parameters\n");
-		chandev_printf(chan_exit,"=============================================================================\n");
-		for_each(curr_parms,chandev_parms_head)
-		{
-			chandev_printf(chan_exit,"0x%02x 0x%04x 0x%04x  %s\n",
-				       curr_parms->chan_type,(int)curr_parms->lo_devno,
-				       (int)curr_parms->hi_devno,curr_parms->parmstr);
-		}
-	}
- chan_error:
-	*eof=TRUE;
- chan_exit:
-	if(currlen>length) {
-		/* rewind to previous printf so that we are correctly
-		 * aligned if we get called to print another page.
-                 */
-		currlen-=splen;
-	}
-	chandev_unlock();
-	return(currlen);
-}
-
-
-static int chandev_write_proc(struct file *file, const char *buffer,
-			   unsigned long count, void *data)
-{
-	int         rc;
-	char        *buff;
-	
-	if ((buff=vmalloc(count+1)) == 0)
-		return -ENOMEM;
-	
-	if (copy_from_user(buff,buffer,count) == 0) {
-		chandev_do_setup(FALSE,buff,count);
-		rc=count;
-	} else {
-		rc=-EFAULT;
-	}
-
-	vfree(buff);
-
-	return rc;
-}
-
-static void __init chandev_create_proc(void)
-{
-	struct proc_dir_entry *dir_entry=
-		create_proc_entry("chandev",0644,
-				  &proc_root);
-	if(dir_entry)
-	{
-		dir_entry->read_proc=&chandev_read_proc;
-		dir_entry->write_proc=&chandev_write_proc;
-	}
-}
-
-
-#endif
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-static  
-#endif
-int __init chandev_init(void)
-{
-	atomic_set(&chandev_initialised,TRUE);
-	chandev_parse_args();
-	chandev_init_default_models();
-#if CONFIG_PROC_FS
-	chandev_create_proc();
-#endif
-	chandev_last_startmsck_list_update=chandev_last_machine_check=jiffies-HZ;
-	atomic_set(&chandev_msck_thread_lock,1);
-	chandev_lock_owner=CHANDEV_INVALID_LOCK_OWNER;
-	chandev_lock_cnt=0;
-	spin_lock_init(&chandev_spinlock);
-	spin_lock_init(&chandev_not_oper_spinlock);
-	atomic_set(&chandev_new_msck,FALSE);
-	return(0);
-}
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-__initcall(chandev_init);
-#endif
-
-int chandev_register_and_probe(chandev_probefunc probefunc,
-			       chandev_shutdownfunc shutdownfunc,
-			       chandev_msck_notification_func msck_notfunc,
-			       chandev_type chan_type)
-{
-	chandev_probelist *new_probe,*curr_probe;
-	/* Avoid chicked & egg situations where we may be called before we */
-	/* are initialised. */
-
-	chandev_interrupt_check("chandev_register_and_probe");
-	if(!atomic_compare_and_swap(FALSE,TRUE,&chandev_initialised))
-		chandev_init();
-	chandev_lock();
-	for_each(curr_probe,chandev_probelist_head)
-	{
-		if(curr_probe->probefunc==probefunc)
-		{
-			chandev_unlock();
-			printk("chandev_register_and_probe detected duplicate probefunc %p"
-			       " for chan_type  0x%02x \n",probefunc,chan_type);
-			return (-EPERM);
-		}
-	}
-	chandev_unlock();
-	if((new_probe=chandev_alloc(sizeof(chandev_probelist))))
-	{
-		new_probe->probefunc=probefunc;
-		new_probe->shutdownfunc=shutdownfunc;
-		new_probe->msck_notfunc=msck_notfunc;
-		new_probe->chan_type=chan_type;
-		new_probe->devices_found=0;
-		chandev_add_to_list((list **)&chandev_probelist_head,new_probe);
-		chandev_probe();
-	}
-	return(new_probe ? new_probe->devices_found:-ENOMEM);
-}
-
-void chandev_unregister(chandev_probefunc probefunc,int call_shutdown)
-{
-	chandev_probelist *curr_probe;
-	chandev_activelist *curr_device,*next_device;
-	
-	chandev_interrupt_check("chandev_unregister");
-	chandev_lock();
-	for_each(curr_probe,chandev_probelist_head)
-	{
-		if(curr_probe->probefunc==probefunc)
-		{
-			for_each_allow_delete(curr_device,next_device,chandev_activelist_head)
-				if(curr_device->probefunc==probefunc&&call_shutdown)
-					chandev_shutdown(curr_device);
-			chandev_free_listmember((list **)&chandev_probelist_head,
-						(list *)curr_probe);
-			break;
-		}
-	}
-	chandev_unlock();
-}
-
-
-int chandev_persist(chandev_type chan_type)
-{
-	return((chandev_persistent&chan_type) ? TRUE:FALSE);
-}
-
-EXPORT_SYMBOL(chandev_register_and_probe);
-EXPORT_SYMBOL(chandev_request_irq);
-EXPORT_SYMBOL(chandev_unregister);
-EXPORT_SYMBOL(chandev_initdevice);
-EXPORT_SYMBOL(chandev_build_device_name);
-EXPORT_SYMBOL(chandev_initnetdevice);
-/* see chandev.h as to why this is exported */
-EXPORT_SYMBOL(chandev_init_netdev);
-EXPORT_SYMBOL(chandev_use_devno_names);
-EXPORT_SYMBOL(chandev_free_irq);
-/* see chandev.h as to why chandev_add_model and chandev_del_model 
- * are exported */
-EXPORT_SYMBOL(chandev_add_model);
-EXPORT_SYMBOL(chandev_del_model);
-EXPORT_SYMBOL(chandev_persist);
-
diff -Nru a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile
--- a/drivers/s390/net/Makefile	Mon Dec  9 18:46:36 2002
+++ b/drivers/s390/net/Makefile	Mon Dec  9 18:46:36 2002
@@ -2,14 +2,14 @@
 # S/390 network devices
 #
 
-export-objs := iucv.o fsm.o
+export-objs := iucv.o fsm.o cu3088.o
 
 ctc-objs := ctcmain.o ctctty.o
 
 obj-$(CONFIG_IUCV) += iucv.o fsm.o
-obj-$(CONFIG_CTC) += ctc.o fsm.o
+obj-$(CONFIG_CTC) += ctc.o fsm.o cu3088.o
 obj-$(CONFIG_IUCV) += netiucv.o
-obj-$(CONFIG_LCS) += lcs.o
+obj-$(CONFIG_LCS) += lcs.o cu3088.o
 
 include $(TOPDIR)/Rules.make
 
diff -Nru a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c
--- a/drivers/s390/net/ctcmain.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/s390/net/ctcmain.c	Mon Dec  9 18:46:36 2002
@@ -1,5 +1,5 @@
 /*
- * $Id: ctcmain.c,v 1.55 2001/12/03 14:28:45 felfert Exp $
+ * $Id: ctcmain.c,v 1.29 2002/12/06 12:31:38 cohuck Exp $
  *
  * CTC / ESCON network driver
  *
@@ -7,6 +7,7 @@
  * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
  * Fixes by : Jochen Röhrig (roehrig@de.ibm.com)
  *            Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ * Driver Model stuff by : Cornelia Huck <cohuck@de.ibm.com>
  *
  * Documentation used:
  *  - Principles of Operation (IBM doc#: SA22-7201-06)
@@ -35,10 +36,12 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.55 $
+ * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.29 $
  *
  */
 
+#undef DEBUG
+
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -52,7 +55,6 @@
 
 #include <linux/signal.h>
 #include <linux/string.h>
-#include <linux/proc_fs.h>
 
 #include <linux/ip.h>
 #include <linux/if_arp.h>
@@ -62,50 +64,20 @@
 #include <net/dst.h>
 
 #include <asm/io.h>
+#include <asm/ccwdev.h>
+#include <asm/ccwgroup.h>
 #include <asm/bitops.h>
 #include <asm/uaccess.h>
-#ifdef CONFIG_CHANDEV
-#define CTC_CHANDEV
-#endif
-
-#ifdef CTC_CHANDEV
-#include <asm/chandev.h>
-#define REQUEST_IRQ chandev_request_irq
-#define FREE_IRQ chandev_free_irq
-#else
-#define REQUEST_IRQ request_irq
-#define FREE_IRQ free_irq
-#endif
 
 #include <asm/idals.h>
 
-#include <asm/irq.h>
-
 #include "ctctty.h"
 #include "fsm.h"
+#include "cu3088.h"
 
-#ifdef MODULE
 MODULE_AUTHOR("(C) 2000 IBM Corp. by Fritz Elfert (felfert@millenux.com)");
 MODULE_DESCRIPTION("Linux for S/390 CTC/Escon Driver");
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,12))
 MODULE_LICENSE("GPL");
-#endif
-#ifndef CTC_CHANDEV
-MODULE_PARM(ctc, "s");
-MODULE_PARM_DESC(ctc,
-"One or more definitions in the same format like the kernel param for ctc.\n"
-"E.g.: ctc0:0x700:0x701:0:ctc1:0x702:0x703:0\n");
-
-char *ctc = NULL;
-#endif
-#else
-/**
- * Number of devices in monolithic (not module) driver version.
- */
-#define MAX_STATIC_DEVICES 16
-#endif /* MODULE */
-
-#undef DEBUG
 
 /**
  * CCW commands, used in this driver.
@@ -130,65 +102,15 @@
 
 #define READ			0
 #define WRITE			1
-
-/**
- * Enum for classifying detected devices.
- */
-enum channel_types {
-        /**
-	 * Device is not a channel.
-	 */
-	channel_type_none,
-
-	/**
-	 * Device is a channel, but we don't know
-	 * anything about it.
-	 */
-	channel_type_unknown,
-
-        /**
-	 * Device is a CTC/A.
-	 */
-	channel_type_ctca,
-
-	/**
-	 * Device is a ESCON channel.
-	 */
-	channel_type_escon,
-	/**
-	 * Device is an unsupported model.
-	 */
-	channel_type_unsupported
-};
-
-typedef enum channel_types channel_type_t;
-
-#ifndef CTC_CHANDEV
-static int ctc_no_auto = 0;
-#endif
 
+#define CTC_ID_SIZE             DEVICE_ID_SIZE+3
+
 /**
  * If running on 64 bit, this must be changed. XXX Why? (bird)
  */
 typedef unsigned long intparm_t;
 
-#ifndef CTC_CHANDEV
-/**
- * Definition of a per device parameter block
- */
-#define MAX_PARAM_NAME_LEN 11
-typedef struct param_t {
-	struct param_t *next;
-	int            read_dev;
-	int            write_dev;
-	__u16          proto;
-	char           name[MAX_PARAM_NAME_LEN];
-} param;
-
-static param *params = NULL;
-#endif
-
-typedef struct {
+struct ctc_profile {
 	unsigned long maxmulti;
 	unsigned long maxcqueue;
 	unsigned long doios_single;
@@ -196,51 +118,51 @@
 	unsigned long txlen;
 	unsigned long tx_time;
 	struct timespec send_stamp;
-} ctc_profile;
+};
 
 /**
  * Definition of one channel
  */
-typedef struct channel_t {
+struct channel {
 
-        /**
+	/**
 	 * Pointer to next channel in list.
 	 */
-	struct channel_t    *next;
-	__u16               devno;
-	int                 irq;
+	struct channel *next;
+	char id[CTC_ID_SIZE];
+	struct ccw_device *cdev;
 
 	/**
 	 * Type of this channel.
 	 * CTC/A or Escon for valid channels.
 	 */
-	channel_type_t      type;
+	enum channel_types type;
 
-        /**
+	/**
 	 * Misc. flags. See CHANNEL_FLAGS_... below
 	 */
-	__u32               flags;
+	__u32 flags;
 
 	/**
 	 * The protocol of this channel
 	 */
-	__u16               protocol;
+	__u16 protocol;
 
 	/**
 	 * I/O and irq related stuff
 	 */
-	ccw1_t              *ccw;
-	devstat_t           *devstat;
+	struct ccw1 *ccw;
+	struct irb *irb;
 
 	/**
 	 * RX/TX buffer size
 	 */
-	int                 max_bufsize;
+	int max_bufsize;
 
 	/**
 	 * Transmit/Receive buffer.
 	 */
-	struct sk_buff      *trans_skb;
+	struct sk_buff *trans_skb;
 
 	/**
 	 * Universal I/O queue.
@@ -255,39 +177,39 @@
 	/**
 	 * Amount of data in collect_queue.
 	 */
-	int                 collect_len;
+	int collect_len;
 
 	/**
 	 * spinlock for collect_queue and collect_len
 	 */
-	spinlock_t          collect_lock;
+	spinlock_t collect_lock;
 
 	/**
 	 * Timer for detecting unresposive
 	 * I/O operations.
 	 */
-	fsm_timer           timer;
+	fsm_timer timer;
 
 	/**
 	 * Retry counter for misc. operations.
 	 */
-	int                 retry;
+	int retry;
 
 	/**
 	 * The finite state machine of this channel
 	 */
-	fsm_instance        *fsm;
+	fsm_instance *fsm;
 
 	/**
 	 * The corresponding net_device this channel
 	 * belongs to.
 	 */
-	net_device          *netdev;
+	struct net_device *netdev;
 
-	ctc_profile         prof;
+	struct ctc_profile prof;
 
-	unsigned char       *trans_skb_data;
-} channel;
+	unsigned char *trans_skb_data;
+};
 
 #define CHANNEL_FLAGS_READ            0
 #define CHANNEL_FLAGS_WRITE           1
@@ -299,54 +221,53 @@
 /**
  * Linked list of all detected channels.
  */
-static channel *channels = NULL;
-
-#ifdef CTC_CHANDEV
-static int activated;
-#endif
+static struct channel *channels = NULL;
 
-typedef struct ctc_priv_t {
+struct ctc_priv {
 	struct net_device_stats stats;
-	unsigned long           tbusy;
+	unsigned long tbusy;
 	/**
 	 * The finite state machine of this interface.
 	 */
-	fsm_instance            *fsm;
+	fsm_instance *fsm;
 	/**
 	 * The protocol of this device
 	 */
-	__u16                   protocol;
-	channel                 *channel[2];
-	struct proc_dir_entry   *proc_dentry;
-	struct proc_dir_entry   *proc_stat_entry;
-	struct proc_dir_entry   *proc_ctrl_entry;
-	int                     proc_registered;
-} ctc_priv;
+	__u16 protocol;
+ 	/**
+ 	 * Timer for restarting after I/O Errors
+ 	 */
+ 	fsm_timer               restart_timer;
+
+	struct channel *channel[2];
+};
 
 /**
  * Definition of our link level header.
  */
-typedef struct ll_header_t {
-	__u16	      length;
-	__u16	      type;
-	__u16	      unused;
-} ll_header;
-#define LL_HEADER_LENGTH (sizeof(ll_header))
+struct ll_header {
+	__u16 length;
+	__u16 type;
+	__u16 unused;
+};
+#define LL_HEADER_LENGTH (sizeof(struct ll_header))
 
 /**
  * Compatibility macros for busy handling
  * of network devices.
  */
-static __inline__ void ctc_clear_busy(net_device *dev)
+static __inline__ void
+ctc_clear_busy(struct net_device * dev)
 {
-	clear_bit(0, &(((ctc_priv *)dev->priv)->tbusy));
+	clear_bit(0, &(((struct ctc_priv *) dev->priv)->tbusy));
 	netif_wake_queue(dev);
 }
 
-static __inline__ int ctc_test_and_set_busy(net_device *dev)
+static __inline__ int
+ctc_test_and_set_busy(struct net_device * dev)
 {
 	netif_stop_queue(dev);
-	return test_and_set_bit(0, &((ctc_priv *)dev->priv)->tbusy);
+	return test_and_set_bit(0, &((struct ctc_priv *) dev->priv)->tbusy);
 }
 
 #define SET_DEVICE_START(device, value)
@@ -354,9 +275,11 @@
 /**
  * Print Banner.
  */
-static void print_banner(void) {
+static void
+print_banner(void)
+{
 	static int printed = 0;
-	char vbuf[] = "$Revision: 1.55 $";
+	char vbuf[] = "$Revision: 1.29 $";
 	char *version = vbuf;
 
 	if (printed)
@@ -367,12 +290,7 @@
 			*p = '\0';
 	} else
 		version = " ??? ";
-	printk(KERN_INFO
-	       "CTC driver Version%swith"
-#ifndef CTC_CHANDEV
-	       "out"
-#endif
-	       " CHANDEV support"
+	printk(KERN_INFO "CTC driver Version%s"
 #ifdef DEBUG
 	       " (DEBUG-VERSION, " __DATE__ __TIME__ ")"
 #endif
@@ -380,72 +298,19 @@
 	printed = 1;
 }
 
-
-#ifndef CTC_CHANDEV
 /**
  * Return type of a detected device.
  */
-static channel_type_t channel_type (senseid_t *id) {
-	channel_type_t type = channel_type_none;
+static enum channel_types
+get_channel_type(struct ccw_device_id *id)
+{
+	enum channel_types type = (enum channel_types) id->driver_info;
 
-	switch (id->cu_type) {
-		case 0x3088:
-			switch (id->cu_model) {
-				case 0x08:
-					/**
-					 * 3088-08 = CTCA
-					 */
-					type = channel_type_ctca;
-					break;
-
-				case 0x1F:
-					/**
-					 * 3088-1F = ESCON channel
-					 */
-					type = channel_type_escon;
-					break;
-
-					/**
-					 * 3088-01 = P390 OSA emulation
-					 */
-				case 0x01:
-					/* fall thru */
-
-					/**
-					 * 3088-60 = OSA/2 adapter
-					 */
-				case 0x60:
-					/* fall thru */
-
-					/**
-					 * 3088-61 = CISCO 7206 CLAW proto
-					 * on ESCON
-					 */
-				case 0x61:
-					/* fall thru */
-
-					/**
-					 * 3088-62 = OSA/D device
-					 */
-				case 0x62:
-					type = channel_type_unsupported;
-					break;
-
-				default:
-					type = channel_type_unknown;
-					printk(KERN_INFO
-					       "channel: Unknown model found "
-					       "3088-%02x\n", id->cu_model);
-			}
-			break;
+	if (type == channel_type_ficon)
+		type = channel_type_escon;
 
-		default:
-			type = channel_type_none;
-	}
 	return type;
 }
-#endif
-
 
 /**
  * States of the interface statemachine.
@@ -486,6 +351,7 @@
 	DEV_EVENT_TXUP,
 	DEV_EVENT_RXDOWN,
 	DEV_EVENT_TXDOWN,
+	DEV_EVENT_RESTART,
 	/**
 	 * MUST be always the last element!!
 	 */
@@ -499,6 +365,7 @@
 	"TX up",
 	"RX down",
 	"TX down",
+	"Restart",
 };
 
 /**
@@ -507,7 +374,7 @@
 enum ch_events {
 	/**
 	 * Events, representing return code of
-	 * I/O operations (do_IO, halt_IO et al.)
+	 * I/O operations (ccw_device_start, ccw_device_halt et al.)
 	 */
 	CH_EVENT_IO_SUCCESS,
 	CH_EVENT_IO_EBUSY,
@@ -653,7 +520,6 @@
 	"Not operational",
 };
 
-
 #ifdef DEBUG
 /**
  * Dump header and first 16 bytes of an sk_buff for debugging purposes.
@@ -661,25 +527,26 @@
  * @param skb    The sk_buff to dump.
  * @param offset Offset relative to skb-data, where to start the dump.
  */
-static void ctc_dump_skb(struct sk_buff *skb, int offset)
+static void
+ctc_dump_skb(struct sk_buff *skb, int offset)
 {
 	unsigned char *p = skb->data;
 	__u16 bl;
-	ll_header *header;
+	struct ll_header *header;
 	int i;
 
 	p += offset;
-	bl = *((__u16*)p);
+	bl = *((__u16 *) p);
 	p += 2;
-	header = (ll_header *)p;
+	header = (struct ll_header *) p;
 	p -= 2;
-	
+
 	printk(KERN_DEBUG "dump:\n");
 	printk(KERN_DEBUG "blocklen=%d %04x\n", bl, bl);
 
 	printk(KERN_DEBUG "h->length=%d %04x\n", header->length,
-	       header->length); 
-	printk(KERN_DEBUG "h->type=%04x\n", header->type); 
+	       header->length);
+	printk(KERN_DEBUG "h->type=%04x\n", header->type);
 	printk(KERN_DEBUG "h->unused=%04x\n", header->unused);
 	if (bl > 16)
 		bl = 16;
@@ -688,6 +555,11 @@
 		printk("%02x%s", *p++, (i % 16) ? " " : "\n<7>");
 	printk("\n");
 }
+#else
+static inline void
+ctc_dump_skb(struct sk_buff *skb, int offset)
+{
+}
 #endif
 
 /**
@@ -697,19 +569,20 @@
  * @param ch The channel where this skb has been received.
  * @param pskb The received skb.
  */
-static __inline__ void ctc_unpack_skb(channel *ch, struct sk_buff *pskb)
+static __inline__ void
+ctc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
 {
-	net_device     *dev = ch->netdev;
-	ctc_priv       *privptr = (ctc_priv *)dev->priv;
+	struct net_device *dev = ch->netdev;
+	struct ctc_priv *privptr = (struct ctc_priv *) dev->priv;
 
-	__u16 len = *((__u16*)pskb->data);
+	__u16 len = *((__u16 *) pskb->data);
 	skb_put(pskb, 2 + LL_HEADER_LENGTH);
 	skb_pull(pskb, 2);
 	pskb->dev = dev;
 	pskb->ip_summed = CHECKSUM_UNNECESSARY;
 	while (len > 0) {
 		struct sk_buff *skb;
-		ll_header *header = (ll_header *)pskb->data;
+		struct ll_header *header = (struct ll_header *) pskb->data;
 
 		skb_pull(pskb, LL_HEADER_LENGTH);
 		if ((ch->protocol == CTC_PROTO_S390) &&
@@ -722,11 +595,8 @@
 			 */
 			printk(KERN_WARNING
 			       "%s Illegal packet type 0x%04x "
-			       "received, dropping\n",
-			       dev->name, header->type);
-#ifdef DEBUG
+			       "received, dropping\n", dev->name, header->type);
 			ctc_dump_skb(pskb, -6);
-#endif
 			privptr->stats.rx_dropped++;
 			privptr->stats.rx_frame_errors++;
 			return;
@@ -741,9 +611,7 @@
 			       "received (MTU=%d blocklen=%d), "
 			       "dropping\n", dev->name, header->length,
 			       dev->mtu, len);
-#ifdef DEBUG
 			ctc_dump_skb(pskb, -6);
-#endif
 			privptr->stats.rx_dropped++;
 			privptr->stats.rx_length_errors++;
 			return;
@@ -753,9 +621,7 @@
 			       "%s Illegal packet size %d "
 			       "(beyond the end of received data), "
 			       "dropping\n", dev->name, header->length);
-#ifdef DEBUG
 			ctc_dump_skb(pskb, -6);
-#endif
 			privptr->stats.rx_dropped++;
 			privptr->stats.rx_length_errors++;
 			return;
@@ -780,7 +646,7 @@
 			ctc_tty_netif_rx(skb);
 		else
 			netif_rx(skb);
-#warning FIXME: [kj] Net drivers should set dev->last_rx immediately after netif_rx
+		dev->last_rx = jiffies;
 		privptr->stats.rx_packets++;
 		privptr->stats.rx_bytes += skb->len;
 		if (len > 0) {
@@ -796,32 +662,31 @@
  * @param ch          The channel, the error belongs to.
  * @param return_code The error code to inspect.
  */
-static void inline ccw_check_return_code (channel *ch, int return_code)
+static void inline
+ccw_check_return_code(struct channel *ch, int return_code)
 {
 	switch (return_code) {
-		case 0:
-			fsm_event(ch->fsm, CH_EVENT_IO_SUCCESS, ch);
-			break;
-		case -EBUSY:
-			printk(KERN_INFO "ch-%04x: Busy !\n", ch->devno);
-			fsm_event(ch->fsm, CH_EVENT_IO_EBUSY, ch);
-			break;
-		case -ENODEV:
-			printk(KERN_EMERG
-			       "ch-%04x: Invalid device called for IO\n",
-			       ch->devno);
-			fsm_event(ch->fsm, CH_EVENT_IO_ENODEV, ch);
-			break;
-		case -EIO:
-			printk(KERN_EMERG
-			       "ch-%04x: Status pending... \n", ch->devno);
-			fsm_event(ch->fsm, CH_EVENT_IO_EIO, ch);
-			break;
-		default:
-			printk(KERN_EMERG
-			       "ch-%04x: Unknown error in do_IO %04x\n",
-			       ch->devno, return_code);
-			fsm_event(ch->fsm, CH_EVENT_IO_UNKNOWN, ch);
+	case 0:
+		fsm_event(ch->fsm, CH_EVENT_IO_SUCCESS, ch);
+		break;
+	case -EBUSY:
+		printk(KERN_INFO "%s: Busy !\n", ch->id);
+		fsm_event(ch->fsm, CH_EVENT_IO_EBUSY, ch);
+		break;
+	case -ENODEV:
+		printk(KERN_EMERG
+		       "%s: Invalid device called for IO\n", ch->id);
+		fsm_event(ch->fsm, CH_EVENT_IO_ENODEV, ch);
+		break;
+	case -EIO:
+		printk(KERN_EMERG "%s: Status pending... \n", ch->id);
+		fsm_event(ch->fsm, CH_EVENT_IO_EIO, ch);
+		break;
+	default:
+		printk(KERN_EMERG
+		       "%s: Unknown error in do_IO %04x\n",
+		       ch->id, return_code);
+		fsm_event(ch->fsm, CH_EVENT_IO_UNKNOWN, ch);
 	}
 }
 
@@ -831,58 +696,59 @@
  * @param ch    The channel, the sense code belongs to.
  * @param sense The sense code to inspect.
  */
-static void inline ccw_unit_check (channel *ch, unsigned char sense) {
+static void inline
+ccw_unit_check(struct channel *ch, unsigned char sense)
+{
 	if (sense & SNS0_INTERVENTION_REQ) {
-		if (sense & 0x01)  {
+		if (sense & 0x01) {
 			if (ch->protocol != CTC_PROTO_LINUX_TTY)
 				printk(KERN_DEBUG
-				       "ch-%04x: Interface disc. or Sel. reset "
-				       "(remote)\n", ch->devno);
+				       "%s: Interface disc. or Sel. reset "
+				       "(remote)\n", ch->id);
 			fsm_event(ch->fsm, CH_EVENT_UC_RCRESET, ch);
 		} else {
-			printk(KERN_DEBUG "ch-%04x: System reset (remote)\n",
-			       ch->devno);
+			printk(KERN_DEBUG "%s: System reset (remote)\n",
+			       ch->id);
 			fsm_event(ch->fsm, CH_EVENT_UC_RSRESET, ch);
 		}
 	} else if (sense & SNS0_EQUIPMENT_CHECK) {
 		if (sense & SNS0_BUS_OUT_CHECK) {
 			printk(KERN_WARNING
-			       "ch-%04x: Hardware malfunction (remote)\n",
-			       ch->devno);
+			       "%s: Hardware malfunction (remote)\n",
+			       ch->id);
 			fsm_event(ch->fsm, CH_EVENT_UC_HWFAIL, ch);
 		} else {
 			printk(KERN_WARNING
-			       "ch-%04x: Read-data parity error (remote)\n",
-			       ch->devno);
+			       "%s: Read-data parity error (remote)\n",
+			       ch->id);
 			fsm_event(ch->fsm, CH_EVENT_UC_RXPARITY, ch);
 		}
 	} else if (sense & SNS0_BUS_OUT_CHECK) {
 		if (sense & 0x04) {
 			printk(KERN_WARNING
-			       "ch-%04x: Data-streaming timeout)\n",
-			       ch->devno);
+			       "%s: Data-streaming timeout)\n", ch->id);
 			fsm_event(ch->fsm, CH_EVENT_UC_TXTIMEOUT, ch);
 		} else {
 			printk(KERN_WARNING
-			       "ch-%04x: Data-transfer parity error\n",
-			       ch->devno);
+			       "%s: Data-transfer parity error\n",
+			       ch->id);
 			fsm_event(ch->fsm, CH_EVENT_UC_TXPARITY, ch);
 		}
 	} else if (sense & SNS0_CMD_REJECT) {
-			printk(KERN_WARNING "ch-%04x: Command reject\n",
-			       ch->devno);
+		printk(KERN_WARNING "%s: Command reject\n", ch->id);
 	} else if (sense == 0) {
-		printk(KERN_DEBUG "ch-%04x: Unit check ZERO\n", ch->devno);
+		printk(KERN_DEBUG "%s: Unit check ZERO\n", ch->id);
 		fsm_event(ch->fsm, CH_EVENT_UC_ZERO, ch);
 	} else {
 		printk(KERN_WARNING
-		       "ch-%04x: Unit Check with sense code: %02x\n",
-		       ch->devno, sense);
+		       "%s: Unit Check with sense code: %02x\n",
+		       ch->id, sense);
 		fsm_event(ch->fsm, CH_EVENT_UC_UNKNOWN, ch);
 	}
 }
 
-static void ctc_purge_skb_queue(struct sk_buff_head *q)
+static void
+ctc_purge_skb_queue(struct sk_buff_head *q)
 {
 	struct sk_buff *skb;
 
@@ -892,19 +758,21 @@
 	}
 }
 
-static __inline__ int ctc_checkalloc_buffer(channel *ch, int warn) {
+static __inline__ int
+ctc_checkalloc_buffer(struct channel *ch, int warn)
+{
 	if ((ch->trans_skb == NULL) ||
 	    (ch->flags & CHANNEL_FLAGS_BUFSIZE_CHANGED)) {
 		if (ch->trans_skb != NULL)
 			dev_kfree_skb(ch->trans_skb);
 		clear_normalized_cda(&ch->ccw[1]);
 		ch->trans_skb = __dev_alloc_skb(ch->max_bufsize,
-						GFP_ATOMIC|GFP_DMA);
+						GFP_ATOMIC | GFP_DMA);
 		if (ch->trans_skb == NULL) {
 			if (warn)
 				printk(KERN_WARNING
-				       "ch-%04x: Couldn't alloc %s trans_skb\n",
-				       ch->devno,
+				       "%s: Couldn't alloc %s trans_skb\n",
+				       ch->id,
 				       (CHANNEL_DIRECTION(ch->flags) == READ) ?
 				       "RX" : "TX");
 			return -ENOMEM;
@@ -915,9 +783,9 @@
 			ch->trans_skb = NULL;
 			if (warn)
 				printk(KERN_WARNING
-				       "ch-%04x: set_normalized_cda for %s "
+				       "%s: set_normalized_cda for %s "
 				       "trans_skb failed, dropping packets\n",
-				       ch->devno,
+				       ch->id,
 				       (CHANNEL_DIRECTION(ch->flags) == READ) ?
 				       "RX" : "TX");
 			return -ENOMEM;
@@ -932,7 +800,8 @@
 /**
  * Dummy NOP action for statemachines
  */
-static void fsm_action_nop(fsm_instance *fi, int event, void *arg)
+static void
+fsm_action_nop(fsm_instance * fi, int event, void *arg)
 {
 }
 
@@ -949,26 +818,27 @@
  * @param event The event, just happened.
  * @param arg   Generic pointer, casted from channel * upon call.
  */
-static void ch_action_txdone(fsm_instance *fi, int event, void *arg)
+static void
+ch_action_txdone(fsm_instance * fi, int event, void *arg)
 {
-	channel        *ch = (channel *)arg;
-	net_device     *dev = ch->netdev;
-	ctc_priv       *privptr = dev->priv;
+	struct channel *ch = (struct channel *) arg;
+	struct net_device *dev = ch->netdev;
+	struct ctc_priv *privptr = dev->priv;
 	struct sk_buff *skb;
-	int            first = 1;
-	int            i;
+	int first = 1;
+	int i;
 
 	struct timespec done_stamp = xtime;
-	unsigned long duration = 
-		(done_stamp.tv_sec - ch->prof.send_stamp.tv_sec) * 1000000 +
-		(done_stamp.tv_nsec - ch->prof.send_stamp.tv_nsec) / 1000;
+	unsigned long duration =
+	    (done_stamp.tv_sec - ch->prof.send_stamp.tv_sec) * 1000000 +
+	    (done_stamp.tv_nsec - ch->prof.send_stamp.tv_nsec) / 1000;
 	if (duration > ch->prof.tx_time)
 		ch->prof.tx_time = duration;
 
-	if (ch->devstat->rescnt != 0)
+	if (ch->irb->scsw.count != 0)
 		printk(KERN_DEBUG "%s: TX not complete, remaining %d bytes\n",
-		       dev->name, ch->devstat->rescnt);
-	
+		       dev->name, ch->irb->scsw.count);
+
 	fsm_deltimer(&ch->timer);
 	while ((skb = skb_dequeue(&ch->io_queue))) {
 		privptr->stats.tx_packets++;
@@ -995,7 +865,7 @@
 			ch->prof.maxmulti = ch->collect_len + 2;
 		if (ch->prof.maxcqueue < skb_queue_len(&ch->collect_queue))
 			ch->prof.maxcqueue = skb_queue_len(&ch->collect_queue);
-		*((__u16 *)skb_put(ch->trans_skb, 2)) = ch->collect_len + 2;
+		*((__u16 *) skb_put(ch->trans_skb, 2)) = ch->collect_len + 2;
 		i = 0;
 		while ((skb = skb_dequeue(&ch->collect_queue))) {
 			memcpy(skb_put(ch->trans_skb, skb->len), skb->data,
@@ -1011,7 +881,8 @@
 		ch->ccw[1].count = ch->trans_skb->len;
 		fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC, CH_EVENT_TIMER, ch);
 		ch->prof.send_stamp = xtime;
-		rc = do_IO(ch->irq, &ch->ccw[0], (intparm_t)ch, 0xff, 0);
+		rc = ccw_device_start(ch->cdev, &ch->ccw[0],
+				      (intparm_t) ch, 0xff, 0);
 		ch->prof.doios_multi++;
 		if (rc != 0) {
 			privptr->stats.tx_dropped += i;
@@ -1035,13 +906,14 @@
  * @param event The event, just happened.
  * @param arg   Generic pointer, casted from channel * upon call.
  */
-static void ch_action_txidle(fsm_instance *fi, int event, void *arg)
+static void
+ch_action_txidle(fsm_instance * fi, int event, void *arg)
 {
-	channel *ch = (channel *)arg;
+	struct channel *ch = (struct channel *) arg;
 
 	fsm_deltimer(&ch->timer);
 	fsm_newstate(fi, CH_STATE_TXIDLE);
-	fsm_event(((ctc_priv *)ch->netdev->priv)->fsm, DEV_EVENT_TXUP,
+	fsm_event(((struct ctc_priv *) ch->netdev->priv)->fsm, DEV_EVENT_TXUP,
 		  ch->netdev);
 }
 
@@ -1053,27 +925,28 @@
  * @param event The event, just happened.
  * @param arg   Generic pointer, casted from channel * upon call.
  */
-static void ch_action_rx(fsm_instance *fi, int event, void *arg)
+static void
+ch_action_rx(fsm_instance * fi, int event, void *arg)
 {
-	channel        *ch = (channel *)arg;
-	net_device     *dev = ch->netdev;
-	ctc_priv       *privptr = dev->priv;
-	int            len = ch->max_bufsize - ch->devstat->rescnt;
+	struct channel *ch = (struct channel *) arg;
+	struct net_device *dev = ch->netdev;
+	struct ctc_priv *privptr = dev->priv;
+	int len = ch->max_bufsize - ch->irb->scsw.count;
 	struct sk_buff *skb = ch->trans_skb;
-	__u16          block_len = *((__u16*)skb->data);
-	int            check_len;
-	int            rc;
+	__u16 block_len = *((__u16 *) skb->data);
+	int check_len;
+	int rc;
 
 	fsm_deltimer(&ch->timer);
 	if (len < 8) {
-		printk(KERN_WARNING "%s: got packet with length %d < 8\n",
+		printk(KERN_DEBUG "%s: got packet with length %d < 8\n",
 		       dev->name, len);
 		privptr->stats.rx_dropped++;
 		privptr->stats.rx_length_errors++;
 		goto again;
 	}
 	if (len > ch->max_bufsize) {
-		printk(KERN_WARNING "%s: got packet with length %d > %d\n",
+		printk(KERN_DEBUG "%s: got packet with length %d > %d\n",
 		       dev->name, len, ch->max_bufsize);
 		privptr->stats.rx_dropped++;
 		privptr->stats.rx_length_errors++;
@@ -1084,42 +957,40 @@
 	 * VM TCP seems to have a bug sending 2 trailing bytes of garbage.
 	 */
 	switch (ch->protocol) {
-		case CTC_PROTO_S390:
-		case CTC_PROTO_OS390:
-			check_len = block_len + 2;
-			break;
-		default:
-			check_len = block_len;
-			break;
+	case CTC_PROTO_S390:
+	case CTC_PROTO_OS390:
+		check_len = block_len + 2;
+		break;
+	default:
+		check_len = block_len;
+		break;
 	}
 	if ((len < block_len) || (len > check_len)) {
-		printk(KERN_WARNING "%s: got block length %d != rx length %d\n",
+		printk(KERN_DEBUG "%s: got block length %d != rx length %d\n",
 		       dev->name, block_len, len);
-#ifdef DEBUG
 		ctc_dump_skb(skb, 0);
-#endif
-		*((__u16*)skb->data) = len;
+		*((__u16 *) skb->data) = len;
 		privptr->stats.rx_dropped++;
 		privptr->stats.rx_length_errors++;
 		goto again;
 	}
 	block_len -= 2;
 	if (block_len > 0) {
-		*((__u16*)skb->data) = block_len;
+		*((__u16 *) skb->data) = block_len;
 		ctc_unpack_skb(ch, skb);
 	}
- again:
+      again:
 	skb->data = skb->tail = ch->trans_skb_data;
 	skb->len = 0;
 	if (ctc_checkalloc_buffer(ch, 1))
 		return;
 	ch->ccw[1].count = ch->max_bufsize;
-	rc = do_IO(ch->irq, &ch->ccw[0], (intparm_t)ch, 0xff, 0);
+	rc = ccw_device_start(ch->cdev, &ch->ccw[0], (intparm_t) ch, 0xff, 0);
 	if (rc != 0)
 		ccw_check_return_code(ch, rc);
 }
 
-static void ch_action_rxidle(fsm_instance *fi, int event, void *arg);
+static void ch_action_rxidle(fsm_instance * fi, int event, void *arg);
 
 /**
  * Initialize connection by sending a __u16 of value 0.
@@ -1128,14 +999,15 @@
  * @param event The event, just happened.
  * @param arg   Generic pointer, casted from channel * upon call.
  */
-static void ch_action_firstio(fsm_instance *fi, int event, void *arg)
+static void
+ch_action_firstio(fsm_instance * fi, int event, void *arg)
 {
-	channel *ch = (channel *)arg;
-	int     rc;
+	struct channel *ch = (struct channel *) arg;
+	int rc;
 
 	if (fsm_getstate(fi) == CH_STATE_TXIDLE)
-		printk(KERN_DEBUG "ch-%04x: remote side issued READ?, "
-		       "init ...\n", ch->devno);
+		printk(KERN_DEBUG "%s: remote side issued READ?, "
+		       "init ...\n", ch->id);
 	fsm_deltimer(&ch->timer);
 	if (ctc_checkalloc_buffer(ch, 1))
 		return;
@@ -1143,14 +1015,14 @@
 	    (ch->protocol == CTC_PROTO_OS390)) {
 		/* OS/390 resp. z/OS */
 		if (CHANNEL_DIRECTION(ch->flags) == READ) {
-			*((__u16 *)ch->trans_skb->data) = CTC_INITIAL_BLOCKLEN;
+			*((__u16 *) ch->trans_skb->data) = CTC_INITIAL_BLOCKLEN;
 			fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC,
 				     CH_EVENT_TIMER, ch);
 			ch_action_rxidle(fi, event, arg);
 		} else {
-			net_device *dev = ch->netdev;
+			struct net_device *dev = ch->netdev;
 			fsm_newstate(fi, CH_STATE_TXIDLE);
-			fsm_event(((ctc_priv *)dev->priv)->fsm,
+			fsm_event(((struct ctc_priv *) dev->priv)->fsm,
 				  DEV_EVENT_TXUP, dev);
 		}
 		return;
@@ -1165,12 +1037,12 @@
 	    (ch->protocol != CTC_PROTO_S390))
 		fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC, CH_EVENT_TIMER, ch);
 
-	*((__u16 *)ch->trans_skb->data) = CTC_INITIAL_BLOCKLEN;
-	ch->ccw[1].count = 2; /* Transfer only length */
+	*((__u16 *) ch->trans_skb->data) = CTC_INITIAL_BLOCKLEN;
+	ch->ccw[1].count = 2;	/* Transfer only length */
 
 	fsm_newstate(fi, (CHANNEL_DIRECTION(ch->flags) == READ)
 		     ? CH_STATE_RXINIT : CH_STATE_TXINIT);
-	rc = do_IO(ch->irq, &ch->ccw[0], (intparm_t)ch, 0xff, 0);
+	rc = ccw_device_start(ch->cdev, &ch->ccw[0], (intparm_t) ch, 0xff, 0);
 	if (rc != 0) {
 		fsm_deltimer(&ch->timer);
 		fsm_newstate(fi, CH_STATE_SETUPWAIT);
@@ -1185,8 +1057,9 @@
 	 */
 	if ((CHANNEL_DIRECTION(ch->flags) == READ) &&
 	    (ch->protocol == CTC_PROTO_S390)) {
-		net_device *dev = ch->netdev;
-		fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_RXUP, dev);
+		struct net_device *dev = ch->netdev;
+		fsm_event(((struct ctc_priv *) dev->priv)->fsm, DEV_EVENT_RXUP,
+			  dev);
 	}
 }
 
@@ -1199,29 +1072,29 @@
  * @param event The event, just happened.
  * @param arg   Generic pointer, casted from channel * upon call.
  */
-static void ch_action_rxidle(fsm_instance *fi, int event, void *arg)
+static void
+ch_action_rxidle(fsm_instance * fi, int event, void *arg)
 {
-	channel    *ch = (channel *)arg;
-	net_device *dev = ch->netdev;
-	__u16      buflen;
-	int        rc;
+	struct channel *ch = (struct channel *) arg;
+	struct net_device *dev = ch->netdev;
+	__u16 buflen;
+	int rc;
 
 	fsm_deltimer(&ch->timer);
-	buflen = *((__u16 *)ch->trans_skb->data);
-#ifdef DEBUG
-	printk(KERN_DEBUG "%s: Initial RX count %d\n", dev->name, buflen);
-#endif
+	buflen = *((__u16 *) ch->trans_skb->data);
+	pr_debug("%s: Initial RX count %d\n", dev->name, buflen);
 	if (buflen >= CTC_INITIAL_BLOCKLEN) {
 		if (ctc_checkalloc_buffer(ch, 1))
 			return;
 		ch->ccw[1].count = ch->max_bufsize;
 		fsm_newstate(fi, CH_STATE_RXIDLE);
-		rc = do_IO(ch->irq, &ch->ccw[0], (intparm_t)ch, 0xff, 0);
+		rc = ccw_device_start(ch->cdev, &ch->ccw[0],
+				      (intparm_t) ch, 0xff, 0);
 		if (rc != 0) {
 			fsm_newstate(fi, CH_STATE_RXINIT);
 			ccw_check_return_code(ch, rc);
 		} else
-			fsm_event(((ctc_priv *)dev->priv)->fsm,
+			fsm_event(((struct ctc_priv *) dev->priv)->fsm,
 				  DEV_EVENT_RXUP, dev);
 	} else {
 		printk(KERN_DEBUG "%s: Initial RX count %d not %d\n",
@@ -1237,20 +1110,21 @@
  * @param event The event, just happened.
  * @param arg   Generic pointer, casted from channel * upon call.
  */
-static void ch_action_setmode(fsm_instance *fi, int event, void *arg)
+static void
+ch_action_setmode(fsm_instance * fi, int event, void *arg)
 {
-	channel *ch = (channel *)arg;
-	int     rc;
+	struct channel *ch = (struct channel *) arg;
+	int rc;
 	unsigned long saveflags;
 
 	fsm_deltimer(&ch->timer);
 	fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC, CH_EVENT_TIMER, ch);
 	fsm_newstate(fi, CH_STATE_SETUPWAIT);
 	if (event == CH_EVENT_TIMER)
-		s390irq_spin_lock_irqsave(ch->irq, saveflags);
-	rc = do_IO(ch->irq, &ch->ccw[6], (intparm_t)ch, 0xff, 0);
+		spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
+	rc = ccw_device_start(ch->cdev, &ch->ccw[6], (intparm_t) ch, 0xff, 0);
 	if (event == CH_EVENT_TIMER)
-		s390irq_spin_unlock_irqrestore(ch->irq, saveflags);
+		spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
 	if (rc != 0) {
 		fsm_deltimer(&ch->timer);
 		fsm_newstate(fi, CH_STATE_STARTWAIT);
@@ -1266,28 +1140,27 @@
  * @param event The event, just happened.
  * @param arg   Generic pointer, casted from channel * upon call.
  */
-static void ch_action_start(fsm_instance *fi, int event, void *arg)
+static void
+ch_action_start(fsm_instance * fi, int event, void *arg)
 {
-	channel *ch = (channel *)arg;
+	struct channel *ch = (struct channel *) arg;
 	unsigned long saveflags;
-	int     rc;
-	net_device *dev;
+	int rc;
+	struct net_device *dev;
 
 	if (ch == NULL) {
 		printk(KERN_WARNING "ch_action_start ch=NULL\n");
 		return;
 	}
 	if (ch->netdev == NULL) {
-		printk(KERN_WARNING "ch_action_start dev=NULL, irq=%d\n",
-		       ch->irq);
+		printk(KERN_WARNING "ch_action_start dev=NULL, id=%s\n",
+		       ch->id);
 		return;
 	}
 	dev = ch->netdev;
 
-#ifdef DEBUG
-	printk(KERN_DEBUG "%s: %s channel start\n", dev->name,
-	       (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
-#endif
+	pr_debug("%s: %s channel start\n", dev->name,
+		 (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
 
 	if (ch->trans_skb != NULL) {
 		clear_normalized_cda(&ch->ccw[1]);
@@ -1296,44 +1169,42 @@
 	}
 	if (CHANNEL_DIRECTION(ch->flags) == READ) {
 		ch->ccw[1].cmd_code = CCW_CMD_READ;
-		ch->ccw[1].flags    = CCW_FLAG_SLI;
-		ch->ccw[1].count    = 0;
+		ch->ccw[1].flags = CCW_FLAG_SLI;
+		ch->ccw[1].count = 0;
 	} else {
 		ch->ccw[1].cmd_code = CCW_CMD_WRITE;
-		ch->ccw[1].flags    = CCW_FLAG_SLI | CCW_FLAG_CC;
-		ch->ccw[1].count    = 0;
+		ch->ccw[1].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
+		ch->ccw[1].count = 0;
 	}
 	if (ctc_checkalloc_buffer(ch, 0))
 		printk(KERN_NOTICE
 		       "%s: Could not allocate %s trans_skb, delaying "
 		       "allocation until first transfer\n",
-		       dev->name, 
+		       dev->name,
 		       (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
 
 	ch->ccw[0].cmd_code = CCW_CMD_PREPARE;
-	ch->ccw[0].flags    = CCW_FLAG_SLI | CCW_FLAG_CC;
-	ch->ccw[0].count    = 0;
-	ch->ccw[0].cda	    = 0;
-	ch->ccw[2].cmd_code = CCW_CMD_NOOP;	 /* jointed CE + DE */
-	ch->ccw[2].flags    = CCW_FLAG_SLI;
-	ch->ccw[2].count    = 0;
-	ch->ccw[2].cda	    = 0;
-	memcpy(&ch->ccw[3], &ch->ccw[0], sizeof(ccw1_t) * 3);
-	ch->ccw[4].cda	    = 0;
-	ch->ccw[4].flags    &= ~CCW_FLAG_IDA;
+	ch->ccw[0].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
+	ch->ccw[0].count = 0;
+	ch->ccw[0].cda = 0;
+	ch->ccw[2].cmd_code = CCW_CMD_NOOP;	/* jointed CE + DE */
+	ch->ccw[2].flags = CCW_FLAG_SLI;
+	ch->ccw[2].count = 0;
+	ch->ccw[2].cda = 0;
+	memcpy(&ch->ccw[3], &ch->ccw[0], sizeof (struct ccw1) * 3);
+	ch->ccw[4].cda = 0;
+	ch->ccw[4].flags &= ~CCW_FLAG_IDA;
 
 	fsm_newstate(fi, CH_STATE_STARTWAIT);
 	fsm_addtimer(&ch->timer, 1000, CH_EVENT_TIMER, ch);
-	s390irq_spin_lock_irqsave(ch->irq, saveflags);
-	rc = halt_IO(ch->irq, (intparm_t)ch, 0);
-	s390irq_spin_unlock_irqrestore(ch->irq, saveflags);
+	spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
+	rc = ccw_device_halt(ch->cdev, (intparm_t) ch);
+	spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
 	if (rc != 0) {
 		fsm_deltimer(&ch->timer);
 		ccw_check_return_code(ch, rc);
 	}
-#ifdef DEBUG
-	printk(KERN_DEBUG "ctc: %s(): leaving\n", __FUNCTION__);
-#endif
+	pr_debug(KERN_DEBUG "ctc: %s(): leaving\n", __FUNCTION__);
 }
 
 /**
@@ -1343,22 +1214,23 @@
  * @param event The event, just happened.
  * @param arg   Generic pointer, casted from channel * upon call.
  */
-static void ch_action_haltio(fsm_instance *fi, int event, void *arg)
+static void
+ch_action_haltio(fsm_instance * fi, int event, void *arg)
 {
-	channel *ch = (channel *)arg;
+	struct channel *ch = (struct channel *) arg;
 	unsigned long saveflags;
-	int     rc;
-	int     oldstate;
+	int rc;
+	int oldstate;
 
 	fsm_deltimer(&ch->timer);
 	fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC, CH_EVENT_TIMER, ch);
 	if (event == CH_EVENT_STOP)
-		s390irq_spin_lock_irqsave(ch->irq, saveflags);
+		spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
 	oldstate = fsm_getstate(fi);
 	fsm_newstate(fi, CH_STATE_TERM);
-	rc = halt_IO (ch->irq, (intparm_t)ch, 0);
+	rc = ccw_device_halt(ch->cdev, (intparm_t) ch);
 	if (event == CH_EVENT_STOP)
-		s390irq_spin_unlock_irqrestore(ch->irq, saveflags);
+		spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
 	if (rc != 0) {
 		fsm_deltimer(&ch->timer);
 		fsm_newstate(fi, oldstate);
@@ -1374,10 +1246,11 @@
  * @param event The event, just happened.
  * @param arg   Generic pointer, casted from channel * upon call.
  */
-static void ch_action_stopped(fsm_instance *fi, int event, void *arg)
+static void
+ch_action_stopped(fsm_instance * fi, int event, void *arg)
 {
-	channel *ch = (channel *)arg;
-	net_device *dev = ch->netdev;
+	struct channel *ch = (struct channel *) arg;
+	struct net_device *dev = ch->netdev;
 
 	fsm_deltimer(&ch->timer);
 	fsm_newstate(fi, CH_STATE_STOPPED);
@@ -1388,14 +1261,16 @@
 	}
 	if (CHANNEL_DIRECTION(ch->flags) == READ) {
 		skb_queue_purge(&ch->io_queue);
-		fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_RXDOWN, dev);
+		fsm_event(((struct ctc_priv *) dev->priv)->fsm,
+			  DEV_EVENT_RXDOWN, dev);
 	} else {
 		ctc_purge_skb_queue(&ch->io_queue);
 		spin_lock(&ch->collect_lock);
 		ctc_purge_skb_queue(&ch->collect_queue);
 		ch->collect_len = 0;
 		spin_unlock(&ch->collect_lock);
-		fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_TXDOWN, dev);
+		fsm_event(((struct ctc_priv *) dev->priv)->fsm,
+			  DEV_EVENT_TXDOWN, dev);
 	}
 }
 
@@ -1407,7 +1282,8 @@
  * @param event The event, just happened.
  * @param arg   Generic pointer, casted from channel * upon call.
  */
-static void ch_action_stop(fsm_instance *fi, int event, void *arg)
+static void
+ch_action_stop(fsm_instance * fi, int event, void *arg)
 {
 	fsm_newstate(fi, CH_STATE_STOPPED);
 }
@@ -1421,23 +1297,26 @@
  * @param event The event, just happened.
  * @param arg   Generic pointer, casted from channel * upon call.
  */
-static void ch_action_fail(fsm_instance *fi, int event, void *arg)
+static void
+ch_action_fail(fsm_instance * fi, int event, void *arg)
 {
-	channel *ch = (channel *)arg;
-	net_device *dev = ch->netdev;
+	struct channel *ch = (struct channel *) arg;
+	struct net_device *dev = ch->netdev;
 
 	fsm_deltimer(&ch->timer);
 	fsm_newstate(fi, CH_STATE_NOTOP);
 	if (CHANNEL_DIRECTION(ch->flags) == READ) {
 		skb_queue_purge(&ch->io_queue);
-		fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_RXDOWN, dev);
+		fsm_event(((struct ctc_priv *) dev->priv)->fsm,
+			  DEV_EVENT_RXDOWN, dev);
 	} else {
 		ctc_purge_skb_queue(&ch->io_queue);
 		spin_lock(&ch->collect_lock);
 		ctc_purge_skb_queue(&ch->collect_queue);
 		ch->collect_len = 0;
 		spin_unlock(&ch->collect_lock);
-		fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_TXDOWN, dev);
+		fsm_event(((struct ctc_priv *) dev->priv)->fsm,
+			  DEV_EVENT_TXDOWN, dev);
 	}
 }
 
@@ -1448,10 +1327,11 @@
  * @param event The event, just happened.
  * @param arg   Generic pointer, casted from channel * upon call.
  */
-static void ch_action_setuperr(fsm_instance *fi, int event, void *arg)
+static void
+ch_action_setuperr(fsm_instance * fi, int event, void *arg)
 {
-	channel *ch = (channel *)arg;
-	net_device *dev = ch->netdev;
+	struct channel *ch = (struct channel *) arg;
+	struct net_device *dev = ch->netdev;
 
 	/**
 	 * Special case: Got UC_RCRESET on setmode.
@@ -1460,12 +1340,12 @@
 	 */
 	if ((fsm_getstate(fi) == CH_STATE_SETUPWAIT) &&
 	    ((event == CH_EVENT_UC_RCRESET) ||
-	     (event == CH_EVENT_UC_RSRESET)   )         ) {
+	     (event == CH_EVENT_UC_RSRESET))) {
 		fsm_newstate(fi, CH_STATE_STARTRETRY);
 		fsm_deltimer(&ch->timer);
 		fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC, CH_EVENT_TIMER, ch);
 		if (CHANNEL_DIRECTION(ch->flags) == READ) {
-			int rc = halt_IO (ch->irq, (intparm_t)ch, 0);
+			int rc = ccw_device_halt(ch->cdev, (intparm_t) ch);
 			if (rc != 0)
 				ccw_check_return_code(ch, rc);
 		}
@@ -1478,10 +1358,12 @@
 	       fsm_getstate_str(fi));
 	if (CHANNEL_DIRECTION(ch->flags) == READ) {
 		fsm_newstate(fi, CH_STATE_RXERR);
-		fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_RXDOWN, dev);
+		fsm_event(((struct ctc_priv *) dev->priv)->fsm,
+			  DEV_EVENT_RXDOWN, dev);
 	} else {
 		fsm_newstate(fi, CH_STATE_TXERR);
-		fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_TXDOWN, dev);
+		fsm_event(((struct ctc_priv *) dev->priv)->fsm,
+			  DEV_EVENT_TXDOWN, dev);
 	}
 }
 
@@ -1492,14 +1374,15 @@
  * @param event The event, just happened.
  * @param arg   Generic pointer, casted from channel * upon call.
  */
-static void ch_action_restart(fsm_instance *fi, int event, void *arg)
+static void
+ch_action_restart(fsm_instance * fi, int event, void *arg)
 {
 	unsigned long saveflags;
-	int   oldstate;
-	int   rc;
+	int oldstate;
+	int rc;
 
-	channel *ch = (channel *)arg;
-	net_device *dev = ch->netdev;
+	struct channel *ch = (struct channel *) arg;
+	struct net_device *dev = ch->netdev;
 
 	fsm_deltimer(&ch->timer);
 	printk(KERN_DEBUG "%s: %s channel restart\n", dev->name,
@@ -1508,10 +1391,10 @@
 	oldstate = fsm_getstate(fi);
 	fsm_newstate(fi, CH_STATE_STARTWAIT);
 	if (event == CH_EVENT_TIMER)
-		s390irq_spin_lock_irqsave(ch->irq, saveflags);
-	rc = halt_IO (ch->irq, (intparm_t)ch, 0);
+		spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
+	rc = ccw_device_halt(ch->cdev, (intparm_t) ch);
 	if (event == CH_EVENT_TIMER)
-		s390irq_spin_unlock_irqrestore(ch->irq, saveflags);
+		spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
 	if (rc != 0) {
 		fsm_deltimer(&ch->timer);
 		fsm_newstate(fi, oldstate);
@@ -1527,10 +1410,11 @@
  * @param event The event, just happened.
  * @param arg   Generic pointer, casted from channel * upon call.
  */
-static void ch_action_rxiniterr(fsm_instance *fi, int event, void *arg)
+static void
+ch_action_rxiniterr(fsm_instance * fi, int event, void *arg)
 {
-	channel *ch = (channel *)arg;
-	net_device *dev = ch->netdev;
+	struct channel *ch = (struct channel *) arg;
+	struct net_device *dev = ch->netdev;
 
 	if (event == CH_EVENT_TIMER) {
 		fsm_deltimer(&ch->timer);
@@ -1540,7 +1424,7 @@
 			ch_action_restart(fi, event, arg);
 		else {
 			fsm_newstate(fi, CH_STATE_RXERR);
-			fsm_event(((ctc_priv *)dev->priv)->fsm,
+			fsm_event(((struct ctc_priv *) dev->priv)->fsm,
 				  DEV_EVENT_RXDOWN, dev);
 		}
 	} else
@@ -1556,15 +1440,16 @@
  * @param event The event, just happened.
  * @param arg   Generic pointer, casted from channel * upon call.
  */
-static void ch_action_rxinitfail(fsm_instance *fi, int event, void *arg)
+static void
+ch_action_rxinitfail(fsm_instance * fi, int event, void *arg)
 {
-	channel *ch = (channel *)arg;
-	net_device *dev = ch->netdev;
+	struct channel *ch = (struct channel *) arg;
+	struct net_device *dev = ch->netdev;
 
 	fsm_newstate(fi, CH_STATE_RXERR);
 	printk(KERN_WARNING "%s: RX initialization failed\n", dev->name);
 	printk(KERN_WARNING "%s: RX <-> RX connection detected\n", dev->name);
-	fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_RXDOWN, dev);
+	fsm_event(((struct ctc_priv *) dev->priv)->fsm, DEV_EVENT_RXDOWN, dev);
 }
 
 /**
@@ -1574,11 +1459,12 @@
  * @param event The event, just happened.
  * @param arg   Generic pointer, casted from channel * upon call.
  */
-static void ch_action_rxdisc(fsm_instance *fi, int event, void *arg)
+static void
+ch_action_rxdisc(fsm_instance * fi, int event, void *arg)
 {
-	channel    *ch = (channel *)arg;
-	channel    *ch2;
-	net_device *dev = ch->netdev;
+	struct channel *ch = (struct channel *) arg;
+	struct channel *ch2;
+	struct net_device *dev = ch->netdev;
 
 	fsm_deltimer(&ch->timer);
 	printk(KERN_DEBUG "%s: Got remote disconnect, re-initializing ...\n",
@@ -1587,15 +1473,15 @@
 	/**
 	 * Notify device statemachine
 	 */
-	fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_RXDOWN, dev);
-	fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_TXDOWN, dev);
+	fsm_event(((struct ctc_priv *) dev->priv)->fsm, DEV_EVENT_RXDOWN, dev);
+	fsm_event(((struct ctc_priv *) dev->priv)->fsm, DEV_EVENT_TXDOWN, dev);
 
 	fsm_newstate(fi, CH_STATE_DTERM);
-	ch2 = ((ctc_priv *)dev->priv)->channel[WRITE];
+	ch2 = ((struct ctc_priv *) dev->priv)->channel[WRITE];
 	fsm_newstate(ch2->fsm, CH_STATE_DTERM);
 
-	halt_IO(ch->irq, (intparm_t)ch, 0);
-	halt_IO(ch2->irq, (intparm_t)ch2, 0);
+	ccw_device_halt(ch->cdev, (intparm_t) ch);
+	ccw_device_halt(ch2->cdev, (intparm_t) ch2);
 }
 
 /**
@@ -1605,10 +1491,11 @@
  * @param event The event, just happened.
  * @param arg   Generic pointer, casted from channel * upon call.
  */
-static void ch_action_txiniterr(fsm_instance *fi, int event, void *arg)
+static void
+ch_action_txiniterr(fsm_instance * fi, int event, void *arg)
 {
-	channel *ch = (channel *)arg;
-	net_device *dev = ch->netdev;
+	struct channel *ch = (struct channel *) arg;
+	struct net_device *dev = ch->netdev;
 
 	if (event == CH_EVENT_TIMER) {
 		fsm_deltimer(&ch->timer);
@@ -1618,7 +1505,7 @@
 			ch_action_restart(fi, event, arg);
 		else {
 			fsm_newstate(fi, CH_STATE_TXERR);
-			fsm_event(((ctc_priv *)dev->priv)->fsm,
+			fsm_event(((struct ctc_priv *) dev->priv)->fsm,
 				  DEV_EVENT_TXDOWN, dev);
 		}
 	} else
@@ -1633,17 +1520,19 @@
  * @param event The event, just happened.
  * @param arg   Generic pointer, casted from channel * upon call.
  */
-static void ch_action_txretry(fsm_instance *fi, int event, void *arg)
+static void
+ch_action_txretry(fsm_instance * fi, int event, void *arg)
 {
-	channel    *ch = (channel *)arg;
-	net_device *dev = ch->netdev;
+	struct channel *ch = (struct channel *) arg;
+	struct net_device *dev = ch->netdev;
 	unsigned long saveflags;
 
 	fsm_deltimer(&ch->timer);
 	if (ch->retry++ > 3) {
 		printk(KERN_DEBUG "%s: TX retry failed, restarting channel\n",
 		       dev->name);
-		fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_TXDOWN, dev);
+		fsm_event(((struct ctc_priv *) dev->priv)->fsm,
+			  DEV_EVENT_TXDOWN, dev);
 		ch_action_restart(fi, event, arg);
 	} else {
 		struct sk_buff *skb;
@@ -1657,18 +1546,20 @@
 			if (set_normalized_cda(&ch->ccw[4], skb->data)) {
 				printk(KERN_DEBUG "%s: IDAL alloc failed, "
 				       "restarting channel\n", dev->name);
-				fsm_event(((ctc_priv *)dev->priv)->fsm,
+				fsm_event(((struct ctc_priv *) dev->priv)->fsm,
 					  DEV_EVENT_TXDOWN, dev);
 				ch_action_restart(fi, event, arg);
 				return;
 			}
 			fsm_addtimer(&ch->timer, 1000, CH_EVENT_TIMER, ch);
 			if (event == CH_EVENT_TIMER)
-				s390irq_spin_lock_irqsave(ch->irq, saveflags);
-			rc = do_IO(ch->irq, &ch->ccw[3], (intparm_t)ch, 0xff, 0);
+				spin_lock_irqsave(get_ccwdev_lock(ch->cdev),
+						  saveflags);
+			rc = ccw_device_start(ch->cdev, &ch->ccw[3],
+					      (intparm_t) ch, 0xff, 0);
 			if (event == CH_EVENT_TIMER)
-				s390irq_spin_unlock_irqrestore(ch->irq,
-							       saveflags);
+				spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev),
+						       saveflags);
 			if (rc != 0) {
 				fsm_deltimer(&ch->timer);
 				ccw_check_return_code(ch, rc);
@@ -1686,161 +1577,192 @@
  * @param event The event, just happened.
  * @param arg   Generic pointer, casted from channel * upon call.
  */
-static void ch_action_iofatal(fsm_instance *fi, int event, void *arg)
+static void
+ch_action_iofatal(fsm_instance * fi, int event, void *arg)
 {
-	channel *ch = (channel *)arg;
-	net_device *dev = ch->netdev;
+	struct channel *ch = (struct channel *) arg;
+	struct net_device *dev = ch->netdev;
 
 	fsm_deltimer(&ch->timer);
 	if (CHANNEL_DIRECTION(ch->flags) == READ) {
 		printk(KERN_DEBUG "%s: RX I/O error\n", dev->name);
 		fsm_newstate(fi, CH_STATE_RXERR);
-		fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_RXDOWN, dev);
+		fsm_event(((struct ctc_priv *) dev->priv)->fsm,
+			  DEV_EVENT_RXDOWN, dev);
 	} else {
 		printk(KERN_DEBUG "%s: TX I/O error\n", dev->name);
 		fsm_newstate(fi, CH_STATE_TXERR);
-		fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_TXDOWN, dev);
+		fsm_event(((struct ctc_priv *) dev->priv)->fsm,
+			  DEV_EVENT_TXDOWN, dev);
 	}
 }
+
+static void 
+ch_action_reinit(fsm_instance *fi, int event, void *arg)
+{
+ 	struct channel *ch = (struct channel *)arg;
+ 	struct net_device *dev = ch->netdev;
+ 	struct ctc_priv *privptr = dev->priv;
+ 
+ 	ch_action_iofatal(fi, event, arg);
+ 	fsm_addtimer(&privptr->restart_timer, 1000, DEV_EVENT_RESTART, dev);
+}
+
 
 /**
  * The statemachine for a channel.
  */
 static const fsm_node ch_fsm[] = {
-	{ CH_STATE_STOPPED,    CH_EVENT_STOP,       fsm_action_nop       },
-	{ CH_STATE_STOPPED,    CH_EVENT_START,      ch_action_start      },
-	{ CH_STATE_STOPPED,    CH_EVENT_FINSTAT,    fsm_action_nop       },
-	{ CH_STATE_STOPPED,    CH_EVENT_MC_FAIL,    fsm_action_nop       },
-
-	{ CH_STATE_NOTOP,      CH_EVENT_STOP,       ch_action_stop       },
-	{ CH_STATE_NOTOP,      CH_EVENT_START,      fsm_action_nop       },
-	{ CH_STATE_NOTOP,      CH_EVENT_FINSTAT,    fsm_action_nop       },
-	{ CH_STATE_NOTOP,      CH_EVENT_MC_FAIL,    fsm_action_nop       },
-	{ CH_STATE_NOTOP,      CH_EVENT_MC_GOOD,    ch_action_start      },
-
-	{ CH_STATE_STARTWAIT,  CH_EVENT_STOP,       ch_action_haltio     },
-	{ CH_STATE_STARTWAIT,  CH_EVENT_START,      fsm_action_nop       },
-	{ CH_STATE_STARTWAIT,  CH_EVENT_FINSTAT,    ch_action_setmode    },
-	{ CH_STATE_STARTWAIT,  CH_EVENT_TIMER,      ch_action_setuperr   },
-	{ CH_STATE_STARTWAIT,  CH_EVENT_IO_ENODEV,  ch_action_iofatal    },
-	{ CH_STATE_STARTWAIT,  CH_EVENT_IO_EIO,     ch_action_iofatal    },
-	{ CH_STATE_STARTWAIT,  CH_EVENT_MC_FAIL,    ch_action_fail       },
-
-	{ CH_STATE_STARTRETRY, CH_EVENT_STOP,       ch_action_haltio     },
-	{ CH_STATE_STARTRETRY, CH_EVENT_TIMER,      ch_action_setmode    },
-	{ CH_STATE_STARTRETRY, CH_EVENT_FINSTAT,    fsm_action_nop       },
-	{ CH_STATE_STARTRETRY, CH_EVENT_MC_FAIL,    ch_action_fail       },
-
-	{ CH_STATE_SETUPWAIT,  CH_EVENT_STOP,       ch_action_haltio     },
-	{ CH_STATE_SETUPWAIT,  CH_EVENT_START,      fsm_action_nop       },
-	{ CH_STATE_SETUPWAIT,  CH_EVENT_FINSTAT,    ch_action_firstio    },
-	{ CH_STATE_SETUPWAIT,  CH_EVENT_UC_RCRESET, ch_action_setuperr   },
-	{ CH_STATE_SETUPWAIT,  CH_EVENT_UC_RSRESET, ch_action_setuperr   },
-	{ CH_STATE_SETUPWAIT,  CH_EVENT_TIMER,      ch_action_setmode    },
-	{ CH_STATE_SETUPWAIT,  CH_EVENT_IO_ENODEV,  ch_action_iofatal    },
-	{ CH_STATE_SETUPWAIT,  CH_EVENT_IO_EIO,     ch_action_iofatal    },
-	{ CH_STATE_SETUPWAIT,  CH_EVENT_MC_FAIL,    ch_action_fail       },
-
-	{ CH_STATE_RXINIT,     CH_EVENT_STOP,       ch_action_haltio     },
-	{ CH_STATE_RXINIT,     CH_EVENT_START,      fsm_action_nop       },
-	{ CH_STATE_RXINIT,     CH_EVENT_FINSTAT,    ch_action_rxidle     },
-	{ CH_STATE_RXINIT,     CH_EVENT_UC_RCRESET, ch_action_rxiniterr  },
-	{ CH_STATE_RXINIT,     CH_EVENT_UC_RSRESET, ch_action_rxiniterr  },
-	{ CH_STATE_RXINIT,     CH_EVENT_TIMER,      ch_action_rxiniterr  },
-	{ CH_STATE_RXINIT,     CH_EVENT_ATTNBUSY,   ch_action_rxinitfail },
-	{ CH_STATE_RXINIT,     CH_EVENT_IO_ENODEV,  ch_action_iofatal    },
-	{ CH_STATE_RXINIT,     CH_EVENT_IO_EIO,     ch_action_iofatal    },
-	{ CH_STATE_RXINIT,     CH_EVENT_UC_ZERO,    ch_action_firstio    },
-	{ CH_STATE_RXINIT,     CH_EVENT_MC_FAIL,    ch_action_fail       },
-
-	{ CH_STATE_RXIDLE,     CH_EVENT_STOP,       ch_action_haltio     },
-	{ CH_STATE_RXIDLE,     CH_EVENT_START,      fsm_action_nop       },
-	{ CH_STATE_RXIDLE,     CH_EVENT_FINSTAT,    ch_action_rx         },
-	{ CH_STATE_RXIDLE,     CH_EVENT_UC_RCRESET, ch_action_rxdisc     },
-//	{ CH_STATE_RXIDLE,     CH_EVENT_UC_RSRESET, ch_action_rxretry    },
-	{ CH_STATE_RXIDLE,     CH_EVENT_IO_ENODEV,  ch_action_iofatal    },
-	{ CH_STATE_RXIDLE,     CH_EVENT_IO_EIO,     ch_action_iofatal    },
-	{ CH_STATE_RXIDLE,     CH_EVENT_MC_FAIL,    ch_action_fail       },
-	{ CH_STATE_RXIDLE,     CH_EVENT_UC_ZERO,    ch_action_rx         },
-
-	{ CH_STATE_TXINIT,     CH_EVENT_STOP,       ch_action_haltio     },
-	{ CH_STATE_TXINIT,     CH_EVENT_START,      fsm_action_nop       },
-	{ CH_STATE_TXINIT,     CH_EVENT_FINSTAT,    ch_action_txidle     },
-	{ CH_STATE_TXINIT,     CH_EVENT_UC_RCRESET, ch_action_txiniterr  },
-	{ CH_STATE_TXINIT,     CH_EVENT_UC_RSRESET, ch_action_txiniterr  },
-	{ CH_STATE_TXINIT,     CH_EVENT_TIMER,      ch_action_txiniterr  },
-	{ CH_STATE_TXINIT,     CH_EVENT_IO_ENODEV,  ch_action_iofatal    },
-	{ CH_STATE_TXINIT,     CH_EVENT_IO_EIO,     ch_action_iofatal    },
-	{ CH_STATE_TXINIT,     CH_EVENT_MC_FAIL,    ch_action_fail       },
-
-	{ CH_STATE_TXIDLE,     CH_EVENT_STOP,       ch_action_haltio     },
-	{ CH_STATE_TXIDLE,     CH_EVENT_START,      fsm_action_nop       },
-	{ CH_STATE_TXIDLE,     CH_EVENT_FINSTAT,    ch_action_firstio    },
-	{ CH_STATE_TXIDLE,     CH_EVENT_UC_RCRESET, fsm_action_nop       },
-	{ CH_STATE_TXIDLE,     CH_EVENT_UC_RSRESET, fsm_action_nop       },
-	{ CH_STATE_TXIDLE,     CH_EVENT_IO_ENODEV,  ch_action_iofatal    },
-	{ CH_STATE_TXIDLE,     CH_EVENT_IO_EIO,     ch_action_iofatal    },
-	{ CH_STATE_TXIDLE,     CH_EVENT_MC_FAIL,    ch_action_fail       },
-
-	{ CH_STATE_TERM,       CH_EVENT_STOP,       fsm_action_nop       },
-	{ CH_STATE_TERM,       CH_EVENT_START,      ch_action_restart    },
-	{ CH_STATE_TERM,       CH_EVENT_FINSTAT,    ch_action_stopped    },
-	{ CH_STATE_TERM,       CH_EVENT_UC_RCRESET, fsm_action_nop       },
-	{ CH_STATE_TERM,       CH_EVENT_UC_RSRESET, fsm_action_nop       },
-	{ CH_STATE_TERM,       CH_EVENT_MC_FAIL,    ch_action_fail       },
-
-	{ CH_STATE_DTERM,      CH_EVENT_STOP,       ch_action_haltio     },
-	{ CH_STATE_DTERM,      CH_EVENT_START,      ch_action_restart    },
-	{ CH_STATE_DTERM,      CH_EVENT_FINSTAT,    ch_action_setmode    },
-	{ CH_STATE_DTERM,      CH_EVENT_UC_RCRESET, fsm_action_nop       },
-	{ CH_STATE_DTERM,      CH_EVENT_UC_RSRESET, fsm_action_nop       },
-	{ CH_STATE_DTERM,      CH_EVENT_MC_FAIL,    ch_action_fail       },
-
-	{ CH_STATE_TX,         CH_EVENT_STOP,       ch_action_haltio     },
-	{ CH_STATE_TX,         CH_EVENT_START,      fsm_action_nop       },
-	{ CH_STATE_TX,         CH_EVENT_FINSTAT,    ch_action_txdone     },
-	{ CH_STATE_TX,         CH_EVENT_UC_RCRESET, ch_action_txretry    },
-	{ CH_STATE_TX,         CH_EVENT_UC_RSRESET, ch_action_txretry    },
-	{ CH_STATE_TX,         CH_EVENT_TIMER,      ch_action_txretry    },
-	{ CH_STATE_TX,         CH_EVENT_IO_ENODEV,  ch_action_iofatal    },
-	{ CH_STATE_TX,         CH_EVENT_IO_EIO,     ch_action_iofatal    },
-	{ CH_STATE_TX,         CH_EVENT_MC_FAIL,    ch_action_fail       },
-
-	{ CH_STATE_RXERR,      CH_EVENT_STOP,       ch_action_haltio     },
-	{ CH_STATE_TXERR,      CH_EVENT_STOP,       ch_action_haltio     },
-	{ CH_STATE_TXERR,      CH_EVENT_MC_FAIL,    ch_action_fail       },
-	{ CH_STATE_RXERR,      CH_EVENT_MC_FAIL,    ch_action_fail       },
+	{CH_STATE_STOPPED, CH_EVENT_STOP, fsm_action_nop},
+	{CH_STATE_STOPPED, CH_EVENT_START, ch_action_start},
+	{CH_STATE_STOPPED, CH_EVENT_FINSTAT, fsm_action_nop},
+	{CH_STATE_STOPPED, CH_EVENT_MC_FAIL, fsm_action_nop},
+
+	{CH_STATE_NOTOP, CH_EVENT_STOP, ch_action_stop},
+	{CH_STATE_NOTOP, CH_EVENT_START, fsm_action_nop},
+	{CH_STATE_NOTOP, CH_EVENT_FINSTAT, fsm_action_nop},
+	{CH_STATE_NOTOP, CH_EVENT_MC_FAIL, fsm_action_nop},
+	{CH_STATE_NOTOP, CH_EVENT_MC_GOOD, ch_action_start},
+
+	{CH_STATE_STARTWAIT, CH_EVENT_STOP, ch_action_haltio},
+	{CH_STATE_STARTWAIT, CH_EVENT_START, fsm_action_nop},
+	{CH_STATE_STARTWAIT, CH_EVENT_FINSTAT, ch_action_setmode},
+	{CH_STATE_STARTWAIT, CH_EVENT_TIMER, ch_action_setuperr},
+	{CH_STATE_STARTWAIT, CH_EVENT_IO_ENODEV, ch_action_iofatal},
+	{CH_STATE_STARTWAIT, CH_EVENT_IO_EIO, ch_action_reinit},
+	{CH_STATE_STARTWAIT, CH_EVENT_MC_FAIL, ch_action_fail},
+
+	{CH_STATE_STARTRETRY, CH_EVENT_STOP, ch_action_haltio},
+	{CH_STATE_STARTRETRY, CH_EVENT_TIMER, ch_action_setmode},
+	{CH_STATE_STARTRETRY, CH_EVENT_FINSTAT, fsm_action_nop},
+	{CH_STATE_STARTRETRY, CH_EVENT_MC_FAIL, ch_action_fail},
+
+	{CH_STATE_SETUPWAIT, CH_EVENT_STOP, ch_action_haltio},
+	{CH_STATE_SETUPWAIT, CH_EVENT_START, fsm_action_nop},
+	{CH_STATE_SETUPWAIT, CH_EVENT_FINSTAT, ch_action_firstio},
+	{CH_STATE_SETUPWAIT, CH_EVENT_UC_RCRESET, ch_action_setuperr},
+	{CH_STATE_SETUPWAIT, CH_EVENT_UC_RSRESET, ch_action_setuperr},
+	{CH_STATE_SETUPWAIT, CH_EVENT_TIMER, ch_action_setmode},
+	{CH_STATE_SETUPWAIT, CH_EVENT_IO_ENODEV, ch_action_iofatal},
+	{CH_STATE_SETUPWAIT, CH_EVENT_IO_EIO, ch_action_reinit},
+	{CH_STATE_SETUPWAIT, CH_EVENT_MC_FAIL, ch_action_fail},
+
+	{CH_STATE_RXINIT, CH_EVENT_STOP, ch_action_haltio},
+	{CH_STATE_RXINIT, CH_EVENT_START, fsm_action_nop},
+	{CH_STATE_RXINIT, CH_EVENT_FINSTAT, ch_action_rxidle},
+	{CH_STATE_RXINIT, CH_EVENT_UC_RCRESET, ch_action_rxiniterr},
+	{CH_STATE_RXINIT, CH_EVENT_UC_RSRESET, ch_action_rxiniterr},
+	{CH_STATE_RXINIT, CH_EVENT_TIMER, ch_action_rxiniterr},
+	{CH_STATE_RXINIT, CH_EVENT_ATTNBUSY, ch_action_rxinitfail},
+	{CH_STATE_RXINIT, CH_EVENT_IO_ENODEV, ch_action_iofatal},
+	{CH_STATE_RXINIT, CH_EVENT_IO_EIO, ch_action_reinit},
+	{CH_STATE_RXINIT, CH_EVENT_UC_ZERO, ch_action_firstio},
+	{CH_STATE_RXINIT, CH_EVENT_MC_FAIL, ch_action_fail},
+
+	{CH_STATE_RXIDLE, CH_EVENT_STOP, ch_action_haltio},
+	{CH_STATE_RXIDLE, CH_EVENT_START, fsm_action_nop},
+	{CH_STATE_RXIDLE, CH_EVENT_FINSTAT, ch_action_rx},
+	{CH_STATE_RXIDLE, CH_EVENT_UC_RCRESET, ch_action_rxdisc},
+//      { CH_STATE_RXIDLE,     CH_EVENT_UC_RSRESET, ch_action_rxretry    },
+	{CH_STATE_RXIDLE, CH_EVENT_IO_ENODEV, ch_action_iofatal},
+	{CH_STATE_RXIDLE, CH_EVENT_IO_EIO, ch_action_reinit},
+	{CH_STATE_RXIDLE, CH_EVENT_MC_FAIL, ch_action_fail},
+	{CH_STATE_RXIDLE, CH_EVENT_UC_ZERO, ch_action_rx},
+
+	{CH_STATE_TXINIT, CH_EVENT_STOP, ch_action_haltio},
+	{CH_STATE_TXINIT, CH_EVENT_START, fsm_action_nop},
+	{CH_STATE_TXINIT, CH_EVENT_FINSTAT, ch_action_txidle},
+	{CH_STATE_TXINIT, CH_EVENT_UC_RCRESET, ch_action_txiniterr},
+	{CH_STATE_TXINIT, CH_EVENT_UC_RSRESET, ch_action_txiniterr},
+	{CH_STATE_TXINIT, CH_EVENT_TIMER, ch_action_txiniterr},
+	{CH_STATE_TXINIT, CH_EVENT_IO_ENODEV, ch_action_iofatal},
+	{CH_STATE_TXINIT, CH_EVENT_IO_EIO, ch_action_reinit},
+	{CH_STATE_TXINIT, CH_EVENT_MC_FAIL, ch_action_fail},
+
+	{CH_STATE_TXIDLE, CH_EVENT_STOP, ch_action_haltio},
+	{CH_STATE_TXIDLE, CH_EVENT_START, fsm_action_nop},
+	{CH_STATE_TXIDLE, CH_EVENT_FINSTAT, ch_action_firstio},
+	{CH_STATE_TXIDLE, CH_EVENT_UC_RCRESET, fsm_action_nop},
+	{CH_STATE_TXIDLE, CH_EVENT_UC_RSRESET, fsm_action_nop},
+	{CH_STATE_TXIDLE, CH_EVENT_IO_ENODEV, ch_action_iofatal},
+	{CH_STATE_TXIDLE, CH_EVENT_IO_EIO, ch_action_reinit},
+	{CH_STATE_TXIDLE, CH_EVENT_MC_FAIL, ch_action_fail},
+
+	{CH_STATE_TERM, CH_EVENT_STOP, fsm_action_nop},
+	{CH_STATE_TERM, CH_EVENT_START, ch_action_restart},
+	{CH_STATE_TERM, CH_EVENT_FINSTAT, ch_action_stopped},
+	{CH_STATE_TERM, CH_EVENT_UC_RCRESET, fsm_action_nop},
+	{CH_STATE_TERM, CH_EVENT_UC_RSRESET, fsm_action_nop},
+	{CH_STATE_TERM, CH_EVENT_MC_FAIL, ch_action_fail},
+
+	{CH_STATE_DTERM, CH_EVENT_STOP, ch_action_haltio},
+	{CH_STATE_DTERM, CH_EVENT_START, ch_action_restart},
+	{CH_STATE_DTERM, CH_EVENT_FINSTAT, ch_action_setmode},
+	{CH_STATE_DTERM, CH_EVENT_UC_RCRESET, fsm_action_nop},
+	{CH_STATE_DTERM, CH_EVENT_UC_RSRESET, fsm_action_nop},
+	{CH_STATE_DTERM, CH_EVENT_MC_FAIL, ch_action_fail},
+
+	{CH_STATE_TX, CH_EVENT_STOP, ch_action_haltio},
+	{CH_STATE_TX, CH_EVENT_START, fsm_action_nop},
+	{CH_STATE_TX, CH_EVENT_FINSTAT, ch_action_txdone},
+	{CH_STATE_TX, CH_EVENT_UC_RCRESET, ch_action_txretry},
+	{CH_STATE_TX, CH_EVENT_UC_RSRESET, ch_action_txretry},
+	{CH_STATE_TX, CH_EVENT_TIMER, ch_action_txretry},
+	{CH_STATE_TX, CH_EVENT_IO_ENODEV, ch_action_iofatal},
+	{CH_STATE_TX, CH_EVENT_IO_EIO, ch_action_reinit},
+	{CH_STATE_TX, CH_EVENT_MC_FAIL, ch_action_fail},
+
+	{CH_STATE_RXERR, CH_EVENT_STOP, ch_action_haltio},
+	{CH_STATE_TXERR, CH_EVENT_STOP, ch_action_haltio},
+	{CH_STATE_TXERR, CH_EVENT_MC_FAIL, ch_action_fail},
+	{CH_STATE_RXERR, CH_EVENT_MC_FAIL, ch_action_fail},
 };
 
-static const int CH_FSM_LEN = sizeof(ch_fsm) / sizeof(fsm_node);
+static const int CH_FSM_LEN = sizeof (ch_fsm) / sizeof (fsm_node);
 
 /**
  * Functions related to setup and device detection.
  *****************************************************************************/
 
+static inline int
+less_than(char *id1, char *id2)
+{
+	int dev1,dev2,i;
+
+	for (i=0;i<5;i++) {
+		id1++;
+		id2++;
+	}
+	dev1 = simple_strtoul(id1, &id1, 16);
+	dev2 = simple_strtoul(id2, &id2, 16);
+	
+	return (dev1<dev2);
+}
+
 /**
  * Add a new channel to the list of channels.
  * Keeps the channel list sorted.
  *
- * @param irq   The IRQ to be used by the new channel.
- * @param devno The device number of the new channel.
+ * @param cdev  The ccw_device to be added.
  * @param type  The type class of the new channel.
  *
  * @return 0 on success, !0 on error.
  */
-static int add_channel(int irq, __u16 devno, channel_type_t type)
+static int
+add_channel(struct ccw_device *cdev, enum channel_types type)
 {
-	channel **c = &channels;
-	channel *ch;
-	char name[10];
+	struct channel **c = &channels;
+	struct channel *ch;
 
-	if ((ch = (channel *)kmalloc(sizeof(channel), GFP_KERNEL)) == NULL) {
+	if ((ch =
+	     (struct channel *) kmalloc(sizeof (struct channel),
+					GFP_KERNEL)) == NULL) {
 		printk(KERN_WARNING "ctc: Out of memory in add_channel\n");
 		return -1;
 	}
-	memset(ch, 0, sizeof(channel));
-	if ((ch->ccw = (ccw1_t *)kmalloc(sizeof(ccw1_t) * 8,
-					 GFP_KERNEL|GFP_DMA)) == NULL) {
+	memset(ch, 0, sizeof (struct channel));
+	if ((ch->ccw = (struct ccw1 *) kmalloc(sizeof (struct ccw1) * 8,
+					       GFP_KERNEL | GFP_DMA)) == NULL) {
 		kfree(ch);
 		printk(KERN_WARNING "ctc: Out of memory in add_channel\n");
 		return -1;
@@ -1866,22 +1788,21 @@
 	 * the channel's direction is yet unknown here.
 	 */
 	ch->ccw[6].cmd_code = CCW_CMD_SET_EXTENDED;
-	ch->ccw[6].flags    = CCW_FLAG_SLI;
-	ch->ccw[6].count    = 0;
-	ch->ccw[6].cda      = 0;
-	
+	ch->ccw[6].flags = CCW_FLAG_SLI;
+	ch->ccw[6].count = 0;
+	ch->ccw[6].cda = 0;
+
 	ch->ccw[7].cmd_code = CCW_CMD_NOOP;
-	ch->ccw[7].flags    = CCW_FLAG_SLI;
-	ch->ccw[7].count    = 0;
-	ch->ccw[7].cda      = 0;
+	ch->ccw[7].flags = CCW_FLAG_SLI;
+	ch->ccw[7].count = 0;
+	ch->ccw[7].cda = 0;
 
-	ch->irq = irq;
-	ch->devno = devno;
+	ch->cdev = cdev;
+	snprintf(ch->id, DEVICE_ID_SIZE, "ch-%s", cdev->dev.bus_id);
 	ch->type = type;
-	sprintf(name, "ch-%04x", devno);
-	ch->fsm = init_fsm(name, ch_state_names,
-			ch_event_names, NR_CH_STATES, NR_CH_EVENTS,
-			ch_fsm, CH_FSM_LEN, GFP_KERNEL);
+	ch->fsm = init_fsm(ch->id, ch_state_names,
+			   ch_event_names, NR_CH_STATES, NR_CH_EVENTS,
+			   ch_fsm, CH_FSM_LEN, GFP_KERNEL);
 	if (ch->fsm == NULL) {
 		printk(KERN_WARNING
 		       "ctc: Could not create FSM in add_channel\n");
@@ -1889,21 +1810,21 @@
 		return -1;
 	}
 	fsm_newstate(ch->fsm, CH_STATE_IDLE);
-	if ((ch->devstat = (devstat_t*)kmalloc(sizeof(devstat_t), GFP_KERNEL))
-	    == NULL) {
+	if ((ch->irb = (struct irb *) kmalloc(sizeof (struct irb),
+					      GFP_KERNEL)) == NULL) {
 		printk(KERN_WARNING "ctc: Out of memory in add_channel\n");
 		kfree_fsm(ch->fsm);
 		kfree(ch);
 		return -1;
 	}
-	memset(ch->devstat, 0, sizeof(devstat_t));
-	while (*c && ((*c)->devno < devno))
+	memset(ch->irb, 0, sizeof (struct irb));
+	while (*c && less_than((*c)->id, ch->id))
 		c = &(*c)->next;
-	if ((*c)->devno == devno) {
+	if (!strncmp((*c)->id, ch->id, CTC_ID_SIZE)) {
 		printk(KERN_DEBUG
-		       "ctc: add_channel: device %04x already in list, "
-		       "using old entry\n", (*c)->devno);
-		kfree(ch->devstat);
+		       "ctc: add_channel: device %s already in list, "
+		       "using old entry\n", (*c)->id);
+		kfree(ch->irb);
 		kfree_fsm(ch->fsm);
 		kfree(ch);
 		return 0;
@@ -1916,61 +1837,13 @@
 	return 0;
 }
 
-#ifndef CTC_CHANDEV
-/**
- * scan for all channels and create an entry in the channels list
- * for every supported channel.
- */
-static void channel_scan(void)
-{
-	static int      print_result = 1;
-	int	        irq;
-	int             nr_escon = 0;
-	int             nr_ctca  = 0;
-	s390_dev_info_t di;
-
-	for (irq = 0; irq < NR_IRQS; irq++) {
-		if (get_dev_info_by_irq(irq, &di) == 0) {
-			if ((di.status == DEVSTAT_NOT_OPER) ||
-			    (di.status == DEVSTAT_DEVICE_OWNED))
-				continue;
-			switch (channel_type(&di.sid_data)) {
-				case channel_type_ctca:
-					/* CTC/A */
-					if (!add_channel(irq, di.devno,
-							 channel_type_ctca))
-						nr_ctca++;
-					break;
-				case channel_type_escon:
-					/* ESCON */
-					if (!add_channel(irq, di.devno,
-							 channel_type_escon))
-						nr_escon++;
-					break;
-			default:
-			}
-		}
-	}
-	if (print_result) {
-		if (nr_escon + nr_ctca)
-			printk(KERN_INFO
-			       "ctc: %d CTC/A channel%s and %d ESCON "
-			       "channel%s found.\n",
-			       nr_ctca, (nr_ctca == 1) ? "s" : "",
-			       nr_escon, (nr_escon == 1) ? "s" : "");
-		else
-			printk(KERN_INFO "ctc: No channel devices found.\n");
-	}
-	print_result = 0;
-}
-#endif
-
 /**
  * Release a specific channel in the channel list.
  *
  * @param ch Pointer to channel struct to be released.
  */
-static void channel_free(channel *ch)
+static void
+channel_free(struct channel *ch)
 {
 	ch->flags &= ~CHANNEL_FLAGS_INUSE;
 	fsm_newstate(ch->fsm, CH_STATE_IDLE);
@@ -1981,17 +1854,14 @@
  *
  * @param ch Pointer to channel struct to be released.
  */
-static void channel_remove(channel *ch)
+static void
+channel_remove(struct channel *ch)
 {
-	channel **c = &channels;
+	struct channel **c = &channels;
 
 	if (ch == NULL)
 		return;
 
-#ifndef CTC_CHANDEV
-	if (ch->flags & CHANNEL_FLAGS_INUSE)
-		FREE_IRQ(ch->irq, ch->devstat);
-#endif
 	channel_free(ch);
 	while (*c) {
 		if (*c == ch) {
@@ -2010,84 +1880,49 @@
 	}
 }
 
-
 /**
  * Get a specific channel from the channel list.
  *
  * @param type Type of channel we are interested in.
- * @param devno Device number of channel we are interested in.
+ * @param id Id of channel we are interested in.
  * @param direction Direction we want to use this channel for.
  *
  * @return Pointer to a channel or NULL if no matching channel available.
  */
-static channel *channel_get(channel_type_t type, int devno, int direction)
-{
-	channel *ch = channels;
-
-#ifdef DEBUG
-	printk(KERN_DEBUG
-	       "ctc: %s(): searching for ch with devno %d and type %d\n",
-	       __FUNCTION__, devno, type);
-#endif
-
-	while (ch && ((ch->devno != devno) || (ch->type != type))) {
-#ifdef DEBUG
-		printk(KERN_DEBUG
-		       "ctc: %s(): ch=0x%p (devno=%d, type=%d\n",
-		       __FUNCTION__, ch, ch->devno, ch->type);
-#endif
+static struct channel
+*
+channel_get(enum channel_types type, char *id, int direction)
+{
+	struct channel *ch = channels;
+
+	pr_debug("ctc: %s(): searching for ch with id %d and type %d\n",
+		 __FUNCTION__, id, type);
+
+	while (ch && ((strncmp(ch->id, id, CTC_ID_SIZE)) || (ch->type != type))) {
+		pr_debug("ctc: %s(): ch=0x%p (id=%s, type=%d\n",
+			 __FUNCTION__, ch, ch->id, ch->type);
 		ch = ch->next;
 	}
-#ifdef DEBUG
-	printk(KERN_DEBUG
-	       "ctc: %s(): ch=0x%pq (devno=%d, type=%d\n",
-	       __FUNCTION__, ch, ch->devno, ch->type);
-#endif
+	pr_debug("ctc: %s(): ch=0x%pq (id=%s, type=%d\n",
+		 __FUNCTION__, ch, ch->id, ch->type);
 	if (!ch) {
-		printk(KERN_WARNING "ctc: %s(): channel with devno %d "
+		printk(KERN_WARNING "ctc: %s(): channel with id %s "
 		       "and type %d not found in channel list\n",
-	       __FUNCTION__, devno, type);
-	}
-	else {
+		       __FUNCTION__, id, type);
+	} else {
 		if (ch->flags & CHANNEL_FLAGS_INUSE)
 			ch = NULL;
 		else {
 			ch->flags |= CHANNEL_FLAGS_INUSE;
 			ch->flags &= ~CHANNEL_FLAGS_RWMASK;
 			ch->flags |= (direction == WRITE)
-				? CHANNEL_FLAGS_WRITE:CHANNEL_FLAGS_READ;
+			    ? CHANNEL_FLAGS_WRITE : CHANNEL_FLAGS_READ;
 			fsm_newstate(ch->fsm, CH_STATE_STOPPED);
 		}
 	}
 	return ch;
 }
 
-#ifndef CTC_CHANDEV
-/**
- * Get the next free channel from the channel list
- *
- * @param type Type of channel we are interested in.
- * @param direction Direction we want to use this channel for.
- *
- * @return Pointer to a channel or NULL if no matching channel available.
- */
-static channel *channel_get_next(channel_type_t type, int direction)
-{
-	channel *ch = channels;
-
-	while (ch && (ch->type != type || (ch->flags & CHANNEL_FLAGS_INUSE)))
-		ch = ch->next;
-	if (ch) {
-		ch->flags |= CHANNEL_FLAGS_INUSE;
-		ch->flags &= ~CHANNEL_FLAGS_RWMASK;
-		ch->flags |= (direction == WRITE)
-			? CHANNEL_FLAGS_WRITE:CHANNEL_FLAGS_READ;
-		fsm_newstate(ch->fsm, CH_STATE_STOPPED);
-	}
-	return ch;
-}
-#endif
-
 /**
  * Return the channel type by name.
  *
@@ -2095,13 +1930,14 @@
  *
  * @return Type class of channel to be used for that interface.
  */
-static channel_type_t inline extract_channel_media(char *name)
+static enum channel_types inline
+extract_channel_media(char *name)
 {
-	channel_type_t ret = channel_type_unknown;
+	enum channel_types ret = channel_type_unknown;
 
 	if (name != NULL) {
 		if (strncmp(name, "ctc", 3) == 0)
-			ret = channel_type_ctca;
+			ret = channel_type_parallel;
 		if (strncmp(name, "escon", 5) == 0)
 			ret = channel_type_escon;
 	}
@@ -2109,98 +1945,82 @@
 }
 
 /**
- * Find a channel in the list by its IRQ.
- *
- * @param irq IRQ to search for.
+ * Main IRQ handler.
  *
- * @return Pointer to channel or NULL if no matching channel found.
+ * @param cdev    The ccw_device the interrupt is for.
+ * @param intparm interruption parameter.
+ * @param irb     interruption response block.
  */
-static channel *find_channel_by_irq(int irq)
+static void
+ctc_irq_handler(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
 {
-	channel *ch = channels;
-	while (ch && (ch->irq != irq))
-		ch = ch->next;
-	return ch;
-}
-
-/**
- * Main IRQ handler.
- *
- * @param irq     The IRQ to handle.
- * @param intparm IRQ params.
- * @param regs    CPU registers.
- */
-static void ctc_irq_handler (int irq, void *intparm, struct pt_regs *regs)
-{
-	devstat_t  *devstat = (devstat_t *)intparm;
-	channel    *ch = (channel *)devstat->intparm;
-	net_device *dev;
-
+	struct channel *ch;
+	struct net_device *dev;
+	
+	ch = (struct channel *) intparm;
 	/**
 	 * Check for unsolicited interrupts.
-	 * If intparm is NULL, then loop over all our known
-	 * channels and try matching the irq number.
+	 * If intparm is NULL, try to get channel from ccw_device.
 	 */
 	if (ch == NULL) {
-		if ((ch = find_channel_by_irq(irq)) == NULL) {
+		ch = container_of(&cdev, struct channel, cdev);
+ 		if (ch == NULL) {
 			printk(KERN_WARNING
-			       "ctc: Got unsolicited irq: %04x c-%02x d-%02x"
-			       "f-%02x\n", devstat->devno, devstat->cstat,
-			       devstat->dstat, devstat->flag);
-			goto done;
+			       "ctc: Got unsolicited irq: %s c-%02x d-%02x\n",
+			       cdev->dev.bus_id, irb->scsw.cstat,
+			       irb->scsw.dstat);
+			return;
 		}
 	}
 
-	dev = (net_device *)(ch->netdev);
+	dev = (struct net_device *) (ch->netdev);
 	if (dev == NULL) {
 		printk(KERN_CRIT
-		       "ctc: ctc_irq_handler dev = NULL irq=%d, ch=0x%p\n",
-		       irq, ch);
-		goto done;
-	}
-	if (intparm == NULL)
-		printk(KERN_DEBUG "%s: Channel %04x found by IRQ %d\n",
-		       dev->name, ch->devno, irq);
+		       "ctc: ctc_irq_handler dev = NULL bus_id=%s, ch=0x%p\n",
+		       cdev->dev.bus_id, ch);
+		return;
+	}
 
-#ifdef DEBUG
-	printk(KERN_DEBUG
-	       "%s: interrupt for device: %04x received c-%02x d-%02x "
-	       "f-%02x\n", dev->name, devstat->devno, devstat->cstat,
-	       devstat->dstat, devstat->flag);
-#endif
+	pr_debug("%s: interrupt for device: %s received c-%02x d-%02x\n"
+		 dev->name, ch->id, irb->scsw.cstat, irb->scsw.dstat);
+
+	/* Copy interruption response block. */
+	memcpy(ch->irb, irb, sizeof(struct irb));
 
 	/* Check for good subchannel return code, otherwise error message */
-	if (devstat->cstat) {
+	if (ch->irb->scsw.cstat) {
 		fsm_event(ch->fsm, CH_EVENT_SC_UNKNOWN, ch);
 		printk(KERN_WARNING
-		       "%s: subchannel check for device: %04x - %02x %02x "
-		       "%02x\n", dev->name, ch->devno, devstat->cstat,
-		       devstat->dstat, devstat->flag);
-		goto done;
+		       "%s: subchannel check for device: %s - %02x %02x\n",
+		       dev->name, ch->id, ch->irb->scsw.cstat,
+		       ch->irb->scsw.dstat);
+		return;
 	}
 
 	/* Check the reason-code of a unit check */
-	if (devstat->dstat & DEV_STAT_UNIT_CHECK) {
-		ccw_unit_check(ch, devstat->ii.sense.data[0]);
-		goto done;
+	if (ch->irb->scsw.dstat & DEV_STAT_UNIT_CHECK) {
+		ccw_unit_check(ch, ch->irb->ecw[0]);
+		return;
 	}
-	if (devstat->dstat & DEV_STAT_BUSY) {
-		if (devstat->dstat & DEV_STAT_ATTENTION)
+	if (ch->irb->scsw.dstat & DEV_STAT_BUSY) {
+		if (ch->irb->scsw.dstat & DEV_STAT_ATTENTION)
 			fsm_event(ch->fsm, CH_EVENT_ATTNBUSY, ch);
 		else
 			fsm_event(ch->fsm, CH_EVENT_BUSY, ch);
-		goto done;
+		return;
 	}
-	if (devstat->dstat & DEV_STAT_ATTENTION) {
+	if (ch->irb->scsw.dstat & DEV_STAT_ATTENTION) {
 		fsm_event(ch->fsm, CH_EVENT_ATTN, ch);
-		goto done;
+		return;
 	}
-	if (devstat->flag & DEVSTAT_FINAL_STATUS)
+	if ((ch->irb->scsw.stctl & SCSW_STCTL_SEC_STATUS) ||
+	    (ch->irb->scsw.stctl == SCSW_STCTL_STATUS_PEND) ||
+	    (ch->irb->scsw.stctl ==
+	     (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)))
 		fsm_event(ch->fsm, CH_EVENT_FINSTAT, ch);
 	else
 		fsm_event(ch->fsm, CH_EVENT_IRQ, ch);
 
- done:
 }
 
 /**
@@ -2212,17 +2032,19 @@
  *
  * @param fi    An instance of an interface statemachine.
  * @param event The event, just happened.
- * @param arg   Generic pointer, casted from net_device * upon call.
+ * @param arg   Generic pointer, casted from struct net_device * upon call.
  */
-static void dev_action_start(fsm_instance *fi, int event, void *arg)
+static void
+dev_action_start(fsm_instance * fi, int event, void *arg)
 {
-	net_device *dev = (net_device *)arg;
-	ctc_priv   *privptr = dev->priv;
-	int        direction;
+	struct net_device *dev = (struct net_device *) arg;
+	struct ctc_priv *privptr = dev->priv;
+	int direction;
 
+	fsm_deltimer(&privptr->restart_timer);
 	fsm_newstate(fi, DEV_STATE_STARTWAIT_RXTX);
 	for (direction = READ; direction <= WRITE; direction++) {
-		channel *ch = privptr->channel[direction];
+		struct channel *ch = privptr->channel[direction];
 		fsm_event(ch->fsm, CH_EVENT_START, ch);
 	}
 }
@@ -2232,20 +2054,33 @@
  *
  * @param fi    An instance of an interface statemachine.
  * @param event The event, just happened.
- * @param arg   Generic pointer, casted from net_device * upon call.
+ * @param arg   Generic pointer, casted from struct net_device * upon call.
  */
-static void dev_action_stop(fsm_instance *fi, int event, void *arg)
+static void
+dev_action_stop(fsm_instance * fi, int event, void *arg)
 {
-	net_device *dev = (net_device *)arg;
-	ctc_priv   *privptr = dev->priv;
-	int        direction;
+	struct net_device *dev = (struct net_device *) arg;
+	struct ctc_priv *privptr = dev->priv;
+	int direction;
 
 	fsm_newstate(fi, DEV_STATE_STOPWAIT_RXTX);
 	for (direction = READ; direction <= WRITE; direction++) {
-		channel *ch = privptr->channel[direction];
+		struct channel *ch = privptr->channel[direction];
 		fsm_event(ch->fsm, CH_EVENT_STOP, ch);
 	}
 }
+static void 
+dev_action_restart(fsm_instance *fi, int event, void *arg)
+{
+	struct net_device *dev = (struct net_device *)arg;
+	struct ctc_priv *privptr = dev->priv;
+	
+	printk(KERN_DEBUG "%s: Restarting\n", dev->name);
+	dev_action_stop(fi, event, arg);
+	fsm_event(privptr->fsm, DEV_EVENT_STOP, dev);
+	fsm_addtimer(&privptr->restart_timer, CTC_TIMEOUT_5SEC,
+		     DEV_EVENT_START, dev);
+}
 
 /**
  * Called from channel statemachine
@@ -2253,50 +2088,49 @@
  *
  * @param fi    An instance of an interface statemachine.
  * @param event The event, just happened.
- * @param arg   Generic pointer, casted from net_device * upon call.
+ * @param arg   Generic pointer, casted from struct net_device * upon call.
  */
-static void dev_action_chup(fsm_instance *fi, int event, void *arg)
+static void
+dev_action_chup(fsm_instance * fi, int event, void *arg)
 {
-	net_device *dev = (net_device *)arg;
-	ctc_priv   *privptr = dev->priv;
+	struct net_device *dev = (struct net_device *) arg;
+	struct ctc_priv *privptr = dev->priv;
 
 	switch (fsm_getstate(fi)) {
-		case DEV_STATE_STARTWAIT_RXTX:
-			if (event == DEV_EVENT_RXUP)
-				fsm_newstate(fi, DEV_STATE_STARTWAIT_TX);
-			else
-				fsm_newstate(fi, DEV_STATE_STARTWAIT_RX);
-			break;
-		case DEV_STATE_STARTWAIT_RX:
-			if (event == DEV_EVENT_RXUP) {
-				fsm_newstate(fi, DEV_STATE_RUNNING);
-				printk(KERN_INFO
-				       "%s: connected with remote side\n",
-				       dev->name);
-				if (privptr->protocol == CTC_PROTO_LINUX_TTY)
-					ctc_tty_setcarrier(dev, 1);
-				ctc_clear_busy(dev);
-			}
-			break;
-		case DEV_STATE_STARTWAIT_TX:
-			if (event == DEV_EVENT_TXUP) {
-				fsm_newstate(fi, DEV_STATE_RUNNING);
-				printk(KERN_INFO
-				       "%s: connected with remote side\n",
-				       dev->name);
-				if (privptr->protocol == CTC_PROTO_LINUX_TTY)
-					ctc_tty_setcarrier(dev, 1);
-				ctc_clear_busy(dev);
-			}
-			break;
-		case DEV_STATE_STOPWAIT_TX:
-			if (event == DEV_EVENT_RXUP)
-				fsm_newstate(fi, DEV_STATE_STOPWAIT_RXTX);
-			break;
-		case DEV_STATE_STOPWAIT_RX:
-			if (event == DEV_EVENT_TXUP)
-				fsm_newstate(fi, DEV_STATE_STOPWAIT_RXTX);
-			break;
+	case DEV_STATE_STARTWAIT_RXTX:
+		if (event == DEV_EVENT_RXUP)
+			fsm_newstate(fi, DEV_STATE_STARTWAIT_TX);
+		else
+			fsm_newstate(fi, DEV_STATE_STARTWAIT_RX);
+		break;
+	case DEV_STATE_STARTWAIT_RX:
+		if (event == DEV_EVENT_RXUP) {
+			fsm_newstate(fi, DEV_STATE_RUNNING);
+			printk(KERN_INFO
+			       "%s: connected with remote side\n", dev->name);
+			if (privptr->protocol == CTC_PROTO_LINUX_TTY)
+				ctc_tty_setcarrier(dev, 1);
+			ctc_clear_busy(dev);
+		}
+		break;
+	case DEV_STATE_STARTWAIT_TX:
+		if (event == DEV_EVENT_TXUP) {
+			fsm_newstate(fi, DEV_STATE_RUNNING);
+			printk(KERN_INFO
+			       "%s: connected with remote side\n", dev->name);
+			if (privptr->protocol == CTC_PROTO_LINUX_TTY)
+				ctc_tty_setcarrier(dev, 1);
+			ctc_clear_busy(dev);
+		}
+		break;
+	case DEV_STATE_STOPWAIT_TX:
+		if (event == DEV_EVENT_RXUP)
+			fsm_newstate(fi, DEV_STATE_STOPWAIT_RXTX);
+		break;
+	case DEV_STATE_STOPWAIT_RX:
+		if (event == DEV_EVENT_TXUP)
+			fsm_newstate(fi, DEV_STATE_STOPWAIT_RXTX);
+		break;
 	}
 }
 
@@ -2306,88 +2140,96 @@
  *
  * @param fi    An instance of an interface statemachine.
  * @param event The event, just happened.
- * @param arg   Generic pointer, casted from net_device * upon call.
+ * @param arg   Generic pointer, casted from struct net_device * upon call.
  */
-static void dev_action_chdown(fsm_instance *fi, int event, void *arg)
+static void
+dev_action_chdown(fsm_instance * fi, int event, void *arg)
 {
-	net_device *dev = (net_device *)arg;
-	ctc_priv   *privptr = dev->priv;
+	struct net_device *dev = (struct net_device *) arg;
+	struct ctc_priv *privptr = dev->priv;
 
 	switch (fsm_getstate(fi)) {
-		case DEV_STATE_RUNNING:
-			if (privptr->protocol == CTC_PROTO_LINUX_TTY)
-				ctc_tty_setcarrier(dev, 0);
-			if (event == DEV_EVENT_TXDOWN)
-				fsm_newstate(fi, DEV_STATE_STARTWAIT_TX);
-			else
-				fsm_newstate(fi, DEV_STATE_STARTWAIT_RX);
-			break;
-		case DEV_STATE_STARTWAIT_RX:
-			if (event == DEV_EVENT_TXDOWN)
-				fsm_newstate(fi, DEV_STATE_STARTWAIT_RXTX);
-			break;
-		case DEV_STATE_STARTWAIT_TX:
-			if (event == DEV_EVENT_RXDOWN)
-				fsm_newstate(fi, DEV_STATE_STARTWAIT_RXTX);
-			break;
-		case DEV_STATE_STOPWAIT_RXTX:
-			if (event == DEV_EVENT_TXDOWN)
-				fsm_newstate(fi, DEV_STATE_STOPWAIT_RX);
-			else
-				fsm_newstate(fi, DEV_STATE_STOPWAIT_TX);
-			break;
-		case DEV_STATE_STOPWAIT_RX:
-			if (event == DEV_EVENT_RXDOWN)
-				fsm_newstate(fi, DEV_STATE_STOPPED);
-			break;
-		case DEV_STATE_STOPWAIT_TX:
-			if (event == DEV_EVENT_TXDOWN)
-				fsm_newstate(fi, DEV_STATE_STOPPED);
-			break;
+	case DEV_STATE_RUNNING:
+		if (privptr->protocol == CTC_PROTO_LINUX_TTY)
+			ctc_tty_setcarrier(dev, 0);
+		if (event == DEV_EVENT_TXDOWN)
+			fsm_newstate(fi, DEV_STATE_STARTWAIT_TX);
+		else
+			fsm_newstate(fi, DEV_STATE_STARTWAIT_RX);
+		break;
+	case DEV_STATE_STARTWAIT_RX:
+		if (event == DEV_EVENT_TXDOWN)
+			fsm_newstate(fi, DEV_STATE_STARTWAIT_RXTX);
+		break;
+	case DEV_STATE_STARTWAIT_TX:
+		if (event == DEV_EVENT_RXDOWN)
+			fsm_newstate(fi, DEV_STATE_STARTWAIT_RXTX);
+		break;
+	case DEV_STATE_STOPWAIT_RXTX:
+		if (event == DEV_EVENT_TXDOWN)
+			fsm_newstate(fi, DEV_STATE_STOPWAIT_RX);
+		else
+			fsm_newstate(fi, DEV_STATE_STOPWAIT_TX);
+		break;
+	case DEV_STATE_STOPWAIT_RX:
+		if (event == DEV_EVENT_RXDOWN)
+			fsm_newstate(fi, DEV_STATE_STOPPED);
+		break;
+	case DEV_STATE_STOPWAIT_TX:
+		if (event == DEV_EVENT_TXDOWN)
+			fsm_newstate(fi, DEV_STATE_STOPPED);
+		break;
 	}
 }
 
 static const fsm_node dev_fsm[] = {
-	{ DEV_STATE_STOPPED,        DEV_EVENT_START,   dev_action_start  },
+	{DEV_STATE_STOPPED, DEV_EVENT_START, dev_action_start},
 
-	{ DEV_STATE_STOPWAIT_RXTX,  DEV_EVENT_START,   dev_action_start  },
-	{ DEV_STATE_STOPWAIT_RXTX,  DEV_EVENT_RXDOWN,  dev_action_chdown },
-	{ DEV_STATE_STOPWAIT_RXTX,  DEV_EVENT_TXDOWN,  dev_action_chdown },
-
-	{ DEV_STATE_STOPWAIT_RX,    DEV_EVENT_START,   dev_action_start  },
-	{ DEV_STATE_STOPWAIT_RX,    DEV_EVENT_RXUP,    dev_action_chup   },
-	{ DEV_STATE_STOPWAIT_RX,    DEV_EVENT_TXUP,    dev_action_chup   },
-	{ DEV_STATE_STOPWAIT_RX,    DEV_EVENT_RXDOWN,  dev_action_chdown },
-
-	{ DEV_STATE_STOPWAIT_TX,    DEV_EVENT_START,   dev_action_start  },
-	{ DEV_STATE_STOPWAIT_TX,    DEV_EVENT_RXUP,    dev_action_chup   },
-	{ DEV_STATE_STOPWAIT_TX,    DEV_EVENT_TXUP,    dev_action_chup   },
-	{ DEV_STATE_STOPWAIT_TX,    DEV_EVENT_TXDOWN,  dev_action_chdown },
-
-	{ DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_STOP,    dev_action_stop   },
-	{ DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RXUP,    dev_action_chup   },
-	{ DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_TXUP,    dev_action_chup   },
-	{ DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RXDOWN,  dev_action_chdown },
-	{ DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_TXDOWN,  dev_action_chdown },
-
-	{ DEV_STATE_STARTWAIT_TX,   DEV_EVENT_STOP,    dev_action_stop   },
-	{ DEV_STATE_STARTWAIT_TX,   DEV_EVENT_RXUP,    dev_action_chup   },
-	{ DEV_STATE_STARTWAIT_TX,   DEV_EVENT_TXUP,    dev_action_chup   },
-	{ DEV_STATE_STARTWAIT_TX,   DEV_EVENT_RXDOWN,  dev_action_chdown },
-
-	{ DEV_STATE_STARTWAIT_RX,   DEV_EVENT_STOP,    dev_action_stop   },
-	{ DEV_STATE_STARTWAIT_RX,   DEV_EVENT_RXUP,    dev_action_chup   },
-	{ DEV_STATE_STARTWAIT_RX,   DEV_EVENT_TXUP,    dev_action_chup   },
-	{ DEV_STATE_STARTWAIT_RX,   DEV_EVENT_TXDOWN,  dev_action_chdown },
-
-	{ DEV_STATE_RUNNING,        DEV_EVENT_STOP,    dev_action_stop   },
-	{ DEV_STATE_RUNNING,        DEV_EVENT_RXDOWN,  dev_action_chdown },
-	{ DEV_STATE_RUNNING,        DEV_EVENT_TXDOWN,  dev_action_chdown },
-	{ DEV_STATE_RUNNING,        DEV_EVENT_TXUP,    fsm_action_nop    },
-	{ DEV_STATE_RUNNING,        DEV_EVENT_RXUP,    fsm_action_nop    },
+	{DEV_STATE_STOPWAIT_RXTX, DEV_EVENT_START, dev_action_start},
+	{DEV_STATE_STOPWAIT_RXTX, DEV_EVENT_RXDOWN, dev_action_chdown},
+	{DEV_STATE_STOPWAIT_RXTX, DEV_EVENT_TXDOWN, dev_action_chdown},
+ 	{DEV_STATE_STOPWAIT_RXTX, DEV_EVENT_RESTART, dev_action_restart },
+
+	{DEV_STATE_STOPWAIT_RX, DEV_EVENT_START, dev_action_start},
+	{DEV_STATE_STOPWAIT_RX, DEV_EVENT_RXUP, dev_action_chup},
+	{DEV_STATE_STOPWAIT_RX, DEV_EVENT_TXUP, dev_action_chup},
+	{DEV_STATE_STOPWAIT_RX, DEV_EVENT_RXDOWN, dev_action_chdown},
+ 	{DEV_STATE_STOPWAIT_RX, DEV_EVENT_RESTART, dev_action_restart },
+
+	{DEV_STATE_STOPWAIT_TX, DEV_EVENT_START, dev_action_start},
+	{DEV_STATE_STOPWAIT_TX, DEV_EVENT_RXUP, dev_action_chup},
+	{DEV_STATE_STOPWAIT_TX, DEV_EVENT_TXUP, dev_action_chup},
+	{DEV_STATE_STOPWAIT_TX, DEV_EVENT_TXDOWN, dev_action_chdown},
+ 	{DEV_STATE_STOPWAIT_TX, DEV_EVENT_RESTART, dev_action_restart },
+
+	{DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_STOP, dev_action_stop},
+	{DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RXUP, dev_action_chup},
+	{DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_TXUP, dev_action_chup},
+	{DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RXDOWN, dev_action_chdown},
+	{DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_TXDOWN, dev_action_chdown},
+ 	{DEV_STATE_STARTWAIT_RXTX, DEV_EVENT_RESTART, dev_action_restart },
+
+	{DEV_STATE_STARTWAIT_TX, DEV_EVENT_STOP, dev_action_stop},
+	{DEV_STATE_STARTWAIT_TX, DEV_EVENT_RXUP, dev_action_chup},
+	{DEV_STATE_STARTWAIT_TX, DEV_EVENT_TXUP, dev_action_chup},
+	{DEV_STATE_STARTWAIT_TX, DEV_EVENT_RXDOWN, dev_action_chdown},
+ 	{DEV_STATE_STARTWAIT_TX, DEV_EVENT_RESTART, dev_action_restart },
+
+	{DEV_STATE_STARTWAIT_RX, DEV_EVENT_STOP, dev_action_stop},
+	{DEV_STATE_STARTWAIT_RX, DEV_EVENT_RXUP, dev_action_chup},
+	{DEV_STATE_STARTWAIT_RX, DEV_EVENT_TXUP, dev_action_chup},
+	{DEV_STATE_STARTWAIT_RX, DEV_EVENT_TXDOWN, dev_action_chdown},
+ 	{DEV_STATE_STARTWAIT_RX, DEV_EVENT_RESTART, dev_action_restart },
+
+	{DEV_STATE_RUNNING, DEV_EVENT_STOP, dev_action_stop},
+	{DEV_STATE_RUNNING, DEV_EVENT_RXDOWN, dev_action_chdown},
+	{DEV_STATE_RUNNING, DEV_EVENT_TXDOWN, dev_action_chdown},
+	{DEV_STATE_RUNNING, DEV_EVENT_TXUP, fsm_action_nop},
+	{DEV_STATE_RUNNING, DEV_EVENT_RXUP, fsm_action_nop},
+ 	{DEV_STATE_RUNNING, DEV_EVENT_RESTART, dev_action_restart },
 };
 
-static const int DEV_FSM_LEN = sizeof(dev_fsm) / sizeof(fsm_node);
+static const int DEV_FSM_LEN = sizeof (dev_fsm) / sizeof (fsm_node);
 
 /**
  * Transmit a packet.
@@ -2400,10 +2242,12 @@
  *
  * @return 0 on success, -ERRNO on failure. (Never fails.)
  */
-static int transmit_skb(channel *ch, struct sk_buff *skb) {
+static int
+transmit_skb(struct channel *ch, struct sk_buff *skb)
+{
 	unsigned long saveflags;
-	ll_header header;
-	int       rc = 0;
+	struct ll_header header;
+	int rc = 0;
 
 	if (fsm_getstate(ch->fsm) != CH_STATE_TXIDLE) {
 		int l = skb->len + LL_HEADER_LENGTH;
@@ -2440,13 +2284,13 @@
 		memcpy(skb_push(skb, LL_HEADER_LENGTH), &header,
 		       LL_HEADER_LENGTH);
 		block_len = skb->len + 2;
-		*((__u16 *)skb_push(skb, 2)) = block_len;
+		*((__u16 *) skb_push(skb, 2)) = block_len;
 
 		/**
 		 * IDAL support in CTC is broken, so we have to
 		 * care about skb's above 2G ourselves.
 		 */
-		hi = ((unsigned long)skb->tail + LL_HEADER_LENGTH) >> 31;
+		hi = ((unsigned long) skb->tail + LL_HEADER_LENGTH) >> 31;
 		if (hi) {
 			nskb = alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
 			if (!nskb) {
@@ -2494,12 +2338,12 @@
 		}
 		ch->retry = 0;
 		fsm_newstate(ch->fsm, CH_STATE_TX);
-		fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC,
-			     CH_EVENT_TIMER, ch);
-		s390irq_spin_lock_irqsave(ch->irq, saveflags);
+		fsm_addtimer(&ch->timer, CTC_TIMEOUT_5SEC, CH_EVENT_TIMER, ch);
+		spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
 		ch->prof.send_stamp = xtime;
-		rc = do_IO(ch->irq, &ch->ccw[ccw_idx], (intparm_t)ch, 0xff, 0);
-		s390irq_spin_unlock_irqrestore(ch->irq, saveflags);
+		rc = ccw_device_start(ch->cdev, &ch->ccw[ccw_idx],
+				      (intparm_t) ch, 0xff, 0);
+		spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
 		if (ccw_idx == 3)
 			ch->prof.doios_single++;
 		if (rc != 0) {
@@ -2514,11 +2358,11 @@
 			skb_pull(skb, LL_HEADER_LENGTH + 2);
 		} else {
 			if (ccw_idx == 0) {
-				net_device *dev = ch->netdev;
-				ctc_priv   *privptr = dev->priv;
+				struct net_device *dev = ch->netdev;
+				struct ctc_priv *privptr = dev->priv;
 				privptr->stats.tx_packets++;
 				privptr->stats.tx_bytes +=
-					skb->len - LL_HEADER_LENGTH;
+				    skb->len - LL_HEADER_LENGTH;
 			}
 		}
 	}
@@ -2538,9 +2382,11 @@
  *
  * @return 0 on success, -ERRNO on failure. (Never fails.)
  */
-static int ctc_open(net_device *dev) {
+static int
+ctc_open(struct net_device * dev)
+{
 	MOD_INC_USE_COUNT;
-	fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_START, dev);
+	fsm_event(((struct ctc_priv *) dev->priv)->fsm, DEV_EVENT_START, dev);
 	return 0;
 }
 
@@ -2552,9 +2398,11 @@
  *
  * @return 0 on success, -ERRNO on failure. (Never fails.)
  */
-static int ctc_close(net_device *dev) {
+static int
+ctc_close(struct net_device * dev)
+{
 	SET_DEVICE_START(dev, 0);
-	fsm_event(((ctc_priv *)dev->priv)->fsm, DEV_EVENT_STOP, dev);
+	fsm_event(((struct ctc_priv *) dev->priv)->fsm, DEV_EVENT_STOP, dev);
 	MOD_DEC_USE_COUNT;
 	return 0;
 }
@@ -2570,10 +2418,11 @@
  *         Note: If we return !0, then the packet is free'd by
  *               the generic network layer.
  */
-static int ctc_tx(struct sk_buff *skb, net_device *dev)
+static int
+ctc_tx(struct sk_buff *skb, struct net_device * dev)
 {
-	int       rc = 0;
-	ctc_priv  *privptr = (ctc_priv *)dev->priv;
+	int rc = 0;
+	struct ctc_priv *privptr = (struct ctc_priv *) dev->priv;
 
 	/**
 	 * Some sanity checks ...
@@ -2619,7 +2468,6 @@
 	return rc;
 }
 
-
 /**
  * Sets MTU of an interface.
  *
@@ -2631,8 +2479,10 @@
  *         remote side, maximum MTU is 32760, however this is
  *         <em>not</em> checked here.
  */
-static int ctc_change_mtu(net_device *dev, int new_mtu) {
-	ctc_priv  *privptr = (ctc_priv *)dev->priv;
+static int
+ctc_change_mtu(struct net_device * dev, int new_mtu)
+{
+	struct ctc_priv *privptr = (struct ctc_priv *) dev->priv;
 
 	if ((new_mtu < 576) || (new_mtu > 65527) ||
 	    (new_mtu > (privptr->channel[READ]->max_bufsize -
@@ -2643,7 +2493,6 @@
 	return 0;
 }
 
-
 /**
  * Returns interface statistics of a device.
  *
@@ -2651,134 +2500,89 @@
  *
  * @return Pointer to stats struct of this interface.
  */
-static struct net_device_stats *ctc_stats(net_device *dev) {
-	return &((ctc_priv *)dev->priv)->stats;
-}
-
-/**
- * procfs related structures and routines
- *****************************************************************************/
-
-static net_device *find_netdev_by_ino(struct proc_dir_entry *pde)
+static struct net_device_stats *
+ctc_stats(struct net_device * dev)
 {
-	channel *ch = channels;
-	net_device *dev = NULL;
-	ctc_priv *privptr;
-
-	while (ch) {
-		if (ch->netdev != dev) {
-			dev = ch->netdev;
-			privptr = (ctc_priv *)dev->priv;
-
-			if ((privptr->proc_ctrl_entry == pde) ||
-			    (privptr->proc_stat_entry == pde))
-				return dev;
-		}
-		ch = ch->next;
-	}
-	return NULL;
+	return &((struct ctc_priv *) dev->priv)->stats;
 }
 
+/*
+ * sysfs attributes
+ */
 #define CTRL_BUFSIZE 40
 
-static int ctc_ctrl_open(struct inode *inode, struct file *file)
+static ssize_t
+buffer_show(struct device *dev, char *buf, size_t count, loff_t off)
 {
-	file->private_data = kmalloc(CTRL_BUFSIZE, GFP_KERNEL);
-	if (file->private_data == NULL)
-		return -ENOMEM;
-	MOD_INC_USE_COUNT;
-	return 0;
-}
+	struct ctc_priv *priv;
 
-static int ctc_ctrl_close(struct inode *inode, struct file *file)
-{
-	kfree(file->private_data);
-	MOD_DEC_USE_COUNT;
-	return 0;
+	priv = dev->driver_data;
+	if (!priv)
+		return -ENODEV;
+	return off ? 0 : snprintf(buf, count, "%d\n",
+				  priv->channel[READ]->max_bufsize);
 }
 
-static ssize_t ctc_ctrl_write(struct file *file, const char *buf, size_t count,
-			   loff_t *off)
+static ssize_t
+buffer_write(struct device *dev, const char *buf, size_t count, loff_t off)
 {
-	struct proc_dir_entry *pde = PDE(file->f_dentry->d_inode);
-	net_device   *dev;
-	ctc_priv     *privptr;
-	char         *e;
-	int          bs1;
-	char         tmp[40];
-
-	if (!(dev = find_netdev_by_ino(pde)))
-		return -ENODEV;
-	if (off != &file->f_pos)
-		return -ESPIPE;
+	struct ctc_priv *priv;
+	struct net_device *ndev;
+	int bs1;
 
-	privptr = (ctc_priv *)dev->priv;
-
-	if (count >= 39)
-		return -EINVAL;
+	if (off)
+		return 0;
 
-	if (copy_from_user(tmp, buf, count))
-		return -EFAULT;
-	tmp[count+1] = '\0';
-	bs1 = simple_strtoul(tmp, &e, 0);
+	priv = dev->driver_data;
+	if (!priv)
+		return -ENODEV;
+	ndev = container_of((void *) priv, struct net_device, priv);
+	if (!ndev)
+		return -ENODEV;
+	sscanf(buf, "%u", &bs1);
 
-	if ((bs1 > CTC_BUFSIZE_LIMIT) ||
-	    (e && (!isspace(*e))))
+	if (bs1 > CTC_BUFSIZE_LIMIT)
 		return -EINVAL;
-	if ((dev->flags & IFF_RUNNING) &&
-	    (bs1 < (dev->mtu + LL_HEADER_LENGTH + 2)))
+	if ((ndev->flags & IFF_RUNNING) &&
+	    (bs1 < (ndev->mtu + LL_HEADER_LENGTH + 2)))
 		return -EINVAL;
 	if (bs1 < (576 + LL_HEADER_LENGTH + 2))
 		return -EINVAL;
 
-
-	privptr->channel[READ]->max_bufsize =
-		privptr->channel[WRITE]->max_bufsize = bs1;
-	if (!(dev->flags & IFF_RUNNING))
-		dev->mtu = bs1 - LL_HEADER_LENGTH - 2;
-	privptr->channel[READ]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED;
-	privptr->channel[WRITE]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED;
+	priv->channel[READ]->max_bufsize =
+	    priv->channel[WRITE]->max_bufsize = bs1;
+	if (!(ndev->flags & IFF_RUNNING))
+		ndev->mtu = bs1 - LL_HEADER_LENGTH - 2;
+	priv->channel[READ]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED;
+	priv->channel[WRITE]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED;
 
 	return count;
+
 }
 
-static ssize_t ctc_ctrl_read(struct file *file, char *buf, size_t count,
-			  loff_t *off)
-{
-	struct proc_dir_entry *pde = PDE(file->f_dentry->d_inode);
-	char *sbuf = (char *)file->private_data;
-	net_device *dev;
-	ctc_priv *privptr;
-	ssize_t ret = 0;
-	char *p = sbuf;
-	int l;
+static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write);
 
-	if (!(dev = find_netdev_by_ino(pde)))
-		return -ENODEV;
-	if (off != &file->f_pos)
-		return -ESPIPE;
+static int
+ctc_add_attributes(struct device *dev)
+{
+	return device_create_file(dev, &dev_attr_buffer);
 
-	privptr = (ctc_priv *)dev->priv;
+}
 
-	if (file->f_pos == 0)
-		sprintf(sbuf, "%d\n", privptr->channel[READ]->max_bufsize);
+static void
+ctc_remove_attributes(struct device *dev)
+{
+	device_remove_file(dev, &dev_attr_buffer);
 
-	l = strlen(sbuf);
-	p = sbuf;
-	if (file->f_pos < l) {
-		p += file->f_pos;
-		l = strlen(p);
-		ret = (count > l) ? l : count;
-		if (copy_to_user(buf, p, ret))
-			return -EFAULT;
-	}
-	file->f_pos += ret;
-	return ret;
 }
 
+#if 0
+/* FIXME: This has to be converted to another interface, as we can only have one
+ *        value per file and can't have atomicity then */
 #define STATS_BUFSIZE 2048
 
-static int ctc_stat_open(struct inode *inode, struct file *file)
+static int
+ctc_stat_open(struct inode *inode, struct file *file)
 {
 	file->private_data = kmalloc(STATS_BUFSIZE, GFP_KERNEL);
 	if (file->private_data == NULL)
@@ -2787,23 +2591,24 @@
 	return 0;
 }
 
-static int ctc_stat_close(struct inode *inode, struct file *file)
+static int
+ctc_stat_close(struct inode *inode, struct file *file)
 {
 	kfree(file->private_data);
 	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
-static ssize_t ctc_stat_write(struct file *file, const char *buf, size_t count,
-			      loff_t *off)
+static ssize_t
+ctc_stat_write(struct file *file, const char *buf, size_t count, loff_t * off)
 {
 	struct proc_dir_entry *pde = PDE(file->f_dentry->d_inode);
-	net_device *dev;
-	ctc_priv *privptr;
+	struct net_device *dev;
+	struct ctc_priv *privptr;
 
 	if (!(dev = find_netdev_by_ino(pde)))
 		return -ENODEV;
-	privptr = (ctc_priv *)dev->priv;
+	privptr = (struct ctc_priv *) dev->priv;
 	privptr->channel[WRITE]->prof.maxmulti = 0;
 	privptr->channel[WRITE]->prof.maxcqueue = 0;
 	privptr->channel[WRITE]->prof.doios_single = 0;
@@ -2813,13 +2618,13 @@
 	return count;
 }
 
-static ssize_t ctc_stat_read(struct file *file, char *buf, size_t count,
-			      loff_t *off)
+static ssize_t
+ctc_stat_read(struct file *file, char *buf, size_t count, loff_t * off)
 {
 	struct proc_dir_entry *pde = PDE(file->f_dentry->d_inode);
-	char *sbuf = (char *)file->private_data;
-	net_device *dev;
-	ctc_priv *privptr;
+	char *sbuf = (char *) file->private_data;
+	struct net_device *dev;
+	struct ctc_priv *privptr;
 	ssize_t ret = 0;
 	char *p = sbuf;
 	int l;
@@ -2829,7 +2634,7 @@
 	if (off != &file->f_pos)
 		return -ESPIPE;
 
-	privptr = (ctc_priv *)dev->priv;
+	privptr = (struct ctc_priv *) dev->priv;
 
 	if (file->f_pos == 0) {
 		p += sprintf(p, "Device FSM state: %s\n",
@@ -2870,365 +2675,16 @@
 	.open    = ctc_stat_open,
 	.release = ctc_stat_close,
 };
-
-static struct file_operations ctc_ctrl_fops = {
-	.read    = ctc_ctrl_read,
-	.write   = ctc_ctrl_write,
-	.open    = ctc_ctrl_open,
-	.release = ctc_ctrl_close,
-};
-
-static struct proc_dir_entry *ctc_dir = NULL;
-
-/**
- * Create the driver's main directory /proc/net/ctc
- */
-static void ctc_proc_create_main(void) {
-	/**
-	 * If not registered, register main proc dir-entry now
-	 */
-	if (!ctc_dir)
-		ctc_dir = proc_mkdir("ctc", proc_net);
-}
-
-#ifdef MODULE
-/**
- * Destroy /proc/net/ctc
- */
-static void ctc_proc_destroy_main(void) {
-	remove_proc_entry("ctc", proc_net);
-}
-#endif MODULE
-
-/**
- * Create a device specific subdirectory in /proc/net/ctc/ with the
- * same name like the device. In that directory, create 2 entries
- * "statistics" and "buffersize".
- *
- * @param dev The device for which the subdirectory should be created.
- *
- */
-static void ctc_proc_create_sub(net_device *dev) {
-	ctc_priv *privptr = dev->priv;
-
-	privptr->proc_dentry = proc_mkdir(dev->name, ctc_dir);
-	privptr->proc_stat_entry =
-		create_proc_entry("statistics",
-				  S_IFREG | S_IRUSR | S_IWUSR,
-				  privptr->proc_dentry);
-	privptr->proc_stat_entry->proc_fops = &ctc_stat_fops;
-	privptr->proc_ctrl_entry =
-		create_proc_entry("buffersize",
-				  S_IFREG | S_IRUSR | S_IWUSR,
-				  privptr->proc_dentry);
-	privptr->proc_ctrl_entry->proc_fops = &ctc_ctrl_fops;
-	privptr->proc_registered = 1;
-}
-
-
-/**
- * Destroy a device specific subdirectory.
- *
- * @param privptr Pointer to device private data.
- */
-static void ctc_proc_destroy_sub(ctc_priv *privptr) {
-	if (!privptr->proc_registered)
-		return;
-	remove_proc_entry("statistics", privptr->proc_dentry);
-	remove_proc_entry("buffersize", privptr->proc_dentry);
-	remove_proc_entry(privptr->proc_dentry->name, ctc_dir);
-	privptr->proc_registered = 0;
-}
-
-
-
-#ifndef CTC_CHANDEV
-/**
- * Setup related routines
- *****************************************************************************/
-
-/**
- * Parse a portion of the setup string describing a single device or option
- * providing the following syntax:
- *
- * [Device/OptionName[:int1][:int2][:int3]]
- *
- *
- * @param setup    Pointer to a pointer to the remainder of the parameter
- *                 string to be parsed. On return, the content of this
- *                 pointer is updated to point to the first character after
- *                 the parsed portion (e.g. possible start of next portion)
- *                 NOTE: The string pointed to must be writeable, since a
- *                 \0 is written for termination of the device/option name.
- *
- * @param dev_name Pointer to a pointer to the name of the device whose
- *                 parameters are parsed. On return, this is set to the
- *                 name of the device/option.
- *
- * @param ints     Pointer to an array of integer parameters. On return,
- *                 element 0 is set to the number of parameters found.
- *
- * @param maxip    Maximum number of ints to parse.
- *                 (ints[] must have size maxip+1)
- *
- * @return     0 if string "setup" was empty, !=0 otherwise
- */
-static int parse_opts(char **setup, char **dev_name, int *ints, int maxip) {
-	char *cur = *setup;
-	int i = 1;
-	int rc = 0;
-	int in_name = 1;
-	int noauto = 0;
-
-#ifdef DEBUG
-	printk(KERN_DEBUG
-	       "ctc: parse_opts(): *setup='%s', maxip=%d\n", *setup, maxip);
-#endif
-	if (*setup) {
-		*dev_name = *setup;
-
-		if (strncmp(cur, "ctc", 3) && strncmp(cur, "escon", 5) &&
-		    strncmp(cur, "noauto", 6)) {
-			if ((*setup = strchr(cur, ':')))
-				*(*setup)++ = '\0';
-			printk(KERN_WARNING
-			       "ctc: Invalid device name or option '%s'\n",
-			       cur);
-			return 1;
-		}
-		switch (*cur) {
-			case 'c':
-				cur += 3;
-				break;
-			case 'e':
-				cur += 5;
-				break;
-			case 'n':
-				cur += 6;
-				*cur++ = '\0';
-				noauto = 1;
-		}
-		if (!noauto) {
-			while (cur &&
-			       (*cur == '-' || isdigit(*cur)) &&
-			       i <= maxip) {
-				if (in_name) {
-					cur++;
-					if (*cur == ':') {
-						*cur++ = '\0';
-						in_name = 0;
-					}
-				} else {
-					ints[i++] =
-						simple_strtoul(cur, NULL, 0);
-#ifdef DEBUG
-					printk(KERN_DEBUG
-					       "ctc: %s: ints[%d]=%d\n",
-					       __FUNCTION__,
-					       i-1, ints[i-1]);
-#endif
-					if ((cur = strchr(cur, ':')) != NULL)
-						cur++;
-				}
-			}
-		}
-		ints[0] = i - 1;
-		*setup = cur;
-		if (cur && (*cur == ':'))
-			(*setup)++;
-		rc = 1;
-	}
-	return rc;
-}
-
-/**
- *
- * Allocate one param struct
- *
- * If the driver is loaded as a module this functions is called during
- *   module set up and we can allocate the struct by using kmalloc()
- *
- * If the driver is statically linked into the kernel this function is called
- * when kmalloc() is not yet available so we must allocate from a static array
- *
- */
-#ifdef MODULE
-#define alloc_param() ((param *)kmalloc(sizeof(param), GFP_KERNEL));
-#else
-static param parms_array[MAX_STATIC_DEVICES];
-static param *next_param = parms_array;
-#define alloc_param() \
-        ((next_param<parms_array+MAX_STATIC_DEVICES)?next_param++:NULL)
-#endif MODULE
-
-/**
- * Returns commandline parameter using device name as key.
- *
- * @param name Name of interface to get parameters from.
- *
- * @return Pointer to corresponting param struct, NULL if not found.
- */
-static param *find_param(char *name) {
-	param *p = params;
-
-	while (p && strcmp(p->name, name))
-		p = p->next;
-	return p;
-}
-
-/**
- * maximum number of integer parametes that may be specified
- * for one device in the setup string
- */
-#define CTC_MAX_INTPARMS 3
-
-/**
- * Parse configuration options for all interfaces.
- *
- * This function is called from two possible locations:
- *  - If built as module, this function is called from init_module().
- *  - If built in monolithic kernel, this function is called from within
- *    init/main.c.
- * Parsing is always done here.
- *
- * Valid parameters are:
- *
- *
- *   [NAME[:0xRRRR[:0xWWWW[:P]]]]
- *
- *     where P       is the channel protocol (always 0)
- *	      0xRRRR is the cu number for the read channel
- *	      0xWWWW is the cu number for the write channel
- *	      NAME   is either ctc0 ... ctcN for CTC/A
- *                      or     escon0 ... esconN for Escon.
- *                      or     noauto
- *                             which switches off auto-detection of channels.
- *
- * @param setup    The parameter string to parse. MUST be writeable!
- * @param ints     Pointer to an array of ints. Only for kernel 2.2,
- *                 builtin (not module) version. With kernel 2.2,
- *                 normally all integer-parameters, preceeding some
- *                 configuration-string are pre-parsed in init/main.c
- *                 and handed over here.
- *                 To simplify 2.2/2.4 compatibility, by definition,
- *                 our parameters always start with a string and ints
- *                 is always unset and ignored.
- */
-#ifdef MODULE
-   static void ctc_setup(char *setup)
-#  define ctc_setup_return return
-#else MODULE
-     static int __init ctc_setup(char *setup)
-#    define ctc_setup_return return(1)
-#endif MODULE
-{
-	int write_dev;
-	int read_dev;
-	int proto;
-	param *par;
-	char *dev_name;
-	int ints[CTC_MAX_INTPARMS+1];
-
-	while (parse_opts(&setup, &dev_name, ints, CTC_MAX_INTPARMS)) {
-		write_dev = -1;
-		read_dev = -1;
-		proto = CTC_PROTO_S390;
-#ifdef DEBUG
-		printk(KERN_DEBUG
-		       "ctc: ctc_setup(): setup='%s' dev_name='%s',"
-		       " ints[0]=%d)\n",
-		       setup, dev_name, ints[0]);
-#endif DEBUG
-		if (dev_name == NULL) {
-			/**
-			 * happens if device name is not specified in
-			 * parameter line (cf. init/main.c:get_options()
-			 */
-			printk(KERN_WARNING
-			       "ctc: %s(): Device name not specified\n",
-			       __FUNCTION__);
-			ctc_setup_return;
-		}
-
-#ifdef DEBUG
-		printk(KERN_DEBUG "name=´%s´ argc=%d\n", dev_name, ints[0]);
-#endif
-
-		if (strcmp(dev_name, "noauto") == 0) {
-			printk(KERN_INFO "ctc: autoprobing disabled\n");
-			ctc_no_auto = 1;
-			continue;
-		}
-
-		if (find_param(dev_name) != NULL) {
-			printk(KERN_WARNING
-			       "ctc: Definition for device %s already set. "
-			       "Ignoring second definition\n", dev_name);
-			continue;
-		}
-
-		switch (ints[0]) {
-			case 3: /* protocol type passed */
-				proto = ints[3];
-				if (proto > CTC_PROTO_MAX) {
-					printk(KERN_WARNING
-					       "%s: wrong protocol type "
-					       "passed\n", dev_name);
-					ctc_setup_return;
-				}
-			case 2: /* write channel passed */
-				write_dev = ints[2];
-			case 1: /* read channel passed */
-				read_dev = ints[1];
-				if (write_dev == -1)
-					write_dev = read_dev + 1;
-				break;
-			default:
-				printk(KERN_WARNING
-				       "ctc: wrong number of parameter "
-				       "passed (is: %d, expected: [1..3]\n",
-				       ints[0]);
-				ctc_setup_return;
-		}
-		par = alloc_param();
-		if (!par) {
-#ifdef MODULE
-			printk(KERN_WARNING
-			       "ctc: Couldn't allocate setup param block\n");
-#else
-			printk(KERN_WARNING
-			       "ctc: Number of device definitions in "
-			       " kernel commandline exceeds builtin limit "
-			       " of %d devices.\n", MAX_STATIC_DEVICES);
-#endif
-			ctc_setup_return;
-		}
-		par->read_dev = read_dev;
-		par->write_dev = write_dev;
-		par->proto = proto;
-		strncpy(par->name, dev_name, MAX_PARAM_NAME_LEN);
-		par->next = params;
-		params = par;
-#ifdef DEBUG
-		printk(KERN_DEBUG "%s: protocol=%x read=%04x write=%04x\n",
-		       dev_name, proto, read_dev, write_dev);
 #endif
-	}
-	ctc_setup_return;
-}
-
-__setup("ctc=", ctc_setup);
-#endif /* !CTC_CHANDEV */
 
-
 static void
-ctc_netdev_unregister(net_device *dev)
+ctc_netdev_unregister(struct net_device * dev)
 {
-	ctc_priv *privptr;
+	struct ctc_priv *privptr;
 
 	if (!dev)
 		return;
-	privptr = (ctc_priv *)dev->priv;
+	privptr = (struct ctc_priv *) dev->priv;
 	if (privptr->protocol != CTC_PROTO_LINUX_TTY)
 		unregister_netdev(dev);
 	else
@@ -3236,9 +2692,9 @@
 }
 
 static int
-ctc_netdev_register(net_device *dev)
+ctc_netdev_register(struct net_device * dev)
 {
-	ctc_priv *privptr = (ctc_priv *)dev->priv;
+	struct ctc_priv *privptr = (struct ctc_priv *) dev->priv;
 	if (privptr->protocol != CTC_PROTO_LINUX_TTY)
 		return register_netdev(dev);
 	else
@@ -3246,16 +2702,15 @@
 }
 
 static void
-ctc_free_netdevice(net_device *dev, int free_dev)
+ctc_free_netdevice(struct net_device * dev, int free_dev)
 {
-	ctc_priv *privptr;
+	struct ctc_priv *privptr;
 	if (!dev)
 		return;
 	privptr = dev->priv;
 	if (privptr) {
 		if (privptr->fsm)
 			kfree_fsm(privptr->fsm);
-		ctc_proc_destroy_sub(privptr);
 		kfree(privptr);
 	}
 #ifdef MODULE
@@ -3264,560 +2719,327 @@
 #endif
 }
 
-#ifdef CTC_CHANDEV
-static int
-ctc_shutdown(net_device *dev)
-{
-	ctc_priv *privptr;
-
-	if (!dev)
-		return 0;
-	privptr = (ctc_priv *)dev->priv;
-	channel_remove(privptr->channel[READ]);
-	channel_remove(privptr->channel[WRITE]);
-	ctc_free_netdevice(dev, 0);
-	return 0;
-}
-#endif
-
 /**
  * Initialize everything of the net device except the name and the
  * channel structs.
  */
-static net_device *
-ctc_init_netdevice(net_device *dev, int alloc_device)
+static struct net_device *
+ctc_init_netdevice(struct net_device * dev, int alloc_device, 
+		   struct ctc_priv *privptr)
 {
-	ctc_priv *privptr;
-	int      priv_size;
+	if (!privptr)
+		return NULL;
+
 	if (alloc_device) {
-		dev = kmalloc(sizeof(net_device), GFP_KERNEL);
+		dev = kmalloc(sizeof (struct net_device), GFP_KERNEL);
 		if (!dev)
 			return NULL;
-		memset(dev, 0, sizeof(net_device));
+		memset(dev, 0, sizeof (struct net_device));
 	}
-	priv_size = sizeof(ctc_priv);
-	dev->priv = kmalloc(priv_size, GFP_KERNEL);
-	if (dev->priv == NULL) {
-		if (alloc_device)
-			kfree(dev);
-		return NULL;
-	}
-        memset(dev->priv, 0, priv_size);
-        privptr = (ctc_priv *)dev->priv;
+
+	dev->priv = privptr;
 	privptr->fsm = init_fsm("ctcdev", dev_state_names,
-			dev_event_names, NR_DEV_STATES, NR_DEV_EVENTS,
-			dev_fsm, DEV_FSM_LEN, GFP_KERNEL);
+				dev_event_names, NR_DEV_STATES, NR_DEV_EVENTS,
+				dev_fsm, DEV_FSM_LEN, GFP_KERNEL);
 	if (privptr->fsm == NULL) {
-		kfree(privptr);
 		if (alloc_device)
 			kfree(dev);
 		return NULL;
 	}
 	fsm_newstate(privptr->fsm, DEV_STATE_STOPPED);
-	dev->mtu	         = CTC_BUFSIZE_DEFAULT - LL_HEADER_LENGTH - 2;
-	dev->hard_start_xmit     = ctc_tx;
-	dev->open	         = ctc_open;
-	dev->stop	         = ctc_close;
-	dev->get_stats	         = ctc_stats;
-	dev->change_mtu          = ctc_change_mtu;
-	dev->hard_header_len     = LL_HEADER_LENGTH + 2;
-	dev->addr_len            = 0;
-	dev->type                = ARPHRD_SLIP;
-	dev->tx_queue_len        = 100;
+	fsm_settimer(privptr->fsm, &privptr->restart_timer);
+	dev->mtu = CTC_BUFSIZE_DEFAULT - LL_HEADER_LENGTH - 2;
+	dev->hard_start_xmit = ctc_tx;
+	dev->open = ctc_open;
+	dev->stop = ctc_close;
+	dev->get_stats = ctc_stats;
+	dev->change_mtu = ctc_change_mtu;
+	dev->hard_header_len = LL_HEADER_LENGTH + 2;
+	dev->addr_len = 0;
+	dev->type = ARPHRD_SLIP;
+	dev->tx_queue_len = 100;
 	SET_DEVICE_START(dev, 1);
 	dev_init_buffers(dev);
-	dev->flags	         = IFF_POINTOPOINT | IFF_NOARP;
+	dev->flags = IFF_POINTOPOINT | IFF_NOARP;
 	return dev;
 }
 
-#ifdef CTC_CHANDEV
+static ssize_t
+ctc_proto_show(struct device *dev, char *buf, size_t count, loff_t off)
+{
+	struct ctc_priv *priv;
+
+	if (off)
+		return 0;
+	priv = dev->driver_data;
+	if (!priv)
+		return -ENODEV;
+
+	return snprintf(buf, count, "%d\n", priv->protocol);
+}
+
+static ssize_t
+ctc_proto_store(struct device *dev, const char *buf, size_t count, loff_t off)
+{
+	struct ctc_priv *priv;
+	int value;
+
+	if (off)
+		return 0;
+	priv = dev->driver_data;
+	if (!priv)
+		return -ENODEV;
+	sscanf(buf, "%u", &value);
+	/* TODO: sanity checks */
+	priv->protocol = value;
+
+	return count;
+}
+
+static DEVICE_ATTR(protocol, 0644, ctc_proto_show, ctc_proto_store);
+
+static int
+ctc_add_files(struct device *dev)
+{
+	return device_create_file(dev, &dev_attr_protocol);
+
+}
+
 static void
-ctc_chandev_msck_notify(void *dev, int msck_irq,
-			chandev_msck_status prevstatus,
-			chandev_msck_status newstatus)
+ctc_remove_files(struct device *dev)
 {
-	net_device *device = (net_device *)dev;
-	ctc_priv *privptr;
-	int direction;
+	device_remove_file(dev, &dev_attr_protocol);
 
-	if (!dev)
-		return;
+}
 
-	privptr = device->priv;
-	if (prevstatus == chandev_status_revalidate)
-		for (direction = READ; direction <= WRITE; direction++) {
-			channel *ch = privptr->channel[direction];
-			if(ch->irq == msck_irq) {
-				s390_dev_info_t devinfo;
-
-				if (get_dev_info_by_irq(ch->irq, &devinfo))
-					ch->devno = devinfo.devno;
-				else
-					printk(KERN_WARNING
-					       "ctc_chandev_msck_notify: "
-					       "get_dev_info_by_irq failed for "
-					       "irq %d\n", ch->irq);
-			}
-		}
-	switch (newstatus) {
-		case chandev_status_not_oper:
-		case chandev_status_no_path:
-		case chandev_status_gone:
-			for (direction = READ; direction <= WRITE; direction++) {
-				channel *ch = privptr->channel[direction];
-				fsm_event(ch->fsm, CH_EVENT_MC_FAIL, ch);
-			}
-			printk(KERN_WARNING
-			       "ctc: %s channel deactivated\n", device->name);
-			break;
-		case chandev_status_all_chans_good:
-			for (direction = READ; direction <= WRITE; direction++) {
-				channel *ch = privptr->channel[direction];
-				fsm_event(ch->fsm, CH_EVENT_MC_GOOD, ch);
-			}
-			printk(KERN_WARNING
-			       "ctc: %s channel activated\n", device->name);
-			break;
-		default:
-			break;
+/**
+ * Add ctc specific attributes.
+ * Add ctc private data.
+ * 
+ * @param cgdev pointer to ccwgroup_device just added
+ *
+ * @returns 0 on success, !0 on failure.
+ */
+
+int
+ctc_probe_device(struct ccwgroup_device *cgdev)
+{
+	struct ctc_priv *priv;
+	int rc;
+
+	if (!get_device(&cgdev->dev))
+		return -ENODEV;
+
+	priv = kmalloc(sizeof (struct ctc_priv), GFP_KERNEL);
+	if (!priv) {
+		printk(KERN_ERR "%s: Out of memory\n", __func__);
+		put_device(&cgdev->dev);
+		return -ENOMEM;
+	}
+
+	memset(priv, 0, sizeof (struct ctc_priv));
+	rc = ctc_add_files(&cgdev->dev);
+	if (rc) {
+		kfree(priv);
+		put_device(&cgdev->dev);
+		return rc;
 	}
+
+	cgdev->cdev[0]->handler = ctc_irq_handler;
+	cgdev->cdev[1]->handler = ctc_irq_handler;
+	cgdev->dev.driver_data = priv;
+	cgdev->cdev[0]->dev.driver_data = priv;
+	cgdev->cdev[1]->dev.driver_data = priv;
+	snprintf(cgdev->dev.name, DEVICE_NAME_SIZE, "%s",
+		 cu3088_type[cgdev->cdev[0]->id.driver_info]);
+
+	return 0;
 }
 
 /**
  *
  * Setup an interface.
  *
- * Like ctc_setup(), ctc_probe() can be called from two different locations:
- *  - If built as module, it is called from within init_module().
- *  - If built in monolithic kernel, it is called from within generic network
- *    layer during initialization for every corresponding device, declared in
- *    drivers/net/Space.c
- *
- * @param dev Pointer to net_device to be initialized.
+ * @param cgdev  Device to be setup.
  *
  * @returns 0 on success, !0 on failure.
  */
-static int ctc_chandev_probe(chandev_probeinfo *info)
+int
+ctc_new_device(struct ccwgroup_device *cgdev)
 {
-	int               devno[2];
-	__u16             proto;
-	int               rc;
-	int               direction;
-	channel_type_t    type;
-	ctc_priv          *privptr;
-	net_device        *dev;
-
-	ctc_proc_create_main();
-
-
-	switch (info->chan_type) {
-		case chandev_type_ctc:
-			type = channel_type_ctca;
-			break;
-		case chandev_type_escon:
-			type = channel_type_escon;
-			break;
-		default:
-			printk(KERN_WARNING "ctc_chandev_probe called with "
-			       "unsupported channel type %d\n", info->chan_type);
-			return -ENODEV;
-	}
-	devno[READ]  = info->read.devno;
-	devno[WRITE] = info->write.devno;
-	proto        = info->port_protocol_no;
+	char read_id[CTC_ID_SIZE];
+	char write_id[CTC_ID_SIZE];
+	int direction;
+	enum channel_types type;
+	struct ctc_priv *privptr;
+	struct net_device *dev;
+
+	privptr = cgdev->dev.driver_data;
+	if (!privptr)
+		return -ENODEV;
+
+	type = get_channel_type(&cgdev->cdev[0]->id);
+	
+	snprintf(read_id, DEVICE_ID_SIZE, "ch-%s", cgdev->cdev[0]->dev.bus_id);
+	snprintf(write_id, DEVICE_ID_SIZE, "ch-%s", cgdev->cdev[1]->dev.bus_id);
 
-	if (add_channel(info->read.irq, info->read.devno, type))
+	if (add_channel(cgdev->cdev[0], type))
 		return -ENOMEM;
-	if (add_channel(info->write.irq, info->write.devno, type))
+	if (add_channel(cgdev->cdev[1], type))
 		return -ENOMEM;
 
-	dev = ctc_init_netdevice(NULL, 1);
+	dev = ctc_init_netdevice(NULL, 1, privptr);
 
-	
 	if (!dev) {
 		printk(KERN_WARNING "ctc_init_netdevice failed\n");
 		return -ENODEV;
 	}
-	
-	if (proto == CTC_PROTO_LINUX_TTY)
-		chandev_build_device_name(info, dev->name, "ctctty", 1);
+
+	if (privptr->protocol == CTC_PROTO_LINUX_TTY)
+		snprintf(dev->name, 8, "ctctty%%d");
 	else
-		chandev_build_device_name(info, dev->name, "ctc", 1);
+		snprintf(dev->name, 8, "ctc%%d");
 
-	privptr = (ctc_priv *)dev->priv;
-	privptr->protocol = proto;
 	for (direction = READ; direction <= WRITE; direction++) {
 		privptr->channel[direction] =
-			channel_get(type, devno[direction], direction);
+		    channel_get(type, direction == READ ? read_id : write_id,
+				direction);
 		if (privptr->channel[direction] == NULL) {
-			if (direction == WRITE) {
-				FREE_IRQ(privptr->channel[READ]->irq,
-					 privptr->channel[READ]->devstat);
+			if (direction == WRITE) 
 				channel_free(privptr->channel[READ]);
-			}
+
 			ctc_free_netdevice(dev, 1);
 			return -ENODEV;
 		}
 		privptr->channel[direction]->netdev = dev;
-		privptr->channel[direction]->protocol = proto;
+		privptr->channel[direction]->protocol = privptr->protocol;
 		privptr->channel[direction]->max_bufsize = CTC_BUFSIZE_DEFAULT;
-		rc = REQUEST_IRQ(privptr->channel[direction]->irq,
-				 (void *)ctc_irq_handler, SA_INTERRUPT,
-				 dev->name,
-				 privptr->channel[direction]->devstat);
-		if (rc) {
-			printk(KERN_WARNING
-			       "%s: requested irq %d is busy rc=%02x\n",
-			       dev->name, privptr->channel[direction]->irq,
-			       rc);
-			if (direction == WRITE) {
-				FREE_IRQ(privptr->channel[READ]->irq,
-					 privptr->channel[READ]->devstat);
-				channel_free(privptr->channel[READ]);
-			}
-			channel_free(privptr->channel[direction]);
-			ctc_free_netdevice(dev, 1);
-			return -EBUSY;
-		}
 	}
 	if (ctc_netdev_register(dev) != 0) {
 		ctc_free_netdevice(dev, 1);
 		return -ENODEV;
 	}
 
-	/**
-	 * register subdir in /proc/net/ctc
-	 */
-	ctc_proc_create_sub(dev);
-	strncpy(privptr->fsm->name, dev->name, sizeof(privptr->fsm->name));
-	activated++;
+	ctc_add_attributes(&cgdev->dev);
+
+	strncpy(privptr->fsm->name, dev->name, sizeof (privptr->fsm->name));
 
 	print_banner();
 
 	printk(KERN_INFO
-	       "%s: read: ch %04x (irq %04x), "
-	       "write: ch %04x (irq %04x) proto: %d\n",
-	       dev->name, privptr->channel[READ]->devno,
-	       privptr->channel[READ]->irq, privptr->channel[WRITE]->devno,
-	       privptr->channel[WRITE]->irq, proto);
-
-	chandev_initdevice(info, dev, 0, dev->name,
-			   (proto == CTC_PROTO_LINUX_TTY)
-			   ? chandev_category_serial_device :
-			   chandev_category_network_device,
-			   (chandev_unregfunc)ctc_netdev_unregister);
+	       "%s: read: %s, write: %s, proto: %d\n",
+	       dev->name, privptr->channel[READ]->id,
+	       privptr->channel[WRITE]->id, privptr->protocol);
+
 	return 0;
 }
-#else /* ! CHANDEV */
+
 /**
+ * Shutdown an interface.
  *
- * Setup an interface.
- *
- * Like ctc_setup(), ctc_probe() can be called from two different locations:
- *  - If built as module, it is called from within init_module().
- *  - If built in monolithic kernel, it is called from within generic network
- *    layer during initialization for every corresponding device, declared in
- *    drivers/net/Space.c
- *
- * @param dev Pointer to net_device to be initialized.
+ * @param cgdev  Device to be shut down.
  *
  * @returns 0 on success, !0 on failure.
  */
-int ctc_probe(net_device *dev)
+int
+ctc_shutdown_device(struct ccwgroup_device *cgdev)
 {
-	int            devno[2];
-	__u16          proto;
-	int            rc;
-	int            direction;
-	channel_type_t type;
-	ctc_priv       *privptr;
-	param          *par;
+	struct ctc_priv *priv;
+	struct net_device *ndev;
+		
 
-	ctc_proc_create_main();
+	priv = cgdev->dev.driver_data;
+	if (!priv)
+		return -ENODEV;
+	ndev = container_of((void *)priv, struct net_device, priv);
 
-	/**
-	 * Scan for available channels only the first time,
-	 * ctc_probe gets control.
-	 */
-	if (channels == NULL)
-		channel_scan();
+	/* Close the device */
+	ctc_close(ndev);
+	ndev->flags &=~IFF_RUNNING;
 
-	type = extract_channel_media(dev->name);
-	if (type == channel_type_unknown)
-		return -ENODEV;
+	ctc_remove_attributes(&cgdev->dev);
 
-	par = find_param(dev->name);
-	if (par) {
-		devno[READ] = par->read_dev;
-		devno[WRITE] = par->write_dev;
-		proto = par->proto;
-	} else {
-		if (ctc_no_auto)
-			return -ENODEV;
-		else {
-			devno[READ] = -1;
-			devno[WRITE] = -1;
-			proto = CTC_PROTO_S390;
-		}
-	}
+	channel_free(priv->channel[READ]);
+	channel_free(priv->channel[WRITE]);
 
-#ifndef MODULE
-	if (ctc_init_netdevice(dev, 0) == NULL)
-		return -ENODEV;
-#endif
-	privptr = (ctc_priv *)dev->priv;
-	privptr->protocol = proto;
+	ctc_netdev_unregister(ndev);
+	ndev->priv = NULL;
+	ctc_free_netdevice(ndev, 1);
 
-	for (direction = READ; direction <= WRITE; direction++) {
-		if ((ctc_no_auto == 0) || (devno[direction] == -1))
-			privptr->channel[direction] =
-				channel_get_next(type, direction);
-		else
-			privptr->channel[direction] =
-				channel_get(type, devno[direction], direction);
-		if (privptr->channel[direction] == NULL) {
-			if (direction == WRITE) {
-				FREE_IRQ(privptr->channel[READ]->irq,
-					 privptr->channel[READ]->devstat);
-				channel_free(privptr->channel[READ]);
-			}
-			ctc_free_netdevice(dev, 1);
-			return -ENODEV;
-		}
-		privptr->channel[direction]->netdev = dev;
-		privptr->channel[direction]->protocol = proto;
-		privptr->channel[direction]->max_bufsize = CTC_BUFSIZE_DEFAULT;
-		rc = REQUEST_IRQ(privptr->channel[direction]->irq,
-				 (void *)ctc_irq_handler, SA_INTERRUPT,
-				 dev->name,
-				 privptr->channel[direction]->devstat);
-		if (rc) {
-			printk(KERN_WARNING
-			       "%s: requested irq %d is busy rc=%02x\n",
-			       dev->name, privptr->channel[direction]->irq,
-			       rc);
-			if (direction == WRITE) {
-				FREE_IRQ(privptr->channel[READ]->irq,
-					 privptr->channel[READ]->devstat);
-				channel_free(privptr->channel[READ]);
-			}
-			channel_free(privptr->channel[direction]);
-			ctc_free_netdevice(dev, 1);
-			return -EBUSY;
-		}
-	}
+	kfree_fsm(priv->fsm);
 
-	/**
-	 * register subdir in /proc/net/ctc
-	 */
-	ctc_proc_create_sub(dev);
+	channel_remove(priv->channel[READ]);
+	channel_remove(priv->channel[WRITE]);
+	
+	return 0;
 
-	print_banner();
+}
 
-	printk(KERN_INFO
-	       "%s: read: ch %04x (irq %04x), "
-	       "write: ch %04x (irq %04x) proto: %d\n",
-	       dev->name, privptr->channel[READ]->devno,
-	       privptr->channel[READ]->irq, privptr->channel[WRITE]->devno,
-	       privptr->channel[WRITE]->irq, proto);
+int
+ctc_remove_device(struct ccwgroup_device *cgdev)
+{
+	struct ctc_priv *priv;
+
+	priv = cgdev->dev.driver_data;
+	if (!priv)
+		return 0;
 
+	ctc_remove_files(&cgdev->dev);
+	cgdev->dev.driver_data = NULL;
+	kfree(priv);
+	put_device(&cgdev->dev);
 	return 0;
 }
-#endif
-
+
+struct ccwgroup_driver ctc_group_driver = {
+	.name        = "ctc",
+	.max_slaves  = 2,
+	.driver_id   = 0xC3E3C3,
+	.probe       = ctc_probe_device,
+	.remove      = ctc_remove_device,
+	.set_online  = ctc_new_device,
+	.set_offline = ctc_shutdown_device,
+};
+
 /**
  * Module related routines
  *****************************************************************************/
 
-#ifdef MODULE
 /**
  * Prepare to be unloaded. Free IRQ's and release all resources.
  * This is called just before this module is unloaded. It is
  * <em>not</em> called, if the usage count is !0, so we don't need to check
  * for that.
  */
-void cleanup_module(void) {
-
-	ctc_tty_cleanup(0);
-	/* we are called if all interfaces are down only, so no need
-	 * to bother around with locking stuff
-	 */
-#ifndef CTC_CHANDEV
-	while (channels) {
-		if ((channels->flags & CHANNEL_FLAGS_INUSE) &&
-		    (channels->netdev != NULL)) {
-			net_device *dev = channels->netdev;
-			ctc_priv *privptr = dev->priv;
-
-			if (privptr) {
-				privptr->channel[READ]->netdev = NULL;
-				privptr->channel[WRITE]->netdev = NULL;
-			}
-			channels->netdev = NULL;
-			ctc_netdev_unregister(dev);
-			ctc_free_netdevice(dev, 1);
-		}
-		channel_remove(channels);
-	}
-	channels = NULL;
-#endif
-	ctc_tty_cleanup(1);
-	ctc_proc_destroy_main();
-#ifdef CTC_CHANDEV
-	chandev_unregister(ctc_chandev_probe, 1);
-#endif
+static void __exit
+ctc_exit(void)
+{
+	unregister_cu3088_discipline(&ctc_group_driver);
+	ctc_tty_cleanup();
 	printk(KERN_INFO "CTC driver unloaded\n");
 }
 
-#define ctc_init init_module
-#endif MODULE
-
 /**
  * Initialize module.
  * This is called just after the module is loaded.
  *
  * @return 0 on success, !0 on error.
  */
-static int ctc_init(void) {
-#ifndef CTC_CHANDEV
-	int   cnt[2];
-	int   itype;
-	int   activated;
-	param *par;
-#endif
-	int   ret = 0;
-	int   probed = 0;
+static int __init
+ctc_init(void)
+{
+	int ret = 0;
 
 	print_banner();
 
-#if defined(DEBUG) && !defined(CTC_CHANDEV)
-	printk(KERN_DEBUG
-	       "ctc: init_module(): got string '%s'\n", ctc);
-#endif
-
-#ifndef CTC_CHANDEV
-#ifdef MODULE
-	ctc_setup(ctc);
-#endif
-	par = params;
-#endif
-
-	activated = 0;
 	ctc_tty_init();
-#ifdef CTC_CHANDEV
-	chandev_register_and_probe(ctc_chandev_probe,
-				   (chandev_shutdownfunc)ctc_shutdown,
-				   ctc_chandev_msck_notify,
-				   chandev_type_ctc|chandev_type_escon);
-#else /* CTC_CHANDEV */
-	for (itype = 0; itype < 2; itype++) {
-		net_device *dev = NULL;
-		char       *bname = (itype) ? "escon" : "ctc";
-
-		cnt[itype] = 0;
-		do {
-			dev = ctc_init_netdevice(NULL, 1);
-			if (!dev) {
-				ret = -ENOMEM;
-				break;
-			}
-			if (par && par->name) {
-				char *p;
-				int  n;
-
-				sprintf(dev->name, "%s", par->name);
-				par = par->next;
-				for (p = dev->name; p && *p; p++)
-					if (isdigit(*p))
-						break;
-				if (p && *p) {
-					int it =
-						(strncmp(dev->name, "escon", 5))
-						? 1 : 0;
-					n = simple_strtoul(p, NULL, 0);
-					if (n >= cnt[it])
-						cnt[it] = n + 1;
-				}
-			} else {
-				if (ctc_no_auto) {
-					itype = 3;
-					ctc_free_netdevice(dev, 1);
-					dev = NULL;
-					break;
-				}
-				sprintf(dev->name, "%s%d", bname,
-					(cnt[itype])++);
-			}
-#ifdef DEBUG
-			printk(KERN_DEBUG "ctc: %s(): probing for device %s\n",
-						 __FUNCTION__, dev->name);
-#endif			
-			probed = 1;
-			if (ctc_probe(dev) == 0) {
-				ctc_priv *privptr = (ctc_priv *)dev->priv;
-#ifdef DEBUG
-				printk(KERN_DEBUG
-				       "ctc: %s(): probing succeeded\n",
-				       __FUNCTION__);
-				printk(KERN_DEBUG
-				       "ctc: %s(): registering device %s\n",
-				       __FUNCTION__, dev->name);
-#endif
-				if (ctc_netdev_register(dev) != 0) {
-					printk(KERN_WARNING
-					       "ctc: Couldn't register %s\n",
-					       dev->name);
-					FREE_IRQ(
-						privptr->channel[READ]->irq,
-						privptr->channel[READ]->devstat);
-					FREE_IRQ(
-						privptr->channel[WRITE]->irq,
-						privptr->channel[WRITE]->devstat);
-					channel_free(privptr->channel[READ]);
-					channel_free(privptr->channel[WRITE]);
-					ctc_free_netdevice(dev, 1);
-					dev = NULL;
-				} else {
-#ifdef DEBUG
-					printk(KERN_DEBUG
-					       "ctc: %s(): register succeed\n",
-					       __FUNCTION__);
-#endif			
-					activated++;
-				}
-			} else {
-#ifdef DEBUG
-				printk(KERN_DEBUG
-				       "ctc: %s(): probing failed\n",
-				       __FUNCTION__);
-#endif			
-				dev = NULL;
-			}
-		} while (dev && (ret == 0));
-	}
-#endif /* CHANDEV */
-#if !defined(CTC_CHANDEV) && defined(MODULE)
-	if (!activated) {
-		printk(KERN_WARNING "ctc: No devices registered\n");
-		ret = -ENODEV;
-	}
-#endif
-	if (ret) {
-		ctc_tty_cleanup(0);
-		ctc_tty_cleanup(1);
-#if defined(CTC_CHANDEV) && defined(MODULE)
-		chandev_unregister(ctc_chandev_probe, 0);
-#endif
-#ifdef MODULE
-		if (probed)
-			ctc_proc_destroy_main();
-#endif
-	}
+	ret = register_cu3088_discipline(&ctc_group_driver);
+	if (ret) 
+		ctc_tty_cleanup();
 	return ret;
 }
 
-#ifndef MODULE
-__initcall(ctc_init);
-#endif /* MODULE */
+module_init(ctc_init);
+module_exit(ctc_exit);
 
 /* --- This is the END my friend --- */
diff -Nru a/drivers/s390/net/ctctty.c b/drivers/s390/net/ctctty.c
--- a/drivers/s390/net/ctctty.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/s390/net/ctctty.c	Mon Dec  9 18:46:38 2002
@@ -1,5 +1,5 @@
 /*
- * $Id: ctctty.c,v 1.8 2001/05/16 16:28:31 felfert Exp $
+ * $Id: ctctty.c,v 1.9 2002/12/02 15:25:13 aberg Exp $
  *
  * CTC / ESCON network driver, tty interface.
  *
@@ -34,23 +34,6 @@
 #endif
 #include "ctctty.h"
 
-#if LINUX_VERSION_CODE < 0x020212
-typedef struct wait_queue wait_queue_t;
-typedef struct wait_queue *wait_queue_head_t;
-#define DECLARE_WAITQUEUE(wait, current) \
-	struct wait_queue wait = { current, NULL }
-#define init_waitqueue_head(x) *(x)=NULL
-#define __set_current_state(state_value) \
-	do { current->state = state_value; } while (0)
-#ifdef __SMP__
-#define set_current_state(state_value) \
-	do { __set_current_state(state_value); mb(); } while (0)
-#else
-#define set_current_state(state_value) __set_current_state(state_value)
-#endif
-#define init_MUTEX(x) *(x)=MUTEX
-#endif
-
 #define CTC_TTY_MAJOR       43
 #define CTC_TTY_MAX_DEVICES 64
 
@@ -78,7 +61,7 @@
   int			line;
   int			count;		 /* # of fd on device              */
   int			blocked_open;	 /* # of blocked opens             */
-  net_device            *netdev;
+  struct net_device     *netdev;
   struct sk_buff_head   tx_queue;        /* transmit queue                 */
   struct sk_buff_head   rx_queue;        /* receive queue                  */
   struct tty_struct 	*tty;            /* Pointer to corresponding tty   */
@@ -114,8 +97,6 @@
 static char *ctc_ttyname = CTC_TTY_NAME;
 #endif
 
-static char *ctc_tty_revision = "$Revision: 1.8 $";
-
 static __u32 ctc_tty_magic = CTC_ASYNC_MAGIC;
 static int ctc_tty_shuttingdown = 0;
 
@@ -195,7 +176,7 @@
 }
 
 void
-ctc_tty_setcarrier(net_device *netdev, int on)
+ctc_tty_setcarrier(struct net_device *netdev, int on)
 {
 	int i;
 
@@ -896,8 +877,8 @@
 	if (tty_hung_up_p(filp) ||
 	    (info->flags & CTC_ASYNC_CLOSING)) {
 		if (info->flags & CTC_ASYNC_CLOSING)
-#warning: FIXME [kj] Using sleep_on derivative, is racy. consider using wait_event instead
-			interruptible_sleep_on(&info->close_wait);
+			wait_event(info->close_wait, 
+				   !(info->flags & CTC_ASYNC_CLOSING));
 #ifdef MODEM_DO_RESTART
 		if (info->flags & CTC_ASYNC_HUP_NOTIFY)
 			return -EAGAIN;
@@ -1094,7 +1075,7 @@
 	 * line status register.
 	 */
 	if (info->flags & CTC_ASYNC_INITIALIZED) {
-		tty_wait_until_sent(tty, 3000);	/* 30 seconds timeout */
+		tty_wait_until_sent(tty, 30*HZ); /* 30 seconds timeout */
 		/*
 		 * Before we drop DTR, make sure the UART transmitter
 		 * has completely drained; this is especially
@@ -1104,7 +1085,7 @@
 		while (!(info->lsr & UART_LSR_TEMT)) {
 			set_current_state(TASK_INTERRUPTIBLE);
 			spin_unlock_irqrestore(&ctc_tty_lock, flags);
-			schedule_timeout(20);
+			schedule_timeout(HZ/2);
 			spin_lock_irqsave(&ctc_tty_lock, flags);
 			if (time_after(jiffies,timeout))
 				break;
@@ -1119,7 +1100,7 @@
 	tty->closing = 0;
 	if (info->blocked_open) {
 		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(50);
+		schedule_timeout(HZ/2);
 		wake_up_interruptible(&info->open_wait);
 	}
 	info->flags &= ~(CTC_ASYNC_NORMAL_ACTIVE | CTC_ASYNC_CLOSING);
@@ -1250,7 +1231,7 @@
 }
 
 int
-ctc_tty_register_netdev(net_device *dev) {
+ctc_tty_register_netdev(struct net_device *dev) {
 	int ttynum;
 	char *err;
 	char *p;
@@ -1282,7 +1263,7 @@
 }
 
 void
-ctc_tty_unregister_netdev(net_device *dev) {
+ctc_tty_unregister_netdev(struct net_device *dev) {
 	int i;
 	unsigned long saveflags;
 	ctc_tty_info *info = NULL;
@@ -1302,16 +1283,13 @@
 }
 
 void
-ctc_tty_cleanup(int final) {
+ctc_tty_cleanup(void) {
 	unsigned long saveflags;
 	
 	spin_lock_irqsave(&ctc_tty_lock, saveflags);
 	ctc_tty_shuttingdown = 1;
-	if (final) {
-		kfree(driver);
-		driver = NULL;
-	} else {
-		tty_unregister_driver(&driver->ctc_tty_device);
-	}
+	tty_unregister_driver(&driver->ctc_tty_device);
+	kfree(driver);
+	driver = NULL;
 	spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
 }
diff -Nru a/drivers/s390/net/ctctty.h b/drivers/s390/net/ctctty.h
--- a/drivers/s390/net/ctctty.h	Mon Dec  9 18:46:34 2002
+++ b/drivers/s390/net/ctctty.h	Mon Dec  9 18:46:34 2002
@@ -1,5 +1,5 @@
 /*
- * $Id: ctctty.h,v 1.4 2001/03/22 12:46:01 felfert Exp $
+ * $Id: ctctty.h,v 1.3 2002/10/24 16:42:55 cohuck Exp $
  *
  * CTC / ESCON network driver, tty interface.
  *
@@ -28,17 +28,11 @@
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 
-#if LINUX_VERSION_CODE < 0x020300
-typedef struct device      net_device;
-#else
-typedef struct net_device  net_device;
-#endif
-
-extern int  ctc_tty_register_netdev(net_device *);
-extern void ctc_tty_unregister_netdev(net_device *);
+extern int  ctc_tty_register_netdev(struct net_device *);
+extern void ctc_tty_unregister_netdev(struct net_device *);
 extern void ctc_tty_netif_rx(struct sk_buff *);
 extern int  ctc_tty_init(void);
-extern void ctc_tty_cleanup(int);
-extern void ctc_tty_setcarrier(net_device *, int);
+extern void ctc_tty_cleanup(void);
+extern void ctc_tty_setcarrier(struct net_device *, int);
 
 #endif
diff -Nru a/drivers/s390/net/cu3088.c b/drivers/s390/net/cu3088.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/net/cu3088.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,176 @@
+/*
+ * $Id: cu3088.c,v 1.21 2002/12/03 16:26:45 cohuck Exp $
+ *
+ * CTC / LCS ccw_device driver
+ *
+ * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Author(s): Arnd Bergmann <arndb@de.ibm.com>
+ *            Cornelia Huck <cohuck@de.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 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+
+#include <asm/ccwdev.h>
+#include <asm/ccwgroup.h>
+
+#include "cu3088.h"
+
+const char *cu3088_type[] = {
+	"not a channel",
+	"CTC/A",
+	"ESCON channel",
+	"FICON channel",
+	"P390 LCS card",
+	"OSA2 card",
+	"unknown channel type",
+	"unsupported channel type",
+};
+
+/* static definitions */
+
+static struct ccw_device_id cu3088_ids[] = {
+	{ CCW_DEVICE(0x3088, 0x08), .driver_info = channel_type_parallel },
+	{ CCW_DEVICE(0x3088, 0x1f), .driver_info = channel_type_escon },
+	{ CCW_DEVICE(0x3088, 0x1e), .driver_info = channel_type_ficon },
+	{ CCW_DEVICE(0x3088, 0x01), .driver_info = channel_type_p390 },
+	{ CCW_DEVICE(0x3088, 0x60), .driver_info = channel_type_osa2 },
+	{ /* end of list */ }
+};
+
+static struct ccw_driver cu3088_driver;
+
+struct device cu3088_root_dev = {
+	.name   = "CU3088 Devices",
+	.bus_id = "cu3088",
+};
+
+static ssize_t
+group_write(struct device_driver *drv, const char *buf, size_t count,
+	    loff_t off)
+{
+	const char *start, *end;
+	char bus_ids[2][BUS_ID_SIZE], *argv[2];
+	int i;
+	int ret;
+	struct ccwgroup_driver *cdrv;
+
+	if (off)
+		return 0;
+
+	cdrv = to_ccwgroupdrv(drv);
+	if (!cdrv)
+		return -EINVAL;
+	start = buf;
+	for (i=0; i<2; i++) {
+		static const char delim[] = {',', '\n'};
+		int len;
+
+		if (!(end = strchr(start, delim[i])))
+			return count;
+		len = min_t(ptrdiff_t, BUS_ID_SIZE, end - start);
+		strncpy (bus_ids[i], start, len);
+		bus_ids[i][len] = '\0';
+		argv[i] = bus_ids[i];
+		start = end + 1;
+	}
+
+	ret = ccwgroup_create(&cu3088_root_dev, cdrv->driver_id,
+			      &cu3088_driver, 2, argv);
+
+	return (ret == 0) ? count : ret;
+}
+
+static DRIVER_ATTR(group, 0200, NULL, group_write);
+
+/* Register-unregister for ctc&lcs */
+int
+register_cu3088_discipline(struct ccwgroup_driver *dcp) 
+{
+	int rc;
+
+	if (!dcp)
+		return -EINVAL;
+
+	/* Register discipline.*/
+	rc = ccwgroup_driver_register(dcp);
+	if (rc)
+		return rc;
+
+	rc = driver_create_file(&dcp->driver, &driver_attr_group);
+	if (rc)
+		ccwgroup_driver_unregister(dcp);
+		
+	return rc;
+
+}
+
+void
+unregister_cu3088_discipline(struct ccwgroup_driver *dcp)
+{
+	if (!dcp)
+		return;
+
+	driver_remove_file(&dcp->driver, &driver_attr_group);
+	ccwgroup_driver_unregister(dcp);
+}
+
+static struct ccw_driver cu3088_driver = {
+	.owner	     = THIS_MODULE,
+	.ids	     = cu3088_ids,
+	.name        = "cu3088",
+	.probe	     = ccwgroup_probe_ccwdev,
+	.remove	     = ccwgroup_remove_ccwdev,
+};
+
+/* module setup */
+static int __init
+cu3088_init (void)
+{
+	int rc;
+	
+	rc = device_register(&cu3088_root_dev);
+	if (rc)
+		return rc;
+	rc = ccw_driver_register(&cu3088_driver);
+	if (rc) {
+		device_unregister(&cu3088_root_dev);
+		return rc;
+	}
+
+	return rc;
+}
+
+static void __exit
+cu3088_exit (void)
+{
+	ccw_driver_unregister(&cu3088_driver);
+	device_unregister(&cu3088_root_dev);
+}
+
+MODULE_DEVICE_TABLE(ccw,cu3088_ids);
+MODULE_AUTHOR("Arnd Bergmann <arndb@de.ibm.com>");
+MODULE_LICENSE("GPL");
+
+module_init(cu3088_init);
+module_exit(cu3088_exit);
+
+EXPORT_SYMBOL(register_cu3088_discipline);
+EXPORT_SYMBOL(unregister_cu3088_discipline);
diff -Nru a/drivers/s390/net/cu3088.h b/drivers/s390/net/cu3088.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/net/cu3088.h	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,41 @@
+#ifndef _CU3088_H
+#define _CU3088_H
+
+/**
+ * Enum for classifying detected devices.
+ */
+enum channel_types {
+        /* Device is not a channel  */
+	channel_type_none,
+
+        /* Device is a CTC/A */
+	channel_type_parallel,
+
+	/* Device is a ESCON channel */
+	channel_type_escon,
+
+	/* Device is a FICON channel */
+	channel_type_ficon,
+
+	/* Device is a P390 LCS card */
+	channel_type_p390,
+
+	/* Device is a OSA2 card */
+	channel_type_osa2,
+
+	/* Device is a channel, but we don't know
+	 * anything about it */
+	channel_type_unknown,
+
+	/* Device is an unsupported model */
+	channel_type_unsupported,
+
+	/* number of type entries */
+	num_channel_types
+};
+
+extern const char *cu3088_type[num_channel_types];
+extern int register_cu3088_discipline(struct ccwgroup_driver *);
+extern void unregister_cu3088_discipline(struct ccwgroup_driver *);
+
+#endif
diff -Nru a/drivers/s390/net/fsm.c b/drivers/s390/net/fsm.c
--- a/drivers/s390/net/fsm.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/s390/net/fsm.c	Mon Dec  9 18:46:37 2002
@@ -1,5 +1,5 @@
 /**
- * $Id: fsm.c,v 1.3 2001/06/18 16:49:19 felfert Exp $
+ * $Id: fsm.c,v 1.3 2002/10/08 16:53:45 mschwide Exp $
  *
  * A generic FSM based on fsm used in isdn4linux
  *
diff -Nru a/drivers/s390/net/fsm.h b/drivers/s390/net/fsm.h
--- a/drivers/s390/net/fsm.h	Mon Dec  9 18:46:50 2002
+++ b/drivers/s390/net/fsm.h	Mon Dec  9 18:46:50 2002
@@ -1,4 +1,4 @@
-/* $Id: fsm.h,v 1.4 2001/09/24 10:38:02 mschwide Exp $
+/* $Id: fsm.h,v 1.1.1.1 2002/03/13 19:33:09 mschwide Exp $
  */
 #ifndef _FSM_H_
 #define _FSM_H_
diff -Nru a/drivers/s390/net/iucv.c b/drivers/s390/net/iucv.c
--- a/drivers/s390/net/iucv.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/s390/net/iucv.c	Mon Dec  9 18:46:34 2002
@@ -1,5 +1,5 @@
 /* 
- * $Id: iucv.c,v 1.32 2002/02/12 21:52:20 felfert Exp $
+ * $Id: iucv.c,v 1.9 2002/11/06 13:37:25 cohuck Exp $
  *
  * IUCV network driver
  *
@@ -29,7 +29,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.32 $
+ * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.9 $
  *
  */
 
@@ -47,7 +47,6 @@
 #include <asm/atomic.h>
 #include "iucv.h"
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/s390_ext.h>
 #include <asm/ebcdic.h>
 
@@ -275,9 +274,7 @@
 
 MODULE_AUTHOR("(C) 2001 IBM Corp. by Fritz Elfert (felfert@millenux.com)");
 MODULE_DESCRIPTION("Linux for S/390 IUCV lowlevel driver");
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,12))
 MODULE_LICENSE("GPL");
-#endif
 
 /*
  * Debugging stuff
@@ -336,7 +333,7 @@
 static void
 iucv_banner(void)
 {
-	char vbuf[] = "$Revision: 1.32 $";
+	char vbuf[] = "$Revision: 1.9 $";
 	char *version = vbuf;
 
 	if ((version = strchr(version, ':'))) {
diff -Nru a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
--- a/drivers/s390/net/lcs.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/s390/net/lcs.c	Mon Dec  9 18:46:34 2002
@@ -3,12 +3,16 @@
  *
  *  Linux for S/390 Lan Channel Station Network Driver
  *
- *  Copyright (C)  1999-2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) 
- *               Frank Pavlic (pavlic@de.ibm.com)
+ *  Copyright (C)  1999-2001 IBM Deutschland Entwicklung GmbH,
+ *			     IBM Corporation
+ *    Author(s): Original Code written by
+ *			  DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+ *		 Rewritten by
+ *			  Frank Pavlic (pavlic@de.ibm.com) and
+ *		 	  Martin Schwidefsky <schwidefsky@de.ibm.com>
+ *
+ *    $Revision: 1.41 $	 $Date: 2002/12/06 12:42:01 $
  *
- *    $Revision: 1.128 $    $Date: 2002/03/01 16:56:47 $
- * 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
@@ -16,4155 +20,1865 @@
  *
  * 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
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
-/*
- 	Thanks to Uli Hild, Martin Schwidefsky,
-	& Ingo who probably will never let it down that 
-	he found the braindamage with my offset calculations on 
-	the IO buffers.
-	( for quality of effort, advise, support & sanity checking )
-	Alex, Boas & the rest of the team for the opportunity to work here.
-
-DRIVER OPERATION OVERVIEW README FIRST
-======================================
-
-The lcs driver currently supports Ethernet & Token Ring, FDDI is still
-experimental.
-
-The lan channel station(lcs) network interface has two channels one read
-channel one  write channel. This is very similar to the S390 CTC interface
-
-The read channel is recognised by having an even cuu number & model 0x3088
-The write channel is recognised by the formula write cuu=read cuu number + 1
-& also a model of 0x3088 only certain cuu models are supported so as not to
-clash with a CTC control unit model.
-
-The driver always has a read outstanding on the read subchannel this is used
-to receive both command replys & network packets ( these are differenciated by
-checking the type field in the lcs header structure ), network packets may
-come in during the startup & shutdown sequence these have to be discarded.
-During normal network I/O the driver will intermittently retry reads to
-permanently keep reads outstanding on the read channel if an -EBUSY or
-similar occurs (otherwise the driver would stop receiving network packets).
-
-The channel progam used work as described below
-===============================================
-The write subchannel has a hack in /net/core/skbuff.c which makes
-sure there is enough head & tailroom to write packets directly out of the
-socket buffer (If their isn't the code will still work). 
-
-If the write subchannel is busy network packets are
-aggregated together into a & queued for transmission, the reason I'm doing
-this is to minimise start subchannels & interrupts which I have been told
-& have proven to be very expensive.
-
-e.g. a ping -f -s 1400 -c 20000 <gateway_addr> >/dev/null used take 40 secs,
-on my machine & a ping -f -s 100 -c 20000 <gateway_addr> >/dev/null took 27
-secs, over token ring with a single buffer this has improved a lot with the
-queueing technique (I also made sure that the delay wasn't caused by waiting
-for the free token).
-
-The new program works as follows
-================================
-The read & channel program consists of of 8 read ccw commands 
-followed by a transfer in channel back to the 1st read ccw. 
-A moving suspend bit is switched on in the read
-ccw of the last buffer processed with pci's switched on in the
-remaining ccw's. This way I recieve buffers with pci's without
-having to issue excess resumes or ssch's & only
-need to issue a resume if the read program gets suspended when
-all the buffers are filled.
-
-The write program consists of 4 to 9 write ccw commands folled
-by a transfer in channel back to the 1st write ccw.
-All unfilled buffers all have the suspend bit on & the
-suspend bit is taken off when buffers are either filled or partially
-filled & the write channel is no longer busy.
-
-The lan channel is started as follows
-1) A halt subchannel is issued to the read & write subchannel
-2) A startup primitive is sent to the lan & the reply is read from the read
-subchannel.
-3) Every possible relative adapter number issued a startlan primative with
-attempts to configure it as token ring ethernet & fddi at some stage in the
-boot sequence or when the module is being inserted.
-The relative adapter number is normally equal to the low byte of the read
-channel cuu/2 & hence the reason for the hint field to speed up lcs_detect.
-5) On success of a startlan we  know whether the osa card is configured as
-token ring, ethernet or fddi, a lanstat primative is issued to get the
-mac address.
-6) The device is now ready for network io.
-
-The shutdown is similar to the startup just a stoplan primative followed
-by a shutdown.
-
-The driver instance globals lcs_drvr_globals are held in the priv element of
-the device structure & these in turn point to a lcs_chan_globals structure
-for the read & write channel. The read & write chan_globals & driver
-globals have their own state machine, so that the interrupt handler can
-make decisions on whether to send packets read to the network layer, or
-whether it is should wake up a process currently issuing lan commands.
-
-*/
-
-#define TRUE 1
-#define FALSE 0
-#define ERETRY 255
-
 #include <linux/version.h>
 #include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/irq.h>
+#include <linux/if.h>
 #include <linux/netdevice.h>
-#if LINUX_VERSION_CODE<KERNEL_VERSION(2,3,0)
-#include <linux/kcomp.h>
-#endif
-
-#if CONFIG_NET_ETHERNET
 #include <linux/etherdevice.h>
-extern int ethif_probe(struct net_device *dev);
-#endif
-#ifdef CONFIG_TR
 #include <linux/trdevice.h>
-extern int trif_probe(struct net_device *dev);
-#endif
-#ifdef CONFIG_FDDI
 #include <linux/fddidevice.h>
-extern int fddiif_probe(struct net_device *dev);
-#endif
-#include <asm/irq.h>
-#include <asm/queue.h>
-#define LCS_CHANDEV CONFIG_CHANDEV
-#if LCS_CHANDEV
-#include <asm/chandev.h>
-#endif
-#ifdef CONFIG_IP_MULTICAST
 #include <linux/inetdevice.h>
-#include <net/arp.h>
-#include <net/ip.h>
 #include <linux/in.h>
 #include <linux/igmp.h>
-#endif
-#include <net/pkt_sched.h>
-#include <net/sock.h>
-#include <net/dst.h>
-
-#define LCS_USE_IDALS  (LINUX_VERSION_CODE>KERNEL_VERSION(2,2,16))
-#if (!CONFIG_ARCH_S390X) || (LCS_USE_IDALS)
-#define lcs_dev_alloc_skb(length) dev_alloc_skb((length))
-#endif
-#if LCS_USE_IDALS
-#  include <asm/idals.h>
-#else
-#define set_normalized_cda(ccw, addr) ((ccw)->cda = (addr),0)
-#define clear_normalized_cda(ccw)
-#endif
-
-#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,2,18))
-#define LCS_DEBUG 1
-#else
-#define LCS_DEBUG 0
-#endif
-#define LCS_PRINTK_DEBUG   0
-#define LCS_ZERO_COPY_READ 0
+#include <net/arp.h>
+#include <net/ip.h>
 
-#if LCS_DEBUG && !LCS_PRINTK_DEBUG
 #include <asm/debug.h>
-#endif
-
-#if !defined(CONFIG_NET_ETHERNET)&&!defined(CONFIG_TR)&&!defined(CONFIG_FDDI)
-#error Cannot compile lcs.c without some net devices switched on.
-#endif
-
-#define lcs_inline inline
-
-#if LINUX_VERSION_CODE<=KERNEL_VERSION(2,2,16)
-#define lcs_daemonize(name,mask,use_init_fs) s390_daemonize(name,mask)
-#else
-#define lcs_daemonize(noargs...)
-#endif
+#include <asm/idals.h>
+#include <asm/timex.h>
+#include <linux/device.h>
+#include <asm/ccwgroup.h>
 
-/* for the proc filesystem */
-static const char *cardname = "S390 Lan Channel Station Interface";
+#include "lcs.h"
+#include "cu3088.h"
 
-/* lcs ccw command codes */
 
-enum {
-	ccw_write = 0x1,
-	ccw_read = 0x2,
-	ccw_read_backward = 0xc,
-	ccw_control = 0x3,
-	ccw_sense = 0x4,
-	ccw_sense_id = 0xe4,
-	ccw_transfer_in_channel0 = 0x8,
-	ccw_transfer_in_channel1 = 0x8,
-	ccw_set_x_mode = 0xc3,	// according to uli's lan notes
-	ccw_nop = 0x3		// according to uli's notes again
-	    // n.b. ccw_control clashes with this
-	    // so I presume its a special case of
-	    // control
-};
-
-/* startup & shutdown primatives */
-
-typedef enum {
-	lcs_startlan = 1,
-	lcs_stoplan = 2,
-	lcs_lanstat = 4,
-	lcs_startup = 7,
-	lcs_shutdown = 8,
-#ifdef CONFIG_IP_MULTICAST
-	lcs_qipassist = 0xb2,
-	lcs_setipm = 0xb4,
-	lcs_delipm = 0xb5
-#endif
-} lcs_cmd;
-
-typedef enum {
-	command_reject = 0x80,
-	intervention_required = 0x40,
-	bus_out_check = 0x20,
-	equipment_check = 0x10,
-	interface_disconnect = 0x01,
-} lcs_sense_byte_0;
-
-typedef enum {
-	resetting_event = 0x0080,
-	device_online = 0x0020,
-} lcs_sense_byte_1;
-
-/* The type of packet we are transmitting or receiving from the lcs */
-typedef enum {
-	lcs_control_frame_type = 0,	/* for startup shutdown etc */
-	lcs_enet_type = 1,	/* the rest are for normal network io */
-	lcs_token_ring_type = 2,
-	lcs_fddi_type = 7,
-	lcs_autodetect_type = -1,
-} lcs_frame_type;
-
-#define LCS_ILLEGAL_OFFSET 0xffff
-
-static int use_hw_stats = 0;
-static int checksum_received_ip_pkts = 0;
-#if !LCS_CHANDEV
-/* Max number of cuu models we can detect */
-#define LCS_CURR_NUM_MODELS   4
-#define LCS_ADDITIONAL_MODELS 12
-#define LCS_ADDITIONAL_MODELS_X2_STR "24"
-#define LCS_MAX_NUM_MODELS  (LCS_CURR_NUM_MODELS+LCS_ADDITIONAL_MODELS)
-/* max number of parms that can be sent to lcs_setup */
-#define LCS_MAX_NUM_PARMS ((LCS_MAX_NUM_MODELS<<1)+2)
-/* configuration parms for the lcs card */
-typedef struct {
-	int cu_model;
-	int max_rel_adapter_no;
-} lcs_model_info;
-
-/* The models supported currently used in probing */
-#define LCS_CUTYPE 0x3088
-
-/* default configuration parms */
-
-static lcs_model_info lcs_models[LCS_CURR_NUM_MODELS]
-    __attribute__ ((section(".data"))) = {
-	{0x1, 15}, 
-	/* P390/Planter 3172 emulation assume maximum 16 to be safe. */
-	{0x8, 15},		
-	/* 3172/2216 Paralell the 2216 allows 16 ports per card */
-	/* the original 3172 only allows 4 we will assume the max of 16 */
-	{0x60, 1},		
-	/* Only 2 ports allowed on OSA2 cards model 0x60 */
-	{0x1F, 15},		
-	/* 3172/2216 Escon serial the 2216 allows 16 ports per card  */
-	/* the original 3172 only allows 4 we will assume the max of 16 */
-};
-static int additional_model_info[LCS_ADDITIONAL_MODELS << 1] = { 0, };
-/* Set this to one to stop autodetection */
-static int noauto = 0, ignore_sense = 0;
-
-/*
- * The lcs header 
- * offset=the offset of the next cmd/network packet 
- * type=command ethernet token ring fddi frame 
- * slot=relative adapter no
- */
-
-#define LCS_MAX_FORCED_DEVNOS 12
-#define LCS_MAX_FORCED_DEVNOS_X2_STR "24"
-typedef struct {
-	int devno;
-	int portno;
-} lcs_dev_portno_pair;
-static int devno_portno_pairs[LCS_MAX_FORCED_DEVNOS << 1] =
-    {[0 ... ((LCS_MAX_FORCED_DEVNOS << 1) - 1)] 2, };
-static lcs_dev_portno_pair *lcs_dev_portno =
-    (lcs_dev_portno_pair *) & devno_portno_pairs[0];
+#if !defined(CONFIG_NET_ETHERNET) && \
+    !defined(CONFIG_TR) && !defined(CONFIG_FDDI)
+#error Cannot compile lcs.c without some net devices switched on.
 #endif
 
-#define lcs_header           \
-u16		offset;      \
-u8		type;        \
-u8		slot;
-
-typedef struct {
-lcs_header} lcs_header_type __attribute__ ((packed));
-
-enum {
-	lcs_390_initiated,
-	lcs_lgw_initiated
-};
-
-/*
- * lcs startup & shutdown commands 
+/**
+ * initialization string for output
  */
-#define lcs_base_cmd         \
-u8		cmd_code;    \
-u8		initiator;   \
-u16		sequence_no; \
-u16		return_code; \
-
-typedef struct {
-	lcs_header lcs_base_cmd u8 lan_type;
-	u8 rel_adapter_no;
-	u16 parameter_count;
-	u8 operator_flags[3];
-	u8 reserved[3];
-	u8 command_data[0];
-} lcs_std_cmd __attribute__ ((packed));
-
-typedef struct {
-	lcs_header lcs_base_cmd u16 unused1;
-	u16 buff_size;
-	u8 unused2[6];
-} lcs_startup_cmd __attribute__ ((packed));
-
-#define LCS_ADDR_LEN 6
+#define VERSION_LCS_C  "$Revision: 1.41 $"
 
-#ifdef CONFIG_IP_MULTICAST
-typedef struct {
-	u32 ip_addr;
-	u8 mac_address[LCS_ADDR_LEN];
-	u8 reserved[2];
-} lcs_ip_mac_addr_pair __attribute__ ((packed));
-
-typedef enum {
-	ipm_set_required,
-	ipm_delete_required,
-	ipm_on_card
-} lcs_ipm_state;
-typedef struct lcs_ipm_list lcs_ipm_list;
-struct lcs_ipm_list {
-	struct lcs_ipm_list *next;
-	lcs_ip_mac_addr_pair ipm;
-	lcs_ipm_state ipm_state;
-};
-
-#define MAX_IP_MAC_PAIRS      32
-typedef struct {
-	lcs_header lcs_base_cmd u8 lan_type;
-	u8 rel_adapter_no;
-	/* OSA only will only support one IP Multicast entry at a time */
-	u16 num_ipm_pairs;
-	u16 ip_assists_supported;	/* returned by OSA  */
-	u16 ip_assists_enabled;	/* returned by OSA */
-	u16 version;		/* IP version i.e. 4 */
-	lcs_ip_mac_addr_pair ip_mac_pair[MAX_IP_MAC_PAIRS];
-	u32 response_data;
-} lcs_ipm_ctlmsg __attribute__ ((packed));
-typedef struct {
-	lcs_header lcs_base_cmd u8 lan_type;
-	u8 rel_adapter_no;
-	u16 num_ip_pairs;	/* should be 0 */
-	u16 ip_assists_supported;	/* returned by OSA  */
-	u16 ip_assists_enabled;	/* returned by OSA */
-	u16 version;		/* IP version i.e. 4 */
-} lcs_qipassist_ctlmsg __attribute__ ((packed));
-
-typedef enum {
-	/* Not supported by LCS */
-	lcs_arp_processing = 0x0001,
-	lcs_inbound_checksum_support = 0x0002,
-	lcs_outbound_checksum_support = 0x0004,
-	lcs_ip_frag_reassembly = 0x0008,
-	lcs_ip_filtering = 0x0010,
-	/* Supported by lcs 3172 */
-	lcs_ip_v6_support = 0x0020,
-	lcs_multicast_support = 0x0040
-} lcs_assists;
-#define LANCMD_DEFAULT_MCAST_PARMS ,0,NULL
-#else
-#define LANCMD_DEFAULT_MCAST_PARMS
-#endif
-
-typedef struct {
-	lcs_header lcs_base_cmd u8 lan_type;
-	u8 rel_adapter_no;
-	u8 unused1[10];
-	u8 mac_address[LCS_ADDR_LEN];
-	u32 num_packets_deblocked;
-	u32 num_packets_blocked;
-	u32 num_packets_tx_on_lan;
-	u32 num_tx_errors_detected;
-	u32 num_tx_packets_disgarded;
-	u32 num_packets_rx_from_lan;
-	u32 num_rx_errors_detected;
-	u32 num_rx_discarded_nobuffs_avail;
-	u32 num_rx_packets_too_large;
-} lcs_lanstat_reply __attribute__ ((packed));
-
-/* This buffer sizes are used by MVS so they should be reasonable */
-#define LCS_IOBUFFSIZE     0x5000
-#define LCS_NUM_TX_BUFFS    8
-#define LCS_NUM_RX_BUFFS    8
-
-#define LCS_INVALID_LOCK_OWNER            -1
-
-#if LINUX_VERSION_CODE<KERNEL_VERSION(2,2,18)
-typedef struct wait_queue *wait_queue_head_t;
-#endif
-#if LINUX_VERSION_CODE<KERNEL_VERSION(2,4,0)
-typedef dev_info_t s390_dev_info_t;
-#endif
-
-typedef enum {
-	chan_dead,
-	chan_idle,
-	chan_busy,
-	chan_starting_up,
-	chan_started_successfully
-} lcs_chan_busy_state;
-
-#define LCS_MAGIC			0x05A22A05	/* OSA2 to you */
-#define LCS_CHAN_GLOBALS(num_io_buffs)      \
-u32                  irq_allocated_magic;   \
-u16 subchannel;                             \
-u16 devno;                                  \
-struct lcs_drvr_globals *drvr_globals;      \
-atomic_t             sleeping_on_io;        \
-unsigned long        flags;                 \
-int                  rc;                    \
-int                  lock_owner;            \
-int                  lock_cnt;              \
-wait_queue_head_t    wait;                  \
-struct work_struct   retry_task;            \
-devstat_t	     devstat;               \
-lcs_chan_busy_state  chan_busy_state;       \
-ccw1_t               ccw[num_io_buffs+1];   \
-
-
-typedef struct {
-	LCS_CHAN_GLOBALS(0)
-} lcs_chan_globals;
-
-typedef struct {
-	LCS_CHAN_GLOBALS(LCS_NUM_RX_BUFFS)
-#if LCS_ZERO_COPY_READ
-	struct sk_buff *skb_buff[LCS_NUM_RX_BUFFS];
-#else
-	u8 *iobuff[LCS_NUM_RX_BUFFS];
-#endif
-	lcs_std_cmd *lancmd_reply_ptr;	/* only used by read channel */
-	u32 rx_idx;
-	u8 pad[0] __attribute__ ((aligned(8)));	/* so the next structure
-						   will be aligned */
-} lcs_read_globals;
-
-typedef struct {
-	LCS_CHAN_GLOBALS(LCS_NUM_TX_BUFFS)
-	u8 *iobuff[LCS_NUM_TX_BUFFS];
-	u32 prepare_idx;	/* current buffer being prepared */
-	u32 tx_idx;		/* last buffer successfully transmitted */
-	unsigned long pkts_still_being_txed;
-	unsigned long bytes_still_being_txed;
-	struct work_struct resume_task;
-	int resume_queued;
-	int resume_loopcnt;
-	uint64_t last_lcs_txpacket_time;
-	uint64_t last_resume_time;
-	uint64_t adjusted_last_bytes_still_being_txed;
-} lcs_write_globals;
+static const char *version="LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")";
 
-#define LCS_READ_ALLOCSIZE      LCS_IOBUFFSIZE
-
-/*
- * drvr_globals main state machine 
+/**
+ * Some prototypes.
  */
-typedef enum {
-	lcs_idle,
-	lcs_halting_subchannels,
-	lcs_doing_io,
-	lcs_idle_requesting_channels_for_lancmds,
-	lcs_requesting_channels_for_lancmds,
-	lcs_got_write_channel_for_lancmds,
-	lcs_doing_lancmds,
-	lcs_interrupted
-} lcs_state;
+static void lcs_tasklet(unsigned long);
+static void lcs_start_kernel_thread(struct lcs_card *card);
+static void lcs_get_frames_cb(struct lcs_channel *, struct lcs_buffer *);
 
-enum {
-	lcs_invalid_adapter_no = -1
-};
-
-typedef struct lcs_drvr_globals lcs_drvr_globals;
-struct lcs_drvr_globals {
-	struct lcs_drvr_globals *next;
-	struct net_device *dev;
-	atomic_t usage_cnt;	/* used by drvr_globals_valid 
-				 * & lcs_usage_free_drvr_globals */
-	u8 lan_type;
-	u8 cmd_code;
-	unsigned short (*lan_type_trans) (struct sk_buff * skb,
-					  struct net_device * dev);
-	wait_queue_head_t lanstat_wait;	/* processes asleep awaiting 
-					 * lanstat results */
-	int doing_lanstat;
-	int up;
-	lcs_state state;
-	lcs_read_globals *read;
-	lcs_write_globals *write;
-	u16 sequence_no;
-	s16 rel_adapter_no;
-	int slow_hw;
-	/* To insure only one kernel thread runs at a time */
-	atomic_t kernel_thread_lock;
-	int (*kernel_thread_routine) (lcs_drvr_globals * drvr_globals);
-	struct work_struct kernel_thread_task;
-	u16 lgw_sequence_no;	/* this isn't required just being thorough */
-	atomic_t retry_cnt;
-	struct net_device_stats stats __attribute__ ((aligned(4)));
-#ifdef CONFIG_IP_MULTICAST
-	spinlock_t ipm_lock;
-	lcs_ipm_list *ipm_list;
-#endif
-	/* So I can use atomic atomic_t for stats if required  */
-	u8 pad[0] __attribute__ ((aligned(8)));
-	/* CCW's need 8 byte alignment ( Thanks Martin ) */
-} __attribute__ ((aligned(8)));
-
-/* 
- * A token ring header can be 40 bytes if you include the llc & rcf so we 
- * leave a small bit extra.
+/**
+ * Debug Facility Stuff
  */
+static debug_info_t *lcs_dbf_setup;
+static debug_info_t *lcs_dbf_trace;
 
-#define LCS_TX_HIWATERMARK          LCS_IOBUFFSIZE-60
-
-#define LCS_ALLOCSIZE (sizeof(lcs_drvr_globals)+sizeof(lcs_read_globals)+sizeof(lcs_write_globals))
-
-/* Function prototypes */
-static int lcs_rxpacket(lcs_drvr_globals * drvr_globals, u8 * start_buff,
-		 lcs_std_cmd ** lancmd_reply
-#if LCS_ZERO_COPY_READ
-		 , u32 curr_idx
-#endif
-		 );
-static int lcs_txpacket(struct sk_buff *skb, struct net_device *dev);
-static int lcs_detect(lcs_drvr_globals * drvr_globals, s16 forced_port_no,
-		      u8 hint_port_no, u8 max_port_no,
-		      lcs_frame_type frame_type, u8 * mac_address);
-static int lcs_check_reset(lcs_chan_globals * chan_globals);
-static void lcs_restartreadio(lcs_drvr_globals * drvr_globals);
-static void lcs_restartwriteio(lcs_drvr_globals * drvr_globals);
-static void lcs_queued_restartreadio(lcs_drvr_globals * drvr_globals);
-static void lcs_queued_restartwriteio(lcs_drvr_globals * drvr_globals);
-static void lcs_resume_writetask(lcs_write_globals * write);
-#ifdef MODULE
-void cleanup_module(void);
-#endif
-
-#ifdef CONFIG_IP_MULTICAST
-static int lcs_fix_multicast_list(lcs_drvr_globals * drvr_globals);
-#endif
-
-#define lcs_debug_initmessage      char *message=NULL;
-#define lcs_debug_setmessage(string) message=string
-
-#if LCS_DEBUG
-#if LCS_PRINTK_DEBUG
-#define lcs_debug_event(level,args...)      printk(##args)
-#define lcs_debug_exception(level,args...)  printk(##args)
-#define lcs_bad_news(args...)         printk(KERN_CRIT ##args);
-#define lcs_good_news(args...)         printk(##args);
-#else
-static debug_info_t *lcs_id = NULL;
-#define lcs_debug_event(args...)      debug_sprintf_event(lcs_id,##args)
-#define lcs_debug_exception(args...)  debug_sprintf_exception(lcs_id,##args)
-
-/* &formatstr[3] is to get over the KERN_CRIT prefix */
-#define lcs_bad_news(format,args...)                   \
-{                                                      \
-        char *formatstr= KERN_CRIT format;             \
-	lcs_debug_exception(0,&formatstr[3] ,## args); \
-	printk(formatstr ,## args);                    \
-}
-
-#define lcs_good_news(format,args...)                  \
-{                                                      \
-        char *formatstr=format;                        \
-	lcs_debug_event(0,formatstr ,## args);         \
-	printk(formatstr ,## args);                    \
+/**
+ *  LCS Debug Facility functions
+ */
+static void
+lcs_unregister_debug_facility(void)
+{
+	if (lcs_dbf_setup)
+		debug_unregister(lcs_dbf_setup);
+	if (lcs_dbf_trace)
+		debug_unregister(lcs_dbf_trace);
 }
-#endif
 
-#define lcs_debugchannel(message,chan_globals) \
-lcs_debugchannel_func((message),(lcs_chan_globals *)(chan_globals))
+static int
+lcs_register_debug_facility(void)
+{
+	lcs_dbf_setup = debug_register("lcs_setup", 1, 1, 8);
+	lcs_dbf_trace = debug_register("lcs_trace", 1, 2, 8);
+	if (lcs_dbf_setup == NULL || lcs_dbf_trace == NULL) {
+		PRINT_ERR("Not enough memory for debug facility.\n");
+		lcs_unregister_debug_facility();
+		return -ENOMEM;
+	}
+	debug_register_view(lcs_dbf_setup, &debug_hex_ascii_view);
+	debug_set_level(lcs_dbf_setup, 5);
+	debug_register_view(lcs_dbf_trace, &debug_hex_ascii_view);
+	debug_set_level(lcs_dbf_trace, 3);
+	return 0;
+}
 
-static void
-lcs_debugchannel_func(char *message, lcs_chan_globals * chan_globals)
+/**
+ * Allocate io buffers.
+ */
+static int
+lcs_alloc_channel(struct lcs_channel *channel)
 {
-	lcs_drvr_globals *drvr_globals;
+	int cnt;
 
-	if (message) {
-		lcs_debug_event(0, "lcs: %s\n", message);
+	LCS_DBF_TEXT(3, setup, "ichalloc");
+	for (cnt = 0; cnt < LCS_NUM_BUFFS; cnt++) {
+		/* alloc memory fo iobuffer */
+		channel->iob[cnt].data = (void *)
+			kmalloc(LCS_IOBUFFERSIZE, GFP_DMA | GFP_KERNEL);
+		if (channel->iob[cnt].data == NULL)
+			break;
+		memset(channel->iob[cnt].data, 0, LCS_IOBUFFERSIZE);
+		channel->iob[cnt].state = BUF_STATE_EMPTY;
 	}
-	lcs_debug_event(0, "lcs  irq=%04x devno=%04x %s\n",
-			(int) chan_globals->subchannel,
-			(int) chan_globals->devno, (message ? message : ""));
-	lcs_debug_event(0, "chan globals=%p\n", chan_globals);
-	if (chan_globals) {
-		drvr_globals = chan_globals->drvr_globals;
-		if (drvr_globals) {
-			if (drvr_globals->read !=
-			    (lcs_read_globals *) chan_globals
-			    && drvr_globals->write !=
-			    (lcs_write_globals *) chan_globals)
-				lcs_debug_event(0,
-						"drvr globals inconsistent\n");
-			lcs_debug_event(0, "drvr_globals=%p:state=%d\n",
-					drvr_globals, drvr_globals->state);
-			lcs_debug_event(0,
-					"chan globals sleeping_on_io=%d"
-					" busy_state=%d lock_owner=%d "
-					"lock_cnt=%d\n",
-					atomic_read(&chan_globals->
-						    sleeping_on_io),
-					chan_globals->chan_busy_state,
-					chan_globals->lock_owner,
-					chan_globals->lock_cnt);
-		}
+	if (cnt < LCS_NUM_BUFFS) {
+		/* Not all io buffers could be allocated. */
+		LCS_DBF_TEXT(3, setup, "echalloc");
+		while (cnt-- > 0)
+			kfree(channel->iob[cnt].data);
+		return -ENOMEM;
 	}
-	lcs_debug_exception(0, "leaving lcs_debugchannel\n");
+	return 0;
 }
 
+/**
+ * Free io buffers.
+ */
 static void
-lcs_debug_display_read_buff(char *message, lcs_std_cmd * lancmd_reply_ptr)
+lcs_free_channel(struct lcs_channel *channel)
 {
-	int *read_buff = (int *) lancmd_reply_ptr;
+	int cnt;
 
-	lcs_debug_event(1, "%s %08x %08x %08x\n", message,
-			read_buff[0], read_buff[1], read_buff[2]);
+	LCS_DBF_TEXT(3, setup, "ichfree");
+	for (cnt = 0; cnt < LCS_NUM_BUFFS; cnt++)
+		kfree(channel->iob[cnt].data);
 }
 
-#else
-#define lcs_debug_event(noargs...)
-#define lcs_debug_exception(noargs...)
-#define lcs_bad_news(args...)  printk(KERN_CRIT ##args)
-#define lcs_good_news(args...)  printk(##args)
-#define lcs_debugchannel(message,chan_globals)   \
-printk("lcs  irq=%04x devno=%04x %s\n",(int)chan_globals->subchannel, \
-(int)chan_globals->devno,(message ? message:""))
-#define lcs_debug_display_read_buff(noargs...)
-#endif
-
-#if (!LCS_USE_IDALS) && (CONFIG_ARCH_S390X)
-static inline struct sk_buff *
-lcs_dev_alloc_skb(unsigned int length)
+/**
+ * LCS alloc memory for card and channels
+ */
+static struct lcs_card *
+lcs_alloc_card(void)
 {
-	struct sk_buff *skb;
+	struct lcs_card *card;
 
-	skb = alloc_skb(length + 16, GFP_ATOMIC | GFP_DMA);
-	if (skb)
-		skb_reserve(skb, 16);
-	return skb;
-}
-#endif
-
-static void lcs_inline
-lcs_resetstate(lcs_drvr_globals * drvr_globals)
-{
-	drvr_globals->state = lcs_idle;
+	LCS_DBF_TEXT(3, setup, "alloclcs");
+	card = kmalloc(sizeof(struct lcs_card), GFP_KERNEL | GFP_DMA);
+	if (card == NULL)
+		return NULL;
+	memset(card, 0, sizeof(struct lcs_card));
+	card->lan_type = LCS_FRAME_TYPE_AUTO;
+	return card;
 }
 
-/* 
- * Primatives used to put the process to sleep or wake it up during startup 
- * or shutdown.
+/**
+ * LCS free memory for card and channels.
  */
-static lcs_inline void
-lcs_initqueue_func(lcs_chan_globals * chan_globals)
+static void
+lcs_free_card(struct lcs_card *card)
 {
-	atomic_set(&chan_globals->sleeping_on_io, TRUE);
-	chan_globals->rc = 0;
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-	init_waitqueue_head(&chan_globals->wait);
-#else
-	chan_globals->wait = NULL;
-#endif
+	LCS_DBF_TEXT(2, setup, "remcard");
+	kfree(card);
 }
 
-#define lcs_initqueue(chan_globals) \
-	lcs_initqueue_func((lcs_chan_globals *)chan_globals)
-
+/*
+ * Setup read channel.
+ */
 static void
-lcs_wakeup_func(lcs_chan_globals * chan_globals, int rc)
+lcs_setup_read_ccws(struct lcs_card *card)
 {
-	lcs_debug_event(2, "lcs_wakeup called sch=%04x rc=%d\n,",
-			(int) chan_globals->subchannel, rc);
-	atomic_set(&chan_globals->sleeping_on_io, FALSE);
-	if (chan_globals->rc == 0)
-		chan_globals->rc = rc;
-	wake_up(&chan_globals->wait);
-}
+	int cnt;
 
-#define TOD_SHIFT_TO_USECS 12
-static inline uint64_t
-lcs_get_tod(void)
-{
-	uint64_t cc;
+	LCS_DBF_TEXT(2, setup, "ireadccw");
+	/* Setup read ccws. */
+	memset(card->read.ccws, 0, sizeof (struct ccw1) * (LCS_NUM_BUFFS + 1));
+	for (cnt = 0; cnt < LCS_NUM_BUFFS; cnt++) {
+		card->read.ccws[cnt].cmd_code = LCS_CCW_READ;
+		card->read.ccws[cnt].count = LCS_IOBUFFERSIZE;
+		card->read.ccws[cnt].flags =
+			CCW_FLAG_CC | CCW_FLAG_SLI | CCW_FLAG_PCI;
+		/*
+		 * Note: we have allocated the buffer with GFP_DMA, so
+		 * we do not need to do set_normalized_cda.
+		 */
+		card->read.ccws[cnt].cda =
+			(__u32) __pa(card->read.iob[cnt].data);
+		((struct lcs_header *)
+		 card->read.iob[cnt].data)->offset = LCS_ILLEGAL_OFFSET;
+		card->read.iob[cnt].callback = lcs_get_frames_cb;
+		card->read.iob[cnt].state = BUF_STATE_READY;
+		card->read.iob[cnt].count = LCS_IOBUFFERSIZE;
+	}
+	card->read.ccws[0].flags &= ~CCW_FLAG_PCI;
+	card->read.ccws[LCS_NUM_BUFFS - 1].flags &= ~CCW_FLAG_PCI;
+	card->read.ccws[LCS_NUM_BUFFS - 1].flags |= CCW_FLAG_SUSPEND;
+	/* Last ccw is a tic (transfer in channel). */
+	card->read.ccws[LCS_NUM_BUFFS].cmd_code = LCS_CCW_TRANSFER;
+	card->read.ccws[LCS_NUM_BUFFS].cda =
+		(__u32) __pa(card->read.ccws);
+	/* Setg initial state of the read channel. */
+	card->read.state = CH_STATE_INIT;
 
- 	asm volatile ("STCK %0":"=m" (cc));
-	return (cc);
+	card->read.io_idx = 0;
+	card->read.buf_idx = 0;
 }
 
-#define lcs_wakeup(chan_globals,rc) \
-	lcs_wakeup_func((lcs_chan_globals *)chan_globals,(rc))
 static int
-lcs_sleepon_func(lcs_chan_globals * chan_globals, int extratime)
+lcs_setup_read(struct lcs_card *card)
 {
-	/*
-	   We have a miniscule chance of sleeping here for 1 second
-	   we have to unfortunately live with it as down_interruptible
-	   dosen't wake up for timers just signals.
-	 */
-	int rc = 0;
-
-	lcs_debug_event(2, "lcs_sleepon called sch=%04x\n,",
-			(int) chan_globals->subchannel);
-#warning FIXME: [kj] Using sleep_on derivative, is racy. consider using wait_event instead
-	sleep_on_timeout(&chan_globals->wait, HZ);
-	if (atomic_read(&chan_globals->sleeping_on_io) && chan_globals->rc == 0
-	    && extratime) {
-		lcs_bad_news
-		    ("lcs_sleepon network card taking time responding "
-		     "irq=%04x devno=%04x,\n"
-		     "please be patient, ctrl-c will exit if shell prompt "
-		     "is available.\n",
-		     (int) chan_globals->subchannel, (int) chan_globals->devno);
-#warning FIXME: [kj] Using sleep_on derivative, is racy. consider using wait_event instead
-		interruptible_sleep_on_timeout(&chan_globals->wait,
-					       extratime * HZ);
-	}
-	if (atomic_read(&chan_globals->sleeping_on_io) && chan_globals->rc == 0) {
-		chan_globals->drvr_globals->state = lcs_interrupted;
-		rc = (test_thread_flag(TIF_SIGPENDING) ? -EINTR : -ETIMEDOUT);
+	int rc;
 
+	LCS_DBF_TEXT(3, setup, "readirq");
+	/* Allocate io buffers for the read channel. */
+	rc = lcs_alloc_channel(&card->read);
+	if (rc){
+		LCS_DBF_TEXT(3, setup, "iccwerr");
+		return rc;
 	}
-	if (chan_globals->rc)
-		rc = chan_globals->rc;
-	lcs_debug_event(2, "lcs_sleepon sch=%04x devno=%04x rc=%d\n",
-			(int) chan_globals->subchannel,
-			(int) chan_globals->devno, rc);
-	return (rc);
-
+	lcs_setup_read_ccws(card);
+	/* Initialize read channel tasklet. */
+	card->read.irq_tasklet.data = (unsigned long) &card->read;
+	card->read.irq_tasklet.func = lcs_tasklet;
+	/* Initialize waitqueue. */
+	init_waitqueue_head(&card->read.wait_q);
+	return 0;
 }
 
-#define lcs_sleepon(chan_globals,extratime) \
-	lcs_sleepon_func((lcs_chan_globals *)chan_globals,extratime)
-
+/*
+ * Setup write channel.
+ */
 static void
-lcs_chan_lock_func(lcs_chan_globals * chan_globals)
+lcs_setup_write_ccws(struct lcs_card *card)
 {
-	eieio();
-	if (chan_globals->lock_owner != smp_processor_id()) {
-		s390irq_spin_lock_irqsave(chan_globals->subchannel,
-					  chan_globals->flags);
-		chan_globals->lock_cnt = 1;
-		chan_globals->lock_owner = smp_processor_id();
+	int cnt;
 
-	} else
-		chan_globals->lock_cnt++;
-	if (chan_globals->lock_cnt < 0 || chan_globals->lock_cnt > 100) {
-		lcs_bad_news("bad lock_cnt %d in lcs_chan_lock chan_globals=%p"
-			     " devno=%04x returnaddrs=%p,%p cpu=%d\n",
-			     chan_globals->lock_cnt, chan_globals,
-			     (int) chan_globals->devno,
-			     __builtin_return_address(0),
-			     __builtin_return_address(1), smp_processor_id());
-		chan_globals->lock_cnt = 1;
+	LCS_DBF_TEXT(2, setup, "iwritccw");
+	/* Setup write ccws. */
+	memset(card->write.ccws, 0, sizeof(struct ccw1) * LCS_NUM_BUFFS + 1);
+	for (cnt = 0; cnt < LCS_NUM_BUFFS; cnt++) {
+		card->write.ccws[cnt].cmd_code = LCS_CCW_WRITE;
+		card->write.ccws[cnt].count = 0;
+		card->write.ccws[cnt].flags =
+			CCW_FLAG_SUSPEND | CCW_FLAG_CC | CCW_FLAG_SLI;
+		/*
+		 * Note: we have allocated the buffer with GFP_DMA, so
+		 * we do not need to do set_normalized_cda.
+		 */
+		card->write.ccws[cnt].cda =
+			(__u32) __pa(card->write.iob[cnt].data);
 	}
+	/* Last ccw is a tic (transfer in channel). */
+	card->write.ccws[LCS_NUM_BUFFS].cmd_code = LCS_CCW_TRANSFER;
+	card->write.ccws[LCS_NUM_BUFFS].cda =
+		(__u32) __pa(card->write.ccws);
+	/* Set initial state of the write channel. */
+	card->read.state = CH_STATE_INIT;
+
+	card->write.io_idx = 0;
+	card->write.buf_idx = 0;
 }
 
-static void
-lcs_chan_unlock_func(lcs_chan_globals * chan_globals)
+static int
+lcs_setup_write(struct lcs_card *card)
 {
-	if (chan_globals->lock_cnt <= 0) {
-		lcs_bad_news
-		    ("bad lock_cnt %d in lcs_chan_unlock chan_globals=%p"
-		     " devno=%04x returnaddrs=%p,%p cpu=%d\n",
-		     chan_globals->lock_cnt, chan_globals,
-		     (int) chan_globals->devno, __builtin_return_address(0),
-		     __builtin_return_address(1), smp_processor_id());
-		chan_globals->lock_cnt = 1;
-	}
+	int rc;
 
-	if (--chan_globals->lock_cnt == 0) {
-		chan_globals->lock_owner = LCS_INVALID_LOCK_OWNER;
-		s390irq_spin_unlock_irqrestore(chan_globals->subchannel,
-					       chan_globals->flags);
+	LCS_DBF_TEXT(3, setup, "writeirq");
+	/* Allocate io buffers for the write channel. */
+	rc = lcs_alloc_channel(&card->write);
+	if (rc) {
+		LCS_DBF_TEXT(3, setup, "iccwerr");
+		return rc;
 	}
-
-}
-
-#define lcs_chan_lock(chan_globals) \
-	lcs_chan_lock_func((lcs_chan_globals *)chan_globals)
-#define lcs_chan_unlock(chan_globals) \
-	lcs_chan_unlock_func((lcs_chan_globals *)chan_globals)
-
-static int inline
-lcs_getbuffs_filled(lcs_write_globals * write)
-{
-	return ((write->prepare_idx - write->tx_idx) +
-		(write->prepare_idx >
-		 write->tx_idx ? -1 : (LCS_NUM_TX_BUFFS - 1))
-		+ (write->ccw[write->prepare_idx].count ? 1 : 0));
+	lcs_setup_write_ccws(card);
+	/* Initialize write channel tasklet. */
+	card->write.irq_tasklet.data = (unsigned long) &card->write;
+	card->write.irq_tasklet.func = lcs_tasklet;
+	/* Initialize waitqueue. */
+	init_waitqueue_head(&card->write.wait_q);
+	return 0;
 }
 
 /*
- * A little utility routine to make a ccw chain.
+ * Cleanup channel.
  */
 static void
-initccws(ccw1_t * ccws, u8 * iobuff[], int num_ccws, u8 cmd_code, u16 count,
-	 u8 flags)
+lcs_cleanup_channel(struct lcs_channel *channel)
 {
-	int cnt;
-	ccw1_t *origccws = ccws;
-	memset(ccws, 0, sizeof (ccw1_t) * num_ccws + 1);
-	for (cnt = 0; cnt < num_ccws; cnt++, ccws++) {
-		ccws->cmd_code = cmd_code;
-		ccws->count = count;
-		ccws->flags = flags;
-		/* ccw addresses are 32 bit */
-		(u32) ccws->cda = (u32) virt_to_phys(iobuff[cnt]);
-	}
-	ccws->cmd_code = ccw_transfer_in_channel1;
-	(u32) ccws->cda = (u32) virt_to_phys(origccws);
+	LCS_DBF_TEXT(3, setup, "cleanch");
+	/* Kill write channel tasklets. */
+	tasklet_kill(&channel->irq_tasklet);
+	/* Free channel buffers. */
+	lcs_free_channel(channel);
 }
 
-/*
- * linked list used to hold all the lcs_drvr_globals so they can be
- * freed up when the driver is finished 
- */
-static spinlock_t lcs_card_list_lock = SPIN_LOCK_UNLOCKED;
-static lcs_drvr_globals *lcs_card_list = NULL;
-
-/*
-  This function is required for kernel threads & timers
-  going off after the driver is closed & long gone & causing mischef.
-  ( thanks Ingo for making me aware that this was happening :-) )
+/**
+ * Initialize channels,card and state machines.
  */
 static int
-lcs_drvr_globals_valid(lcs_drvr_globals * drvr_globals)
+lcs_setup_card(struct lcs_card *card)
 {
-	int in_list = FALSE;
+	int rc;
 
-	if (drvr_globals) {
-		spin_lock(&lcs_card_list_lock);
-		in_list =
-		    is_in_list((list *) lcs_card_list, (list *) drvr_globals);
-		if (in_list)
-			atomic_inc(&drvr_globals->usage_cnt);
-		spin_unlock(&lcs_card_list_lock);
-	}
-	return (in_list);
-}
+	LCS_DBF_TEXT(3, setup, "initcard");
 
-static void *
-lcs_dma_alloc(size_t allocsize)
-{
-	void *newalloc = kmalloc(allocsize, GFP_KERNEL | GFP_DMA);
-	if (newalloc)
-		memset(newalloc, 0, allocsize);
-	return (newalloc);
+	rc = lcs_setup_read(card);
+	if (rc) {
+		PRINT_ERR("Could not initialize read channel\n");
+		return rc;
+	}
+	rc = lcs_setup_write(card);
+	if (rc) {
+		PRINT_ERR("Could not initialize write channel\n");
+		lcs_cleanup_channel(&card->read);
+		return rc;
+	}
+	/* Set cards initial state. */
+	card->state = DEV_STATE_DOWN;
+	card->tx_buffer = NULL;
+	card->tx_emitted = 0;
+
+	/* Initialize kernel thread task used for LGW commands. */
+	INIT_WORK(&card->kernel_thread_starter,
+		  (void *)lcs_start_kernel_thread,card);
+	card->thread_mask = 0;
+	spin_lock_init(&card->lock);
+	INIT_LIST_HEAD(&card->ipm_list);
+	INIT_LIST_HEAD(&card->lancmd_waiters);
+	return 0;
 }
 
+/**
+ * Cleanup channels,card and state machines.
+ */
 static void
-lcs_usage_free_drvr_globals(lcs_drvr_globals * drvr_globals)
+lcs_cleanup_card(struct lcs_card *card)
 {
-#if LCS_ZERO_COPY_READ
-	struct sk_buff **skb_buff;
-#endif
-	u8 **iobuff;
-	int cnt, refcnt;
+	struct list_head *l, *n;
+	struct lcs_ipm_list *ipm_list;
 
-	lcs_debug_event(2, "lcs_usage_free_drvr_globals_called %p\n",
-			drvr_globals);
-	if (drvr_globals) {
-		lcs_read_globals *read = drvr_globals->read;
-		refcnt = atomic_dec_return(&drvr_globals->usage_cnt);
-		if (refcnt < 0)
-			lcs_bad_news("bad ref cnt drvr_globals %p ref %d\n",
-				     drvr_globals, refcnt);
-		if (refcnt <= 0) {
-			spin_lock(&lcs_card_list_lock);
-			if (!remove_from_list
-			    ((list **) & lcs_card_list, (list *) drvr_globals))
-				lcs_bad_news("drvr globals not in list %p\n",
-					     drvr_globals);
-			spin_unlock(&lcs_card_list_lock);
-			lcs_debug_event(2, "freeing drvr globals\n");
-			iobuff = drvr_globals->write->iobuff;
-			for (cnt = 0; cnt < LCS_NUM_TX_BUFFS; cnt++) {
-				if (iobuff[cnt])
-					kfree(iobuff[cnt]);
-			}
-#if LCS_ZERO_COPY_READ
-			skb_buff = read->skb_buff;
-			for (cnt = 0; cnt < LCS_NUM_RX_BUFFS; cnt++) {
-				clear_normalized_cda(&read->ccw[cnt]);
-				if (skb_buff[cnt])
-					dev_kfree_skb(skb_buff[cnt]);
-			}
-#else
-			iobuff = read->iobuff;
-			for (cnt = 0; cnt < LCS_NUM_RX_BUFFS; cnt++) {
-				clear_normalized_cda(&read->ccw[cnt]);
-				if (iobuff[cnt])
-					kfree(iobuff[cnt]);
-			}
-#endif
-			if (drvr_globals->dev)
-				drvr_globals->dev->priv = NULL;
-#ifdef  CONFIG_IP_MULTICAST
-			while (drvr_globals->ipm_list) {
-				spin_lock(&drvr_globals->ipm_lock);
-				remove_from_list((list **) & drvr_globals->
-						 ipm_list,
-						 (list *) drvr_globals->
-						 ipm_list);
-				spin_unlock(&drvr_globals->ipm_lock);
-				kfree(drvr_globals->ipm_list);
-			}
-#endif
-			memset(drvr_globals, 0, LCS_ALLOCSIZE);
-			kfree(drvr_globals);
-		}
+	LCS_DBF_TEXT(3, setup, "cleancrd");
+#ifdef	CONFIG_IP_MULTICAST
+	/* Free multicast list. */
+	list_for_each_safe(l, n, &card->ipm_list) {
+		ipm_list = list_entry(l, struct lcs_ipm_list, list);
+		list_del(&ipm_list->list);
+		kfree(ipm_list);
 	}
+#endif
+	/* Cleanup channels. */
+	lcs_cleanup_channel(&card->write);
+	lcs_cleanup_channel(&card->read);
 }
 
-static void
-lcs_kernel_thread(lcs_drvr_globals * drvr_globals)
+/**
+ * Start channel.
+ */
+static int
+lcs_start_channel(struct lcs_channel *channel)
 {
-#if LINUX_VERSION_CODE<=KERNEL_VERSION(2,2,16)
-	/* tq_scheduler sometimes leaves interrupts disabled from do
-	 * bottom half */
-	local_irq_enable();
-#endif
-	if (kernel_thread((int (*)(void *)) drvr_globals->kernel_thread_routine,
-			  (void *) drvr_globals, SIGCHLD) < 0) {
-		atomic_set(&drvr_globals->kernel_thread_lock, 1);
-		lcs_debug_exception(1,
-				    "lcs_kernel_thread failed to launch a new "
-				    "thread drvr_globals=%p routine=%p",
-				    drvr_globals,
-				    drvr_globals->kernel_thread_routine);
+	char dbf_text[15];
+	unsigned long flags;
+	int rc;
+
+	sprintf(dbf_text,"ssch%s", channel->ccwdev->dev.bus_id);
+	LCS_DBF_TEXT(4, trace, dbf_text);
+	spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
+	rc = ccw_device_start(channel->ccwdev,
+			      channel->ccws + channel->io_idx, 0, 0,
+			      DOIO_DENY_PREFETCH | DOIO_ALLOW_SUSPEND);
+	if (rc == 0)
+		channel->state = CH_STATE_RUNNING;
+	spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
+	if (rc) {
+		sprintf(dbf_text,"essc%s", channel->ccwdev->dev.bus_id);
+		LCS_DBF_TEXT(4, trace, dbf_text);
+		PRINT_ERR("Error in starting channel, rc=%d!\n", rc);
 	}
+	return rc;
 }
 
+/**
+ * Stop channel.
+ */
 static int
-lcs_initreadccws(lcs_read_globals * read)
+lcs_stop_channel(struct lcs_channel *channel)
 {
+	char dbf_text[15];
+	unsigned long flags;
+	int rc;
 
-	int cnt;
-	ccw1_t *origccws, *ccws;
-#if LCS_ZERO_COPY_READ
-	struct sk_buff *curr_skb;
-#else
-	u8 *curr_iobuff;
-#endif
-
-	origccws = ccws = read->ccw;
-	memset(ccws, 0, sizeof (ccw1_t) * LCS_NUM_RX_BUFFS + 1);
-	for (cnt = 0; cnt < LCS_NUM_RX_BUFFS; cnt++, ccws++) {
-		ccws->cmd_code = ccw_read;
-#if LCS_ZERO_COPY_READ
-		curr_skb = read->skb_buff[cnt];
-		if (set_normalized_cda(ccws, curr_skb->data))
-			return -ENOMEM
-#else
-		curr_iobuff = read->iobuff[cnt];
-		if (set_normalized_cda(ccws, curr_iobuff))
-			return -ENOMEM;
-#endif
+	if (channel->state == CH_STATE_STOPPED)
+		return 0;
+	sprintf(dbf_text,"hsch%s", channel->ccwdev->dev.bus_id);
+	LCS_DBF_TEXT(4, trace, dbf_text);
+	spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
+	rc = ccw_device_halt(channel->ccwdev, (addr_t) channel);
+	spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
+	if (rc) {
+		sprintf(dbf_text,"ehsc%s", channel->ccwdev->dev.bus_id);
+		LCS_DBF_TEXT(4, trace, dbf_text);
+		return rc;
 	}
-	ccws->cmd_code = ccw_transfer_in_channel1;
-	(u32) ccws->cda = (u32) virt_to_phys(origccws);
+	/* Asynchronous halt initialted. Wait for its completion. */
+	wait_event(channel->wait_q, (channel->state == CH_STATE_HALTED));
 	return 0;
+}
 
+/**
+ * start read and write channel
+ */
+static int
+lcs_start_channels(struct lcs_card *card)
+{
+	int rc;
+
+	LCS_DBF_TEXT(2, trace, "chstart");
+	/* start read channel */
+	rc = lcs_start_channel(&card->read);
+	if (rc)
+		return rc;
+	/* start write channel */
+	rc = lcs_start_channel(&card->write);
+	if (rc)
+		lcs_stop_channel(&card->read);
+	return rc;
 }
 
-/* 
- * Allocates driver instance globals 
+/**
+ * stop read and write channel
  */
-static lcs_drvr_globals *
-lcs_alloc_drvr_globals(void)
+static int
+lcs_stop_channels(struct lcs_card *card)
 {
-	lcs_drvr_globals *drvr_globals;
-	lcs_write_globals *write;
-	lcs_read_globals *read;
-	int cnt;
-#if LINUX_VERSION_CODE<KERNEL_VERSION(2,5,41)
-	struct tq_struct *lcs_tq;
-#endif
+	LCS_DBF_TEXT(2, trace, "chhalt");
+	lcs_stop_channel(&card->read);
+	lcs_stop_channel(&card->write);
+	return 0;
+}
 
-	lcs_debug_event(2, "lcs_alloc_drvr_globals called\n");
-	drvr_globals = lcs_dma_alloc(LCS_ALLOCSIZE);
-	if (!drvr_globals)
-		return (NULL);
-	atomic_set(&drvr_globals->usage_cnt, 1);
-	drvr_globals->rel_adapter_no = lcs_invalid_adapter_no;
-	read = drvr_globals->read = (lcs_read_globals *) (drvr_globals + 1);
-	write = drvr_globals->write =
-	    (lcs_write_globals *) ((addr_t) read + sizeof (lcs_read_globals));
-	write->lock_owner = drvr_globals->read->lock_owner =
-	    LCS_INVALID_LOCK_OWNER;
-	for (cnt = 0; cnt < LCS_NUM_TX_BUFFS; cnt++) {
-		if ((write->iobuff[cnt] =
-		     lcs_dma_alloc(LCS_IOBUFFSIZE)) == NULL)
-			goto Fail;
+/**
+ * Get empty buffer.
+ */
+static struct lcs_buffer *
+__lcs_get_buffer(struct lcs_channel *channel)
+{
+	int index;
 
-	}
-	for (cnt = 0; cnt < LCS_NUM_RX_BUFFS; cnt++) {
-#if LCS_ZERO_COPY_READ
-		if ((read->skb_buff[cnt] =
-		     lcs_dev_alloc_skb(LCS_READ_ALLOCSIZE)) == NULL)
-#else
-		if ((read->iobuff[cnt] =
-		     kmalloc(LCS_READ_ALLOCSIZE, GFP_ATOMIC | GFP_DMA)) == NULL)
-#endif
-			goto Fail;
-	}
-	if (lcs_initreadccws(read))
-		goto Fail;
-	read->drvr_globals = drvr_globals;
-	write->drvr_globals = drvr_globals;
-	lcs_resetstate(drvr_globals);
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,5,41)
-	INIT_WORK(&drvr_globals->kernel_thread_task, lcs_kernel_thread,
-		  (unsigned long) drvr_globals);
-	INIT_WORK(&read->retry_task, lcs_queued_restartreadio, 
-		  (unsigned long) drvr_globals);
-	INIT_WORK(&write->retry_task, lcs_queued_restartwriteio,
-		  (unsigned long) drvr_globals);
-	INIT_WORK(&resume_task, lcs_resume_writetask, (unsigned long) write);
-#else
-	lcs_tq = &drvr_globals->kernel_thread_task;
-	lcs_tq->routine = (void (*)(void *)) lcs_kernel_thread;
-	lcs_tq->data = (void *) drvr_globals;
-#if LINUX_VERSION_CODE>KERNEL_VERSION(2,3,0)
-	lcs_tq->sync = read->retry_task.sync = write->retry_task.sync = 0;
-#endif
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-	INIT_LIST_HEAD(&lcs_tq->list);
-	INIT_LIST_HEAD(&read->retry_task.list);
-	INIT_LIST_HEAD(&write->retry_task.list);
-#endif
-	read->retry_task.routine = (void (*)(void *)) lcs_queued_restartreadio;
-	write->retry_task.routine =
-	    (void (*)(void *)) lcs_queued_restartwriteio;
-	write->retry_task.data = read->retry_task.data = (void *) drvr_globals;
-	write->resume_task.routine = (void (*)(void *)) lcs_resume_writetask;
-	write->resume_task.data = (void *) write;
-#endif
-	read->chan_busy_state = write->chan_busy_state = chan_dead;
-	atomic_set(&drvr_globals->kernel_thread_lock, 1);
-	spin_lock(&lcs_card_list_lock);
-	add_to_list((list **) & lcs_card_list, (list *) drvr_globals);
-	spin_unlock(&lcs_card_list_lock);
-	drvr_globals->up = FALSE;
-	return (drvr_globals);
-Fail:
-	lcs_usage_free_drvr_globals(drvr_globals);
-	return (NULL);
+	index = channel->io_idx;
+	do {
+		if (channel->iob[index].state == BUF_STATE_EMPTY) {
+			channel->iob[index].state = BUF_STATE_LOCKED;
+			return channel->iob + index;
+		}
+		index = (index + 1) & (LCS_NUM_BUFFS - 1);
+	} while (index != channel->io_idx);
+	return NULL;
 }
 
-static void
-lcs_retry(lcs_chan_globals * chan_globals)
+static struct lcs_buffer *
+lcs_get_buffer(struct lcs_channel *channel)
 {
-	lcs_debug_event(1, "lcs_retry subchannel %04x scheduling retry\n",
-			chan_globals->subchannel);
-	MOD_INC_USE_COUNT;
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,5,41)
-	schedule_work(&chan_globals->retry_task);
-#else
-#if LINUX_VERSION_CODE>KERNEL_VERSION(2,2,16)
-	schedule_task(&chan_globals->retry_task);
-#else
-	queue_task(&chan_globals->retry_task, &tq_scheduler);
-#endif
-#endif
+	struct lcs_buffer *buffer;
+	unsigned long flags;
+
+	spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
+	buffer = __lcs_get_buffer(channel);
+	spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
+	return buffer;
 }
 
+/**
+ * Resume channel program if the channel is suspended.
+ */
 static int
-lcs_doio_func(lcs_chan_globals * chan_globals, unsigned long flags)
+__lcs_resume_channel(struct lcs_channel *channel)
 {
+	char dbf_text[15];
 	int rc;
-	lcs_debug_event(2, "lcs_doio subchannel=%x\n",
-			(int) chan_globals->subchannel);
-	lcs_chan_lock(chan_globals);
-
-	rc = do_IO(chan_globals->subchannel, &chan_globals->ccw[0],
-		   (addr_t) chan_globals, 0, flags);
 
+	if (channel->state != CH_STATE_SUSPENDED)
+		return 0;
+	if (channel->ccws[channel->io_idx].flags & CCW_FLAG_SUSPEND)
+		return 0;
+	sprintf(dbf_text,"rsch%s", channel->ccwdev->dev.bus_id);
+	LCS_DBF_TEXT(4, trace, dbf_text);
+	rc = ccw_device_resume(channel->ccwdev);
 	if (rc) {
-#if LCS_DEBUG
-		lcs_debug_event(1,"lcs_doio do_IO returned %d for " \
-				"subchannel %X\n",rc,chan_globals->subchannel);
-#endif
-		if (rc == -ENODEV)
-			chan_globals->chan_busy_state = chan_dead;
-		else
-			lcs_retry(chan_globals);
+		sprintf(dbf_text,"ersc%s", channel->ccwdev->dev.bus_id);
+		LCS_DBF_TEXT(4, trace, dbf_text);
+		PRINT_ERR("Error in lcs_resume_channel: rc=%d\n",rc);
 	} else
-		chan_globals->chan_busy_state = chan_started_successfully;
-	lcs_chan_unlock(chan_globals);
-	return (rc);
-}
+		channel->state = CH_STATE_RUNNING;
+	return rc;
 
-#define lcs_doio(chan_globals,flags)  \
-	lcs_doio_func((lcs_chan_globals *)(chan_globals),(flags))
+}
 
-/* 
- * halt subchannel wrapper used during driver startup 
+/**
+ * Make a buffer ready for processing.
  */
-static int
-lcs_hsch_func(lcs_chan_globals * chan_globals)
+static inline void
+__lcs_ready_buffer_bits(struct lcs_channel *channel, int index)
 {
-	int rc = 0;
-	lcs_debug_event(2, "lcs_hsch subchannel=%x\n",
-			(int) chan_globals->subchannel);
-	lcs_chan_lock(chan_globals);
-	lcs_initqueue(chan_globals);
-	chan_globals->drvr_globals->state = lcs_halting_subchannels;
-	rc = halt_IO(chan_globals->subchannel, (addr_t) chan_globals, 0);
-	lcs_chan_unlock(chan_globals);
-	if (rc == 0)
-		rc = lcs_sleepon_func(chan_globals, 0);
-	else
-		lcs_debug_event(2, "lcs_hsch subchannel=%x rc=%d\n",
-				(int) chan_globals->subchannel, rc);
-	return (rc);
+	int prev, next;
+
+	prev = (index - 1) & (LCS_NUM_BUFFS - 1);
+	next = (index + 1) & (LCS_NUM_BUFFS - 1);
+	/* Check if we may clear the suspend bit of this buffer. */
+	if (channel->ccws[next].flags & CCW_FLAG_SUSPEND) {
+		/* Check if we have to set the PCI bit. */
+		if (!(channel->ccws[prev].flags & CCW_FLAG_SUSPEND))
+			/* Suspend bit of the previous buffer is not set. */
+			channel->ccws[index].flags |= CCW_FLAG_PCI;
+		/* Suspend bit of the next buffer is set. */
+		channel->ccws[index].flags &= ~CCW_FLAG_SUSPEND;
+	}
 }
 
-#define lcs_hsch(chan_globals) \
-	lcs_hsch_func((lcs_chan_globals *)(chan_globals))
+static int
+lcs_ready_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer)
+{
+	unsigned long flags;
+	int index, rc;
+
+	if (buffer->state != BUF_STATE_LOCKED &&
+	    buffer->state != BUF_STATE_PROCESSED)
+		BUG();
+	spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
+	buffer->state = BUF_STATE_READY;
+	index = buffer - channel->iob;
+	/* Set length. */
+	channel->ccws[index].count = buffer->count;
+	/* Check relevant PCI/suspend bits. */
+	__lcs_ready_buffer_bits(channel, index);
+	rc = __lcs_resume_channel(channel);
+	spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
+	return rc;
+}
 
+/**
+ * Mark the buffer as processed. Take care of the suspend bit
+ * of the previous buffer. This function is called from
+ * interrupt context, so the lock must not be taken.
+ */
+static int
+__lcs_processed_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer)
+{
+	int index, prevprev, prev, next;
+
+	if (buffer->state != BUF_STATE_READY)
+		BUG();
+	buffer->state = BUF_STATE_PROCESSED;
+	index = buffer - channel->iob;
+	prevprev = (index - 1) & (LCS_NUM_BUFFS - 1);
+	prev = (index - 1) & (LCS_NUM_BUFFS - 1);
+	next = (index + 1) & (LCS_NUM_BUFFS - 1);
+	/* Set the suspend bit and clear the PCI bit of this buffer. */
+	channel->ccws[index].flags |= CCW_FLAG_SUSPEND;
+	channel->ccws[index].flags &= ~CCW_FLAG_PCI;
+	/* Check the suspend bit of the previous buffer. */
+	if (channel->iob[prev].state == BUF_STATE_READY) {
+		/*
+		 * Previous buffer is in state ready. It might have
+		 * happened in lcs_ready_buffer that the suspend bit
+		 * has not been cleared to avoid an endless loop.
+		 * Do it now.
+		 */
+		__lcs_ready_buffer_bits(channel, prev);
+	}
+	/* Clear PCI bit of next buffer. */
+	channel->ccws[next].flags &= ~CCW_FLAG_PCI;
+	return __lcs_resume_channel(channel);
+}
+
+/**
+ * Put a processed buffer back to state empty.
+ */
 static void
-wait_on_write(lcs_drvr_globals * drvr_globals)
+lcs_release_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer)
 {
-	lcs_write_globals *write = drvr_globals->write;
+	unsigned long flags;
 
-	if (drvr_globals->state == lcs_doing_io) {
-		if (drvr_globals->dev)
-			netif_stop_queue(drvr_globals->dev);
-		lcs_chan_lock(write);
-		if (drvr_globals->state == lcs_doing_io &&
-		    (write->chan_busy_state == chan_busy
-		     || write->resume_queued)) {
-			lcs_initqueue(write);
-			drvr_globals->state =
-			    lcs_requesting_channels_for_lancmds;
-			lcs_chan_unlock(write);
-			lcs_sleepon(write, 0);
-		} else
-			lcs_chan_unlock(write);
-	}
-	drvr_globals->state = lcs_doing_lancmds;
+	if (buffer->state != BUF_STATE_LOCKED &&
+	    buffer->state != BUF_STATE_PROCESSED)
+		BUG();
+	spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
+	buffer->state = BUF_STATE_EMPTY;
+	spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
 }
 
-static int
-lcs_getcmdsize(u8 cmd_code)
+/**
+ * Get buffer for a lan command.
+ */
+static struct lcs_buffer *
+lcs_get_lancmd(struct lcs_card *card, int count)
 {
-	int cmdsize;
-	switch (cmd_code) {
-	case lcs_startlan:
-	case lcs_stoplan:
-	case lcs_lanstat:
-	case lcs_shutdown:
-		cmdsize = sizeof (lcs_std_cmd);
-		break;
-	case lcs_startup:
-		cmdsize = sizeof (lcs_startup_cmd);
-		break;
-#ifdef CONFIG_IP_MULTICAST
-	case lcs_setipm:
-	case lcs_delipm:
-		cmdsize = sizeof (lcs_ipm_ctlmsg);
-		break;
-	case lcs_qipassist:
-		cmdsize = sizeof (lcs_qipassist_ctlmsg);
-		break;
-#endif
-	default:
-		lcs_debug_event(1, "illegal lan cmd %d in lcs_getcmdsize\n",
-				cmd_code);
-		cmdsize = -EINVAL;
-	}
-	if (cmdsize != -EINVAL)
-		cmdsize -= sizeof (lcs_header_type);
-	return (cmdsize);
-}
-
-static lcs_header_type *
-lcs_getfreetxbuff(lcs_write_globals * write, u8 type, u8 slot, int len)
-{
-	ccw1_t *curr_ccw;
-	int new_buff = FALSE;
-	lcs_header_type *retbuff;
-	u32 virt_cda;
-
-	curr_ccw = &write->ccw[write->prepare_idx];
-	if (curr_ccw->count == 0)
-		new_buff = TRUE;
-	else if ((curr_ccw->count + len + sizeof (lcs_header_type) +
-		  sizeof (u16)) > LCS_IOBUFFSIZE) {
-
-		if (write->prepare_idx == write->tx_idx)
-			return (NULL);
-		write->prepare_idx =
-		    ((write->prepare_idx + 1) & (LCS_NUM_TX_BUFFS - 1));
-		curr_ccw->flags &= ~CCW_FLAG_SUSPEND;
-		new_buff = TRUE;
-		curr_ccw = &write->ccw[write->prepare_idx];
-	}
-	if (new_buff) {
-		if ((curr_ccw->flags & CCW_FLAG_SUSPEND) == 0) {
-			lcs_bad_news
-			    ("Bug/Race condition detected in "
-			     "lcs_getfreetxbuff "
-			     "CCW_FLAG_SUSPEND not set for\n"
-			     "for ccw at %p", curr_ccw);
-			return (NULL);
-		}
-		if (curr_ccw->count != 0) {
-			lcs_bad_news
-			    ("Bug/Race condition detected in "
-			     "lcs_getfreetxbuff "
-			     "count!=0 in new buffer\n"
-			     "for ccw at %p", curr_ccw);
-			return (NULL);
-		}
-	}
-	len += sizeof (lcs_header_type);
-	virt_cda = (u32) virt_to_phys((void *) ((addr_t) curr_ccw->cda));
-	if (new_buff) {
-		retbuff = (lcs_header_type *) ((addr_t) virt_cda);
-		curr_ccw->count = len + sizeof (u16);
-	} else {
-		retbuff =
-		    (lcs_header_type *) (virt_cda + curr_ccw->count -
-					 sizeof (u16));
-		curr_ccw->count += len;
-		len = curr_ccw->count - sizeof (u16);
-	}
-	retbuff->offset = len;
-	*((u16 *) ((addr_t) (virt_cda + len))) = 0;
-	retbuff->type = type;
-	retbuff->slot = slot;
-	lcs_debug_event(2,
-			"lcs_getfreetxbuff write=%p prepare_idx=%u "
-			"tx_idx=%u len=%d\n",
-			write, write->prepare_idx, write->tx_idx, len);
-	return (retbuff);
-}
-
-static lcs_std_cmd *
-lcs_prepare_lancmd(lcs_write_globals * write, u8 cmd_code, u8 rel_adapter_no,
-		   u8 initiator, u8 lan_type)
-{
-	lcs_std_cmd *writecmd;
-	int cmdsize = lcs_getcmdsize(cmd_code);
-	if (cmdsize < 0)
-		return (NULL);
-	/* Force a fresh ccw buff */
-	writecmd =
-	    (lcs_std_cmd *) lcs_getfreetxbuff(write, lcs_control_frame_type, 0,
-					      cmdsize);
-	if (writecmd == NULL)
-		return (NULL);
-	memset((void *) (((addr_t) writecmd) + sizeof (lcs_header_type)), 0,
-	       cmdsize);
-	writecmd->cmd_code = cmd_code;
-	writecmd->initiator = initiator;
-	switch (cmd_code) {
-	case lcs_startlan:
-	case lcs_stoplan:
-	case lcs_lanstat:
-#ifdef CONFIG_IP_MULTICAST
-	case lcs_setipm:
-	case lcs_delipm:
-	case lcs_qipassist:
-#endif
-		writecmd->lan_type = lan_type;
-		writecmd->rel_adapter_no = rel_adapter_no;
-		break;
-	case lcs_startup:
-		((lcs_startup_cmd *) writecmd)->buff_size = LCS_IOBUFFSIZE;
-		break;
-	case lcs_shutdown:
-		break;
-	default:
-		break;
-	}
-	return (writecmd);
-}
+	struct lcs_buffer *buffer;
+	struct lcs_cmd *cmd;
 
-#if LCS_DEBUG_RESUME
-int lcs_read_resume_cnt, lcs_write_resume_cnt;
-#endif
+	/* Get buffer and wait if none is available. */
+	wait_event(card->write.wait_q,
+		   ((buffer = lcs_get_buffer(&card->write)) != NULL));
+	count += sizeof(struct lcs_header);
+	*(__u16 *)(buffer->data + count) = 0;
+	buffer->count = count + sizeof(__u16);
+	buffer->callback = lcs_release_buffer;
+	cmd = (struct lcs_cmd *) buffer->data;
+	cmd->offset = count;
+	cmd->type = LCS_FRAME_TYPE_CONTROL;
+	cmd->slot = 0;
+	return buffer;
+}
 
+/**
+ * Notifier function for lancmd replies. Called from read irq.
+ */
 static void
-lcs_interrupt_resume_read(lcs_read_globals * read)
+lcs_notify_lancmd_waiters(struct lcs_card *card, struct lcs_cmd *cmd)
 {
-	int rc;
-	ccw1_t *curr_ccw;
+	struct list_head *l, *n;
+	struct lcs_reply *reply;
 
-	lcs_debug_event(2, "lcs_interrupt_resume_read entered\n");
-	if ((read->ccw[(read->rx_idx - 1) & (LCS_NUM_RX_BUFFS - 1)].
-	     flags & CCW_FLAG_SUSPEND) == 0)
-		lcs_bad_news
-		    ("lcs_interrupt_resume_read detected possible lack of "
-		     "suspend bug\n");
-	curr_ccw = &read->ccw[read->rx_idx];
-	curr_ccw->flags = CCW_FLAG_CC | CCW_FLAG_SLI | CCW_FLAG_PCI
-#if LCS_USE_IDALS
-	    | (curr_ccw->flags & CCW_FLAG_IDA)
-#endif
-	    ;
-	if ((rc = resume_IO(read->subchannel)) == 0) {
-#if LCS_DEBUG_RESUME
-		lcs_read_resume_cnt++;
-#endif
-		read->chan_busy_state = chan_busy;
-	} else
-		lcs_bad_news
-		    ("lcs_interrupt_resume_read returned %d for "
-		     "subchannel %X\n",
-		     rc, read->subchannel);
+	spin_lock(&card->lock);
+	list_for_each_safe(l, n, &card->lancmd_waiters) {
+		reply = list_entry(l, struct lcs_reply, list);
+		if (reply->sequence_no == cmd->sequence_no) {
+			list_del(&reply->list);
+			if (reply->callback != NULL)
+				reply->callback(card, cmd);
+			reply->received = 1;
+			reply->rc = cmd->return_code;
+			wake_up(&reply->wait_q);
+			break;
+		}
+	}
+	spin_unlock(&card->lock);
 }
 
-static void
-lcs_resume_read(lcs_read_globals * read)
+/**
+ * Emit buffer of a lan comand.
+ */
+void
+lcs_lancmd_timeout(unsigned long data)
 {
-	lcs_debug_event(2, "lcs_resume_read entered\n");
-	lcs_chan_lock(read);
-	if (read->chan_busy_state == chan_idle)
-		lcs_interrupt_resume_read(read);
-	read->lancmd_reply_ptr = NULL;
-	lcs_chan_unlock(read);
+	struct lcs_reply *reply;
+
+	reply = (struct lcs_reply *) data;
+	list_del(&reply->list);
+	reply->received = 1;
+	reply->rc = -ETIME;
+	wake_up(&reply->wait_q);
 }
 
 static int
-lcs_resume_write(lcs_write_globals * write)
+lcs_send_lancmd(struct lcs_card *card, struct lcs_buffer *buffer,
+		void (*reply_callback)(struct lcs_card *, struct lcs_cmd *))
 {
-	int rc = 0;
-
-	lcs_debug_event(2, "lcs_resume_write entered write=%p\n", write);
-	lcs_chan_lock(write);
-	if (write->chan_busy_state == chan_idle && lcs_getbuffs_filled(write)) {
-		write->ccw[write->prepare_idx].flags &= ~CCW_FLAG_SUSPEND;
-		write->prepare_idx =
-		    ((write->prepare_idx + 1) & (LCS_NUM_TX_BUFFS - 1));
-		if ((rc = resume_IO(write->subchannel)) == 0) {
-			lcs_debug_event(2,"lcs_resume_write resume_IO "
-					"successful prepare_idx=%u "
-					"tx_idx=%u\n",
-					write->prepare_idx, write->tx_idx);
-#if LCS_DEBUG_RESUME
-			lcs_write_resume_cnt++;
-#endif
-			write->chan_busy_state = chan_busy;
-			/* the << TOD_SHIFT_TO_USECS is to adjust 
-			   the inequality to microseconds 
-			   for the tod in lcs_tx_is_busy
-			   The extra is adjustment is
-			   so that the tx_is_busy will weigh 
-			   in favour of large transmission buffers.
-			 */
-
-			write->adjusted_last_bytes_still_being_txed =
-			    (uint64_t) ((write->bytes_still_being_txed +
-					 500) << TOD_SHIFT_TO_USECS);
-			write->last_resume_time = lcs_get_tod();
-		} else
-			lcs_bad_news
-			    ("lcs_resume_write returned %d for "
-			     "subchannel %X\n",rc,write->subchannel);
+	struct lcs_reply reply;
+	struct lcs_cmd *cmd;
+	struct timer_list timer;
+	int rc;
 
-	}
-	lcs_chan_unlock(write);
-	return rc;
+	cmd = (struct lcs_cmd *) buffer->data;
+	cmd->sequence_no = ++card->sequence_no;
+	cmd->return_code = 0;
+	reply.sequence_no = cmd->sequence_no;
+	reply.callback = reply_callback;
+	reply.received = 0;
+	reply.rc = 0;
+	init_waitqueue_head(&reply.wait_q);
+	spin_lock(&card->lock);
+	list_add_tail(&reply.list, &card->lancmd_waiters);
+	spin_unlock(&card->lock);
+	buffer->callback = lcs_release_buffer;
+	rc = lcs_ready_buffer(&card->write, buffer);
+	if (rc)
+		return rc;
+	init_timer(&timer);
+	timer.function = lcs_lancmd_timeout;
+	timer.data = (unsigned long) &reply;
+	timer.expires = jiffies + HZ*5;
+	add_timer(&timer);
+	wait_event(reply.wait_q, reply.received);
+	del_timer(&timer);
+	return reply.rc ? -EIO : 0;
 }
 
-/*
-  Unfortunately we don't know if the lcs interface is busy
-  simply by knowing we have started a transmission & not
-  recieved a interrupt yet because the osa microcode simply
-  copies the packet into its own internal buffers.
-  I estimate whether the interface maybe busy by assuming
-  an extremely optimistic 30MB/sec transmission rate ( might
-  happen on a gigabit ethernet card ), i.e. if this routine
-  returns true the interface is almost definitely busy.
+/**
+ * LCS startup command
  */
 static int
-lcs_tx_is_busy(lcs_write_globals * write, uint64_t tod)
+lcs_send_startup(struct lcs_card *card, __u8 initiator)
 {
-	uint64_t delta_tx = tod - write->last_resume_time;
-	int rc;
+	struct lcs_buffer *buffer;
+	struct lcs_cmd *cmd;
 
-	/* 30MB/sec = 30 bytes per usec */
-	if (write->adjusted_last_bytes_still_being_txed < (30 * delta_tx))
-		rc = FALSE;
-	else
-		rc = TRUE;
-#if 0
-	lcs_debug_event(2,
-			"%s being txed %08X tod %08X last resume=%08X "
-			"delta_tx %08X\n",
-			(rc ? "lcs busy" : "lcs not busy"),
-			(unsigned) ((write->
-				     adjusted_last_bytes_still_being_txed >>
-				     TOD_SHIFT_TO_USECS)),
-			(unsigned) (tod >> TOD_SHIFT_TO_USECS),
-			(unsigned) (write->
-				    last_resume_time >> TOD_SHIFT_TO_USECS),
-			(unsigned) ((delta_tx) >> TOD_SHIFT_TO_USECS));
-#endif
-	return (rc);
+	LCS_DBF_TEXT(2, trace, "startup");
+	buffer = lcs_get_lancmd(card, LCS_STD_CMD_SIZE);
+	cmd = (struct lcs_cmd *) buffer->data;
+	cmd->cmd_code = LCS_CMD_STARTUP;
+	cmd->initiator = initiator;
+	cmd->cmd.lcs_startup.buff_size = LCS_IOBUFFERSIZE;
+	return lcs_send_lancmd(card, buffer, NULL);
 }
 
-static void
-lcs_queue_write(lcs_write_globals * write)
+/**
+ * LCS shutdown command
+ */
+static int
+lcs_send_shutdown(struct lcs_card *card)
 {
-	/* wait on write in shutdown func should avoid this 
-	 * needing mod usage counts */
-	lcs_debug_event(2, "lcs_queue_write write=%p\n", write);
-	write->resume_queued = TRUE;
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,5,41)
-	schedule_work(&write->resume_task);
-#else
-	queue_task(&write->resume_task, &tq_immediate);
-#endif
-	mark_bh(IMMEDIATE_BH);
+	struct lcs_buffer *buffer;
+	struct lcs_cmd *cmd;
+
+	LCS_DBF_TEXT(2, trace, "shutdown");
+	buffer = lcs_get_lancmd(card, LCS_STD_CMD_SIZE);
+	cmd = (struct lcs_cmd *) buffer->data;
+	cmd->cmd_code = LCS_CMD_SHUTDOWN;
+	cmd->initiator = LCS_INITIATOR_TCPIP;
+	return lcs_send_lancmd(card, buffer, NULL);
 }
 
+/**
+ * LCS lanstat command
+ */
 static void
-lcs_queue_write_if_necessary(lcs_write_globals * write)
+__lcs_lanstat_cb(struct lcs_card *card, struct lcs_cmd *cmd)
 {
-	lcs_debug_event(2, "lcs_queue_write_if_necessary write=%p\n", write);
-	if (!write->resume_queued) {
-		write->resume_loopcnt = 0;
-		lcs_queue_write(write);
-	}
+	memcpy(card->mac, cmd->cmd.lcs_lanstat_cmd.mac_addr, LCS_MAC_LENGTH);
 }
 
 static int
-lcs_should_queue_write(lcs_write_globals * write, uint64_t tod)
+lcs_send_lanstat(struct lcs_card *card)
 {
+	struct lcs_buffer *buffer;
+	struct lcs_cmd *cmd;
+
+	LCS_DBF_TEXT(2, trace, "cmdstat");
+	buffer = lcs_get_lancmd(card, LCS_STD_CMD_SIZE);
+	cmd = (struct lcs_cmd *) buffer->data;
+	/* Setup lanstat command. */
+	cmd->cmd_code = LCS_CMD_LANSTAT;
+	cmd->initiator = LCS_INITIATOR_TCPIP;
+	cmd->cmd.lcs_std_cmd.lan_type = card->lan_type;
+	cmd->cmd.lcs_std_cmd.portno = card->portno;
+	return lcs_send_lancmd(card, buffer, __lcs_lanstat_cb);
+}
 
-	if (lcs_getbuffs_filled(write) < (LCS_NUM_TX_BUFFS - 1)
-	    && (lcs_tx_is_busy(write, tod) ||
-		((tod - write->last_lcs_txpacket_time) <
-		 (25 << TOD_SHIFT_TO_USECS))))
-		return (TRUE);
-	return (FALSE);
+/**
+ * send stoplan command
+ */
+static int
+lcs_send_stoplan(struct lcs_card *card, __u8 initiator)
+{
+	struct lcs_buffer *buffer;
+	struct lcs_cmd *cmd;
 
+	LCS_DBF_TEXT(2, trace, "cmdstpln");
+	buffer = lcs_get_lancmd(card, LCS_STD_CMD_SIZE);
+	cmd = (struct lcs_cmd *) buffer->data;
+	cmd->cmd_code = LCS_CMD_STOPLAN;
+	cmd->initiator = initiator;
+	cmd->cmd.lcs_std_cmd.lan_type = card->lan_type;
+	cmd->cmd.lcs_std_cmd.portno = card->portno;
+	return lcs_send_lancmd(card, buffer, NULL);
 }
 
+/**
+ * send startlan command
+ */
 static void
-lcs_resume_writetask(lcs_write_globals * write)
+__lcs_send_startlan_cb(struct lcs_card *card, struct lcs_cmd *cmd)
 {
-	uint64_t tod;
-
-	lcs_debug_event(2, "lcs_resume_writetask write=%p\n", write);
-	lcs_chan_lock(write);
-	tod = lcs_get_tod();
-	if (write->resume_loopcnt < 20 && lcs_should_queue_write(write, tod)) {
-		write->resume_loopcnt++;
-		lcs_queue_write(write);
-		lcs_chan_unlock(write);
-		return;
-	} else {
-#if 0
-		if (write->resume_loopcnt > 10)
-			lcs_debug_event(1,"lcs_resume_writetask bad "
-					"loopcnt %d\n",write->resume_loopcnt);
-#endif
-		lcs_resume_write(write);
-	}
-	write->resume_queued = FALSE;
-	lcs_chan_unlock(write);
+	card->lan_type = cmd->cmd.lcs_std_cmd.lan_type;
+	card->portno = cmd->cmd.lcs_std_cmd.portno;
 }
 
 static int
-lcs_calcsleeptime(lcs_drvr_globals * drvr_globals, u8 cmd_code)
+lcs_send_startlan(struct lcs_card *card, __u8 initiator)
 {
-	if ((cmd_code == lcs_startlan || cmd_code == lcs_stoplan))
-		return (drvr_globals->slow_hw ? 60 : 5);
-	else
-		return (drvr_globals->slow_hw ? 5 : 5);
+	struct lcs_buffer *buffer;
+	struct lcs_cmd *cmd;
 
+	LCS_DBF_TEXT(2, trace, "cmdstpln");
+	buffer = lcs_get_lancmd(card, LCS_STD_CMD_SIZE);
+	cmd = (struct lcs_cmd *) buffer->data;
+	cmd->cmd_code = LCS_CMD_STARTLAN;
+	cmd->initiator = initiator;
+	cmd->cmd.lcs_std_cmd.lan_type = card->lan_type;
+	cmd->cmd.lcs_std_cmd.portno = card->portno;
+	return lcs_send_lancmd(card, buffer, __lcs_send_startlan_cb);
 }
 
+#ifdef CONFIG_IP_MULTICAST
+/**
+ * send setipm command (Multicast)
+ */
 static int
-lcs_resumeandwait(lcs_write_globals * write, u8 cmd_code)
+lcs_send_setipm(struct lcs_card *card,struct lcs_ipm_list *ipm_list)
 {
-	int rc;
+	struct lcs_buffer *buffer;
+	struct lcs_cmd *cmd;
 
-	lcs_initqueue(write);
-	if ((rc = lcs_resume_write(write)))
-		return (rc);
-	return (lcs_sleepon
-		(write, lcs_calcsleeptime(write->drvr_globals, cmd_code)));
+	LCS_DBF_TEXT(2, trace, "cmdsetim");
+	buffer = lcs_get_lancmd(card, LCS_MULTICAST_CMD_SIZE);
+	cmd = (struct lcs_cmd *) buffer->data;
+	cmd->cmd_code = LCS_CMD_SETIPM;
+	cmd->initiator = LCS_INITIATOR_TCPIP;
+	cmd->cmd.lcs_qipassist.lan_type = card->lan_type;
+	cmd->cmd.lcs_qipassist.portno = card->portno;
+	cmd->cmd.lcs_qipassist.version = 4;
+	cmd->cmd.lcs_qipassist.num_ip_pairs = 1;
+	memcpy(cmd->cmd.lcs_qipassist.lcs_ipass_ctlmsg.ip_mac_pair,
+	       &ipm_list->ipm, sizeof (struct lcs_ip_mac_pair));
+	return lcs_send_lancmd(card, buffer, NULL);
 }
 
+/**
+ * send delipm command (Multicast)
+ */
 static int
-lcs_lgw_common(lcs_drvr_globals * drvr_globals, u8 cmd_code)
+lcs_send_delipm(struct lcs_card *card,struct lcs_ipm_list *ipm_list)
 {
+	struct lcs_buffer *buffer;
+	struct lcs_cmd *cmd;
 
-	lcs_write_globals *write = drvr_globals->write;
-	lcs_std_cmd *writecmd;
-	wait_on_write(drvr_globals);
-	writecmd = lcs_prepare_lancmd(write, cmd_code,
-				      drvr_globals->rel_adapter_no,
-				      lcs_lgw_initiated,
-				      drvr_globals->lan_type);
-	writecmd->sequence_no = drvr_globals->lgw_sequence_no;
-	return (lcs_resumeandwait(write, cmd_code));
+	LCS_DBF_TEXT(2, trace, "cmddelim");
+	buffer = lcs_get_lancmd(card, LCS_MULTICAST_CMD_SIZE);
+	cmd = (struct lcs_cmd *) buffer->data;
+	cmd->cmd_code = LCS_CMD_DELIPM;
+	cmd->initiator = LCS_INITIATOR_TCPIP;
+	cmd->cmd.lcs_qipassist.lan_type = card->lan_type;
+	cmd->cmd.lcs_qipassist.portno = card->portno;
+	cmd->cmd.lcs_qipassist.version = 4;
+	cmd->cmd.lcs_qipassist.num_ip_pairs = 1;
+	memcpy(cmd->cmd.lcs_qipassist.lcs_ipass_ctlmsg.ip_mac_pair,
+	       &ipm_list->ipm, sizeof (struct lcs_ip_mac_pair));
+	return lcs_send_lancmd(card, buffer, NULL);
 }
 
+/**
+ * check if multicast is supported by LCS
+ */
 static void
-lcs_start_doing_io(lcs_drvr_globals * drvr_globals)
+__lcs_check_multicast_cb(struct lcs_card *card, struct lcs_cmd *cmd)
 {
-	netif_wake_queue(drvr_globals->dev);
-	drvr_globals->state = lcs_doing_io;
+	card->ip_assists_supported =
+		cmd->cmd.lcs_qipassist.ip_assists_supported;
+	card->ip_assists_enabled =
+		cmd->cmd.lcs_qipassist.ip_assists_enabled;
 }
 
 static int
-lcs_lgw_stoplan(lcs_drvr_globals * drvr_globals)
+lcs_check_multicast_support(struct lcs_card *card)
 {
-	struct net_device *dev;
+	struct lcs_buffer *buffer;
+	struct lcs_cmd *cmd;
+	int rc;
 
-	lcs_daemonize("lcs_lgw_stoplan", 0, TRUE);
-	if (!lcs_drvr_globals_valid(drvr_globals))
-		goto Done2;
-	if (drvr_globals->state != lcs_doing_io)
-		goto Done1;
-	dev = drvr_globals->dev;
-	lcs_bad_news("lcs problems detected %s temporarily unavailable.\n",
-		     dev->name);
-	lcs_lgw_common(drvr_globals, lcs_stoplan);
-	netif_stop_queue(dev);
-	drvr_globals->state = lcs_doing_io;
-Done1:
-	atomic_set(&drvr_globals->kernel_thread_lock, 1);
-	lcs_usage_free_drvr_globals(drvr_globals);
-Done2:
-	MOD_DEC_USE_COUNT;
-	return (0);
+	LCS_DBF_TEXT(2, trace, "cmdqipa");
+	/* Send query ipassist. */
+	buffer = lcs_get_lancmd(card, LCS_STD_CMD_SIZE);
+	cmd = (struct lcs_cmd *) buffer->data;
+	cmd->cmd_code = LCS_CMD_QIPASSIST;
+	cmd->initiator = LCS_INITIATOR_TCPIP;
+	cmd->cmd.lcs_qipassist.lan_type = card->lan_type;
+	cmd->cmd.lcs_qipassist.portno = card->portno;
+	cmd->cmd.lcs_qipassist.version = 4;
+	cmd->cmd.lcs_qipassist.num_ip_pairs = 1;
+	rc = lcs_send_lancmd(card, buffer, __lcs_check_multicast_cb);
+	if (rc != 0) {
+		PRINT_ERR("Query IPAssist failed. Assuming unsupported!\n");
+		return -EOPNOTSUPP;
+	}
+	/* Print out supported assists: IPv6 */
+	PRINT_INFO("LCS device %s %s IPv6 support\n", card->dev->name,
+		   (card->ip_assists_supported & LCS_IPASS_IPV6_SUPPORT) ?
+		   "with" : "without");
+	/* Print out supported assist: Multicast */
+	PRINT_INFO("LCS device %s %s Multicast support\n", card->dev->name,
+		   (card->ip_assists_supported & LCS_IPASS_MULTICAST_SUPPORT) ?
+		   "with" : "without");
+	if (card->ip_assists_supported & LCS_IPASS_MULTICAST_SUPPORT)
+		return 0;
+	return -EOPNOTSUPP;
 }
 
+/**
+ * set or del multicast address on LCS card
+ */
 static int
-lcs_lgw_startlan(lcs_drvr_globals * drvr_globals)
+lcs_fix_multicast_list(void *data)
 {
-	struct net_device *dev;
-
-	lcs_daemonize("lcs_lgw_startlan", 0, TRUE);
-	if (!lcs_drvr_globals_valid(drvr_globals))
-		goto Done2;
-	if (drvr_globals->state != lcs_doing_io)
-		goto Done1;
-	dev = drvr_globals->dev;
-	lcs_good_news("lcs device %s restarted.\n", dev->name);
-	lcs_lgw_common(drvr_globals, lcs_startlan);
-	lcs_start_doing_io(drvr_globals);
-Done1:
-	atomic_set(&drvr_globals->kernel_thread_lock, 1);
-	lcs_usage_free_drvr_globals(drvr_globals);
-Done2:
-	MOD_DEC_USE_COUNT;
-	return (0);
-}
+	struct list_head *l, *n;
+	struct lcs_ipm_list *ipm;
+	struct lcs_card *card;
 
-static int
-lcs_lgw_resetlan(lcs_drvr_globals * drvr_globals)
-{
-	struct net_device *dev;
-	int retrycnt;
+	card = (struct lcs_card *) data;
 
-	lcs_daemonize("lcs_lgw_resetlan", 0, TRUE);
-	if (!lcs_drvr_globals_valid(drvr_globals))
-		goto Done2;
-	if (drvr_globals->state != lcs_doing_io)
-		goto Done1;
-	dev = drvr_globals->dev;
-	lcs_debug_event(0, "lcs reset %s.\n", dev->name);
-	for (retrycnt = 0; retrycnt < 10; retrycnt++) {
-		if (lcs_detect(drvr_globals,drvr_globals->rel_adapter_no,0,0,
-			       drvr_globals->lan_type,dev->dev_addr) == 0) {
-			lcs_start_doing_io(drvr_globals);
-			lcs_good_news("lcs reset %s successfully.\n",
-				      dev->name);
-			goto Done1;
+	daemonize();
+	LCS_DBF_TEXT(5, trace, "fixipm");
+	spin_lock(&card->lock);
+	list_for_each_safe(l, n, &card->ipm_list) {
+		ipm = list_entry(l, struct lcs_ipm_list, list);
+		switch (ipm->ipm_state) {
+		case LCS_IPM_STATE_SET_REQUIRED:
+			if (lcs_send_setipm(card, ipm))
+				PRINT_INFO("Adding multicast address failed."
+					   "Table possibly full!\n");
+			else
+				ipm->ipm_state = LCS_IPM_STATE_ON_CARD;
+			break;
+		case LCS_IPM_STATE_DEL_REQUIRED:
+			lcs_send_delipm(card, ipm);
+			list_del(&ipm->list);
+			kfree(ipm);
+			break;
+		case LCS_IPM_STATE_ON_CARD:
+			break;
 		}
-		lcs_debug_event(0, "lcs_resetlan retrycnt %d\n", retrycnt);
-		schedule_timeout(3 * HZ);
-		atomic_set(&drvr_globals->retry_cnt, 0);
 	}
-	lcs_resetstate(drvr_globals);
-	lcs_bad_news("lcs problems occured restarting after reset %s.\n",
-		     dev->name);
-Done1:
-	atomic_set(&drvr_globals->kernel_thread_lock, 1);
-	lcs_usage_free_drvr_globals(drvr_globals);
-Done2:
-	MOD_DEC_USE_COUNT;
-	return (0);
+	if (card->state == DEV_STATE_UP)
+		netif_wake_queue(card->dev);
+	spin_unlock(&card->lock);
+	return 0;
 }
 
+/**
+ * get mac address for the relevant Multicast address
+ */
 static void
-lcs_queue_thread(int (*routine) (lcs_drvr_globals *),
-		 lcs_drvr_globals * drvr_globals)
+lcs_get_mac_for_ipm(__u32 ipm, char *mac, struct net_device *dev)
 {
-	if (atomic_dec_and_test(&drvr_globals->kernel_thread_lock)) {
-		netif_stop_queue(drvr_globals->dev);
-		MOD_INC_USE_COUNT;
-		drvr_globals->kernel_thread_routine = routine;
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,5,41)
-		schedule_work(&drvr_globals->kernel_thread_task);
-#else
-#if LINUX_VERSION_CODE<=KERNEL_VERSION(2,2,16)
-		queue_task(&drvr_globals->kernel_thread_task, &tq_scheduler);
-#else
-		schedule_task(&drvr_globals->kernel_thread_task);
-#endif
-#endif
-	} else
-		lcs_debug_event(1,"lcs_queue_thread busy drvr_globals=%p "
-				"routine=%p",drvr_globals,routine);
+	if (dev->type == ARPHRD_IEEE802_TR)
+		ip_tr_mc_map(ipm, mac);
+	else
+		ip_eth_mc_map(ipm, mac);
 }
 
-static int
-lcs_check_reset(lcs_chan_globals * chan_globals)
+/**
+ * function called by net device to handle multicast address relevant things
+ */
+static void
+lcs_set_multicast_list(struct net_device *dev)
 {
-	lcs_drvr_globals *drvr_globals = chan_globals->drvr_globals;
-	devstat_t *devstat = &chan_globals->devstat;
+	char buf[MAX_ADDR_LEN];
+	struct list_head *l;
+	struct ip_mc_list *im4;
+	struct in_device *in4_dev;
+	struct lcs_ipm_list *ipm, *tmp;
+	struct lcs_card *card;
 
-	if (devstat->flag & DEVSTAT_FLAG_SENSE_AVAIL) {
-		if (drvr_globals->state == lcs_doing_io &&
-		    (devstat->scnt >= 1) &&
-		    ((lcs_sense_byte_1) (devstat->ii.sense.data[1]))
-		    == resetting_event) {
-			lcs_debug_exception(0,"lcs reseting event occuring "
-					    "devno=%04x\n",
-					    (int) chan_globals->devno);
-			atomic_set(&drvr_globals->retry_cnt, 0);
-			switch (drvr_globals->state) {
-			case lcs_idle_requesting_channels_for_lancmds:
-			case lcs_requesting_channels_for_lancmds:
-			case lcs_got_write_channel_for_lancmds:
-			case lcs_doing_lancmds:
-				lcs_wakeup(drvr_globals->read, -ERETRY);
-				lcs_wakeup(drvr_globals->write, -ERETRY);
-				break;
-			case lcs_doing_io:
-				lcs_queue_thread(lcs_lgw_resetlan,
-						 drvr_globals);
+	LCS_DBF_TEXT(5, trace, "setmulti");
+	in4_dev = in_dev_get(dev);
+	if (in4_dev == NULL)
+		return;
+	read_lock(&in4_dev->lock);
+	card = (struct lcs_card *) dev->priv;
+	spin_lock(&card->lock);
+	/* Check for multicast addresses to be removed. */
+	list_for_each(l, &card->ipm_list) {
+		ipm = list_entry(l, struct lcs_ipm_list, list);
+		for (im4 = in4_dev->mc_list; im4 != NULL; im4 = im4->next) {
+			lcs_get_mac_for_ipm(im4->multiaddr, buf, dev);
+			if (memcmp(buf, &ipm->ipm.mac_addr,
+				   LCS_MAC_LENGTH) == 0 &&
+			    ipm->ipm.ip_addr == im4->multiaddr)
 				break;
-			default:
+		}
+		if (im4 == NULL)
+			ipm->ipm_state = LCS_IPM_STATE_DEL_REQUIRED;
+	}
+	/* Check for multicast addresses to be added. */
+	for (im4 = in4_dev->mc_list; im4; im4 = im4->next) {
+		lcs_get_mac_for_ipm(im4->multiaddr, buf, dev);
+		ipm = NULL;
+		list_for_each(l, &card->ipm_list) {
+			tmp = list_entry(l, struct lcs_ipm_list, list);
+			if (memcmp(buf, &tmp->ipm.mac_addr,
+				   LCS_MAC_LENGTH) == 0 &&
+			    tmp->ipm.ip_addr == im4->multiaddr) {
+				ipm = tmp;
 				break;
 			}
-			return (TRUE);
-		} else {
-			if ((devstat->scnt >= 1) && ((lcs_sense_byte_0)
-						     (devstat->ii.sense.
-						      data[0]) ==
-						     (intervention_required |
-						      interface_disconnect)))
-				lcs_debug_exception(0,
-						    "lcs intervention_required "
-						    "& interface_disconnect "
-						    "detected devno=0x%04x\n",
-						    (int) chan_globals->devno);
-			else {
-				lcs_debug_event(0,
-						"lcs unknown sense data "
-						"devno=0x%04x\n"
-						"sense_cnt=%d sense_data=\n"
-						"%08x %08x %08x %08x\n"
-						"%08x %08x %08x %08x\n",
-						(int) chan_globals->devno,
-						(int) devstat->scnt,
-						((int *)&devstat->
-						 ii.sense.data)[0],
-						((int *)&devstat->
-						 ii.sense.data)[1],
-						((int *)&devstat->
-						 ii.sense.data)[2],
-						((int *)&devstat->
-						 ii.sense.data)[3],
-						((int *)&devstat->
-						 ii.sense.data)[4],
-						((int *)&devstat->
-						 ii.sense.data)[5],
-						((int *)&devstat->
-						 ii.sense.data)[6],
-						((int *)&devstat->
-						 ii.sense.data)[7]);
-				if (devstat->scnt > 2
-				    || (devstat->ii.sense.data[0] == 0
-					&& devstat->ii.sense.data[1] == 0)) {
-					lcs_debug_event(0,
-							"lcs sense data "
-							"looks like rubbish "
-							"ignoring it\n");
-					devstat->flag &=
-						~DEVSTAT_FLAG_SENSE_AVAIL;
-				}
-			}
 		}
+		if (ipm != NULL)
+			continue;	/* Address already in list. */
+		ipm = (struct lcs_ipm_list *)
+			kmalloc(sizeof(struct lcs_ipm_list), GFP_ATOMIC);
+		if (ipm == NULL) {
+			PRINT_INFO("Not enough memory to add "
+				   "new multicast entry!\n");
+			break;
+		}
+		memset(ipm, 0, sizeof(struct lcs_ipm_list));
+		memcpy(&ipm->ipm.mac_addr, buf, LCS_MAC_LENGTH);
+		ipm->ipm.ip_addr = im4->multiaddr;
+		ipm->ipm_state = LCS_IPM_STATE_SET_REQUIRED;
+		list_add(&ipm->list, &card->ipm_list);
 	}
-	return (FALSE);
+	spin_unlock(&card->lock);
+	read_unlock(&in4_dev->lock);
+	set_bit(3, &card->thread_mask);
+	schedule_work(&card->kernel_thread_starter);
 }
 
-#if LCS_ZERO_COPY_READ
-static inline void
-lcs_rxskb(lcs_drvr_globals * drvr_globals, struct sk_buff *skb, u16 pkt_len,
-	  u16 offset, struct net_device_stats *stats)
-{
-	stats->rx_bytes += pkt_len;
-	if (use_hw_stats == FALSE)
-		stats->rx_packets++;
-	lcs_debug_event(2, "netif_rx called\n");
-	lcs_debug_event(2, "received %u bytes rx_bytes=%lu\n",
-			(unsigned) pkt_len, stats->rx_bytes);
-	skb_reserve(skb, sizeof (lcs_header_type) + offset);
-	skb_put(skb, pkt_len);
-	/* Horrible horrible kludge to fix bug in some socket code */
-	/* usage of skb->truesize hopefully this bug will be fixed in */
-	/* upper layers soon */
-	skb->truesize = skb->len;
-	skb->protocol = drvr_globals->lan_type_trans(skb, skb->dev);
-	netif_rx(skb);
-	skb->dev->last_rx = jiffies;
-}
-#endif
+#endif /* CONFIG_IP_MULTICAST */
 
-static int
-lcs_rxpacket(lcs_drvr_globals * drvr_globals, u8 * start_lcs_buff,
-	     lcs_std_cmd ** lancmd_reply
-#if LCS_ZERO_COPY_READ
-	     , u32 curr_idx
-#endif
-    )
+/**
+ * IRQ Handler for LCS channels
+ */
+static void
+lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
 {
-	lcs_read_globals *read = NULL;
+	char dbf_text[15];
+	struct lcs_card *card;
+	struct lcs_channel *channel;
+	int index;
 
-	struct sk_buff *curr_skb
-#if LCS_ZERO_COPY_READ
-	, *prev_skb
-#endif
-	;
-	struct net_device *dev = NULL;
-	struct net_device_stats *stats = NULL;
-	lcs_header_type *lcs_header_ptr = (lcs_header_type *) start_lcs_buff;
-	u16 curr_offset, curr_pkt_len
-#if  LCS_ZERO_COPY_READ
-	, prev_pkt_len, curr_skb_offset, prev_skb_offset
-#endif
-	;
+	card = (struct lcs_card *)cdev->dev.driver_data;
+	if (card->read.ccwdev == cdev)
+		channel = &card->read;
+	else
+		channel = &card->write;
 
-	lcs_debug_event(2, "Entering lcs_rxpacket\n");
-	if (drvr_globals == NULL) {
-		lcs_bad_news("drvr_globals=NULL\n");
-		return -EPERM;
+	sprintf(dbf_text, "Rint%s", cdev->dev.bus_id);
+	LCS_DBF_TEXT(5, trace, dbf_text);
+	sprintf(dbf_text, "%4x%4x", irb->scsw.cstat, irb->scsw.dstat);
+	LCS_DBF_TEXT(5, trace, dbf_text);
+
+	/* How far in the ccw chain have we processed? */
+	if (channel->state != CH_STATE_INIT) {
+		index = (struct ccw1 *) __va((addr_t) irb->scsw.cpa) 
+			- channel->ccws;
+		if ((irb->scsw.actl & SCSW_ACTL_SUSPENDED) ||
+		    (irb->scsw.cstat | SCHN_STAT_PCI))
+			/* Bloody io subsystem tells us lies about cpa... */
+			index = (index - 1) & (LCS_NUM_BUFFS - 1);
+		while (channel->io_idx != index) {
+			__lcs_processed_buffer(channel,
+					       channel->iob + channel->io_idx);
+			channel->io_idx =
+				(channel->io_idx + 1) & (LCS_NUM_BUFFS - 1);
+		}
 	}
 
-	dev = drvr_globals->dev;
-	read = drvr_globals->read;
-#if LCS_ZERO_COPY_READ
-	if (atomic_read(skb_datarefp(read->skb_buff[curr_idx])) != 1) {
-		lcs_bad_news("lcs_rxpacket skb->refcnt=%d start_lcs_buff=%p\n",
-			     atomic_read(skb_datarefp
-					 (read->skb_buff[curr_idx])),
-			     start_lcs_buff);
-		return -EIO;
+	if ((irb->scsw.dstat & DEV_STAT_DEV_END) ||
+	    (irb->scsw.dstat & DEV_STAT_CHN_END) ||
+	    (irb->scsw.dstat & DEV_STAT_UNIT_CHECK))
+		/* Mark channel as stopped. */
+		channel->state = CH_STATE_STOPPED;
+	else if (irb->scsw.actl & SCSW_ACTL_SUSPENDED)
+		/* CCW execution stopped on a suspend bit. */
+		channel->state = CH_STATE_SUSPENDED;
+
+	if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC)
+		/* The channel has been stopped by halt_IO. */
+		channel->state = CH_STATE_HALTED;
+
+	/* Do the rest in the tasklet. */
+	tasklet_schedule(&channel->irq_tasklet);
+}
+
+/**
+ * Tasklet for IRQ handler
+ */
+static void
+lcs_tasklet(unsigned long data)
+{
+	char dbf_text[15];
+	unsigned long flags;
+	struct lcs_channel *channel;
+	struct lcs_buffer *iob;
+	int buf_idx, io_idx;
+	int rc;
+
+	channel = (struct lcs_channel *) data;
+	sprintf(dbf_text, "tlet%s", channel->ccwdev->dev.bus_id);
+	LCS_DBF_TEXT(5, trace, dbf_text);
+
+	/* Check for processed buffers. */
+	iob = channel->iob;
+	buf_idx = channel->buf_idx;
+	io_idx = channel->io_idx;
+	while (buf_idx != io_idx &&
+	       iob[buf_idx].state == BUF_STATE_PROCESSED) {
+		/* Do the callback thing. */
+		if (iob[buf_idx].callback != NULL)
+			iob[buf_idx].callback(channel, iob + buf_idx);
+		buf_idx = (buf_idx + 1) & (LCS_NUM_BUFFS - 1);
 	}
-#endif
-	stats = &drvr_globals->stats;
-	lcs_debug_event(2, "We appear to have received a packet buff=%p\n",
-			lcs_header_ptr);
-#if LCS_ZERO_COPY_READ
-	curr_skb = NULL;
-	curr_pkt_len = curr_skb_offset =
-#endif
-	    curr_offset = 0;
-	while (lcs_header_ptr->offset) {
-		lcs_debug_event(3, "lcs_header_ptr=%p curroffset=%d\n",
-				lcs_header_ptr, curr_offset);
-#if LCS_ZERO_COPY_READ
-		prev_pkt_len = curr_pkt_len;
-		prev_skb = curr_skb;
-		prev_skb_offset = curr_skb_offset;
-#endif
-#if 0
-		static int idx = 0;
-		idx++;
-		if ((idx & 0x1ff) == 0) {
-			lcs_header_ptr->type = lcs_control_frame_type;
-			((lcs_std_cmd *) lcs_header_ptr)->initiator =
-			    lcs_lgw_initiated;
-			(((lcs_std_cmd *) lcs_header_ptr)->cmd_code) =
-			    lcs_startup;
-		}
-#endif
-		if (lcs_header_ptr->offset > LCS_IOBUFFSIZE ||
-		    lcs_header_ptr->offset < curr_offset) {
-			if (use_hw_stats == FALSE) {
-				stats->rx_length_errors++;
-				stats->rx_errors++;
-			}
-			lcs_bad_news
-			    ("lcs whacko rx_buffer read_globals=%p "
-			     "curr_offset=%d new_offset=%d\n",
-			     read, (int) curr_offset,
-			     (int) lcs_header_ptr->offset);
-			return -EIO;
-		}
+	channel->buf_idx = buf_idx;
 
-		if (lcs_header_ptr->type == lcs_control_frame_type) {
-			if (((lcs_std_cmd *) lcs_header_ptr)->initiator ==
-			    lcs_lgw_initiated
-			    && drvr_globals->state == lcs_doing_io) {
-				drvr_globals->lgw_sequence_no =
-				    ((lcs_std_cmd *) lcs_header_ptr)->sequence_no;
-				lcs_debug_display_read_buff
-				    ("lgw_initiated_command read buff",
-				     ((lcs_std_cmd *) lcs_header_ptr));
-				switch ((int)
-					(((lcs_std_cmd *)lcs_header_ptr)->
-					 cmd_code)) {
-				case lcs_startup:
-					atomic_set(&drvr_globals->retry_cnt,
-						   -1);
-					lcs_queue_thread(lcs_lgw_resetlan,
-							 drvr_globals);
-					break;
-				case lcs_startlan:
-					lcs_queue_thread(lcs_lgw_startlan,
-							 drvr_globals);
-					break;
-				case lcs_stoplan:
-					lcs_queue_thread(lcs_lgw_stoplan,
-							 drvr_globals);
-					break;
-				default:
-					lcs_debug_exception(1,"lcs "
-					    "unrecognised lgw command "
-					    "received 0x%02x on "
-					    "devno=%04x\n",
-					    (int)((lcs_std_cmd *)
-						  lcs_header_ptr)->cmd_code,
-					    (int)read->devno);
-				}
-			} else {
-				if (drvr_globals->state == lcs_doing_lancmds) {
-					if (((((lcs_std_cmd *) 
-					       lcs_header_ptr)->sequence_no ==
-					      drvr_globals->sequence_no))
-					    &&
-					    (((lcs_std_cmd *) 
-					      lcs_header_ptr)->cmd_code ==
-					     drvr_globals->cmd_code)) {
-						*lancmd_reply =
-						    read->lancmd_reply_ptr =
-						    (lcs_std_cmd *)lcs_header_ptr;
-						lcs_debug_event(2,
-							"got a valid "
-							"lancommand %p "
-							"cmd_code=%02x "
-							"sequence_no=%d\n",
-							read->lancmd_reply_ptr,
-							(int) 
-							((lcs_std_cmd *)
-							 lcs_header_ptr)->
-							cmd_code, 
-							(int) 
-							((lcs_std_cmd *)
-							 lcs_header_ptr)->
-							sequence_no);
-						lcs_wakeup((lcs_chan_globals *)
-							   read, 0);
-						break;
-					}
-				}
-			}
-		} else if (dev && drvr_globals->state == lcs_doing_io) {	
-			/* the packet is for tcpip */
-			
-			/* dev_alloc_skb allocs with GFP_ATOMIC currently */
-			/* so this should be okay under interrupt */
-			/* hopefully .... */
-#if LCS_ZERO_COPY_READ
-			if (curr_skb == NULL) {
-				/* We need to detach the buffer */
-				struct sk_buff *new_skb;
-				ccw1_t temp_ccw = read->ccw[curr_idx];
-				if (set_normalized_cda (&temp_ccw,
-							new_skb->data)) {
-					stats->rx_dropped++;
-					lcs_bad_news
-					    ("%s: Memory squeeze, "
-					     "dropping packet.\n",
-					     dev->name);
-					return -ENOMEM;
-				}
-				if ((new_skb=
-				     lcs_dev_alloc_skb(LCS_READ_ALLOCSIZE))==
-				    NULL) {
-					clear_normalized_cda(&temp_ccw);
-					stats->rx_dropped++;
-					lcs_bad_news
-					    ("%s: Memory squeeze, "
-					     "dropping packet.\n",
-					     dev->name);
-					return -ENOMEM;
-				}
-				curr_skb = read->skb_buff[curr_idx];
-				curr_skb->dev = dev;
-				curr_skb->ip_summed=(checksum_received_ip_pkts
-						     ? CHECKSUM_NONE :
-						     CHECKSUM_UNNECESSARY);
-				clear_normalized_cda(&read->ccw[curr_idx]);
-				read->skb_buff[curr_idx] = new_skb;
-				read->ccw[curr_idx] = temp_ccw;
-			} else {
-				curr_skb = skb_clone(prev_skb, GFP_ATOMIC);
-				if (curr_skb == NULL) {
-					curr_skb = prev_skb;
-					stats->rx_dropped++;
-					lcs_bad_news("%s: Memory squeeze, "
-						     "dropping packet.\n",
-						     dev->name);
-					return -ENOMEM;
-				}
-				curr_skb_offset = curr_offset;
-			}
-			if (prev_skb)
-				lcs_rxskb(drvr_globals, prev_skb, prev_pkt_len,
-					  prev_skb_offset, stats);
-			curr_pkt_len =
-			    lcs_header_ptr->offset - curr_skb_offset -
-			    sizeof (lcs_header_type);
-#else
-			curr_pkt_len =
-			    lcs_header_ptr->offset - curr_offset -
-			    sizeof (lcs_header_type);
-			curr_skb = lcs_dev_alloc_skb(curr_pkt_len);
-			if (curr_skb) {
-				curr_skb->dev = dev;
-				memcpy(skb_put(curr_skb, curr_pkt_len),
-				       lcs_header_ptr + 1, curr_pkt_len);
-				curr_skb->protocol =
-				    drvr_globals->lan_type_trans(curr_skb, dev);
-				curr_skb->ip_summed =
-				    (checksum_received_ip_pkts ? CHECKSUM_NONE :
-				     CHECKSUM_UNNECESSARY);
-				stats->rx_bytes += curr_pkt_len;
-				if (use_hw_stats == FALSE)
-					stats->rx_packets++;
-				lcs_debug_event(2,"netif_rx called\n");
-				lcs_debug_event(2,"received %u bytes " \
-						"rx_bytes=%lu\n",
-						(unsigned) curr_pkt_len,
-						stats->rx_bytes);
-				netif_rx(curr_skb);
-				curr_skb->dev->last_rx = jiffies;
-			} else {
-				lcs_bad_news
-				    ("%s: Memory squeeze, dropping packet.\n",
-				     dev->name);
-				stats->rx_dropped++;
-				return -ENOMEM;
-			}
-#endif
-		}
-		curr_offset = lcs_header_ptr->offset;
-		((addr_t) lcs_header_ptr) = start_lcs_buff + curr_offset;
+	if (channel->state == CH_STATE_STOPPED)
+		// FIXME: what if rc != 0 ??
+		rc = lcs_start_channel(channel);
+	spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
+	if (channel->state == CH_STATE_SUSPENDED &&
+	    channel->iob[channel->io_idx].state == BUF_STATE_READY) {
+		// FIXME: what if rc != 0 ??
+		rc = __lcs_resume_channel(channel);
 	}
-#if LCS_ZERO_COPY_READ
-	if (curr_skb)
-		lcs_rxskb(drvr_globals, curr_skb, curr_pkt_len, curr_skb_offset,
-			  stats);
-#endif
-	return 0;
+	spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
+
+	/* Something happened on the channel. Wake up waiters. */
+	wake_up(&channel->wait_q);
 }
 
-/*
- * This is the main interrupt handler it does a lot of sanity checking &
- * wakes up a process if doing startup or shutdown or calls 
- * queues lcs_rxpacket if a network packet is received or
- * resets transmit busy a network packet has been transmitted &
- * marks the bottom half so that networking knows it can transmit more packets 
- * N.B. if we decide to call ssch directly or indirectly from the irq_handler 
- * we had better increment chan_globals->lock_cnt & decrement it when done to avoid
- * deadlocks ( this count can be over 2 inside the interrupt handler ),
- * but not in normal tasks.
+/**
+ * Finish current tx buffer and make it ready for transmit.
  */
+static void
+__lcs_emit_txbuffer(struct lcs_card *card)
+{
+	*(__u16 *)(card->tx_buffer->data + card->tx_buffer->count) = 0;
+	card->tx_buffer->count += 2;
+	lcs_ready_buffer(&card->write, card->tx_buffer);
+	card->tx_buffer = NULL;
+	card->tx_emitted++;
+}
 
+/**
+ * Callback for finished tx buffers.
+ */
 static void
-lcs_handle_irq(int irq, devstat_t * devstat, struct pt_regs *regs)
+lcs_txbuffer_cb(struct lcs_channel *channel, struct lcs_buffer *buffer)
 {
-	union {
-		lcs_read_globals *read;
-		lcs_write_globals *write;
-		lcs_chan_globals *globals;
-	} chan;
-	struct net_device *dev = NULL;
-	lcs_drvr_globals *drvr_globals = NULL;
-	lcs_debug_initmessage struct net_device_stats *stats;
-	ccw1_t *curr_ccw;
-	lcs_header_type *lcs_hdr;
-	u32 curr_ccwidx, curr_ccwidx2, curr_idx;
-	int chan_globals_valid = FALSE;
-
-	chan.globals = NULL;
-	if (!devstat)
-		goto lcs_int_spurious;
-	chan.globals = (lcs_chan_globals *) devstat->intparm;
-	if (!chan.globals || (irq != chan.globals->subchannel))
-		goto lcs_int_spurious;
-	chan_globals_valid = TRUE;
-	drvr_globals = chan.globals->drvr_globals;
-	lcs_debug_event(2,
-			"lcs_handle_irq irq=%x chan_globals=%p drvr_globals=%p"
-			" drvr_state=%d devstat=%p irb=%p cpu=%d "
-			"chan_busy_state=%d\n",
-			irq, chan.globals, drvr_globals, drvr_globals->state,
-			&chan.globals->devstat, &chan.globals->devstat.ii.irb,
-			smp_processor_id(), chan.globals->chan_busy_state);
-	if (chan.globals->lock_cnt)
-		lcs_bad_news("lcs_handle_irq lock owner %d lock_cnt=%d\n",
-			     chan.globals->lock_owner, chan.globals->lock_cnt);
-	if (drvr_globals->state == lcs_interrupted) {
-		lcs_wakeup(chan.globals, -EINTR);
-	} else {
-		if (lcs_check_reset(chan.globals))
-			return;
-		if (chan.globals->irq_allocated_magic != LCS_MAGIC)
-			goto lcs_int_spurious;
-	}
-	dev = drvr_globals->dev;
-	if (dev == NULL && drvr_globals->state == lcs_doing_io) {
-		lcs_debug_setmessage("dev=NULL in handle irq");
-		goto lcs_int_debug_info;
-	}
-	stats = &drvr_globals->stats;
-	if (drvr_globals->state == lcs_halting_subchannels) {
-		lcs_wakeup(chan.globals, 0);
-		return;
-	}
-	chan.globals->lock_owner = smp_processor_id();
-	chan.globals->lock_cnt = 1;
-	if (drvr_globals->read == chan.read) {
-		if (devstat->dstat != 0 ||
-		    (devstat->cstat & ~SCHN_STAT_PCI) != 0) {
-
-			lcs_debug_event(0,
-					"lcs_handle_irq dstat=%02x cstat=%02x "
-					"drvr_globals_state=%d\n",
-					devstat->dstat, devstat->cstat,
-					drvr_globals->state);
-			switch (drvr_globals->state) {
-			case lcs_idle_requesting_channels_for_lancmds:
-			case lcs_requesting_channels_for_lancmds:
-			case lcs_got_write_channel_for_lancmds:
-			case lcs_doing_lancmds:
-				lcs_restartreadio(drvr_globals);
-				break;
-			case lcs_doing_io:
-				lcs_retry(chan.globals);
-				break;
-			default:
-				break;
-			}
-			goto lcs_normal_ret;
-		}
-		switch (chan.read->chan_busy_state) {
-		case chan_busy: {
-			int rxerr = 0;
-			lcs_std_cmd *lancmd_reply_ptr;
-			
-			switch (drvr_globals->state) {
-			case lcs_doing_io:
-			case lcs_doing_lancmds:
-				curr_idx =
-		    			((ccw1_t *)
-	    				 phys_to_virt(devstat->cpa) -
-    					 &chan.read->ccw[0]);
-				/* We don't need to divide by
-				 * sizeof(ccw1_t) here as we are
-				 * doing pointer arithmetic */
-				curr_ccwidx = ((curr_idx - 2) 
-					       & (LCS_NUM_RX_BUFFS - 1));
-				curr_ccwidx2 = ((curr_idx - 1) 
-						& (LCS_NUM_RX_BUFFS - 1));
-				for (curr_idx = chan.read->rx_idx;
-				     curr_idx != curr_ccwidx2;
-				     curr_idx = ((curr_idx + 1) 
-						 & (LCS_NUM_RX_BUFFS - 1))) {
-#if LCS_ZERO_COPY_READ
-					lcs_hdr = (lcs_header_type *) 
-						(chan.read->
-						 skb_buff[curr_idx]->data);
-#else
-					lcs_hdr = (lcs_header_type *)
-						(chan.read->
-						 iobuff[curr_idx]);
-#endif
-					
-					if (lcs_hdr->offset !=
-					    LCS_ILLEGAL_OFFSET) {
-						/* Detect duplicate interrupts 
-						   unfilled buffers etc. */
-						lancmd_reply_ptr = NULL;
-						if (rxerr != -ENOMEM)
-							rxerr = lcs_rxpacket
-							(drvr_globals,
-							 (u8 *)lcs_hdr,
-							 &lancmd_reply_ptr
-#if LCS_ZERO_COPY_READ
-							 , curr_idx
-#endif
-							);
-						if (lancmd_reply_ptr == NULL) {
-#if LCS_ZERO_COPY_READ
-							lcs_hdr =
-							(lcs_header_type *) 
-							(chan.read->
-							 skb_buff[curr_idx]->
-							 data);
-#endif
-							lcs_hdr->offset =
-							LCS_ILLEGAL_OFFSET;
-						}
-					} else {
-						lcs_bad_news
-							("lcs_handle_irq race "
-							 "condition Illegal"
-							 " offset buffer "
-							 "for ccw=%p\n",
-							 &chan.read->
-							 ccw[curr_idx]);
-						goto lcs_int_debug_info;
-					}
-				}
-				if (chan.read->rx_idx != curr_ccwidx2) {
-					curr_ccw =
-						&chan.read->ccw[curr_ccwidx];
-					curr_ccw->flags =
-						CCW_FLAG_CC | CCW_FLAG_SLI |
-						CCW_FLAG_SUSPEND
-#if LCS_USE_IDALS
-						| (curr_ccw->flags &
-						   CCW_FLAG_IDA)
-#endif
-						;
-					curr_idx = (chan.read->rx_idx - 1) & 
-						(LCS_NUM_RX_BUFFS - 1);
-					curr_ccw = &chan.read->ccw[curr_idx];
-					curr_ccw->flags = CCW_FLAG_CC |
-						CCW_FLAG_SLI |
-						CCW_FLAG_PCI
-#if LCS_USE_IDALS
-						| (curr_ccw->flags &
-						   CCW_FLAG_IDA)
-#endif
-						;
-					chan.read->rx_idx = curr_ccwidx2;
-				}
-				break;
-			default:
-				break;
-			}
-				}
-				break;
-		case chan_started_successfully:
-			chan.read->chan_busy_state = chan_busy;
-			break;
-		default:
-			break;
-		}
+	struct lcs_card *card;
 
+	/* Put buffer back to pool. */
+	lcs_release_buffer(channel, buffer);
+	card = (struct lcs_card *)
+		((char *) channel - offsetof(struct lcs_card, write));
+	spin_lock(&card->lock);
+	card->tx_emitted--;
+	if (card->tx_emitted <= 0 && card->tx_buffer != NULL)
 		/*
-		   We need to suspend if till the lancmd reply is consumed.
+		 * Last running tx buffer has finished. Submit partially
+		 * filled current buffer.
 		 */
-		if ((chan.read->chan_busy_state == chan_busy ||
-		     chan.read->chan_busy_state == chan_idle) &&
-#if 0
-		    devstat->flag & DEVSTAT_SUSPENDED
-#else
-		    devstat->ii.irb.scsw.actl & SCSW_ACTL_SUSPENDED
-#endif
-		    ) {
-			chan.read->chan_busy_state = chan_idle;
-			if (chan.read->lancmd_reply_ptr == NULL) {
-				lcs_debug_event(2,"resume called from "
-						"interrupt handler.\n");
-				lcs_interrupt_resume_read(chan.read);
-			}
-		}
-	} else {
-
-		if (devstat->dstat != 0 ||
-		    devstat->flag & DEVSTAT_FLAG_SENSE_AVAIL ||
-		    devstat->cstat != 0) {
-			lcs_debug_event(0,
-					"lcs_handle_irq write channel "
-					"dstat=%02x flag=%x cstat=%02x "
-					"drvr_globals_state=%d\n",
-					(int) devstat->dstat,
-					(int) devstat->flag,
-					(int) devstat->cstat,
-					drvr_globals->state);
-			switch (drvr_globals->state) {
-			case lcs_idle_requesting_channels_for_lancmds:
-			case lcs_requesting_channels_for_lancmds:
-			case lcs_got_write_channel_for_lancmds:
-			case lcs_doing_lancmds:
-				lcs_restartwriteio(drvr_globals);
-				break;
-			case lcs_doing_io:
-				lcs_queue_thread(lcs_lgw_resetlan,
-						 drvr_globals);
-				break;
-			default:
-				break;
-			}
-			goto lcs_normal_ret;
-		}
-		switch (chan.write->chan_busy_state) {
-		case chan_started_successfully:
-			chan.write->chan_busy_state = chan_idle;
-			break;
-		case chan_busy:
-			chan.write->chan_busy_state = chan_idle;
-#if 0
-			if (devstat->flag & DEVSTAT_SUSPENDED)
-#else
-			if (devstat->ii.irb.scsw.actl & SCSW_ACTL_SUSPENDED)
-#endif
-			{
-				switch (drvr_globals->state) {
-				case lcs_doing_io:
-				case lcs_requesting_channels_for_lancmds:
-				case lcs_doing_lancmds:
-					curr_idx =
-					    ((ccw1_t *)
-					     phys_to_virt(devstat->cpa) -
-					     &chan.write->ccw[0]);
-					curr_ccwidx =
-					    ((curr_idx - 2) & 
-					     (LCS_NUM_TX_BUFFS - 1));
-					curr_ccwidx2 =
-					    ((curr_idx - 1) 
-					     & (LCS_NUM_TX_BUFFS - 1));
-					if (curr_ccwidx == chan.write->tx_idx) {
-						lcs_bad_news
-						    ("lcs_handle_irq race "
-						     "tx_idx=%d=curr_ccwidx "
-						     "prepare_idx=%u "
-						     "write_globals=%p\n",
-						     chan.write->tx_idx,
-						     chan.write->prepare_idx,
-						     chan.write);
-						goto lcs_int_debug_info;
-					}
-
-					for (curr_idx =
-					     ((chan.write->tx_idx + 1) 
-					      & (LCS_NUM_TX_BUFFS - 1));
-					     curr_idx != curr_ccwidx2;
-					     curr_idx =
-					     ((curr_idx + 1) 
-					      & (LCS_NUM_TX_BUFFS - 1))) {
-						curr_ccw =
-						    &chan.write->ccw[curr_idx];
-						curr_ccw->flags |=
-						    CCW_FLAG_SUSPEND;
-						curr_ccw->count = 0;
-					}
-					chan.write->tx_idx = curr_ccwidx;
-					curr_ccw =
-					    &chan.write->ccw[chan.write->
-							     prepare_idx];
-					if (curr_ccw !=
-					    &chan.write->ccw[curr_ccwidx]) {
-					    if (curr_ccw->count != 0) {
-						/* Tx the buffer currently
-						 * being prepared */
-					 	if (drvr_globals->state ==
-						    lcs_doing_io &&
-						    lcs_should_queue_write
-						    (chan.write, lcs_get_tod()))
-						lcs_queue_write_if_necessary
-								(chan.write);
-						else
-							lcs_resume_write
-								(chan.write);
-					    }
-					} else {
-						lcs_bad_news
-						    ("lcs_handle_irq race "
-						     "tx_idx=%u=prepare_idx "
-						     "write_globals=%p\n",
-						     (int) chan.write->
-						     prepare_idx, chan.write);
-						goto lcs_normal_ret;
-					}
-					break;
-				default:
-					break;
-				}
-			}
-			break;
-		default:
-			break;
-		}
-		if (chan.write->chan_busy_state == chan_idle) {
-			switch (drvr_globals->state) {
-			case lcs_idle_requesting_channels_for_lancmds:
-			case lcs_requesting_channels_for_lancmds:
-				drvr_globals->state =
-				    lcs_got_write_channel_for_lancmds;
-			case lcs_doing_lancmds:
-				lcs_wakeup(chan.globals, 0);
-				break;
-			case lcs_doing_io:
-				stats->tx_bytes +=
-				    chan.write->bytes_still_being_txed;
-				chan.write->bytes_still_being_txed = 0;
-				if (!use_hw_stats)
-					stats->tx_packets +=
-					    chan.write->pkts_still_being_txed;
-				chan.write->pkts_still_being_txed = 0;
-				netif_wake_queue(dev);
-				break;
-			default:
-				break;
-			}
-		}
-	}
-	goto lcs_normal_ret;
-lcs_int_spurious:
-	lcs_debug_setmessage("received spurious interrupt");
-lcs_int_debug_info:
-	lcs_debugchannel(message, chan.globals);
-lcs_normal_ret:
-	lcs_debug_event(2, "lcs irq exited irq=%x\n", irq);
-	if (chan_globals_valid) {
-		chan.globals->lock_owner = LCS_INVALID_LOCK_OWNER;
-		chan.globals->lock_cnt = 0;
-	}
+		__lcs_emit_txbuffer(card);
+	spin_unlock(&card->lock);
 }
 
-/* 
- * Wrappers to allocate irqs if these fail the io channel is probably
- * being used by another device.
+/**
+ * Packet transmit function called by network stack
  */
 static int
-lcs_allocirq_func(lcs_chan_globals * chan_globals)
+__lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb,
+		 struct net_device *dev)
 {
-	int rc;
+	struct lcs_header *header;
 
-	lcs_debug_event(2, "lcs_allocirq called chan_globals=%p\n",
-			chan_globals);
-	if (chan_globals->irq_allocated_magic) {
-		lcs_bad_news("lcs_allocirq irq already allocated");
+	if (skb == NULL) {
+		card->stats.tx_dropped++;
+		card->stats.tx_errors++;
+		return -EIO;
+	}
+	if (card->state != DEV_STATE_UP) {
+		dst_link_failure(skb);
+		dev_kfree_skb(skb);
+		card->stats.tx_dropped++;
+		card->stats.tx_errors++;
+		card->stats.tx_carrier_errors++;
+		return 0;
+	}
+	if (netif_queue_stopped(dev) ) {
+		card->stats.tx_dropped++;
 		return -EBUSY;
-	} else {
-		chan_globals->devstat.intparm = (addr_t) chan_globals;
-		rc =
-#if LCS_CHANDEV
-		    chandev_request_irq
-#else
-		    request_irq
-#endif
-		    (chan_globals->subchannel,
-		     (void (*)(int, void *, struct pt_regs *)) lcs_handle_irq,
-		     0, cardname, &chan_globals->devstat);
-		if (!rc)
-			chan_globals->irq_allocated_magic = LCS_MAGIC;
-
-#if LCS_DEBUG
-		else
-			lcs_debug_event(2,"request irq failed error code %d "
-					"subchannel %2X\n",
-					rc,chan_globals->subchannel);
-#endif
-		return rc;
 	}
+	if (card->tx_buffer != NULL &&
+	    card->tx_buffer->count + sizeof(struct lcs_header) +
+	    skb->len + sizeof(u16) > LCS_IOBUFFERSIZE)
+		/* skb too big for current tx buffer. */
+		__lcs_emit_txbuffer(card);
+	if (card->tx_buffer == NULL) {
+		/* Get new tx buffer */
+		card->tx_buffer = lcs_get_buffer(&card->write);
+		if (card->tx_buffer == NULL) {
+			netif_stop_queue(dev);
+			card->stats.tx_dropped++;
+			return -EBUSY;
+		}
+		card->tx_buffer->callback = lcs_txbuffer_cb;
+		card->tx_buffer->count = 0;
+	}
+	header = (struct lcs_header *)
+		(card->tx_buffer->data + card->tx_buffer->count);
+	card->tx_buffer->count += skb->len + sizeof(struct lcs_header);
+	header->offset = card->tx_buffer->count;
+	header->type = card->lan_type;
+	header->slot = card->portno;
+	memcpy(header + 1, skb->data, skb->len);
+	card->stats.tx_bytes += skb->len;
+	card->stats.tx_packets++;
+	dev_kfree_skb(skb);
+	if (card->tx_emitted <= 0)
+		/* If this is the first tx buffer emit it immediatly. */
+		__lcs_emit_txbuffer(card);
+	return 0;
 }
 
-#define lcs_allocirq(chan_globals) \
-	lcs_allocirq_func((lcs_chan_globals *)(chan_globals))
-
-static void
-lcs_freeirq(lcs_chan_globals * chan_globals)
+static int
+lcs_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	if (chan_globals->irq_allocated_magic) {
-#if LCS_CHANDEV
-		chandev_free_irq(chan_globals->subchannel,
-				 &chan_globals->devstat);
-#else
-		free_irq(chan_globals->subchannel, &chan_globals->devstat);
-#endif
-		chan_globals->irq_allocated_magic = 0;
-	}
-}
+	struct lcs_card *card;
+	int rc;
 
-static lcs_inline void
-lcs_freeallirqs(lcs_drvr_globals * drvr_globals)
-{
-	lcs_debug_event(2, "lcs_freeallirqs called %p\n", drvr_globals);
-	lcs_freeirq((lcs_chan_globals *) drvr_globals->read);
-	lcs_freeirq((lcs_chan_globals *) drvr_globals->write);
+	LCS_DBF_TEXT(5, trace, "pktxmit");
+	card = (struct lcs_card *) dev->priv;
+	spin_lock(&card->lock);
+	rc = __lcs_start_xmit(card, skb, dev);
+	spin_unlock(&card->lock);
+	return rc;
 }
 
-/*
- * Generic routine for sending all startup & shutdown command primatives  
- * to lcs.
- * A unit check with a sense code of 0x42 may be presented here if this
- * happens we restart the startup procedure, currently the osa card has been
- * seen to present the unit check very late in the startup sequence 
- * & resend outstanding buffers already read, the source of this problem is
- * unknown, this problem is handled basically by checking sequence
- * numbers & disgarding packets already received.
+/**
+ * send startlan and lanstat command to make LCS device ready
  */
 static int
-lcs_lancmd(lcs_cmd cmd_code, u8 rel_adapter_no, lcs_drvr_globals * drvr_globals
-#ifdef CONFIG_IP_MULTICAST
-	   , u16 num_ipm_pairs, lcs_ip_mac_addr_pair * ip_mac_pairs
-#endif
-)
+lcs_startlan_auto(struct lcs_card *card)
 {
-	lcs_std_cmd *readcmd, *writecmd;
-	lcs_read_globals *read;
-	lcs_write_globals *write;
-	int rc = 0;
-	int retry_cnt = 0;
-
-	read = drvr_globals->read;
-	write = drvr_globals->write;
-	lcs_debug_exception(2, "lcs_lancmd cmd code=%02x drvr_globals=%p\n",
-			    (int) cmd_code, drvr_globals);
-	wait_on_write(drvr_globals);
-Retry:
-	read->lancmd_reply_ptr = NULL;
-	do {
-		if ((writecmd =
-		     lcs_prepare_lancmd(write, cmd_code, rel_adapter_no,
-					lcs_390_initiated,
-					drvr_globals->lan_type)) == 0) {
-			lcs_debug_event(2, "lancmd2 lcs_prepare_cmd failed\n");
-			return (-EIO);
-		}
-		lcs_debug_event(2, "lcs_lancmd writecmd=%p\n", writecmd);
-		read->lancmd_reply_ptr = NULL;
-		lcs_initqueue(read);
-#ifdef CONFIG_IP_MULTICAST
-		if (cmd_code == lcs_setipm || cmd_code == lcs_delipm) {
-			((lcs_ipm_ctlmsg *) writecmd)->version = 4;
-			((lcs_ipm_ctlmsg *) writecmd)->num_ipm_pairs =
-			    num_ipm_pairs;
-			memcpy(&((lcs_ipm_ctlmsg *) writecmd)->ip_mac_pair[0],
-			       ip_mac_pairs,
-			       sizeof (lcs_ip_mac_addr_pair) * num_ipm_pairs);
-		}
-		if (cmd_code == lcs_qipassist) {
-			((lcs_qipassist_ctlmsg *) writecmd)->num_ip_pairs = 0;
-			((lcs_qipassist_ctlmsg *) writecmd)->version = 4;
-		}
-#endif
-		writecmd->sequence_no = ++drvr_globals->sequence_no;
-		lcs_debug_event(2, "sequence_no=%d\n",
-				(int) drvr_globals->sequence_no);
-		drvr_globals->cmd_code = cmd_code;
-		rc = lcs_resumeandwait(write, cmd_code);
-	} while (rc == -EAGAIN && retry_cnt++ < 3);
-	if (rc)
-		goto Done;
-	rc = lcs_sleepon(read, lcs_calcsleeptime(drvr_globals, cmd_code));
-	if (rc == -ERETRY)
-		goto Done;
-	if ((readcmd = read->lancmd_reply_ptr) == NULL || rc == -EAGAIN) {
-		if (retry_cnt++ < 3) {
-			lcs_debug_event(2,
-					"retrying cmd_code=0x02 read_cmd=%p "
-					"rc=%d\n",
-					(int) cmd_code, readcmd, rc);
-			goto Retry;
-		} else {
-			lcs_debug_event(2,"lcs_lancmd retry count "
-					"exceeded giving up\n");
-			goto Done;
-		}
-	}
-	if (readcmd->cmd_code != cmd_code
-	    || (writecmd->sequence_no - readcmd->sequence_no) > 3) {
-		lcs_debug_event(1,
-				"readcmd=%p read_cmd_code=%02x write_cmd_code=%02x "
-				"read_seq=%04x write_seq=%04x\n",
-				readcmd, (int) readcmd->cmd_code,
-				(int) cmd_code, (int) readcmd->sequence_no,
-				(int) writecmd->sequence_no);
-		goto Fail;
-	} else {
-		switch (cmd_code) {
-		case lcs_lanstat:
-			if (readcmd->rel_adapter_no != rel_adapter_no) {
-				lcs_debug_event(1, "rel adapters differ\n");
-				goto Fail;
-			}
-			/* I got back a funny rel adapter no from stoplan 
-			 * so I'll assume it's broke */
-		case lcs_startlan:
-			if (readcmd->lan_type != writecmd->lan_type) {
-				lcs_debug_event(1,"lan types differ\n");
-				goto Fail;
-			}
-			if (readcmd->return_code != 0) {
-				lcs_debug_event(2,"readcmd_return_code=%02x\n",
-						(int) readcmd->return_code);
-				rc = -ENXIO;
-				goto Done;
-			}
-		case lcs_stoplan:
-			/* the stoplan primative should return the
-			 * adapter type */
-			/* it dosen't appar to though */
-		case lcs_startup:
-		case lcs_shutdown:
-#ifdef CONFIG_IP_MULTICAST
-		case lcs_setipm:
-		case lcs_delipm:
-		case lcs_qipassist:
-#endif
-			if (readcmd->return_code != 0)
-				goto Fail;
+	int rc;
+
+#ifdef CONFIG_NET_ETHERNET
+	card->lan_type = LCS_FRAME_TYPE_ENET;
+	rc = lcs_send_startlan(card, LCS_INITIATOR_TCPIP);
+	if (rc == 0)
+		return 0;
 
-		}
-	}
-Done:
-	lcs_debug_event(2, "lcs_lancmd cmd_code=%02x rc=%d reply_ptr=%p\n",
-			(int) cmd_code, rc, read->lancmd_reply_ptr);
-#if LCS_DEBUG
-	if (rc && read->lancmd_reply_ptr)
-		lcs_debug_display_read_buff("reply", read->lancmd_reply_ptr);
 #endif
-	drvr_globals->state = lcs_idle;
-	if (rc || (cmd_code != lcs_lanstat
-#ifdef CONFIG_IP_MULTICAST
-		   && cmd_code != lcs_qipassist
+#ifdef CONFIG_TR
+	card->lan_type = LCS_FRAME_TYPE_TR;
+	rc = lcs_send_startlan(card, LCS_INITIATOR_TCPIP);
+	if (rc == 0)
+		return 0;
 #endif
-	    ))
-		lcs_resume_read(read);
-	return rc;
-Fail:
-	rc = -EIO;
-	goto Done;
+#ifdef CONFIG_FDDI
+	card->lan_type = LCS_FRAME_TYPE_FDDI;
+	rc = lcs_send_startlan(card, LCS_INITIATOR_TCPIP);
+	if (rc == 0)
+		return 0;
+#endif
+	return -EIO;
 }
 
-#ifdef CONFIG_IP_MULTICAST
 static int
-lcs_print_ipassists(lcs_qipassist_ctlmsg * reply, char *name,
-		    char *ipassist_str, lcs_assists mask)
+lcs_startlan(struct lcs_card *card)
 {
-	lcs_good_news("%s: %s supported %s enabled %s\n",
-		      name, ipassist_str,
-		      reply->ip_assists_supported & mask ? "yes" : "no",
-		      reply->ip_assists_enabled & mask ? "yes" : "no");
-	return ((reply->ip_assists_supported & reply->
-		 ip_assists_enabled & mask) ? TRUE : FALSE);
+	int rc, i;
+
+	LCS_DBF_TEXT(2, trace, "startlan");
+	rc = 0;
+	if (card->portno != LCS_INVALID_PORT_NO) {
+		if (card->lan_type == LCS_FRAME_TYPE_AUTO)
+			rc = lcs_startlan_auto(card);
+		else
+			rc = lcs_send_startlan(card, LCS_INITIATOR_TCPIP);
+	} else {
+                for (i = 0; i <= card->max_port_no; i++) {
+                        card->portno = i;
+                        if (card->lan_type != LCS_FRAME_TYPE_AUTO)
+                                rc = lcs_send_startlan(card,
+                                                       LCS_INITIATOR_TCPIP);
+                        else
+                                /* autodetecting lan type */
+                                rc = lcs_startlan_auto(card);
+                        if (rc == 0)
+                                break;
+                }
+        }
+	if (rc == 0)
+		return lcs_send_lanstat(card);
+	return rc;
 }
 
+/**
+ * LCS detect function
+ * setup channels and make them I/O ready
+ */
 static int
-lcs_check_multicast_supported(lcs_drvr_globals * drvr_globals)
+lcs_detect(struct lcs_card *card)
 {
-	lcs_qipassist_ctlmsg *lcs_reply;
-	char *name = drvr_globals->dev->name;
-	int rc = FALSE;
-	if (lcs_lancmd(lcs_qipassist, drvr_globals->rel_adapter_no,
-		       drvr_globals LANCMD_DEFAULT_MCAST_PARMS) == 0) {
-		lcs_reply = (lcs_qipassist_ctlmsg *)
-		    drvr_globals->read->lancmd_reply_ptr;
-		if (lcs_reply) {
-			lcs_print_ipassists(lcs_reply, name, "ip v6",
-					    lcs_ip_v6_support);
-			rc = lcs_print_ipassists(lcs_reply, name, "multicast",
-						 lcs_multicast_support);
+	int rc;
+
+	LCS_DBF_TEXT(3, setup," lcsdetct");
+	/* start/reset card */
+	if (card->dev)
+		netif_stop_queue(card->dev);
+	card->write.state = CH_STATE_INIT;
+	card->read.state = CH_STATE_INIT;
+	rc = lcs_stop_channels(card);
+	if (rc == 0) {
+		rc = lcs_start_channels(card);
+		if (rc == 0) {
+			rc = lcs_send_startup(card, LCS_INITIATOR_TCPIP);
+			if (rc == 0)
+				rc = lcs_startlan(card);
 		}
-	} else
-		lcs_good_news("qipassist failed, ipassists assumed "
-			      "unsupported for %s\n",name);
-	lcs_resume_read(drvr_globals->read);
-	return (rc);
+	}
+	if (rc == 0) {
+		card->state = DEV_STATE_UP;
+	} else {
+		card->state = DEV_STATE_DOWN;
+		card->write.state = CH_STATE_INIT;
+		card->read.state =  CH_STATE_INIT;
+	}
+	return rc;
 }
-#endif
 
-/* 
- * Update network statistics from hardware.
+/**
+ * reset card
  */
 static int
-lcs_gethwinfo(struct net_device *dev)
+lcs_resetcard(struct lcs_card *card)
 {
-	lcs_drvr_globals *drvr_globals = ((lcs_drvr_globals *) dev->priv);
-	lcs_lanstat_reply *lcs_reply;
-	struct net_device_stats *stats;
-	int rc;
-	lcs_read_globals *read = drvr_globals->read;
+	int retries;
 
-	if ((rc = lcs_lancmd(lcs_lanstat,
-			     drvr_globals->rel_adapter_no,
-			     drvr_globals LANCMD_DEFAULT_MCAST_PARMS)) == 0) {
-
-		lcs_reply = (lcs_lanstat_reply *)
-		    read->lancmd_reply_ptr;
-		if (lcs_reply) {
-			stats = &drvr_globals->stats;
-			stats->rx_packets = lcs_reply->num_packets_rx_from_lan;
-			stats->rx_errors = lcs_reply->num_rx_errors_detected;
-			stats->rx_length_errors =
-			    lcs_reply->num_rx_packets_too_large;
-			stats->rx_missed_errors =
-			    lcs_reply->num_rx_discarded_nobuffs_avail;
-			stats->tx_packets = lcs_reply->num_packets_tx_on_lan;
-			stats->tx_errors = lcs_reply->num_tx_errors_detected;
-			stats->tx_aborted_errors =
-			    lcs_reply->num_tx_packets_disgarded;
+	LCS_DBF_TEXT(4, trace, "rescard");
+	for (retries = 0; retries < 10; retries++) {
+		if (lcs_detect(card) == 0) {
+			netif_wake_queue(card->dev);
+			card->state = DEV_STATE_UP;
+			PRINT_INFO("LCS device %s successfully restarted!\n",
+				   card->dev->name);
+			return 0;
 		}
+		schedule_timeout(3 * HZ);
 	}
-#if LCS_DEBUG
-	else
-		lcs_debug_event(2, "gethwinfo failed\n");
-#endif
-	lcs_resume_read(read);
-	return rc;
+	PRINT_ERR("Error in Reseting LCS card!\n");
+	return -EIO;
 }
 
-/*
- * Displays the mac address etc. on startup.
+/**
+ * LCS Stop card
  */
-static void
-lcs_displayinfo(struct net_device *dev)
+static int
+lcs_stopcard(struct lcs_card *card)
 {
-	lcs_drvr_globals *drvr_globals = ((lcs_drvr_globals *) dev->priv);
-	u8 *mac_address = dev->dev_addr;
-	lcs_read_globals *read = drvr_globals->read;
-	lcs_write_globals *write = drvr_globals->write;
-
-	lcs_good_news
-	    ("\nlcs: %s configured as follows read subchannel=%x "
-	     "write subchannel=%x\n"
-	     "read_devno=%04x write_devno=%04x\n"
-	     "hw_address=%02X:%02X:%02X:%02X:%02X:%02X rel_adapter_no=%d\n",
-	     dev->name, read->subchannel, write->subchannel, (int) read->devno,
-	     (int) write->devno, (int) mac_address[0], (int) mac_address[1],
-	     (int) mac_address[2], (int) mac_address[3], (int) mac_address[4],
-	     (int) mac_address[5], drvr_globals->rel_adapter_no);
-}
+	int rc;
 
-/* shutdown osa card */
+	LCS_DBF_TEXT(3, setup, "stopcard");
+	if (card->read.state != CH_STATE_STOPPED &&
+	    card->write.state != CH_STATE_STOPPED &&
+	    card->state == DEV_STATE_UP)
+		rc = lcs_send_stoplan(card,LCS_INITIATOR_TCPIP);
+	rc = lcs_send_shutdown(card);
+	rc = lcs_stop_channels(card);
+	card->state = DEV_STATE_DOWN;
+	return rc;
+}
 
+/**
+ * LGW initiated commands
+ */
 static int
-lcs_halt_channels(lcs_drvr_globals * drvr_globals, int delay)
+lcs_lgw_startlan_thread(void *data)
 {
-	int rc, rc2;
-	if (delay & 1) {
-/* [arnd] maybe better rethink/rewrite this whole function */
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(2);
-	}
-	rc = lcs_hsch(drvr_globals->read);
-	if (delay & 2) {
+	struct lcs_card *card;
 
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(2);
-	}
-	drvr_globals->read->chan_busy_state = chan_dead;
-	rc2 = lcs_hsch(drvr_globals->write);
-	if (delay & 4) {
+	card = (struct lcs_card *) data;
+	daemonize();
+	LCS_DBF_TEXT(4, trace, "lgwstpln");
+	if (card->dev)
+		netif_stop_queue(card->dev);
+	if (lcs_startlan(card) == 0) {
+		netif_wake_queue(card->dev);
+		card->state = DEV_STATE_UP;
+		PRINT_INFO("LCS Startlan for device %s succeeded!\n",
+			   card->dev->name);
 
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(2);
-	}
-	drvr_globals->write->chan_busy_state = chan_dead;
-	return (rc ? rc : rc2);
+	} else
+		PRINT_ERR("LCS Startlan for device %s failed!\n",
+			  card->dev->name);
+	return 0;
 }
 
+/**
+ * Send startup command initiated by Lan Gateway
+ */
 static int
-lcs_stopcard(lcs_drvr_globals * drvr_globals)
+lcs_lgw_startup_thread(void *data)
 {
-	int rc1, rc2, rc3;
+	int rc;
+
+	struct lcs_card *card;
 
-	rc1 = rc2 = rc3 = 0;
-	drvr_globals->up = FALSE;
-	lcs_debug_event(2, "lcs_stopcard called\n");
-	if (drvr_globals->state == lcs_interrupted)
-		drvr_globals->state = lcs_idle;
-	/* Make sure that we don't attempt to resume a channel */
-	/* that was halted or dead to avoid the -ENOTCONNECTED */
-	/* errors reported from Ingo on resume_IO */
-	if (drvr_globals->read->chan_busy_state != chan_dead &&
-	    drvr_globals->write->chan_busy_state != chan_dead) {
-		rc1 = lcs_lancmd(lcs_stoplan, drvr_globals->rel_adapter_no,
-				 drvr_globals LANCMD_DEFAULT_MCAST_PARMS);
-		/* We probably haven't got a good relative adapter no */
-		if (drvr_globals->rel_adapter_no != lcs_invalid_adapter_no)
-			rc2 = lcs_lancmd(lcs_shutdown, 0, drvr_globals
-					 LANCMD_DEFAULT_MCAST_PARMS);
+	card = (struct lcs_card *) data;
+	daemonize();
+	LCS_DBF_TEXT(4, trace, "lgwstpln");
+	if (card->dev)
+		netif_stop_queue(card->dev);
+	rc = lcs_send_startup(card, LCS_INITIATOR_LGW);
+	if (rc != 0) {
+		PRINT_ERR("Startup for LCS device %s initiated " \
+			  "by LGW failed!\nReseting card ...\n",
+			  card->dev->name);
+		/* do a card reset */
+		rc = lcs_resetcard(card);
+		if (rc == 0)
+			goto Done;
 	}
-	lcs_resetstate(drvr_globals);
-	rc3 = lcs_halt_channels(drvr_globals, 7);
-	lcs_resetstate(drvr_globals);
-	return (rc1 ? rc1 : (rc2 ? rc2 : rc3));
+	rc = lcs_startlan(card);
+	if (rc == 0) {
+		netif_wake_queue(card->dev);
+		card->state = DEV_STATE_UP;
+	}
+Done:
+	if (rc == 0)
+		PRINT_INFO("LCS Startup for device %s succeeded!\n",
+			   card->dev->name);
+	else
+		PRINT_ERR("LCS Startup for device %s failed!\n",
+			  card->dev->name);
+	return 0;
 }
 
-static void
-lcs_initwriteccws(lcs_write_globals * write)
-{
-	initccws(write->ccw, write->iobuff, LCS_NUM_TX_BUFFS, ccw_write, 0,
-		 CCW_FLAG_CC | CCW_FLAG_SLI | CCW_FLAG_SUSPEND);
-	write->prepare_idx = 0;
-	write->tx_idx = LCS_NUM_TX_BUFFS - 1;
-	write->resume_queued = FALSE;
-	write->bytes_still_being_txed = write->pkts_still_being_txed = 0;
-	write->adjusted_last_bytes_still_being_txed = 0;
-	write->last_resume_time = lcs_get_tod();
-	write->chan_busy_state = chan_starting_up;
-}
 
-static void
-lcs_startreadio(lcs_read_globals * read)
+/**
+ * send stoplan command initiated by Lan Gateway
+ */
+static int
+lcs_lgw_stoplan_thread(void *data)
 {
-	int cnt;
-	ccw1_t *ccws;
-	lcs_debug_event(0, "lcs_startreadio read_globals=%p\n", read);
-	ccws = read->ccw;
-	for (cnt = 0; cnt < LCS_NUM_RX_BUFFS; cnt++, ccws++) {
-		ccws->count = LCS_IOBUFFSIZE;
-		ccws->flags = CCW_FLAG_CC | CCW_FLAG_SLI |
-		    (cnt ==
-		     (LCS_NUM_RX_BUFFS - 1) ? CCW_FLAG_SUSPEND : CCW_FLAG_PCI)
-#if LCS_USE_IDALS
-		    | (ccws->flags & CCW_FLAG_IDA)
-#endif
-		    ;
-#if LCS_ZERO_COPY_READ
-		((lcs_header_type *) read->skb_buff[cnt]->data)->offset =
-		    LCS_ILLEGAL_OFFSET;
-#else
-		((lcs_header_type *) read->iobuff[cnt])->offset =
-		    LCS_ILLEGAL_OFFSET;
-#endif
-	}
-	read->lancmd_reply_ptr = NULL;
-	read->rx_idx = 0;
-	read->chan_busy_state = chan_starting_up;
-	lcs_doio(read, DOIO_DENY_PREFETCH | DOIO_ALLOW_SUSPEND
-		 /*|DOIO_REPORT_ALL */ );
+	struct lcs_card *card;
 
+	card = (struct lcs_card *) data;
+	daemonize();
+	LCS_DBF_TEXT(4, trace, "lgwstop");
+	if (card->dev)
+		netif_stop_queue(card->dev);
+	if (lcs_send_stoplan(card, LCS_INITIATOR_LGW) == 0)
+		PRINT_INFO("Stoplan for %s initiated by LGW succeeded!\n",
+			   card->dev->name);
+	else
+		PRINT_ERR("Stoplan %s initiated by LGW failed!\n",
+			  card->dev->name);
+	return 0;
 }
 
+/**
+ * Kernel Thread helper functions for LGW initiated commands
+ */
 static void
-lcs_startwriteio(lcs_write_globals * write)
+lcs_start_kernel_thread(struct lcs_card *card)
 {
-	lcs_debug_event(0, "lcs_startwriteio write_globals=%p\n", write);
-	lcs_initwriteccws(write);
-	lcs_doio(write,DOIO_DENY_PREFETCH | DOIO_ALLOW_SUSPEND 
-		 /* | DOIO_REPORT_ALL */
-		 );
+	LCS_DBF_TEXT(5, trace, "krnthrd");
+	if (test_and_clear_bit(0, &card->thread_mask))
+		kernel_thread(lcs_lgw_startup_thread, (void *) card, SIGCHLD);
+	if (test_and_clear_bit(1, &card->thread_mask))
+		kernel_thread(lcs_lgw_startlan_thread, (void *) card, SIGCHLD);
+	if (test_and_clear_bit(2, &card->thread_mask))
+		kernel_thread(lcs_lgw_stoplan_thread, (void *) card, SIGCHLD);
+	if (test_and_clear_bit(3, &card->thread_mask))
+		kernel_thread(lcs_fix_multicast_list, (void *) card, SIGCHLD);
 }
 
+/**
+ * Process control frames.
+ */
 static void
-lcs_restartreadio(lcs_drvr_globals * drvr_globals)
+lcs_get_control(struct lcs_card *card, struct lcs_cmd *cmd)
 {
-	lcs_debug_event(2, "lcs_restartreadio\n");
-	lcs_wakeup(drvr_globals->read, -EAGAIN);
-	lcs_startreadio(drvr_globals->read);
+	if (cmd->initiator == LCS_INITIATOR_LGW) {
+		switch(cmd->cmd_code) {
+		case LCS_CMD_STARTUP:
+			set_bit(0, &card->thread_mask);
+			schedule_work(&card->kernel_thread_starter);
+			break;
+		case LCS_CMD_STARTLAN:
+			set_bit(1, &card->thread_mask);
+			schedule_work(&card->kernel_thread_starter);
+			break;
+		case LCS_CMD_STOPLAN:
+			set_bit(2, &card->thread_mask);
+			schedule_work(&card->kernel_thread_starter);
+			break;
+		default:
+			PRINT_INFO("UNRECOGNIZED LGW COMMAND\n");
+			break;
+		}
+	} else
+		lcs_notify_lancmd_waiters(card, cmd);
 }
 
+/**
+ * Unpack network packet.
+ */
 static void
-lcs_queued_restartreadio(lcs_drvr_globals * drvr_globals)
+lcs_get_skb(struct lcs_card *card, char *skb_data, unsigned int skb_len)
 {
+	struct sk_buff *skb;
 
-	if (!lcs_drvr_globals_valid(drvr_globals))
-		goto Done2;
-	if (drvr_globals->state == lcs_idle
-	    || drvr_globals->state == lcs_halting_subchannels)
-		goto Done1;
-	lcs_restartreadio(drvr_globals);
-Done1:
-	lcs_usage_free_drvr_globals(drvr_globals);
-Done2:
-	MOD_DEC_USE_COUNT;
+	if (card->dev == NULL ||
+	    card->state != DEV_STATE_UP)
+		/* The card isn't up. Ignore the packet. */
+		return;
+
+	skb = dev_alloc_skb(skb_len);
+	if (skb == NULL) {
+		PRINT_ERR("LCS: alloc_skb failed for device=%s\n",
+			  card->dev->name);
+		card->stats.rx_dropped++;
+		return;
+	}
+	skb->dev = card->dev;
+	memcpy(skb_put(skb, skb_len), skb_data, skb_len);
+	skb->protocol =	card->lan_type_trans(skb, card->dev);
+	card->stats.rx_bytes += skb_len;
+	card->stats.rx_packets++;
+	netif_rx(skb);
 }
 
+/**
+ * LCS main routine to get packets and lancmd replies from the buffers
+ */
 static void
-lcs_restartwriteio(lcs_drvr_globals * drvr_globals)
+lcs_get_frames_cb(struct lcs_channel *channel, struct lcs_buffer *buffer)
 {
-	lcs_write_globals *write;
+	struct lcs_card *card;
+	struct lcs_header *lcs_hdr;
+	__u16 offset;
 
-	write = drvr_globals->write;
-	write->bytes_still_being_txed = 0;
-	drvr_globals->stats.tx_dropped += write->pkts_still_being_txed;
-	if (!use_hw_stats)
-		drvr_globals->stats.tx_errors += write->pkts_still_being_txed;
-	write->pkts_still_being_txed = 0;
-	switch (drvr_globals->state) {
-	case lcs_doing_io:
-		netif_wake_queue(drvr_globals->dev);
-		break;
-	case lcs_idle_requesting_channels_for_lancmds:
-	case lcs_requesting_channels_for_lancmds:
-	case lcs_got_write_channel_for_lancmds:
-		lcs_wakeup(write, 0);
-		break;
-	case lcs_doing_lancmds:
-		lcs_wakeup(write, -EAGAIN);
-		break;
-	default:
-		break;
+	LCS_DBF_TEXT(5, trace, "lcsgtpkt");
+	lcs_hdr = (struct lcs_header *) buffer->data;
+	if (lcs_hdr->offset == LCS_ILLEGAL_OFFSET) {
+		LCS_DBF_TEXT(4, trace, "-eiogpkt");
+		return;
+	}
+	card = (struct lcs_card *)
+		((char *) channel - offsetof(struct lcs_card, read));
+	offset = 0;
+	while (lcs_hdr->offset != 0) {
+		if (lcs_hdr->offset <= 0 ||
+		    lcs_hdr->offset > LCS_IOBUFFERSIZE ||
+		    lcs_hdr->offset < offset) {
+			/* Offset invalid. */
+			card->stats.rx_length_errors++;
+			card->stats.rx_errors++;
+			return;
+		}
+		/* What kind of frame is it? */
+		if (lcs_hdr->type == LCS_FRAME_TYPE_CONTROL)
+			/* Control frame. */
+			lcs_get_control(card, (struct lcs_cmd *) lcs_hdr);
+		else if (lcs_hdr->type == LCS_FRAME_TYPE_ENET ||
+			 lcs_hdr->type == LCS_FRAME_TYPE_TR ||
+			 lcs_hdr->type == LCS_FRAME_TYPE_FDDI)
+			/* Normal network packet. */
+			lcs_get_skb(card, (char *)(lcs_hdr + 1),
+				    lcs_hdr->offset - offset -
+				    sizeof(struct lcs_header));
+		else
+			/* Unknown frame type. */
+			; // FIXME: error message ?
+		/* Proceed to next frame. */
+		offset = lcs_hdr->offset;
+		lcs_hdr->offset = LCS_ILLEGAL_OFFSET;
+		lcs_hdr = (struct lcs_header *) (buffer->data + offset);
 	}
-	lcs_startwriteio(write);
+	/* The buffer is now empty. Make it ready again. */
+	lcs_ready_buffer(&card->read, buffer);
 }
 
-static void
-lcs_queued_restartwriteio(lcs_drvr_globals * drvr_globals)
+/**
+ * get network statistics for ifconfig and other user programs
+ */
+struct net_device_stats *
+lcs_getstats(struct net_device *dev)
 {
-	if (!lcs_drvr_globals_valid(drvr_globals))
-		goto Done2;
-	if (drvr_globals->state == lcs_idle ||
-	    drvr_globals->state == lcs_halting_subchannels)
-		goto Done1;
-	lcs_restartwriteio(drvr_globals);
-Done1:
-	lcs_usage_free_drvr_globals(drvr_globals);
-Done2:
-	MOD_DEC_USE_COUNT;
-}
+	struct lcs_card *card;
 
-static void
-lcs_startallio(lcs_drvr_globals * drvr_globals)
-{
-	if (drvr_globals->dev)
-		netif_stop_queue(drvr_globals->dev);
-	drvr_globals->state = lcs_idle_requesting_channels_for_lancmds;
-	lcs_startreadio(drvr_globals->read);
-	lcs_initqueue(drvr_globals->write);
-	lcs_startwriteio(drvr_globals->write);
-	lcs_sleepon(drvr_globals->write, 0);
-	drvr_globals->state = lcs_doing_lancmds;
+	LCS_DBF_TEXT(4, trace, "netstats");
+	card = (struct lcs_card *) dev->priv;
+	return &card->stats;
 }
 
-/*
- * The osa detection/startup routine called from lcs_probe on
- * bootup & lcs_open this is called after the irq's are allocated &
- * successful sensing of the read & write subchannels.
+/**
+ * stop lcs device
+ * This function will be called by user doing ifconfig xxx down
  */
-
-static int
-lcs_detect(lcs_drvr_globals * drvr_globals, s16 forced_port_no, u8 hint_port_no,
-	   u8 max_port_no, lcs_frame_type frame_type, u8 * mac_address)
+int
+lcs_stop_device(struct net_device *dev)
 {
-	int rc = 0, successful_startup = FALSE;
-	int rel_adapter_no, rel_adapter_idx;
-	lcs_read_globals *read;
-	lcs_write_globals *write;
-	lcs_lanstat_reply *lcs_reply;
-
-	read = drvr_globals->read;
-	write = drvr_globals->write;
-#ifdef CONFIG_IP_MULTICAST
-	spin_lock_init(&drvr_globals->ipm_lock);
-#endif
-	lcs_debug_event(1, "Entering detect read subchannel=%X\n",
-			(unsigned) drvr_globals->read->subchannel);
-	if (drvr_globals->dev)
-		netif_stop_queue(drvr_globals->dev);
-	do {
-		lcs_debug_event(1, "lcs_detect retry_cnt=%d\n",
-				drvr_globals->retry_cnt);
-		if (atomic_read(&drvr_globals->retry_cnt) >= 0) {
-			if (atomic_read(&drvr_globals->retry_cnt) > 0)
-				lcs_resetstate(drvr_globals);
-			if (atomic_read(&drvr_globals->retry_cnt) > 1
-			    && rc != -ERETRY) {
-				/* Time to change tactics */
-				rc = lcs_stopcard(drvr_globals);
-			} else
-				rc = lcs_halt_channels(drvr_globals,
-				       (atomic_read(&drvr_globals->retry_cnt)
-					==0) ? 0 : 7);
-			if (rc)
-				continue;
-			lcs_startallio(drvr_globals);
-			if ((rc =
-			     lcs_lancmd(lcs_startup, 0,
-					drvr_globals
-					LANCMD_DEFAULT_MCAST_PARMS)))
-				continue;
-			else
-				successful_startup = TRUE;
-		} else if ((rc = lcs_lgw_common(drvr_globals, lcs_startup)))
-			continue;
-		else
-			successful_startup = TRUE;
-		for (rel_adapter_idx = 0; 
-		     rel_adapter_idx <= max_port_no &&
-		     (rc == -ENXIO || rel_adapter_idx == 0);
-		     rel_adapter_idx++) {
-			if (forced_port_no != -1) {
-				if (rel_adapter_idx > 0)
-					break;
-				rel_adapter_no = forced_port_no;
-			} else {
-				rel_adapter_no =
-				    (rel_adapter_idx ==
-				     0 ? hint_port_no : (rel_adapter_idx ==
-							 hint_port_no ? 0 :
-							 rel_adapter_idx));
-			}
-			lcs_debug_event(2,
-					"Trying startlan rel adapter no %u\n",
-					(unsigned) rel_adapter_no);
-			rc = -1;
-			if (frame_type == lcs_autodetect_type) {
-#ifdef CONFIG_NET_ETHERNET
-				drvr_globals->lan_type = lcs_enet_type;
-				rc = lcs_lancmd(lcs_startlan, rel_adapter_no,
-						drvr_globals
-						LANCMD_DEFAULT_MCAST_PARMS);
-				if (rc == 0)
-					goto lcs_good_detect;
-#endif
-#ifdef CONFIG_TR
-				drvr_globals->lan_type = lcs_token_ring_type;
-				rc = lcs_lancmd(lcs_startlan, rel_adapter_no,
-						drvr_globals
-						LANCMD_DEFAULT_MCAST_PARMS);
-				if (rc == 0)
-					goto lcs_good_detect;
-#endif
-#ifdef CONFIG_FDDI
-				drvr_globals->lan_type = lcs_fddi_type;
-				rc = lcs_lancmd(lcs_startlan, rel_adapter_no,
-						drvr_globals
-						LANCMD_DEFAULT_MCAST_PARMS);
-#endif
-			} else {
-				drvr_globals->lan_type = frame_type;
-				rc = lcs_lancmd(lcs_startlan, rel_adapter_no,
-						drvr_globals
-						LANCMD_DEFAULT_MCAST_PARMS);
-			}
-lcs_good_detect:
-			if (rc == 0) {
-				lcs_debug_event(2,"Found relative adapter "
-						"number %d\n",
-						rel_adapter_no);
-				drvr_globals->rel_adapter_no = rel_adapter_no;
-lcs_do_lanstat:
-				rc = lcs_lancmd(lcs_lanstat,
-						drvr_globals->rel_adapter_no,
-						drvr_globals
-						LANCMD_DEFAULT_MCAST_PARMS);
-				if (!rc) {
-					lcs_reply = (lcs_lanstat_reply *)
-					    drvr_globals->read->
-					    lancmd_reply_ptr;
-					if (lcs_reply == NULL)
-						goto lcs_do_lanstat;
-					memcpy(mac_address,
-					       lcs_reply->mac_address,
-					       LCS_ADDR_LEN);
-					lcs_resume_read(drvr_globals->read);
-					drvr_globals->up = TRUE;
-					return (0);
-				}
-			}
-		}
+	struct lcs_card *card;
+	int rc;
 
-	} while ((rc == -EAGAIN || rc == -ETIMEDOUT || rc == -ERETRY)
-		 && atomic_inc_return(&drvr_globals->retry_cnt) < 5);
-	if (successful_startup && rc)
-		lcs_bad_news
-		    ("A partially successful startup read_devno=%04x "
-		     "write_devno=%4x was detected rc=%d\n"
-		     "please check your configuration parameters,cables "
-		     "& connection to the network.\n",
-		     drvr_globals->read->devno,drvr_globals->write->devno,rc);
-	return (rc == EINTR ? -EINTR : -ENODEV);
+	LCS_DBF_TEXT(2, trace, "stopdev");
+	card   = (struct lcs_card *) dev->priv;
+	netif_stop_queue(dev);
+	// FIXME: really free the net_device here ?!?
+	kfree(card->dev);
+	rc = lcs_stopcard(card);
+	if (rc)
+		PRINT_ERR("Try it again!\n ");
+	MOD_DEC_USE_COUNT;
+	return rc;
 }
 
-/* Called by user doing ifconfig <network_device e.g. tr0> up */
-static int
-lcs_open(struct net_device *dev)
+/**
+ * start lcs device and make it runnable
+ * This function will be called by user doing ifconfig xxx up
+ */
+int
+lcs_open_device(struct net_device *dev)
 {
-	int rc = 0;
-	lcs_drvr_globals *drvr_globals;
-	lcs_read_globals *read;
-	lcs_write_globals *write;
+	struct lcs_card *card;
+	int rc;
+
+	LCS_DBF_TEXT(2, trace, "opendev");
+	card = (struct lcs_card *) dev->priv;
+	/* initialize statistics */
+	rc = lcs_detect(card);
+	if (rc) {
+		PRINT_ERR("LCS:Error in opening device!\n");
 
-#if LCS_DEBUG_RESUME
-	lcs_read_resume_cnt = lcs_write_resume_cnt = 0;
-#endif
-	drvr_globals = ((lcs_drvr_globals *) dev->priv);
-	read = drvr_globals->read;
-	write = drvr_globals->write;
-	drvr_globals->state = lcs_idle;
-	if (use_hw_stats == FALSE)
-		memset(&drvr_globals->stats, 0,
-		       sizeof (struct net_device_stats));
-	atomic_set(&drvr_globals->retry_cnt, 0);
-	if ((rc = lcs_detect(drvr_globals, drvr_globals->rel_adapter_no, 0, 0,
-			     drvr_globals->lan_type, dev->dev_addr))) {
-		lcs_debug_event(2, "Opening %s failed errcode=%d.\n",
-				dev->name,rc);
-		lcs_resetstate(drvr_globals);
 	} else {
 		MOD_INC_USE_COUNT;
-		lcs_start_doing_io(drvr_globals);
-		lcs_debug_event(2, "Successfully opened %s\n", dev->name);
-#if LCS_DEBUG && !LCS_PRINTK_DEBUG
-		/* When debugging we are usually only intrested till
-		 * the device is open. */
-		if (lcs_id && lcs_id->level != DEBUG_MAX_LEVEL)
-			debug_set_level(lcs_id, 0);
-#endif
+		netif_wake_queue(dev);
+		card->state = DEV_STATE_UP;
 	}
 	return rc;
 }
 
-/* Called by user doing ifconfig <network_device e.g. tr0> down */
-static int
-lcs_close(struct net_device *dev)
+/**
+ * show function for portno called by cat or similar things
+ */
+static ssize_t
+lcs_portno_show (struct device *dev, char *buf, size_t count,
+		 loff_t off)
 {
-	lcs_debug_event(2, "lcs_close called\n");
-	netif_stop_queue(dev);
-	lcs_stopcard((lcs_drvr_globals *) dev->priv);
-	MOD_DEC_USE_COUNT;
-	return (0);
-}
+        struct lcs_card *card;
 
-static int
-lcs_txpacket(struct sk_buff *skb, struct net_device *dev)
-{
-	lcs_drvr_globals *drvr_globals;
-	lcs_write_globals *write;
-	u16 pkt_len;
-	lcs_header_type *tx_lcs_header_ptr;
-	uint64_t tod, delta_tx;
-	struct net_device_stats *stats;
-
-	lcs_debug_event(2, "lcs_txpacket\n");
-	if (dev == NULL || dev->priv == NULL) {
-		lcs_debug_event(1, "lcs txpacket detected sick code\n");
-		return -EINVAL;
-	}
-	drvr_globals = ((lcs_drvr_globals *) dev->priv);
-	write = drvr_globals->write;
-	tod = lcs_get_tod();
-	delta_tx = tod - write->last_lcs_txpacket_time;
-	write->last_lcs_txpacket_time = tod;
-	stats = &drvr_globals->stats;
-	if (write->chan_busy_state != chan_busy &&
-	    write->chan_busy_state != chan_idle) {
-		dst_link_failure(skb);
-		dev_kfree_skb(skb);
-		stats->tx_dropped++;
-		if (!use_hw_stats) {
-			stats->tx_errors++;
-			stats->tx_carrier_errors++;
-		}
-		return (0);
-	}
-	if (netif_queue_stopped(dev)) {
-		lcs_debug_event(1, "lcs_txpacket netif_is_busy dev=%p\n", dev);
+	card = (struct lcs_card *)dev->driver_data;
 
-		stats->tx_dropped++;
-		return -EBUSY;
-	}
-	if (!skb) {
-		lcs_debug_event(1, "lcs_txpacket skb=NULL dev=%p\n", dev);
-		stats->tx_dropped++;
-		if (!use_hw_stats)
-			stats->tx_errors++;
-		return -EIO;
-	}
-	lcs_debug_event(2, "skb_len %d\n", skb->len);
-	pkt_len = skb->len;
-#if 0
-	/* This apparently can be omitted & saves us a lot of hassle */
-	pkt_len = (ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN);
-#endif
-	dev->trans_start = jiffies;
-	lcs_chan_lock(write);
-	if ((tx_lcs_header_ptr = lcs_getfreetxbuff(write,
-						   drvr_globals->lan_type,
-						   drvr_globals->rel_adapter_no,
-						   pkt_len)) == NULL) {
-		netif_stop_queue(dev);
-		stats->tx_dropped++;
-		lcs_debug_event(1,"lcs_txpacket no tx buffers "
-				"available dev=%p\n",dev);
-		lcs_resume_write(write);
-		lcs_chan_unlock(write);
-		return -EBUSY;
-	}
-	write->bytes_still_being_txed += pkt_len;
-	write->pkts_still_being_txed++;
-	memcpy(++tx_lcs_header_ptr, skb->data, pkt_len);
-	dev_kfree_skb(skb);
+        if (off || !card)
+                return 0;
 
-	if (lcs_should_queue_write(write, tod)) {
-		lcs_queue_write_if_necessary(write);
-	} else {
-		lcs_resume_write(write);
-	}
-	lcs_chan_unlock(write);
-	return (0);
+        return snprintf(buf, count, "%d\n", card->portno);
 }
 
-/*
- * Used by ifconfig & the proc filesystem to receive network statistics
+/**
+ * store the value which is piped to file portno
  */
-static struct net_device_stats *
-lcs_getstats(struct net_device *dev)
+static ssize_t
+lcs_portno_store (struct device *dev, const char *buf, size_t count,
+		  loff_t off)
 {
-	lcs_drvr_globals *drvr_globals = (lcs_drvr_globals *) dev->priv;
-	lcs_debug_event(2, "lcs_enet_stats\n");
+        struct lcs_card *card;
+        int value;
 
-	if (dev == NULL || dev->priv == NULL)
-		return NULL;	/* shouldn't happen */
-	if (use_hw_stats) {
-		if (drvr_globals->doing_lanstat)
-#warning FIXME: [kj] Using sleep_on derivative, is racy. consider using wait_event instead
-			interruptible_sleep_on(&drvr_globals->lanstat_wait);
-		else {
-			if (drvr_globals->state == lcs_doing_io) {
-				drvr_globals->doing_lanstat = TRUE;
-				lcs_gethwinfo(dev);
-				drvr_globals->doing_lanstat = FALSE;
-				netif_wake_queue(dev);
-				/* Gracefully start the lan again */
-				drvr_globals->state = lcs_doing_io;
-				/* Wake up processes awaiting
-				 * lanstat results */
-				wake_up_interruptible(&drvr_globals->
-						      lanstat_wait);
-			}
-		}
-	}
-	return &((lcs_drvr_globals *) dev->priv)->stats;
+	card = (struct lcs_card *)dev->driver_data;
 
-}
+        if (off || !card)
+                return 0;
 
-#if !LCS_CHANDEV
-/*
- * Used to setup kernel parameters for the osa card
- * read the printk's in the function for a description of how it
- * should be called.
- */
-static __inline__ lcs_model_info *
-lcs_get_model_info_by_idx(int idx)
-{
-	return (idx < LCS_CURR_NUM_MODELS ? &lcs_models[idx] :
-		(lcs_model_info *) & additional_model_info
-		[(idx - LCS_CURR_NUM_MODELS) << 1]);
-}
-static void
-lcs_display_conf(void)
-{
-	int cu_idx;
-	lcs_model_info *model_info;
+        sscanf(buf, "%u", &value);
+        /* TODO: sanity checks */
+        card->portno = value;
+
+        return count;
 
-	lcs_good_news("\nlcs configured to use %s statistics,\n"
-		      "ip checksumming of received packets is %s.\n"
-		      "autodetection is %s ignore sense is %s.\n",
-		      (use_hw_stats ? "hw" : "sw"),
-		      (checksum_received_ip_pkts ? "on" : "off"),
-		      (noauto ? "off" : "on"), (ignore_sense ? "on" : "off"));
-	lcs_good_news("configured to detect\n");
-	for (cu_idx = 0; cu_idx < LCS_MAX_NUM_MODELS; cu_idx++) {
-		model_info = lcs_get_model_info_by_idx(cu_idx);
-		if ((model_info->max_rel_adapter_no == 0))
-			break;
-		lcs_good_news("cu_model 0x%02X,%d rel_adapter(s)\n",
-			      model_info->cu_model,
-			      model_info->max_rel_adapter_no);
-	}
 }
 
-MODULE_AUTHOR
-("(C) 1999 IBM Corp. by DJ Barrow <djbarrow@de.ibm.com,barrow_dj@yahoo.com>");
-MODULE_DESCRIPTION("Linux for S/390 Lan Channel Station Network Driver");
-MODULE_LICENSE("GPL");
+static DEVICE_ATTR(portno, 0644, lcs_portno_show, lcs_portno_store);
 
-#ifdef MODULE
-MODULE_PARM(use_hw_stats, "i");
-MODULE_PARM_DESC(use_hw_stats,
-		 "Get network stats from LANSTAT lcs primitive as opposed to "
-		 "doing it in software\n"
-		 "this isn't used by MVS not recommended "
-		 "& dosen't appear to work usually\n");
-MODULE_PARM(checksum_received_ip_pkts, "i");
-MODULE_PARM_DESC(checksum_received_ip_pkts,
-		 "Do ip checksumming on inbound packets");
-
-MODULE_PARM(additional_model_info, "0-" LCS_ADDITIONAL_MODELS_X2_STR "i");
-MODULE_PARM_DESC(additional_model_info,
-		 "This is made up of sets of model/max rel adapter no pairs\n"
-		 "e.g. insmod additional_model_info=0x70,3 will look for "
-		 "2 ports on a model 0x70.\n");
-MODULE_PARM(devno_portno_pairs, "0-" LCS_MAX_FORCED_DEVNOS_X2_STR "i");
-MODULE_PARM_DESC(devno_portno_pairs, "devno,rel_adapter_no pairs\n"
-		 "rel adapter no of -1 indicates don't use this adapter.");
-MODULE_PARM(noauto, "i");
-MODULE_PARM_DESC(noauto,
-		 "set this equal to 1 if you want autodetection off, "
-		 "this means you have\n"
-		 "explicitly configure LCS devices with the "
-		 "devno_portno_pairs module parameter\n.");
-MODULE_PARM(ignore_sense, "i");
-MODULE_PARM_DESC(ignore_sense,
-		 "set this to 1 if you wish to ignore sense information "
-		 "from the device layer for\n"
-		 "non auto detected devices.\n");
-#else
-
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-static int __init
-lcs_setup_models(char *str)
-#else
-void __init
-lcs_setup_models(char *str, int *ints)
-#endif
+/**
+ * lcs_probe_device is called on establishing a new ccwgroup_device.
+ */
+int
+lcs_probe_device(struct ccwgroup_device *ccwgdev)
 {
-	int max_parms = LCS_MAX_NUM_PARMS - (LCS_CURR_NUM_MODELS << 1);
-	int num_new_models;
-#if  LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-	int ints[(LCS_ADDITIONAL_MODELS << 1) + 1];
-	get_options(str, (LCS_ADDITIONAL_MODELS << 1), ints);
-#endif
-	num_new_models = (ints[0] - 2);
-	if (num_new_models < 0)
-		num_new_models = 0;
-	else if (num_new_models & 1)
-		num_new_models = -1;
-	else
-		num_new_models >>= 1;
-	if ((ints[0] >= 1 && ints[0] <= max_parms) && num_new_models >= 0) {
-		use_hw_stats = ints[1];
-		if (ints[0] >= 2)
-			checksum_received_ip_pkts = ints[2];
-		if (num_new_models) {
-			memcpy(&additional_model_info[0], &ints[3],
-			       num_new_models * sizeof (lcs_model_info));
-		}
-		lcs_display_conf();
-	} else {
-		lcs_bad_news("lcs_setup: incorrect number of arguments\n");
-		printk("Usage: lcs=hw-stats,ip-checksumming,additional "
-		       "cu model/max rel adapter no. pairs. \n");
-		printk("  The driver now auto detects how the card is "
-		         "configured.\n");
-		printk("  e.g lcs=1,1,0x60,2\n");
-		printk("  Will collect network stats from LANSTAT lcs "
-		         "primitive as opposed\n");
-		printk("  to doing it in software for ifconfig (this isn't "
-		         "used by MVS & doesn't\n");
-		printk("  to be widely supported, ip checksum received "
-		         "packets\n");
-		printk("  and detect 0x3088 model 0x60 devices\n");
-		printk("  will look for 2 ports per card associated with "
-		         "this model.\n");
-		printk("  The default is to use sw stats, with ip "
-		         "checksumming off,\n");
-		printk("  this improves performance, network hw uses "
-		         "a crc32\n");
-		printk("  ( crc64 for fddi ) which should be adequete to "
-		         "gaurantee\n");
-		printk("  integrity for normal use\n");
-		printk("  however, financial institutions etc. may like "
-		         "the additional\n");
-		printk("  security of ip checksumming.\n");
-	}
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-	return (1);
-#endif
-}
+	struct lcs_card *card;
+	int ret;
 
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-static int __init
-lcs_setup_devnos(char *str)
-#else
-void __init
-lcs_setup_devnos(char *str, int *ints)
-#endif
-{
-	int fixed_devnos;
-#if  LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-	int ints[(LCS_MAX_FORCED_DEVNOS << 1) + 1];
-	get_options(str, (LCS_MAX_FORCED_DEVNOS << 1), ints);
-#endif
-	fixed_devnos = ints[0];
-	if ((fixed_devnos & 1) == 0 && fixed_devnos > 0) {
-		memcpy(devno_portno_pairs, &ints[1],
-		       sizeof (int) * fixed_devnos);
-	} else {
-		lcs_bad_news("lcs_setup: incorrect number of arguments\n");
-		printk("usage lcs_devno=devno,rel_adapter_no pairs\n");
-		printk
-		    ("rel adapter no of -1 indicates don't use this adapter.\n");
-	}
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-	return (1);
-#endif
-}
+	if (!get_device(&ccwgdev->dev))
+		return -ENODEV;
 
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-static int __init
-lcs_noauto(char *str)
-#else
-void __init
-lcs_noauto(char *str, int *ints)
-#endif
-{
-	noauto = 1;
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-	return (1);
-#endif
+	LCS_DBF_TEXT(3, setup, "add_dev");
+        card = lcs_alloc_card();
+        if (!card) {
+                PRINT_ERR("Allocation of lcs card failed\n");
+		put_device(&ccwgdev->dev);
+                return -ENOMEM;
+        }
+	ret = device_create_file(&ccwgdev->dev, &dev_attr_portno);
+	if (ret) {
+                PRINT_ERR("Creating attributes failed");
+		lcs_free_card(card);
+		put_device(&ccwgdev->dev);
+		return ret;
+        }
+	ccwgdev->dev.driver_data = card;
+	snprintf(ccwgdev->dev.name, DEVICE_NAME_SIZE, "%s",
+		 cu3088_type[ccwgdev->cdev[0]->id.driver_info]);
+	ccwgdev->cdev[0]->dev.driver_data = card;
+	ccwgdev->cdev[0]->handler = lcs_irq;
+	ccwgdev->cdev[1]->dev.driver_data = card;
+	ccwgdev->cdev[1]->handler = lcs_irq;
+        return 0;
 }
 
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-static int __init
-lcs_ignore_sense(char *str)
-#else
-void __init
-lcs_ignore_sense(char *str, int *ints)
-#endif
+/**
+ * lcs_new_device will be called by setting the group device online.
+ */
+int
+lcs_new_device(struct ccwgroup_device *ccwgdev)
 {
-	ignore_sense = 1;
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-	return (1);
-#endif
-}
+	struct  lcs_card *card;
+	struct net_device *dev;
+	int rc;
 
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-__setup("lcs_devno=", lcs_setup_devnos);
-__setup("lcs=", lcs_setup_models);
-__setup("lcs_noauto", lcs_noauto);
-__setup("lcs_ignore_sense", lcs_ignore_sense);
-#endif
-#endif
+	card = (struct lcs_card *)ccwgdev->dev.driver_data;
+	if (!card)
+		return -ENODEV;
 
-static lcs_inline int
-lcs_model_supported(s390_dev_info_t * dev_info_ptr, int *forced_rel_adapter_no)
-{
-	int cu_idx, dev_port_idx;
-	lcs_model_info *model_info;
-	lcs_dev_portno_pair *dev_portno;
-
-	*forced_rel_adapter_no = -1;
-	for (dev_port_idx = 0; dev_port_idx < LCS_MAX_FORCED_DEVNOS;
-	     dev_port_idx++) {
-		dev_portno = &lcs_dev_portno[dev_port_idx];
-		if (dev_portno->portno == -2)
-			break;
-		/*
-		   Check are we dealing with the device passed in as
-		   a parameter.
-		 */
-		if ((dev_portno->devno & 0xfffe) ==
-		    (dev_info_ptr->devno & 0xfffe)) {
-			/* portno=-1 we want to ignore this device */
-			if (dev_portno->portno == -1)
-				return (-1);
-			else {
-				*forced_rel_adapter_no = dev_portno->portno;
-				break;
-			}
-		}
-	}
-	if (noauto && *forced_rel_adapter_no == -1)
-		return (-1);
-	if (ignore_sense)
-		return (*forced_rel_adapter_no);
-	if (dev_info_ptr->sid_data.cu_type != LCS_CUTYPE)
-		return (-1);
-	for (cu_idx = 0; cu_idx < LCS_MAX_NUM_MODELS; cu_idx++) {
-		model_info = lcs_get_model_info_by_idx(cu_idx);
-		if (model_info->max_rel_adapter_no == 0)
-			break;
-		if (model_info->cu_model == dev_info_ptr->sid_data.cu_model) {
-			if (*forced_rel_adapter_no == -1)
-				return (model_info->max_rel_adapter_no);
-			else
-				return (*forced_rel_adapter_no);
-		}
-	}
-	return (-1);
-}
+	card->read.ccwdev  = ccwgdev->cdev[0];
+	card->write.ccwdev = ccwgdev->cdev[1];
 
-#endif				/* LCS_CHANDEV */
+	ccw_device_set_online(card->read.ccwdev);
+	ccw_device_set_online(card->write.ccwdev);
 
-#if !LCS_CHANDEV
-void
-lcs_unregister(struct net_device *dev, u8 lan_type)
-{
-	if (dev) {
-		switch (lan_type) {
-#ifdef CONFIG_FDDI
-		case lcs_fddi_type:
-			unregister_netdev(dev);
-			break;
-#endif
+	LCS_DBF_TEXT(3, setup, "lcsnewdv");
+	rc = lcs_setup_card(card);
+	if (rc) {
+		LCS_DBF_TEXT(3, setup, "errinit");
+		PRINT_ERR("LCS card Initialization failed\n");
+		lcs_free_card(card);
+		return rc;
+	}
+
+	rc = lcs_detect(card);
+	if (rc) {
+		lcs_stopcard(card);
+		lcs_cleanup_card(card);
+		lcs_free_card(card);
+		return -ENODEV;
+	}
+	switch (card->lan_type) {
 #ifdef CONFIG_NET_ETHERNET
-		case lcs_enet_type:
-			unregister_netdev(dev);
-			break;
+	case LCS_FRAME_TYPE_ENET:
+		card->lan_type_trans = eth_type_trans;
+		dev = init_etherdev(NULL,0);
+		break;
 #endif
 #ifdef CONFIG_TR
-		case lcs_token_ring_type:
-			unregister_trdev(dev);
-			break;
+	case LCS_FRAME_TYPE_TR:
+		card->lan_type_trans = tr_type_trans;
+		dev = init_trdev(NULL,0);
+		break;
 #endif
-		default:
-			lcs_bad_news
-			    ("lcs_unregister attempt to unregister %p "
-			     "unknown device type\n",
-			     dev);
-			return;
-		}
-
-	}
-}
+#ifdef CONFIG_FDDI
+	case LCS_FRAME_TYPE_FDDI:
+		card->lan_type_trans = fddi_type_trans;
+		dev = init_fddidev(NULL,0);
+		break;
 #endif
+	default:
+		LCS_DBF_TEXT(3, setup, "errinit");
+		PRINT_ERR("LCS: Initialization failed\n");
+		PRINT_ERR("LCS: No device found!\n");
+		lcs_cleanup_channel(&card->read);
+		lcs_cleanup_channel(&card->write);
+		lcs_free_card(card);
+		return -ENODEV;
+	}
+	memcpy(dev->dev_addr, card->mac, LCS_MAC_LENGTH);
+	card->dev = dev;
+	dev->priv = card;
+	dev->open = lcs_open_device;
+	dev->stop = lcs_stop_device;
+	dev->hard_start_xmit = lcs_start_xmit;
 #ifdef CONFIG_IP_MULTICAST
-static int
-lcs_fix_multicast_list(lcs_drvr_globals * drvr_globals)
-{
-	lcs_ipm_list *curr_lmem;
-	lcs_state oldstate;
-
-	lcs_daemonize("lcs_fix_multi", 0, TRUE);
-	if (!lcs_drvr_globals_valid(drvr_globals))
-		goto Done2;
-	if (drvr_globals->up == FALSE)
-		goto Done1;
-	oldstate = drvr_globals->state;
-	spin_lock(&drvr_globals->ipm_lock);
-	for (curr_lmem = drvr_globals->ipm_list; curr_lmem;
-	     curr_lmem = curr_lmem->next) {
-		switch (curr_lmem->ipm_state) {
-		case ipm_set_required:
-			spin_unlock(&drvr_globals->ipm_lock);
-			if (lcs_lancmd
-			    (lcs_setipm, drvr_globals->rel_adapter_no,
-			     drvr_globals, 1, &curr_lmem->ipm)) {
-				lcs_good_news("lcs_fix_multicast_list "
-					      "failed to add multicast "
-					      "entry %x multicast address "
-					      "table possibly full.\n",
-					      (u32) curr_lmem->ipm.ip_addr);
-			} else
-				curr_lmem->ipm_state = ipm_on_card;
-			spin_lock(&drvr_globals->ipm_lock);
-			break;
-		case ipm_delete_required:
-			spin_unlock(&drvr_globals->ipm_lock);
-			lcs_lancmd(lcs_delipm, drvr_globals->rel_adapter_no,
-				   drvr_globals, 1, &curr_lmem->ipm);
-			spin_lock(&drvr_globals->ipm_lock);
-			if (remove_from_list((list **)&drvr_globals->ipm_list,
-					     (list *)curr_lmem))
-				kfree(curr_lmem);
-			else
-				lcs_bad_news("lcs_fix_multicast_list "
-					     "detected nonexistant entry"
-					     " ipm_list=%p member %p\n",
-					     drvr_globals->ipm_list,curr_lmem);
-			break;
-		case ipm_on_card:
-			break;
-		}
-	}
-	spin_unlock(&drvr_globals->ipm_lock);
-	drvr_globals->state = oldstate;
-	if (oldstate == lcs_doing_io && drvr_globals->dev)
-		netif_wake_queue(drvr_globals->dev);
-Done1:
-	atomic_set(&drvr_globals->kernel_thread_lock, 1);
-	lcs_usage_free_drvr_globals(drvr_globals);
-Done2:
-	MOD_DEC_USE_COUNT;
-	return (0);
-}
-
-static void
-lcs_get_mac_for_ipm(__u32 ipm, char *mac, struct net_device *dev)
-{
-#ifdef CONFIG_TR
-	if (dev->type == ARPHRD_IEEE802_TR)
-		ip_tr_mc_map(ipm, mac);
-	else
-#endif
-#if defined(CONFIG_NET_ETHERNET) || defined (CONFIG_FDDI)
-		ip_eth_mc_map(ipm, mac);
+	if (lcs_check_multicast_support(card))
+		dev->set_multicast_list = lcs_set_multicast_list;
 #endif
+	dev->get_stats = lcs_getstats;
+	netif_stop_queue(dev);
+	lcs_stopcard(card);
+	return 0;
 }
 
-/*
-  Owing to a quirk in the osa microcode it is incompatible with its API's 
-  & we can only add or delete a single ipm entry at a time.
-  We are also called with the spin_lock_bh held meaning we in_interrupt is true
-  to add & delete multicast entries to get around this we indirectly start
-  a kernel thread which executes the io commands necessary at a later
-  time.
-  We also need ip addresses for the setipm & delipm primatives
-  to do this we use lcs_get_mac_for_ipm.
-  N.B. We even need to kmalloc GFP_ATOMIC here
-
+/**
+ * lcs_shutdown_device, called when setting the group device offline.
  */
-static void
-lcs_set_multicast_list(struct net_device *dev)
+int
+lcs_shutdown_device(struct ccwgroup_device *ccwgdev)
 {
-	lcs_drvr_globals *drvr_globals;
-	struct ip_mc_list *im4;
-	struct in_device *in4_dev;
-	int addr_in_list;
-
-#if 0				/* LCS doesn't do IPV6 yet. */
-	struct ifmcaddr6 *im6;
-	struct inet6_dev *in6_dev;
-#endif
-	char buf[MAX_ADDR_LEN];
-	lcs_ipm_list *curr_lmem, *new_lmem;
-	lcs_state oldstate;
+	struct lcs_card *card;
 
-	if ((dev == NULL) || (dev->priv == NULL)) {
-		lcs_bad_news("invalid dev=%p in lcs_set_multicast_list\n", dev);
-		return;
-	}
-	drvr_globals = (lcs_drvr_globals *) dev->priv;
-	oldstate = drvr_globals->state;
-#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,3,0)
-	if ((in4_dev = in_dev_get(dev)) == NULL)
-		return;
-	read_lock(&in4_dev->lock);
-#else
-	if ((in4_dev = dev->ip_ptr) == NULL)
-		return;
-#endif
-	/* Pass 1 find the entries to be deleted */
-	/* This is done first to avoid overflowing the cards */
-	/* onboard multicast list. */
-	spin_lock(&drvr_globals->ipm_lock);
-	for (curr_lmem = drvr_globals->ipm_list; curr_lmem;
-	     curr_lmem = curr_lmem->next) {
-		addr_in_list = FALSE;
-		for (im4 = in4_dev->mc_list; im4; im4 = im4->next) {
-			lcs_get_mac_for_ipm(im4->multiaddr, buf, dev);
-			if ((memcmp(buf, &curr_lmem->ipm.mac_address,
-				    LCS_ADDR_LEN) == 0) &&
-			    (curr_lmem->ipm.ip_addr == im4->multiaddr)) {
-				addr_in_list = TRUE;
-				break;
-			}
+	LCS_DBF_TEXT(3, setup, "shtdndev");
+	card = (struct lcs_card *)ccwgdev->dev.driver_data;
+	if (!card)
+		return -ENODEV;
 
-		}
-		if (!addr_in_list)
-			curr_lmem->ipm_state = ipm_delete_required;
-	}
-	/* Pass 2 find the new entries to be added */
-	for (im4 = in4_dev->mc_list; im4; im4 = im4->next) {
-		lcs_get_mac_for_ipm(im4->multiaddr, buf, dev);
-		addr_in_list = FALSE;
-		for (curr_lmem = drvr_globals->ipm_list; curr_lmem;
-		     curr_lmem = curr_lmem->next) {
-			if ((memcmp
-			     (buf, &curr_lmem->ipm.mac_address,
-			      LCS_ADDR_LEN) == 0)
-			    && (curr_lmem->ipm.ip_addr == im4->multiaddr)) {
-				addr_in_list = TRUE;
-				break;
-			}
-		}
-		if (!addr_in_list) {
-			new_lmem =
-			    (lcs_ipm_list *) kmalloc(sizeof (lcs_ipm_list),
-						     GFP_ATOMIC);
-			if (!new_lmem) {
-				lcs_good_news
-				    ("lcs_set_multicast_list failed to add "
-				     "multicast entry %x not enough memory.\n",
-				     (u32) im4->multiaddr);
-				goto done;
-			}
-			memset(new_lmem, 0, sizeof (lcs_ipm_list));
-			memcpy(&new_lmem->ipm.mac_address, buf, LCS_ADDR_LEN);
-			new_lmem->ipm.ip_addr = im4->multiaddr;
-			new_lmem->ipm_state = ipm_set_required;
-			add_to_list((list **) & drvr_globals->ipm_list,
-				    (list *) new_lmem);
-		}
-	}
-#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,3,0)
-	read_unlock(&in4_dev->lock);
-	in_dev_put(in4_dev);
-#endif
-#if 0				/* LCS doesn't do IPV6 yet */
-	if ((in6_dev = in6_dev_get(dev)) == NULL)
-		return;
-	read_lock_bh(&in6_dev->lock);
-	for (im6 = in6_dev->mc_list; im6; im6 = im6->next) {
-	}
-	read_unlock(&in4_dev->lock);
-	in6_dev_put(idev);
-#endif
-done:
-	spin_unlock(&drvr_globals->ipm_lock);
-	lcs_queue_thread(lcs_fix_multicast_list, drvr_globals);
+	return lcs_stop_device(card->dev);
 }
-#endif
 
-static void
-lcs_set_slow_hw(lcs_drvr_globals * drvr_globals, u16 cu_type, u8 cu_model)
+/**
+ * lcs_remove_device, free buffers and card
+ */
+int
+lcs_remove_device(struct ccwgroup_device *ccwgdev)
 {
-	drvr_globals->slow_hw =
-	    ((cu_type == 0x3088
-	      && (cu_model == 0x8 || cu_model == 0x1f)) ? TRUE : FALSE);
-}
+	struct lcs_card *card;
 
-#if LCS_DEBUG && !LCS_PRINTK_DEBUG
-
-static void
-lcs_debug_register(void)
-{
-	if (lcs_id == NULL) {
-		lcs_id = debug_register("lcs", 1, 16, 16 * sizeof (long));
-		debug_register_view(lcs_id, &debug_sprintf_view);
-		debug_set_level(lcs_id, 0);
-	}
+	LCS_DBF_TEXT(3, setup, "remdev");
+	card = (struct lcs_card *)ccwgdev->dev.driver_data;
+	if (!card)
+		return 0;
+	lcs_cleanup_card(card);
+	lcs_free_card(card);
+	put_device(&ccwgdev->dev);
+	return 0;
 }
-#endif
 
-/*
- * The main device detection routine called  on bootup or module installation
- * to do. An unfortunately unwieldly function which dosen't lend itself
- * easily to being broken into smaller functional blocks & my reason for
- * hating tabs of 8. 
+/**
+ * LCS ccwgroup driver registration
  */
+struct ccwgroup_driver lcs_group_driver = {
+	.name        = "lcs",
+	.max_slaves  = 2,
+	.driver_id   = 0xD3C3E2,
+	.probe       = lcs_probe_device,
+	.remove      = lcs_remove_device,
+	.set_online  = lcs_new_device,
+	.set_offline = lcs_shutdown_device,
+};
 
-#if LCS_CHANDEV
+/**
+ *  LCS Module/Kernel initialization function
+ */
 static int
-lcs_probe(chandev_probeinfo * probeinfo)
+__init lcs_init_module(void)
 {
-	lcs_drvr_globals *drvr_globals = NULL;
-	int rc = -ENODEV;
-	lcs_write_globals *write;
-	lcs_read_globals *read;
-	u8 mac_address[LCS_ADDR_LEN];
-	struct net_device *dev = NULL;
-	char *basename = NULL;
-	struct net_device *(*init_netdevfunc) (struct net_device * dev,
-					       int sizeof_priv) = NULL;
-	void (*unreg_netdevfunc) (struct net_device * dev) = NULL;
-
-	drvr_globals = lcs_alloc_drvr_globals();
-	if (!drvr_globals) {
-		lcs_bad_news("lcs_probe kmalloc failed\n");
-		return -ENOMEM;
-	}
-	read = drvr_globals->read;
-	write = drvr_globals->write;
-	read->subchannel = probeinfo->read.irq;
-	write->subchannel = probeinfo->write.irq;
-	read->devno = probeinfo->read.devno;
-	write->devno = probeinfo->write.devno;
-	lcs_set_slow_hw(drvr_globals, probeinfo->read.cu_type,
-			probeinfo->read.cu_model);
-	if (lcs_allocirq(read) || lcs_allocirq(write)) {
-		rc = -ENODEV;
-		goto Fail;
-	}
-	checksum_received_ip_pkts = probeinfo->checksum_received_ip_pkts;
-	use_hw_stats = probeinfo->use_hw_stats;
-	atomic_set(&drvr_globals->retry_cnt, 0);
-	rc = lcs_detect(drvr_globals,
-			(probeinfo->device_forced ? probeinfo->
-			 port_protocol_no : -1), probeinfo->hint_port_no,
-			probeinfo->max_port_no, lcs_autodetect_type,
-			mac_address);
+	int rc;
 
+	LCS_DBF_TEXT(0, setup, "lcsinit");
+	PRINT_INFO("Loading %s\n",version);
+	rc = lcs_register_debug_facility();
 	if (rc) {
-		lcs_stopcard(drvr_globals);
-		goto Fail;
-	} else {
-		/*Fill in the fields of the device structure 
-		 * with interface specific values.
-		 */
-		switch (drvr_globals->lan_type) {
-#ifdef CONFIG_NET_ETHERNET
-		case lcs_enet_type:
-			init_netdevfunc = init_etherdev;
-			unreg_netdevfunc = unregister_netdev;
-			basename = "eth";
-			drvr_globals->lan_type_trans = eth_type_trans;
-			break;
-#endif
-#ifdef CONFIG_TR
-		case lcs_token_ring_type:
-			init_netdevfunc = init_trdev;
-			unreg_netdevfunc = unregister_netdev;
-			basename = "tr";
-			drvr_globals->lan_type_trans = tr_type_trans;
-			break;
-#endif
-#ifdef CONFIG_FDDI
-		case lcs_fddi_type:
-			init_netdevfunc = init_fddidev;
-			unreg_netdevfunc = unregister_netdev;
-			basename = "fddi";
-			drvr_globals->lan_type_trans = fddi_type_trans;
-			break;
-#endif
-		}
-		probeinfo->memory_usage_in_k =
-		    -(((LCS_READ_ALLOCSIZE * LCS_NUM_RX_BUFFS) +
-		       (LCS_NUM_TX_BUFFS * LCS_IOBUFFSIZE)) / 1024);
-		if ((dev =
-		     chandev_initnetdevice(probeinfo,
-					   drvr_globals->rel_adapter_no, NULL,
-					   0, basename, init_netdevfunc,
-					   unreg_netdevfunc)) == 0)
-			goto Fail;
-		memcpy(dev->dev_addr, mac_address, LCS_ADDR_LEN);
-		dev->open = lcs_open;
-		dev->stop = lcs_close;
-		dev->hard_start_xmit = lcs_txpacket;
-		dev->get_stats = lcs_getstats;
-
-		drvr_globals->dev = dev;
-
-		dev->priv = drvr_globals;
-#ifdef CONFIG_IP_MULTICAST
-		dev->set_multicast_list =
-		    (lcs_check_multicast_supported(drvr_globals)
-		     ? lcs_set_multicast_list : NULL);
-#endif
-		lcs_stopcard(drvr_globals);
-		netif_stop_queue(dev);
-		lcs_displayinfo(dev);
-		lcs_debug_exception(0, "device structure=%p drvr globals=%p\n"
-				    "read=%p write=%p\n"
-				    "read_ccws=%p  write_cwws=%p\n", dev,
-				    drvr_globals, drvr_globals->read,
-				    drvr_globals->write,
-				    &drvr_globals->read->ccw[0],
-				    &drvr_globals->write->ccw[0]);
-		return 0;
-	}
-Fail:
-	if (drvr_globals) {
-		lcs_freeallirqs(drvr_globals);
-		lcs_usage_free_drvr_globals(drvr_globals);
-	}
-	lcs_debug_event(2, "osa_probe error %d\n", rc);
-	return rc;
-}
-#else
-int __init
-lcs_probe(void)
-{
-	int read_irq, write_irq;
-	s390_dev_info_t read_devinfo, write_devinfo;
-	lcs_drvr_globals *drvr_globals = NULL;
-	int hint, detect_error;
-	int rc = -ENODEV;
-	int max_rel_adapter_no;
-	int err;
-	int forced_rel_adapter_no;
-	int lcs_loopcnt = 0;
-	u8 mac_address[LCS_ADDR_LEN];
-	struct net_device *dev = NULL;
-	lcs_frame_type lan_type = lcs_autodetect_type;
-	lcs_write_globals *write;
-	lcs_read_globals *read;
-
-	lcs_debug_event(1, "Starting lcs_probe dev=%p\n", dev);
-
-	for (read_irq = get_irq_first(); read_irq >= 0;
-	     read_irq = get_irq_next(read_irq)) {
-		/* check read channel
-		 * we had to do the cu_model check also because ctc devices
-		 * have the same cutype & after asking some people
-		 * the model numbers are given out pseudo randomly so
-		 * we can't just take a range of them also the 
-		 * dev_type & models are 0
-		 */
-		lcs_loopcnt++;
-		if (lcs_loopcnt > 0x10000) {
-			lcs_bad_news("lcs probe detected infinite loop "
-				     "bug in get_irq_next\n");
-			goto Fail;
-		}
-		if ((err = get_dev_info_by_irq(read_irq, &read_devinfo))) {
-			lcs_bad_news("lcs_probe get_dev_info_by_irq "
-				     "reported err=%X on irq %d\n"
-				     "should not happen\n", err, read_irq);
-			continue;
-		}
-		if (read_devinfo.status & DEVSTAT_DEVICE_OWNED)
-			continue;
-		if (read_devinfo.devno & 1)
-			continue;
-		if ((max_rel_adapter_no =
-		     lcs_model_supported(&read_devinfo,
-					 &forced_rel_adapter_no)) < 0)
-			continue;
-		if (get_dev_info_by_devno
-		    (read_devinfo.devno + 1, &write_devinfo))
-			continue;
-		if (write_devinfo.status & DEVSTAT_DEVICE_OWNED)
-			continue;
-		write_irq = write_devinfo.irq;
-		if ((ignore_sense==FALSE && forced_rel_adapter_no != -1) &&
-		    ((write_devinfo.sid_data.cu_type !=
-		      read_devinfo.sid_data.cu_type)
-		     || (write_devinfo.sid_data.cu_model !=
-			 read_devinfo.sid_data.cu_model)))
-			continue;
-		if (drvr_globals == NULL) {
-			drvr_globals = lcs_alloc_drvr_globals();
-			if (!drvr_globals) {
-				lcs_bad_news("lcs_probe kmalloc failed\n");
-				return -ENOMEM;
-			}
-		}
-		read = drvr_globals->read;
-		write = drvr_globals->write;
-		read->subchannel = read_irq;
-		write->subchannel = write_irq;
-		read->devno = read_devinfo.devno;
-		write->devno = write_devinfo.devno;
-		lcs_set_slow_hw(drvr_globals, read_devinfo.sid_data.cu_type,
-				read_devinfo.sid_data.cu_model);
-		if (lcs_allocirq(read) || lcs_allocirq(write)) {
-			lcs_freeallirqs(drvr_globals);
-			/* We may find another card further up the chain */
-		} else {
-			if (forced_rel_adapter_no == -1) {
-				hint = (read_devinfo.devno & 0xFF) >> 1;
-				/* The card is possibly emulated e.g P/390 */
-				/* or possibly configured to use a shared */
-				/* port configured by osa-sf. */
-				if (hint > max_rel_adapter_no) {
-					hint = 0;
-				}
-			} else {
-				hint = -1;
-			}
-			detect_error =
-			    lcs_detect(drvr_globals, forced_rel_adapter_no,
-				       hint, max_rel_adapter_no, lan_type,
-				       mac_address, 0);
-			if (detect_error) {
-				lcs_stopcard(drvr_globals);
-				lcs_freeallirqs(drvr_globals);
-			} else {
-				/*
-				 * Fill in the fields of the device structure 
-				 * with interface specific values.
-				 */
-				switch (drvr_globals->lan_type) {
-#ifdef CONFIG_NET_ETHERNET
-				case lcs_enet_type:
-					dev = init_etherdev(dev, 0);
-					drvr_globals->lan_type_trans =
-					    eth_type_trans;
-					break;
-#endif
-#ifdef CONFIG_TR
-				case lcs_token_ring_type:
-					dev = init_trdev(dev, 0);
-					drvr_globals->lan_type_trans =
-					    tr_type_trans;
-					break;
-#endif
-#ifdef CONFIG_FDDI
-				case lcs_fddi_type:
-					/* I'm not sure whether this
-					 * function is 
-					 * in the generic kernel anymore */
-					dev = init_fddidev(dev, 0);
-					drvr_globals->lan_type_trans =
-					    fddi_type_trans;
-					break;
-#endif
-				}
-				if (dev)
-					memcpy(dev->dev_addr, mac_address,
-					       LCS_ADDR_LEN);
-				else {
-					rc = -ENOMEM;
-					goto Fail;
-				}
-				dev->open = lcs_open;
-				dev->stop = lcs_close;
-				dev->hard_start_xmit = lcs_txpacket;
-				dev->get_stats = lcs_getstats;
-				drvr_globals->dev = dev;
-				dev->priv = drvr_globals;
-#ifdef CONFIG_IP_MULTICAST
-				dev->set_multicast_list =
-				    (lcs_check_multicast_supported(drvr_globals)
-				     ? lcs_set_multicast_list : NULL);
-#endif
-				lcs_stopcard(drvr_globals);
-				netif_stop_queue(dev);
-				lcs_displayinfo(dev);
-				lcs_debug_event(0,"device structure=%p "
-						"drvr globals=%p\n"
-						"read=%p write=%p\n"
-						"read_ccws=%p  write_cwws=%p\n",
-						dev, drvr_globals,
-						drvr_globals->read,
-						drvr_globals->write,
-						&drvr_globals->read->ccw[0],
-						&drvr_globals->write->ccw[0]);
-
-				return 0;
-			}
-		}
+		PRINT_ERR("Initialization failed\n");
+		return rc;
 	}
-Fail:
-	if (drvr_globals) {
-
-		lcs_freeallirqs(drvr_globals);
-		lcs_usage_free_drvr_globals(drvr_globals);
 
+	rc = register_cu3088_discipline(&lcs_group_driver);
+	if (rc) {
+		PRINT_ERR("Initialization failed\n");
+		return rc;
 	}
-	lcs_debug_event(2, "osa_probe error %d\n", rc);
-	return rc;
-}
-#endif
 
-#if LCS_CHANDEV || MODULE
-static int
-lcs_shutdown_card(struct net_device *dev)
-{
-	lcs_drvr_globals *drvr_globals = ((lcs_drvr_globals *) dev->priv);
-
-#if !LCS_CHANDEV
-	lcs_unregister(dev, drvr_globals->lan_type);	
-	/* unregister_netdev calls close */
-#endif
-	lcs_freeallirqs(drvr_globals);
-	lcs_usage_free_drvr_globals(drvr_globals);
-	kfree(dev);
-	return (0);
+	return 0;
 }
-#endif
-
-#if LCS_CHANDEV
-static void
-lcs_msck_notification_func(struct net_device *dev, int msck_irq,
-			   chandev_msck_status prevstatus,
-			   chandev_msck_status newstatus)
-{
-	lcs_drvr_globals *drvr_globals = (lcs_drvr_globals *) dev->priv;
-
-	lcs_debug_event(0,"lcs_msck_notifcation_func drvr_globals=%p "
-			"msck_irq=%d prevstatus=%d newstatus=%d",
-			drvr_globals, msck_irq, prevstatus, newstatus);
-	if (!drvr_globals) {
-		lcs_debug_exception(0,"lcs_msck_notification_func "
-				    "drvr_globals=NULL");
-		return;
-	}
-	if (drvr_globals->state == lcs_doing_io) {
-		if (newstatus == chandev_status_good
-		    || newstatus == chandev_status_all_chans_good) {
-			switch (prevstatus) {
-			case chandev_status_no_path:
-			case chandev_status_gone:
-			case chandev_status_not_oper:
-				if (msck_irq == drvr_globals->read->subchannel)
-					lcs_restartreadio(drvr_globals);
-				else
-					lcs_restartwriteio(drvr_globals);
-				break;
-			default:
-				break;
-			}
-		} else if (msck_irq == drvr_globals->write->subchannel
-			   && newstatus != chandev_status_revalidate)
-			drvr_globals->write->chan_busy_state = chan_dead;
 
-	} else			/* Allow lcs_detect loop a few more times */
-		atomic_set(&drvr_globals->retry_cnt, 0);
-}
-#endif
 
-#if MODULE
+/**
+ *  LCS module cleanup function
+ */
 static void
-lcs_cleanup(void)
+__exit lcs_cleanup_module(void)
 {
-#if LCS_CHANDEV
-	chandev_unregister(lcs_probe, TRUE);
-#else
-	while (lcs_card_list)
-		lcs_shutdown_card(lcs_card_list->dev);
-#endif
+	PRINT_INFO("Terminating lcs module.\n");
+	LCS_DBF_TEXT(0, trace, "cleanup");
+	unregister_cu3088_discipline(&lcs_group_driver);
+	lcs_unregister_debug_facility();
 }
-#endif
-
-#if MODULE
-int
-init_module(void)
-#else
-#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,3,0)
-static
-#endif
-    int __init
-lcs_init(void)
-#endif
-{
-	int cardsfound = 0;
-#if MODULE && LINUX_VERSION_CODE>KERNEL_VERSION(2,4,5)
-	int persist = chandev_persist(chandev_type_lcs);
-#endif
-	static char initstr[] = "Starting lcs "
-#ifdef MODULE
-	    "module "
-#else
-	    "compiled into kernel "
-#endif
-	    " $Revision: 1.128 $ $Date: 2002/03/01 16:56:47 $ \n"
-#if LCS_CHANDEV
-	    "with"
-#else
-	    "without"
-#endif
-	    " chandev support,"
-#ifdef CONFIG_IP_MULTICAST
-	    "with"
-#else
-	    "without"
-#endif
-	    " multicast support, "
-#ifdef CONFIG_NET_ETHERNET
-	    "with"
-#else
-	    "without"
-#endif
-	    " ethernet support, "
-#ifdef CONFIG_TR
-	    "with"
-#else
-	    "without"
-#endif
-	    " token ring support"
-#if 0
-	    ", "
-#ifdef CONFIG_FDDI
-	    "with"
-#else
-	    "without"
-#endif
-	    " fddi support"
-#endif
-	    ".\n";
 
-	lcs_good_news(initstr);
-#if LCS_DEBUG && !LCS_PRINTK_DEBUG
-	lcs_debug_register();
-#endif
-
-#if LCS_CHANDEV
-	cardsfound = chandev_register_and_probe(lcs_probe,
-		       (chandev_shutdownfunc) lcs_shutdown_card,
-		       (chandev_msck_notification_func)
-		       lcs_msck_notification_func,
-		       chandev_type_lcs);
-#else
-	while ((lcs_probe() == 0)) {
-		cardsfound++;
-	}
-#endif
-	if (cardsfound <= 0) {
-		lcs_bad_news("No lcs capable cards found\n");
-#if MODULE
-#if LINUX_VERSION_CODE>KERNEL_VERSION(2,4,5)
-		if (!persist)
-#endif
-			cleanup_module();
-#endif
-	}
-#if !LCS_CHANDEV
-	else {
-		lcs_display_conf();
-	}
-#endif
-	return (cardsfound ? 0 : (
-#if MODULE && LINUX_VERSION_CODE>KERNEL_VERSION(2,4,5)
-					 persist ? 0 :
-#endif
-					 -ENODEV));
-}
+module_init(lcs_init_module);
+module_exit(lcs_cleanup_module);
 
-/*
- * Code for module loading & unloading
- */
+MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>");
+MODULE_LICENSE("GPL");
 
-#ifdef MODULE
-void
-cleanup_module(void)
-{
-	lcs_good_news("Terminating lcs module.\n");
-	lcs_cleanup();
-#if LCS_DEBUG && !LCS_PRINTK_DEBUG
-	if (lcs_id) {
-		debug_unregister_view(lcs_id, &debug_sprintf_view);
-		debug_unregister(lcs_id);
-		lcs_id = NULL;
-	}
-#endif
-}
-#else
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,2,18)
-__initcall(lcs_init);
-#endif
-#endif
diff -Nru a/drivers/s390/net/lcs.h b/drivers/s390/net/lcs.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/net/lcs.h	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,285 @@
+/*lcs.h*/
+
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/workqueue.h>
+#include <asm/ccwdev.h>
+
+#define VERSION_LCS_H "$Revision: 1.12 $"
+
+#define LCS_DBF_TEXT(level, name, text) \
+	do { \
+		debug_text_event(lcs_dbf_##name, level, text); \
+	} while (0)
+
+/**
+ * some more definitions for debug or output stuff
+ */
+#define PRINTK_HEADER		" lcs: "
+
+/**
+ * CCW commands used in this driver
+ */
+#define LCS_CCW_WRITE		0x01
+#define LCS_CCW_READ		0x02
+#define LCS_CCW_TRANSFER	0x08
+
+/**
+ * LCS device status primitives
+ */
+#define LCS_CMD_STARTLAN	0x01
+#define LCS_CMD_STOPLAN		0x02
+#define LCS_CMD_LANSTAT		0x04
+#define LCS_CMD_STARTUP		0x07
+#define LCS_CMD_SHUTDOWN	0x08
+#define LCS_CMD_QIPASSIST	0xb2
+#define LCS_CMD_SETIPM		0xb4
+#define LCS_CMD_DELIPM		0xb5
+
+#define LCS_INITIATOR_TCPIP	0x00
+#define LCS_INITIATOR_LGW	0x01
+#define LCS_STD_CMD_SIZE	16
+#define LCS_MULTICAST_CMD_SIZE	404
+
+/**
+ * LCS IPASSIST MASKS,only used when multicast is switched on
+ */
+/* Not supported by LCS */
+#define LCS_IPASS_ARP_PROCESSING	0x0001
+#define LCS_IPASS_IN_CHECKSUM_SUPPORT	0x0002
+#define LCS_IPASS_OUT_CHECKSUM_SUPPORT	0x0004
+#define LCS_IPASS_IP_FRAG_REASSEMBLY	0x0008
+#define LCS_IPASS_IP_FILTERING		0x0010
+/* Supported by lcs 3172 */
+#define LCS_IPASS_IPV6_SUPPORT		0x0020
+#define LCS_IPASS_MULTICAST_SUPPORT	0x0040
+
+/**
+ * LCS sense byte definitions
+ */
+#define LCS_SENSE_INTERFACE_DISCONNECT	0x01
+#define LCS_SENSE_EQUIPMENT_CHECK	0x10
+#define LCS_SENSE_BUS_OUT_CHECK		0x20
+#define LCS_SENSE_INTERVENTION_REQUIRED 0x40
+#define LCS_SENSE_CMD_REJECT		0x80
+#define LCS_SENSE_RESETTING_EVENT	0x0080
+#define LCS_SENSE_DEVICE_ONLINE		0x0020
+
+/**
+ * LCS packet type definitions
+ */
+#define LCS_FRAME_TYPE_CONTROL		0
+#define LCS_FRAME_TYPE_ENET		1
+#define LCS_FRAME_TYPE_TR		2
+#define LCS_FRAME_TYPE_FDDI		7
+#define LCS_FRAME_TYPE_AUTO		-1
+
+/**
+ * some more definitions,we will sort them later
+ */
+#define LCS_ILLEGAL_OFFSET		0xffff
+#define LCS_IOBUFFERSIZE		0x5000
+#define LCS_NUM_BUFFS			8	/* needs to be power of 2 */
+#define LCS_MAC_LENGTH			6
+#define LCS_INVALID_PORT_NO		-1
+
+/**
+ * Multicast state
+ */
+#define	 LCS_IPM_STATE_SET_REQUIRED	0
+#define	 LCS_IPM_STATE_DEL_REQUIRED	1
+#define	 LCS_IPM_STATE_ON_CARD		2
+
+/**
+ * LCS IP Assist declarations
+ * seems to be only used for multicast
+ */
+#define	 LCS_IPASS_ARP_PROCESSING	0x0001
+#define	 LCS_IPASS_INBOUND_CSUM_SUPP	0x0002
+#define	 LCS_IPASS_OUTBOUND_CSUM_SUPP	0x0004
+#define	 LCS_IPASS_IP_FRAG_REASSEMBLY	0x0008
+#define	 LCS_IPASS_IP_FILTERING		0x0010
+#define	 LCS_IPASS_IPV6_SUPPORT		0x0020
+#define	 LCS_IPASS_MULTICAST_SUPPORT	0x0040
+
+/**
+ * LCS Buffer states
+ */
+enum lcs_buffer_states {
+	BUF_STATE_EMPTY,	/* buffer is empty */
+	BUF_STATE_LOCKED,	/* buffer is locked, don't touch */
+	BUF_STATE_READY,	/* buffer is ready for read/write */
+	BUF_STATE_PROCESSED,
+};
+
+/**
+ * LCS Channel State Machine declarations
+ */
+enum lcs_channel_states {
+	CH_STATE_INIT,
+	CH_STATE_HALTED,
+	CH_STATE_STOPPED,
+	CH_STATE_RUNNING,
+	CH_STATE_SUSPENDED,
+};
+
+/**
+ * LCS device state machine
+ */
+enum lcs_dev_states {
+	DEV_STATE_DOWN,
+	DEV_STATE_UP,
+};
+
+/**
+ * LCS struct declarations
+ */
+struct lcs_header {
+	__u16  offset;
+	__u8   type;
+	__u8   slot;
+}  __attribute__ ((packed));
+
+struct lcs_ip_mac_pair {
+	__u32  ip_addr;
+	__u8   mac_addr[LCS_MAC_LENGTH];
+	__u8   reserved[2];
+}  __attribute__ ((packed));
+
+struct lcs_ipm_list {
+	struct list_head list;
+	struct lcs_ip_mac_pair ipm;
+	__u8 ipm_state;
+};
+
+struct lcs_cmd {
+	__u16  offset;
+	__u8   type;
+	__u8   slot;
+	__u8   cmd_code;
+	__u8   initiator;
+	__u16  sequence_no;
+	__u16  return_code;
+	union {
+		struct {
+			__u8   lan_type;
+			__u8   portno;
+			__u16  parameter_count;
+			__u8   operator_flags[3];
+			__u8   reserved[3];
+		} lcs_std_cmd;
+		struct {
+			__u16  unused1;
+			__u16  buff_size;
+			__u8   unused2[6];
+		} lcs_startup;
+		struct {
+			__u8   lan_type;
+			__u8   portno;
+			__u8   unused[10];
+			__u8   mac_addr[LCS_MAC_LENGTH];
+			__u32  num_packets_deblocked;
+			__u32  num_packets_blocked;
+			__u32  num_packets_tx_on_lan;
+			__u32  num_tx_errors_detected;
+			__u32  num_tx_packets_disgarded;
+			__u32  num_packets_rx_from_lan;
+			__u32  num_rx_errors_detected;
+			__u32  num_rx_discarded_nobuffs_avail;
+			__u32  num_rx_packets_too_large;
+		} lcs_lanstat_cmd;
+#ifdef CONFIG_IP_MULTICAST
+		struct {
+			__u8   lan_type;
+			__u8   portno;
+			__u16  num_ip_pairs;
+			__u16  ip_assists_supported;
+			__u16  ip_assists_enabled;
+			__u16  version;
+			struct {
+				struct lcs_ip_mac_pair
+				ip_mac_pair[32];
+				__u32	  response_data;
+			} lcs_ipass_ctlmsg;
+		} lcs_qipassist;
+#endif /*CONFIG_IP_MULTICAST */
+	} cmd __attribute__ ((packed));
+}  __attribute__ ((packed));
+
+/**
+ * Forward declarations.
+ */
+struct lcs_card;
+struct lcs_channel;
+
+/**
+ * Definition of an lcs buffer.
+ */
+struct lcs_buffer {
+	enum lcs_buffer_states state;
+	void *data;
+	int count;
+	/* Callback for completion notification. */
+	void (*callback)(struct lcs_channel *, struct lcs_buffer *);
+};
+
+struct lcs_reply {
+	struct list_head list;
+	__u16 sequence_no;
+	/* Callback for completion notification. */
+	void (*callback)(struct lcs_card *, struct lcs_cmd *);
+	wait_queue_head_t wait_q;
+	int received;
+	int rc;
+};
+
+/**
+ * Definition of an lcs channel
+ */
+struct lcs_channel {
+	enum lcs_channel_states state;
+	struct ccw_device *ccwdev;
+	struct ccw1 ccws[LCS_NUM_BUFFS + 1];
+	wait_queue_head_t wait_q;
+	struct tasklet_struct irq_tasklet;
+	struct lcs_buffer iob[LCS_NUM_BUFFS];
+	int io_idx;
+	int buf_idx;
+};
+
+/**
+ * definition of the lcs card
+ */
+struct lcs_card {
+	spinlock_t lock;
+	enum lcs_dev_states state;
+	struct net_device *dev;
+	struct net_device_stats stats;
+	unsigned short (*lan_type_trans)(struct sk_buff *skb,
+					 struct net_device *dev);
+	struct lcs_channel read;
+	struct lcs_channel write;
+	struct lcs_buffer *tx_buffer;
+	int tx_emitted;
+	struct list_head lancmd_waiters;
+
+	struct work_struct kernel_thread_starter;
+	unsigned long thread_mask;
+
+#ifdef CONFIG_IP_MULTICAST
+	struct list_head ipm_list;
+#endif
+	__u8 mac[LCS_MAC_LENGTH];
+	__u16 ip_assists_supported;
+	__u16 ip_assists_enabled;
+	__s8 lan_type;
+	__u16 sequence_no;
+	__s16 portno;
+	/* Some info copied from probeinfo */
+	u8 device_forced;
+	u8 max_port_no;
+	u8 hint_port_no;
+	s16 port_protocol_no;
+}  __attribute__ ((aligned(8)));
+
diff -Nru a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
--- a/drivers/s390/net/netiucv.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/s390/net/netiucv.c	Mon Dec  9 18:46:38 2002
@@ -1,11 +1,13 @@
 /*
- * $Id: netiucv.c,v 1.17 2002/02/12 21:52:20 felfert Exp $
+ * $Id: netiucv.c,v 1.12 2002/11/26 16:00:54 mschwide Exp $
  *
  * IUCV network driver
  *
  * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
  * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
  *
+ * Driverfs integration and all bugs therein by Cornelia Huck(cohuck@de.ibm.com)
+ *
  * Documentation used:
  *  the source of the original IUCV driver by:
  *    Stefan Hegewald <hegewald@de.ibm.com>
@@ -28,7 +30,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: IUCV network driver $Revision: 1.17 $
+ * RELEASE-TAG: IUCV network driver $Revision: 1.12 $
  *
  */
 
@@ -45,7 +47,7 @@
 
 #include <linux/signal.h>
 #include <linux/string.h>
-#include <linux/proc_fs.h>
+#include <linux/device.h>
 
 #include <linux/ip.h>
 #include <linux/if_arp.h>
@@ -137,11 +139,7 @@
 	unsigned long           tbusy;
 	fsm_instance            *fsm;
         iucv_connection         *conn;
-	struct proc_dir_entry   *proc_dentry;
-	struct proc_dir_entry   *proc_stat_entry;
-	struct proc_dir_entry   *proc_buffer_entry;
-	struct proc_dir_entry   *proc_user_entry;
-	int                     proc_registered;
+	struct platform_device  pldev;
 } netiucv_priv;
 
 /**
@@ -540,7 +538,7 @@
 		skb->protocol = pskb->protocol;
 		pskb->ip_summed = CHECKSUM_UNNECESSARY;
 		netif_rx(skb);
-#warning FIXME: [kj] Net drivers should set dev->last_rx immediately after netif_rx
+		dev->last_rx = jiffies;
 		privptr->stats.rx_packets++;
 		privptr->stats.rx_bytes += skb->len;
 		skb_pull(pskb, header->next);
@@ -1255,71 +1253,75 @@
 	return 0;
 }
 
-
 /**
- * procfs related structures and routines
+ * attributes in sysfs
  *****************************************************************************/
+#define CTRL_BUFSIZE 40
 
-static net_device *
-find_netdev_by_ino(struct proc_dir_entry *pde)
+static ssize_t
+user_show (struct device *dev, char *buf, size_t count, loff_t off)
 {
-	iucv_connection *conn = connections;
-	net_device *dev = NULL;
-	netiucv_priv *privptr;
+	netiucv_priv *priv = dev->driver_data;
 
-	while (conn) {
-		if (conn->netdev != dev) {
-			dev = conn->netdev;
-			privptr = (netiucv_priv *)dev->priv;
-
-			if ((privptr->proc_buffer_entry == pde) ||
-			    (privptr->proc_user_entry == pde)   ||
-			    (privptr->proc_stat_entry == pde)     )
-				return dev;
-		}
-		conn = conn->next;
-	}
-	return NULL;
+	return off ? 0 : snprintf(buf, count, "%s\n", 
+				  netiucv_printname(priv->conn->userid));
 }
 
-#define CTRL_BUFSIZE 40
-
-static int
-netiucv_buffer_open(struct inode *inode, struct file *file)
+static ssize_t
+user_write (struct device *dev, const char *buf, size_t count, loff_t off)
 {
-	file->private_data = kmalloc(CTRL_BUFSIZE, GFP_KERNEL);
-	if (file->private_data == NULL)
-		return -ENOMEM;
-	MOD_INC_USE_COUNT;
-	return 0;
+	netiucv_priv *priv = dev->driver_data;
+	struct net_device *ndev = container_of((void *)priv, struct net_device, priv);
+	int          i;
+	char         *p;
+	char         tmp[CTRL_BUFSIZE];
+	char         user[9];
+
+	if (count >= 39)
+		return -EINVAL;
+
+	if (copy_from_user(tmp, buf, count))
+		return -EFAULT;
+	tmp[count+1] = '\0';
+
+	memset(user, ' ', sizeof(user));
+	user[8] = '\0';
+	for (p = tmp, i = 0; *p && (!isspace(*p)); p++) {
+		if (i > 7)
+			return -EINVAL;
+		user[i++] = *p;
+	}
+
+	if (memcmp(user, priv->conn->userid, 8) != 0) {
+		/* username changed */
+		if (ndev->flags & IFF_RUNNING)
+			return -EBUSY;
+	}
+	memcpy(priv->conn->userid, user, 9);
+	return count;
+
 }
 
-static int
-netiucv_buffer_close(struct inode *inode, struct file *file)
+static DEVICE_ATTR(user, 0644, user_show, user_write);
+
+static ssize_t
+buffer_show (struct device *dev, char *buf, size_t count, loff_t off)
 {
-	kfree(file->private_data);
-	MOD_DEC_USE_COUNT;
-	return 0;
+	netiucv_priv *priv = dev->driver_data;
+
+	return off ? 0 : snprintf(buf, count, "%d\n", 
+				  priv->conn->max_buffsize);
 }
 
 static ssize_t
-netiucv_buffer_write(struct file *file, const char *buf, size_t count,
-			   loff_t *off)
+buffer_write (struct device *dev, const char *buf, size_t count, loff_t off)
 {
-	struct proc_dir_entry *pde = PDE(file->f_dentry->d_inode);
-	net_device   *dev;
-	netiucv_priv *privptr;
+	netiucv_priv *priv = dev->driver_data;
+	struct net_device *ndev = container_of((void *)priv, struct net_device, priv);
 	char         *e;
 	int          bs1;
 	char         tmp[CTRL_BUFSIZE];
 
-	if (!(dev = find_netdev_by_ino(pde)))
-		return -ENODEV;
-	if (off != &file->f_pos)
-		return -ESPIPE;
-
-	privptr = (netiucv_priv *)dev->priv;
-
 	if (count >= 39)
 		return -EINVAL;
 
@@ -1331,336 +1333,231 @@
 	if ((bs1 > NETIUCV_BUFSIZE_MAX) ||
 	    (e && (!isspace(*e))))
 		return -EINVAL;
-	if ((dev->flags & IFF_RUNNING) &&
-	    (bs1 < (dev->mtu + NETIUCV_HDRLEN + 2)))
+	if ((ndev->flags & IFF_RUNNING) &&
+	    (bs1 < (ndev->mtu + NETIUCV_HDRLEN + 2)))
 		return -EINVAL;
 	if (bs1 < (576 + NETIUCV_HDRLEN + NETIUCV_HDRLEN))
 		return -EINVAL;
 
 
-	privptr->conn->max_buffsize = bs1;
-	if (!(dev->flags & IFF_RUNNING))
-		dev->mtu = bs1 - NETIUCV_HDRLEN - NETIUCV_HDRLEN;
-	privptr->conn->flags |= CONN_FLAGS_BUFSIZE_CHANGED;
+	priv->conn->max_buffsize = bs1;
+	if (!(ndev->flags & IFF_RUNNING))
+		ndev->mtu = bs1 - NETIUCV_HDRLEN - NETIUCV_HDRLEN;
+	priv->conn->flags |= CONN_FLAGS_BUFSIZE_CHANGED;
 
 	return count;
+
 }
 
+static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write);
+
 static ssize_t
-netiucv_buffer_read(struct file *file, char *buf, size_t count, loff_t *off)
+dev_fsm_show (struct device *dev, char *buf, size_t count, loff_t off)
 {
-	struct proc_dir_entry *pde = PDE(file->f_dentry->d_inode);
-	char *sbuf = (char *)file->private_data;
-	net_device *dev;
-	netiucv_priv *privptr;
-	ssize_t ret = 0;
-	char *p = sbuf;
-	int l;
-
-	if (!(dev = find_netdev_by_ino(pde)))
-		return -ENODEV;
-	if (off != &file->f_pos)
-		return -ESPIPE;
-
-	privptr = (netiucv_priv *)dev->priv;
-
-	if (file->f_pos == 0)
-		sprintf(sbuf, "%d\n", privptr->conn->max_buffsize);
-
-	l = strlen(sbuf);
-	p = sbuf;
-	if (file->f_pos < l) {
-		p += file->f_pos;
-		l = strlen(p);
-		ret = (count > l) ? l : count;
-		if (copy_to_user(buf, p, ret))
-			return -EFAULT;
-	}
-	file->f_pos += ret;
-	return ret;
+	netiucv_priv *priv = dev->driver_data;
+	
+	return off ? 0 : snprintf(buf, count, "%s\n",
+				  fsm_getstate_str(priv->fsm));
 }
 
-static int
-netiucv_user_open(struct inode *inode, struct file *file)
+static DEVICE_ATTR(device_fsm_state, 0444, dev_fsm_show, NULL);
+
+static ssize_t
+conn_fsm_show (struct device *dev, char *buf, size_t count, loff_t off)
 {
-	file->private_data = kmalloc(CTRL_BUFSIZE, GFP_KERNEL);
-	if (file->private_data == NULL)
-		return -ENOMEM;
-	MOD_INC_USE_COUNT;
-	return 0;
+	netiucv_priv *priv = dev->driver_data;
+	
+	return off ? 0 : snprintf(buf, count, "%s\n",
+				  fsm_getstate_str(priv->conn->fsm));
 }
 
-static int
-netiucv_user_close(struct inode *inode, struct file *file)
+static DEVICE_ATTR(connection_fsm_state, 0444, conn_fsm_show, NULL);
+
+static ssize_t
+maxmulti_show (struct device *dev, char *buf, size_t count, loff_t off)
 {
-	kfree(file->private_data);
-	MOD_DEC_USE_COUNT;
-	return 0;
+	netiucv_priv *priv = dev->driver_data;
+	
+	return off ? 0 : snprintf(buf, count, "%ld\n",
+				  priv->conn->prof.maxmulti);
 }
 
 static ssize_t
-netiucv_user_write(struct file *file, const char *buf, size_t count,
-			   loff_t *off)
+maxmulti_write (struct device *dev, const char *buf, size_t count, loff_t off)
 {
-	struct proc_dir_entry *pde = PDE(file->f_dentry->d_inode);
-	net_device   *dev;
-	netiucv_priv *privptr;
-	int          i;
-	char         *p;
-	char         tmp[CTRL_BUFSIZE];
-	char         user[9];
-
-	if (!(dev = find_netdev_by_ino(pde)))
-		return -ENODEV;
-	if (off != &file->f_pos)
-		return -ESPIPE;
+	netiucv_priv *priv = dev->driver_data;
+	
+	priv->conn->prof.maxmulti = 0;
+	return count;
+}
 
-	privptr = (netiucv_priv *)dev->priv;
+static DEVICE_ATTR(max_tx_buffer_used, 0644, maxmulti_show, maxmulti_write);
 
-	if (count >= 39)
-		return -EINVAL;
+static ssize_t
+maxcq_show (struct device *dev, char *buf, size_t count, loff_t off)
+{
+	netiucv_priv *priv = dev->driver_data;
+	
+	return off ? 0 : snprintf(buf, count, "%ld\n",
+				  priv->conn->prof.maxcqueue);
+}
 
-	if (copy_from_user(tmp, buf, count))
-		return -EFAULT;
-	tmp[count+1] = '\0';
+static ssize_t
+maxcq_write (struct device *dev, const char *buf, size_t count, loff_t off)
+{
+	netiucv_priv *priv = dev->driver_data;
+	
+	priv->conn->prof.maxcqueue = 0;
+	return count;
+}
 
-	memset(user, ' ', sizeof(user));
-	user[8] = '\0';
-	for (p = tmp, i = 0; *p && (!isspace(*p)); p++) {
-		if (i > 7)
-			return -EINVAL;
-		user[i++] = *p;
-	}
+static DEVICE_ATTR(max_chained_skbs, 0644, maxcq_show, maxcq_write);
 
-	if (memcmp(user, privptr->conn->userid, 8) != 0) {
-		/* username changed */
-		if (dev->flags & IFF_RUNNING)
-			return -EBUSY;
-	}
-	memcpy(privptr->conn->userid, user, 9);
-	return count;
+static ssize_t
+sdoio_show (struct device *dev, char *buf, size_t count, loff_t off)
+{
+	netiucv_priv *priv = dev->driver_data;
+	
+	return off ? 0 : snprintf(buf, count, "%ld\n",
+				  priv->conn->prof.doios_single);
 }
 
 static ssize_t
-netiucv_user_read(struct file *file, char *buf, size_t count, loff_t *off)
+sdoio_write (struct device *dev, const char *buf, size_t count, loff_t off)
 {
-	struct proc_dir_entry *pde = PDE(file->f_dentry->d_inode);
-	char *sbuf = (char *)file->private_data;
-	net_device *dev;
-	netiucv_priv *privptr;
-	ssize_t ret = 0;
-	char *p = sbuf;
-	int l;
-
-	if (!(dev = find_netdev_by_ino(pde)))
-		return -ENODEV;
-	if (off != &file->f_pos)
-		return -ESPIPE;
+	netiucv_priv *priv = dev->driver_data;
+	
+	priv->conn->prof.doios_single = 0;
+	return count;
+}
 
-	privptr = (netiucv_priv *)dev->priv;
+static DEVICE_ATTR(tx_single_write_ops, 0644, sdoio_show, sdoio_write);
 
+static ssize_t
+mdoio_show (struct device *dev, char *buf, size_t count, loff_t off)
+{
+	netiucv_priv *priv = dev->driver_data;
+	
+	return off ? 0 : snprintf(buf, count, "%ld\n",
+				  priv->conn->prof.doios_multi);
+}
 
-	if (file->f_pos == 0)
-		sprintf(sbuf, "%s\n",
-			netiucv_printname(privptr->conn->userid));
-
-	l = strlen(sbuf);
-	p = sbuf;
-	if (file->f_pos < l) {
-		p += file->f_pos;
-		l = strlen(p);
-		ret = (count > l) ? l : count;
-		if (copy_to_user(buf, p, ret))
-			return -EFAULT;
-	}
-	file->f_pos += ret;
-	return ret;
+static ssize_t
+mdoio_write (struct device *dev, const char *buf, size_t count, loff_t off)
+{
+	netiucv_priv *priv = dev->driver_data;
+	
+	priv->conn->prof.doios_multi = 0;
+	return count;
 }
 
-#define STATS_BUFSIZE 2048
+static DEVICE_ATTR(tx_multi_write_ops, 0644, mdoio_show, mdoio_write);
 
-static int
-netiucv_stat_open(struct inode *inode, struct file *file)
+static ssize_t
+txlen_show (struct device *dev, char *buf, size_t count, loff_t off)
 {
-	file->private_data = kmalloc(STATS_BUFSIZE, GFP_KERNEL);
-	if (file->private_data == NULL)
-		return -ENOMEM;
-	MOD_INC_USE_COUNT;
-	return 0;
+	netiucv_priv *priv = dev->driver_data;
+	
+	return off ? 0 : snprintf(buf, count, "%ld\n",
+				  priv->conn->prof.txlen);
 }
 
-static int
-netiucv_stat_close(struct inode *inode, struct file *file)
+static ssize_t
+txlen_write (struct device *dev, const char *buf, size_t count, loff_t off)
 {
-	kfree(file->private_data);
-	MOD_DEC_USE_COUNT;
-	return 0;
+	netiucv_priv *priv = dev->driver_data;
+	
+	priv->conn->prof.txlen = 0;
+	return count;
 }
 
+static DEVICE_ATTR(netto_bytes, 0644, txlen_show, txlen_write);
+
 static ssize_t
-netiucv_stat_write(struct file *file, const char *buf, size_t count, loff_t *off)
+txtime_show (struct device *dev, char *buf, size_t count, loff_t off)
 {
-	struct proc_dir_entry *pde = PDE(file->f_dentry->d_inode);
-	net_device *dev;
-	netiucv_priv *privptr;
-
-	if (!(dev = find_netdev_by_ino(pde)))
-		return -ENODEV;
-	privptr = (netiucv_priv *)dev->priv;
-	privptr->conn->prof.maxmulti = 0;
-	privptr->conn->prof.maxcqueue = 0;
-	privptr->conn->prof.doios_single = 0;
-	privptr->conn->prof.doios_multi = 0;
-	privptr->conn->prof.txlen = 0;
-	privptr->conn->prof.tx_time = 0;
-	return count;
+	netiucv_priv *priv = dev->driver_data;
+	
+	return off ? 0 : snprintf(buf, count, "%ld\n",
+				  priv->conn->prof.tx_time);
 }
 
 static ssize_t
-netiucv_stat_read(struct file *file, char *buf, size_t count, loff_t *off)
+txtime_write (struct device *dev, const char *buf, size_t count, loff_t off)
 {
-	struct proc_dir_entry *pde = PDE(file->f_dentry->d_inode);
-	char *sbuf = (char *)file->private_data;
-	net_device *dev;
-	netiucv_priv *privptr;
-	ssize_t ret = 0;
-	char *p = sbuf;
-	int l;
-
-	if (!(dev = find_netdev_by_ino(pde)))
-		return -ENODEV;
-	if (off != &file->f_pos)
-		return -ESPIPE;
+	netiucv_priv *priv = dev->driver_data;
+	
+	priv->conn->prof.tx_time = 0;
+	return count;
+}
 
-	privptr = (netiucv_priv *)dev->priv;
+static DEVICE_ATTR(max_tx_io_time, 0644, txtime_show, txtime_write);
 
-	if (file->f_pos == 0) {
-		p += sprintf(p, "Device FSM state: %s\n",
-			     fsm_getstate_str(privptr->fsm));
-		p += sprintf(p, "Connection FSM state: %s\n",
-			     fsm_getstate_str(privptr->conn->fsm));
-		p += sprintf(p, "Max. TX buffer used: %ld\n",
-			     privptr->conn->prof.maxmulti);
-		p += sprintf(p, "Max. chained SKBs: %ld\n",
-			     privptr->conn->prof.maxcqueue);
-		p += sprintf(p, "TX single write ops: %ld\n",
-			     privptr->conn->prof.doios_single);
-		p += sprintf(p, "TX multi write ops: %ld\n",
-			     privptr->conn->prof.doios_multi);
-		p += sprintf(p, "Netto bytes written: %ld\n",
-			     privptr->conn->prof.txlen);
-		p += sprintf(p, "Max. TX IO-time: %ld\n",
-			     privptr->conn->prof.tx_time);
-	}
-	l = strlen(sbuf);
-	p = sbuf;
-	if (file->f_pos < l) {
-		p += file->f_pos;
-		l = strlen(p);
-		ret = (count > l) ? l : count;
-		if (copy_to_user(buf, p, ret))
-			return -EFAULT;
+static inline int
+netiucv_add_files(struct device *dev)
+{
+	int ret = 0;
+
+	if ((ret = device_create_file(dev, &dev_attr_user)) ||
+	    (ret = device_create_file(dev, &dev_attr_buffer)) ||
+	    (ret = device_create_file(dev, &dev_attr_device_fsm_state)) ||
+	    (ret = device_create_file(dev, &dev_attr_connection_fsm_state)) ||
+	    (ret = device_create_file(dev, &dev_attr_max_tx_buffer_used)) ||
+	    (ret = device_create_file(dev, &dev_attr_max_chained_skbs)) ||
+	    (ret = device_create_file(dev, &dev_attr_tx_single_write_ops)) ||
+	    (ret = device_create_file(dev, &dev_attr_tx_multi_write_ops)) ||
+	    (ret = device_create_file(dev, &dev_attr_netto_bytes)) ||
+	    (ret = device_create_file(dev, &dev_attr_max_tx_io_time))) {
+		device_remove_file(dev, &dev_attr_netto_bytes);
+		device_remove_file(dev, &dev_attr_tx_multi_write_ops);
+		device_remove_file(dev, &dev_attr_tx_single_write_ops);
+		device_remove_file(dev, &dev_attr_max_chained_skbs);
+		device_remove_file(dev, &dev_attr_max_tx_buffer_used);
+		device_remove_file(dev, &dev_attr_connection_fsm_state);
+		device_remove_file(dev, &dev_attr_device_fsm_state);
+		device_remove_file(dev, &dev_attr_buffer);
+		device_remove_file(dev, &dev_attr_user);
 	}
-	file->f_pos += ret;
 	return ret;
 }
 
-static struct file_operations netiucv_stat_fops = {
-	.read    = netiucv_stat_read,
-	.write   = netiucv_stat_write,
-	.open    = netiucv_stat_open,
-	.release = netiucv_stat_close,
-};
+static int
+netiucv_register_device(struct net_device *ndev, int ifno)
+{
+	netiucv_priv *priv = ndev->priv;
+	struct platform_device *pldev = &priv->pldev;
+	int ret;
+	char *str = "netiucv";
 
-static struct file_operations netiucv_buffer_fops = {
-	.read    = netiucv_buffer_read,
-	.write   = netiucv_buffer_write,
-	.open    = netiucv_buffer_open,
-	.release = netiucv_buffer_close,
-};
+	snprintf(pldev->dev.name, DEVICE_NAME_SIZE, 
+		 "%s%x", str, ifno);
+	pldev->name = str;
+	pldev->id = ifno;
 
-static struct file_operations netiucv_user_fops = {
-	.read    = netiucv_user_read,
-	.write   = netiucv_user_write,
-	.open    = netiucv_user_open,
-	.release = netiucv_user_close,
-};
+	ret = platform_device_register(pldev);
 
-static struct proc_dir_entry *netiucv_dir = NULL;
-static struct proc_dir_entry *netiucv_template = NULL;
+	if (ret)
+		return ret;
 
-/**
- * Create the driver's main directory /proc/net/iucv
- */
-static void
-netiucv_proc_create_main(void)
-{
-	/**
-	 * If not registered, register main proc dir-entry now
-	 */
-	if (!netiucv_dir)
-		netiucv_dir = proc_mkdir("iucv", proc_net);
+	ret = netiucv_add_files(&pldev->dev);
+
+	if (ret) 
+		platform_device_unregister(pldev);
+	else
+		pldev->dev.driver_data = priv;
+	return ret;
 }
 
 #ifdef MODULE
-/**
- * Destroy /proc/net/iucv
- */
 static void
-netiucv_proc_destroy_main(void)
+netiucv_unregister_device(struct net_device *ndev)
 {
-	remove_proc_entry("iucv", proc_net);
-}
-#endif MODULE
-
-/**
- * Create a device specific subdirectory in /proc/net/iucv/ with the
- * same name like the device. In that directory, create 3 entries
- * "statistics", "buffersize" and "username".
- *
- * @param dev The device for which the subdirectory should be created.
- *
- */
-static void
-netiucv_proc_create_sub(net_device *dev) {
-	netiucv_priv *privptr = dev->priv;
-
-	privptr->proc_dentry = proc_mkdir(dev->name, netiucv_dir);
-	privptr->proc_stat_entry =
-		create_proc_entry("statistics",
-				  S_IFREG | S_IRUSR | S_IWUSR,
-				  privptr->proc_dentry);
-	privptr->proc_stat_entry->proc_fops = &netiucv_stat_fops;
-	privptr->proc_buffer_entry =
-		create_proc_entry("buffersize",
-				  S_IFREG | S_IRUSR | S_IWUSR,
-				  privptr->proc_dentry);
-	privptr->proc_buffer_entry->proc_fops = &netiucv_buffer_fops;
-	privptr->proc_user_entry =
-		create_proc_entry("username",
-				  S_IFREG | S_IRUSR | S_IWUSR,
-				  privptr->proc_dentry);
-	privptr->proc_user_entry->proc_fops = &netiucv_user_fops;
-	privptr->proc_registered = 1;
+	netiucv_priv *priv = (netiucv_priv*)ndev->priv;
+	struct platform_device *pldev = &priv->pldev;
+	
+	platform_device_unregister(pldev);
 }
-
-
-/**
- * Destroy a device specific subdirectory.
- *
- * @param privptr Pointer to device private data.
- */
-static void
-netiucv_proc_destroy_sub(netiucv_priv *privptr) {
-	if (!privptr->proc_registered)
-		return;
-	remove_proc_entry("statistics", privptr->proc_dentry);
-	remove_proc_entry("buffersize", privptr->proc_dentry);
-	remove_proc_entry("username", privptr->proc_dentry);
-	remove_proc_entry(privptr->proc_dentry->name, netiucv_dir);
-	privptr->proc_registered = 0;
-}
-
+#endif
 
 /**
  * Allocate and initialize a new connection structure.
@@ -1813,7 +1710,6 @@
 			netiucv_remove_connection(privptr->conn);
 		if (privptr->fsm)
 			kfree_fsm(privptr->fsm);
-		netiucv_proc_destroy_sub(privptr);
 		kfree(privptr);
 	}
 	kfree(dev);
@@ -1822,7 +1718,7 @@
 static void
 netiucv_banner(void)
 {
-	char vbuf[] = "$Revision: 1.17 $";
+	char vbuf[] = "$Revision: 1.12 $";
 	char *version = vbuf;
 
 	if ((version = strchr(version, ':'))) {
@@ -1858,9 +1754,9 @@
 	while (connections) {
 		net_device *dev = connections->netdev;
 		unregister_netdev(dev);
+		netiucv_unregister_device(dev);
 		netiucv_free_netdevice(dev);
 	}
-	netiucv_proc_destroy_main();
 
 	printk(KERN_INFO "NETIUCV driver unloaded\n");
 	return;
@@ -1877,7 +1773,6 @@
 	int i = 0;
 	char username[10];
 
-	netiucv_proc_create_main();
 	while (p) {
 		if (isalnum(*p)) {
 			username[i++] = *p++;
@@ -1915,7 +1810,7 @@
 							netiucv_free_netdevice(dev);
 						} else {
 							printk(KERN_INFO "%s: '%s'\n", dev->name, netiucv_printname(username));
-							netiucv_proc_create_sub(dev);
+							netiucv_register_device(dev, ifno);
 							ifno++;
 						}
 					}						
diff -Nru a/drivers/s390/qdio.c b/drivers/s390/qdio.c
--- a/drivers/s390/qdio.c	Mon Dec  9 18:46:35 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,3526 +0,0 @@
-/*
- *
- * linux/drivers/s390/qdio.c
- *
- * Linux for S/390 QDIO base support, Hipersocket base support
- * version 2
- *
- * Copyright 2000,2002 IBM Corporation
- * Author(s): Utz Bacher <utz.bacher@de.ibm.com>
- *
- * Restriction: only 63 iqdio subchannels would have its own indicator,
- * after that, subsequent subchannels share one indicator
- *
- *
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* we want the eyecatcher to be at the top of the code */
-void volatile qdio_eyecatcher(void)
-{
-	return;
-}
-
-#include <linux/config.h>
-
-#include <linux/module.h>
-
-#include <linux/version.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/proc_fs.h>
-#include <linux/init.h>
-#include <linux/timer.h>
-
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/atomic.h>
-#include <asm/semaphore.h>
-
-#include <asm/debug.h>
-
-#include <asm/qdio.h>
-
-#define VERSION_QDIO_C "$Revision: 1.122 $"
-
-/****************** MODULE PARAMETER VARIABLES ********************/
-MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
-MODULE_DESCRIPTION("QDIO base support version 2, " \
-		   "Copyright 2000 IBM Corporation");
-MODULE_LICENSE("GPL");
-
-/******************** HERE WE GO ***********************************/
-
-static const char *version="QDIO base support version 2 ("
-	VERSION_QDIO_C "/" VERSION_QDIO_H ")";
-
-#ifdef QDIO_PERFORMANCE_STATS
-static int proc_perf_file_registration;
-static unsigned long i_p_c=0,i_p_nc=0,o_p_c=0,o_p_nc=0,ii_p_c=0,ii_p_nc=0;
-
-static struct {
-	unsigned int tl_runs;
-
-	unsigned int siga_outs;
-	unsigned int siga_ins;
-	unsigned int siga_syncs;
-	unsigned int pcis;
-	unsigned int thinints;
-	unsigned int fast_reqs;
-
-	__u64 start_time_outbound;
-	unsigned int outbound_cnt;
-	unsigned int outbound_time;
-	__u64 start_time_inbound;
-	unsigned int inbound_cnt;
-	unsigned int inbound_time;
-} perf_stats;
-
-#endif /* QDIO_PERFORMANCE_STATS */
-
-static int indicator_used[INDICATORS_PER_CACHELINE];
-static __u32 * volatile indicators;
-static __u32 volatile spare_indicator;
-
-static debug_info_t *qdio_dbf_setup=NULL;
-static debug_info_t *qdio_dbf_sbal=NULL;
-static debug_info_t *qdio_dbf_trace=NULL;
-static debug_info_t *qdio_dbf_sense=NULL;
-#ifdef QDIO_DBF_LIKE_HELL
-static debug_info_t *qdio_dbf_slsb_out=NULL;
-static debug_info_t *qdio_dbf_slsb_in=NULL;
-#endif /* QDIO_DBF_LIKE_HELL */
-
-static qdio_irq_t *first_irq[QDIO_IRQ_BUCKETS];
-static rwlock_t irq_list_lock[QDIO_IRQ_BUCKETS]={
-	[0 ... (QDIO_IRQ_BUCKETS-1)] = RW_LOCK_UNLOCKED
-};
-
-static struct semaphore init_sema;
-
-static qdio_chsc_area_t *chsc_area;
-/* iQDIO stuff: */
-static volatile qdio_q_t *iq_list=NULL; /* volatile as it could change
-					   during a while loop */
-static spinlock_t iq_list_lock=SPIN_LOCK_UNLOCKED;
-static int register_thinint_result;
-static void iqdio_tl(unsigned long);
-static DECLARE_TASKLET(iqdio_tasklet,iqdio_tl,0);
-
-#define HEXDUMP16(importance,header,ptr) \
-QDIO_PRINT_##importance(header "%02x %02x %02x %02x  " \
-			"%02x %02x %02x %02x  %02x %02x %02x %02x  " \
-			"%02x %02x %02x %02x\n",*(((char*)ptr)), \
-			*(((char*)ptr)+1),*(((char*)ptr)+2), \
-			*(((char*)ptr)+3),*(((char*)ptr)+4), \
-			*(((char*)ptr)+5),*(((char*)ptr)+6), \
-			*(((char*)ptr)+7),*(((char*)ptr)+8), \
-			*(((char*)ptr)+9),*(((char*)ptr)+10), \
-			*(((char*)ptr)+11),*(((char*)ptr)+12), \
-			*(((char*)ptr)+13),*(((char*)ptr)+14), \
-			*(((char*)ptr)+15)); \
-QDIO_PRINT_##importance(header "%02x %02x %02x %02x  %02x %02x %02x %02x  " \
-			"%02x %02x %02x %02x  %02x %02x %02x %02x\n", \
-			*(((char*)ptr)+16),*(((char*)ptr)+17), \
-			*(((char*)ptr)+18),*(((char*)ptr)+19), \
-			*(((char*)ptr)+20),*(((char*)ptr)+21), \
-			*(((char*)ptr)+22),*(((char*)ptr)+23), \
-			*(((char*)ptr)+24),*(((char*)ptr)+25), \
-			*(((char*)ptr)+26),*(((char*)ptr)+27), \
-			*(((char*)ptr)+28),*(((char*)ptr)+29), \
-			*(((char*)ptr)+30),*(((char*)ptr)+31));
-
-#define atomic_swap(a,b) xchg((int*)a.counter,b)
-
-/* not a macro, as one of the arguments is atomic_read */
-static inline int qdio_min(int a,int b)
-{
-	if (a<b)
-		return a;
-	else
-		return b;
-}
-
-#define SYNC_MEMORY if (q->siga_sync) qdio_siga_sync(q)
-#define NOW qdio_get_micros()
-#define SAVE_TIMESTAMP(q) q->timing.last_transfer_time=NOW
-#define GET_SAVED_TIMESTAMP(q) (q->timing.last_transfer_time)
-#define SAVE_FRONTIER(q,val) q->last_move_ftc=val
-#define GET_SAVED_FRONTIER(q) (q->last_move_ftc)
-
-#define MY_MODULE_STRING(x) #x
-
-#ifdef QDIO_DBF_LIKE_HELL
-
-#define my_spin_lock(x) do { \
-	void *ptr=x; \
-	QDIO_DBF_TEXT6(0,trace,"sp_lck"); \
-	QDIO_DBF_HEX6(0,trace,&ptr,sizeof(void*)); \
-	spin_lock(x); \
-} while (0)
-#define my_spin_unlock(x) do { \
-	void *ptr=x; \
-	QDIO_DBF_TEXT6(0,trace,"sp_unlck"); \
-	QDIO_DBF_HEX6(0,trace,&ptr,sizeof(void*)); \
-	spin_unlock(x); \
-} while (0)
-#define my_spin_lock_irqsave(x,y) do { \
-	void *ptr=x; \
-	QDIO_DBF_TEXT6(0,trace,"sp_lck_i"); \
-	QDIO_DBF_HEX6(0,trace,&ptr,sizeof(void*)); \
-	spin_lock_irqsave(x,y); \
-} while (0)
-#define my_spin_unlock_irqrestore(x,y) do { \
-	void *ptr=x; \
-        QDIO_DBF_TEXT6(0,trace,"sp_nlk_i"); \
-	QDIO_DBF_HEX6(0,trace,&ptr,sizeof(void*)); \
-	spin_unlock_irqrestore(x,y); \
-} while (0)
-#define my_s390irq_spin_lock_irqsave(x,y) do { \
-	void *ptr=x; \
-	QDIO_DBF_TEXT6(0,trace,"sp_lck3i"); \
-	QDIO_DBF_HEX6(0,trace,&ptr,sizeof(void*)); \
-	s390irq_spin_lock_irqsave(x,y); \
-} while (0)
-#define my_s390irq_spin_unlock_irqrestore(x,y) do { \
-	void *ptr=x; \
-        QDIO_DBF_TEXT6(0,trace,"sp_nlk3i"); \
-	QDIO_DBF_HEX6(0,trace,&ptr,sizeof(void*)); \
-	s390irq_spin_unlock_irqrestore(x,y); \
-} while (0)
-
-#else /* QDIO_DBF_LIKE_HELL */
-
-#define my_spin_lock(x) spin_lock(x)
-#define my_spin_unlock(x) spin_unlock(x)
-#define my_spin_lock_irqsave(x,y) spin_lock_irqsave(x,y)
-#define my_spin_unlock_irqrestore(x,y) spin_unlock_irqrestore(x,y)
-#define my_s390irq_spin_lock_irqsave(x,y) s390irq_spin_lock_irqsave(x,y)
-#define my_s390irq_spin_unlock_irqrestore(x,y) s390irq_spin_unlock_irqrestore(x,y)
-
-#endif /* QDIO_DBF_LIKE_HELL */
- 
-#ifdef QDIO_32_BIT
-#define QDIO_GET_ADDR(x) ((__u32)(long)x)
-#else /* QDIO_32_BIT */
-#define QDIO_GET_ADDR(x) ((__u32)(unsigned long)x)
-#endif /* QDIO_32_BIT */
-
-
-/***************** SCRUBBER HELPER ROUTINES **********************/
-
-static inline volatile __u64 qdio_get_micros(void)
-{
-        __u64 time;
-
-        asm volatile ("STCK %0" : "=m" (time));
-        return time>>12; /* time>>12 is microseconds*/
-}
-static inline unsigned long qdio_get_millis(void)
-{
-	return (unsigned long)(qdio_get_micros()>>12);
-}
-
-static __inline__ int atomic_return_add (int i, atomic_t *v)
-{
-	int old, new;
-	__CS_LOOP(old, new, v, i, "ar");
-	return old;
-}
-
-static void qdio_wait_nonbusy(unsigned int timeout)
-{
-        unsigned int start;
-        char dbf_text[15];
-
-	sprintf(dbf_text,"wtnb%4x",timeout);
-	QDIO_DBF_TEXT3(0,trace,dbf_text);
-
-	start=qdio_get_millis();
-	for (;;) {
-		set_task_state(current,TASK_INTERRUPTIBLE);
-		if (qdio_get_millis()-start>timeout) {
-			goto out;
-		}
-		schedule_timeout(((start+timeout-qdio_get_millis())>>10)*HZ);
-	}
-out:
-	set_task_state(current,TASK_RUNNING);
-}
-
-static int qdio_wait_for_no_use_count(atomic_t *use_count)
-{
-	unsigned long start;
-
-	QDIO_DBF_TEXT3(0,trace,"wtnousec");
-	start=qdio_get_millis();
-	for (;;) {
-		if (qdio_get_millis()-start>QDIO_NO_USE_COUNT_TIMEOUT) {
-			QDIO_DBF_TEXT1(1,trace,"WTNOUSTO");
-			return -ETIME;
-		}
-		if (!atomic_read(use_count)) {
-			QDIO_DBF_TEXT3(0,trace,"wtnoused");
-			return 0;
-		}
-		qdio_wait_nonbusy(QDIO_NO_USE_COUNT_TIME);
-	}
-}
-
-/* unfortunately, we can't just xchg the values; in do_QDIO we want to reserve
- * the q in any case, so that we'll not be interrupted when we are in
- * qdio_mark_iq... shouldn't have a really bad impact, as reserving almost
- * ever works (last famous words) */
-static inline int qdio_reserve_q(qdio_q_t *q)
-{
-	return atomic_return_add(1,&q->use_count);
-}
-
-static inline void qdio_release_q(qdio_q_t *q)
-{
-	atomic_dec(&q->use_count);
-}
-#ifdef QDIO_DBF_LIKE_HELL 
-#define set_slsb(x,y) \
-  if(q->queue_type==QDIO_TRACE_QTYPE) { \
-        if(q->is_input_q) { \
-            QDIO_DBF_HEX2(0,slsb_in,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \
-        } else { \
-            QDIO_DBF_HEX2(0,slsb_out,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \
-        } \
-  } \
-  qdio_set_slsb(x,y); \
-  if(q->queue_type==QDIO_TRACE_QTYPE) { \
-        if(q->is_input_q) { \
-            QDIO_DBF_HEX2(0,slsb_in,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \
-        } else { \
-            QDIO_DBF_HEX2(0,slsb_out,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \
-        } \
-  }
-#else /* QDIO_DBF_LIKE_HELL */
-#define set_slsb(x,y) qdio_set_slsb(x,y)
-#endif /* QDIO_DBF_LIKE_HELL */
-static volatile inline void qdio_set_slsb(volatile char *slsb,
-					  unsigned char value)
-{
-	xchg((char*)slsb,value);
-}
-
-static inline int qdio_siga_sync(qdio_q_t *q)
-{
-	unsigned int gpr2,gpr3;
-	int cc;
-
-#ifdef QDIO_DBF_LIKE_HELL
-	QDIO_DBF_TEXT4(0,trace,"sigasync");
-	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-
-#ifdef QDIO_PERFORMANCE_STATS
-	perf_stats.siga_syncs++;
-#endif /* QDIO_PERFORMANCE_STATS */
-	if (q->is_input_q) {
-		gpr2=0;
-		gpr3=q->mask;
-	} else {
-		gpr2=q->mask;
-		gpr3=0;
-	}
-
-#ifdef QDIO_32_BIT
-	asm volatile (
-		"lhi	0,2	\n\t"
-		"lr	1,%1	\n\t"
-		"lr	2,%2	\n\t"
-		"lr	3,%3	\n\t"
-		"siga   0	\n\t"
-		"ipm	%0	\n\t"
-		"srl	%0,28	\n\t"
-		: "=d" (cc)
-		: "d" (0x10000|q->irq), "d" (gpr2), "d" (gpr3)
-		: "cc", "0", "1", "2", "3"
-		);
-#else /* QDIO_32_BIT */
-	asm volatile (
-		"lghi	0,2	\n\t"
-		"llgfr	1,%1	\n\t"
-		"llgfr	2,%2	\n\t"
-		"llgfr	3,%3	\n\t"
-		"siga   0	\n\t"
-		"ipm	%0	\n\t"
-		"srl	%0,28	\n\t"
-		: "=d" (cc)
-		: "d" (0x10000|q->irq), "d" (gpr2), "d" (gpr3)
-		: "cc", "0", "1", "2", "3"
-		);
-#endif /* QDIO_32_BIT */
-
-	if (cc) {
-#ifndef QDIO_DBF_LIKE_HELL
-		/* when QDIO_DBF_LIKE_HELL, we put that already out */
-		QDIO_DBF_TEXT3(0,trace,"sigasync");
-		QDIO_DBF_HEX3(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-		QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*));
-	}
-
-	return cc;
-}
-
-/* returns QDIO_SIGA_ERROR_ACCESS_EXCEPTION as cc, when SIGA returns
-   an access exception */
-static inline int qdio_siga_output(qdio_q_t *q)
-{
-	int cc;
-	__u32 busy_bit;
-	__u64 start_time=0;
-
-#ifdef QDIO_PERFORMANCE_STATS
-	perf_stats.siga_outs++;
-#endif /* QDIO_PERFORMANCE_STATS */
-
-#ifdef QDIO_DBF_LIKE_HELL
-	QDIO_DBF_TEXT4(0,trace,"sigaout");
-	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	for (;;) {
-
-#ifdef QDIO_32_BIT
-		asm volatile (
-		      "lhi	0,0	\n\t"
-		      "lr	1,%2	\n\t"
-		      "lr	2,%3	\n\t"
-		      "siga	0	\n\t"
-		      "0:"
-		      "ipm	%0	\n\t"
-		      "srl	%0,28	\n\t"
-		      "srl	0,31	\n\t"
-		      "lr	%1,0	\n\t"
-		      "1:	\n\t"
-		      ".section .fixup,\"ax\"\n\t"
-		      "2:	\n\t"
-		      "lhi	%0,%4	\n\t"
-		      "bras	1,3f	\n\t"
-		      ".long 1b	\n\t"
-		      "3:	\n\t"
-		      "l	1,0(1)	\n\t"
-		      "br	1	\n\t"
-		      ".previous	\n\t"
-		      ".section __ex_table,\"a\"\n\t"
-		      ".align 4	\n\t"
-		      ".long	0b,2b	\n\t"
-		      ".previous	\n\t"
-			: "=d" (cc), "=d" (busy_bit)
-			: "d" (0x10000|q->irq), "d" (q->mask),
-			"i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION)
-			: "cc", "0", "1", "2", "memory"
-		);
-#else /* QDIO_32_BIT */
-		asm volatile (
-		      "lghi	0,0	\n\t"
-		      "llgfr	1,%2	\n\t"
-		      "llgfr	2,%3	\n\t"
-	      	      "siga	0	\n\t"
-		      "0:"
-		      "ipm	%0	\n\t"
-		      "srl	%0,28	\n\t"
-		      "srl	0,31	\n\t"
-		      "llgfr	%1,0	\n\t"
-		      "1:	\n\t"
-		      ".section .fixup,\"ax\"\n\t"
-		      "lghi	%0,%4	\n\t"
-		      "jg	1b	\n\t"
-		      ".previous\n\t"
-      		      ".section __ex_table,\"a\"\n\t"
-      		      ".align 8	\n\t"
-      		      ".quad	0b,1b	\n\t"
-      		      ".previous	\n\t"
-		      : "=d" (cc), "=d" (busy_bit)
-		      : "d" (0x10000|q->irq), "d" (q->mask),
-	      	      "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION)
-	      	      : "cc", "0", "1", "2", "memory"
-	     );
-#endif /* QDIO_32_BIT */
-
-//QDIO_PRINT_ERR("cc=%x, busy=%x\n",cc,busy_bit);
-	     if ( (cc==2) && (busy_bit) &&
-		  (q->is_iqdio_q) ) {
-		     if (!start_time) start_time=NOW;
-		     if ((NOW-start_time)>QDIO_BUSY_BIT_PATIENCE)
-			     break;
-	     } else
-		     break;
-	}
-
-	if ((cc==2) && (busy_bit)) cc|=QDIO_SIGA_ERROR_B_BIT_SET;
-
-	if (cc) {
-#ifndef QDIO_DBF_LIKE_HELL
-		QDIO_DBF_TEXT3(0,trace,"sigaout");
-		QDIO_DBF_HEX3(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-		QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*));
-	}
-
-	return cc;
-}
-
-static inline int qdio_siga_input(qdio_q_t *q)
-{
-	int cc;
-
-#ifdef QDIO_DBF_LIKE_HELL
-	QDIO_DBF_TEXT4(0,trace,"sigain");
-	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-
-#ifdef QDIO_PERFORMANCE_STATS
-	perf_stats.siga_ins++;
-#endif /* QDIO_PERFORMANCE_STATS */
-
-#ifdef QDIO_32_BIT
-	asm volatile (
-		"lhi	0,1	\n\t"
-		"lr	1,%1	\n\t"
-		"lr	2,%2	\n\t"
-		"siga   0	\n\t"
-		"ipm	%0	\n\t"
-		"srl	%0,28	\n\t"
-		: "=d" (cc)
-		: "d" (0x10000|q->irq), "d" (q->mask)
-		: "cc", "0", "1", "2", "memory"
-		);
-#else /* QDIO_32_BIT */
-	asm volatile (
-		"lghi	0,1	\n\t"
-		"llgfr	1,%1	\n\t"
-		"llgfr	2,%2	\n\t"
-		"siga   0	\n\t"
-		"ipm	%0	\n\t"
-		"srl	%0,28	\n\t"
-		: "=d" (cc)
-		: "d" (0x10000|q->irq), "d" (q->mask)
-		: "cc", "0", "1", "2", "memory"
-		);
-#endif /* QDIO_32_BIT */
-
-	if (cc) {
-#ifndef QDIO_DBF_LIKE_HELL
-		QDIO_DBF_TEXT3(0,trace,"sigain");
-		QDIO_DBF_HEX3(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-		QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*));
-	}
-
-	return cc;
-}
-
-/* locked by the locks in qdio_activate and qdio_cleanup */
-static __u32 * volatile qdio_get_indicator(void)
-{
-	int i=1;
-	int found=0;
-
-	while (i<INDICATORS_PER_CACHELINE) {
-		if (!indicator_used[i]) {
-			indicator_used[i]=1;
-			found=1;
-			break;
-		}
-		i++;
-	}
-
-	if (found)
-		return indicators+i;
-	else
-		return (__u32 * volatile) &spare_indicator;
-}
-
-/* locked by the locks in qdio_activate and qdio_cleanup */
-static void qdio_put_indicator(__u32 *addr)
-{
-	int i;
-
-	if ( (addr) && (addr!=&spare_indicator) ) {
-		i=addr-indicators;
-		indicator_used[i]=0;
-	}
-}
-
-static inline volatile void iqdio_clear_summary_bit(__u32 *location)
-{
-#ifdef QDIO_DBF_LIKE_HELL
-	QDIO_DBF_TEXT5(0,trace,"clrsummb");
-	QDIO_DBF_HEX5(0,trace,&location,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-	xchg(location,0);
-}
-
-static inline volatile void iqdio_set_summary_bit(__u32 *location)
-{
-#ifdef QDIO_DBF_LIKE_HELL
-	QDIO_DBF_TEXT5(0,trace,"setsummb");
-	QDIO_DBF_HEX5(0,trace,&location,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-	xchg(location,-1);
-}
-
-static inline void iqdio_sched_tl(void)
-{
-	tasklet_hi_schedule(&iqdio_tasklet);
-}
-
-static inline void qdio_mark_iq(qdio_q_t *q)
-{
-	unsigned long flags;
-#ifdef QDIO_DBF_LIKE_HELL
-	QDIO_DBF_TEXT4(0,trace,"mark iq");
-	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	my_spin_lock_irqsave(&iq_list_lock,flags);
-	if (atomic_read(&q->is_in_shutdown)) goto out_unlock;
-
-	if (q->is_input_q) {
-		if ((q->list_prev) || (q->list_next)) goto out_unlock;
-
-		if (!iq_list) {
-			iq_list=q;
-			q->list_prev=q;
-			q->list_next=q;
-		} else {
-			q->list_next=iq_list;
-			q->list_prev=iq_list->list_prev;
-			iq_list->list_prev->list_next=q;
-			iq_list->list_prev=q;
-		}
-		my_spin_unlock_irqrestore(&iq_list_lock,flags);
-
-		iqdio_set_summary_bit((__u32*)q->dev_st_chg_ind);
-		iqdio_sched_tl();
-	}
-	return;
-out_unlock:
-	my_spin_unlock_irqrestore(&iq_list_lock,flags);
-	return;
-}
-
-static inline void qdio_mark_q(qdio_q_t *q)
-{
-#ifdef QDIO_DBF_LIKE_HELL
-	QDIO_DBF_TEXT4(0,trace,"mark q");
-	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	if (atomic_read(&q->is_in_shutdown)) return;
-
-	tasklet_schedule(&q->tasklet);
-}
-
-static inline int qdio_stop_polling(qdio_q_t *q)
-{
-#ifdef QDIO_USE_PROCESSING_STATE
-	int gsf;
-
-	if (!atomic_swap(&q->polling,0)) return 1;
-
-#ifdef QDIO_DBF_LIKE_HELL
-	QDIO_DBF_TEXT4(0,trace,"stoppoll");
-	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	/* show the card that we are not polling anymore */
-	if (q->is_input_q) {
-		gsf=GET_SAVED_FRONTIER(q);
-		set_slsb(&q->slsb.acc.val[(gsf+QDIO_MAX_BUFFERS_PER_Q-1)&
-			 (QDIO_MAX_BUFFERS_PER_Q-1)],SLSB_P_INPUT_NOT_INIT);
-		/* we don't issue this SYNC_MEMORY, as we trust Rick T and
-		 * moreover will not use the PROCESSING state, so q->polling
-		 * was 0
-		SYNC_MEMORY;*/
-		if (q->slsb.acc.val[gsf]==SLSB_P_INPUT_PRIMED) {
-			/* set our summary bit again, as otherwise there is a
-			 * small window we can miss between resetting it and
-			 * checking for PRIMED state */
-			if (q->is_iqdio_q)
-				iqdio_set_summary_bit
-					((__u32*)q->dev_st_chg_ind);
-			return 0;
-		}
-	}
-#endif /* QDIO_USE_PROCESSING_STATE */
-	return 1;
-}
-
-/* see the comment in do_QDIO and before qdio_reserve_q about the
- * sophisticated locking outside of unmark_q, so that we don't need to
- * disable the interrupts :-) */
-static inline void qdio_unmark_q(qdio_q_t *q)
-{
-	unsigned long flags;
-
-#ifdef QDIO_DBF_LIKE_HELL
-	QDIO_DBF_TEXT4(0,trace,"unmark q");
-	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	if ((!q->list_prev)||(!q->list_next)) return;
-
-	if ((q->is_iqdio_q)&&(q->is_input_q)) {
-		/* iQDIO */
-		my_spin_lock_irqsave(&iq_list_lock,flags);
-		if (q->list_next==q) {
-			/* q was the only interesting q */
-			iq_list=NULL;
-			q->list_next=NULL;
-			q->list_prev=NULL;
-		} else {
-			q->list_next->list_prev=q->list_prev;
-			q->list_prev->list_next=q->list_next;
-			iq_list=q->list_next;
-			q->list_next=NULL;
-			q->list_prev=NULL;
-		}
-		my_spin_unlock_irqrestore(&iq_list_lock,flags);
-	}
-}
-
-static inline volatile unsigned long iqdio_clear_global_summary(void)
-{
-	unsigned long time;
-
-#ifdef QDIO_DBF_LIKE_HELL
-	QDIO_DBF_TEXT5(0,trace,"clrglobl");
-#endif /* QDIO_DBF_LIKE_HELL */
-
-#ifdef QDIO_32_BIT
-	asm volatile (
-		"lhi	1,3	\n\t"
-		".insn	rre,0xb2650000,2,0	\n\t"
-		"lr	%0,3	\n\t"
-		: "=d" (time) : : "cc", "1", "2", "3"
-		);
-#else /* QDIO_32_BIT */
-	asm volatile (
-		"lghi	1,3	\n\t"
-		".insn	rre,0xb2650000,2,0	\n\t"
-		"lgr	%0,3	\n\t"
-		: "=d" (time) : : "cc", "1", "2", "3"
-		);
-#endif /* QDIO_32_BIT */
-
-#ifdef QDIO_DBF_LIKE_HELL
-	QDIO_DBF_HEX5(0,trace,&time,sizeof(unsigned long));
-#endif /* QDIO_DBF_LIKE_HELL */
-	return time;
-}
-
-/************************* INBOUND ROUTINES *******************************/
-
-
-inline static int qdio_get_inbound_buffer_frontier(qdio_q_t *q)
-{
-	int f,f_mod_no;
-	volatile char *slsb;
-	char slsbyte;
-	int first_not_to_check;
-	char dbf_text[15];
-
-#ifdef QDIO_DBF_LIKE_HELL
-	QDIO_DBF_TEXT4(0,trace,"getibfro");
-	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	slsb=&q->slsb.acc.val[0];
-	f_mod_no=f=q->first_to_check;
-	/* we don't check 128 buffers, as otherwise qdio_has_inbound_q_moved
-	 * would return 0 */
-	first_not_to_check=f+qdio_min(atomic_read(&q->number_of_buffers_used),
-				      (QDIO_MAX_BUFFERS_PER_Q-1));
-
-	/* we don't use this one, as a PCI or we after a thin interrupt
-	 * will sync the queues
-	SYNC_MEMORY;*/
-
-check_next:
-	f_mod_no=f&(QDIO_MAX_BUFFERS_PER_Q-1);
-	if (f==first_not_to_check) goto out;
-	slsbyte=slsb[f_mod_no];
-
-	/* CU_EMPTY means frontier is reached */
-	if (slsbyte==SLSB_CU_INPUT_EMPTY) {
-#ifdef QDIO_DBF_LIKE_HELL
-		QDIO_DBF_TEXT5(0,trace,"inptempt");
-#endif /* QDIO_DBF_LIKE_HELL */
-		goto out;
-	}
-
-	/* P_PRIMED means set slsb to P_PROCESSING and move on */
-	if (slsbyte==SLSB_P_INPUT_PRIMED) {
-#ifdef QDIO_DBF_LIKE_HELL
-		QDIO_DBF_TEXT5(0,trace,"inptprim");
-#endif /* QDIO_DBF_LIKE_HELL */
-
-#ifdef QDIO_USE_PROCESSING_STATE
-		/* as soon as running under VM, polling the input queues will
-		 * kill VM in terms of CP overhead */
-		if (q->siga_sync) {
-			set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT);
-		} else {
-			set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_PROCESSING);
-			atomic_set(&q->polling,1);
-		}
-#else /* QDIO_USE_PROCESSING_STATE */
-		set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT);
-#endif /* QDIO_USE_PROCESSING_STATE */
-		/* not needed, as the inbound queue will be synced on the next
-		 * siga-r
-		SYNC_MEMORY;*/
-		f++;
-		atomic_dec(&q->number_of_buffers_used);
-		goto check_next;
-	}
-
-	if ( (slsbyte==SLSB_P_INPUT_NOT_INIT) ||
-	     (slsbyte==SLSB_P_INPUT_PROCESSING) ) {
-#ifdef QDIO_DBF_LIKE_HELL
-		QDIO_DBF_TEXT5(0,trace,"inpnipro");
-#endif /* QDIO_DBF_LIKE_HELL */
-		goto out;
-	}
-
-	/* P_ERROR means frontier is reached, break and report error */
-	if (slsbyte==SLSB_P_INPUT_ERROR) {
-		sprintf(dbf_text,"inperr%2x",f_mod_no);
-		QDIO_DBF_TEXT3(1,trace,dbf_text);
-		QDIO_DBF_HEX2(1,sbal,q->sbal[f_mod_no],256);
-
-		/* kind of process the buffer */
-		set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT);
-
-		if (q->qdio_error)
-			q->error_status_flags|=
-				QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR;
-		q->qdio_error=SLSB_P_INPUT_ERROR;
-		q->error_status_flags|=QDIO_STATUS_LOOK_FOR_ERROR;
-
-		/* we increment the frontier, as this buffer
-		 * was processed obviously */
-		f_mod_no=(f_mod_no+1)&(QDIO_MAX_BUFFERS_PER_Q-1);
-		atomic_dec(&q->number_of_buffers_used);
-
-		goto out;
-	}
-
-	/* everything else means frontier not changed (HALTED or so) */
-out:
-	q->first_to_check=f_mod_no;
-
-#ifdef QDIO_DBF_LIKE_HELL
-	QDIO_DBF_HEX4(0,trace,&q->first_to_check,sizeof(int));
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	return q->first_to_check;
-}
-
-inline static int qdio_has_inbound_q_moved(qdio_q_t *q)
-{
-	int i;
-
-#ifdef QDIO_PERFORMANCE_STATS
-	static int old_pcis=0;
-	static int old_thinints=0;
-
-	if ((old_pcis==perf_stats.pcis)&&(old_thinints==perf_stats.thinints))
-		perf_stats.start_time_inbound=NOW;
-	else
-		old_pcis=perf_stats.pcis;
-#endif /* QDIO_PERFORMANCE_STATS */
-
-	i=qdio_get_inbound_buffer_frontier(q);
-	if ( (i!=GET_SAVED_FRONTIER(q)) ||
-	     (q->error_status_flags&QDIO_STATUS_LOOK_FOR_ERROR) ) {
-		SAVE_FRONTIER(q,i);
-		if ((!q->siga_sync)&&(!q->hydra_gives_outbound_pcis)) {
-			SAVE_TIMESTAMP(q);
-		}
-
-#ifdef QDIO_DBF_LIKE_HELL
-		QDIO_DBF_TEXT4(0,trace,"inhasmvd");
-		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-		return 1;
-	} else {
-#ifdef QDIO_DBF_LIKE_HELL
-		QDIO_DBF_TEXT4(0,trace,"inhsntmv");
-		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-		return 0;
-	}
-}
-
-/* means, no more buffers to be filled */
-inline static int iqdio_is_inbound_q_done(qdio_q_t *q)
-{
-	int no_used;
-#ifdef QDIO_DBF_LIKE_HELL
-	char dbf_text[15];
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	no_used=atomic_read(&q->number_of_buffers_used);
-
-	/* propagate the change from 82 to 80 through VM */
-	SYNC_MEMORY;
-
-#ifdef QDIO_DBF_LIKE_HELL
-	if (no_used) {
-		sprintf(dbf_text,"iqisnt%02x",no_used);
-		QDIO_DBF_TEXT4(0,trace,dbf_text);
-	} else {
-		QDIO_DBF_TEXT4(0,trace,"iniqisdo");
-	}
-	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	if (!no_used) {
-		return 1;
-	}
-
-	if (q->siga_sync) {
-		if (q->slsb.acc.val[q->first_to_check]==SLSB_P_INPUT_PRIMED) {
-			/* ok, the next input buffer is primed. that means,
-			 * that device state change indicator and adapter
-			 * local summary are set, so we will find it next
-			 * time.
-			 * we will return 0 below, as there is nothing to
-			 * do, except of scheduling ourselves for the next
-			 * time. */
-			iqdio_set_summary_bit((__u32*)q->dev_st_chg_ind);
-			iqdio_sched_tl();
-		} else {
-			/* nothing more to do, if next buffer is not PRIMED.
-			 * note that we did a SYNC_MEMORY before, that there
-			 * has been a sychnronization.
-			 * we will return 0 below, as there is nothing to do
-			 * (stop_polling not necessary, as we have not been
-			 * using the PROCESSING state */
-		}
-	} else {
-		/* we'll check for more primed buffers
-		 * in qeth_stop_polling */
-	}
-
-	return 0;
-}
-
-inline static int qdio_is_inbound_q_done(qdio_q_t *q)
-{
-	int no_used;
-#ifdef QDIO_DBF_LIKE_HELL
-	char dbf_text[15];
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	no_used=atomic_read(&q->number_of_buffers_used);
-
-	/* we need that one for synchronization with Hydra, as Hydra
-	 * does a kind of PCI avoidance */
-	SYNC_MEMORY;
-
-	if (!no_used) {
-#ifdef QDIO_DBF_LIKE_HELL
-		QDIO_DBF_TEXT4(0,trace,"inqisdnA");
-		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-		QDIO_DBF_TEXT4(0,trace,dbf_text);
-#endif /* QDIO_DBF_LIKE_HELL */
-		return 1;
-	}
-
-	if (q->slsb.acc.val[q->first_to_check]==SLSB_P_INPUT_PRIMED) {
-		/* we got something to do */
-#ifdef QDIO_DBF_LIKE_HELL
-		QDIO_DBF_TEXT4(0,trace,"inqisntA");
-		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-		return 0;
-	}
-
-	/* on VM, we don't poll, so the q is always done here */
-	if (q->siga_sync) return 1;
-	if (q->hydra_gives_outbound_pcis) return 1;
-
-	/* at this point we know, that inbound first_to_check
-	   has (probably) not moved (see qdio_inbound_processing) */
-	if (NOW>GET_SAVED_TIMESTAMP(q)+q->timing.threshold) {
-#ifdef QDIO_DBF_LIKE_HELL
-		QDIO_DBF_TEXT4(0,trace,"inqisdon");
-		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-		sprintf(dbf_text,"pf%02xcn%02x",q->first_to_check,no_used);
-		QDIO_DBF_TEXT4(0,trace,dbf_text);
-#endif /* QDIO_DBF_LIKE_HELL */
-		return 1;
-	} else {
-#ifdef QDIO_DBF_LIKE_HELL
-		QDIO_DBF_TEXT4(0,trace,"inqisntd");
-		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-		sprintf(dbf_text,"pf%02xcn%02x",q->first_to_check,no_used);
-		QDIO_DBF_TEXT4(0,trace,dbf_text);
-#endif /* QDIO_DBF_LIKE_HELL */
-		return 0;
-	}
-}
-
-static inline void qdio_translate_buffer_back(qdio_q_t *q,int bufno)
-{
-	if (!q->is_0copy_sbals_q)
-		memcpy(q->qdio_buffers[bufno],
-		       (void*)q->sbal[bufno],SBAL_SIZE);
-}
-
-inline static void qdio_kick_inbound_handler(qdio_q_t *q)
-{
-	int count=0;
-	int start,end,real_end,i;
-#ifdef QDIO_DBF_LIKE_HELL
-	char dbf_text[15];
-
-	QDIO_DBF_TEXT4(0,trace,"kickinh");
-	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	start=q->first_element_to_kick;
-	real_end=q->first_to_check;
-	end=(real_end+QDIO_MAX_BUFFERS_PER_Q-1)&(QDIO_MAX_BUFFERS_PER_Q-1);
-
-	i=start;
-	while (1) {
-		count++;
-		qdio_translate_buffer_back(q,i);
-		if (i==end) break;
-		i=(i+1)&(QDIO_MAX_BUFFERS_PER_Q-1);
-	}
-
-#ifdef QDIO_DBF_LIKE_HELL
-	sprintf(dbf_text,"s=%2xc=%2x",start,count);
-	QDIO_DBF_TEXT4(0,trace,dbf_text);
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	if (q->state==QDIO_IRQ_STATE_ACTIVE)
-		q->handler(q->irq,
-			   QDIO_STATUS_INBOUND_INT|q->error_status_flags,
-			   q->qdio_error,q->siga_error,q->q_no,start,count,
-			   q->int_parm);
-
-	/* for the next time: */
-	q->first_element_to_kick=real_end;
-	q->qdio_error=0;
-	q->siga_error=0;
-	q->error_status_flags=0;
-
-#ifdef QDIO_PERFORMANCE_STATS
-	perf_stats.inbound_time+=NOW-perf_stats.start_time_inbound;
-	perf_stats.inbound_cnt++;
-#endif /* QDIO_PERFORMANCE_STATS */
-}
-
-static inline void iqdio_inbound_processing(qdio_q_t *q)
-{
-#ifdef QDIO_DBF_LIKE_HELL
-	QDIO_DBF_TEXT4(0,trace,"iqinproc");
-	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	/* we first want to reserve the q, so that we know, that we don't
-	 * interrupt ourselves and call qdio_unmark_q, as is_in_shutdown might
-	 * be set */
-	if (qdio_reserve_q(q)) {
-		qdio_release_q(q);
-#ifdef QDIO_PERFORMANCE_STATS
-		ii_p_c++;
-#endif /* QDIO_PERFORMANCE_STATS */
-		/* as we might just be about to stop polling, we make
-		 * sure that we check again at least once more */
-		iqdio_sched_tl();
-		return;
-	}
-#ifdef QDIO_PERFORMANCE_STATS
-	ii_p_nc++;
-#endif /* QDIO_PERFORMANCE_STATS */
-	if (atomic_read(&q->is_in_shutdown)) {
-		qdio_unmark_q(q);
-		goto out;
-	}
-
-	if (*(q->dev_st_chg_ind)) {
-		iqdio_clear_summary_bit((__u32*)q->dev_st_chg_ind);
-
-		if (!q->siga_sync_done_on_thinints) {
-			SYNC_MEMORY;
-		}
-
-		if (qdio_has_inbound_q_moved(q)) {
-			qdio_kick_inbound_handler(q);
-			if (iqdio_is_inbound_q_done(q)) {
-				if (!qdio_stop_polling(q)) {
-					/* we set the flags to get into
-					 * the stuff next time, see also
-					 * comment in qdio_stop_polling */
-					iqdio_set_summary_bit
-						((__u32*)q->dev_st_chg_ind);
-					iqdio_sched_tl();
-				}
-			}
-		}
-	}
-out:
-	qdio_release_q(q);
-}
-
-static void qdio_inbound_processing(qdio_q_t *q)
-{
-	int q_laps=0;
-
-#ifdef QDIO_DBF_LIKE_HELL
-	QDIO_DBF_TEXT4(0,trace,"qinproc");
-	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	if (qdio_reserve_q(q)) {
-		qdio_release_q(q);
-#ifdef QDIO_PERFORMANCE_STATS
-		i_p_c++;
-#endif /* QDIO_PERFORMANCE_STATS */
-		/* as we're sissies, we'll check next time */
-		if (!atomic_read(&q->is_in_shutdown)) {
-			qdio_mark_q(q);
-#ifdef QDIO_DBF_LIKE_HELL
-			QDIO_DBF_TEXT4(0,trace,"busy,agn");
-#endif /* QDIO_DBF_LIKE_HELL */
-		}
-		return;
-	}
-#ifdef QDIO_PERFORMANCE_STATS
-	i_p_nc++;
-	perf_stats.tl_runs++;
-#endif /* QDIO_PERFORMANCE_STATS */
-
-again:
-	if (qdio_has_inbound_q_moved(q)) {
-		qdio_kick_inbound_handler(q);
-		if (!qdio_stop_polling(q)) {
-			q_laps++;
-			if (q_laps<QDIO_Q_LAPS) goto again;
-		}
-		qdio_mark_q(q);
-	} else {
-		if (!qdio_is_inbound_q_done(q)) /* means poll time is 
-						   not yet over */
-			qdio_mark_q(q);
-	}
-
-	qdio_release_q(q);
-}
-
-/************************* OUTBOUND ROUTINES *******************************/
-
-inline static int qdio_get_outbound_buffer_frontier(qdio_q_t *q)
-{
-	int f,f_mod_no;
-	volatile char *slsb;
-	int first_not_to_check;
-	char dbf_text[15];
-	char slsbyte;
-
-#ifdef QDIO_DBF_LIKE_HELL
-	QDIO_DBF_TEXT4(0,trace,"getobfro");
-	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	slsb=&q->slsb.acc.val[0];
-	f_mod_no=f=q->first_to_check;
-	/* f point to already processed elements, so f+no_used is correct...
-	 * ... but: we don't check 128 buffers, as otherwise
-	 * qdio_has_outbound_q_moved would return 0 */
-	first_not_to_check=f+qdio_min(atomic_read(&q->number_of_buffers_used),
-				      (QDIO_MAX_BUFFERS_PER_Q-1));
-
-	if ((!q->is_iqdio_q)&&(!q->hydra_gives_outbound_pcis)) {
-		SYNC_MEMORY;
-	}
-
-check_next:
-	if (f==first_not_to_check) goto out;
-	slsbyte=slsb[f_mod_no];
-
-	/* the hydra has not fetched the output yet */
-	if (slsbyte==SLSB_CU_OUTPUT_PRIMED) {
-#ifdef QDIO_DBF_LIKE_HELL
-		QDIO_DBF_TEXT5(0,trace,"outpprim");
-#endif /* QDIO_DBF_LIKE_HELL */
-		goto out;
-	}
-
-	/* the hydra got it */
-	if (slsbyte==SLSB_P_OUTPUT_EMPTY) {
-		atomic_dec(&q->number_of_buffers_used);
-		f++;
-		f_mod_no=f&(QDIO_MAX_BUFFERS_PER_Q-1);
-#ifdef QDIO_DBF_LIKE_HELL
-		QDIO_DBF_TEXT5(0,trace,"outpempt");
-#endif /* QDIO_DBF_LIKE_HELL */
-		goto check_next;
-	}
-
-	if (slsbyte==SLSB_P_OUTPUT_ERROR) {
-		QDIO_DBF_TEXT3(0,trace,"outperr");
-		sprintf(dbf_text,"%x-%x-%x",f_mod_no,
-			q->sbal[f_mod_no]->element[14].sbalf.value,
-			q->sbal[f_mod_no]->element[15].sbalf.value);
-		QDIO_DBF_TEXT3(1,trace,dbf_text);
-		QDIO_DBF_HEX2(1,sbal,q->sbal[f_mod_no],256);
-
-		/* kind of process the buffer */
-		set_slsb(&q->slsb.acc.val[f_mod_no],
-			 SLSB_P_OUTPUT_NOT_INIT);
-
-		qdio_translate_buffer_back(q,f_mod_no);
-
-		/* we increment the frontier, as this buffer
-		 * was processed obviously */
-		atomic_dec(&q->number_of_buffers_used);
-		f_mod_no=(f_mod_no+1)&(QDIO_MAX_BUFFERS_PER_Q-1);
-
-		if (q->qdio_error)
-			q->error_status_flags|=
-				QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR;
-		q->qdio_error=SLSB_P_OUTPUT_ERROR;
-		q->error_status_flags|=QDIO_STATUS_LOOK_FOR_ERROR;
-
-		goto out;
-	}
-
-	/* no new buffers */
-#ifdef QDIO_DBF_LIKE_HELL
-	QDIO_DBF_TEXT5(0,trace,"outpni");
-#endif /* QDIO_DBF_LIKE_HELL */
-	goto out;
-
-out:
-	return (q->first_to_check=f_mod_no);
-}
-
-/* all buffers are processed */
-inline static int qdio_is_outbound_q_done(qdio_q_t *q)
-{
-	int no_used;
-#ifdef QDIO_DBF_LIKE_HELL
-	char dbf_text[15];
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	no_used=atomic_read(&q->number_of_buffers_used);
-
-#ifdef QDIO_DBF_LIKE_HELL
-	if (no_used) {
-		sprintf(dbf_text,"oqisnt%02x",no_used);
-		QDIO_DBF_TEXT4(0,trace,dbf_text);
-	} else {
-		QDIO_DBF_TEXT4(0,trace,"oqisdone");
-	}
-	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-	return (no_used==0);
-}
-
-inline static int qdio_has_outbound_q_moved(qdio_q_t *q)
-{
-	int i;
-
-	i=qdio_get_outbound_buffer_frontier(q);
-
-	if ( (i!=GET_SAVED_FRONTIER(q)) ||
-	     (q->error_status_flags&QDIO_STATUS_LOOK_FOR_ERROR) ) {
-		SAVE_FRONTIER(q,i);
-		SAVE_TIMESTAMP(q);
-#ifdef QDIO_DBF_LIKE_HELL
-		QDIO_DBF_TEXT4(0,trace,"oqhasmvd");
-		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-		return 1;
-	} else {
-#ifdef QDIO_DBF_LIKE_HELL
-		QDIO_DBF_TEXT4(0,trace,"oqhsntmv");
-		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-		return 0;
-	}
-}
-
-inline static void qdio_kick_outbound_q(qdio_q_t *q)
-{
-	int result;
-#ifdef QDIO_DBF_LIKE_HELL
-	QDIO_DBF_TEXT4(0,trace,"kickoutq");
-	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	if (!q->siga_out) return;
-
-	result=qdio_siga_output(q);
-
-	if (result) {
-		if (q->siga_error)
-			q->error_status_flags|=
-				QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR;
-		q->error_status_flags|=
-			QDIO_STATUS_LOOK_FOR_ERROR;
-		q->siga_error=result;
-	}
-}
-
-inline static void qdio_kick_outbound_handler(qdio_q_t *q)
-{
-#ifdef QDIO_DBF_LIKE_HELL
-	char dbf_text[15];
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	int start=q->first_element_to_kick;
-	/* last_move_ftc was just updated */
-	int real_end=GET_SAVED_FRONTIER(q);
-	int end=(real_end+QDIO_MAX_BUFFERS_PER_Q-1)&
-		(QDIO_MAX_BUFFERS_PER_Q-1);
-	int count=(end+QDIO_MAX_BUFFERS_PER_Q+1-start)&
-		(QDIO_MAX_BUFFERS_PER_Q-1);
-
-#ifdef QDIO_DBF_LIKE_HELL
-	QDIO_DBF_TEXT4(0,trace,"kickouth");
-	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-
-#ifdef QDIO_DBF_LIKE_HELL
-	sprintf(dbf_text,"s=%2xc=%2x",start,count);
-	QDIO_DBF_TEXT4(0,trace,dbf_text);
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	if (q->state==QDIO_IRQ_STATE_ACTIVE)
-		q->handler(q->irq,QDIO_STATUS_OUTBOUND_INT|
-			   q->error_status_flags,
-			   q->qdio_error,q->siga_error,q->q_no,start,count,
-			   q->int_parm);
-
-	/* for the next time: */
-	q->first_element_to_kick=real_end;
-	q->qdio_error=0;
-	q->siga_error=0;
-	q->error_status_flags=0;
-}
-
-static void qdio_outbound_processing(qdio_q_t *q)
-{
-#ifdef QDIO_DBF_LIKE_HELL
-	QDIO_DBF_TEXT4(0,trace,"qoutproc");
-	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	if (qdio_reserve_q(q)) {
-		qdio_release_q(q);
-#ifdef QDIO_PERFORMANCE_STATS
-		o_p_c++;
-#endif /* QDIO_PERFORMANCE_STATS */
-		/* as we're sissies, we'll check next time */
-		if (!atomic_read(&q->is_in_shutdown)) {
-			qdio_mark_q(q);
-#ifdef QDIO_DBF_LIKE_HELL
-			QDIO_DBF_TEXT4(0,trace,"busy,agn");
-#endif /* QDIO_DBF_LIKE_HELL */
-		}
-		return;
-	}
-#ifdef QDIO_PERFORMANCE_STATS
-	o_p_nc++;
-#endif /* QDIO_PERFORMANCE_STATS */
-
-#ifdef QDIO_PERFORMANCE_STATS
-	perf_stats.tl_runs++;
-#endif /* QDIO_PERFORMANCE_STATS */
-
-	if (qdio_has_outbound_q_moved(q)) {
-		qdio_kick_outbound_handler(q);
-	}
-
-	if (q->is_iqdio_q) {
-		/* for asynchronous queues, we better check, if the fill
-		 * level is too high */
-		if (atomic_read(&q->number_of_buffers_used)>
-		    IQDIO_FILL_LEVEL_TO_POLL) {
-			qdio_mark_q(q);
-		}
-	} else if (!q->hydra_gives_outbound_pcis) {
-		if (!qdio_is_outbound_q_done(q)) {
-			qdio_mark_q(q);
-		}
-	}
-
-	qdio_release_q(q);
-}
-
-/************************* MAIN ROUTINES *******************************/
-
-static inline void iqdio_inbound_checks(void)
-{
-	qdio_q_t *q;
-#ifdef QDIO_USE_PROCESSING_STATE
-	int q_laps=0;
-#endif /* QDIO_USE_PROCESSING_STATE */
-
-#ifdef QDIO_DBF_LIKE_HELL
-	char dbf_text[15];
-
-	QDIO_DBF_TEXT4(0,trace,"iqdinbck");
-#endif /* QDIO_DBF_LIKE_HELL */
-
-#ifdef QDIO_DBF_LIKE_HELL
-	QDIO_DBF_TEXT5(0,trace,"iqlocsum");
-#endif /* QDIO_DBF_LIKE_HELL */
-
-#ifdef QDIO_USE_PROCESSING_STATE
-again:
-#endif /* QDIO_USE_PROCESSING_STATE */
-
-	q=(qdio_q_t*)iq_list;
-	do {
-		if (!q) break;
-		iqdio_inbound_processing(q);
-		q=(qdio_q_t*)q->list_next;
-	} while (q!=(qdio_q_t*)iq_list);
-
-#ifdef QDIO_USE_PROCESSING_STATE
-	q=(qdio_q_t*)iq_list;
-	do {
-		if (!q) {
-			iqdio_sched_tl();
-			break;
-		}
-		/* under VM, we have not used the PROCESSING state, so no
-		 * need to stop polling */
-		if (q->siga_sync) {
-			q=(qdio_q_t*)q->list_next;
-			continue;
-		}
-
-		if (qdio_reserve_q(q)) {
-			qdio_release_q(q);
-#ifdef QDIO_PERFORMANCE_STATS
-			ii_p_c++;
-#endif /* QDIO_PERFORMANCE_STATS */
-			/* as we might just be about to stop polling, we make
-			 * sure that we check again at least once more */
-
-			/* sanity -- we'd get here without setting the
-			 * dev st chg ind */
-			iqdio_set_summary_bit((__u32*)q->dev_st_chg_ind);
-			iqdio_sched_tl();
-			break;
-		}
-		if (!qdio_stop_polling(q)) {
-			q_laps++;
-			if (q_laps<QDIO_Q_LAPS) {
-				qdio_release_q(q);
-				goto again;
-			} else {
-				/* we set the flags to get into the stuff
-				 * next time, see also comment in
-				 * qdio_stop_polling */
-				iqdio_set_summary_bit((__u32*)
-						      q->dev_st_chg_ind);
-				iqdio_sched_tl();
-			}
-		}
-		qdio_release_q(q);
-		q=(qdio_q_t*)q->list_next;
-	} while (q!=(qdio_q_t*)iq_list);
-#endif /* QDIO_USE_PROCESSING_STATE */
-}
-
-static void iqdio_check_for_polling(void)
-{
-}
-
-static void iqdio_tl(unsigned long data)
-{
-#ifdef QDIO_DBF_LIKE_HELL
-	QDIO_DBF_TEXT4(0,trace,"iqdio_tl");
-#endif /* QDIO_DBF_LIKE_HELL */
-#ifdef QDIO_PERFORMANCE_STATS
-	perf_stats.tl_runs++;
-#endif /* QDIO_PERFORMANCE_STATS */
-
-	iqdio_inbound_checks();
-	iqdio_check_for_polling();
-}
-
-/********************* GENERAL HELPER_ROUTINES ***********************/
-
-static qdio_irq_t *qdio_get_irq_ptr(int irq)
-{
-	qdio_irq_t *irq_ptr;
-	int bucket=irq&(QDIO_IRQ_BUCKETS-1);
-
-	read_lock(&irq_list_lock[bucket]);
-	irq_ptr=first_irq[bucket];
-	while (irq_ptr) {
-		if (irq_ptr->irq==irq) break;
-		irq_ptr=irq_ptr->next;
-	}
-	read_unlock(&irq_list_lock[bucket]);
-	return irq_ptr;
-}
-
-static qdio_irq_t *qdio_get_irq_ptr_wolock(int irq)
-{
-	qdio_irq_t *irq_ptr=first_irq[irq&(QDIO_IRQ_BUCKETS-1)];
-
-	while (irq_ptr) {
-		if (irq_ptr->irq==irq) break;
-		irq_ptr=irq_ptr->next;
-	}
-	return irq_ptr;
-}
-
-/* irq_ptr->irq should be set already! */
-static void qdio_insert_irq_ptr(qdio_irq_t *irq_ptr)
-{
-	qdio_irq_t *i_p;
-	int irq,bucket;
-
-	if (!irq_ptr) return;
-
-	irq=irq_ptr->irq;
-	bucket=irq&(QDIO_IRQ_BUCKETS-1);
-
-	write_lock(&irq_list_lock[bucket]);
-
-	if (irq_ptr==qdio_get_irq_ptr_wolock(irq)) goto out;
-
-	if (!first_irq[bucket]) {
-		first_irq[bucket]=irq_ptr;
-	} else {
-		i_p=first_irq[bucket];
-		while (i_p->next)
-			i_p=i_p->next;
-		i_p->next=irq_ptr;
-	}
-	irq_ptr->next=NULL;
-out:
-	write_unlock(&irq_list_lock[bucket]);
-}
-
-static void qdio_remove_irq_ptr(qdio_irq_t *irq_ptr)
-{
-	qdio_irq_t *i_p;
-	int irq,bucket;
-
-	if (!irq_ptr) return;
-
-	irq=irq_ptr->irq;
-	bucket=irq&(QDIO_IRQ_BUCKETS-1);
-
-	write_lock(&irq_list_lock[bucket]);
-
-	if (!qdio_get_irq_ptr_wolock(irq)) goto out;
-
-	if (first_irq[irq&(QDIO_IRQ_BUCKETS-1)]==irq_ptr) {
-		first_irq[irq&(QDIO_IRQ_BUCKETS-1)]=irq_ptr->next;
-	} else {
-		for (i_p=first_irq[irq&(QDIO_IRQ_BUCKETS-1)];
-		     i_p->next!=irq_ptr;i_p=i_p->next);
-		i_p->next=irq_ptr->next;
-	}
-	irq_ptr->next=NULL;
-out:
-	write_unlock(&irq_list_lock[bucket]);
-}
-
-static void qdio_release_irq_memory(qdio_irq_t *irq_ptr)
-{
-	int i,j;
-	int available;
-
-	for (i=0;i<QDIO_MAX_QUEUES_PER_IRQ;i++) {
-		if (!irq_ptr->input_qs[i]) goto next;
-		available=0;
-		if (!irq_ptr->input_qs[i]->is_0copy_sbals_q)
-			for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
-				if (!available) {
-					if (irq_ptr->input_qs[i]->sbal[j])
-						kfree((void*)irq_ptr->
-						      input_qs[i]->sbal[j]);
-					available=PAGE_SIZE;
-				}
-				available-=sizeof(sbal_t);
-			}
-		if (irq_ptr->input_qs[i]->slib)
-			kfree(irq_ptr->input_qs[i]->slib);
-			kfree(irq_ptr->input_qs[i]);
-
-next:
-		if (!irq_ptr->output_qs[i]) continue;
-		available=0;
-		if (!irq_ptr->output_qs[i]->is_0copy_sbals_q)
-			for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
-				if (!available) {
-					if (irq_ptr->output_qs[i]->sbal[j])
-						kfree((void*)irq_ptr->
-						      output_qs[i]->sbal[j]);
-					available=PAGE_SIZE;
-				}
-				available-=sizeof(sbal_t);
-			}
-		if (irq_ptr->output_qs[i]->slib)
-			kfree(irq_ptr->output_qs[i]->slib);
-		kfree(irq_ptr->output_qs[i]);
-
-	}
-	if (irq_ptr->qdr) kfree(irq_ptr->qdr);
-	kfree(irq_ptr);
-	QDIO_DBF_TEXT3(0,setup,"MOD_DEC_");
-	MOD_DEC_USE_COUNT;
-}
-
-static inline void qdio_wakeup(atomic_t *var,qdio_irq_t *irq_ptr)
-{
-	wait_queue_head_t *wait_q;
-
-#ifdef QDIO_DBF_LIKE_HELL
-	char dbf_text[20];
-	sprintf(dbf_text,"qwkp%4x",irq_ptr->irq);
-	QDIO_DBF_TEXT3(0,trace,dbf_text);
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	atomic_set(var,1);
-	if ((wait_q=&irq_ptr->wait_q))
-		wake_up(wait_q);
-}
-
-static int qdio_sleepon(atomic_t *var,int timeout,qdio_irq_t *irq_ptr)
-{
-        __u64 stop;
-	int retval;
-        DECLARE_WAITQUEUE (current_wait_q,current);
-
-#ifdef QDIO_DBF_LIKE_HELL
-	char dbf_text[20];
-	sprintf(dbf_text,"qslp%4x",irq_ptr->irq);
-	QDIO_DBF_TEXT3(0,trace,dbf_text);
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	add_wait_queue(&irq_ptr->wait_q,&current_wait_q);
-        stop=(qdio_get_micros()>>10)+timeout;
-        for (;;) {
-		set_task_state(current,TASK_INTERRUPTIBLE);
-		if (atomic_read(var)) {
-			atomic_set(var,0);
-                        retval=0;
-			goto out;
-                }
-                if (qdio_get_micros()>>10>stop) {
-#ifdef QDIO_DBF_LIKE_HELL
-			sprintf(dbf_text,"%xtime",irq_ptr->irq);
-			QDIO_DBF_TEXT3(0,trace,dbf_text);
-#endif /* QDIO_DBF_LIKE_HELL */
-			retval=-ETIME;
-			goto out;
-		}
-                schedule_timeout(((stop-(qdio_get_micros()>>10))>>10)*HZ);
-        }
- out:
-	set_task_state(current,TASK_RUNNING);
-	remove_wait_queue(&irq_ptr->wait_q,&current_wait_q);
-	return retval;
-}
-
-static void qdio_set_impl_params(qdio_irq_t *irq_ptr,
-				 unsigned int qib_param_field_format,
-			  /* pointer to 128 bytes or NULL, if no param field */
-				 unsigned char *qib_param_field,
-			  /* pointer to no_queues*128 words of data or NULL */
-				 unsigned int no_input_qs,
-				 unsigned int no_output_qs,
-				 unsigned long *input_slib_elements,
-				 unsigned long *output_slib_elements)
-{
-	int i,j;
-
-	if (!irq_ptr) return;
-
-	irq_ptr->qib.pfmt=qib_param_field_format;
-	if (qib_param_field)
-		memcpy(irq_ptr->qib.parm,qib_param_field,
-		       QDIO_MAX_BUFFERS_PER_Q);
-
-	if (input_slib_elements)
-		for (i=0;i<no_input_qs;i++) {
-			for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++)
-				irq_ptr->input_qs[i]->slib->slibe[j].parms=
-					input_slib_elements[
-						i*QDIO_MAX_BUFFERS_PER_Q+j];
-		}
-	if (output_slib_elements)
-		for (i=0;i<no_output_qs;i++) {
-			for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++)
-				irq_ptr->output_qs[i]->slib->slibe[j].parms=
-					output_slib_elements[
-						i*QDIO_MAX_BUFFERS_PER_Q+j];
-		}
-}
-
-
-
-static int qdio_alloc_qs(qdio_irq_t *irq_ptr,int no_input_qs,int no_output_qs,
-			 qdio_handler_t *input_handler,
-			 qdio_handler_t *output_handler,
-			 unsigned long int_parm,int q_format,
-			 unsigned long flags,
-			 void **inbound_sbals_array,
-			 void **outbound_sbals_array)
-{
-	qdio_q_t *q;
-	int i,j,result=0;
-	char dbf_text[20]; /* see qdio_initialize */
-	void *ptr;
-	int available;
-
-	for (i=0;i<no_input_qs;i++) {
-		q=kmalloc(sizeof(qdio_q_t),GFP_KERNEL);
-
-		if (!q) {
-			QDIO_PRINT_ERR("kmalloc of q failed!\n");
-			goto out;
-		}
-		memset(q,0,sizeof(qdio_q_t));
-
-		sprintf(dbf_text,"in-q%4x",i);
-		QDIO_DBF_TEXT0(0,setup,dbf_text);
-		QDIO_DBF_HEX0(0,setup,&q,sizeof(void*));
-
-		q->slib=kmalloc(PAGE_SIZE,GFP_KERNEL);
-		if (!q->slib) {
-			QDIO_PRINT_ERR("kmalloc of slib failed!\n");
-			goto out;
-		}
-		memset(q->slib,0,PAGE_SIZE);
-		q->sl=(sl_t*)(((char*)q->slib)+PAGE_SIZE/2);
-
-		available=0;
-		if (flags&QDIO_INBOUND_0COPY_SBALS) {
-			for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
-				q->sbal[j]=*(inbound_sbals_array++);
-			}
-		} else for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
-			if (!available) {
-				q->sbal[j]=kmalloc(PAGE_SIZE,GFP_KERNEL);
-				if (!q->sbal[j]) {
-					goto out;
-				}
-				available=PAGE_SIZE;
-				memset((void*)q->sbal[j],0,PAGE_SIZE);
-			} else {
-				q->sbal[j]=(volatile sbal_t *)
-					(((char*)q->sbal[j-1])+sizeof(sbal_t));
-			}
-			available-=sizeof(sbal_t);
-		}
-
-                q->queue_type=q_format;
-		q->int_parm=int_parm;
-		irq_ptr->input_qs[i]=q;
-		q->irq=irq_ptr->irq;
-		q->mask=1<<(31-i);
-		q->q_no=i;
-		q->is_input_q=1;
-		q->is_0copy_sbals_q=flags&QDIO_INBOUND_0COPY_SBALS;
-		q->first_to_check=0;
-		q->last_move_ftc=0;
-		q->handler=input_handler;
-		q->dev_st_chg_ind=irq_ptr->dev_st_chg_ind;
-
-		q->tasklet.data=(unsigned long)q;
-		q->tasklet.func=(void(*)(unsigned long))
-			(
-			(q_format==QDIO_IQDIO_QFMT)?&iqdio_inbound_processing:
-			&qdio_inbound_processing);
-
-/*		for (j=0;j<QDIO_STATS_NUMBER;j++)
-			q->timing.last_transfer_times[j]=(qdio_get_micros()/
-							  QDIO_STATS_NUMBER)*j;
-		q->timing.last_transfer_index=QDIO_STATS_NUMBER-1;
-*/
-
-		/* fill in slib */
-		if (i>0) irq_ptr->input_qs[i-1]->slib->nsliba=
-				 (unsigned long)(q->slib);
-		q->slib->sla=(unsigned long)(q->sl);
-		q->slib->slsba=(unsigned long)(&q->slsb.acc.val[0]);
-
-		/* fill in sl */
-		for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++)
-			q->sl->element[j].sbal=(unsigned long)(q->sbal[j]);
-
-		QDIO_DBF_TEXT2(0,setup,"sl-sb-b0");
-		ptr=(void*)q->sl;
-		QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*));
-		ptr=(void*)&q->slsb;
-		QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*));
-		ptr=(void*)q->sbal[0];
-		QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*));
-
-		/* fill in slsb */
-		for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
-			set_slsb(&q->slsb.acc.val[j],
-		   		 SLSB_P_INPUT_NOT_INIT);
-/*			q->sbal[j]->element[1].sbalf.i1.key=QDIO_STORAGE_KEY;*/
-		}
-	}
-
-	for (i=0;i<no_output_qs;i++) {
-		q=kmalloc(sizeof(qdio_q_t),GFP_KERNEL);
-
-		if (!q) {
-			goto out;
-		}
-		memset(q,0,sizeof(qdio_q_t));
-
-		sprintf(dbf_text,"outq%4x",i);
-		QDIO_DBF_TEXT0(0,setup,dbf_text);
-		QDIO_DBF_HEX0(0,setup,&q,sizeof(void*));
-
-		q->slib=kmalloc(PAGE_SIZE,GFP_KERNEL);
-		if (!q->slib) {
-			QDIO_PRINT_ERR("kmalloc of slib failed!\n");
-			goto out;
-		}
-		memset(q->slib,0,PAGE_SIZE);
-		q->sl=(sl_t*)(((char*)q->slib)+PAGE_SIZE/2);
-
-		available=0;
-		if (flags&QDIO_OUTBOUND_0COPY_SBALS) {
-			for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
-				q->sbal[j]=*(outbound_sbals_array++);
-			}
-		} else for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
-			if (!available) {
-				q->sbal[j]=kmalloc(PAGE_SIZE,GFP_KERNEL);
-				if (!q->sbal[j]) {
-					goto out;
-				}
-				available=PAGE_SIZE;
-				memset((void*)q->sbal[j],0,PAGE_SIZE);
-			} else {
-				q->sbal[j]=(volatile sbal_t *)
-					(((char*)q->sbal[j-1])+sizeof(sbal_t));
-			}
-			available-=sizeof(sbal_t);
-		}
-
-                q->queue_type=q_format;
-		q->int_parm=int_parm;
-		irq_ptr->output_qs[i]=q;
-		q->is_input_q=0;
-		q->is_0copy_sbals_q=flags&QDIO_OUTBOUND_0COPY_SBALS;
-		q->irq=irq_ptr->irq;
-		q->mask=1<<(31-i);
-		q->q_no=i;
-		q->first_to_check=0;
-		q->last_move_ftc=0;
-		q->handler=output_handler;
-
-		q->tasklet.data=(unsigned long)q;
-		q->tasklet.func=(void(*)(unsigned long))
-			&qdio_outbound_processing;
-
-		/* fill in slib */
-		if (i>0) irq_ptr->output_qs[i-1]->slib->nsliba=
-				 (unsigned long)(q->slib);
-		q->slib->sla=(unsigned long)(q->sl);
-		q->slib->slsba=(unsigned long)(&q->slsb.acc.val[0]);
-
-		/* fill in sl */
-		for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++)
-			q->sl->element[j].sbal=(unsigned long)(q->sbal[j]);
-
-		QDIO_DBF_TEXT2(0,setup,"sl-sb-b0");
-		ptr=(void*)q->sl;
-		QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*));
-		ptr=(void*)&q->slsb;
-		QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*));
-		ptr=(void*)q->sbal[0];
-		QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*));
-
-		/* fill in slsb */
-		for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
-			set_slsb(&q->slsb.acc.val[j],
-		   		 SLSB_P_OUTPUT_NOT_INIT);
-/*			q->sbal[j]->element[1].sbalf.i1.key=QDIO_STORAGE_KEY;*/
-		}
-	}
-
-	result=1;
-out:
-	return result;
-}
-
-static void qdio_fill_thresholds(qdio_irq_t *irq_ptr,
-				 unsigned int no_input_qs,
-				 unsigned int no_output_qs,
-				 unsigned int min_input_threshold,
-				 unsigned int max_input_threshold,
-				 unsigned int min_output_threshold,
-				 unsigned int max_output_threshold)
-{
-	int i;
-	qdio_q_t *q;
-
-	for (i=0;i<no_input_qs;i++) {
-		q=irq_ptr->input_qs[i];
-		q->timing.threshold=max_input_threshold;
-/*		for (j=0;j<QDIO_STATS_CLASSES;j++) {
-			q->threshold_classes[j].threshold=
-				min_input_threshold+
-				(max_input_threshold-min_input_threshold)/
-				QDIO_STATS_CLASSES;
-		}
-		qdio_use_thresholds(q,QDIO_STATS_CLASSES/2);*/
-	}
-	for (i=0;i<no_output_qs;i++) {
-		q=irq_ptr->output_qs[i];
-		q->timing.threshold=max_output_threshold;
-/*		for (j=0;j<QDIO_STATS_CLASSES;j++) {
-			q->threshold_classes[j].threshold=
-				min_output_threshold+
-				(max_output_threshold-min_output_threshold)/
-				QDIO_STATS_CLASSES;
-		}
-		qdio_use_thresholds(q,QDIO_STATS_CLASSES/2);*/
-	}
-}
-
-static int iqdio_thinint_handler(__u32 intparm)
-{
-#ifdef QDIO_DBF_LIKE_HELL
-	QDIO_DBF_TEXT4(0,trace,"thin_int");
-#endif /* QDIO_DBF_LIKE_HELL */
-
-#ifdef QDIO_PERFORMANCE_STATS
-	perf_stats.thinints++;
-	perf_stats.start_time_inbound=NOW;
-#endif /* QDIO_PERFORMANCE_STATS */
-	/* VM will do the SVS for us */
-	if (!MACHINE_IS_VM) {
-		iqdio_clear_global_summary();
-	}
-
-	iqdio_inbound_checks();
-	iqdio_check_for_polling();
-	return 0;
-}
-
-static void qdio_set_state(qdio_irq_t *irq_ptr,int state)
-{
-	int i;
-	char dbf_text[15];
-
-	QDIO_DBF_TEXT5(0,trace,"newstate");
-	sprintf(dbf_text,"%4x%4x",irq_ptr->irq,state);
-	QDIO_DBF_TEXT5(0,trace,dbf_text);
-
-	irq_ptr->state=state;
-	for (i=0;i<irq_ptr->no_input_qs;i++)
-		irq_ptr->input_qs[i]->state=state;
-	for (i=0;i<irq_ptr->no_output_qs;i++)
-		irq_ptr->output_qs[i]->state=state;
-	mb();
-}
-
-static void qdio_handler(int irq,devstat_t *devstat,struct pt_regs *p)
-{
-	qdio_irq_t *irq_ptr;
-	qdio_q_t *q;
-	int i;
-	int cstat,dstat;
-	int rqparam;
-	char dbf_text[15]="qintXXXX";
-
-        cstat = devstat->cstat;
-        dstat = devstat->dstat;
-        rqparam=devstat->intparm;
-
-	*((int*)(&dbf_text[4]))=irq;
-	QDIO_DBF_HEX4(0,trace,dbf_text,QDIO_DBF_TRACE_LEN);
-	
-	if (!rqparam) {
-		QDIO_PRINT_STUPID("got unsolicited interrupt in qdio " \
-				  "handler, irq 0x%x\n",irq);
-		return;
-	}
-
-	irq_ptr=qdio_get_irq_ptr(irq);
-	if (!irq_ptr) {
-		sprintf(dbf_text,"uint%4x",irq);
-		QDIO_DBF_TEXT2(1,trace,dbf_text);
-		QDIO_PRINT_ERR("received interrupt on unused irq 0x%04x!\n",
-			       irq);
-		return;
-	}
-
-	if (devstat->flag&DEVSTAT_FLAG_SENSE_AVAIL) {
-		sprintf(dbf_text,"sens%4x",irq);
-		QDIO_DBF_TEXT2(1,trace,dbf_text);
-		QDIO_DBF_HEX0(0,sense,&devstat->ii.irb,QDIO_DBF_SENSE_LEN);
-
-		QDIO_PRINT_WARN("sense data available on qdio channel.\n");
-		HEXDUMP16(WARN,"irb: ",&devstat->ii.irb);
-		HEXDUMP16(WARN,"sense data: ",&devstat->ii.sense.data[0]);
-	}
-
-	irq_ptr->io_result_cstat=ioinfo[irq]->devstat.cstat;
-	irq_ptr->io_result_dstat=ioinfo[irq]->devstat.dstat;
-	irq_ptr->io_result_flags=ioinfo[irq]->devstat.flag;
-
-	if ( (rqparam==QDIO_DOING_ACTIVATE) &&
-	     (cstat & SCHN_STAT_PCI) ) {
-#ifdef QDIO_PERFORMANCE_STATS
-		perf_stats.pcis++;
-		perf_stats.start_time_inbound=NOW;
-#endif /* QDIO_PERFORMANCE_STATS */
-		for (i=0;i<irq_ptr->no_input_qs;i++) {
-			q=irq_ptr->input_qs[i];
-			if (q->is_input_q&QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT)
-				qdio_mark_q(q);
-			else {
-#ifdef QDIO_PERFORMANCE_STATS
-				perf_stats.tl_runs--;
-#endif /* QDIO_PERFORMANCE_STATS */
-				qdio_inbound_processing(q);
-			}
-		}
-		if (irq_ptr->hydra_gives_outbound_pcis) {
- 			for (i=0;i<irq_ptr->no_output_qs;i++) {
- 				q=irq_ptr->output_qs[i];
-#ifdef QDIO_PERFORMANCE_STATS
-				perf_stats.tl_runs--;
-#endif /* QDIO_PERFORMANCE_STATS */
-				if (!qdio_is_outbound_q_done(q)) {
-					if (!irq_ptr->sync_done_on_outb_pcis) {
-						SYNC_MEMORY;
-					}
-					qdio_outbound_processing(q);
-				}
-			}
-		}
-		return;
-	}
-
-	if ( (rqparam==QDIO_DOING_ACTIVATE) &&
-	     (!cstat) &&
-	     (!dstat) ) {
-		rqparam=QDIO_DOING_CLEANUP;
-	}
-
-	if ( (rqparam==QDIO_DOING_ESTABLISH) &&
-	     ( (cstat) ||
-	       (dstat & ~(DEV_STAT_CHN_END|DEV_STAT_DEV_END)) ) ) {
-		sprintf(dbf_text,"ick1%4x",irq);
-		QDIO_DBF_TEXT2(1,trace,dbf_text);
-		QDIO_DBF_HEX2(0,trace,&rqparam,sizeof(int));
-		QDIO_DBF_HEX2(0,trace,&dstat,sizeof(int));
-		QDIO_DBF_HEX2(0,trace,&cstat,sizeof(int));
-		QDIO_PRINT_ERR("received check condition on establish " \
-			       "queues on irq 0x%x (cs=x%x, ds=x%x).\n",
-			       irq,cstat,dstat);
-		qdio_set_state(irq_ptr,QDIO_IRQ_STATE_STOPPED);
-		return;
-	}
-
-	if ( ( (rqparam==QDIO_DOING_ACTIVATE) &&
-	       (dstat==(DEV_STAT_CHN_END|DEV_STAT_DEV_END)) ) ||
-	     ( (rqparam==QDIO_DOING_CLEANUP) || (!rqparam) ) ) {
-		qdio_wakeup(&irq_ptr->interrupt_has_been_cleaned,irq_ptr);
-		return;
-	}
-
-	if ( (rqparam==QDIO_DOING_ACTIVATE) &&
-	     ( (cstat & ~SCHN_STAT_PCI) ||
-	       (dstat) ) ) {
-		sprintf(dbf_text,"ick2%4x",irq);
-		QDIO_DBF_TEXT2(1,trace,dbf_text);
-		QDIO_DBF_HEX2(0,trace,&rqparam,sizeof(int));
-		QDIO_DBF_HEX2(0,trace,&dstat,sizeof(int));
-		QDIO_DBF_HEX2(0,trace,&cstat,sizeof(int));
-		QDIO_PRINT_ERR("received check condition on activate " \
-			       "queues on irq 0x%x (cs=x%x, ds=x%x).\n",
-			       irq,cstat,dstat);
-		if (irq_ptr->no_input_qs) {
-			q=irq_ptr->input_qs[0];
-		} else if (irq_ptr->no_output_qs) {
-			q=irq_ptr->output_qs[0];
-		} else {
-			QDIO_PRINT_ERR("oops... no queue registered on irq " \
-				  "0x%x!?\n",irq);
-			goto omit_handler_call;
-		}
-		q->handler(q->irq,QDIO_STATUS_ACTIVATE_CHECK_CONDITION|
-			   QDIO_STATUS_LOOK_FOR_ERROR,
-			   0,0,0,-1,-1,q->int_parm);
-	omit_handler_call:
-		qdio_set_state(irq_ptr,QDIO_IRQ_STATE_STOPPED);
-		return;
-	}
-
-	qdio_wakeup(&irq_ptr->interrupt_has_arrived,irq_ptr);
-}
-
-/* this is for mp3 */
-int qdio_synchronize(int irq,unsigned int flags,
-		     unsigned int queue_number)
-{
-	unsigned int gpr2,gpr3;
-	int cc;
-	qdio_q_t *q;
-	qdio_irq_t *irq_ptr;
-	char dbf_text[15]="SyncXXXX";
-	void *ptr;
-
-	*((int*)(&dbf_text[4]))=irq;
-	QDIO_DBF_HEX4(0,trace,dbf_text,QDIO_DBF_TRACE_LEN);
-	*((int*)(&dbf_text[0]))=flags;
-	*((int*)(&dbf_text[4]))=queue_number;
-	QDIO_DBF_HEX4(0,trace,dbf_text,QDIO_DBF_TRACE_LEN);
-
-	irq_ptr=qdio_get_irq_ptr(irq);
-	if (!irq_ptr) return -ENODEV;
-
-	if (flags&QDIO_FLAG_SYNC_INPUT) {
-		q=irq_ptr->input_qs[queue_number];
-		if (!q) return -EINVAL;
-
-		gpr2=0;
-		gpr3=q->mask;
-	} else if (flags&QDIO_FLAG_SYNC_OUTPUT) {
-		q=irq_ptr->output_qs[queue_number];
-		if (!q) return -EINVAL;
-
-		gpr2=q->mask;
-		gpr3=0;
-	} else return -EINVAL;
-
-#ifdef QDIO_32_BIT
-	asm volatile (
-		"lhi	0,2	\n\t"
-		"lr	1,%1	\n\t"
-		"lr	2,%2	\n\t"
-		"lr	3,%3	\n\t"
-		"siga   0	\n\t"
-		"ipm	%0	\n\t"
-		"srl	%0,28	\n\t"
-		: "=d" (cc)
-		: "d" (0x10000|q->irq), "d" (gpr2), "d" (gpr3)
-		: "cc", "0", "1", "2", "3"
-		);
-#else /* QDIO_32_BIT */
-	asm volatile (
-		"lghi	0,2	\n\t"
-		"llgfr	1,%1	\n\t"
-		"llgfr	2,%2	\n\t"
-		"llgfr	3,%3	\n\t"
-		"siga   0	\n\t"
-		"ipm	%0	\n\t"
-		"srl	%0,28	\n\t"
-		: "=d" (cc)
-		: "d" (0x10000|q->irq), "d" (gpr2), "d" (gpr3)
-		: "cc", "0", "1", "2", "3"
-		);
-#endif /* QDIO_32_BIT */
-
-	ptr=&cc;
-	if (cc) QDIO_DBF_HEX3(0,trace,&ptr,sizeof(int));
-
-	return cc;
-}
-
-/* FIXME: this is never used in the kernel, why? */
-unsigned char qdio_get_slsb_state(int irq,unsigned int flag,
-				  unsigned int queue_number,
-				  unsigned int qidx)
-{
-	qdio_irq_t *irq_ptr;
-	qdio_q_t *q;
-
-	irq_ptr=qdio_get_irq_ptr(irq);
-	if (!irq_ptr) return SLSB_ERROR_DURING_LOOKUP;
-
-	if (flag&QDIO_FLAG_SYNC_INPUT) {
-		q=irq_ptr->input_qs[queue_number];
-	} else if (flag&QDIO_FLAG_SYNC_OUTPUT) {
-		q=irq_ptr->output_qs[queue_number];
-	} else return SLSB_ERROR_DURING_LOOKUP;
-
-	return q->slsb.acc.val[qidx&(QDIO_MAX_BUFFERS_PER_Q-1)];
-}
-
-static int qdio_chsc(qdio_chsc_area_t *chsc_area)
-{
-	int cc;
-
-	asm volatile (
-		".insn	rre,0xb25f0000,%1,0	\n\t"
-		"ipm	%0	\n\t"
-		"srl	%0,28	\n\t"
-		: "=d" (cc) : "d" (chsc_area) : "cc"
-		);
-
-	return cc;
-}
-
-static unsigned char qdio_check_siga_needs(int sch)
-{
-	int resp_code,result;
-
-	memset(chsc_area,0,sizeof(qdio_chsc_area_t));
-	chsc_area->request_block.command_code1=0x0010; /* length */
-	chsc_area->request_block.command_code2=0x0024; /* op code */
-	chsc_area->request_block.first_sch=sch;
-	chsc_area->request_block.last_sch=sch;
-
-	result=qdio_chsc(chsc_area);
-
-	if (result) {
-		QDIO_PRINT_WARN("CHSC returned cc %i. Using all " \
-				"SIGAs for sch x%x.\n",
-				result,sch);
-		return -1; /* all flags set */
-	}
-
-	resp_code=chsc_area->request_block.operation_data_area.
-		store_qdio_data_response.response_code;
-	if (resp_code!=QDIO_CHSC_RESPONSE_CODE_OK) {
-		QDIO_PRINT_WARN("response upon checking SIGA needs " \
-				"is 0x%x. Using all SIGAs for sch x%x.\n",
-				resp_code,sch);
-		return -1; /* all flags set */
-	}
-	if (
-	    (!(chsc_area->request_block.operation_data_area.
-	       store_qdio_data_response.flags&CHSC_FLAG_QDIO_CAPABILITY)) ||
-	    (!(chsc_area->request_block.operation_data_area.
-	       store_qdio_data_response.flags&CHSC_FLAG_VALIDITY)) ||
-	    (chsc_area->request_block.operation_data_area.
-	     store_qdio_data_response.sch!=sch)
-	    ) {
-		QDIO_PRINT_WARN("huh? problems checking out sch x%x... " \
-				"using all SIGAs.\n",sch);
-		return CHSC_FLAG_SIGA_INPUT_NECESSARY |
-			CHSC_FLAG_SIGA_OUTPUT_NECESSARY |
-			CHSC_FLAG_SIGA_SYNC_NECESSARY; /* worst case */
-	}
-
-	return chsc_area->request_block.operation_data_area.
-		store_qdio_data_response.qdioac;
-}
-
-/* the chsc_area is locked by the lock in qdio_activate */
-static unsigned int iqdio_check_chsc_availability(void) {
-	int result;
-	int i;
-
-	memset(chsc_area,0,sizeof(qdio_chsc_area_t));
-	chsc_area->request_block.command_code1=0x0010;
-	chsc_area->request_block.command_code2=0x0010;
-	result=qdio_chsc(chsc_area);
-	if (result) {
-		QDIO_PRINT_WARN("Was not able to determine " \
-				"available CHSCs, cc=%i.\n",
-				result);
-		result=-EIO;
-		goto exit;
-	}
-	result=0;
-	i=chsc_area->request_block.operation_data_area.
-		store_qdio_data_response.response_code;
-	if (i!=1) {
-		QDIO_PRINT_WARN("Was not able to determine " \
-				"available CHSCs.\n");
-		result=-EIO;
-		goto exit;
-	}
-	/* 4: request block
-	 * 2: general char
-	 * 512: chsc char */
-	if ( (*(((unsigned int*)(chsc_area))+4+2+1)&0x00800000)!=0x00800000) {
-		QDIO_PRINT_WARN("Adapter interruption facility not " \
-				"installed.\n");
-		result=-ENOENT;
-		goto exit;
-	}
-	if ( (*(((unsigned int*)(chsc_area))+4+512+3)&0x00180000)!=
-	     0x00180000 ) {
-		QDIO_PRINT_WARN("Set Chan Subsys. Char. & Fast-CHSCs " \
-				"not available.\n");
-		result=-ENOENT;
-		goto exit;
-	}
-exit:
-	return result;
-}
-
-/* the chsc_area is locked by the lock in qdio_activate */
-static unsigned int iqdio_set_subchannel_ind(qdio_irq_t *irq_ptr,
-					     int reset_to_zero)
-{
-	unsigned long real_addr_local_summary_bit;
-	unsigned long real_addr_dev_st_chg_ind;
-	void *ptr;
-	char dbf_text[15];
-
-	unsigned int resp_code;
-	int result;
-
-	if (!irq_ptr->is_iqdio_irq) return -ENODEV;
-
-	if (reset_to_zero) {
-		real_addr_local_summary_bit=0;
-		real_addr_dev_st_chg_ind=0;
-	} else {
-		real_addr_local_summary_bit=
-			virt_to_phys((volatile void *)indicators);
-		real_addr_dev_st_chg_ind=
-			virt_to_phys((volatile void *)irq_ptr->dev_st_chg_ind);
-	}
-
-	memset(chsc_area,0,sizeof(qdio_chsc_area_t));
-	chsc_area->request_block.command_code1=0x0fe0;
-	chsc_area->request_block.command_code2=0x0021;
-	chsc_area->request_block.operation_code=0;
-	chsc_area->request_block.image_id=0;
-
-	chsc_area->request_block.operation_data_area.set_chsc.
-		summary_indicator_addr=real_addr_local_summary_bit;
-	chsc_area->request_block.operation_data_area.set_chsc.
-		subchannel_indicator_addr=real_addr_dev_st_chg_ind;
-	chsc_area->request_block.operation_data_area.set_chsc.
-		ks=QDIO_STORAGE_KEY;
-	chsc_area->request_block.operation_data_area.set_chsc.
-		kc=QDIO_STORAGE_KEY;
-	chsc_area->request_block.operation_data_area.set_chsc.
-		isc=IQDIO_THININT_ISC;
-	chsc_area->request_block.operation_data_area.set_chsc.
-		subsystem_id=(1<<16)+irq_ptr->irq;
-
-	result=qdio_chsc(chsc_area);
-	if (result) {
-		QDIO_PRINT_WARN("could not set indicators on irq x%x, " \
-				"cc=%i.\n",irq_ptr->irq,result);
-		return -EIO;
-	}
-
-	resp_code=chsc_area->response_block.response_code;
-	if (resp_code!=QDIO_CHSC_RESPONSE_CODE_OK) {
-		QDIO_PRINT_WARN("response upon setting indicators " \
-				"is 0x%x.\n",resp_code);
-		sprintf(dbf_text,"sidR%4x",resp_code);
-		QDIO_DBF_TEXT1(0,trace,dbf_text);
-		QDIO_DBF_TEXT1(0,setup,dbf_text);
-		ptr=&chsc_area->response_block;
-		QDIO_DBF_HEX2(1,setup,&ptr,QDIO_DBF_SETUP_LEN);
-		return -EIO;
-	}
-
-	QDIO_DBF_TEXT2(0,setup,"setscind");
-	QDIO_DBF_HEX2(0,setup,&real_addr_local_summary_bit,
-		      sizeof(unsigned long));
-	QDIO_DBF_HEX2(0,setup,&real_addr_dev_st_chg_ind,sizeof(unsigned long));
-	return 0;
-}
-
-/* chsc_area would have to be locked if called from outside qdio_activate */
-static unsigned int iqdio_set_delay_target(qdio_irq_t *irq_ptr,
-       					   unsigned long delay_target)
-{
-	unsigned int resp_code;
-	int result;
-	void *ptr;
-	char dbf_text[15];
-
-	if (!irq_ptr->is_iqdio_irq) return -ENODEV;
-
-	memset(chsc_area,0,sizeof(qdio_chsc_area_t));
-	chsc_area->request_block.command_code1=0x0fe0;
-	chsc_area->request_block.command_code2=0x1027;
-	chsc_area->request_block.operation_data_area.set_chsc_fast.
-		delay_target=delay_target<<16;
-
-	result=qdio_chsc(chsc_area);
-	if (result) {
-		QDIO_PRINT_WARN("could not set delay target on irq x%x, " \
-				"cc=%i. Continuing.\n",irq_ptr->irq,result);
-		return -EIO;
-	}
-
-	resp_code=chsc_area->response_block.response_code;
-	if (resp_code!=QDIO_CHSC_RESPONSE_CODE_OK) {
-		QDIO_PRINT_WARN("response upon setting delay target " \
-				"is 0x%x. Continuing.\n",resp_code);
-		sprintf(dbf_text,"sdtR%4x",resp_code);
-		QDIO_DBF_TEXT1(0,trace,dbf_text);
-		QDIO_DBF_TEXT1(0,setup,dbf_text);
-		ptr=&chsc_area->response_block;
-		QDIO_DBF_HEX2(1,trace,&ptr,QDIO_DBF_TRACE_LEN);
-	}
-	QDIO_DBF_TEXT2(0,trace,"delytrgt");
-	QDIO_DBF_HEX2(0,trace,&delay_target,sizeof(unsigned long));
-	return 0;
-}
-
-int qdio_cleanup(int irq,int how)
-{
-	qdio_irq_t *irq_ptr;
-	int i,result;
-	int do_an_irqrestore=0;
-	unsigned long flags;
-	int timeout;
-	char dbf_text[15]="12345678";
-
-	result=0;
-	sprintf(dbf_text,"qcln%4x",irq);
-	QDIO_DBF_TEXT1(0,trace,dbf_text);
-	QDIO_DBF_TEXT0(0,setup,dbf_text);
-
-	irq_ptr=qdio_get_irq_ptr(irq);
-	if (!irq_ptr) return -ENODEV;
-
-	my_spin_lock(&irq_ptr->setting_up_lock);
-
-	/* mark all qs as uninteresting */
-	for (i=0;i<irq_ptr->no_input_qs;i++) {
-		atomic_set(&irq_ptr->input_qs[i]->is_in_shutdown,1);
-	}
-	for (i=0;i<irq_ptr->no_output_qs;i++) {
-		atomic_set(&irq_ptr->output_qs[i]->is_in_shutdown,1);
-	}
-
-	tasklet_kill(&iqdio_tasklet);
-
-	for (i=0;i<irq_ptr->no_input_qs;i++) {
-		qdio_unmark_q(irq_ptr->input_qs[i]);
-		tasklet_kill(&irq_ptr->input_qs[i]->tasklet);
-		if (qdio_wait_for_no_use_count(&irq_ptr->input_qs[i]->
-					       use_count))
-			result=-EINPROGRESS;
-	}
-
-	for (i=0;i<irq_ptr->no_output_qs;i++) {
-		tasklet_kill(&irq_ptr->output_qs[i]->tasklet);
-		if (qdio_wait_for_no_use_count(&irq_ptr->output_qs[i]->
-					       use_count))
-			result=-EINPROGRESS;
-	}
-
-	atomic_set(&irq_ptr->interrupt_has_been_cleaned,0);
-
-	/* cleanup subchannel */
-	my_s390irq_spin_lock_irqsave(irq,flags);
-	if (how&QDIO_FLAG_CLEANUP_USING_CLEAR) {
-		clear_IO(irq_ptr->irq,QDIO_DOING_CLEANUP,0);
-		timeout=QDIO_CLEANUP_CLEAR_TIMEOUT;
-	} else if (how&QDIO_FLAG_CLEANUP_USING_HALT) {
-		halt_IO(irq_ptr->irq,QDIO_DOING_CLEANUP,0);
-		timeout=QDIO_CLEANUP_HALT_TIMEOUT;
-	} else { /* default behaviour */
-		halt_IO(irq_ptr->irq,QDIO_DOING_CLEANUP,0);
-		timeout=QDIO_CLEANUP_HALT_TIMEOUT;
-	}
-	my_s390irq_spin_unlock_irqrestore(irq,flags);
-
-	if (qdio_sleepon(&irq_ptr->interrupt_has_been_cleaned,
-			 timeout,irq_ptr)==-ETIME) {
-		my_s390irq_spin_lock_irqsave(irq,flags);
-		QDIO_PRINT_INFO("Did not get interrupt on %s_IO, " \
-				"irq=0x%x.\n",
-				(how==QDIO_FLAG_CLEANUP_USING_CLEAR)?
-				"clear":"halt",irq);
-		do_an_irqrestore=1;
-	}
-
-	if (irq_ptr->is_iqdio_irq) {
-		qdio_put_indicator((__u32*)irq_ptr->dev_st_chg_ind);
-		iqdio_set_subchannel_ind(irq_ptr,1); /* reset adapter
-							interrupt indicators */
-	}
-
-	/* exchange int handlers, if necessary */
-	if ((void*)ioinfo[irq]->irq_desc.handler
-	    ==(void*)qdio_handler) {
-		ioinfo[irq]->irq_desc.handler=
-			irq_ptr->original_int_handler;
-/*		irq_ptr->original_int_handler=NULL; */
-	}
-
-	qdio_set_state(irq_ptr,QDIO_IRQ_STATE_INACTIVE);
-
-	if (do_an_irqrestore)
-		my_s390irq_spin_unlock_irqrestore(irq,flags);
-
-	my_spin_unlock(&irq_ptr->setting_up_lock);
-
-	qdio_remove_irq_ptr(irq_ptr);
-	qdio_release_irq_memory(irq_ptr);
-	return result;
-}
-
-static unsigned long qdio_get_characteristics(int irq)
-{
-	qdio_irq_t *irq_ptr;
-	int result=0;
-
-	irq_ptr=qdio_get_irq_ptr(irq);
-	if (!irq_ptr) return -ENODEV;
-
-	if (irq_ptr->state!=QDIO_IRQ_STATE_ACTIVE) {
-		return -EBUSY;
-	}
-
-	if (irq_ptr->state==QDIO_IRQ_STATE_INACTIVE) {
-		result|=QDIO_STATE_INACTIVE;
-	} else if (irq_ptr->state==QDIO_IRQ_STATE_ESTABLISHED) {
-		result|=QDIO_STATE_ESTABLISHED;
-	} else if (irq_ptr->state==QDIO_IRQ_STATE_ACTIVE) {
-		result|=QDIO_STATE_ACTIVE;
-	} else if (irq_ptr->state==QDIO_IRQ_STATE_STOPPED) {
-		result|=QDIO_STATE_STOPPED;
-	}
-
-	if (irq_ptr->hydra_gives_outbound_pcis)
-		result|=QDIO_STATE_MUST_USE_OUTB_PCI;
-
-	return result;
-}
-
-int qdio_initialize(qdio_initialize_t *init_data)
-{
-	int i,ciw_cnt;
-	unsigned long saveflags;
-	qdio_irq_t *irq_ptr=NULL;
-	int result,result2;
-	int found;
-	char dbf_text[20]; /* if a printf would print out more than 8 chars */
-
-	down_interruptible(&init_sema);
-
-	sprintf(dbf_text,"qini%4x",init_data->irq);
-	QDIO_DBF_TEXT0(0,setup,dbf_text);
-	QDIO_DBF_TEXT0(0,trace,dbf_text);
-	sprintf(dbf_text,"qfmt:%x",init_data->q_format);
-	QDIO_DBF_TEXT0(0,setup,dbf_text);
-	QDIO_DBF_TEXT0(0,setup,init_data->adapter_name);
-	QDIO_DBF_HEX0(0,setup,init_data->adapter_name,8);
-	sprintf(dbf_text,"qpff%4x",init_data->qib_param_field_format);
-	QDIO_DBF_TEXT0(0,setup,dbf_text);
-	QDIO_DBF_HEX0(0,setup,&init_data->qib_param_field,sizeof(char*));
-	QDIO_DBF_HEX0(0,setup,&init_data->input_slib_elements,sizeof(long*));
-	QDIO_DBF_HEX0(0,setup,&init_data->output_slib_elements,sizeof(long*));
-	sprintf(dbf_text,"miit%4x",init_data->min_input_threshold);
-	QDIO_DBF_TEXT0(0,setup,dbf_text);
-	sprintf(dbf_text,"mait%4x",init_data->min_input_threshold);
-	QDIO_DBF_TEXT0(0,setup,dbf_text);
-	sprintf(dbf_text,"miot%4x",init_data->max_output_threshold);
-	QDIO_DBF_TEXT0(0,setup,dbf_text);
-	sprintf(dbf_text,"maot%4x",init_data->max_output_threshold);
-	QDIO_DBF_TEXT0(0,setup,dbf_text);
-	sprintf(dbf_text,"niq:%4x",init_data->no_input_qs);
-	QDIO_DBF_TEXT0(0,setup,dbf_text);
-	sprintf(dbf_text,"noq:%4x",init_data->no_output_qs);
-	QDIO_DBF_TEXT0(0,setup,dbf_text);
-	QDIO_DBF_HEX0(0,setup,&init_data->input_handler,sizeof(void*));
-	QDIO_DBF_HEX0(0,setup,&init_data->output_handler,sizeof(void*));
-	QDIO_DBF_HEX0(0,setup,&init_data->int_parm,sizeof(long));
-	QDIO_DBF_HEX0(0,setup,&init_data->flags,sizeof(long));
-	QDIO_DBF_HEX0(0,setup,&init_data->input_sbal_addr_array,sizeof(void*));
-	QDIO_DBF_HEX0(0,setup,&init_data->output_sbal_addr_array,sizeof(void*));
-
-	/* sanity checks */
-	if (qdio_get_irq_ptr(init_data->irq)) {
-		result=-EBUSY;
-		goto out;
-	}
-
-	if (ioinfo[init_data->irq]==INVALID_STORAGE_AREA) {
-		result=-ENODEV;
-		goto out;
-	}
-
-	if (!ioinfo[init_data->irq]) {
-		QDIO_PRINT_WARN("ioinfo[%i] is NULL!\n",init_data->irq);
-		result=-ENODEV;
-		goto out;
-	}
-
-#define DEVSTAT_FLAG_IRQ_QDIO ~0UL
-	if (!(ioinfo[init_data->irq]->devstat.flag&DEVSTAT_FLAG_IRQ_QDIO)) {
-		QDIO_PRINT_WARN("ioinfo[%i]->devstat.flag=0x%08x\n",
-				init_data->irq,
-				ioinfo[init_data->irq]->devstat.flag);
-		result=-ENODEV;
-		goto out;
-	}
-
-	if ( (init_data->no_input_qs>QDIO_MAX_QUEUES_PER_IRQ) ||
-	     (init_data->no_output_qs>QDIO_MAX_QUEUES_PER_IRQ) ||
-	     ((init_data->no_input_qs) && (!init_data->input_handler)) ||
-	     ((init_data->no_output_qs) && (!init_data->output_handler)) ) {
-		result=-EINVAL;
-		goto out;
-	}
-
-	if ( (init_data->flags&QDIO_INBOUND_0COPY_SBALS)&&
-	     (!init_data->input_sbal_addr_array) ) {
-		result=-EINVAL;
-		goto out;
-	}
-	if ( (init_data->flags&QDIO_OUTBOUND_0COPY_SBALS)&&
-	     (!init_data->output_sbal_addr_array) ) {
-		result=-EINVAL;
-		goto out;
-	}
-
-	/* create irq */
-	irq_ptr=kmalloc(sizeof(qdio_irq_t),GFP_DMA);
-
-	QDIO_DBF_TEXT0(0,setup,"irq_ptr:");
-	QDIO_DBF_HEX0(0,setup,&irq_ptr,sizeof(void*));
-
-	if (!irq_ptr) {
-		QDIO_PRINT_ERR("kmalloc of irq_ptr failed!\n");
-		result=-ENOMEM;
-		goto out;
-	}
-
-	memset(irq_ptr,0,sizeof(qdio_irq_t)); /* wipes qib.ac,
-						 required by ar7063 */
-
-	irq_ptr->qdr=kmalloc(sizeof(qdr_t),GFP_DMA);
-  	if (!(irq_ptr->qdr)) {
-   		kfree(irq_ptr->qdr);
-   		kfree(irq_ptr);
-    		QDIO_PRINT_ERR("kmalloc of irq_ptr->qdr failed!\n");
-     		result=-ENOMEM;
-      		goto out;
-       	}
-	memset(irq_ptr->qdr,0,sizeof(qdr_t));
-	QDIO_DBF_TEXT0(0,setup,"qdr:");
-	QDIO_DBF_HEX0(0,setup,&irq_ptr->qdr,sizeof(void*));
-
-	init_waitqueue_head(&irq_ptr->wait_q);
-
-	irq_ptr->int_parm=init_data->int_parm;
-
-	irq_ptr->irq=init_data->irq;
-	irq_ptr->no_input_qs=init_data->no_input_qs;
-	irq_ptr->no_output_qs=init_data->no_output_qs;
-
-	irq_ptr->is_iqdio_irq=(init_data->q_format==QDIO_IQDIO_QFMT)?1:0;
-
-	if (irq_ptr->is_iqdio_irq) {
-		irq_ptr->dev_st_chg_ind=qdio_get_indicator();
-		QDIO_DBF_HEX1(0,setup,&irq_ptr->dev_st_chg_ind,sizeof(void*));
-		if (!irq_ptr->dev_st_chg_ind) {
-			QDIO_PRINT_WARN("no indicator location available " \
-					"for irq 0x%x\n",irq_ptr->irq);
-			qdio_release_irq_memory(irq_ptr);
-			result=-ENOBUFS;
-			goto out;
-		}
-	}
-
-	/* defaults */
-	irq_ptr->commands.eq=DEFAULT_ESTABLISH_QS_CMD;
-	irq_ptr->commands.count_eq=DEFAULT_ESTABLISH_QS_COUNT;
-	irq_ptr->commands.aq=DEFAULT_ACTIVATE_QS_CMD;
-	irq_ptr->commands.count_aq=DEFAULT_ACTIVATE_QS_COUNT;
-
-	if (!qdio_alloc_qs(irq_ptr,init_data->no_input_qs,
-			   init_data->no_output_qs,
-			   init_data->input_handler,
-			   init_data->output_handler,init_data->int_parm,
-			   init_data->q_format,init_data->flags,
-			   init_data->input_sbal_addr_array,
-			   init_data->output_sbal_addr_array)) {
-		qdio_release_irq_memory(irq_ptr);
-		result=-ENOMEM;
-		goto out;
-	}
-
-	qdio_set_state(irq_ptr,QDIO_IRQ_STATE_INACTIVE);
-
-	irq_ptr->setting_up_lock=SPIN_LOCK_UNLOCKED;
-
-	MOD_INC_USE_COUNT;
-	QDIO_DBF_TEXT3(0,setup,"MOD_INC_");
-
-	my_spin_lock(&irq_ptr->setting_up_lock);
-
-	qdio_insert_irq_ptr(irq_ptr);
-
-	qdio_fill_thresholds(irq_ptr,init_data->no_input_qs,
-			     init_data->no_output_qs,
-			     init_data->min_input_threshold,
-			     init_data->max_input_threshold,
-			     init_data->min_output_threshold,
-			     init_data->max_output_threshold);
-
-	/* fill in qdr */
-	irq_ptr->qdr->qfmt=init_data->q_format;
-	irq_ptr->qdr->iqdcnt=init_data->no_input_qs;
-	irq_ptr->qdr->oqdcnt=init_data->no_output_qs;
-	irq_ptr->qdr->iqdsz=sizeof(qdesfmt0_t)/4; /* size in words */
-	irq_ptr->qdr->oqdsz=sizeof(qdesfmt0_t)/4;
-
-	irq_ptr->qdr->qiba=(unsigned long)&irq_ptr->qib;
-	irq_ptr->qdr->qkey=QDIO_STORAGE_KEY;
-
-	/* fill in qib */
-	irq_ptr->qib.qfmt=init_data->q_format;
-	if (init_data->no_input_qs) irq_ptr->qib.isliba=
-				 (unsigned long)(irq_ptr->input_qs[0]->slib);
-	if (init_data->no_output_qs) irq_ptr->qib.osliba=(unsigned long)
-				  (irq_ptr->output_qs[0]->slib);
-	memcpy(irq_ptr->qib.ebcnam,init_data->adapter_name,8);
-
-	qdio_set_impl_params(irq_ptr,init_data->qib_param_field_format,
-			     init_data->qib_param_field,
-			     init_data->no_input_qs,
-			     init_data->no_output_qs,
-			     init_data->input_slib_elements,
-			     init_data->output_slib_elements);
-
-	/* first input descriptors, then output descriptors */
-	for (i=0;i<init_data->no_input_qs;i++) {
-		irq_ptr->input_qs[i]->is_iqdio_q=
-			(init_data->q_format==QDIO_IQDIO_QFMT)?1:0;
-
-		irq_ptr->qdr->qdf0[i].sliba=
-			(unsigned long)(irq_ptr->input_qs[i]->slib);
-
-		irq_ptr->qdr->qdf0[i].sla=
-			(unsigned long)(irq_ptr->input_qs[i]->sl);
-
-		irq_ptr->qdr->qdf0[i].slsba=
-			(unsigned long)(&irq_ptr->input_qs[i]->
-					slsb.acc.val[0]);
-
-		irq_ptr->qdr->qdf0[i].akey=QDIO_STORAGE_KEY;
-		irq_ptr->qdr->qdf0[i].bkey=QDIO_STORAGE_KEY;
-		irq_ptr->qdr->qdf0[i].ckey=QDIO_STORAGE_KEY;
-		irq_ptr->qdr->qdf0[i].dkey=QDIO_STORAGE_KEY;
-	}
-
-	for (i=0;i<init_data->no_output_qs;i++) {
-		irq_ptr->output_qs[i]->is_iqdio_q=
-			(init_data->q_format==QDIO_IQDIO_QFMT)?1:0;
-
-		irq_ptr->qdr->qdf0[i+init_data->no_input_qs].sliba=
-			(unsigned long)(irq_ptr->output_qs[i]->slib);
-
-		irq_ptr->qdr->qdf0[i+init_data->no_input_qs].sla=
-			(unsigned long)(irq_ptr->output_qs[i]->sl);
-
-		irq_ptr->qdr->qdf0[i+init_data->no_input_qs].slsba=
-			(unsigned long)(&irq_ptr->output_qs[i]->
-					slsb.acc.val[0]);
-
-		irq_ptr->qdr->qdf0[i+init_data->no_input_qs].akey=
-			QDIO_STORAGE_KEY;
-		irq_ptr->qdr->qdf0[i+init_data->no_input_qs].bkey=
-			QDIO_STORAGE_KEY;
-		irq_ptr->qdr->qdf0[i+init_data->no_input_qs].ckey=
-			QDIO_STORAGE_KEY;
-		irq_ptr->qdr->qdf0[i+init_data->no_input_qs].dkey=
-			QDIO_STORAGE_KEY;
-	}
-	/* qdr, qib, sls, slsbs, slibs, sbales filled. */
-
-	my_s390irq_spin_lock_irqsave(irq_ptr->irq,saveflags);
-	/* keep track of original int handler */
-	irq_ptr->original_int_handler=ioinfo[irq_ptr->irq]->irq_desc.handler;
-
-	/* insert qdio int handler */
-	ioinfo[irq_ptr->irq]->irq_desc.handler=(void*)qdio_handler;
-
-	my_s390irq_spin_unlock_irqrestore(irq_ptr->irq,saveflags);
-
-#define TAKEOVER_CIW(x) irq_ptr->commands.##x=ioinfo[irq_ptr->irq]->senseid.ciw[ciw_cnt].cmd; irq_ptr->commands.count_##x=ioinfo[irq_ptr->irq]->senseid.ciw[ciw_cnt].count
-	/* get qdio commands */
-	found=0;
-	for (ciw_cnt=0;ciw_cnt<MAX_CIWS;ciw_cnt++) {
-		switch (ioinfo[irq_ptr->irq]->senseid.ciw[ciw_cnt].ct) {
-		case CIW_TYPE_RCD: TAKEOVER_CIW(rcd); break;
-		case CIW_TYPE_SII: TAKEOVER_CIW(sii); break;
-		case CIW_TYPE_RNI: TAKEOVER_CIW(rni); break;
-		case CIW_TYPE_EQUEUE: TAKEOVER_CIW(eq); found++; break;
-		case CIW_TYPE_AQUEUE: TAKEOVER_CIW(aq); found++; break;
-		}
-		if ( (ciw_cnt>0) &&
-		     (ioinfo[irq_ptr->irq]->senseid.ciw[ciw_cnt].ct==0) &&
-		     (ioinfo[irq_ptr->irq]->senseid.ciw[ciw_cnt].cmd==0) &&
-		     (ioinfo[irq_ptr->irq]->senseid.ciw[ciw_cnt].count) )
-			break;
-	}
-	if (found<2) {
-		QDIO_DBF_TEXT2(1,setup,"no ciws");
-		QDIO_PRINT_INFO("No CIWs found for QDIO commands. Trying to " \
-				"use defaults.\n");
-	}
-
-	/* the iqdio CHSC stuff */
-	if (irq_ptr->is_iqdio_irq) {
-/*		iqdio_enable_adapter_int_facility(irq_ptr);*/
-
-		if (iqdio_check_chsc_availability()) {
-			QDIO_PRINT_ERR("Not all CHSCs supported. " \
-				       "Continuing.\n");
-		}
-		result=iqdio_set_subchannel_ind(irq_ptr,0);
-		if (result) {
-			my_spin_unlock(&irq_ptr->setting_up_lock);
-			qdio_cleanup(irq_ptr->irq,
-				     QDIO_FLAG_CLEANUP_USING_CLEAR);
-			goto out2;
-		}
-		iqdio_set_delay_target(irq_ptr,IQDIO_DELAY_TARGET);
-	}
-
-	/* establish q */
-	irq_ptr->ccw.cmd_code=irq_ptr->commands.eq;
-	irq_ptr->ccw.flags=CCW_FLAG_SLI;
-	irq_ptr->ccw.count=irq_ptr->commands.count_eq;
-	irq_ptr->ccw.cda=QDIO_GET_ADDR(irq_ptr->qdr);
-
-	my_s390irq_spin_lock_irqsave(irq_ptr->irq,saveflags);
-	atomic_set(&irq_ptr->interrupt_has_arrived,0);
-
-	result=do_IO(irq_ptr->irq,&irq_ptr->ccw,QDIO_DOING_ESTABLISH,0,0);
-	if (result) {
-		result2=do_IO(irq_ptr->irq,&irq_ptr->ccw,
-			      QDIO_DOING_ESTABLISH,0,0);
-		sprintf(dbf_text,"eq:io%4x",result);
-		QDIO_DBF_TEXT2(1,setup,dbf_text);
-		if (result2) {
-			sprintf(dbf_text,"eq:io%4x",result);
-			QDIO_DBF_TEXT2(1,setup,dbf_text);
-		}
-		QDIO_PRINT_WARN("establish queues on irq %04x: do_IO " \
-                           "returned %i, next try returned %i\n",
-                           irq_ptr->irq,result,result2);
-		result=result2;
-	}
-
-	my_s390irq_spin_unlock_irqrestore(irq_ptr->irq,saveflags);
-
-	if (result) {
-		my_spin_unlock(&irq_ptr->setting_up_lock);
-		qdio_cleanup(irq_ptr->irq,QDIO_FLAG_CLEANUP_USING_CLEAR);
-		goto out2;
-	}
-
-	result=qdio_sleepon(&irq_ptr->interrupt_has_arrived,
-			    QDIO_ESTABLISH_TIMEOUT,irq_ptr);
-
-	if (result) {
-		QDIO_PRINT_ERR("establish queues on irq %04x: timed out\n",
-			   irq_ptr->irq);
-		QDIO_DBF_TEXT2(1,setup,"eq:timeo");
-		my_spin_unlock(&irq_ptr->setting_up_lock);
-		qdio_cleanup(irq_ptr->irq,QDIO_FLAG_CLEANUP_USING_CLEAR);
-		goto out2;
-	}
-
-	if (!(irq_ptr->io_result_dstat & DEV_STAT_DEV_END)) {
-		QDIO_DBF_TEXT2(1,setup,"eq:no de");
-		QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_dstat,
-			      sizeof(irq_ptr->io_result_dstat));
-		QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_cstat,
-			      sizeof(irq_ptr->io_result_cstat));
-		QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_flags,
-			      sizeof(irq_ptr->io_result_flags));
-		QDIO_PRINT_ERR("establish queues on irq %04x: didn't get " \
-			       "device end: dstat=%02x, cstat=%02x, " \
-			       "flags=%02x\n",
-			       irq_ptr->irq,irq_ptr->io_result_dstat,
-			       irq_ptr->io_result_cstat,
-			       irq_ptr->io_result_flags);
-		my_spin_unlock(&irq_ptr->setting_up_lock);
-		qdio_cleanup(irq_ptr->irq,QDIO_FLAG_CLEANUP_USING_CLEAR);
-		result=-EIO;
-		goto out2;
-	}
-
-	if (irq_ptr->io_result_dstat & ~(DEV_STAT_CHN_END|DEV_STAT_DEV_END)) {
-		QDIO_DBF_TEXT2(1,setup,"eq:badio");
-		QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_dstat,
-			      sizeof(irq_ptr->io_result_dstat));
-		QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_cstat,
-			      sizeof(irq_ptr->io_result_cstat));
-		QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_flags,
-			      sizeof(irq_ptr->io_result_flags));
-		QDIO_PRINT_ERR("establish queues on irq %04x: got " \
-			       "the following devstat: dstat=%02x, " \
-			       "cstat=%02x, flags=%02x\n",
-			       irq_ptr->irq,irq_ptr->io_result_dstat,
-			       irq_ptr->io_result_cstat,
-			       irq_ptr->io_result_flags);
-		result=-EIO;
-		goto out;
-	}
-
-	if (MACHINE_IS_VM)
-		irq_ptr->qdioac=qdio_check_siga_needs(irq_ptr->irq);
-	else { 
-                irq_ptr->qdioac=CHSC_FLAG_SIGA_INPUT_NECESSARY
-                        | CHSC_FLAG_SIGA_OUTPUT_NECESSARY;
-        }
-	sprintf(dbf_text,"qdioac%2x",irq_ptr->qdioac);
-	QDIO_DBF_TEXT2(0,setup,dbf_text);
-
-	sprintf(dbf_text,"qib ac%2x",irq_ptr->qib.ac);
-	QDIO_DBF_TEXT2(0,setup,dbf_text);
-
-	if (init_data->flags&QDIO_USE_OUTBOUND_PCIS) {
-		irq_ptr->hydra_gives_outbound_pcis=
-			irq_ptr->qib.ac&QIB_AC_OUTBOUND_PCI_SUPPORTED;
-	} else {
-		irq_ptr->hydra_gives_outbound_pcis=0;
-	}
-	irq_ptr->sync_done_on_outb_pcis=
-		irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS;
-
-	for (i=0;i<init_data->no_input_qs;i++) {
-		irq_ptr->input_qs[i]->siga_sync=
-			irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_NECESSARY;
-		irq_ptr->input_qs[i]->siga_in=
-			irq_ptr->qdioac&CHSC_FLAG_SIGA_INPUT_NECESSARY;
-		irq_ptr->input_qs[i]->siga_out=
-			irq_ptr->qdioac&CHSC_FLAG_SIGA_OUTPUT_NECESSARY;
-		irq_ptr->input_qs[i]->siga_sync_done_on_thinints=
-			irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS;
-		irq_ptr->input_qs[i]->hydra_gives_outbound_pcis=
-			irq_ptr->hydra_gives_outbound_pcis;
-	}
-
-	for (i=0;i<init_data->no_output_qs;i++) {
-		irq_ptr->output_qs[i]->siga_sync=
-			irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_NECESSARY;
-		irq_ptr->output_qs[i]->siga_in=
-			irq_ptr->qdioac&CHSC_FLAG_SIGA_INPUT_NECESSARY;
-		irq_ptr->output_qs[i]->siga_out=
-			irq_ptr->qdioac&CHSC_FLAG_SIGA_OUTPUT_NECESSARY;
-		irq_ptr->output_qs[i]->siga_sync_done_on_thinints=
-			irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS;
-		irq_ptr->output_qs[i]->hydra_gives_outbound_pcis=
-			irq_ptr->hydra_gives_outbound_pcis;
-	}
-
-	qdio_set_state(irq_ptr,QDIO_IRQ_STATE_ESTABLISHED);
-
- out:
-	if (irq_ptr) {
-		my_spin_unlock(&irq_ptr->setting_up_lock);
-	}
- out2:
-	up(&init_sema);
-
-	return result;
-}
-
-int qdio_activate(int irq,int flags)
-{
-	qdio_irq_t *irq_ptr;
-	int i,result=0,result2;
-	unsigned long saveflags;
-	char dbf_text[20]; /* see qdio_initialize */
-
-	irq_ptr=qdio_get_irq_ptr(irq);
-	if (!irq_ptr) return -ENODEV;
-
-	my_spin_lock(&irq_ptr->setting_up_lock);
-	if (irq_ptr->state==QDIO_IRQ_STATE_INACTIVE) {
-		result=-EBUSY;
-		goto out;
-	}
-
-	sprintf(dbf_text,"qact%4x",irq);
-	QDIO_DBF_TEXT2(0,setup,dbf_text);
-	QDIO_DBF_TEXT2(0,trace,dbf_text);
-
-	/* activate q */
-	irq_ptr->ccw.cmd_code=irq_ptr->commands.aq;
-	irq_ptr->ccw.flags=CCW_FLAG_SLI;
-	irq_ptr->ccw.count=irq_ptr->commands.count_aq;
-	irq_ptr->ccw.cda=QDIO_GET_ADDR(0);
-
-	my_s390irq_spin_lock_irqsave(irq_ptr->irq,saveflags);
-	atomic_set(&irq_ptr->interrupt_has_arrived,0);
-
-	result=do_IO(irq_ptr->irq,&irq_ptr->ccw,QDIO_DOING_ACTIVATE,
-		     0,DOIO_REPORT_ALL|DOIO_DENY_PREFETCH);
-	if (result) {
-		result2=do_IO(irq_ptr->irq,&irq_ptr->ccw,
-			      QDIO_DOING_ACTIVATE,0,DOIO_REPORT_ALL);
-		sprintf(dbf_text,"aq:io%4x",result);
-		QDIO_DBF_TEXT2(1,setup,dbf_text);
-		if (result2) {
-			sprintf(dbf_text,"aq:io%4x",result);
-			QDIO_DBF_TEXT2(1,setup,dbf_text);
-		}
-		QDIO_PRINT_WARN("activate queues on irq %04x: do_IO " \
-                           "returned %i, next try returned %i\n",
-                           irq_ptr->irq,result,result2);
-		result=result2;
-	}
-
-	my_s390irq_spin_unlock_irqrestore(irq_ptr->irq,saveflags);
-	if (result) {
-		goto out;
-	}
-
-	if (!(flags&QDIO_FLAG_UNDER_INTERRUPT)) {
-		result=qdio_sleepon(&irq_ptr->interrupt_has_arrived,
-				    QDIO_ACTIVATE_TIMEOUT,irq_ptr);
-
-		if (result!=-ETIME) {
-			QDIO_DBF_TEXT2(1,setup,"aq:badio");
-			QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_dstat,
-				      sizeof(irq_ptr->io_result_dstat));
-			QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_cstat,
-				      sizeof(irq_ptr->io_result_cstat));
-			QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_flags,
-				      sizeof(irq_ptr->io_result_flags));
-			QDIO_PRINT_ERR("activate queues on irq %04x: got " \
-				       "the following devstat: dstat=%02x, " \
-				       "cstat=%02x, flags=%02x\n",
-				       irq_ptr->irq,irq_ptr->io_result_dstat,
-				       irq_ptr->io_result_cstat,
-				       irq_ptr->io_result_flags);
-			result=-EIO;
-			goto out;
-		} else { /* result is -ETIME, but timeout is ok for us */
-			result=0;
-		}
-	} else result=0;
-
-	for (i=0;i<irq_ptr->no_input_qs;i++) {
-		if (irq_ptr->is_iqdio_irq) {
-			/* that way we know, that, if we will
-			 * get interrupted
-			 * by iqdio_inbound_processing,
-			 * qdio_unmark_q will
-			 * not be called */
-			qdio_reserve_q(irq_ptr->input_qs[i]);
-			qdio_mark_iq(irq_ptr->input_qs[i]);
-			qdio_release_q(irq_ptr->input_qs[i]);
-		}
-	}
-
-	if (flags&QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT) {
-		for (i=0;i<irq_ptr->no_input_qs;i++) {
-			irq_ptr->input_qs[i]->is_input_q|=
-				QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT;
-		}
-	}
-
-	qdio_set_state(irq_ptr,QDIO_IRQ_STATE_ACTIVE);
-
- out:
-	my_spin_unlock(&irq_ptr->setting_up_lock);
-
-	return result;
-}
-
-/* buffers filled forwards again to make Rick happy */
-static void qdio_do_qdio_fill_input(qdio_q_t *q,unsigned int qidx,
-				    unsigned int count,qdio_buffer_t *buffers)
-{
-	for (;;) {
-		if (!q->is_0copy_sbals_q) {
-			memcpy((void*)q->sbal[qidx],buffers,SBAL_SIZE);
-			q->qdio_buffers[qidx]=buffers;
-			buffers++;
-		}
-		set_slsb(&q->slsb.acc.val[qidx],SLSB_CU_INPUT_EMPTY);
-		count--;
-		if (!count) break;
-		qidx=(qidx+1)&(QDIO_MAX_BUFFERS_PER_Q-1);
-	}
-
-	/* not necessary, as the queues are synced during the SIGA read
-	SYNC_MEMORY;*/
-}
-
-static inline void qdio_do_qdio_fill_output(qdio_q_t *q,unsigned int qidx,
-					    unsigned int count,
-					    qdio_buffer_t *buffers)
-{
-	for (;;) {
-		if (!q->is_0copy_sbals_q) {
-			memcpy((void*)q->sbal[qidx],buffers,SBAL_SIZE);
-			q->qdio_buffers[qidx]=buffers;
-			buffers++;
-		}
-		set_slsb(&q->slsb.acc.val[qidx],SLSB_CU_OUTPUT_PRIMED);
-		count--;
-		if (!count) break;
-		qidx=(qidx+1)&(QDIO_MAX_BUFFERS_PER_Q-1);
-	}
-
-	/* SIGA write will sync the queues
-	SYNC_MEMORY;*/
-}
-
-/* count must be 1 in iqdio */
-int do_QDIO(int irq,unsigned int callflags,unsigned int queue_number,
-	    unsigned int qidx,unsigned int count,qdio_buffer_t *buffers)
-{
-	qdio_q_t *q;
-	qdio_irq_t *irq_ptr;
-	int result;
-	int used_elements;
-
-#ifdef QDIO_DBF_LIKE_HELL
-	char dbf_text[20];
-
-	sprintf(dbf_text,"doQD%04x",irq);
-	QDIO_DBF_TEXT3(0,trace,dbf_text);
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	if ( (qidx>QDIO_MAX_BUFFERS_PER_Q) ||
-	     (count>QDIO_MAX_BUFFERS_PER_Q) ||
-	     (queue_number>QDIO_MAX_QUEUES_PER_IRQ) )
-		return -EINVAL;
-
-	if (count==0) return 0;
-
-	irq_ptr=qdio_get_irq_ptr(irq);
-	if (!irq_ptr) return -ENODEV;
-
-#ifdef QDIO_DBF_LIKE_HELL
-	if (callflags&QDIO_FLAG_SYNC_INPUT)
-		QDIO_DBF_HEX3(0,trace,&irq_ptr->input_qs[queue_number],
-			      sizeof(void*));
-	else
-		QDIO_DBF_HEX3(0,trace,&irq_ptr->output_qs[queue_number],
-			      sizeof(void*));
-	sprintf(dbf_text,"flag%04x",callflags);
-	QDIO_DBF_TEXT3(0,trace,dbf_text);
-	sprintf(dbf_text,"qi%02xct%02x",qidx,count);
-	QDIO_DBF_TEXT3(0,trace,dbf_text);
-	if ( ((callflags&QDIO_FLAG_SYNC_INPUT)&&
-	      (!irq_ptr->input_qs[queue_number]->is_0copy_sbals_q)) ||
-	     ((callflags&QDIO_FLAG_SYNC_OUTPUT)&&
-	      (!irq_ptr->output_qs[queue_number]->is_0copy_sbals_q)) )
-		QDIO_DBF_HEX5(0,sbal,buffers,256);
-#endif /* QDIO_DBF_LIKE_HELL */
-
-	if (irq_ptr->state!=QDIO_IRQ_STATE_ACTIVE) {
-		return -EBUSY;
-	}
-
-	if (callflags&QDIO_FLAG_SYNC_INPUT) {
-		/* This is the inbound handling of queues */
-		q=irq_ptr->input_qs[queue_number];
-
-		used_elements=atomic_return_add(count,
-						&q->number_of_buffers_used);
-
-		qdio_do_qdio_fill_input(q,qidx,count,buffers);
-
-		if ((used_elements+count==QDIO_MAX_BUFFERS_PER_Q)&&
-		    (callflags&QDIO_FLAG_UNDER_INTERRUPT))
-			atomic_swap(&q->polling,0);
-
-		if (!used_elements) if (!(callflags&QDIO_FLAG_DONT_SIGA)) {
-			if (q->siga_in) {
-				result=qdio_siga_input(q);
-				if (result) {
-					if (q->siga_error)
-						q->error_status_flags|=
-							QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR;
-					q->error_status_flags|=
-						QDIO_STATUS_LOOK_FOR_ERROR;
-					q->siga_error=result;
-				}
-			}
-
-			qdio_mark_q(q);
-		}
-	} else if (callflags&QDIO_FLAG_SYNC_OUTPUT) {
-		/* This is the outbound handling of queues */
-#ifdef QDIO_PERFORMANCE_STATS
-		perf_stats.start_time_outbound=NOW;
-#endif /* QDIO_PERFORMANCE_STATS */
-		q=irq_ptr->output_qs[queue_number];
-
-		qdio_do_qdio_fill_output(q,qidx,count,buffers);
-
-		used_elements=atomic_return_add(count,
-						&q->number_of_buffers_used);
-
-		if (!(callflags&QDIO_FLAG_DONT_SIGA)) {
-			if (q->is_iqdio_q) {
-				/* one siga for every sbal */
-				while (count--) {
-					qdio_kick_outbound_q(q);
-				}
-
-				qdio_outbound_processing(q);
-			} else {
-				/* under VM, we do a SIGA sync
-				 * unconditionally */
-				SYNC_MEMORY;
-				else {
-					/* w/o shadow queues (else branch of
-					 * SYNC_MEMORY :-/ ), we try to
-					 * fast-requeue buffers */
-					if (q->slsb.acc.val
-					    [(qidx+QDIO_MAX_BUFFERS_PER_Q-1)
-					    &(QDIO_MAX_BUFFERS_PER_Q-1)]!=
-					    SLSB_CU_OUTPUT_PRIMED) {
-						qdio_kick_outbound_q(q);
-					} else {
-#ifdef QDIO_DBF_LIKE_HELL
-						QDIO_DBF_TEXT3(0,trace,
-							       "fast-req");
-#endif /* QDIO_DBF_LIKE_HELL */
-#ifdef QDIO_PERFORMANCE_STATS
-						perf_stats.fast_reqs++;
-#endif /* QDIO_PERFORMANCE_STATS */
-					}
-				}
-				/* only marking the q could take
-				 * too long, the upper layer
-				 * module could do a lot of
-				 * traffic in that time */
-				qdio_outbound_processing(q);
-			}
-		}
-
-#ifdef QDIO_PERFORMANCE_STATS
-		perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound;
-		perf_stats.outbound_cnt++;
-#endif /* QDIO_PERFORMANCE_STATS */
-	} else {
-		QDIO_DBF_TEXT3(1,trace,"doQD:inv");
-		return -EINVAL;
-	}
-	return 0;
-}
-
-#ifdef QDIO_PERFORMANCE_STATS
-static int qdio_perf_procfile_read(char *buffer,char **buffer_location,
-       				   off_t offset,int buffer_length,int *eof,
-				   void *data)
-{
-        int c=0;
-	qdio_irq_t *irq_ptr;
-
-        /* we are always called with buffer_length=4k, so we all
-           deliver on the first read */
-        if (offset>0) return 0;
-
-	/* FIXME: wtf are you trying to do? this is guaranteed to
-	 * fail, you even get a compiler warning! */
-	irq_ptr=first_irq;
-
-#define _OUTP_IT(x...) c+=sprintf(buffer+c,x)
-	_OUTP_IT("i_p_nc/c=%lu/%lu\n",i_p_nc,i_p_c);
-	_OUTP_IT("ii_p_nc/c=%lu/%lu\n",ii_p_nc,ii_p_c);
-	_OUTP_IT("o_p_nc/c=%lu/%lu\n",o_p_nc,o_p_c);
-	_OUTP_IT("Number of tasklet runs (total)                  : %u\n",
-		 perf_stats.tl_runs);
-	_OUTP_IT("\n");
-	_OUTP_IT("Number of SIGA sync's issued                    : %u\n",
-		 perf_stats.siga_syncs);
-	_OUTP_IT("Number of SIGA in's issued                      : %u\n",
-		 perf_stats.siga_ins);
-	_OUTP_IT("Number of SIGA out's issued                     : %u\n",
-		 perf_stats.siga_outs);
-	_OUTP_IT("Number of PCI's caught                          : %u\n",
-		 perf_stats.pcis);
-	_OUTP_IT("Number of adapter interrupts caught             : %u\n",
-		 perf_stats.thinints);
-	_OUTP_IT("Number of fast requeues (outg. SBALs w/o SIGA)  : %u\n",
-		 perf_stats.fast_reqs);
-	_OUTP_IT("\n");
-	_OUTP_IT("Total time of all inbound actions (us) incl. UL : %u\n",
-		 perf_stats.inbound_time);
-	_OUTP_IT("Number of inbound transfers                     : %u\n",
-		 perf_stats.inbound_cnt);
-	_OUTP_IT("Total time of all outbound do_QDIOs (us)        : %u\n",
-		 perf_stats.outbound_time);
-	_OUTP_IT("Number of do_QDIOs outbound                     : %u\n",
-		 perf_stats.outbound_cnt);
-	_OUTP_IT("\n");
-	while (irq_ptr) {
-		_OUTP_IT("Polling time on irq %4x                        " \
-			 ": %u\n",
-			 irq_ptr->irq,irq_ptr->input_qs[0]->timing.threshold);
-		irq_ptr=irq_ptr->next;
-	}
-
-        return c;
-}
-
-static struct proc_dir_entry *qdio_perf_proc_file;
-#endif /* QDIO_PERFORMANCE_STATS */
-
-static void qdio_add_procfs_entry(void)
-{
-#ifdef QDIO_PERFORMANCE_STATS
-        proc_perf_file_registration=0;
-	qdio_perf_proc_file=create_proc_entry(QDIO_PERF,
-					      S_IFREG|0444,&proc_root);
-	if (qdio_perf_proc_file) {
-		qdio_perf_proc_file->read_proc=&qdio_perf_procfile_read;
-	} else proc_perf_file_registration=-1;
-
-        if (proc_perf_file_registration)
-                QDIO_PRINT_WARN("was not able to register perf. " \
-				"proc-file (%i).\n",
-				proc_perf_file_registration);
-#endif /* QDIO_PERFORMANCE_STATS */
-}
-#ifdef MODULE
-static void qdio_remove_procfs_entry(void)
-{
-#ifdef QDIO_PERFORMANCE_STATS
-	perf_stats.tl_runs=0;
-
-        if (!proc_perf_file_registration) /* means if it went ok earlier */
-		remove_proc_entry(QDIO_PERF,&proc_root);
-#endif /* QDIO_PERFORMANCE_STATS */
-}
-#endif /* MODULE */
-
-static void iqdio_register_thinints(void)
-{
-	char dbf_text[20];
-	register_thinint_result=
-		s390_register_adapter_interrupt(&iqdio_thinint_handler);
-	if (register_thinint_result) {
-		sprintf(dbf_text,"regthn%x",(register_thinint_result&0xff));
-		QDIO_DBF_TEXT0(0,setup,dbf_text);
-		QDIO_PRINT_ERR("failed to register adapter handler " \
-			       "(rc=%i).\nAdapter interrupts might " \
-			       "not work. Continuing.\n",
-			       register_thinint_result);
-	}
-}
-
-#ifdef MODULE
-static void iqdio_unregister_thinints(void)
-{
-	if (!register_thinint_result)
-		s390_unregister_adapter_interrupt(&iqdio_thinint_handler);
-}
-#endif /* MODULE */
-
-static int qdio_get_qdio_memory(void)
-{
-	int i;
-	indicator_used[0]=1;
-
-	for (i=1;i<INDICATORS_PER_CACHELINE;i++)
-		indicator_used[i]=0;
-	indicators=(__u32*)kmalloc(sizeof(__u32)*(INDICATORS_PER_CACHELINE),
-				   GFP_KERNEL);
-       	if (!indicators) return -ENOMEM;
-	memset(indicators,0,sizeof(__u32)*(INDICATORS_PER_CACHELINE));
-
-	chsc_area=(qdio_chsc_area_t *)
-		kmalloc(sizeof(qdio_chsc_area_t),GFP_KERNEL);
-	QDIO_DBF_TEXT3(0,trace,"chscarea"); \
-	QDIO_DBF_HEX3(0,trace,&chsc_area,sizeof(void*)); \
-	if (!chsc_area) {
-		/* ahem... let's call it data area */
-		QDIO_PRINT_ERR("not enough memory for data area. Cannot " \
-			       "initialize QDIO.\n");
-		kfree(indicators);
-		return -ENOMEM;
-	}
-	memset(chsc_area,0,sizeof(qdio_chsc_area_t));
-	return 0;
-}
-
-#ifdef MODULE
-static void qdio_release_qdio_memory(void)
-{
-	kfree(chsc_area);
-	if (indicators) kfree(indicators);
-}
-#endif /* MODULE */
-
-int init_module(void); /* we want to use it in init_QDIO */
-
-static void qdio_unregister_dbf_views(void)
-{
-	if (qdio_dbf_setup)
-		debug_unregister(qdio_dbf_setup);
-	if (qdio_dbf_sbal)
-		debug_unregister(qdio_dbf_sbal);
-	if (qdio_dbf_sense)
-		debug_unregister(qdio_dbf_sense);
-	if (qdio_dbf_trace)
-		debug_unregister(qdio_dbf_trace);
-#ifdef QDIO_DBF_LIKE_HELL
-        if (qdio_dbf_slsb_out)
-                debug_unregister(qdio_dbf_slsb_out);
-        if (qdio_dbf_slsb_in)
-                debug_unregister(qdio_dbf_slsb_in);
-#endif /* QDIO_DBF_LIKE_HELL */
-}
-
-/* this is not __initfunc, as it is called from init_module */
-static int __init init_QDIO(void)
-{
-	int res;
-#if defined(MODULE)||defined(QDIO_PERFORMANCE_STATS)
-	void *ptr;
-#endif /* defined(MODULE)||defined(QDIO_PERFORMANCE_STATS) */
-
-	qdio_eyecatcher();
-
-	printk("qdio: loading %s\n",version);
-
-	res=qdio_get_qdio_memory();
-	if (res) return res;
-
-	sema_init(&init_sema,1);
-
-	qdio_dbf_setup=debug_register(QDIO_DBF_SETUP_NAME,
-				      QDIO_DBF_SETUP_INDEX,
-				      QDIO_DBF_SETUP_NR_AREAS,
-				      QDIO_DBF_SETUP_LEN);
-	if (!qdio_dbf_setup) goto oom;
-	debug_register_view(qdio_dbf_setup,&debug_hex_ascii_view);
-	debug_set_level(qdio_dbf_setup,QDIO_DBF_SETUP_LEVEL);
-
-	qdio_dbf_sbal=debug_register(QDIO_DBF_SBAL_NAME,
-				     QDIO_DBF_SBAL_INDEX,
-				     QDIO_DBF_SBAL_NR_AREAS,
-				     QDIO_DBF_SBAL_LEN);
-	if (!qdio_dbf_sbal) goto oom;
-
-	debug_register_view(qdio_dbf_sbal,&debug_hex_ascii_view);
-	debug_set_level(qdio_dbf_sbal,QDIO_DBF_SBAL_LEVEL);
-
-	qdio_dbf_sense=debug_register(QDIO_DBF_SENSE_NAME,
-				      QDIO_DBF_SENSE_INDEX,
-				      QDIO_DBF_SENSE_NR_AREAS,
-				      QDIO_DBF_SENSE_LEN);
-	if (!qdio_dbf_sense) goto oom;
-
-	debug_register_view(qdio_dbf_sense,&debug_hex_ascii_view);
-	debug_set_level(qdio_dbf_sense,QDIO_DBF_SENSE_LEVEL);
-
-	qdio_dbf_trace=debug_register(QDIO_DBF_TRACE_NAME,
-				      QDIO_DBF_TRACE_INDEX,
-				      QDIO_DBF_TRACE_NR_AREAS,
-				      QDIO_DBF_TRACE_LEN);
-	if (!qdio_dbf_trace) goto oom;
-
-	debug_register_view(qdio_dbf_trace,&debug_hex_ascii_view);
-	debug_set_level(qdio_dbf_trace,QDIO_DBF_TRACE_LEVEL);
-
-#ifdef QDIO_DBF_LIKE_HELL
-        qdio_dbf_slsb_out=debug_register(QDIO_DBF_SLSB_OUT_NAME,
-                                         QDIO_DBF_SLSB_OUT_INDEX,
-                                         QDIO_DBF_SLSB_OUT_NR_AREAS,
-                                         QDIO_DBF_SLSB_OUT_LEN);
-        if (!qdio_dbf_slsb_out) goto oom;
-        debug_register_view(qdio_dbf_slsb_out,&debug_hex_ascii_view);
-        debug_set_level(qdio_dbf_slsb_out,QDIO_DBF_SLSB_OUT_LEVEL);
-
-        qdio_dbf_slsb_in=debug_register(QDIO_DBF_SLSB_IN_NAME,
-                                        QDIO_DBF_SLSB_IN_INDEX,
-                                        QDIO_DBF_SLSB_IN_NR_AREAS,
-                                        QDIO_DBF_SLSB_IN_LEN);
-        if (!qdio_dbf_slsb_in) goto oom;
-        debug_register_view(qdio_dbf_slsb_in,&debug_hex_ascii_view);
-        debug_set_level(qdio_dbf_slsb_in,QDIO_DBF_SLSB_IN_LEVEL);
-#endif /* QDIO_DBF_LIKE_HELL */
-
-#ifdef QDIO_PERFORMANCE_STATS
-       	memset((void*)&perf_stats,0,sizeof(perf_stats));
-	QDIO_DBF_TEXT0(0,setup,"perfstat");
-	ptr=&perf_stats;
-	QDIO_DBF_HEX0(0,setup,&ptr,sizeof(void*));
-#endif /* QDIO_PERFORMANCE_STATS */
-
-#ifdef MODULE
-	QDIO_DBF_TEXT0(0,setup,"initmodl");
-	ptr=&init_module;
-	QDIO_DBF_HEX0(0,setup,&ptr,sizeof(void*));
-#endif /* MODULE */
-
-	qdio_add_procfs_entry();
-
-	iqdio_register_thinints();
-
-	return 0;
- oom:
-	QDIO_PRINT_ERR("not enough memory for dbf.\n");
-	qdio_unregister_dbf_views();
-	return -ENOMEM;
-}
-
-#ifdef MODULE
-int init_module(void)
-{
-	return init_QDIO();
-}
-
-void cleanup_module(void)
-{
-	iqdio_unregister_thinints();
-
-	qdio_remove_procfs_entry();
-
-	qdio_release_qdio_memory();
-
-	qdio_unregister_dbf_views();
-
-  	printk("qdio: %s: module removed\n",version);
-}
-#else /* MODULE */
-static int __init initcall_QDIO(void)
-{
-	        return init_QDIO();
-}
-__initcall(initcall_QDIO);
-#endif /* MODULE */
-
-EXPORT_SYMBOL(qdio_initialize);
-EXPORT_SYMBOL(qdio_activate);
-EXPORT_SYMBOL(do_QDIO);
-EXPORT_SYMBOL(qdio_cleanup);
-EXPORT_SYMBOL(qdio_eyecatcher);
-EXPORT_SYMBOL(qdio_synchronize);
diff -Nru a/drivers/s390/s390dyn.c b/drivers/s390/s390dyn.c
--- a/drivers/s390/s390dyn.c	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,160 +0,0 @@
-/*
- *  drivers/s390/s390dyn.c
- *   S/390 dynamic device attachment
- *
- *  S390 version
- *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Ingo Adlung (adlung@de.ibm.com)
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/smp_lock.h>
-#include <linux/errno.h>
-
-#include <asm/irq.h>
-#include <asm/s390io.h>
-#include <asm/s390dyn.h>
-
-static struct list_head devreg_anchor = LIST_HEAD_INIT(devreg_anchor);
-static spinlock_t dyn_lock = SPIN_LOCK_UNLOCKED;
-
-static inline int
-s390_device_register_internal(devreg_t * drinfo)
-{
-	struct list_head *p;
-
-	list_for_each(p, &devreg_anchor) {
-		devreg_t *pdevreg = list_entry(p, devreg_t, list);
-
-		if (pdevreg == drinfo)
-			return -EINVAL;
-		/*
-		 * We don't allow multiple drivers to register
-		 * for the same device number
-		 */
-		if (pdevreg->ci.devno == drinfo->ci.devno &&
-		    (pdevreg->flag & DEVREG_TYPE_DEVNO) &&
-		    (drinfo->flag & DEVREG_TYPE_DEVNO))
-			return -EBUSY;
-
-		if (drinfo->flag == (DEVREG_TYPE_DEVCHARS |
-				     DEVREG_EXACT_MATCH) &&
-		    !memcmp(&drinfo->ci.hc, &pdevreg->ci.hc,
-			    sizeof (devreg_hc_t)))
-			return -EBUSY;
-	}
-
-	/*
-	 * no collision found, enqueue
-	 */
-	list_add(&drinfo->list, &devreg_anchor);
-
-	return 0;
-}
-
-int
-s390_device_register(devreg_t * drinfo)
-{
-	unsigned long flags;
-	int ret;
-
-	if (drinfo == NULL ||
-	    !(drinfo->flag & (DEVREG_TYPE_DEVNO | DEVREG_TYPE_DEVCHARS)))
-		return -EINVAL;
-
-	spin_lock_irqsave(&dyn_lock, flags);
-	ret = s390_device_register_internal(drinfo);
-	spin_unlock_irqrestore(&dyn_lock, flags);
-
-	return ret;
-}
-
-static inline int
-s390_device_unregister_internal(devreg_t * dreg)
-{
-	struct list_head *p;
-
-	list_for_each(p, &devreg_anchor) {
-		devreg_t *pdevreg = list_entry(p, devreg_t, list);
-
-		if (pdevreg == dreg) {
-			list_del(&dreg->list);
-			return 0;
-		}
-	}
-	return -EINVAL;
-}
-
-int
-s390_device_unregister(devreg_t * dreg)
-{
-	unsigned long flags;
-	int ret;
-
-	if (dreg == NULL)
-		return -EINVAL;
-
-	spin_lock_irqsave(&dyn_lock, flags);
-	ret = s390_device_unregister_internal(dreg);
-	spin_unlock_irqrestore(&dyn_lock, flags);
-
-	return ret;
-}
-
-static inline devreg_t *
-s390_search_devreg_internal(ioinfo_t * ioinfo)
-{
-	struct list_head *p;
-
-	list_for_each(p, &devreg_anchor) {
-		devreg_t *pdevreg = list_entry(p, devreg_t, list);
-		senseid_t *sid;
-		int flag;
-
-		flag = pdevreg->flag;
-		sid = &ioinfo->senseid;
-		if (flag & DEVREG_TYPE_DEVNO) {
-			if (ioinfo->ui.flags.dval != 1 ||
-			    ioinfo->devno != pdevreg->ci.devno)
-				continue;
-		} else if (flag & DEVREG_TYPE_DEVCHARS) {
-			if ((flag & DEVREG_MATCH_CU_TYPE) &&
-			    pdevreg->ci.hc.ctype != sid->cu_type)
-				continue;
-			if ((flag & DEVREG_MATCH_CU_MODEL) &&
-			    pdevreg->ci.hc.cmode != sid->cu_model)
-				continue;
-			if ((flag & DEVREG_MATCH_DEV_TYPE) &&
-			    pdevreg->ci.hc.dtype != sid->dev_type)
-				continue;
-			if ((flag & DEVREG_MATCH_DEV_MODEL) &&
-			    pdevreg->ci.hc.dmode != sid->dev_model)
-				continue;
-		} else {
-			continue;
-		}
-
-		return pdevreg;
-	}
-	return NULL;
-}
-
-devreg_t *
-s390_search_devreg(ioinfo_t * ioinfo)
-{
-	unsigned long flags;
-	devreg_t *pdevreg;
-
-	if (ioinfo == NULL)
-		return NULL;
-
-	spin_lock_irqsave(&dyn_lock, flags);
-	pdevreg = s390_search_devreg_internal(ioinfo);
-	spin_unlock_irqrestore(&dyn_lock, flags);
-
-	return pdevreg;
-}
-
-EXPORT_SYMBOL(s390_device_register);
-EXPORT_SYMBOL(s390_device_unregister);
diff -Nru a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c
--- a/drivers/s390/s390mach.c	Mon Dec  9 18:46:52 2002
+++ b/drivers/s390/s390mach.c	Mon Dec  9 18:46:52 2002
@@ -5,617 +5,172 @@
  *  S390 version
  *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
  *    Author(s): Ingo Adlung (adlung@de.ibm.com)
+ *		 Martin Schwidefsky (schwidefsky@de.ibm.com)
  */
 
 #include <linux/config.h>
-#include <linux/spinlock.h>
 #include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/completion.h>
-#ifdef CONFIG_SMP
-#include <linux/smp.h>
-#endif
+#include <linux/sched.h>
 
-#include <asm/irq.h>
 #include <asm/lowcore.h>
-#include <asm/semaphore.h>
-#include <asm/s390io.h>
-#include <asm/s390dyn.h>
-#include <asm/s390mach.h>
-#ifdef CONFIG_MACHCHK_WARNING
-#include <asm/signal.h>
-#endif
 
-#define S390_MACHCHK_DEBUG
+#include "s390mach.h"
 
-#ifdef S390_MACHCHK_DEBUG
 #define DBG printk
-#else				/* S390_MACHCHK_DEBUG */
-#define DBG(args,...) do {} while (0);
-#endif				/* S390_MACHCHK_DEBUG */
-
-static int s390_machine_check_handler(void *parm);
-static void s390_enqueue_mchchk(mache_t * mchchk);
-static mache_t *s390_dequeue_mchchk(void);
-static void s390_enqueue_free_mchchk(mache_t * mchchk);
-static mache_t *s390_dequeue_free_mchchk(void);
-static int s390_collect_crw_info(void);
-#ifdef CONFIG_MACHCHK_WARNING
-static int s390_post_warning(void);
-#endif
-
-static mache_t *mchchk_queue_head = NULL;
-static mache_t *mchchk_queue_tail = NULL;
-static mache_t *mchchk_queue_free = NULL;
-static crwe_t *crw_buffer_anchor = NULL;
-static spinlock_t mchchk_queue_lock = SPIN_LOCK_UNLOCKED;
-static spinlock_t crw_queue_lock = SPIN_LOCK_UNLOCKED;
+// #define DBG(args,...) do {} while (0);
 
-static struct semaphore s_sem;
-static DECLARE_COMPLETION(mchchk_thread_active);
+extern void css_process_crw(int);
+extern void chsc_process_crw(void);
 
-#ifdef CONFIG_MACHCHK_WARNING
-static int mchchk_wng_posted = 0;
-#endif
-
-/*
- * s390_init_machine_check
- *
- * initialize machine check handling
- */
-void
-s390_init_machine_check(void)
+static void
+s390_handle_damage(char *msg)
 {
-	crwe_t *pcrwe;		/* CRW buffer element pointer */
-	mache_t *pmache;	/* machine check element pointer */
-	int i;
-
-	init_MUTEX_LOCKED(&s_sem);
-
-	pcrwe = kmalloc(MAX_CRW_PENDING * sizeof (crwe_t), GFP_KERNEL);
-
-	if (!pcrwe) 
-		panic("s390_init_machine_check: unable to obtain memory\n");
-
-	crw_buffer_anchor = pcrwe;
-	
-	for (i = 0; i < MAX_CRW_PENDING - 1; i++) {
-		pcrwe->crwe_next =
-			(crwe_t *) ((unsigned long) pcrwe + sizeof (crwe_t));
-		pcrwe = pcrwe->crwe_next;
-		
-	}
-
-	pcrwe->crwe_next = NULL;
-
-	pmache = kmalloc(MAX_MACH_PENDING * sizeof (mache_t), GFP_KERNEL);
-
-	if (!pmache) 
-		panic("s390_init_machine_check: unable to obtain memory\n");
-
-	for (i = 0; i < MAX_MACH_PENDING; i++) {
-		s390_enqueue_free_mchchk(pmache);
-		pmache =
-			(mache_t *) ((unsigned long) pmache + sizeof (mache_t));
-		
-	}
-	
-	DBG(KERN_NOTICE "init_mach : starting machine check handler\n");
-
-	kernel_thread(s390_machine_check_handler, &s_sem,
-		      CLONE_FS | CLONE_FILES);
-
-	wait_for_completion(&mchchk_thread_active);
-
-	ctl_clear_bit(14, 25);	/* disable damage MCH */
-
-	ctl_set_bit(14, 26);	/* enable degradation MCH */
-	ctl_set_bit(14, 27);	/* enable system recovery MCH */
-
-
-#ifdef CONFIG_MACHCHK_WARNING
-	ctl_set_bit(14, 24);	/* enable warning MCH */
+	printk(KERN_EMERG "%s\n", msg);
+#ifdef CONFIG_SMP
+	smp_send_stop();
 #endif
-
-	DBG(KERN_DEBUG "init_mach : machine check buffer : head = %08X\n",
-	    (unsigned) &mchchk_queue_head);
-	DBG(KERN_DEBUG "init_mach : machine check buffer : tail = %08X\n",
-	    (unsigned) &mchchk_queue_tail);
-	DBG(KERN_DEBUG "init_mach : machine check buffer : free = %08X\n",
-	    (unsigned) &mchchk_queue_free);
-	DBG(KERN_DEBUG "init_mach : CRW entry buffer anchor = %08X\n",
-	    (unsigned) &crw_buffer_anchor);
-	DBG(KERN_DEBUG "init_mach : machine check handler ready\n");
-
-	return;
-}
-
-/*
- * initialize the machine check handler really early to be able to
- * catch all machine checks that happen during boot
- */
-static int __init
-machine_check_init (void)
-{
-	s390_init_machine_check();
-	return 0;
+	disabled_wait((unsigned long) __builtin_return_address(0));
 }
-arch_initcall(machine_check_init);
 
 /*
- * Machine checks for the channel subsystem must be enabled
- * after the channel subsystem is initialized
+ * Retrieve CRWs and call function to handle event.
+ *
+ * Note : we currently process CRWs for io and chsc subchannels only
  */
-static int __init
-machine_check_crw_init (void)
-{
-	ctl_set_bit(14, 28);	/* enable channel report MCH */
-	return 0;
-}
-device_initcall (machine_check_crw_init);
-
 static void
-s390_handle_damage(char *msg)
+s390_collect_crw_info(void)
 {
+	struct crw crw;
+	int ccode;
 
-	unsigned long caller = (unsigned long) __builtin_return_address(0);
-
-	printk(KERN_EMERG "%s\n", msg);
-#ifdef CONFIG_SMP
-	smp_send_stop();
-#endif
-	disabled_wait(caller);
-	return;
+	do {
+		ccode = stcrw(&crw);
+		if (ccode != 0)
+			break;
+		DBG(KERN_DEBUG "crw_info : CRW reports slct=%d, oflw=%d, "
+		    "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
+		    crw.slct, crw.oflw, crw.chn, crw.rsc, crw.anc,
+		    crw.erc, crw.rsid);
+		switch (crw.rsc) {
+		case CRW_RSC_SCH:
+			pr_debug(KERN_NOTICE, "source is subchannel %04X\n",
+				 crw.rsid);
+			css_process_crw (crw.rsid);
+			break;
+		case CRW_RSC_MONITOR:
+			pr_debug(KERN_NOTICE,
+				 "source is monitoring facility\n");
+			break;
+		case CRW_RSC_CPATH:
+			pr_debug(KERN_NOTICE,
+				 "source is channel path %02X\n",
+				 pcrwe->crw.rsid);
+			break;
+		case CRW_RSC_CONFIG:
+			pr_debug(KERN_NOTICE,
+				 "source is configuration-alert facility\n");
+			break;
+		case CRW_RSC_CSS:
+			pr_debug(KERN_NOTICE, "source is channel subsystem\n");
+			chsc_process_crw();
+			break;
+		default:
+			pr_debug(KERN_NOTICE, "unknown source\n");
+			break;
+		}
+	} while (crw.chn);
 }
 
 /*
- * s390_do_machine_check
- *
- * mchine check pre-processor, collecting the machine check info,
- *  queueing it and posting the machine check handler for processing.
+ * machine check handler.
  */
 void
 s390_do_machine_check(void)
 {
-	int crw_count;
-	mcic_t mcic;
+	struct mci *mci;
 
-	DBG(KERN_INFO "s390_do_machine_check : starting ...\n");
+	mci = (struct mci *) &S390_lowcore.mcck_interruption_code;
 
-	memcpy(&mcic, &S390_lowcore.mcck_interruption_code, sizeof (__u64));
-
-	if (mcic.mcc.mcd.sd)	/* system damage */
+	if (mci->sd)		/* system damage */
 		s390_handle_damage("received system damage machine check\n");
 
-	if (mcic.mcc.mcd.pd)	/* instruction processing damage */
-		s390_handle_damage
-		    ("received instruction processing damage machine check\n");
-
-	if (mcic.mcc.mcd.se)	/* storage error uncorrected */
-		s390_handle_damage
-		    ("received storage error uncorrected machine check\n");
+	if (mci->pd)		/* instruction processing damage */
+		s390_handle_damage("received instruction processing "
+				   "damage machine check\n");
+
+	if (mci->se)		/* storage error uncorrected */
+		s390_handle_damage("received storage error uncorrected "
+				   "machine check\n");
 
-	if (mcic.mcc.mcd.sc)	/* storage error corrected */
+	if (mci->sc)		/* storage error corrected */
 		printk(KERN_WARNING
 		       "received storage error corrected machine check\n");
 
-	if (mcic.mcc.mcd.ke)	/* storage key-error uncorrected */
-		s390_handle_damage
-		    ("received storage key-error uncorrected machine check\n");
-
-	if (mcic.mcc.mcd.ds && mcic.mcc.mcd.fa)	/* storage degradation */
-		s390_handle_damage
-		    ("received storage degradation machine check\n");
-
-	if (mcic.mcc.mcd.cp) {	/* CRW pending ? */
-
-		crw_count = s390_collect_crw_info();
+	if (mci->ke)		/* storage key-error uncorrected */
+		s390_handle_damage("received storage key-error uncorrected "
+				   "machine check\n");
+
+	if (mci->ds && mci->fa)	/* storage degradation */
+		s390_handle_damage("received storage degradation machine "
+				   "check\n");
 
-		if (crw_count)
-			up(&s_sem);
+	if (mci->cp)		/* channel report word pending */
+		s390_collect_crw_info();
 
-	}
 #ifdef CONFIG_MACHCHK_WARNING
 /*
  * The warning may remain for a prolonged period on the bare iron.
  * (actually till the machine is powered off, or until the problem is gone)
  * So we just stop listening for the WARNING MCH and prevent continuously
- * being interrupted.  One caveat is however, that we must do this per 
+ * being interrupted.  One caveat is however, that we must do this per
  * processor and cannot use the smp version of ctl_clear_bit().
  * On VM we only get one interrupt per virtally presented machinecheck.
- * Though one suffices, we may get one interrupt per (virtual) processor. 
+ * Though one suffices, we may get one interrupt per (virtual) processor.
  */
-	if (mcic.mcc.mcd.w) {	/* WARNING pending ? */
-
-		/* 
-		 * Use single machine clear, as we cannot handle smp right now 
+	if (mci->w) {	/* WARNING pending ? */
+		static int mchchk_wng_posted = 0;
+		/*
+		 * Use single machine clear, as we cannot handle smp right now
 		 */
 		__ctl_clear_bit(14, 24);	/* Disable WARNING MCH */
-
-		if (!mchchk_wng_posted) {
-			mchchk_wng_posted = s390_post_warning();
-
-			if (mchchk_wng_posted)
-				up(&s_sem);
-
-		}
-
+		if (xchg(&mchchk_wng_posted, 1) == 0)
+			kill_proc(1, SIGPWR, 1);
 	}
 #endif
-
-	DBG(KERN_INFO "s390_do_machine_check : done \n");
-
-	return;
 }
 
 /*
- * s390_machine_check_handler
+ * s390_init_machine_check
  *
- * machine check handler, dequeueing machine check entries
- *  and processing them
+ * initialize machine check handling
  */
 static int
-s390_machine_check_handler(void *parm)
+machine_check_init(void)
 {
-	struct semaphore *sem = parm;
-	unsigned long flags;
-	mache_t *pmache;
-
-	int found = 0;
-
-	/* set name to something sensible */
-	strcpy(current->comm, "kmcheck");
-
-	/* block all signals */
-	sigfillset(&current->blocked);
-
-	DBG(KERN_NOTICE "mach_handler : ready\n");
-
-	complete(&mchchk_thread_active);
-
-	do {
-
-		DBG(KERN_NOTICE "mach_handler : waiting for wakeup\n");
-
-		down_interruptible(sem);
-
-		DBG(KERN_NOTICE "\nmach_handler : wakeup ... \n");
-
-		found = 0;	/* init ... */
-
-		local_irq_save(flags);
-
-		do {
-
-			pmache = s390_dequeue_mchchk();
-
-			if (!pmache) {
-
-				/* unconditional surrender ... */
-				DBG(KERN_DEBUG
-				    "mach_handler : nothing to do, sleeping\n");
-				break;
-			}
-				
-			found = 1;
-			
-			if (pmache->mcic.mcc.mcd.cp) {
-				crwe_t *pcrwe_n;
-				crwe_t *pcrwe_h;
-				
-				s390_do_crw_pending(pmache->mc.crwe);
-				
-				pcrwe_h = pmache->mc.crwe;
-				pcrwe_n = pmache->mc.crwe->crwe_next;
-				
-				pmache->mcic.mcc.mcd.cp = 0;
-				pmache->mc.crwe = NULL;
-				
-				spin_lock(&crw_queue_lock);
-				
-				while (pcrwe_h) {
-					pcrwe_h->crwe_next = crw_buffer_anchor;
-					crw_buffer_anchor = pcrwe_h;
-					pcrwe_h = pcrwe_n;
-					
-					if (pcrwe_h != NULL)
-						pcrwe_n = pcrwe_h->crwe_next;
-					
-				}
-				
-				spin_unlock(&crw_queue_lock);
-				
-			}
+	ctl_clear_bit(14, 25);	/* disable damage MCH */
+	ctl_set_bit(14, 26);	/* enable degradation MCH */
+	ctl_set_bit(14, 27);	/* enable system recovery MCH */
 #ifdef CONFIG_MACHCHK_WARNING
-			if (pmache->mcic.mcc.mcd.w) {
-				kill_proc(1, SIGPWR, 1);	/* Send INIT the signal */
-				
-				DBG(KERN_DEBUG 
-				    "mach_handler : kill -SIGPWR init\n");
-			}
+	ctl_set_bit(14, 24);	/* enable warning MCH */
 #endif
-			
-			s390_enqueue_free_mchchk(pmache);
-
-		} while (pmache);
-
-		local_irq_restore(flags);
-
-	} while (1);
-
 	return 0;
 }
 
 /*
- * s390_dequeue_mchchk
- *
- * Dequeue an entry from the machine check queue
- *
- * Note : The queue elements provide for a double linked list.
- *  We dequeue entries from the tail, and enqueue entries to
- *  the head.
- *
- */
-static mache_t *
-s390_dequeue_mchchk(void)
-{
-	mache_t *qe;
-
-	spin_lock(&mchchk_queue_lock);
-
-	qe = mchchk_queue_tail;
-
-	if (qe != NULL) {
-		mchchk_queue_tail = qe->prev;
-
-		if (mchchk_queue_tail != NULL) {
-			mchchk_queue_tail->next = NULL;
-		} else {
-			mchchk_queue_head = NULL;
-
-		}
-
-	}
-
-	spin_unlock(&mchchk_queue_lock);
-
-	return qe;
-}
-
-/*
- * s390_enqueue_mchchk
- *
- * Enqueue an entry to the machine check queue.
- *
- * Note : The queue elements provide for a double linked list.
- *  We enqueue entries to the head, and dequeue entries from
- *  the tail.
- *
- */
-static void
-s390_enqueue_mchchk(mache_t * pmache)
-{
-	spin_lock(&mchchk_queue_lock);
-
-	if (pmache != NULL) {
-
-		if (mchchk_queue_head == NULL) {	/* first element */
-			pmache->next = NULL;
-			pmache->prev = NULL;
-
-			mchchk_queue_head = pmache;
-			mchchk_queue_tail = pmache;
-		} else {	/* new head */
-
-			pmache->prev = NULL;
-			pmache->next = mchchk_queue_head;
-
-			mchchk_queue_head->prev = pmache;
-			mchchk_queue_head = pmache;
-
-		}
-
-	}
-
-	spin_unlock(&mchchk_queue_lock);
-
-	return;
-}
-
-/*
- * s390_enqueue_free_mchchk
- *
- * Enqueue a free entry to the free queue.
- *
- * Note : While the queue elements provide for a double linked list,
- *  the free queue entries are only concatenated by means of a
- *  single linked list (forward concatenation).
- *
- */
-static void
-s390_enqueue_free_mchchk(mache_t * pmache)
-{
-	if (pmache != NULL) {
-		memset(pmache, '\0', sizeof (mache_t));
-
-		spin_lock(&mchchk_queue_lock);
-
-		pmache->next = mchchk_queue_free;
-
-		mchchk_queue_free = pmache;
-
-		spin_unlock(&mchchk_queue_lock);
-
-	}
-
-	return;
-}
-
-/*
- * s390_dequeue_free_mchchk
- *
- * Dequeue an entry from the free queue.
- *
- * Note : While the queue elements provide for a double linked list,
- *  the free queue entries are only concatenated by means of a
- *  single linked list (forward concatenation).
- *
+ * Initialize the machine check handler really early to be able to
+ * catch all machine checks that happen during boot
  */
-static mache_t *
-s390_dequeue_free_mchchk(void)
-{
-	mache_t *qe;
-
-	spin_lock(&mchchk_queue_lock);
-
-	qe = mchchk_queue_free;
-
-	if (qe != NULL) {
-		mchchk_queue_free = qe->next;
-
-	}
-
-	spin_unlock(&mchchk_queue_lock);
-
-	return qe;
-}
+arch_initcall(machine_check_init);
 
 /*
- * s390_collect_crw_info
- *
- * Retrieve CRWs. If a CRW was found a machine check element
- *  is dequeued from the free chain, filled and enqueued to
- *  be processed.
- *
- * The function returns the number of CRWs found.
- *
- * Note : We must always be called disabled ...
+ * Machine checks for the channel subsystem must be enabled
+ * after the channel subsystem is initialized
  */
-static int
-s390_collect_crw_info(void)
+static int __init
+machine_check_crw_init (void)
 {
-	crw_t tcrw;		/* temporarily holds a CRW */
-	int ccode;		/* condition code from stcrw() */
-	crwe_t *pcrwe;		/* pointer to CRW buffer entry */
-
-	mache_t *pmache = NULL;	/* ptr to mchchk entry */
-	int chain = 0;		/* indicate chaining */
-	crwe_t *pccrw = NULL;	/* ptr to current CRW buffer entry */
-	int count = 0;		/* CRW count */
-
-	DBG(KERN_DEBUG "crw_info : looking for CRWs ...\n");
-
-	do {
-		ccode = stcrw((__u32 *) & tcrw);
-
-		if (ccode != 0) 
-			break;
-		count++;
-		
-		DBG(KERN_DEBUG "crw_info : CRW reports "
-		    "slct=%d, oflw=%d, chn=%d, "
-		    "rsc=%X, anc=%d, erc=%X, "
-		    "rsid=%X\n",
-		    tcrw.slct,
-		    tcrw.oflw,
-		    tcrw.chn, tcrw.rsc, tcrw.anc, tcrw.erc, tcrw.rsid);
-		
-		/*
-		 * Dequeue a CRW entry from the free chain
-		 *  and process it ...
-		 */
-		spin_lock(&crw_queue_lock);
-		
-		pcrwe = crw_buffer_anchor;
-		
-		if (pcrwe == NULL) {
-			spin_unlock(&crw_queue_lock);
-			printk(KERN_CRIT "crw_info : "
-			       "no CRW buffer entries available\n");
-			break;
-			
-		}
-		
-		crw_buffer_anchor = pcrwe->crwe_next;
-		pcrwe->crwe_next = NULL;
-		
-		spin_unlock(&crw_queue_lock);
-		
-		memcpy(&(pcrwe->crw), &tcrw, sizeof (crw_t));
-		
-		/*
-		 * If it is the first CRW, chain it to the mchchk
-		 *  buffer entry, otherwise to the last CRW entry.
-		 */
-		if (chain == 0) {
-			pmache = s390_dequeue_free_mchchk();
-			
-			if (!pmache) 
-				panic("crw_info: unable to dequeue "
-				      "free mchchk buffer");
-
-			memset(pmache, '\0', sizeof (mache_t));
-			
-			pmache->mcic.mcc.mcd.cp = 1;
-			pmache->mc.crwe = pcrwe;
-			pccrw = pcrwe;
-				
-		} else {
-			pccrw->crwe_next = pcrwe;
-			pccrw = pcrwe;
-			
-		}
-		
-		if (pccrw->crw.chn) {
-			
-			DBG(KERN_DEBUG "crw_info: "
-			    "chained CRWs pending ...\n\n");
-			
-			chain = 1;
-		} else {
-			chain = 0;
-			
-			/*
-			 * We can enqueue the mchchk buffer if
-			 *  there aren't more CRWs chained.
-			 */
-			s390_enqueue_mchchk(pmache);
-			
-		}
-		
-
-	} while (ccode == 0);
-
-	return count;
+	ctl_set_bit(14, 28);	/* enable channel report MCH */
+	return 0;
 }
 
-#ifdef CONFIG_MACHCHK_WARNING
-/*
- * s390_post_warning
- *
- * Post a warning type machine check
- *
- * The function returns 1 when succesfull (panics otherwise)
- */
-static int
-s390_post_warning(void)
-{
-	mache_t *pmache = NULL;	/* ptr to mchchk entry */
-
-	pmache = s390_dequeue_free_mchchk();
-
-	if (!pmache) 
-		panic("post_warning : "
-		      "unable to dequeue free mchchk buffer");
-
-	memset(pmache, '\0', sizeof (mache_t));
-	
-	pmache->mcic.mcc.mcd.w = 1;
-	
-	s390_enqueue_mchchk(pmache);
-
-	DBG(KERN_DEBUG "post_warning : 1 warning machine check posted\n");
-
-	return 1;
-}
-#endif
+device_initcall (machine_check_crw_init);
diff -Nru a/drivers/s390/s390mach.h b/drivers/s390/s390mach.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/s390/s390mach.h	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,83 @@
+/*
+ *  drivers/s390/s390mach.h
+ *   S/390 data definitions for machine check processing
+ *
+ *  S390 version
+ *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Author(s): Ingo Adlung (adlung@de.ibm.com)
+ */
+
+#ifndef __s390mach_h
+#define __s390mach_h
+
+#include <asm/types.h>
+
+struct mci {
+	__u32   sd              :  1; /* 00 system damage */
+	__u32   pd              :  1; /* 01 instruction-processing damage */
+	__u32   sr              :  1; /* 02 system recovery */
+	__u32   to_be_defined_1 :  4; /* 03-06 */
+	__u32   dg              :  1; /* 07 degradation */
+	__u32   w               :  1; /* 08 warning pending */
+	__u32   cp              :  1; /* 09 channel-report pending */
+	__u32   to_be_defined_2 :  6; /* 10-15 */
+	__u32   se              :  1; /* 16 storage error uncorrected */
+	__u32   sc              :  1; /* 17 storage error corrected */
+	__u32   ke              :  1; /* 18 storage-key error uncorrected */
+	__u32   ds              :  1; /* 19 storage degradation */
+	__u32	to_be_defined_3 :  4; /* 20-23 */
+	__u32   fa              :  1; /* 24 failing storage address validity */
+	__u32   to_be_defined_4 :  7; /* 25-31 */
+	__u32   ie              :  1; /* 32 indirect storage error */
+	__u32	to_be_defined_5 : 31; /* 33-63 */
+};
+
+/*
+ * Channel Report Word
+ */
+struct crw {
+	__u32 res1    :  1;   /* reserved zero */
+	__u32 slct    :  1;   /* solicited */
+	__u32 oflw    :  1;   /* overflow */
+	__u32 chn     :  1;   /* chained */
+	__u32 rsc     :  4;   /* reporting source code */
+	__u32 anc     :  1;   /* ancillary report */
+	__u32 res2    :  1;   /* reserved zero */
+	__u32 erc     :  6;   /* error-recovery code */
+	__u32 rsid    : 16;   /* reporting-source ID */
+} __attribute__ ((packed));
+
+#define CRW_RSC_MONITOR  0x2  /* monitoring facility */
+#define CRW_RSC_SCH      0x3  /* subchannel */
+#define CRW_RSC_CPATH    0x4  /* channel path */
+#define CRW_RSC_CONFIG   0x9  /* configuration-alert facility */
+#define CRW_RSC_CSS      0xB  /* channel subsystem */
+
+#define CRW_ERC_EVENT    0x00 /* event information pending */
+#define CRW_ERC_AVAIL    0x01 /* available */
+#define CRW_ERC_INIT     0x02 /* initialized */
+#define CRW_ERC_TERROR   0x03 /* temporary error */
+#define CRW_ERC_IPARM    0x04 /* installed parm initialized */
+#define CRW_ERC_TERM     0x05 /* terminal */
+#define CRW_ERC_PERRN    0x06 /* perm. error, fac. not init */
+#define CRW_ERC_PERRI    0x07 /* perm. error, facility init */
+#define CRW_ERC_PMOD     0x08 /* installed parameters modified */
+
+#define MCHCHK_STATUS_TO_PROCESS    0x00000001
+#define MCHCHK_STATUS_IN_PROGRESS   0x00000002
+#define MCHCHK_STATUS_WAITING       0x00000004
+
+extern __inline__ int stcrw(struct crw *pcrw )
+{
+        int ccode;
+
+        __asm__ __volatile__(
+                "STCRW 0(%1)\n\t"
+                "IPM %0\n\t"
+                "SRL %0,28\n\t"
+                : "=d" (ccode) : "a" (pcrw)
+                : "cc", "1" );
+        return ccode;
+}
+
+#endif /* __s390mach */
diff -Nru a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c
--- a/drivers/sbus/char/bpp.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/sbus/char/bpp.c	Mon Dec  9 18:46:34 2002
@@ -1031,8 +1031,6 @@
 
 #endif
 
-static devfs_handle_t devfs_handle;
-
 static int __init bpp_init(void)
 {
 	int rc;
@@ -1046,14 +1044,18 @@
 	if (rc < 0)
 		return rc;
 
-	for (idx = 0; idx < BPP_NO; idx += 1) {
+	for (idx = 0; idx < BPP_NO; idx++) {
 		instances[idx].opened = 0;
 		probeLptPort(idx);
 	}
-	devfs_handle = devfs_mk_dir (NULL, "bpp", NULL);
-	devfs_register_series (devfs_handle, "%u", BPP_NO, DEVFS_FL_DEFAULT,
-			       BPP_MAJOR, 0, S_IFCHR | S_IRUSR | S_IWUSR,
+	devfs_mk_dir (NULL, "bpp", NULL);
+	for (idx = 0; idx < BPP_NO; idx++) {
+		char name[16];
+		sprintf(name, "bpp/%d", idx);
+		devfs_register(NULL, name, DEVFS_FL_DEFAULT,
+			       BPP_MAJOR, idx, S_IFCHR | S_IRUSR | S_IWUSR,
 			       &bpp_fops, NULL);
+	}
 
 	return 0;
 }
@@ -1062,10 +1064,12 @@
 {
 	unsigned idx;
 
-	devfs_unregister (devfs_handle);
+	for (idx = 0; idx < BPP_NO; idx++)
+		devfs_remove("bpp/%d", idx);
+	devfs_remove("bpp");
 	unregister_chrdev(BPP_MAJOR, dev_name);
 
-	for (idx = 0 ;  idx < BPP_NO ;  idx += 1) {
+	for (idx = 0;  idx < BPP_NO; idx++) {
 		if (instances[idx].present)
 			freeLptPort(idx);
 	}
diff -Nru a/drivers/sbus/char/vfc.h b/drivers/sbus/char/vfc.h
--- a/drivers/sbus/char/vfc.h	Mon Dec  9 18:46:34 2002
+++ b/drivers/sbus/char/vfc.h	Mon Dec  9 18:46:34 2002
@@ -128,7 +128,6 @@
 	volatile struct vfc_regs *regs;
 	struct vfc_regs *phys_regs;
 	unsigned int control_reg;
-	devfs_handle_t de;
 	struct semaphore device_lock_sem;
 	struct timer_list poll_timer;
 	wait_queue_head_t poll_wait;
diff -Nru a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
--- a/drivers/sbus/char/vfc_dev.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/sbus/char/vfc_dev.c	Mon Dec  9 18:46:38 2002
@@ -44,7 +44,6 @@
 #include <asm/vfc_ioctls.h>
 
 static struct file_operations vfc_fops;
-static devfs_handle_t devfs_handle;  /*  For the directory  */
 struct vfc_dev **vfc_dev_lst;
 static char vfcstr[]="vfc";
 static unsigned char saa9051_init_array[VFC_SAA9051_NR] = {
@@ -144,7 +143,7 @@
 
 int init_vfc_device(struct sbus_dev *sdev,struct vfc_dev *dev, int instance)
 {
-	char devname[8];
+	char devname[16];
 
 	if(dev == NULL) {
 		printk(KERN_ERR "VFC: Bogus pointer passed\n");
@@ -168,8 +167,8 @@
 	if (init_vfc_hw(dev))
 		return -EIO;
 
-	sprintf (devname, "%d", instance);
-	dev->de = devfs_register (devfs_handle, devname, DEVFS_FL_DEFAULT,
+	sprintf (devname, "vfc/%d", instance);
+	dev->de = devfs_register (NULL, devname, DEVFS_FL_DEFAULT,
 				  VFC_MAJOR, instance,
 				  S_IFCHR | S_IRUSR | S_IWUSR,
 				  &vfc_fops, NULL);
@@ -682,8 +681,7 @@
 		kfree(vfc_dev_lst);
 		return -EIO;
 	}
-	devfs_handle = devfs_mk_dir (NULL, "vfc", NULL);
-
+	devfs_mk_dir (NULL, "vfc", NULL);
 	instance = 0;
 	for_all_sbusdev(sdev, sbus) {
 		if (strcmp(sdev->prom_name, "vfc") == 0) {
@@ -723,7 +721,7 @@
 {
 	if(dev == NULL)
 		return;
-	devfs_unregister (dev->de);
+	devfs_remove("vfc/%d", dev->instance);
 	sbus_iounmap((unsigned long)dev->regs, sizeof(struct vfc_regs));
 	kfree(dev);
 }
@@ -737,7 +735,7 @@
 	for (devp = vfc_dev_lst; *devp; devp++)
 		deinit_vfc_device(*devp);
 
-	devfs_unregister (devfs_handle);
+	devfs_remove("vfc");
 	kfree(vfc_dev_lst);
 	return;
 }
diff -Nru a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
--- a/drivers/scsi/53c700.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/scsi/53c700.c	Mon Dec  9 18:46:35 2002
@@ -124,8 +124,6 @@
 #include <linux/spinlock.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
-#include <linux/init.h>
-#include <linux/mca.h>
 #include <asm/dma.h>
 #include <asm/system.h>
 #include <asm/io.h>
@@ -236,7 +234,7 @@
 	NCR_700_MAX_OFFSET
 };
 
-struct Scsi_Host * __init
+struct Scsi_Host *
 NCR_700_detect(Scsi_Host_Template *tpnt,
 	       struct NCR_700_Host_Parameters *hostdata)
 {
@@ -2020,3 +2018,5 @@
 EXPORT_SYMBOL(NCR_700_detect);
 EXPORT_SYMBOL(NCR_700_release);
 EXPORT_SYMBOL(NCR_700_intr);
+
+no_module_init;
diff -Nru a/drivers/scsi/Makefile b/drivers/scsi/Makefile
--- a/drivers/scsi/Makefile	Mon Dec  9 18:46:50 2002
+++ b/drivers/scsi/Makefile	Mon Dec  9 18:46:50 2002
@@ -123,7 +123,8 @@
 obj-$(CONFIG_CHR_DEV_SG)	+= sg.o
 
 scsi_mod-objs	:= scsi.o hosts.o scsi_ioctl.o constants.o scsicam.o \
-		   scsi_error.o scsi_lib.o scsi_scan.o scsi_syms.o
+		   scsi_error.o scsi_lib.o scsi_scan.o scsi_syms.o \
+		   scsi_sysfs.o
 
 ifdef CONFIG_PROC_FS
 scsi_mod-objs	+= scsi_proc.o
diff -Nru a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
--- a/drivers/scsi/NCR5380.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/scsi/NCR5380.c	Mon Dec  9 18:46:35 2002
@@ -1477,8 +1477,8 @@
 	int len;
 	unsigned long timeout;
 	unsigned char value;
-	NCR5380_setup(instance);
 	int err;
+	NCR5380_setup(instance);
 
 	if (hostdata->selecting) {
 		if(instance->irq != IRQ_NONE)
diff -Nru a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c
--- a/drivers/scsi/NCR_D700.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/scsi/NCR_D700.c	Mon Dec  9 18:46:35 2002
@@ -105,6 +105,7 @@
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
 #include <linux/init.h>
+#include <linux/device.h>
 #include <linux/mca.h>
 
 #include <asm/dma.h>
@@ -182,131 +183,140 @@
 __setup("NCR_D700=", param_setup);
 #endif
 
+/* private stack allocated structure for passing device information from
+ * detect to probe */
+struct NCR_700_info {
+	Scsi_Host_Template *tpnt;
+	int found;
+};
+
 /* Detect a D700 card.  Note, because of the set up---the chips are
  * essentially connectecd to the MCA bus independently, it is easier
  * to set them up as two separate host adapters, rather than one
  * adapter with two channels */
-STATIC int __init
-D700_detect(Scsi_Host_Template *tpnt)
+static int
+NCR_D700_probe(struct device *dev)
 {
-	int slot = 0;
-	int found = 0;
 	int differential;
-	int banner = 1;
-
-	if(!MCA_bus)
-		return 0;
-
-#ifdef MODULE
-	if(NCR_D700)
-		param_setup(NCR_D700);
-#endif
+	static int banner = 1;
+	struct mca_device *mca_dev = to_mca_device(dev);
+	int slot = mca_dev->slot;
+	struct NCR_700_info *info = to_mca_driver(dev->driver)->driver_data;
+	int found = 0;
+	int irq, i;
+	int pos3j, pos3k, pos3a, pos3b, pos4;
+	__u32 base_addr, offset_addr;
+	struct Scsi_Host *host = NULL;
+
+	/* enable board interrupt */
+	pos4 = mca_device_read_pos(mca_dev, 4);
+	pos4 |= 0x4;
+	mca_device_write_pos(mca_dev, 4, pos4);
+
+	mca_device_write_pos(mca_dev, 6, 9);
+	pos3j = mca_device_read_pos(mca_dev, 3);
+	mca_device_write_pos(mca_dev, 6, 10);
+	pos3k = mca_device_read_pos(mca_dev, 3);
+	mca_device_write_pos(mca_dev, 6, 0);
+	pos3a = mca_device_read_pos(mca_dev, 3);
+	mca_device_write_pos(mca_dev, 6, 1);
+	pos3b = mca_device_read_pos(mca_dev, 3);
+
+	base_addr = ((pos3j << 8) | pos3k) & 0xfffffff0;
+	offset_addr = ((pos3a << 8) | pos3b) & 0xffffff70;
+
+	irq = (pos4 & 0x3) + 11;
+	if(irq >= 13)
+		irq++;
+	if(banner) {
+		printk(KERN_NOTICE "NCR D700: Driver Version " NCR_D700_VERSION "\n"
+		       "NCR D700:  Copyright (c) 2001 by James.Bottomley@HansenPartnership.com\n"
+		       "NCR D700:\n");
+		banner = 0;
+	}
+	/* now do the bus related transforms */
+	irq = mca_device_transform_irq(mca_dev, irq);
+	base_addr = mca_device_transform_ioport(mca_dev, base_addr);
+	offset_addr = mca_device_transform_ioport(mca_dev, offset_addr);
+
+	printk(KERN_NOTICE "NCR D700: found in slot %d  irq = %d  I/O base = 0x%x\n", slot, irq, offset_addr);
+
+	info->tpnt->proc_name = "NCR_D700";
+
+	/*outb(BOARD_RESET, base_addr);*/
+
+	/* clear any pending interrupts */
+	(void)inb(base_addr + 0x08);
+	/* get modctl, used later for setting diff bits */
+	switch(differential = (inb(base_addr + 0x08) >> 6)) {
+	case 0x00:
+		/* only SIOP1 differential */
+		differential = 0x02;
+		break;
+	case 0x01:
+		/* Both SIOPs differential */
+		differential = 0x03;
+		break;
+	case 0x03:
+		/* No SIOPs differential */
+		differential = 0x00;
+		break;
+	default:
+		printk(KERN_ERR "D700: UNEXPECTED DIFFERENTIAL RESULT 0x%02x\n",
+		       differential);
+		differential = 0x00;
+		break;
+	}
 
-	for(slot = 0; (slot = mca_find_adapter(NCR_D700_MCA_ID, slot)) != MCA_NOTFOUND; slot++) {
-		int irq, i;
-		int pos3j, pos3k, pos3a, pos3b, pos4;
-		__u32 base_addr, offset_addr;
-		struct Scsi_Host *host = NULL;
-
-		/* enable board interrupt */
-		pos4 = mca_read_pos(slot, 4);
-		pos4 |= 0x4;
-		mca_write_pos(slot, 4, pos4);
-
-		mca_write_pos(slot, 6, 9);
-		pos3j = mca_read_pos(slot, 3);
-		mca_write_pos(slot, 6, 10);
-		pos3k = mca_read_pos(slot, 3);
-		mca_write_pos(slot, 6, 0);
-		pos3a = mca_read_pos(slot, 3);
-		mca_write_pos(slot, 6, 1);
-		pos3b = mca_read_pos(slot, 3);
-
-		base_addr = ((pos3j << 8) | pos3k) & 0xfffffff0;
-		offset_addr = ((pos3a << 8) | pos3b) & 0xffffff70;
-
-		irq = (pos4 & 0x3) + 11;
-		if(irq >= 13)
-			irq++;
-		if(banner) {
-			printk(KERN_NOTICE "NCR D700: Driver Version " NCR_D700_VERSION "\n"
-			       "NCR D700:  Copyright (c) 2001 by James.Bottomley@HansenPartnership.com\n"
-			       "NCR D700:\n");
-			banner = 0;
+	/* plumb in both 700 chips */
+	for(i=0; i<2; i++) {
+		__u32 region = offset_addr | (0x80 * i);
+		struct NCR_700_Host_Parameters *hostdata =
+			kmalloc(sizeof(struct NCR_700_Host_Parameters),
+				GFP_KERNEL);
+		if(hostdata == NULL) {
+			printk(KERN_ERR "NCR D700: Failed to allocate host data for channel %d, detatching\n", i);
+			continue;
 		}
-		printk(KERN_NOTICE "NCR D700: found in slot %d  irq = %d  I/O base = 0x%x\n", slot, irq, offset_addr);
-
-		tpnt->proc_name = "NCR_D700";
-
-		/*outb(BOARD_RESET, base_addr);*/
-
-		/* clear any pending interrupts */
-		(void)inb(base_addr + 0x08);
-		/* get modctl, used later for setting diff bits */
-		switch(differential = (inb(base_addr + 0x08) >> 6)) {
-		case 0x00:
-			/* only SIOP1 differential */
-			differential = 0x02;
-			break;
-		case 0x01:
-			/* Both SIOPs differential */
-			differential = 0x03;
-			break;
-		case 0x03:
-			/* No SIOPs differential */
-			differential = 0x00;
-			break;
-		default:
-			printk(KERN_ERR "D700: UNEXPECTED DIFFERENTIAL RESULT 0x%02x\n",
-			       differential);
-			differential = 0x00;
-			break;
+		memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters));
+		if(request_region(region, 64, "NCR_D700") == NULL) {
+			printk(KERN_ERR "NCR D700: Failed to reserve IO region 0x%x\n", region);
+			kfree(hostdata);
+			continue;
 		}
-
-		/* plumb in both 700 chips */
-		for(i=0; i<2; i++) {
-			__u32 region = offset_addr | (0x80 * i);
-			struct NCR_700_Host_Parameters *hostdata =
-				kmalloc(sizeof(struct NCR_700_Host_Parameters),
-					GFP_KERNEL);
-			if(hostdata == NULL) {
-				printk(KERN_ERR "NCR D700: Failed to allocate host data for channel %d, detatching\n", i);
-				continue;
-			}
-			memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters));
-			if(request_region(region, 64, "NCR_D700") == NULL) {
-				printk(KERN_ERR "NCR D700: Failed to reserve IO region 0x%x\n", region);
-				kfree(hostdata);
-				continue;
-			}
-
-			/* Fill in the three required pieces of hostdata */
-			hostdata->base = region;
-			hostdata->differential = (((1<<i) & differential) != 0);
-			hostdata->clock = NCR_D700_CLOCK_MHZ;
-			/* and register the chip */
-			if((host = NCR_700_detect(tpnt, hostdata)) == NULL) {
-				kfree(hostdata);
-				release_region(host->base, 64);
-				continue;
-			}
-			host->irq = irq;
-			/* FIXME: Read this from SUS */
-			host->this_id = id_array[slot * 2 + i];
-			printk(KERN_NOTICE "NCR D700: SIOP%d, SCSI id is %d\n",
-			       i, host->this_id);
-			if(request_irq(irq, NCR_700_intr, SA_SHIRQ, "NCR_D700", host)) {
-				printk(KERN_ERR "NCR D700, channel %d: irq problem, detatching\n", i);
-				scsi_unregister(host);
-				NCR_700_release(host);
-				continue;
-			}
-			found++;
-			mca_set_adapter_name(slot, "NCR D700 SCSI Adapter (version " NCR_D700_VERSION ")");
+		
+		/* Fill in the three required pieces of hostdata */
+		hostdata->base = region;
+		hostdata->differential = (((1<<i) & differential) != 0);
+		hostdata->clock = NCR_D700_CLOCK_MHZ;
+		/* and register the chip */
+		if((host = NCR_700_detect(info->tpnt, hostdata)) == NULL) {
+			kfree(hostdata);
+			release_region(host->base, 64);
+			continue;
 		}
+		host->irq = irq;
+		/* FIXME: Read this from SUS */
+		host->this_id = id_array[slot * 2 + i];
+		printk(KERN_NOTICE "NCR D700: SIOP%d, SCSI id is %d\n",
+		       i, host->this_id);
+		if(request_irq(irq, NCR_700_intr, SA_SHIRQ, "NCR_D700", host)) {
+			printk(KERN_ERR "NCR D700, channel %d: irq problem, detatching\n", i);
+			scsi_unregister(host);
+			NCR_700_release(host);
+			continue;
+		}
+		scsi_set_device(host, dev);
+		found++;
+	}
+	info->found += found;
+
+	if(found) {
+		mca_device_set_claim(mca_dev, 1);
+		strncpy(dev->name, "NCR_D700", sizeof(dev->name));
 	}
 
-	return found;
+	return found? 0 : -ENODEV;
 }
 
 
@@ -323,7 +333,38 @@
 	return 1;
 }
 
+static short NCR_D700_id_table[] = { NCR_D700_MCA_ID, 0 };
+
+struct mca_driver NCR_D700_driver = {
+	.id_table = NCR_D700_id_table,
+	.driver = {
+		.name = "NCR_D700",
+		.bus = &mca_bus_type,
+		.probe = NCR_D700_probe,
+	},
+};
+		
+
+STATIC int __init
+D700_detect(Scsi_Host_Template *tpnt)
+{
+	struct NCR_700_info info;
+
+	if(!MCA_bus)
+		return 0;
+
+#ifdef MODULE
+	if(NCR_D700)
+		param_setup(NCR_D700);
+#endif
+	info.tpnt = tpnt;
+	info.found = 0;
+	NCR_D700_driver.driver_data = &info;
+	mca_register_driver(&NCR_D700_driver);
 
+	return info.found;
+}
+	
 static Scsi_Host_Template driver_template = NCR_D700_SCSI;
 
 #include "scsi_module.c"
diff -Nru a/drivers/scsi/NCR_D700.h b/drivers/scsi/NCR_D700.h
--- a/drivers/scsi/NCR_D700.h	Mon Dec  9 18:46:38 2002
+++ b/drivers/scsi/NCR_D700.h	Mon Dec  9 18:46:38 2002
@@ -22,11 +22,11 @@
  * remaining parameters shown below must be filled in.  The 53c700
  * routine NCR_700_detect will fill in all of the missing routines */
 #define NCR_D700_SCSI {						\
-	name:				"NCR Dual 700 MCA",	\
-	proc_name:			"NCR_D700",		\
-	detect: 			D700_detect,		\
-	release:			D700_release,		\
-	this_id:			7,			\
+	.name =				"NCR Dual 700 MCA",	\
+	.proc_name =			"NCR_D700",		\
+	.detect = 			D700_detect,		\
+	.release =			D700_release,		\
+	.this_id =			7,			\
 }
 
 
diff -Nru a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
--- a/drivers/scsi/aacraid/aachba.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/scsi/aacraid/aachba.c	Mon Dec  9 18:46:36 2002
@@ -33,18 +33,12 @@
 #include <linux/completion.h>
 #include <asm/semaphore.h>
 #include <asm/uaccess.h>
-#define MAJOR_NR SCSI_DISK0_MAJOR	/* For DEVICE_NR() */
 #include <linux/blk.h>
 #include "scsi.h"
 #include "hosts.h"
 
 #include "aacraid.h"
 
-#warning this is broken
-#define N_SD_MAJORS	8
-#define SD_MAJOR_MASK	(N_SD_MAJORS - 1)
-#define DEVICE_NR(device) (((major(device) & SD_MAJOR_MASK) << (8 - 4)) + (minor(device) >> 4))
-
 /*	SCSI Commands */
 /*	TODO:  dmb - use the ones defined in include/scsi/scsi.h */
 
@@ -567,7 +561,7 @@
 			scsicmd->use_sg,
 			scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
 	else if(scsicmd->request_bufflen)
-		pci_unmap_single(dev->pdev, (dma_addr_t)(unsigned long)scsicmd->SCp.ptr,
+		pci_unmap_single(dev->pdev, scsicmd->SCp.dma_handle,
 				 scsicmd->request_bufflen,
 				 scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
 	readreply = (struct aac_read_reply *)fib_data(fibptr);
@@ -611,7 +605,7 @@
 			scsicmd->use_sg,
 			scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
 	else if(scsicmd->request_bufflen)
-		pci_unmap_single(dev->pdev, (dma_addr_t)(unsigned long)scsicmd->SCp.ptr,
+		pci_unmap_single(dev->pdev, scsicmd->SCp.dma_handle,
 				 scsicmd->request_bufflen,
 				 scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
 
@@ -1113,12 +1107,12 @@
 	qd.locked = fsa_dev_ptr->locked[qd.cnum];
 	qd.deleted = fsa_dev_ptr->deleted[qd.cnum];
 
-	if (fsa_dev_ptr->devno[qd.cnum][0] == '\0')
+	if (fsa_dev_ptr->devname[qd.cnum][0] == '\0')
 		qd.unmapped = 1;
 	else
 		qd.unmapped = 0;
 
-	strncpy(dq.name, fsa_dev_ptr->devname[qd.cnum], 8);
+	strncpy(qd.name, fsa_dev_ptr->devname[qd.cnum], 8);
 
 	if (copy_to_user(arg, &qd, sizeof (struct aac_query_disk)))
 		return -EFAULT;
@@ -1170,7 +1164,7 @@
 		 *	Mark the container as no longer being valid.
 		 */
 		fsa_dev_ptr->valid[dd.cnum] = 0;
-		fsa_dev_ptr->devno[dd.cnum][0] = '\0';
+		fsa_dev_ptr->devname[dd.cnum][0] = '\0';
 		return 0;
 	}
 }
@@ -1225,7 +1219,8 @@
 			scsicmd->use_sg,
 			scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
 	else if(scsicmd->request_bufflen)
-		pci_unmap_single(dev->pdev, (ulong)scsicmd->SCp.ptr, scsicmd->request_bufflen,
+		pci_unmap_single(dev->pdev, scsicmd->SCp.dma_handle,
+			scsicmd->request_bufflen,
 			scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
 
 	/*
@@ -1516,7 +1511,7 @@
 		psg->count = cpu_to_le32(1);
 		psg->sg[0].addr = cpu_to_le32(addr);
 		psg->sg[0].count = cpu_to_le32(scsicmd->request_bufflen);  
-		scsicmd->SCp.ptr = (void *)addr;
+		scsicmd->SCp.dma_handle = addr;
 		byte_count = scsicmd->request_bufflen;
 	}
 	return byte_count;
@@ -1577,7 +1572,7 @@
 		psg->sg[0].addr[1] = (u32)(le_addr>>32);
 		psg->sg[0].addr[0] = (u32)(le_addr & 0xffffffff);
 		psg->sg[0].count = cpu_to_le32(scsicmd->request_bufflen);  
-		scsicmd->SCp.ptr = (void *)addr;
+		scsicmd->SCp.dma_handle = addr;
 		byte_count = scsicmd->request_bufflen;
 	}
 	return byte_count;
diff -Nru a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
--- a/drivers/scsi/aacraid/aacraid.h	Mon Dec  9 18:46:35 2002
+++ b/drivers/scsi/aacraid/aacraid.h	Mon Dec  9 18:46:35 2002
@@ -1369,6 +1369,21 @@
 	return (struct hw_fib *)addr;
 }
 
+/**
+ * 	Convert capacity to cylinders
+ *  	accounting for the fact capacity could be a 64 bit value
+ *
+ */
+static inline u32 cap_to_cyls(sector_t capacity, u32 divisor)
+{
+#ifdef CONFIG_LBD
+	do_div(capacity, divisor);
+#else
+	capacity /= divisor;
+#endif
+	return (u32) capacity;
+}
+
 const char *aac_driverinfo(struct Scsi_Host *);
 struct fib *fib_alloc(struct aac_dev *dev);
 int fib_setup(struct aac_dev *dev);
diff -Nru a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
--- a/drivers/scsi/aacraid/linit.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/scsi/aacraid/linit.c	Mon Dec  9 18:46:36 2002
@@ -443,7 +443,8 @@
 		param->sectors = 32;
 	}
 
-	param->cylinders = capacity/(param->heads * param->sectors);
+	param->cylinders = cap_to_cyls(capacity,
+			(param->heads * param->sectors));
 
 	/*
 	 *	Read the partition table block
@@ -497,7 +498,8 @@
 			end_sec = first->end_sector & 0x3f;
 		}
 
-		param->cylinders = capacity / (param->heads * param->sectors);
+		param->cylinders = cap_to_cyls(capacity,
+				(param->heads * param->sectors));
 
 		if(num < 4 && end_sec == param->sectors)
 		{
diff -Nru a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
--- a/drivers/scsi/hosts.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/scsi/hosts.c	Mon Dec  9 18:46:34 2002
@@ -36,7 +36,6 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
-#include <linux/smp_lock.h>
 
 #define __KERNEL_SYSCALLS__
 
@@ -50,7 +49,6 @@
 static spinlock_t scsi_host_list_lock = SPIN_LOCK_UNLOCKED;
 
 static int scsi_host_next_hn;		/* host_no for next new host */
-static int scsi_hosts_registered;	/* cnt of registered scsi hosts */
 static char *scsihosts;
 
 MODULE_PARM(scsihosts, "s");
@@ -173,14 +171,14 @@
 }
 
 /**
- * scsi_host_generic_release - default release function for hosts
+ * scsi_host_legacy_release - default release function for hosts
  * @shost: 
  * 
  * Description:
  * 	This is the default case for the release function.  Its completely
  *	useless for anything but old ISA adapters
  **/
-static void scsi_host_legacy_release(struct Scsi_Host *shost)
+static int scsi_host_legacy_release(struct Scsi_Host *shost)
 {
 	if (shost->irq)
 		free_irq(shost->irq, NULL);
@@ -188,23 +186,17 @@
 		free_dma(shost->dma_channel);
 	if (shost->io_port && shost->n_io_port)
 		release_region(shost->io_port, shost->n_io_port);
+
+	return 0;
 }
 
 static int scsi_remove_legacy_host(struct Scsi_Host *shost)
 {
-	int error, pcount = scsi_hosts_registered;
+	int error;
 
 	error = scsi_remove_host(shost);
-	if (error)
-		return error;
-
-	if (shost->hostt->release)
+	if (!error)
 		(*shost->hostt->release)(shost);
-	else
-		scsi_host_legacy_release(shost);
-
-	if (pcount == scsi_hosts_registered)
-		scsi_unregister(shost);
 	return 0;
 }
 
@@ -260,7 +252,6 @@
 int scsi_remove_host(struct Scsi_Host *shost)
 {
 	struct scsi_device *sdev;
-	struct list_head *le, *lh;
 
 	/*
 	 * FIXME Do ref counting.  We force all of the devices offline to
@@ -287,20 +278,13 @@
 			       sdev->attached);
 			return 1;
 		}
-		devfs_unregister(sdev->de);
-		device_unregister(&sdev->sdev_driverfs_dev);
-	}
-
-	/* Next we free up the Scsi_Cmnd structures for this host */
-
-	list_for_each_safe(le, lh, &shost->my_devices) {
-		scsi_free_sdev(list_entry(le, Scsi_Device, siblings));
 	}
 
+	scsi_forget_host(shost);
 	return 0;
 }
 
-int scsi_add_host(struct Scsi_Host *shost)
+int __scsi_add_host(struct Scsi_Host *shost)
 {
 	Scsi_Host_Template *sht = shost->hostt;
 	struct scsi_device *sdev;
@@ -309,7 +293,6 @@
 	printk(KERN_INFO "scsi%d : %s\n", shost->host_no,
 			sht->info ? sht->info(shost) : sht->name);
 
-	device_register(&shost->host_driverfs_dev);
 	scsi_scan_host(shost);
 			
 	list_for_each_entry (sdev, &shost->my_devices, siblings) {
@@ -322,6 +305,22 @@
 }
 
 /**
+ * scsi_add_host - add a scsi host
+ * @shost:	scsi host pointer to add
+ * @dev:	a struct device of type scsi class
+ *
+ * Return value: 
+ * 	0 on success / != 0 for error
+ **/
+int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
+{
+	dev->class_data = shost;
+	shost->host_gendev = dev;
+
+	return __scsi_add_host(shost);
+}
+
+/**
  * scsi_unregister - unregister a scsi host
  * @shost:	scsi host to be unregistered
  **/
@@ -343,12 +342,10 @@
 		shost->eh_notify = NULL;
 	}
 
-	scsi_hosts_registered--;
 	shost->hostt->present--;
 
-	/* Cleanup proc and driverfs */
+	/* Cleanup proc */
 	scsi_proc_host_rm(shost);
-	device_unregister(&shost->host_driverfs_dev);
 
 	kfree(shost);
 }
@@ -395,7 +392,6 @@
 	memset(shost, 0, sizeof(struct Scsi_Host) + xtr_bytes);
 
 	shost->host_no = scsi_alloc_host_num(shost_tp->proc_name);
-	scsi_hosts_registered++;
 
 	spin_lock_init(&shost->default_lock);
 	scsi_assign_lock(shost, &shost->default_lock);
@@ -462,11 +458,6 @@
 
 	scsi_proc_host_add(shost);
 
-	strncpy(shost->host_driverfs_dev.name, shost_tp->proc_name,
-		DEVICE_NAME_SIZE-1);
-	sprintf(shost->host_driverfs_dev.bus_id, "scsi%d",
-		shost->host_no);
-
 	shost->eh_notify = &sem;
 	kernel_thread((int (*)(void *)) scsi_error_handler, (void *) shost, 0);
 	/*
@@ -491,64 +482,34 @@
 int scsi_register_host(Scsi_Host_Template *shost_tp)
 {
 	struct Scsi_Host *shost;
-	int cur_cnt;
 
-	/*
-	 * Check no detect routine.
-	 */
-	if (!shost_tp->detect)
-		return 1;
+	BUG_ON(!shost_tp->detect);
 
-	/* If max_sectors isn't set, default to max */
-	if (!shost_tp->max_sectors)
+	if (!shost_tp->max_sectors) {
+		printk(KERN_WARNING
+		    "scsi HBA driver %s didn't set max_sectors, "
+		    "please fix the template", shost_tp->name);
 		shost_tp->max_sectors = 1024;
+	}
 
-	cur_cnt = scsi_hosts_registered;
-
-	/*
-	 * The detect routine must carefully spinunlock/spinlock if it
-	 * enables interrupts, since all interrupt handlers do spinlock as
-	 * well.
-	 */
+	if (!shost_tp->release) {
+		printk(KERN_WARNING
+		    "scsi HBA driver %s didn't set a release method, "
+		    "please fix the template", shost_tp->name);
+		shost_tp->release = &scsi_host_legacy_release;
+	}
 
-	/*
-	 * detect should do its own locking
-	 * FIXME present is now set is scsi_register which breaks manual
-	 * registration code below.
-	 */
 	shost_tp->detect(shost_tp);
 	if (!shost_tp->present)
 		return 0;
 
-	if (cur_cnt == scsi_hosts_registered) {
-		if (shost_tp->present > 1) {
-			printk(KERN_ERR "scsi: Failure to register"
-			       "low-level scsi driver");
-			scsi_unregister_host(shost_tp);
-			return 1;
-		}
-
-		/*
-		 * The low-level driver failed to register a driver.
-		 * We can do this now.
-		 *
-	 	 * XXX Who needs manual registration and why???
-		 */
-		if (!scsi_register(shost_tp, 0)) {
-			printk(KERN_ERR "scsi: register failed.\n");
-			scsi_unregister_host(shost_tp);
-			return 1;
-		}
-	}
-
-	
 	/*
 	 * XXX(hch) use scsi_tp_for_each_host() once it propagates
 	 *	    error returns properly.
 	 */
 	list_for_each_entry(shost, &scsi_host_list, sh_list)
 		if (shost->hostt == shost_tp)
-			if (scsi_add_host(shost))
+			if (__scsi_add_host(shost))
 				goto out_of_space;
 
 	return 0;
@@ -575,20 +536,7 @@
  **/
 int scsi_unregister_host(Scsi_Host_Template *shost_tp)
 {
-	int pcount;
-
-	/* get the big kernel lock, so we don't race with open() */
-	lock_kernel();
-
-	pcount = scsi_hosts_registered;
-
 	scsi_tp_for_each_host(shost_tp, scsi_remove_legacy_host);
-
-	if (pcount != scsi_hosts_registered)
-		printk(KERN_INFO "scsi : %d host%s left.\n", scsi_hosts_registered,
-		       (scsi_hosts_registered == 1) ? "" : "s");
-
-	unlock_kernel();
 	return 0;
 
 }
@@ -668,64 +616,6 @@
 	}
 }
 
-/*
- * Function:    scsi_get_host_dev()
- *
- * Purpose:     Create a Scsi_Device that points to the host adapter itself.
- *
- * Arguments:   SHpnt   - Host that needs a Scsi_Device
- *
- * Lock status: None assumed.
- *
- * Returns:     The Scsi_Device or NULL
- *
- * Notes:
- *	Attach a single Scsi_Device to the Scsi_Host - this should
- *	be made to look like a "pseudo-device" that points to the
- *	HA itself.
- *
- *	Note - this device is not accessible from any high-level
- *	drivers (including generics), which is probably not
- *	optimal.  We can add hooks later to attach 
- */
-struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
-{
-	struct scsi_device *sdev;
-
-	sdev = scsi_alloc_sdev(shost, 0, shost->this_id, 0);
-	if (sdev) {
-		scsi_build_commandblocks(sdev);
-		if (sdev->current_queue_depth == 0)
-			goto fail;
-		sdev->borken = 0;
-	}
-
-	return sdev;
-
-fail:
-	kfree(sdev);
-	return NULL;
-}
-
-/*
- * Function:    scsi_free_host_dev()
- *
- * Purpose:     Free a scsi_device that points to the host adapter itself.
- *
- * Arguments:   SHpnt   - Host that needs a Scsi_Device
- *
- * Lock status: None assumed.
- *
- * Returns:     Nothing
- *
- * Notes:
- */
-void scsi_free_host_dev(struct scsi_device *sdev)
-{
-	BUG_ON(sdev->id != sdev->host->this_id);
-	scsi_free_sdev(sdev);
-}
-
 void scsi_host_busy_inc(struct Scsi_Host *shost, Scsi_Device *sdev)
 {
 	unsigned long flags;
@@ -765,22 +655,3 @@
 	}
 	spin_unlock_irqrestore(shost->host_lock, flags);
 }
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff -Nru a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h
--- a/drivers/scsi/hosts.h	Mon Dec  9 18:46:35 2002
+++ b/drivers/scsi/hosts.h	Mon Dec  9 18:46:35 2002
@@ -479,16 +479,10 @@
      */
     unsigned int max_host_blocked;
 
-    /*
-     * For SCSI hosts which are PCI devices, set pci_dev so that
-     * we can do BIOS EDD 3.0 mappings
-     */
-    struct pci_dev *pci_dev;
-
     /* 
      * Support for driverfs filesystem
      */
-    struct device host_driverfs_dev;
+    struct device *host_gendev;
 
     /*
      * We should ensure that this is aligned, both for better performance
@@ -499,6 +493,8 @@
         __attribute__ ((aligned (sizeof(unsigned long))));
 };
 
+#define	to_scsi_host(d)	d->class_data
+	
 /*
  * These two functions are used to allocate and free a pseudo device
  * which will connect to the host adapter itself rather than any
@@ -520,11 +516,21 @@
 	shost->host_lock = lock;
 }
 
+static inline void scsi_set_device(struct Scsi_Host *shost,
+                                   struct device *dev)
+{
+        shost->host_gendev = dev;
+}
+
+static inline struct device *scsi_get_device(struct Scsi_Host *shost)
+{
+        return shost->host_gendev;
+}
+
 static inline void scsi_set_pci_device(struct Scsi_Host *shost,
                                        struct pci_dev *pdev)
 {
-	shost->pci_dev = pdev;
-	shost->host_driverfs_dev.parent=&pdev->dev;
+        scsi_set_device(shost, &pdev->dev);
 }
 
 
@@ -532,12 +538,13 @@
  * Prototypes for functions/data in scsi_scan.c
  */
 extern void scsi_scan_host(struct Scsi_Host *);
+extern void scsi_forget_host(struct Scsi_Host *);
+
 
 struct Scsi_Device_Template
 {
     struct list_head list;
     const char * name;
-    const char * tag;
     struct module * module;	  /* Used for loadable modules */
     unsigned char scsi_type;
     int (*attach)(Scsi_Device *); /* Attach devices to arrays */
@@ -565,7 +572,7 @@
 /*
  * HBA registration/unregistration.
  */
-extern int scsi_add_host(struct Scsi_Host *);
+extern int scsi_add_host(struct Scsi_Host *, struct device *);
 extern int scsi_remove_host(struct Scsi_Host *);
 
 /*
@@ -603,7 +610,15 @@
                         break;
         return sdev;
 }
-    
+
+/*
+ * sysfs support
+ */
+extern int scsi_upper_driver_register(struct Scsi_Device_Template *);
+extern void scsi_upper_driver_unregister(struct Scsi_Device_Template *);
+
+extern struct device_class shost_devclass;
+
 #endif
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
diff -Nru a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
--- a/drivers/scsi/ide-scsi.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/scsi/ide-scsi.c	Mon Dec  9 18:46:50 2002
@@ -764,7 +764,7 @@
 
 	if (disk) {
 		struct Scsi_Device_Template **p = disk->private_data;
-		if (strcmp((*p)->tag, "sg") == 0)
+		if (strcmp((*p)->scsi_driverfs_driver.name, "sg") == 0)
 			return test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
 	}
 	return test_bit(IDESCSI_TRANSFORM, &scsi->transform);
diff -Nru a/drivers/scsi/ini9100u.c b/drivers/scsi/ini9100u.c
--- a/drivers/scsi/ini9100u.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/scsi/ini9100u.c	Mon Dec  9 18:46:35 2002
@@ -115,9 +115,6 @@
 #endif
 
 #include <linux/module.h>
-
-#include <stdarg.h>
-#include <asm/irq.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
@@ -126,16 +123,18 @@
 #include <linux/spinlock.h>
 #include <linux/stat.h>
 #include <linux/config.h>
-
 #include <linux/kernel.h>
+#include <linux/proc_fs.h>
 #include <linux/string.h>
+#include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/sched.h>
-#include <linux/proc_fs.h>
+#include <linux/slab.h>
+
 #include <asm/io.h>
+
 #include "scsi.h"
 #include "hosts.h"
-#include <linux/slab.h>
 #include "ini9100u.h"
 
 #ifdef DEBUG_i91u
diff -Nru a/drivers/scsi/osst.c b/drivers/scsi/osst.c
--- a/drivers/scsi/osst.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/scsi/osst.c	Mon Dec  9 18:46:37 2002
@@ -13,18 +13,18 @@
   order) Klaus Ehrenfried, Wolfgang Denk, Steve Hirsch, Andreas Koppenh"ofer,
   Michael Leodolter, Eyal Lebedinsky, J"org Weule, and Eric Youngdale.
 
-  Copyright 1992 - 2000 Kai Makisara
-		 email Kai.Makisara@metla.fi
+  Copyright 1992 - 2002 Kai Makisara / Willem Riede
+	 email Kai.Makisara@metla.fi / osst@riede.org
 
   $Header: /home/cvsroot/Driver/osst.c,v 1.65 2001/11/11 20:38:56 riede Exp $
 
   Microscopic alterations - Rik Ling, 2000/12/21
-  Last modified: Wed Feb  2 22:04:05 2000 by makisara@kai.makisara.local
+  Last st.c sync: Tue Oct 15 22:01:04 2002 by makisara
   Some small formal changes - aeb, 950809
 */
 
 static const char * cvsid = "$Id: osst.c,v 1.65 2001/11/11 20:38:56 riede Exp $";
-const char * osst_version = "0.9.10";
+const char * osst_version = "0.99.0p3";
 
 /* The "failure to reconnect" firmware bug */
 #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/
@@ -46,6 +46,7 @@
 #include <linux/spinlock.h>
 #include <linux/vmalloc.h>
 #include <linux/version.h>
+#include <linux/blk.h>
 #include <asm/uaccess.h>
 #include <asm/dma.h>
 #include <asm/system.h>
@@ -59,9 +60,6 @@
    in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
 #define OSST_DEB_MSG  KERN_NOTICE
 
-#define MAJOR_NR OSST_MAJOR
-#define DEVICE_NR(device) (minor(device) & 0x7f) 
-#include <linux/blk.h>
 
 #include "scsi.h"
 #include "hosts.h"
@@ -74,30 +72,32 @@
 #include "osst_options.h"
 #include "osst_detect.h"
 
-static int buffer_kbs = 0;
+static int max_dev = 0;
 static int write_threshold_kbs = 0;
-static int max_buffers = 0;
 static int max_sg_segs = 0;
 
 #ifdef MODULE
 MODULE_AUTHOR("Willem Riede");
-MODULE_DESCRIPTION("OnStream SCSI Tape Driver");
+MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(buffer_kbs, "i");
+MODULE_PARM(max_dev, "i");
+MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)");
+
 MODULE_PARM(write_threshold_kbs, "i");
-MODULE_PARM(max_buffers, "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 (9)");
 #else
 static struct osst_dev_parm {
        char   *name;
        int    *val;
 } parms[] __initdata = {
-       { "buffer_kbs",          &buffer_kbs          },
+       { "max_dev",             &max_dev             },
        { "write_threshold_kbs", &write_threshold_kbs },
-       { "max_buffers",         &max_buffers         },
        { "max_sg_segs",         &max_sg_segs         }
-       };
+};
 #endif
 
 /* Some default definitions have been moved to osst_options.h */
@@ -116,34 +116,41 @@
 // #define OSST_INJECT_ERRORS 1 
 #endif
 
-#define MAX_RETRIES 0
+#define MAX_RETRIES 2
+#define MAX_READ_RETRIES 0
 #define MAX_WRITE_RETRIES 0
-#define MAX_READY_RETRIES 5
+#define MAX_READY_RETRIES 0
 #define NO_TAPE  NOT_READY
 
+#define OSST_WAIT_POSITION_COMPLETE   (HZ > 200 ? HZ / 200 : 1)
+#define OSST_WAIT_WRITE_COMPLETE      (HZ / 12)
+#define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2)
+	
 #define OSST_TIMEOUT (200 * HZ)
 #define OSST_LONG_TIMEOUT (1800 * HZ)
 
-#define TAPE_NR(x) (minor(x) & ~(128 | ST_MODE_MASK))
+#define TAPE_NR(x) (minor(x) & ~(-1 << ST_MODE_SHIFT))
 #define TAPE_MODE(x) ((minor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
+#define TAPE_REWIND(x) ((minor(x) & 0x80) == 0)
+#define TAPE_IS_RAW(x) (TAPE_MODE(x) & (ST_NBR_MODES >> 1))
 
 /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
    24 bits) */
 #define SET_DENS_AND_BLK 0x10001
 
-static int osst_nbr_buffers;
 static int osst_buffer_size       = OSST_BUFFER_SIZE;
 static int osst_write_threshold   = OSST_WRITE_THRESHOLD;
-static int osst_max_buffers       = OSST_MAX_BUFFERS;
 static int osst_max_sg_segs       = OSST_MAX_SG;
+static int osst_max_dev           = OSST_MAX_TAPES;
+static int osst_nr_dev;
 
 static OS_Scsi_Tape **os_scsi_tapes = NULL;
-static OSST_buffer  **osst_buffers  = NULL;
+static rwlock_t  os_scsi_tapes_lock = RW_LOCK_UNLOCKED;
 
 static int modes_defined = FALSE;
 
-static OSST_buffer *new_tape_buffer(int, int);
-static int enlarge_buffer(OSST_buffer *, int, int);
+static OSST_buffer *new_tape_buffer(int, int, int);
+static int enlarge_buffer(OSST_buffer *, int);
 static void normalize_buffer(OSST_buffer *);
 static int append_to_buffer(const char *, OSST_buffer *, int);
 static int from_buffer(OSST_buffer *, char *, int);
@@ -151,22 +158,20 @@
 static int osst_copy_to_buffer(OSST_buffer *, unsigned char *);
 static int osst_copy_from_buffer(OSST_buffer *, unsigned char *);
 
-static int osst_init(void);
 static int osst_attach(Scsi_Device *);
 static void osst_detach(Scsi_Device *);
 
-static int osst_nr_dev;
-static int osst_dev_max;
-
 struct Scsi_Device_Template osst_template =
 {
-       .module		= THIS_MODULE,
-       .list		= LIST_HEAD_INIT(osst_template.list),
-       .name		= "OnStream tape",
-       .tag		= "osst",
-       .scsi_type	= TYPE_TAPE,
-       .attach		= osst_attach,
-       .detach		= osst_detach
+	.module =       THIS_MODULE,
+	.list =         LIST_HEAD_INIT(osst_template.list),
+	.name =         "OnStream Tape",
+	.scsi_type =    TYPE_TAPE,
+	.attach =       osst_attach,
+	.detach =       osst_detach,
+	.scsi_driverfs_driver = {
+		.name	= "osst",
+	},
 };
 
 static int osst_int_ioctl(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, unsigned int cmd_in,unsigned long arg);
@@ -181,9 +186,8 @@
 
 static inline char *tape_name(OS_Scsi_Tape *tape)
 {
-	return tape->disk->disk_name;
+	return tape->drive->disk_name;
 }
-
 
 /* Routines that handle the interaction with mid-layer SCSI routines */
 
@@ -201,13 +205,12 @@
 		sense[0] = 0;    /* We don't have sense data if this byte is zero */
 		return 0;
 	}
-	if (driver_byte(result) & DRIVER_SENSE)
+	if ((driver_byte(result) & DRIVER_MASK) == DRIVER_SENSE)
 		scode = sense[2] & 0x0f;
 	else {
 		sense[0] = 0;    /* We don't have sense data if this byte is zero */
 		scode = 0;
 	}
-
 #if DEBUG
 	if (debugging) {
 		printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n",
@@ -215,10 +218,12 @@
 		   SRpnt->sr_cmnd[0], SRpnt->sr_cmnd[1], SRpnt->sr_cmnd[2],
 		   SRpnt->sr_cmnd[3], SRpnt->sr_cmnd[4], SRpnt->sr_cmnd[5],
 		   SRpnt->sr_bufflen);
+		if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n",
+			       	name, scode, sense[12], sense[13]);
 		if (driver_byte(result) & DRIVER_SENSE)
 			print_req_sense("osst", SRpnt);
 	}
-	else
+//	else
 #endif
 	if (!(driver_byte(result) & DRIVER_SENSE) ||
 		((sense[0] & 0x70) == 0x70 &&
@@ -249,6 +254,8 @@
 			}
 		}
 	}
+	STp->pos_unknown |= STp->device->was_reset;
+
 	if ((sense[0] & 0x70) == 0x70 &&
 	     scode == RECOVERED_ERROR) {
 		STp->recover_count++;
@@ -275,22 +282,21 @@
 /* Wakeup from interrupt */
 static void osst_sleep_done (Scsi_Cmnd * SCpnt)
 {
-	OS_Scsi_Tape * STp = container_of(SCpnt->request->rq_disk->private_data,
-					OS_Scsi_Tape, driver);
+	OS_Scsi_Tape * STp = container_of(SCpnt->request->rq_disk->private_data, OS_Scsi_Tape, driver);
 
 	if ((STp->buffer)->writing &&
 	    (SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
 	    (SCpnt->sense_buffer[2] & 0x40)) {
 		/* EOM at write-behind, has all been written? */
 		if ((SCpnt->sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW)
-			(STp->buffer)->midlevel_result = SCpnt->result; /* Error */
+			STp->buffer->midlevel_result = SCpnt->result; /* Error */
 		else
-			(STp->buffer)->midlevel_result = INT_MAX;       /* OK */
+			STp->buffer->midlevel_result = INT_MAX;       /* OK */
 	}
 	else
-		(STp->buffer)->midlevel_result = SCpnt->result;
+		STp->buffer->midlevel_result = SCpnt->result;
 	SCpnt->request->rq_status = RQ_SCSI_DONE;
-	(STp->buffer)->last_SRpnt = SCpnt->sc_request;
+	STp->buffer->last_SRpnt = SCpnt->sc_request;
 
 #if DEBUG
 	STp->write_pending = 0;
@@ -312,7 +318,7 @@
 #endif
 	if (SRpnt == NULL) {
 		if ((SRpnt = scsi_allocate_request(STp->device)) == NULL) {
-			printk(KERN_ERR "%s:E: Can't get SCSI request->\n", tape_name(STp));
+			printk(KERN_ERR "%s:E: Can't get SCSI request.\n", tape_name(STp));
 			if (signal_pending(current))
 				(STp->buffer)->syscall_result = (-EINTR);
 			else
@@ -335,7 +341,7 @@
 	SRpnt->sr_cmd_len = 0;
 	SRpnt->sr_request->waiting = &(STp->wait);
 	SRpnt->sr_request->rq_status = RQ_SCSI_BUSY;
-	SRpnt->sr_request->rq_disk = STp->disk;
+	SRpnt->sr_request->rq_disk = STp->drive;
 
 	scsi_do_req(SRpnt, (void *)cmd, bp, bytes, osst_sleep_done, timeout, retries);
 
@@ -387,7 +393,7 @@
 	scsi_release_request((STp->buffer)->last_SRpnt);
 
 	if (STbuffer->writing < STbuffer->buffer_bytes)
-		printk(KERN_WARNING "osst:A: write_behind_check: something left in buffer!\n");
+		printk(KERN_WARNING "osst :A: write_behind_check: something left in buffer!\n");
 
 	STbuffer->buffer_bytes -= STbuffer->writing;
 	STbuffer->writing = 0;
@@ -537,7 +543,7 @@
 				 STp->first_frame_position);
 		goto err_out;
 	}
-	STp->frame_in_buffer = 1;
+//	STp->frame_in_buffer = 1;
 
         if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) {
 		if (!quiet)
@@ -565,12 +571,14 @@
 	}
 	if (aux->frame_type == OS_FRAME_TYPE_EOD) {
 		STps->eof = ST_EOD_1;
+		STp->frame_in_buffer = 1;
 	}
 	if (aux->frame_type == OS_FRAME_TYPE_DATA) {
                 blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt);
 		blk_sz  = ntohl(aux->dat.dat_list[0].blk_sz);
 		STp->buffer->buffer_bytes = blk_cnt * blk_sz;
 		STp->buffer->read_pointer = 0;
+		STp->frame_in_buffer = 1;
 
 		/* See what block size was used to write file */
 		if (STp->block_size != blk_sz && blk_sz > 0) {
@@ -597,18 +605,23 @@
 /*
  * Wait for the unit to become Ready
  */
-static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned timeout)
+static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned timeout, int initial_delay)
 {
 	unsigned char	cmd[MAX_COMMAND_SIZE];
 	Scsi_Request  * SRpnt;
 	long		startwait = jiffies;
 #if DEBUG
-	int		dbg = debugging;
-	char *name = tape_name(STp);
+	int		dbg  = debugging;
+	char          * name = tape_name(STp);
 
 	printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name);
 #endif
 
+	if (initial_delay > 0) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(initial_delay);
+	}
+
 	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = TEST_UNIT_READY;
 
@@ -720,10 +733,10 @@
 {
 	int	retval;
 
-	osst_wait_ready(STp, aSRpnt, 15 * 60);			/* TODO - can this catch a write error? */
+	osst_wait_ready(STp, aSRpnt, 15 * 60, 0);			/* TODO - can this catch a write error? */
 	retval = osst_set_frame_position(STp, aSRpnt, frame, 0);
 	if (retval) return (retval);
-	osst_wait_ready(STp, aSRpnt, 15 * 60);
+	osst_wait_ready(STp, aSRpnt, 15 * 60, OSST_WAIT_POSITION_COMPLETE);
 	return (osst_get_frame_position(STp, aSRpnt));
 }
 
@@ -736,6 +749,7 @@
 	Scsi_Request  * SRpnt;
 
 	int             result = 0;
+	int		delay  = OSST_WAIT_LONG_WRITE_COMPLETE;
 #if DEBUG
 	char *name = tape_name(STp);
 
@@ -749,12 +763,20 @@
 	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_WRITE_RETRIES, TRUE);
 	*aSRpnt = SRpnt;
 	if (!SRpnt) return (-EBUSY);
-
-	if ((STp->buffer)->syscall_result)
-		result = osst_write_error_recovery(STp, aSRpnt, 0);
-
-	result |= osst_wait_ready(STp, aSRpnt, 5 * 60);
+//printk(OSST_DEB_MSG "%s:X: Write filemark returned %x:%02x:%02x:%02x\n",dev,STp->buffer->syscall_result,SRpnt->sr_sense_buffer[2] & 0x0f,SRpnt->sr_sense_buffer[12],SRpnt->sr_sense_buffer[13]);
+	if (STp->buffer->syscall_result) {
+		if ((SRpnt->sr_sense_buffer[2] & 0x0f) == 2 && SRpnt->sr_sense_buffer[12] == 4) {
+			if (SRpnt->sr_sense_buffer[13] == 8) {
+//printk(OSST_DEB_MSG "%s:X: Long initial delay\n", dev);
+				delay = OSST_WAIT_LONG_WRITE_COMPLETE;
+			}
+		} else
+			result = osst_write_error_recovery(STp, aSRpnt, 0);
+	}
+//printk(OSST_DEB_MSG "%s:X: Entering wait ready (%d)\n",dev,delay);
+	result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay);
 	STp->ps[STp->partition].rw = OS_WRITING_COMPLETE;
+
 	return (result);
 }
 
@@ -845,7 +867,7 @@
 	    printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name);
 #endif
 	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ,
-				      STp->timeout, MAX_RETRIES, TRUE);
+				      STp->timeout, MAX_READ_RETRIES, TRUE);
 	*aSRpnt = SRpnt;
 	if (!SRpnt)
 	    return (-EBUSY);
@@ -901,7 +923,8 @@
 #endif
 
 	if (STps->rw != ST_READING) {         /* Initialize read operation */
-		if (STps->rw == ST_WRITING) {
+		if (STps->rw == ST_WRITING || STp->dirty) {
+			STp->write_type = OS_WRITE_DATA;
                         osst_flush_write_buffer(STp, aSRpnt);
 			osst_flush_drive_buffer(STp, aSRpnt);
 		}
@@ -919,7 +942,7 @@
 #if DEBUG
 		printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name);
 #endif
-		SRpnt   = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_RETRIES, TRUE);
+		SRpnt   = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READ_RETRIES, TRUE);
 		*aSRpnt = SRpnt;
 		retval  = STp->buffer->syscall_result;
 	}
@@ -938,6 +961,15 @@
 		      position;
 
 	/*
+	 * If we want just any frame (-1) and there is a frame in the buffer, return it
+	 */
+	if (frame_seq_number == -1 && STp->frame_in_buffer) {
+#if DEBUG
+		printk(OSST_DEB_MSG "%s:D: Frame %d still in buffer\n", name, STp->frame_seq_number);
+#endif
+		return (STps->eof);
+	}
+	/*
          * Search and wait for the next logical tape frame
 	 */
 	while (1) {
@@ -1090,6 +1122,7 @@
 		    if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
 		    move               /= (OS_DATA_SIZE / STp->block_size);
 		 }
+		 if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : -1;
 #if DEBUG
 		 printk(OSST_DEB_MSG
 			"%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n",
@@ -1287,7 +1320,7 @@
 		cmd[8] = 32768 & 0xff;
 
 		SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ,
-					    STp->timeout, MAX_RETRIES, TRUE);
+					    STp->timeout, MAX_READ_RETRIES, TRUE);
 	
 		if ((STp->buffer)->syscall_result || !SRpnt) {
 			printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
@@ -1327,7 +1360,7 @@
 						name, new_frame+i, frame_seq_number+i);
 #endif
 			osst_set_frame_position(STp, aSRpnt, new_frame + i, 0);
-			osst_wait_ready(STp, aSRpnt, 60);
+			osst_wait_ready(STp, aSRpnt, 60, OSST_WAIT_POSITION_COMPLETE);
 			osst_get_frame_position(STp, aSRpnt);
 			SRpnt = * aSRpnt;
 
@@ -1395,6 +1428,7 @@
 					if (SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 4 &&
 					    (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8)) {
 						/* in the process of becoming ready */
+						set_current_state(TASK_INTERRUPTIBLE);
 						schedule_timeout(HZ / 10);
 						continue;
 					}
@@ -1467,6 +1501,8 @@
 			osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
 			flag = 0;
 			attempts--;
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(HZ / 10);
 		}
 		if (osst_get_frame_position(STp, aSRpnt) < 0) {		/* additional write error */
 #if DEBUG
@@ -1909,6 +1945,7 @@
 	if (mt_op == MTFSF) {
 		STp->frame_seq_number++;
 		STp->frame_in_buffer  = 0;
+		STp->buffer->read_pointer = 0;
 		STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
 	}
 	return 0;
@@ -2009,7 +2046,7 @@
 #if DEBUG
 	printk(OSST_DEB_MSG "%s:D: Reached onstream write filler group %d\n", name, where);
 #endif
-	osst_wait_ready(STp, aSRpnt, 60 * 5);
+	osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
 	osst_set_frame_position(STp, aSRpnt, where, 0);
 	STp->write_type = OS_WRITE_FILLER;
 	while (count--) {
@@ -2035,7 +2072,7 @@
 #if DEBUG
 	printk(OSST_DEB_MSG "%s:D: Reached onstream write header group %d\n", name, where);
 #endif
-	osst_wait_ready(STp, aSRpnt, 60 * 5);
+	osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
 	osst_set_frame_position(STp, aSRpnt, where, 0);
 	STp->write_type = OS_WRITE_HEADER;
 	while (count--) {
@@ -2669,7 +2706,7 @@
 
 	STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
 	SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, SCSI_DATA_READ,
-				      STp->timeout, MAX_READY_RETRIES, TRUE);
+				      STp->timeout, MAX_RETRIES, TRUE);
 	if (!SRpnt) {
 		STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
 		return (-EBUSY);
@@ -2690,7 +2727,7 @@
 			scmd[0] = READ_POSITION;
 			STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
 			SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, SCSI_DATA_READ,
-						    STp->timeout, MAX_READY_RETRIES, TRUE);
+						    STp->timeout, MAX_RETRIES, TRUE);
 			if (!STp->buffer->syscall_result)
 				memcpy (SRpnt->sr_sense_buffer, mysense, 16);
 		}
@@ -2762,7 +2799,7 @@
 			scmd[9] = 0x80;
 
 		SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, SCSI_DATA_NONE, STp->long_timeout,
-								MAX_READY_RETRIES, TRUE);
+								MAX_RETRIES, TRUE);
 		if (!SRpnt)
 			return (-EBUSY);
 		*aSRpnt  = SRpnt;
@@ -2775,7 +2812,7 @@
 			result = (-EIO);
 		}
 		if (pp != ppos)
-			osst_wait_ready(STp, aSRpnt, 5 * 60);
+			osst_wait_ready(STp, aSRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
 	} while ((pp != ppos) && (pp = ppos));
 	STp->first_frame_position = STp->last_frame_position = ppos;
 	STps->eof = ST_NOEOF;
@@ -2932,16 +2969,17 @@
 	 * If there was a bus reset, block further access
 	 * to this device.
 	 */
-	if( STp->device->was_reset )
+	if( STp->pos_unknown)
 		return (-EIO);
 
 	if (STp->ready != ST_READY)
 		return 0;
 
 	STps = &(STp->ps[STp->partition]);
-	if (STps->rw == ST_WRITING)  /* Writing */
+	if (STps->rw == ST_WRITING || STp->dirty) {	/* Writing */
+		STp->write_type = OS_WRITE_DATA;
 		return osst_flush_write_buffer(STp, aSRpnt);
-
+	}
 	if (STp->block_size == 0)
 		return 0;
 
@@ -3063,6 +3101,43 @@
 	return 0;
 }
 
+/* Lock or unlock the drive door. Don't use when Scsi_Request allocated. */
+static int do_door_lock(OS_Scsi_Tape * STp, int do_lock)
+{
+	int retval, cmd;
+
+	cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
+#if DEBUG
+	printk(OSST_DEB_MSG "%s:D: %socking drive door.\n", tape_name(STp), do_lock ? "L" : "Unl");
+#endif
+	retval = scsi_ioctl(STp->device, cmd, NULL);
+	if (!retval) {
+		STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
+	}
+	else {
+		STp->door_locked = ST_LOCK_FAILS;
+	}
+	return retval;
+}
+
+/* Set the internal state after reset */
+static void reset_state(OS_Scsi_Tape *STp)
+{
+	int i;
+	ST_partstat *STps;
+
+	STp->pos_unknown = 0;
+	for (i = 0; i < ST_NBR_PARTITIONS; i++) {
+		STps = &(STp->ps[i]);
+		STps->rw = ST_IDLE;
+		STps->eof = ST_NOEOF;
+		STps->at_sm = 0;
+		STps->last_block_valid = FALSE;
+		STps->drv_block = -1;
+		STps->drv_file = -1;
+	}
+}
+				
 
 /* Entry points to osst */
 
@@ -3120,7 +3195,7 @@
 	 * If there was a bus reset, block further access
 	 * to this device.
 	 */
-	if (STp->device->was_reset) {
+	if (STp->pos_unknown) {
 		retval = (-EIO);
 		goto out;
 	}
@@ -3154,20 +3229,22 @@
 		goto out;
 	}
 
-	STps = &(STp->ps[STp->partition]);
-
-	if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED &&
-	    !osst_int_ioctl(STp, &SRpnt, MTLOCK, 0))
+	if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
 		STp->door_locked = ST_LOCKED_AUTO;
 
+	STps = &(STp->ps[STp->partition]);
 
 	if (STps->rw == ST_READING) {
+#if DEBUG
+		printk(OSST_DEB_MSG "%s:D: Switching from read to write at file %d, block %d\n", name, 
+					STps->drv_file, STps->drv_block);
+#endif
 		retval = osst_flush_buffer(STp, &SRpnt, 0);
 		if (retval)
 			goto out;
 		STps->rw = ST_IDLE;
 	}
-	else if (STps->rw != ST_WRITING) {
+	if (STps->rw != ST_WRITING) {
 		/* Are we totally rewriting this tape? */
 		if (!STp->header_ok ||
 		    (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) ||
@@ -3518,9 +3595,19 @@
 			    printk(OSST_DEB_MSG "%s:D: EOF up (%d). Left %d, needed %d.\n", name,
 						 STps->eof, (STp->buffer)->buffer_bytes, count - total);
 #endif
+		       	/* force multiple of block size, note block_size may have been adjusted */
 			transfer = (((STp->buffer)->buffer_bytes < count - total ?
 				     (STp->buffer)->buffer_bytes : count - total)/
-					STp->block_size) * STp->block_size; /* force multiple of block size */
+					STp->block_size) * STp->block_size;
+
+			if (transfer == 0) {
+				printk(KERN_WARNING
+				  "%s:W: Nothing can be transfered, requested %Zd, tape block size (%d%c).\n",
+			   		name, count, STp->block_size < 1024?
+					STp->block_size:STp->block_size/1024,
+				       	STp->block_size<1024?'b':'k');
+				break;
+			}
 			i = from_buffer(STp->buffer, buf, transfer);
 			if (i)  {
 				retval = i;
@@ -3870,9 +3957,10 @@
 		 }
 		 break;
 	 case MTWEOF:
-		 if ( STps->rw == ST_WRITING && !(STp->device)->was_reset)
+		 if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
+			STp->write_type = OS_WRITE_DATA;
 			ioctl_result = osst_flush_write_buffer(STp, &SRpnt);
-		 else
+		 } else
 			ioctl_result = 0;
 #if DEBUG
 		 if (debugging) 
@@ -3993,26 +4081,6 @@
 		fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
 		break;
 
-	 case MTLOCK:
-		chg_eof = FALSE;
-		cmd[0] = ALLOW_MEDIUM_REMOVAL;
-		cmd[4] = SCSI_REMOVAL_PREVENT;
-#if DEBUG
-		if (debugging)
-		    printk(OSST_DEB_MSG "%s:D: Locking drive door.\n", name);
-#endif
-		break;
-
-	 case MTUNLOCK:
-		chg_eof = FALSE;
-		cmd[0] = ALLOW_MEDIUM_REMOVAL;
-		cmd[4] = SCSI_REMOVAL_ALLOW;
-#if DEBUG
-		if (debugging)
-		   printk(OSST_DEB_MSG "%s:D: Unlocking drive door.\n", name);
-#endif
-	break;
-
 	 case MTSETBLK:           /* Set block length */
 	 case MTSETDENSITY:       /* Set tape density */
 	 case MTSETDRVBUFFER:     /* Set drive buffering */
@@ -4070,13 +4138,10 @@
 		STps->drv_file = fileno;
 		STps->at_sm = at_sm;
 
-		if (cmd_in == MTLOCK)
-			 STp->door_locked = ST_LOCKED_EXPLICIT;
-		else if (cmd_in == MTUNLOCK)
-			STp->door_locked = ST_UNLOCKED;
-
 		if (cmd_in == MTEOM)
 			STps->eof = ST_EOD;
+		else if ((cmd_in == MTFSFM || cmd_in == MTBSF) && STps->eof == ST_FM_HIT)
+			ioctl_result = osst_seek_logical_blk(STp, &SRpnt, STp->logical_blk_num - 1);
 		else if (cmd_in == MTFSF)
 			STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM;
 		else if (chg_eof)
@@ -4085,7 +4150,6 @@
 		if (cmd_in == MTOFFL || cmd_in == MTUNLOAD)
 			STp->rew_at_close = 0;
 		else if (cmd_in == MTLOAD) {
-/*      		STp->rew_at_close = (minor(inode->i_rdev) & 0x80) == 0;  FIXME */
 			for (i=0; i < ST_NBR_PARTITIONS; i++) {
 			    STp->ps[i].rw = ST_IDLE;
 			    STp->ps[i].last_block_valid = FALSE;/* FIXME - where else is this field maintained? */
@@ -4130,11 +4194,8 @@
 		if ((SRpnt->sr_sense_buffer[2] & 0x0f) == BLANK_CHECK)
 			STps->eof = ST_EOD;
 
-		if (cmd_in == MTLOCK)
-			STp->door_locked = ST_LOCK_FAILS;
-
 		if (cmd_in == MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60))
-			ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60);
+			ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
 	}
 	*aSRpnt = SRpnt;
 
@@ -4146,38 +4207,48 @@
 static int os_scsi_tape_open(struct inode * inode, struct file * filp)
 {
 	unsigned short flags;
-	int i, b_size, need_dma_buffer, new_session = FALSE, retval = 0;
+	int i, b_size, new_session = FALSE, retval = 0;
 	unsigned char cmd[MAX_COMMAND_SIZE];
 	Scsi_Request * SRpnt;
 	OS_Scsi_Tape * STp;
 	ST_mode * STm;
 	ST_partstat * STps;
-	int dev = TAPE_NR(inode->i_rdev);
 	char *name;
+	int dev = TAPE_NR(inode->i_rdev);
 	int mode = TAPE_MODE(inode->i_rdev);
 
-	if (dev >= osst_dev_max || (STp = os_scsi_tapes[dev]) == NULL || !STp->device)
+	write_lock(&os_scsi_tapes_lock);
+	if (dev >= osst_max_dev || os_scsi_tapes == NULL ||
+	    (STp = os_scsi_tapes[dev]) == NULL || !STp->device) {
+		write_unlock(&os_scsi_tapes_lock);
 		return (-ENXIO);
+	}
 
-	filp->private_data = STp;
 	name = tape_name(STp);
 
-	if( !scsi_block_when_processing_errors(STp->device) ) {
-		return -ENXIO;
-	}
-
 	if (STp->in_use) {
+		write_unlock(&os_scsi_tapes_lock);
 #if DEBUG
 		printk(OSST_DEB_MSG "%s:D: Device already in use.\n", name);
 #endif
 		return (-EBUSY);
 	}
-	
-	if (!try_module_get(STp->device->host->hostt->module))
+
+	if (!scsi_device_get(STp->device)) {
+		write_unlock(&os_scsi_tapes_lock);
+#if DEBUG
+                printk(OSST_DEB_MSG "%s:D: Failed scsi_device_get.\n", name);
+#endif
 		return (-ENXIO);
-	STp->device->access_count++;
-	STp->in_use       = 1;
-	STp->rew_at_close = (minor(inode->i_rdev) & 0x80) == 0;
+	}
+	filp->private_data = STp;
+	STp->in_use = 1;
+	write_unlock(&os_scsi_tapes_lock);
+	STp->rew_at_close = TAPE_REWIND(inode->i_rdev);
+
+	if( !scsi_block_when_processing_errors(STp->device) ) {
+		return -ENXIO;
+	}
 
 	if (mode != STp->current_mode) {
 #if DEBUG
@@ -4193,10 +4264,10 @@
 	flags = filp->f_flags;
 	STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY);
 
-	STp->raw = (minor(inode->i_rdev) & 0x40) != 0;
+	STp->raw = TAPE_IS_RAW(inode->i_rdev);
 	if (STp->raw)
 		STp->header_ok = 0;
-
+#if 0
 	/* Allocate a buffer for this user */
 	need_dma_buffer = STp->restr_dma;
 	for (i=0; i < osst_nbr_buffers; i++)
@@ -4213,9 +4284,16 @@
 	}
 	else
 		STp->buffer = osst_buffers[i];
-	(STp->buffer)->in_use = 1;
+#endif  /*     	now pre_allocated */
+	/* Allocate data segments for this device's tape buffer */
+	if (!enlarge_buffer(STp->buffer, STp->restr_dma)) {
+		printk(KERN_ERR "%s:E: Unable to allocate memory segments for tape buffer.\n", name);
+		retval = (-EOVERFLOW);
+		goto err_out;
+	}
 	(STp->buffer)->writing = 0;
 	(STp->buffer)->syscall_result = 0;
+#if 0
 	(STp->buffer)->use_sg = STp->device->host->sg_tablesize;
 
 	/* Compute the usable buffer size for this SCSI adapter */
@@ -4226,7 +4304,7 @@
 		     i < (STp->buffer)->sg_segs; i++)
 			(STp->buffer)->buffer_size += (STp->buffer)->sg[i].length;
 	}
-
+#endif
 	STp->dirty = 0;
 	for (i=0; i < ST_NBR_PARTITIONS; i++) {
 		STps = &(STp->ps[i]);
@@ -4251,6 +4329,10 @@
 #if DEBUG
 		printk(OSST_DEB_MSG "%s:D: Unit not ready, cause %x\n", name, SRpnt->sr_sense_buffer[13]);
 #endif
+		if (filp->f_flags & O_NONBLOCK) {
+			retval = -EAGAIN;
+			goto err_out;
+		}
 		if (SRpnt->sr_sense_buffer[13] == 2) {	/* initialize command required (LOAD) */
 			memset (cmd, 0, MAX_COMMAND_SIZE);
         		cmd[0] = START_STOP;
@@ -4259,7 +4341,7 @@
 			SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE,
 					     STp->timeout, MAX_READY_RETRIES, TRUE);
 		}
-		osst_wait_ready(STp, &SRpnt, (SRpnt->sr_sense_buffer[13]==1?15:3) * 60);
+		osst_wait_ready(STp, &SRpnt, (SRpnt->sr_sense_buffer[13]==1?15:3) * 60, 0);
 	}
 	if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
 	    (SRpnt->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */
@@ -4280,7 +4362,7 @@
 				break;
 		}
 
-		STp->device->was_reset = 0;
+		STp->pos_unknown = 0;
 		STp->partition = STp->new_partition = 0;
 		if (STp->can_partitions)
 			STp->nbr_partitions = 1;  /* This guess will be updated later if necessary */
@@ -4388,7 +4470,7 @@
 			break;
 
 			if ((SRpnt->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION) {
-				STp->device->was_reset = 0;
+				STp->pos_unknown = 0;
 				STp->partition = STp->new_partition = 0;
 				if (STp->can_partitions)
 					STp->nbr_partitions = 1;  /* This guess will be updated later if necessary */
@@ -4406,8 +4488,8 @@
 		}
 	}
 
-	if (osst_wait_ready(STp, &SRpnt, 15 * 60))		/* FIXME - not allowed with NOBLOCK */
-		 printk(KERN_INFO "%s:I: Device did not become Ready in open\n",name);
+	if (osst_wait_ready(STp, &SRpnt, 15 * 60, 0))		/* FIXME - not allowed with NOBLOCK */
+		 printk(KERN_INFO "%s:I: Device did not become Ready in open\n", name);
 
 	if ((STp->buffer)->syscall_result != 0) {
 		if ((STp->device)->scsi_level >= SCSI_2 &&
@@ -4430,19 +4512,9 @@
 
 	osst_configure_onstream(STp, &SRpnt);
 
-/*	STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0; FIXME */
-
-	if (OS_FRAME_SIZE > (STp->buffer)->buffer_size &&
-	    !enlarge_buffer(STp->buffer, OS_FRAME_SIZE, STp->restr_dma)) {
-		printk(KERN_NOTICE "%s:A: Framesize %d too large for buffer.\n", name,
-				     OS_FRAME_SIZE);
-		retval = (-EIO);
-		goto err_out;
-	}
-
-	if ((STp->buffer)->buffer_size >= OS_FRAME_SIZE) {
+	if (STp->buffer->buffer_size >= OS_FRAME_SIZE) {
 		for (i = 0, b_size = 0; 
-		     i < STp->buffer->sg_segs && (b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE; 
+		     (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE); 
 		     b_size += STp->buffer->sg[i++].length);
 		STp->buffer->aux = (os_aux_t *) (page_address(STp->buffer->sg[i].page) + OS_DATA_SIZE - b_size);
 #if DEBUG
@@ -4451,8 +4523,12 @@
 		printk(OSST_DEB_MSG "%s:D: AUX points to %p in segment %d at %p\n", name,
 			 STp->buffer->aux, i, page_address(STp->buffer->sg[i].page));
 #endif
-	} else
+	} else {
 		STp->buffer->aux = NULL; /* this had better never happen! */
+		printk(KERN_NOTICE "%s:A: Framesize %d too large for buffer.\n", name, OS_FRAME_SIZE);
+		retval = (-EIO);
+		goto err_out;
+	}
 
 	STp->block_size = STp->raw ? OS_FRAME_SIZE : (
 			     (STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE);
@@ -4509,15 +4585,10 @@
 err_out:
 	if (SRpnt != NULL)
 		scsi_release_request(SRpnt);
-	if (STp->buffer != NULL) {
-		STp->buffer->in_use = 0;
-		STp->buffer = NULL;
-	}
-	STp->in_use = 0;
+	normalize_buffer(STp->buffer);
 	STp->header_ok = 0;
-	STp->device->access_count--;
-
-	module_put(STp->device->host->hostt->module);
+	STp->in_use = 0;
+	scsi_device_put(STp->device);
 
 	return retval;
 }
@@ -4536,12 +4607,13 @@
 	if (file_count(filp) > 1)
 		return 0;
 
-	if ( STps->rw == ST_WRITING && !(STp->device)->was_reset) {
+	if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
+		STp->write_type = OS_WRITE_DATA;
 		result = osst_flush_write_buffer(STp, &SRpnt);
 		if (result != 0 && result != (-ENOSPC))
 			goto out;
 	}
-	if ( STps->rw >= ST_WRITING && !(STp->device)->was_reset) {
+	if ( STps->rw >= ST_WRITING && !STp->pos_unknown) {
 
 #if DEBUG
 		if (debugging) {
@@ -4632,20 +4704,20 @@
 	OS_Scsi_Tape * STp = filp->private_data;
 	Scsi_Request * SRpnt = NULL;
 
-	if (STp->door_locked == ST_LOCKED_AUTO)
-		osst_int_ioctl(STp, &SRpnt, MTUNLOCK, 0);
 	if (SRpnt) scsi_release_request(SRpnt);
 
-	if (STp->buffer != NULL)
-		STp->buffer->in_use = 0;
+	if (STp->door_locked == ST_LOCKED_AUTO)
+		do_door_lock(STp, 0);
 
 	if (STp->raw)
 		STp->header_ok = 0;
-
+	
+	normalize_buffer(STp->buffer);
+	write_lock(&os_scsi_tapes_lock);
 	STp->in_use = 0;
-	STp->device->access_count--;
+	write_unlock(&os_scsi_tapes_lock);
 
-	module_put(STp->device->host->hostt->module);
+	scsi_device_put(STp->device);
 
 	return result;
 }
@@ -4718,7 +4790,7 @@
 			goto out;
 		}
 
-		if (!(STp->device)->was_reset) {
+		if (!STp->pos_unknown) {
 
 			if (STps->eof == ST_FM_HIT) {
 				if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM|| mtc.mt_op == MTEOM) {
@@ -4764,15 +4836,9 @@
 				retval = (-EIO);
 				goto out;
 			}
+			reset_state(STp);
+			/* remove this when the midlevel properly clears was_reset */
 			STp->device->was_reset = 0;
-			if (STp->door_locked != ST_UNLOCKED &&
-			    STp->door_locked != ST_LOCK_FAILS) {
-				if (osst_int_ioctl(STp, &SRpnt, MTLOCK, 0)) {
-					printk(KERN_NOTICE "%s:I: Could not relock door after bus reset.\n",
-								  name);
-					STp->door_locked = ST_UNLOCKED;
-				}
-			}
 		}
 
 		if (mtc.mt_op != MTNOP && mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM &&
@@ -4781,7 +4847,7 @@
 			STps->rw = ST_IDLE;  /* Prevent automatic WEOF and fsf */
 
 		if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
-			osst_int_ioctl(STp, &SRpnt, MTUNLOCK, 0);  /* Ignore result! */
+			do_door_lock(STp, 0);  /* Ignore result! */
 
 		if (mtc.mt_op == MTSETDRVBUFFER &&
 		   (mtc.mt_count & MT_ST_OPTIONS) != 0) {
@@ -4837,7 +4903,12 @@
 			retval = i;
 			goto out;
 		}
-
+ 
+		if (mtc.mt_op == MTLOCK || mtc.mt_op == MTUNLOCK) {
+			retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
+			goto out;
+		}
+			
 /*   if (STp->can_partitions && STp->ready == ST_READY &&
 	 (i = update_partition(inode)) < 0)
 		 {retval=i;goto out;}*/
@@ -4967,15 +5038,12 @@
 
 /* Memory handling routines */
 
-/* Try to allocate a new tape buffer */
-static OSST_buffer * new_tape_buffer( int from_initialization, int need_dma )
+/* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */
+static OSST_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg )
 {
-	int i, priority, b_size, order, got = 0, segs = 0;
+	int i, priority;
 	OSST_buffer *tb;
 
-	if (osst_nbr_buffers >= osst_dev_max)
-		return NULL;  /* Should never happen */
-
 	if (from_initialization)
 		priority = GFP_ATOMIC;
 	else
@@ -4983,144 +5051,94 @@
 
 	i = sizeof(OSST_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist);
 	tb = (OSST_buffer *)kmalloc(i, priority);
-	if (tb) {
-//    tb->this_size = i;
-		if (need_dma)
-			priority |= GFP_DMA;
-
-		/* Try to allocate the first segment up to OSST_FIRST_ORDER and the
-		 others big enough to reach the goal */
-		for (b_size = PAGE_SIZE,          order = 0;
-		     b_size < osst_buffer_size && order < OSST_FIRST_ORDER;
-		     b_size *= 2,                 order++ );
-
-		for ( ; b_size >= PAGE_SIZE; order--, b_size /= 2) {
-			tb->sg[0].page = alloc_pages(priority, order);
-			tb->sg[0].offset = 0;
-			if (tb->sg[0].page != NULL) {
-			    tb->sg[0].length = b_size;
-			    break;
-			}
-		}
-		if (tb->sg[segs].page == NULL) {
-			kfree(tb);
-			tb = NULL;
-		}
-		else {  /* Got something, continue */
-
-			for (b_size = PAGE_SIZE, order = 0;
-			     osst_buffer_size > tb->sg[0].length + (OSST_FIRST_SG - 1) * b_size;
-			     b_size *= 2, order++ );
-
-			for (segs=1, got=tb->sg[0].length;
-			     got < osst_buffer_size && segs < OSST_FIRST_SG; ) {
-			    tb->sg[segs].page = alloc_pages(priority, order);
-			    tb->sg[segs].offset = 0;
-			    if (tb->sg[segs].page == NULL) {
-				if (osst_buffer_size - got <=
-				    (OSST_FIRST_SG - segs) * b_size / 2) {
-				    b_size /= 2; /* Large enough for the rest of the buffers */
-				    order--;
-				    continue;
-				}
-				tb->sg_segs = segs;
-				tb->orig_sg_segs = 0;
-#if DEBUG
-				tb->buffer_size = got;
-#endif
-				normalize_buffer(tb);
-				kfree(tb);
-				tb = NULL;
-				break;
-			    }
-                            tb->sg[segs].page = NULL;
-			    tb->sg[segs].length = b_size;
-			    got += b_size;
-			    segs++;
-			}
-		}
-	}
 	if (!tb) {
-		printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer (nbr %d).\n",
-				   osst_nbr_buffers);
+		printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n");
 		return NULL;
 	}
-	tb->sg_segs = tb->orig_sg_segs = segs;
-	tb->b_data = page_address(tb->sg[0].page);
-
+	memset(tb, 0, i);
+	tb->sg_segs = tb->orig_sg_segs = 0;
+	tb->use_sg = max_sg;
+	tb->in_use = TRUE;
+	tb->dma = need_dma;
+	tb->buffer_size = 0;
 #if DEBUG
-	if (debugging) {
+	if (debugging) 
 		printk(OSST_DEB_MSG
-			"osst :D: Allocated tape buffer %d (%d bytes, %d segments, dma: %d, a: %p).\n",
-			   osst_nbr_buffers, got, tb->sg_segs, need_dma, tb->b_data);
-		printk(OSST_DEB_MSG
-			"osst :D: segment sizes: first %d, last %d bytes.\n",
-			   tb->sg[0].length, tb->sg[segs-1].length);
-	}
+			"osst :D: Allocated tape buffer skeleton (%d bytes, %d segments, dma: %d).\n",
+			   i, max_sg, need_dma);
 #endif
-	tb->in_use = 0;
-	tb->dma = need_dma;
-	tb->buffer_size = got;
-	tb->writing = 0;
-	osst_buffers[osst_nbr_buffers++] = tb;
-
 	return tb;
 }
 
-
-/* Try to allocate a temporary enlarged tape buffer */
-static int enlarge_buffer(OSST_buffer *STbuffer, int new_size, int need_dma)
+/* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */
+static int enlarge_buffer(OSST_buffer *STbuffer, int need_dma)
 {
 	int segs, nbr, max_segs, b_size, priority, order, got;
 
-	normalize_buffer(STbuffer);
+	if (STbuffer->buffer_size >= OS_FRAME_SIZE)
+		return TRUE;
 
-	max_segs = STbuffer->use_sg;
-	if (max_segs > osst_max_sg_segs)
-		max_segs = osst_max_sg_segs;
-	nbr = max_segs - STbuffer->sg_segs;
-	if (nbr <= 0)
+	if (STbuffer->sg_segs) {
+		printk(KERN_WARNING "osst :A: Buffer not previously normalized.\n");
+		normalize_buffer(STbuffer);
+	}
+	/* See how many segments we can use -- need at least two */
+	nbr = max_segs = STbuffer->use_sg;
+	if (nbr <= 2)
 		return FALSE;
 
 	priority = GFP_KERNEL;
 	if (need_dma)
 		priority |= GFP_DMA;
-	for (b_size = PAGE_SIZE, order = 0;
-		 b_size * nbr < new_size - STbuffer->buffer_size;
-		 b_size *= 2, order++);
-
-	for (segs=STbuffer->sg_segs, got=STbuffer->buffer_size;
-	     segs < max_segs && got < new_size; ) {
-		STbuffer->sg[segs].page = alloc_pages(priority, order);
+
+	/* Try to allocate the first segment up to OS_DATA_SIZE and the others
+	   big enough to reach the goal (code assumes no segments in place) */
+	for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
+		STbuffer->sg[0].page = alloc_pages(priority, order);
+		STbuffer->sg[0].offset = 0;
+		if (STbuffer->sg[0].page != NULL) {
+		    STbuffer->sg[0].length = b_size;
+		    STbuffer->b_data = page_address(STbuffer->sg[0].page);
+		    break;
+		}
+	}
+	if (STbuffer->sg[0].page == NULL) {
+		printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
+		return FALSE;
+	}
+	/* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
+	for (segs=STbuffer->sg_segs=1, got=b_size;
+	     segs < max_segs && got < OS_FRAME_SIZE; ) {
+		STbuffer->sg[segs].page =
+			(OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ?
+				kmalloc(OS_FRAME_SIZE - got, priority):
+				alloc_pages(priority, order);
 		STbuffer->sg[segs].offset = 0;
 		if (STbuffer->sg[segs].page == NULL) {
-			if (new_size - got <= (max_segs - segs) * b_size / 2) {
+			if (OS_FRAME_SIZE - got <= (max_segs - segs) * b_size / 2 && order) {
 				b_size /= 2;  /* Large enough for the rest of the buffers */
 				order--;
 				continue;
 			}
 			printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.\n",
-						new_size);
+						OS_FRAME_SIZE);
 #if DEBUG
 			STbuffer->buffer_size = got;
 #endif
 			normalize_buffer(STbuffer);
 			return FALSE;
 		}
-		STbuffer->sg[segs].page = NULL;
-		STbuffer->sg[segs].length = b_size;
-		STbuffer->sg_segs += 1;
-		got += b_size;
+		STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size;
+		got += STbuffer->sg[segs].length;
 		STbuffer->buffer_size = got;
-		segs++;
+		STbuffer->sg_segs = ++segs;
 	}
 #if DEBUG
 	if (debugging) {
-		for (nbr=0; osst_buffers[nbr] != STbuffer && nbr < osst_nbr_buffers; nbr++);
-			printk(OSST_DEB_MSG
-			   "osst :D: Expanded tape buffer %d (%d bytes, %d->%d segments, dma: %d, a: %p).\n",
-			   nbr, got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data);
-			printk(OSST_DEB_MSG
+		printk(OSST_DEB_MSG
+			   "osst :D: Expanded tape buffer (%d bytes, %d->%d segments, dma: %d, at: %p).\n",
+			   got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data);
+		printk(OSST_DEB_MSG
 			   "osst :D: segment sizes: first %d, last %d bytes.\n",
 			   STbuffer->sg[0].length, STbuffer->sg[segs-1].length);
 	}
@@ -5130,12 +5148,12 @@
 }
 
 
-/* Release the extra buffer */
+/* Release the segments */
 static void normalize_buffer(OSST_buffer *STbuffer)
 {
   int i, order, b_size;
 
-	for (i=STbuffer->orig_sg_segs; i < STbuffer->sg_segs; i++) {
+	for (i=0; i < STbuffer->sg_segs; i++) {
 
 		for (b_size = PAGE_SIZE, order = 0;
 		     b_size < STbuffer->sg[i].length;
@@ -5149,7 +5167,7 @@
 		printk(OSST_DEB_MSG "osst :D: Buffer at %p normalized to %d bytes (segs %d).\n",
 			     STbuffer->b_data, STbuffer->buffer_size, STbuffer->sg_segs);
 #endif
-	STbuffer->sg_segs = STbuffer->orig_sg_segs;
+	STbuffer->sg_segs = STbuffer->orig_sg_segs = 0;
 }
 
 
@@ -5293,19 +5311,17 @@
 
 static void validate_options (void)
 {
-  if (buffer_kbs > 0)
-		osst_buffer_size = buffer_kbs * ST_KILOBYTE;
+  if (max_dev > 0)
+		osst_max_dev = max_dev;  
   if (write_threshold_kbs > 0)
 		osst_write_threshold = write_threshold_kbs * ST_KILOBYTE;
   if (osst_write_threshold > osst_buffer_size)
 		osst_write_threshold = osst_buffer_size;
-  if (max_buffers > 0)
-		osst_max_buffers = max_buffers;
   if (max_sg_segs >= OSST_FIRST_SG)
 		osst_max_sg_segs = max_sg_segs;
 #if DEBUG
-  printk(OSST_DEB_MSG "osst :D: bufsize %d, wrt %d, max buffers %d, s/g segs %d.\n",
-	 osst_buffer_size, osst_write_threshold, osst_max_buffers, osst_max_sg_segs);
+  printk(OSST_DEB_MSG "osst :D: max tapes %d, write threshold %d, s/g segs %d.\n",
+			   osst_max_dev, osst_write_threshold, osst_max_sg_segs);
 //printk(OSST_DEB_MSG "osst :D: sizeof(header) = %d (%s)\n",
 //		sizeof(os_header_t),sizeof(os_header_t)==OS_DATA_SIZE?"ok":"error");
 #endif
@@ -5313,8 +5329,8 @@
 	
 #ifndef MODULE
 /* Set the boot options. Syntax: osst=xxx,yyy,...
-   where xxx is buffer size in 1024 byte blocks and yyy is write threshold
-   in 1024 byte blocks. */
+   where xxx is write threshold in 1024 byte blocks,
+   and   yyy is number of s/g segments to use. */
 static int __init osst_setup (char *str)
 {
   int i, ints[5];
@@ -5352,14 +5368,30 @@
 
 #endif
 
+/* Driverfs file support */
+static ssize_t osst_device_kdev_read(struct device *driverfs_dev, char *page, size_t count, loff_t off)
+{
+	kdev_t kdev; 
+	kdev.value=(int)(long)driverfs_dev->driver_data;
+	return off ? 0 : sprintf(page, "%x\n",kdev.value);
+}
+static DEVICE_ATTR(kdev,S_IRUGO,osst_device_kdev_read,NULL);
+
+static ssize_t osst_device_type_read(struct device *driverfs_dev, char *page, size_t count, loff_t off) 
+{
+	return off ? 0 : sprintf (page, "CHR\n");
+}
+static DEVICE_ATTR(type,S_IRUGO,osst_device_type_read,NULL);
+
 
 static struct file_operations osst_fops = {
-	.read		= osst_read,
-	.write		= osst_write,
-	.ioctl		= osst_ioctl,
-	.open		= os_scsi_tape_open,
-	.flush		= os_scsi_tape_flush,
-	.release	= os_scsi_tape_close,
+	.owner =        THIS_MODULE,
+	.read =         osst_read,
+	.write =        osst_write,
+	.ioctl =        osst_ioctl,
+	.open =         os_scsi_tape_open,
+	.flush =        os_scsi_tape_flush,
+	.release =      os_scsi_tape_close,
 };
 
 static int osst_supports(Scsi_Device * SDp)
@@ -5390,102 +5422,93 @@
 	return 0;
 }
 
+/*
+ * osst startup / cleanup code
+ */
+
 static int osst_attach(Scsi_Device * SDp)
 {
 	OS_Scsi_Tape * tpnt;
 	ST_mode * STm;
 	ST_partstat * STps;
-	int i, dev;
-	struct gendisk *disk;
-#ifdef CONFIG_DEVFS_FS
-	int mode;
-#endif
+	OSST_buffer *buffer;
+	struct gendisk *drive;
+	int i, mode, dev_num;
 
 	if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
-		 return 1;
-
-	osst_init();
-
-	disk = alloc_disk(1);
-	if (!disk)
 		return 1;
 
-	if (osst_nr_dev >= osst_dev_max) {
-		 put_disk(disk);
-		 return 1;
+	if (scsi_slave_attach(SDp)) {
+		printk(KERN_ERR "osst :E: Failed to attach scsi slave.\n");
+		return 1;
 	}
 
-	if (scsi_slave_attach(SDp))
+	drive = alloc_disk(1);
+	if (!drive) {
+		printk(KERN_ERR "osst :E: Out of memory. Device not attached.\n");
 		return 1;
+	}
+
+	/* if this is the first attach, build the infrastructure */
+	write_lock(&os_scsi_tapes_lock);
+	if (os_scsi_tapes == NULL) {
+		os_scsi_tapes =
+			(OS_Scsi_Tape **)kmalloc(osst_max_dev * sizeof(OS_Scsi_Tape *),
+				   GFP_ATOMIC);
+		if (os_scsi_tapes == NULL) {
+			write_unlock(&os_scsi_tapes_lock);
+			printk(KERN_ERR "osst :E: Unable to allocate array for OnStream SCSI tapes.\n");
+			return 1;
+		}
+		for (i=0; i < osst_max_dev; ++i) os_scsi_tapes[i] = NULL;
+	}
 	
+	if (osst_nr_dev >= osst_max_dev) {
+		write_unlock(&os_scsi_tapes_lock);
+		printk(KERN_ERR "osst :E: Too many tape devices (max. %d).\n", osst_max_dev);
+		put_disk(drive);
+		return 1;
+	}
+
 	/* find a free minor number */
-	for (i=0; os_scsi_tapes[i] && i<osst_dev_max; i++);
-	if(i >= osst_dev_max) panic ("Scsi_devices corrupt (osst)");
+	for (i=0; os_scsi_tapes[i] && i<osst_max_dev; i++);
+	if(i >= osst_max_dev) panic ("Scsi_devices corrupt (osst)");
+	dev_num = i;
 
 	/* allocate a OS_Scsi_Tape for this device */
 	tpnt = (OS_Scsi_Tape *)kmalloc(sizeof(OS_Scsi_Tape), GFP_ATOMIC);
 	if (tpnt == NULL) {
-		 printk(KERN_WARNING "osst :W: Can't allocate device descriptor.\n");
-		 put_disk(disk);
-
-		 scsi_slave_detach(SDp);
-		 return 1;
+		write_unlock(&os_scsi_tapes_lock);
+		printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n");
+		put_disk(drive);
+		scsi_slave_detach(SDp);
+		return 1;
 	}
 	memset(tpnt, 0, sizeof(OS_Scsi_Tape));
-	os_scsi_tapes[i] = tpnt;
-	dev = i;
-	tpnt->capacity = 0xfffff;
 
 	/* allocate a buffer for this device */
-	if (!new_tape_buffer(TRUE, TRUE)) 
-		 printk(KERN_ERR "osst :W: Unable to allocate a tape buffer.\n");
-
-#ifdef CONFIG_DEVFS_FS
-	for (mode = 0; mode < ST_NBR_MODES; ++mode) {
-		 char name[8];
-		 static char *formats[ST_NBR_MODES] ={"", "l", "m", "a"};
-
-		 /*  Rewind entry  */
-		 sprintf (name, "mt%s", formats[mode]);
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-		 tpnt->de_r[mode] =
-			devfs_register (SDp->de, name, DEVFS_FL_DEFAULT,
-			   MAJOR_NR, i + (mode << 5),
-			   S_IFCHR | S_IRUGO | S_IWUGO,
-			   &osst_fops, NULL);
-# else
-		 tpnt->de_r[mode] =
-			devfs_register (SDp->de, name, 0, DEVFS_FL_DEFAULT,
-			   MAJOR_NR, i + (mode << 5),
-			   S_IFCHR | S_IRUGO | S_IWUGO,
-			   0, 0, &osst_fops, NULL);
-# endif		
-		 /*  No-rewind entry  */
-		 sprintf (name, "mt%sn", formats[mode]);
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-		 tpnt->de_n[mode] =
-			devfs_register (SDp->de, name, DEVFS_FL_DEFAULT,
-			   MAJOR_NR, i + (mode << 5) + 128,
-			   S_IFCHR | S_IRUGO | S_IWUGO,
-			   &osst_fops, NULL);
-# else		
-		 tpnt->de_n[mode] =
-			devfs_register (SDp->de, name, 0, DEVFS_FL_DEFAULT,
-			   MAJOR_NR, i + (mode << 5) + 128,
-			   S_IFCHR | S_IRUGO | S_IWUGO,
-			   0, 0, &osst_fops, NULL);
-# endif
+	i = SDp->host->sg_tablesize;
+	if (osst_max_sg_segs < i)
+		i = osst_max_sg_segs;
+	buffer = new_tape_buffer(TRUE, SDp->host->unchecked_isa_dma, i);
+	if (buffer == NULL) {
+		write_unlock(&os_scsi_tapes_lock);
+		printk(KERN_ERR "osst :E: Unable to allocate a tape buffer, device not attached.\n");
+		kfree(tpnt);
+		put_disk(drive);
+		scsi_slave_detach(SDp);
+		return 1;
 	}
-	disk->number = devfs_register_tape(SDp->de);
-#endif
-
+	os_scsi_tapes[dev_num] = tpnt;
+	tpnt->buffer = buffer;
 	tpnt->device = SDp;
-	disk->private_data = &tpnt->driver;
-	sprintf(disk->disk_name, "osst%d", i);
+	drive->private_data = &tpnt->driver;
+	sprintf(drive->disk_name, "osst%d", dev_num);
 	tpnt->driver = &osst_template;
-	tpnt->disk = disk;
-	tpnt->dirty = 0;
+	tpnt->drive = drive;
 	tpnt->in_use = 0;
+	tpnt->capacity = 0xfffff;
+	tpnt->dirty = 0;
 	tpnt->drv_buffer = 1;  /* Try buffering if no mode sense */
 	tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
 	tpnt->density = 0;
@@ -5510,7 +5533,8 @@
 	tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev);
 	tpnt->omit_blklims = 1;
 
-	tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp);
+	tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) || 
+		     (strncmp(SDp->model, "FW-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp);
 	tpnt->frame_in_buffer = 0;
 	tpnt->header_ok = 0;
 	tpnt->linux_media = 0;
@@ -5543,9 +5567,56 @@
 	tpnt->modes[0].defined = TRUE;
 	tpnt->modes[2].defined = TRUE;
 	tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = FALSE;
-	init_MUTEX(&tpnt->lock);
 
+	init_MUTEX(&tpnt->lock);
 	osst_nr_dev++;
+	write_unlock(&os_scsi_tapes_lock);
+
+	for (mode = 0; mode < ST_NBR_MODES; ++mode) {
+		char name[8];
+		static char *formats[ST_NBR_MODES] ={"", "l", "m", "a"};
+		
+		/*  Rewind entry  */
+		sprintf (name, "ot%s", formats[mode]);
+		sprintf(tpnt->driverfs_dev_r[mode].bus_id, "%s:%s", 
+				SDp->sdev_driverfs_dev.bus_id, name);
+		sprintf(tpnt->driverfs_dev_r[mode].name, "%s%s", 
+				SDp->sdev_driverfs_dev.name, name);
+		tpnt->driverfs_dev_r[mode].parent = &SDp->sdev_driverfs_dev;
+		tpnt->driverfs_dev_r[mode].bus = SDp->sdev_driverfs_dev.bus;
+		tpnt->driverfs_dev_r[mode].driver_data =
+			(void *)(long)__mkdev(OSST_MAJOR, dev_num + (mode << 5));
+		device_register(&tpnt->driverfs_dev_r[mode]);
+		device_create_file(&tpnt->driverfs_dev_r[mode], 
+				&dev_attr_type);
+		device_create_file(&tpnt->driverfs_dev_r[mode], &dev_attr_kdev);
+		tpnt->de_r[mode] =
+			devfs_register (SDp->de, name, DEVFS_FL_DEFAULT,
+					OSST_MAJOR, dev_num + (mode << 5),
+					S_IFCHR | S_IRUGO | S_IWUGO,
+					&osst_fops, NULL);
+		/*  No-rewind entry  */
+		sprintf (name, "ot%sn", formats[mode]);
+		sprintf(tpnt->driverfs_dev_n[mode].bus_id, "%s:%s", 
+				SDp->sdev_driverfs_dev.bus_id, name);
+		sprintf(tpnt->driverfs_dev_n[mode].name, "%s%s", 
+				SDp->sdev_driverfs_dev.name, name);
+		tpnt->driverfs_dev_n[mode].parent= &SDp->sdev_driverfs_dev;
+		tpnt->driverfs_dev_n[mode].bus = SDp->sdev_driverfs_dev.bus;
+		tpnt->driverfs_dev_n[mode].driver_data =
+			(void *)(long)__mkdev(OSST_MAJOR, dev_num + (mode << 5) + 128);
+		device_register(&tpnt->driverfs_dev_n[mode]);
+		device_create_file(&tpnt->driverfs_dev_n[mode], 
+				&dev_attr_type);
+		device_create_file(&tpnt->driverfs_dev_n[mode], 
+				&dev_attr_kdev);
+		tpnt->de_n[mode] =
+			devfs_register (SDp->de, name, DEVFS_FL_DEFAULT,
+					OSST_MAJOR, dev_num + (mode << 5) + 128,
+					S_IFCHR | S_IRUGO | S_IWUGO,
+					&osst_fops, NULL);
+	}
+	drive->number = devfs_register_tape (SDp->de);
 
 	printk(KERN_INFO
 		"osst :I: Attached OnStream %.5s tape at scsi%d, channel %d, id %d, lun %d as %s\n",
@@ -5554,94 +5625,73 @@
 	return 0;
 };
 
-static int osst_registered = 0;
-
-/* Driver initialization (not __initfunc because may be called later) */
-static int osst_init()
-{
-	int i;
-
-	if (!osst_registered) {
-		if (register_chrdev(MAJOR_NR,"osst",&osst_fops)) {
-			printk(KERN_ERR "osst :W: Unable to get major %d for OnStream tapes\n",MAJOR_NR);
-			return 1;
-		}
-		osst_registered++;
-	}
-
-	if (os_scsi_tapes)
-		return 0;
-	osst_dev_max = OSST_MAX_TAPES;
-	if (osst_dev_max > 128 / ST_NBR_MODES)
-		printk(KERN_INFO "osst :I: Only %d tapes accessible.\n", 128 / ST_NBR_MODES);
-	os_scsi_tapes = kmalloc(osst_dev_max * sizeof(OS_Scsi_Tape *),
-								GFP_ATOMIC);
-	if (!os_scsi_tapes) {
-		printk(KERN_ERR "osst :W: Unable to allocate array for OnStream SCSI tapes.\n");
-		unregister_chrdev(MAJOR_NR, "osst");
-		return 1;
-	}
-
-	for (i=0; i < osst_dev_max; ++i)
-		os_scsi_tapes[i] = NULL;
-
-	/* Allocate the buffer pointers */
-	osst_buffers = kmalloc(osst_dev_max * sizeof(OSST_buffer *),
-								GFP_ATOMIC);
-	if (!osst_buffers) {
-		printk(KERN_ERR "osst :W: Unable to allocate tape buffer pointers.\n");
-		unregister_chrdev(MAJOR_NR, "osst");
-		kfree(os_scsi_tapes);
-		return 1;
-	}
-	osst_nbr_buffers = 0;
-
-	printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
-
-#if DEBUG
-	printk(OSST_DEB_MSG "osst :D: Buffer size %d bytes, write threshold %d bytes.\n",
-			osst_buffer_size, osst_write_threshold);
-#endif
-	return 0;
-}
-
-
 static void osst_detach(Scsi_Device * SDp)
 {
   OS_Scsi_Tape * tpnt;
-  int i;
-#ifdef CONFIG_DEVFS_FS
-  int mode;
-#endif
-
-  for(i=0; i<osst_dev_max; i++) {
-	tpnt = os_scsi_tapes[i];
-	if(tpnt != NULL && tpnt->device == SDp) {
-		tpnt->device = NULL;
-#ifdef CONFIG_DEVFS_FS
-		for (mode = 0; mode < ST_NBR_MODES; ++mode) {
-			devfs_unregister (tpnt->de_r[mode]);
-			tpnt->de_r[mode] = NULL;
-			devfs_unregister (tpnt->de_n[mode]);
-			tpnt->de_n[mode] = NULL;
+  int i, mode;
+
+  write_lock(&os_scsi_tapes_lock);
+  if (os_scsi_tapes != NULL) {
+	  for(i=0; i<osst_max_dev; i++) {
+		tpnt = os_scsi_tapes[i];
+		if(tpnt != NULL && tpnt->device == SDp) {
+			tpnt->device = NULL;
+			for (mode = 0; mode < ST_NBR_MODES; ++mode) {
+				devfs_unregister (tpnt->de_r[mode]);
+				tpnt->de_r[mode] = NULL;
+				devfs_unregister (tpnt->de_n[mode]);
+				tpnt->de_n[mode] = NULL;
+			}
+			devfs_unregister_tape(tpnt->drive->number);
+			put_disk(tpnt->drive);
+			os_scsi_tapes[i] = NULL;
+			scsi_slave_detach(SDp);
+			osst_nr_dev--;
+			write_unlock(&os_scsi_tapes_lock);
+			for (mode = 0; mode < ST_NBR_MODES; ++mode) {
+				device_remove_file(&tpnt->driverfs_dev_r[mode],
+						&dev_attr_type);
+				device_remove_file(&tpnt->driverfs_dev_r[mode],
+						&dev_attr_kdev);
+				device_unregister(&tpnt->driverfs_dev_r[mode]);
+				device_remove_file(&tpnt->driverfs_dev_n[mode],
+						&dev_attr_type);
+				device_remove_file(&tpnt->driverfs_dev_n[mode],
+						&dev_attr_kdev);
+				device_unregister(&tpnt->driverfs_dev_n[mode]);
+			}
+			if (tpnt->header_cache != NULL)
+				vfree(tpnt->header_cache);
+			if (tpnt->buffer) {
+				normalize_buffer(tpnt->buffer);
+				kfree(tpnt->buffer);
+			}
+			kfree(tpnt);
+			break;
 		}
-		devfs_unregister_tape(tpnt->disk->number);
-#endif
-		put_disk(tpnt->disk);
-		kfree(tpnt);
-		os_scsi_tapes[i] = NULL;
-		scsi_slave_detach(SDp);
-		osst_nr_dev--;
-		return;
-	}
+	  }
   }
+
+  write_unlock(&os_scsi_tapes_lock);
   return;
 }
 
 static int __init init_osst(void) 
 {
+	printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
+
 	validate_options();
-	return scsi_register_device(&osst_template);
+#if DEBUG
+	 printk(OSST_DEB_MSG "osst :D: %d s/g segments, write threshold %d bytes.\n",
+			 max_sg_segs, osst_write_threshold);
+#endif
+	if ((register_chrdev(OSST_MAJOR, "osst", &osst_fops) < 0) ||
+			scsi_register_device(&osst_template)) {
+		printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
+		return 1;
+	}
+
+	return 0;
 }
 
 static void __exit exit_osst (void)
@@ -5650,32 +5700,23 @@
 	OS_Scsi_Tape * STp;
 
 	scsi_unregister_device(&osst_template);
-	unregister_chrdev(MAJOR_NR, "osst");
-	osst_registered--;
+	unregister_chrdev(OSST_MAJOR, "osst");
+
 	if (os_scsi_tapes) {
-		for (i=0; i < osst_dev_max; ++i) {
-			STp = os_scsi_tapes[i];
-			if (!STp)
-				continue;
+		for (i=0; i < osst_max_dev; ++i) {
+			if (!(STp = os_scsi_tapes[i])) continue;
+			/* This is defensive, supposed to happen during detach */
 			if (STp->header_cache)
 				vfree(STp->header_cache);
-			put_disk(STp->disk);
+			if (STp->buffer) {
+				normalize_buffer(STp->buffer);
+				kfree(STp->buffer);
+			}
+			put_disk(STp->drive);
 			kfree(STp);
 		}
 		kfree(os_scsi_tapes);
-
-		if (osst_buffers) {
-			for (i=0; i < osst_nbr_buffers; i++) {
-				if (osst_buffers[i]) {
-					osst_buffers[i]->orig_sg_segs = 0;
-					normalize_buffer(osst_buffers[i]);
-					kfree(osst_buffers[i]);
-				}
-			}
-			kfree(osst_buffers);
-		}
 	}
-	osst_dev_max = 0;
 	printk(KERN_INFO "osst :I: Unloaded.\n");
 }
 
diff -Nru a/drivers/scsi/osst.h b/drivers/scsi/osst.h
--- a/drivers/scsi/osst.h	Mon Dec  9 18:46:49 2002
+++ b/drivers/scsi/osst.h	Mon Dec  9 18:46:49 2002
@@ -510,7 +510,7 @@
 #define OS_AUX_SIZE     (512)
 //#define OSST_MAX_SG      2
 
-/* The tape buffer descriptor. */
+/* The OnStream tape buffer descriptor. */
 typedef struct {
   unsigned char in_use;
   unsigned char dma;	/* DMA-able buffer */
@@ -523,14 +523,14 @@
   int syscall_result;
   Scsi_Request *last_SRpnt;
   unsigned char *b_data;
-  os_aux_t *aux;               /* onstream AUX structure at end of each block */
-  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 */
-  struct scatterlist sg[1];    /* MUST BE last item */
+  os_aux_t *aux;               /* onstream AUX structure at end of each block     */
+  unsigned short use_sg;       /* zero or number of s/g segments for this adapter */
+  unsigned short sg_segs;      /* number of segments in s/g list                  */
+  unsigned short orig_sg_segs; /* number of segments allocated at first try       */
+  struct scatterlist sg[1];    /* MUST BE last item                               */
 } OSST_buffer;
 
-/* The tape drive descriptor */
+/* The OnStream tape drive descriptor */
 typedef struct {
   struct Scsi_Device_Template *driver;
   unsigned capacity;
@@ -549,6 +549,7 @@
   unsigned char restr_dma;
   unsigned char scsi2_logical;
   unsigned char default_drvbuffer;  /* 0xff = don't touch, value 3 bits */
+  unsigned char pos_unknown;        /* after reset position unknown */
   int write_threshold;
   int timeout;			/* timeout for normal commands */
   int long_timeout;		/* timeout for commands known to take long time*/
@@ -556,10 +557,10 @@
   /* Mode characteristics */
   ST_mode modes[ST_NBR_MODES];
   int current_mode;
-#ifdef CONFIG_DEVFS_FS
   devfs_handle_t de_r[ST_NBR_MODES];  /*  Rewind entries     */
   devfs_handle_t de_n[ST_NBR_MODES];  /*  No-rewind entries  */
-#endif
+  struct device driverfs_dev_r[ST_NBR_MODES];
+  struct device driverfs_dev_n[ST_NBR_MODES];
 
   /* Status variables */
   int partition;
@@ -628,7 +629,7 @@
   unsigned char last_cmnd[6];
   unsigned char last_sense[16];
 #endif
-  struct gendisk *disk;
+  struct gendisk *drive;
 } OS_Scsi_Tape;
 
 /* Values of write_type */
diff -Nru a/drivers/scsi/pci2000.c b/drivers/scsi/pci2000.c
--- a/drivers/scsi/pci2000.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/scsi/pci2000.c	Mon Dec  9 18:46:50 2002
@@ -35,8 +35,9 @@
  ****************************************************************************/
 #define PCI2000_VERSION		"1.20"
 
+#include <linux/blk.h>
+#include <linux/interrupt.h>
 #include <linux/module.h>
-
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/string.h>
@@ -45,15 +46,15 @@
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
+#include <linux/stat.h>
+#include <linux/spinlock.h>
+
 #include <asm/dma.h>
 #include <asm/system.h>
 #include <asm/io.h>
-#include <linux/blk.h>
+
 #include "scsi.h"
 #include "hosts.h"
-#include <linux/stat.h>
-#include <linux/spinlock.h>
-
 #include "pci2000.h"
 #include "psi_roy.h"
 
diff -Nru a/drivers/scsi/pci2220i.c b/drivers/scsi/pci2220i.c
--- a/drivers/scsi/pci2220i.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/scsi/pci2220i.c	Mon Dec  9 18:46:34 2002
@@ -38,6 +38,7 @@
 
 //#define DEBUG 1
 
+#include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -52,9 +53,11 @@
 #include <linux/blk.h>
 #include <linux/timer.h>
 #include <linux/spinlock.h>
+
 #include <asm/dma.h>
 #include <asm/system.h>
 #include <asm/io.h>
+
 #include "scsi.h"
 #include "hosts.h"
 #include "pci2220i.h"
diff -Nru a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
--- a/drivers/scsi/pcmcia/fdomain_stub.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/scsi/pcmcia/fdomain_stub.c	Mon Dec  9 18:46:38 2002
@@ -92,7 +92,8 @@
 static dev_link_t *fdomain_attach(void);
 static void fdomain_detach(dev_link_t *);
 
-static Scsi_Host_Template driver_template = FDOMAIN_16X0;
+#define driver_template fdomain_driver_template
+extern Scsi_Host_Template fdomain_driver_template;
 
 static dev_link_t *dev_list = NULL;
 
diff -Nru a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
--- a/drivers/scsi/pcmcia/qlogic_stub.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/scsi/pcmcia/qlogic_stub.c	Mon Dec  9 18:46:38 2002
@@ -50,8 +50,6 @@
 
 #include <../drivers/scsi/qlogicfas.h>
 
-#define qlogic_reset(h) qlogicfas_reset(h, 0)
-
 #include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
@@ -65,8 +63,7 @@
 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 =
-"qlogic_cs.c 1.79 2000/06/12 21:27:26 (David Hinds)";
+static char *version = "qlogic_cs.c 1.79-ac 2002/10/26 (David Hinds)";
 #else
 #define DEBUG(n, args...)
 #endif
@@ -76,7 +73,7 @@
 /* Parameters that can be set with 'insmod' */
 
 /* Bit map of interrupts to choose from */
-static u_int irq_mask = 0xdeb8;
+static unsigned int irq_mask = 0xdeb8;
 static int irq_list[4] = { -1 };
 
 MODULE_PARM(irq_mask, "i");
@@ -85,20 +82,21 @@
 /*====================================================================*/
 
 typedef struct scsi_info_t {
-    dev_link_t		link;
-    u_short		manf_id;
-    int			ndev;
-    dev_node_t		node[8];
+	dev_link_t link;
+	unsigned short manf_id;
+	int ndev;
+	dev_node_t node[8];
 } scsi_info_t;
 
 static void qlogic_release(u_long arg);
-static int qlogic_event(event_t event, int priority,
-			event_callback_args_t *args);
+static int qlogic_event(event_t event, int priority, event_callback_args_t * args);
 
 static dev_link_t *qlogic_attach(void);
 static void qlogic_detach(dev_link_t *);
 
-static Scsi_Host_Template driver_template = QLOGICFAS;
+/* Import our driver template */
+extern Scsi_Host_Template qlogicfas_driver_template;
+#define driver_template qlogicfas_driver_template
 
 static dev_link_t *dev_list = NULL;
 
@@ -108,97 +106,97 @@
 
 static void cs_error(client_handle_t handle, int func, int ret)
 {
-    error_info_t err = { func, ret };
-    CardServices(ReportError, handle, &err);
+	error_info_t err = { func, ret };
+	CardServices(ReportError, handle, &err);
 }
 
 /*====================================================================*/
 
 static dev_link_t *qlogic_attach(void)
 {
-    scsi_info_t *info;
-    client_reg_t client_reg;
-    dev_link_t *link;
-    int i, ret;
-    
-    DEBUG(0, "qlogic_attach()\n");
-
-    /* Create new SCSI 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 = &qlogic_release;
-    link->release.data = (u_long)link;
-
-    link->io.NumPorts1 = 16;
-    link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-    link->io.IOAddrLines = 10;
-    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;
-    link->conf.IntType = INT_MEMORY_AND_IO;
-    link->conf.Present = PRESENT_OPTION;
-
-    /* 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.event_handler = &qlogic_event;
-    client_reg.EventMask =
-	CS_EVENT_RESET_REQUEST | CS_EVENT_CARD_RESET |
-	CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-	CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = CardServices(RegisterClient, &link->handle, &client_reg);
-    if (ret != 0) {
-	cs_error(link->handle, RegisterClient, ret);
-	qlogic_detach(link);
-	return NULL;
-    }
-    
-    return link;
-} /* qlogic_attach */
+	scsi_info_t *info;
+	client_reg_t client_reg;
+	dev_link_t *link;
+	int i, ret;
+
+	DEBUG(0, "qlogic_attach()\n");
+
+	/* Create new SCSI 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 = &qlogic_release;
+	link->release.data = (u_long) link;
+
+	link->io.NumPorts1 = 16;
+	link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+	link->io.IOAddrLines = 10;
+	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;
+	link->conf.IntType = INT_MEMORY_AND_IO;
+	link->conf.Present = PRESENT_OPTION;
+
+	/* 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.event_handler = &qlogic_event;
+	client_reg.EventMask = CS_EVENT_RESET_REQUEST | CS_EVENT_CARD_RESET | CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
+	client_reg.Version = 0x0210;
+	client_reg.event_callback_args.client_data = link;
+	ret = CardServices(RegisterClient, &link->handle, &client_reg);
+	if (ret != 0) {
+		cs_error(link->handle, RegisterClient, ret);
+		qlogic_detach(link);
+		return NULL;
+	}
+
+	return link;
+}				/* qlogic_attach */
 
 /*====================================================================*/
 
-static void qlogic_detach(dev_link_t *link)
+static void qlogic_detach(dev_link_t * link)
 {
-    dev_link_t **linkp;
+	dev_link_t **linkp;
 
-    DEBUG(0, "qlogic_detach(0x%p)\n", link);
-    
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-	if (*linkp == link) break;
-    if (*linkp == NULL)
-	return;
+	DEBUG(0, "qlogic_detach(0x%p)\n", link);
 
-    del_timer(&link->release);
-    if (link->state & DEV_CONFIG) {
-	qlogic_release((u_long)link);
-	if (link->state & DEV_STALE_CONFIG) {
-	    link->state |= DEV_STALE_LINK;
-	    return;
+	/* Locate device structure */
+	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+		if (*linkp == link)
+			break;
+	if (*linkp == NULL)
+		return;
+
+	del_timer_sync(&link->release);
+	if (link->state & DEV_CONFIG) {
+		qlogic_release((u_long) link);
+		if (link->state & DEV_STALE_CONFIG) {
+			link->state |= DEV_STALE_LINK;
+			return;
+		}
 	}
-    }
 
-    if (link->handle)
-	CardServices(DeregisterClient, link->handle);
-    
-    /* Unlink device structure, free bits */
-    *linkp = link->next;
-    kfree(link->priv);
-    
-} /* qlogic_detach */
+	if (link->handle)
+		CardServices(DeregisterClient, link->handle);
+
+	/* Unlink device structure, free bits */
+	*linkp = link->next;
+	kfree(link->priv);
+
+}				/* qlogic_detach */
 
 /*====================================================================*/
 
@@ -208,220 +206,216 @@
 #define CFG_CHECK(fn, args...) \
 if (CardServices(fn, args) != 0) goto next_entry
 
-static void qlogic_config(dev_link_t *link)
+static void qlogic_config(dev_link_t * link)
 {
-    client_handle_t handle = link->handle;
-    scsi_info_t *info = link->priv;
-    tuple_t tuple;
-    cisparse_t parse;
-    int i, last_ret, last_fn;
-    u_short tuple_data[32];
-    Scsi_Device *dev;
-    dev_node_t **tail, *node;
-    struct Scsi_Host *host;
-
-    DEBUG(0, "qlogic_config(0x%p)\n", link);
-
-    tuple.TupleData = (cisdata_t *)tuple_data;
-    tuple.TupleDataMax = 64;
-    tuple.TupleOffset = 0;
-    tuple.DesiredTuple = CISTPL_CONFIG;
-    CS_CHECK(GetFirstTuple, handle, &tuple);
-    CS_CHECK(GetTupleData, handle, &tuple);
-    CS_CHECK(ParseTuple, handle, &tuple, &parse);
-    link->conf.ConfigBase = parse.config.base;
-    
-    tuple.DesiredTuple = CISTPL_MANFID;
-    if ((CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS) &&
-	(CardServices(GetTupleData, handle, &tuple) == CS_SUCCESS))
-	info->manf_id = le16_to_cpu(tuple.TupleData[0]);
-
-    /* Configure card */
-    driver_template.module = &__this_module;
-    link->state |= DEV_CONFIG;
-
-    tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-    CS_CHECK(GetFirstTuple, handle, &tuple);
-    while (1) {
-	CFG_CHECK(GetTupleData, handle, &tuple);
-	CFG_CHECK(ParseTuple, handle, &tuple, &parse);
-	link->conf.ConfigIndex = parse.cftable_entry.index;
-	link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
-	link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
-	if (link->io.BasePort1 != 0) {
-	    i = CardServices(RequestIO, handle, &link->io);
-	    if (i == CS_SUCCESS) break;
+	client_handle_t handle = link->handle;
+	scsi_info_t *info = link->priv;
+	tuple_t tuple;
+	cisparse_t parse;
+	int i, last_ret, last_fn;
+	unsigned short tuple_data[32];
+	Scsi_Device *dev;
+	dev_node_t **tail, *node;
+	struct Scsi_Host *host;
+
+	DEBUG(0, "qlogic_config(0x%p)\n", link);
+
+	tuple.TupleData = (cisdata_t *) tuple_data;
+	tuple.TupleDataMax = 64;
+	tuple.TupleOffset = 0;
+	tuple.DesiredTuple = CISTPL_CONFIG;
+	CS_CHECK(GetFirstTuple, handle, &tuple);
+	CS_CHECK(GetTupleData, handle, &tuple);
+	CS_CHECK(ParseTuple, handle, &tuple, &parse);
+	link->conf.ConfigBase = parse.config.base;
+
+	tuple.DesiredTuple = CISTPL_MANFID;
+	if ((CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS) && (CardServices(GetTupleData, handle, &tuple) == CS_SUCCESS))
+		info->manf_id = le16_to_cpu(tuple.TupleData[0]);
+
+	/* Configure card */
+	driver_template.module = &__this_module;
+	link->state |= DEV_CONFIG;
+
+	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+	CS_CHECK(GetFirstTuple, handle, &tuple);
+	while (1) {
+		CFG_CHECK(GetTupleData, handle, &tuple);
+		CFG_CHECK(ParseTuple, handle, &tuple, &parse);
+		link->conf.ConfigIndex = parse.cftable_entry.index;
+		link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
+		link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
+		if (link->io.BasePort1 != 0) {
+			i = CardServices(RequestIO, handle, &link->io);
+			if (i == CS_SUCCESS)
+				break;
+		}
+	      next_entry:
+		CS_CHECK(GetNextTuple, handle, &tuple);
 	}
-    next_entry:
-	CS_CHECK(GetNextTuple, handle, &tuple);
-    }
-    
-    CS_CHECK(RequestIRQ, handle, &link->irq);
-    CS_CHECK(RequestConfiguration, handle, &link->conf);
-
-    if ((info->manf_id == MANFID_MACNICA) ||
-	(info->manf_id == MANFID_PIONEER) ||
-	(info->manf_id == 0x0098)) {
-	/* set ATAcmd */
-	outb(0xb4, link->io.BasePort1+0xd);
-	outb(0x24, link->io.BasePort1+0x9);
-	outb(0x04, link->io.BasePort1+0xd);
-    }
-
-    /* A bad hack... */
-    release_region(link->io.BasePort1, link->io.NumPorts1);
-
-    /* The KXL-810AN has a bigger IO port window */
-    if (link->io.NumPorts1 == 32)
-	qlogicfas_preset(link->io.BasePort1+16, link->irq.AssignedIRQ);
-    else
-	qlogicfas_preset(link->io.BasePort1, link->irq.AssignedIRQ);
-    
-    scsi_register_host(&driver_template);
-
-    tail = &link->dev;
-    info->ndev = 0;
-	for (host = scsi_host_get_next(NULL); host;
-	     host = scsi_host_get_next(host))
-	if (host->hostt == &driver_template)
-	    list_for_each_entry (dev, &host->my_devices, siblings) {
-	    u_long arg[2], id;
-	    kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg);
-	    id = (arg[0]&0x0f) + ((arg[0]>>4)&0xf0) +
-		((arg[0]>>8)&0xf00) + ((arg[0]>>12)&0xf000);
-	    node = &info->node[info->ndev];
-	    node->minor = 0;
-	    switch (dev->type) {
-	    case TYPE_TAPE:
-		node->major = SCSI_TAPE_MAJOR;
-		sprintf(node->dev_name, "st#%04lx", id);
-		break;
-	    case TYPE_DISK:
-	    case TYPE_MOD:
-		node->major = SCSI_DISK0_MAJOR;
-		sprintf(node->dev_name, "sd#%04lx", id);
-		break;
-	    case TYPE_ROM:
-	    case TYPE_WORM:
-		node->major = SCSI_CDROM_MAJOR;
-		sprintf(node->dev_name, "sr#%04lx", id);
-		break;
-	    default:
-		node->major = SCSI_GENERIC_MAJOR;
-		sprintf(node->dev_name, "sg#%04lx", id);
-		break;
-	    }
-	    *tail = node; tail = &node->next;
-	    info->ndev++;
+
+	CS_CHECK(RequestIRQ, handle, &link->irq);
+	CS_CHECK(RequestConfiguration, handle, &link->conf);
+
+	if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) {
+		/* set ATAcmd */
+		outb(0xb4, link->io.BasePort1 + 0xd);
+		outb(0x24, link->io.BasePort1 + 0x9);
+		outb(0x04, link->io.BasePort1 + 0xd);
 	}
-    *tail = NULL;
-    if (info->ndev == 0)
-	printk(KERN_INFO "qlogic_cs: no SCSI devices found\n");
-    
-    link->state &= ~DEV_CONFIG_PENDING;
-    return;
+
+	/* A bad hack... */
+	release_region(link->io.BasePort1, link->io.NumPorts1);
+
+	/* The KXL-810AN has a bigger IO port window */
+	if (link->io.NumPorts1 == 32)
+		qlogicfas_preset(link->io.BasePort1 + 16, link->irq.AssignedIRQ);
+	else
+		qlogicfas_preset(link->io.BasePort1, link->irq.AssignedIRQ);
+
+	scsi_register_host(&driver_template);
+
+	tail = &link->dev;
+	info->ndev = 0;
+	for (host = scsi_host_get_next(NULL); host; host = scsi_host_get_next(host))
+		if (host->hostt == &driver_template)
+			list_for_each_entry (dev, &host->my_devices, siblings) {
+				u_long arg[2], id;
+				kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg);
+				id = (arg[0] & 0x0f) + ((arg[0] >> 4) & 0xf0) + ((arg[0] >> 8) & 0xf00) + ((arg[0] >> 12) & 0xf000);
+				node = &info->node[info->ndev];
+				node->minor = 0;
+				switch (dev->type) {
+				case TYPE_TAPE:
+					node->major = SCSI_TAPE_MAJOR;
+					sprintf(node->dev_name, "st#%04lx", id);
+					break;
+				case TYPE_DISK:
+				case TYPE_MOD:
+					node->major = SCSI_DISK0_MAJOR;
+					sprintf(node->dev_name, "sd#%04lx", id);
+					break;
+				case TYPE_ROM:
+				case TYPE_WORM:
+					node->major = SCSI_CDROM_MAJOR;
+					sprintf(node->dev_name, "sr#%04lx", id);
+					break;
+				default:
+					node->major = SCSI_GENERIC_MAJOR;
+					sprintf(node->dev_name, "sg#%04lx", id);
+					break;
+				}
+				*tail = node;
+				tail = &node->next;
+				info->ndev++;
+			}
+	*tail = NULL;
+	if (info->ndev == 0)
+		printk(KERN_INFO "qlogic_cs: no SCSI devices found\n");
+
+	link->state &= ~DEV_CONFIG_PENDING;
+	return;
 
 cs_failed:
-    cs_error(link->handle, last_fn, last_ret);
-    qlogic_release((u_long)link);
-    return;
+	cs_error(link->handle, last_fn, last_ret);
+	qlogic_release((u_long) link);
+	return;
 
-} /* qlogic_config */
+}				/* qlogic_config */
 
 /*====================================================================*/
 
 static void qlogic_release(u_long arg)
 {
-    dev_link_t *link = (dev_link_t *)arg;
+	dev_link_t *link = (dev_link_t *) arg;
 
-    DEBUG(0, "qlogic_release(0x%p)\n", link);
+	DEBUG(0, "qlogic_release(0x%p)\n", link);
 
-    if (GET_USE_COUNT(&__this_module) != 0) {
-	DEBUG(0, "qlogic_cs: release postponed, device still open\n");
-	link->state |= DEV_STALE_CONFIG;
-	return;
-    }
+	if (GET_USE_COUNT(&__this_module) != 0) {
+		DEBUG(0, "qlogic_cs: release postponed, device still open\n");
+		link->state |= DEV_STALE_CONFIG;
+		return;
+	}
+
+	scsi_unregister_host(&driver_template);
+	link->dev = NULL;
 
-    scsi_unregister_host(&driver_template);
-    link->dev = NULL;
-    
-    CardServices(ReleaseConfiguration, link->handle);
-    CardServices(ReleaseIO, link->handle, &link->io);
-    CardServices(ReleaseIRQ, link->handle, &link->irq);
-    
-    link->state &= ~DEV_CONFIG;
-    if (link->state & DEV_STALE_LINK)
-	qlogic_detach(link);
-    
-} /* qlogic_release */
+	CardServices(ReleaseConfiguration, link->handle);
+	CardServices(ReleaseIO, link->handle, &link->io);
+	CardServices(ReleaseIRQ, link->handle, &link->irq);
+
+	link->state &= ~DEV_CONFIG;
+	if (link->state & DEV_STALE_LINK)
+		qlogic_detach(link);
+
+}				/* qlogic_release */
 
 /*====================================================================*/
 
-static int qlogic_event(event_t event, int priority,
-			event_callback_args_t *args)
+static int qlogic_event(event_t event, int priority, event_callback_args_t * args)
 {
-    dev_link_t *link = args->client_data;
+	dev_link_t *link = args->client_data;
 
-    DEBUG(1, "qlogic_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;
-	qlogic_config(link);
-	break;
-    case CS_EVENT_PM_SUSPEND:
-	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-	if (link->state & DEV_CONFIG)
-	    CardServices(ReleaseConfiguration, link->handle);
-	break;
-    case CS_EVENT_PM_RESUME:
-	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
-	if (link->state & DEV_CONFIG) {
-	    scsi_info_t *info = link->priv;
-	    CardServices(RequestConfiguration, link->handle, &link->conf);
-	    if ((info->manf_id == MANFID_MACNICA) ||
-		(info->manf_id == MANFID_PIONEER) ||
-		(info->manf_id == 0x0098)) {
-		outb( 0x80, link->io.BasePort1+0xd);
-		outb( 0x24, link->io.BasePort1+0x9);
-		outb( 0x04, link->io.BasePort1+0xd);
-	    }
-	    qlogic_reset(NULL);
+	DEBUG(1, "qlogic_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;
+		qlogic_config(link);
+		break;
+	case CS_EVENT_PM_SUSPEND:
+		link->state |= DEV_SUSPEND;
+		/* Fall through... */
+	case CS_EVENT_RESET_PHYSICAL:
+		if (link->state & DEV_CONFIG)
+			CardServices(ReleaseConfiguration, link->handle);
+		break;
+	case CS_EVENT_PM_RESUME:
+		link->state &= ~DEV_SUSPEND;
+		/* Fall through... */
+	case CS_EVENT_CARD_RESET:
+		if (link->state & DEV_CONFIG) {
+			scsi_info_t *info = link->priv;
+			CardServices(RequestConfiguration, link->handle, &link->conf);
+			if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) {
+				outb(0x80, link->io.BasePort1 + 0xd);
+				outb(0x24, link->io.BasePort1 + 0x9);
+				outb(0x04, link->io.BasePort1 + 0xd);
+			}
+			/* Ugggglllyyyy!!! */
+			driver_template.eh_bus_reset_handler(NULL);
+		}
+		break;
 	}
-	break;
-    }
-    return 0;
-} /* qlogic_event */
+	return 0;
+}				/* qlogic_event */
 
 /*====================================================================*/
 
-static int __init init_qlogic_cs(void) {
-    servinfo_t serv;
-    DEBUG(0, "%s\n", version);
-    CardServices(GetCardServicesInfo, &serv);
-    if (serv.Revision != CS_RELEASE_CODE) {
-	printk(KERN_NOTICE "qlogic_cs: Card Services release "
-	       "does not match!\n");
-	return -1;
-    }
-    register_pccard_driver(&dev_info, &qlogic_attach, &qlogic_detach);
-    return 0;
+static int __init init_qlogic_cs(void)
+{
+	servinfo_t serv;
+	DEBUG(0, "%s\n", version);
+	CardServices(GetCardServicesInfo, &serv);
+	if (serv.Revision != CS_RELEASE_CODE) {
+		printk(KERN_NOTICE "qlogic_cs: Card Services release " "does not match!\n");
+		return -1;
+	}
+	register_pccard_driver(&dev_info, &qlogic_attach, &qlogic_detach);
+	return 0;
 }
 
-static void __exit exit_qlogic_cs(void) {
-    DEBUG(0, "qlogic_cs: unloading\n");
-    unregister_pccard_driver(&dev_info);
-    while (dev_list != NULL)
-	qlogic_detach(dev_list);
+static void __exit exit_qlogic_cs(void)
+{
+	DEBUG(0, "qlogic_cs: unloading\n");
+	unregister_pccard_driver(&dev_info);
+	while (dev_list != NULL)
+		qlogic_detach(dev_list);
 }
 
 module_init(init_qlogic_cs);
diff -Nru a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
--- a/drivers/scsi/scsi.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/scsi/scsi.c	Mon Dec  9 18:46:37 2002
@@ -55,7 +55,6 @@
 #include <linux/init.h>
 #include <linux/smp_lock.h>
 #include <linux/completion.h>
-#include <linux/mempool.h>
 
 #define __KERNEL_SYSCALLS__
 
@@ -74,24 +73,6 @@
 #include <linux/kmod.h>
 #endif
 
-#define SG_MEMPOOL_NR		5
-#define SG_MEMPOOL_SIZE		32
-
-struct scsi_host_sg_pool {
-	int size;
-	char *name; 
-	kmem_cache_t *slab;
-	mempool_t *pool;
-};
-
-#define SP(x) { x, "sgpool-" #x } 
-struct scsi_host_sg_pool scsi_sg_pools[SG_MEMPOOL_NR] = { 
-	SP(8), SP(16), SP(32), SP(64), SP(MAX_PHYS_SEGMENTS)
-}; 	
-#undef SP 	
-/*
-   static const char RCSid[] = "$Header: /vger/u4/cvs/linux/drivers/scsi/scsi.c,v 1.38 1997/01/19 23:07:18 davem Exp $";
- */
 
 /*
  * Definitions and constants.
@@ -169,30 +150,13 @@
 /*
  * Function:    scsi_initialize_queue()
  *
- * Purpose:     Selects queue handler function for a device.
+ * Purpose:     Sets up the block queue for a device.
  *
  * Arguments:   SDpnt   - device for which we need a handler function.
  *
  * Returns:     Nothing
  *
  * Lock status: No locking assumed or required.
- *
- * Notes:       Most devices will end up using scsi_request_fn for the
- *              handler function (at least as things are done now).
- *              The "block" feature basically ensures that only one of
- *              the blocked hosts is active at one time, mainly to work around
- *              buggy DMA chipsets where the memory gets starved.
- *              For this case, we have a special handler function, which
- *              does some checks and ultimately calls scsi_request_fn.
- *
- *              The single_lun feature is a similar special case.
- *
- *              We handle these things by stacking the handlers.  The
- *              special case handlers simply check a few conditions,
- *              and return if they are not supposed to do anything.
- *              In the event that things are OK, then they call the next
- *              handler in the list - ultimately they call scsi_request_fn
- *              to do the dirty deed.
  */
 void  scsi_initialize_queue(Scsi_Device * SDpnt, struct Scsi_Host * SHpnt)
 {
@@ -685,10 +649,7 @@
  */
 void scsi_release_command(Scsi_Cmnd * SCpnt)
 {
-        request_queue_t *q;
-        Scsi_Device * SDpnt;
-
-        SDpnt = SCpnt->device;
+        request_queue_t *q = &SCpnt->device->request_queue;
 
         __scsi_release_command(SCpnt);
 
@@ -698,7 +659,6 @@
          * This won't block - if the device cannot take any more, life
          * will go on.  
          */
-        q = &SDpnt->request_queue;
         scsi_queue_next_request(q, NULL);                
 }
 
@@ -793,7 +753,6 @@
 			rtn = host->hostt->queuecommand(SCpnt, scsi_done);
 			spin_unlock_irqrestore(host->host_lock, flags);
 			if (rtn != 0) {
-				scsi_delete_timer(SCpnt);
 				scsi_mlqueue_insert(SCpnt, rtn == SCSI_MLQUEUE_DEVICE_BUSY ? rtn : SCSI_MLQUEUE_HOST_BUSY);
 				SCSI_LOG_MLQUEUE(3,
 				   printk("queuecommand : request rejected\n"));                                
@@ -832,8 +791,6 @@
 	return rtn;
 }
 
-devfs_handle_t scsi_devfs_handle;
-
 /*
  * scsi_do_cmd sends all the commands out to the low-level driver.  It
  * handles the specifics required for each low level driver - ie queued
@@ -1895,20 +1852,12 @@
 	struct Scsi_Device_Template *sdt;
 
 	down_read(&scsi_devicelist_mutex);
-	list_for_each_entry(sdt, &scsi_devicelist, list)
-		if (sdt->attach) {
-			/*
-			 * XXX check result when the upper level attach
-			 * return values are fixed, and on failure goto
-			 * fail.
-			 */
-			if(try_module_get(sdt->module)) {
-				(*sdt->attach)(sdev);
-				module_put(sdt->module);
-			} else {
-				printk(KERN_WARNING "SCSI module %s not ready, skipping attach.\n", sdt->name);
-			}
-		}
+	list_for_each_entry(sdt, &scsi_devicelist, list) {
+		if (!try_module_get(sdt->module))
+			continue;
+		(*sdt->attach)(sdev);
+		module_put(sdt->module);
+	}
 	up_read(&scsi_devicelist_mutex);
 	return 0;
 }
@@ -1918,18 +1867,30 @@
 	struct Scsi_Device_Template *sdt;
 
 	down_read(&scsi_devicelist_mutex);
-	list_for_each_entry(sdt, &scsi_devicelist, list)
-		if (sdt->detach) {
-			if(try_module_get(sdt->module)) {
-				(*sdt->detach)(sdev);
-				module_put(sdt->module);
-			} else {
-				printk(KERN_WARNING "SCSI module %s not ready, skipping detach.\n", sdt->name);
-			}
-		}
+	list_for_each_entry(sdt, &scsi_devicelist, list) {
+		if (!try_module_get(sdt->module))
+			continue;
+		(*sdt->detach)(sdev);
+		module_put(sdt->module);
+	}
 	up_read(&scsi_devicelist_mutex);
 }
 
+int scsi_device_get(struct scsi_device *sdev)
+{
+	if (!try_module_get(sdev->host->hostt->module))
+		return -ENXIO;
+
+	sdev->access_count++;
+	return 0;
+}
+
+void scsi_device_put(struct scsi_device *sdev)
+{
+	sdev->access_count--;
+	module_put(sdev->host->hostt->module);
+}
+
 /*
  * Function:	scsi_slave_attach()
  *
@@ -1953,7 +1914,7 @@
 			printk(KERN_ERR "scsi: Allocation failure during"
 			       " attach, some SCSI devices might not be"
 			       " configured\n");
-			return 1;
+			return -ENOMEM;
 		}
 		if (sdev->host->hostt->slave_configure != NULL) {
 			if (sdev->host->hostt->slave_configure(sdev) != 0) {
@@ -1961,7 +1922,7 @@
 				       " attach, some SCSI device might not be"
 				       " configured\n");
 				scsi_release_commandblocks(sdev);
-				return 1;
+				return -ENOMEM;
 			}
 		} else if (sdev->host->cmd_per_lun != 0)
 			scsi_adjust_queue_depth(sdev, 0,
@@ -2019,10 +1980,7 @@
 	list_add_tail(&tpnt->list, &scsi_devicelist);
 	up_write(&scsi_devicelist_mutex);
 
-	tpnt->scsi_driverfs_driver.name = (char *)tpnt->tag;
-	tpnt->scsi_driverfs_driver.bus = &scsi_driverfs_bus_type;
-
-	driver_register(&tpnt->scsi_driverfs_driver);
+	scsi_upper_driver_register(tpnt);
 
 	for (shpnt = scsi_host_get_next(NULL); shpnt;
 	     shpnt = scsi_host_get_next(shpnt)) 
@@ -2037,7 +1995,6 @@
 	Scsi_Device *SDpnt;
 	struct Scsi_Host *shpnt;
 	
-	driver_unregister(&tpnt->scsi_driverfs_driver);
 
 	/*
 	 * Next, detach the devices from the driver.
@@ -2055,6 +2012,8 @@
 	list_del(&tpnt->list);
 	up_write(&scsi_devicelist_mutex);
 
+	scsi_upper_driver_unregister(tpnt);
+
 	/*
 	 * Final cleanup for the driver is done in the driver sources in the
 	 * cleanup function.
@@ -2100,135 +2059,29 @@
 __setup("scsi_default_dev_flags=", setup_scsi_default_dev_flags);
 
 #endif
-static void *scsi_pool_alloc(int gfp_mask, void *data)
-{
-	return kmem_cache_alloc(data, gfp_mask);
-}
-
-static void scsi_pool_free(void *ptr, void *data)
-{
-	kmem_cache_free(data, ptr);
-}
-
-struct scatterlist *scsi_alloc_sgtable(Scsi_Cmnd *SCpnt, int gfp_mask)
-{
-	struct scsi_host_sg_pool *sgp;
-	struct scatterlist *sgl;
-	int pf_flags;
-
-	BUG_ON(!SCpnt->use_sg);
-
-	switch (SCpnt->use_sg) {
-		case 1 ... 8			: SCpnt->sglist_len = 0; break;
-		case 9 ... 16			: SCpnt->sglist_len = 1; break;
-		case 17 ... 32			: SCpnt->sglist_len = 2; break;
-		case 33 ... 64			: SCpnt->sglist_len = 3; break;
-		case 65 ... MAX_PHYS_SEGMENTS	: SCpnt->sglist_len = 4; break;
-		default: return NULL;
-	}
-
-	sgp = scsi_sg_pools + SCpnt->sglist_len;
-
-	pf_flags = current->flags;
-	current->flags |= PF_NOWARN;
-	sgl = mempool_alloc(sgp->pool, gfp_mask);
-	current->flags = pf_flags;
-	if (sgl) {
-		memset(sgl, 0, sgp->size);
-		return sgl;
-	}
-
-	return sgl;
-}
-
-void scsi_free_sgtable(struct scatterlist *sgl, int index)
-{
-	struct scsi_host_sg_pool *sgp = scsi_sg_pools + index;
-
-	if (unlikely(index > SG_MEMPOOL_NR)) {
-		printk("scsi_free_sgtable: mempool %d\n", index);
-		BUG();
-	}
-
-	mempool_free(sgl, sgp->pool);
-}
-
-static int scsi_bus_match(struct device *scsi_driverfs_dev, 
-                          struct device_driver *scsi_driverfs_drv)
-{
-        char *p=0;
-
-        if (!strcmp("sd", scsi_driverfs_drv->name)) {
-                if ((p = strstr(scsi_driverfs_dev->bus_id, ":disc")) || 
-		    (p = strstr(scsi_driverfs_dev->bus_id, ":p"))) { 
-                        return 1;
-                }
-        } else if (!strcmp("sg", scsi_driverfs_drv->name)) {
-                if (strstr(scsi_driverfs_dev->bus_id, ":gen"))
-                        return 1;
-        } else if (!strcmp("sr",scsi_driverfs_drv->name)) {
-                if (strstr(scsi_driverfs_dev->bus_id,":cd"))
-                        return 1;
-        } else if (!strcmp("st",scsi_driverfs_drv->name)) {
-                if (strstr(scsi_driverfs_dev->bus_id,":mt"))
-                        return 1;
-        }
-        return 0;
-}
-
-struct bus_type scsi_driverfs_bus_type = {
-        .name	= "scsi",
-        .match	= scsi_bus_match,
-};
 
 static int __init init_scsi(void)
 {
-	int i;
-
 	printk(KERN_INFO "SCSI subsystem driver " REVISION "\n");
 
-	/*
-	 * setup sg memory pools
-	 */
-	for (i = 0; i < SG_MEMPOOL_NR; i++) {
-		struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
-		int size = sgp->size * sizeof(struct scatterlist);
-
-		sgp->slab = kmem_cache_create(sgp->name, size, 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
-		if (!sgp->slab)
-			printk(KERN_ERR "SCSI: can't init sg slab %s\n", sgp->name);
-
-		sgp->pool = mempool_create(SG_MEMPOOL_SIZE, scsi_pool_alloc, scsi_pool_free, sgp->slab);
-		if (!sgp->pool)
-			printk(KERN_ERR "SCSI: can't init sg mempool %s\n", sgp->name);
-	}
-
+	scsi_init_queue();
 	scsi_init_procfs();
-	scsi_devfs_handle = devfs_mk_dir(NULL, "scsi", NULL);
+	devfs_mk_dir(NULL, "scsi", NULL);
 	scsi_host_init();
 	scsi_dev_info_list_init(scsi_dev_flags);
-	bus_register(&scsi_driverfs_bus_type);
+	scsi_sysfs_register();
 	open_softirq(SCSI_SOFTIRQ, scsi_softirq, NULL);
 	return 0;
 }
 
 static void __exit exit_scsi(void)
 {
-	int i;
-
-	bus_unregister(&scsi_driverfs_bus_type);
+	scsi_sysfs_unregister();
 	scsi_dev_info_list_delete();
-	devfs_unregister(scsi_devfs_handle);
+	devfs_remove("scsi");
 	scsi_exit_procfs();
-
-	for (i = 0; i < SG_MEMPOOL_NR; i++) {
-		struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
-		mempool_destroy(sgp->pool);
-		kmem_cache_destroy(sgp->slab);
-		sgp->pool = NULL;
-		sgp->slab = NULL;
-	}
+	scsi_exit_queue();
 }
 
-module_init(init_scsi);
+subsys_initcall(init_scsi);
 module_exit(exit_scsi);
diff -Nru a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h
--- a/drivers/scsi/scsi.h	Mon Dec  9 18:46:35 2002
+++ b/drivers/scsi/scsi.h	Mon Dec  9 18:46:35 2002
@@ -401,9 +401,6 @@
 
 extern unsigned int scsi_logging_level;		/* What do we log? */
 
-extern struct bus_type scsi_driverfs_bus_type;
-
-
 /*
  * These are the error handling functions defined in scsi_error.c
  */
@@ -424,12 +421,6 @@
                     unsigned int *secs);
 
 /*
- * sg list allocations
- */
-struct scatterlist *scsi_alloc_sgtable(Scsi_Cmnd *SCpnt, int gfp_mask);
-void scsi_free_sgtable(struct scatterlist *sgl, int index);
-
-/*
  * Prototypes for functions in scsi_lib.c
  */
 extern int scsi_maybe_unblock_host(Scsi_Device * SDpnt);
@@ -440,19 +431,21 @@
 extern void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt);
 extern int scsi_prep_fn(struct request_queue *q, struct request *req);
 extern void scsi_request_fn(request_queue_t * q);
-extern int scsi_starvation_completion(Scsi_Device * SDpnt);
+extern int scsi_init_queue(void);
+extern void scsi_exit_queue(void);
 
 /*
  * Prototypes for functions in scsi.c
  */
 extern int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt);
-extern void scsi_bottom_half_handler(void);
 extern void scsi_release_commandblocks(Scsi_Device * SDpnt);
 extern void scsi_build_commandblocks(Scsi_Device * SDpnt);
 extern void scsi_adjust_queue_depth(Scsi_Device *, int, int);
 extern int scsi_track_queue_full(Scsi_Device *, int);
-extern int scsi_slave_attach(struct scsi_device *sdev);
-extern void scsi_slave_detach(struct scsi_device *sdev);
+extern int scsi_slave_attach(struct scsi_device *);
+extern void scsi_slave_detach(struct scsi_device *);
+extern int scsi_device_get(struct scsi_device *);
+extern void scsi_device_put(struct scsi_device *);
 extern void scsi_done(Scsi_Cmnd * SCpnt);
 extern void scsi_finish_command(Scsi_Cmnd *);
 extern int scsi_retry_command(Scsi_Cmnd *);
@@ -463,7 +456,6 @@
 			void *buffer, unsigned bufflen,
 			void (*done) (struct scsi_cmnd *),
 			int timeout, int retries);
-extern int scsi_dev_init(void);
 extern int scsi_mlqueue_insert(struct scsi_cmnd *, int);
 extern int scsi_attach_device(struct scsi_device *);
 extern void scsi_detach_device(struct scsi_device *);
@@ -509,9 +501,6 @@
 /*
  * Prototypes for functions in scsi_scan.c
  */
-extern struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *,
-			uint, uint, uint);
-extern void scsi_free_sdev(struct scsi_device *);
 extern int scsi_add_single_device(uint, uint, uint, uint);
 extern int scsi_remove_single_device(uint, uint, uint, uint);
 
@@ -991,5 +980,11 @@
 #define SCSI_SENSE_VALID(scmd) ((scmd->sense_buffer[0] & 0x70) == 0x70)
 
 int scsi_set_medium_removal(Scsi_Device *dev, char state);
+
+extern int scsi_device_register(struct scsi_device *);
+extern void scsi_device_unregister(struct scsi_device *);
+
+extern int scsi_sysfs_register(void);
+extern void scsi_sysfs_unregister(void);
 
 #endif
diff -Nru a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
--- a/drivers/scsi/scsi_debug.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/scsi/scsi_debug.c	Mon Dec  9 18:46:38 2002
@@ -51,7 +51,7 @@
 
 #include "scsi_debug.h"
 
-static const char * scsi_debug_version_str = "Version: 1.65 (20021119)";
+static const char * scsi_debug_version_str = "Version: 1.66 (20021205)";
 
 #ifndef SCSI_CMD_READ_16
 #define SCSI_CMD_READ_16 0x88
@@ -155,6 +155,7 @@
 static char sdebug_proc_name[] = "scsi_debug";
 static struct device_driver sdebug_driverfs_driver = {
 	.name = sdebug_proc_name,
+	.devclass = &shost_devclass,
 };
 
 /* function declarations */
@@ -396,7 +397,7 @@
 		if ((errsts = check_reset(SCpnt, devip)))
 			break;
 		mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x20, 0, 14);
-		errsts = (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
+		errsts = (DRIVER_SENSE << 24) | (CHECK_CONDITION << 1);
 		break;
 	}
 	return schedule_resp(SCpnt, devip, done, errsts, scsi_debug_delay);
@@ -416,7 +417,7 @@
 	if (devip->reset) {
 		devip->reset = 0;
 		mk_sense_buffer(devip, UNIT_ATTENTION, 0x29, 0, 14);
-		return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
+		return (DRIVER_SENSE << 24) | (CHECK_CONDITION << 1);
 	}
 	return 0;
 }
@@ -477,7 +478,7 @@
 	arr[0] = pq_pdt;
 	if (0x2 & cmd[1]) {  /* CMDDT bit set */
 		mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x24, 0, 14);
-		return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
+		return (DRIVER_SENSE << 24) | (CHECK_CONDITION << 1);
 	} else if (0x1 & cmd[1]) {  /* EVPD bit set */
 		int dev_id_num, len;
 		char dev_id_str[6];
@@ -502,7 +503,7 @@
 		} else {
 			/* Illegal request, invalid field in cdb */
 			mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x24, 0, 14);
-			return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
+			return (DRIVER_SENSE << 24) | (CHECK_CONDITION << 1);
 		}
 		memcpy(buff, arr, min_len); 
 		return 0;
@@ -615,7 +616,7 @@
 	memset(arr, 0, SDEBUG_MAX_MSENSE_SZ);
 	if (0x3 == pcontrol) {  /* Saving values not supported */
 		mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x39, 0, 14);
-		return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
+		return (DRIVER_SENSE << 24) | (CHECK_CONDITION << 1);
 	}
 	dev_spec = DEV_READONLY(target) ? 0x80 : 0x0;
 	if (msense_6) {
@@ -658,7 +659,7 @@
 		break;
 	default:
 		mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x24, 0, 14);
-		return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
+		return (DRIVER_SENSE << 24) | (CHECK_CONDITION << 1);
 	}
 	if (msense_6)
 		arr[0] = offset - 1;
@@ -682,14 +683,14 @@
 
 	if (upper_blk || (block + num > sdebug_capacity)) {
 		mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x21, 0, 14);
-		return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
+		return (DRIVER_SENSE << 24) | (CHECK_CONDITION << 1);
 	}
 	if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) &&
 	    (block >= OPT_MEDIUM_ERR_ADDR) && 
 	    (block < (OPT_MEDIUM_ERR_ADDR + num))) {
 		mk_sense_buffer(devip, MEDIUM_ERROR, 0x11, 0, 14);
 		/* claim unrecoverable read error */
-		return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
+		return (DRIVER_SENSE << 24) | (CHECK_CONDITION << 1);
 	}
 	read_lock_irqsave(&atomic_rw, iflags);
         sgcount = 0;
@@ -731,7 +732,7 @@
 
 	if (upper_blk || (block + num > sdebug_capacity)) {
 		mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x21, 0, 14);
-		return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
+		return (DRIVER_SENSE << 24) | (CHECK_CONDITION << 1);
 	}
 
 	write_lock_irqsave(&atomic_rw, iflags);
@@ -772,7 +773,7 @@
 	alloc_len = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24);
 	if ((alloc_len < 16) || (select_report > 2)) {
 		mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x24, 0, 14);
-		return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
+		return (DRIVER_SENSE << 24) | (CHECK_CONDITION << 1);
 	}
 	if (bufflen > 3) {
 		lun_cnt = min((int)(bufflen / sizeof(ScsiLun)),
@@ -1501,7 +1502,7 @@
 		printk(KERN_ERR "sdebug_add_shost: scsi_register failed\n");
 		return;
 	}
-	err = scsi_add_host(hpnt);
+	err = scsi_add_host(hpnt, scsi_debug_hosts[num].dev);
 	if (err) {
 		printk(KERN_ERR "sdebug_add_shost: scsi_add_host failed\n");
 		scsi_unregister(hpnt);
diff -Nru a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
--- a/drivers/scsi/scsi_ioctl.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/scsi/scsi_ioctl.c	Mon Dec  9 18:46:51 2002
@@ -393,12 +393,13 @@
  *          any copy_to_user() error on failure there
  */
 static int
-scsi_ioctl_get_pci(Scsi_Device * dev, void *arg)
+scsi_ioctl_get_pci(Scsi_Device * sdev, void *arg)
 {
+	struct device *dev = scsi_get_device(sdev->host);
 
-        if (!dev->host->pci_dev) return -ENXIO;
-        return copy_to_user(arg, dev->host->pci_dev->slot_name,
-                            sizeof(dev->host->pci_dev->slot_name));
+        if (!dev) return -ENXIO;
+        return copy_to_user(arg, dev->bus_id,
+                            sizeof(dev->bus_id));
 }
 
 
diff -Nru a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
--- a/drivers/scsi/scsi_lib.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/scsi/scsi_lib.c	Mon Dec  9 18:46:37 2002
@@ -7,18 +7,33 @@
  *                        of people at Linux Expo.
  */
 
-#include <linux/string.h>
-#include <linux/slab.h>
 #include <linux/bio.h>
-#include <linux/kernel.h>
 #include <linux/blk.h>
-#include <asm/hardirq.h>
-#include <linux/smp_lock.h>
 #include <linux/completion.h>
+#include <linux/kernel.h>
+#include <linux/mempool.h>
+#include <linux/slab.h>
+#include <linux/init.h>
 
 #include "scsi.h"
 #include "hosts.h"
-#include <scsi/scsi_ioctl.h>
+
+
+#define SG_MEMPOOL_NR		5
+#define SG_MEMPOOL_SIZE		32
+
+struct scsi_host_sg_pool {
+	size_t		size;
+	char		*name; 
+	kmem_cache_t	*slab;
+	mempool_t	*pool;
+};
+
+#define SP(x) { x, "sgpool-" #x } 
+struct scsi_host_sg_pool scsi_sg_pools[SG_MEMPOOL_NR] = { 
+	SP(8), SP(16), SP(32), SP(64), SP(MAX_PHYS_SEGMENTS)
+}; 	
+#undef SP 	
 
 /*
  * Function:    scsi_insert_special_cmd()
@@ -351,6 +366,51 @@
 	return NULL;
 }
 
+static struct scatterlist *scsi_alloc_sgtable(Scsi_Cmnd *SCpnt, int gfp_mask)
+{
+	struct scsi_host_sg_pool *sgp;
+	struct scatterlist *sgl;
+
+	BUG_ON(!SCpnt->use_sg);
+
+	switch (SCpnt->use_sg) {
+	case 1 ... 8:
+		SCpnt->sglist_len = 0;
+		break;
+	case 9 ... 16:
+		SCpnt->sglist_len = 1;
+		break;
+	case 17 ... 32:
+		SCpnt->sglist_len = 2;
+		break;
+	case 33 ... 64:
+		SCpnt->sglist_len = 3;
+		break;
+	case 65 ... MAX_PHYS_SEGMENTS:
+		SCpnt->sglist_len = 4;
+		break;
+	default:
+		return NULL;
+	}
+
+	sgp = scsi_sg_pools + SCpnt->sglist_len;
+	sgl = mempool_alloc(sgp->pool, gfp_mask);
+	if (sgl)
+		memset(sgl, 0, sgp->size);
+	return sgl;
+}
+
+static void scsi_free_sgtable(struct scatterlist *sgl, int index)
+{
+	struct scsi_host_sg_pool *sgp;
+
+	BUG_ON(index > SG_MEMPOOL_NR);
+
+	sgp = scsi_sg_pools + index;
+	mempool_free(sgl, sgp->pool);
+}
+
+
 /*
  * Function:    scsi_release_buffers()
  *
@@ -377,15 +437,10 @@
 	/*
 	 * Free up any indirection buffers we allocated for DMA purposes. 
 	 */
-	if (SCpnt->use_sg) {
-		struct scatterlist *sgpnt;
-
-		sgpnt = (struct scatterlist *) SCpnt->request_buffer;
+	if (SCpnt->use_sg)
 		scsi_free_sgtable(SCpnt->request_buffer, SCpnt->sglist_len);
-	} else {
-		if (SCpnt->request_buffer != req->buffer)
-			kfree(SCpnt->request_buffer);
-	}
+	else if (SCpnt->request_buffer != req->buffer)
+		kfree(SCpnt->request_buffer);
 
 	/*
 	 * Zero these out.  They now point to freed memory, and it is
@@ -465,22 +520,16 @@
 	 * For the case of a READ, we need to copy the data out of the
 	 * bounce buffer and into the real buffer.
 	 */
-	if (SCpnt->use_sg) {
-		struct scatterlist *sgpnt;
-
-		sgpnt = (struct scatterlist *) SCpnt->buffer;
+	if (SCpnt->use_sg)
 		scsi_free_sgtable(SCpnt->buffer, SCpnt->sglist_len);
-	} else {
-		if (SCpnt->buffer != req->buffer) {
-			if (rq_data_dir(req) == READ) {
-				unsigned long flags;
-				char *to = bio_kmap_irq(req->bio, &flags);
-
-				memcpy(to, SCpnt->buffer, SCpnt->bufflen);
-				bio_kunmap_irq(to, &flags);
-			}
-			kfree(SCpnt->buffer);
+	else if (SCpnt->buffer != req->buffer) {
+		if (rq_data_dir(req) == READ) {
+			unsigned long flags;
+			char *to = bio_kmap_irq(req->bio, &flags);
+			memcpy(to, SCpnt->buffer, SCpnt->bufflen);
+			bio_kunmap_irq(to, &flags);
 		}
+		kfree(SCpnt->buffer);
 	}
 
 	if (blk_pc_request(req)) {
@@ -665,7 +714,7 @@
 {
 	struct request     *req = SCpnt->request;
 	struct scatterlist *sgpnt;
-	int count, gfp_mask, ret = 0;
+	int count, ret = 0;
 
 	/*
 	 * if this is a rq->data based REQ_BLOCK_PC, setup for a non-sg xfer
@@ -685,16 +734,10 @@
 	 */
 	SCpnt->use_sg = req->nr_phys_segments;
 
-	gfp_mask = GFP_NOIO;
-	if (likely(in_atomic())) {
-		gfp_mask &= ~__GFP_WAIT;
-		gfp_mask |= __GFP_HIGH;
-	}
-
 	/*
 	 * if sg table allocation fails, requeue request later.
 	 */
-	sgpnt = scsi_alloc_sgtable(SCpnt, gfp_mask);
+	sgpnt = scsi_alloc_sgtable(SCpnt, GFP_ATOMIC);
 	if (unlikely(!sgpnt)) {
 		req->flags |= REQ_SPECIAL;
 		ret = BLKPREP_DEFER;
@@ -1101,4 +1144,42 @@
 
 void scsi_deregister_blocked_host(struct Scsi_Host * SHpnt)
 {
+}
+
+int __init scsi_init_queue(void)
+{
+	int i;
+
+	for (i = 0; i < SG_MEMPOOL_NR; i++) {
+		struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
+		int size = sgp->size * sizeof(struct scatterlist);
+
+		sgp->slab = kmem_cache_create(sgp->name, size, 0,
+				SLAB_HWCACHE_ALIGN, NULL, NULL);
+		if (!sgp->slab) {
+			printk(KERN_ERR "SCSI: can't init sg slab %s\n",
+					sgp->name);
+		}
+
+		sgp->pool = mempool_create(SG_MEMPOOL_SIZE,
+				mempool_alloc_slab, mempool_free_slab,
+				sgp->slab);
+		if (!sgp->pool) {
+			printk(KERN_ERR "SCSI: can't init sg mempool %s\n",
+					sgp->name);
+		}
+	}
+
+	return 0;
+}
+
+void __exit scsi_exit_queue(void)
+{
+	int i;
+
+	for (i = 0; i < SG_MEMPOOL_NR; i++) {
+		struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
+		mempool_destroy(sgp->pool);
+		kmem_cache_destroy(sgp->slab);
+	}
 }
diff -Nru a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
--- a/drivers/scsi/scsi_scan.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/scsi/scsi_scan.c	Mon Dec  9 18:46:50 2002
@@ -313,73 +313,6 @@
 }
 
 /**
- * scsi_device_type_read - copy out the SCSI type
- * @driverfs_dev:	driverfs device to check
- * @page:		copy data into this area
- * @count:		number of bytes to copy
- * @off:		start at this offset in page
- *
- * Description:
- *     Called via driverfs when the "type" (in scsi_device_type_file)
- *     field is read. Copy the appropriate SCSI type string into @page,
- *     followed by a newline and a '\0'. Go through gyrations so we don't
- *     write more than @count, and we don't write past @off.
- *
- * Notes:
- *     This is for the top-most scsi entry in driverfs, the upper-level
- *     drivers have their own type file. XXX This is not part of scanning,
- *     other than we reference the attr struct in this file, move to
- *     scsi.c or scsi_lib.c.
- *
- * Return:
- *     number of bytes written into page.
- **/
-static ssize_t scsi_device_type_read(struct device *driverfs_dev, char *page,
-	size_t count, loff_t off)
-{
-	struct scsi_device *sdev = to_scsi_device(driverfs_dev);
-	const char *type;
-	size_t size, len;
-
-	if ((sdev->type > MAX_SCSI_DEVICE_CODE) ||
-	    (scsi_device_types[(int)sdev->type] == NULL))
-		type = "Unknown";
-	else
-		type = scsi_device_types[(int)sdev->type];
-	size = strlen(type);
-	/*
-	 * Check if off is past size + 1 for newline + 1 for a '\0'.
-	 */
-	if (off >= (size + 2))
-		return 0;
-	if (size > off) {
-		len = min((size_t) (size - off), count);
-		memcpy(page + off, type + off, len);
-	} else
-		len = 0;
-	if (((len + off) == size) && (len < count))
-		/*
-		 * We are at the end of the string and have space, add a
-		 * new line.
-		 */
-		*(page + off + len++) = '\n';
-	if (((len + off) == (size + 1)) && (len < count))
-		/*
-		 * We are past the newline and have space, add a
-		 * terminating '\0'.
-		 */
-		*(page + off + len++) = '\0';
-	return len;
-}
-
-/*
- * Create dev_attr_type. This is different from the dev_attr_type in scsi
- * upper level drivers.
- */
-static DEVICE_ATTR(type,S_IRUGO,scsi_device_type_read,NULL);
-
-
-/**
  * print_inquiry - printk the inquiry information
  * @inq_result:	printk this SCSI INQUIRY
  *
@@ -440,11 +373,12 @@
 {
 	request_queue_t *q = &sd->request_queue;
 	struct Scsi_Host *sh = sd->host;
+	struct device *dev = scsi_get_device(sh);
 	u64 bounce_limit;
 
 	if (sh->highmem_io) {
-		if (sh->pci_dev && PCI_DMA_BUS_IS_PHYS) {
-			bounce_limit = sh->pci_dev->dma_mask;
+		if (dev && dev->dma_mask && PCI_DMA_BUS_IS_PHYS) {
+			bounce_limit = *dev->dma_mask;
 		} else {
 			/*
 			 * Platforms with virtual-DMA translation
@@ -472,8 +406,8 @@
  * Return value:
  *     Scsi_Device pointer, or NULL on failure.
  **/
-struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, uint channel,
-				    uint id, uint lun)
+static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
+					   uint channel, uint id, uint lun)
 {
 	struct scsi_device *sdev, *device;
 
@@ -542,7 +476,7 @@
  *     Undo the actions in scsi_alloc_sdev, including removing @sdev from
  *     the list, and freeing @sdev.
  **/
-void scsi_free_sdev(struct scsi_device *sdev)
+static void scsi_free_sdev(struct scsi_device *sdev)
 {
 	list_del(&sdev->siblings);
 	list_del(&sdev->same_target_siblings);
@@ -1365,20 +1299,8 @@
 	 * function.
 	 */
 	scsi_load_identifier(sdev, sreq);
-
-	/*
-	 * create driverfs files
-	 */
-	sprintf(sdev->sdev_driverfs_dev.bus_id,"%d:%d:%d:%d",
-		sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
-	sdev->sdev_driverfs_dev.parent = &sdev->host->host_driverfs_dev;
-	sdev->sdev_driverfs_dev.bus = &scsi_driverfs_bus_type;
-	device_register(&sdev->sdev_driverfs_dev);
-
-	/*
-	 * Create driverfs file entries
-	 */
-	device_create_file(&sdev->sdev_driverfs_dev, &dev_attr_type);
+	
+	scsi_device_register(sdev);
 
 	sprintf(devname, "scsi/host%d/bus%d/target%d/lun%d",
 		sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
@@ -1419,6 +1341,14 @@
 	return SCSI_SCAN_LUN_PRESENT;
 }
 
+static void scsi_remove_lun(struct scsi_device *sdev)
+{
+	devfs_unregister(sdev->de);
+	scsi_device_unregister(sdev);
+
+	scsi_free_sdev(sdev);
+}
+
 /**
  * scsi_probe_and_add_lun - probe a LUN, if a LUN is found add it
  * @sdevscan:	probe the LUN corresponding to this Scsi_Device
@@ -1941,8 +1871,7 @@
 	if (sdev->attached)
 		goto out;
 
-	devfs_unregister(sdev->de);
-	scsi_free_sdev(sdev);
+	scsi_remove_lun(sdev);
 	error = 0;
 
 out:
@@ -2067,4 +1996,70 @@
 		}
 	}
 	scsi_free_sdev(sdevscan);
+}
+
+void scsi_forget_host(struct Scsi_Host *shost)
+{
+	struct list_head *le, *lh;
+
+	list_for_each_safe(le, lh, &shost->my_devices)
+		scsi_remove_lun(list_entry(le, struct scsi_device, siblings));
+}
+
+/*
+ * Function:    scsi_get_host_dev()
+ *
+ * Purpose:     Create a Scsi_Device that points to the host adapter itself.
+ *
+ * Arguments:   SHpnt   - Host that needs a Scsi_Device
+ *
+ * Lock status: None assumed.
+ *
+ * Returns:     The Scsi_Device or NULL
+ *
+ * Notes:
+ *	Attach a single Scsi_Device to the Scsi_Host - this should
+ *	be made to look like a "pseudo-device" that points to the
+ *	HA itself.
+ *
+ *	Note - this device is not accessible from any high-level
+ *	drivers (including generics), which is probably not
+ *	optimal.  We can add hooks later to attach 
+ */
+struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
+{
+	struct scsi_device *sdev;
+
+	sdev = scsi_alloc_sdev(shost, 0, shost->this_id, 0);
+	if (sdev) {
+		scsi_build_commandblocks(sdev);
+		if (sdev->current_queue_depth == 0)
+			goto fail;
+		sdev->borken = 0;
+	}
+
+	return sdev;
+
+fail:
+	kfree(sdev);
+	return NULL;
+}
+
+/*
+ * Function:    scsi_free_host_dev()
+ *
+ * Purpose:     Free a scsi_device that points to the host adapter itself.
+ *
+ * Arguments:   SHpnt   - Host that needs a Scsi_Device
+ *
+ * Lock status: None assumed.
+ *
+ * Returns:     Nothing
+ *
+ * Notes:
+ */
+void scsi_free_host_dev(struct scsi_device *sdev)
+{
+	BUG_ON(sdev->id != sdev->host->this_id);
+	scsi_free_sdev(sdev);
 }
diff -Nru a/drivers/scsi/scsi_syms.c b/drivers/scsi/scsi_syms.c
--- a/drivers/scsi/scsi_syms.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/scsi/scsi_syms.c	Mon Dec  9 18:46:37 2002
@@ -81,6 +81,8 @@
 EXPORT_SYMBOL(scsi_deregister_blocked_host);
 EXPORT_SYMBOL(scsi_slave_attach);
 EXPORT_SYMBOL(scsi_slave_detach);
+EXPORT_SYMBOL(scsi_device_get);
+EXPORT_SYMBOL(scsi_device_put);
 
 /*
  * This symbol is for the highlevel drivers (e.g. sg) only.
@@ -104,6 +106,6 @@
 EXPORT_SYMBOL(scsi_delete_timer);
 
 /*
- * driverfs support for determining driver types
+ * sysfs support
  */
-EXPORT_SYMBOL(scsi_driverfs_bus_type);
+EXPORT_SYMBOL(shost_devclass);
diff -Nru a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/scsi/scsi_sysfs.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,286 @@
+/*
+ * scsi_sysfs.c
+ *
+ * SCSI sysfs interface routines.
+ *
+ * Created to pull SCSI mid layer sysfs routines into one file.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/device.h>
+#include "scsi.h"
+#include "hosts.h"
+
+/**
+ * scsi_host_class_name_show - copy out the SCSI host name
+ * @dev:		device to check
+ * @page:		copy data into this area
+ * @count:		number of bytes to copy
+ * @off:		start at this offset in page
+ * Return:
+ *     number of bytes written into page.
+ **/
+static ssize_t scsi_host_class_name_show(struct device *dev, char *page,
+	size_t count, loff_t off)
+{
+	struct Scsi_Host *shost;
+
+	if (off)
+		return 0;
+
+	shost = to_scsi_host(dev);
+
+	if (!shost)
+		return 0;
+	
+	return snprintf(page, count, "scsi%d\n", shost->host_no);
+}
+
+DEVICE_ATTR(class_name, S_IRUGO, scsi_host_class_name_show, NULL);
+
+static int scsi_host_class_add_dev(struct device * dev)
+{
+	device_create_file(dev, &dev_attr_class_name);
+	return 0;
+}
+
+static void scsi_host_class_rm_dev(struct device * dev)
+{
+	device_remove_file(dev, &dev_attr_class_name);
+}
+
+struct device_class shost_devclass = {
+	.name		= "scsi-host",
+	.add_device	= scsi_host_class_add_dev,
+	.remove_device	= scsi_host_class_rm_dev,
+};
+
+/**
+ * scsi_bus_match:
+ * @dev:
+ * @dev_driver:
+ *
+ * Return value:
+ **/
+static int scsi_bus_match(struct device *dev, 
+                          struct device_driver *dev_driver)
+{
+        if (!strcmp("sg", dev_driver->name)) {
+                if (strstr(dev->bus_id, ":gen"))
+                        return 1;
+        } else if (!strcmp("st",dev_driver->name)) {
+                if (strstr(dev->bus_id,":mt"))
+                        return 1;
+        } else if (!strcmp("sd", dev_driver->name)) {
+                if ((!strstr(dev->bus_id, ":gen")) && 
+		    (!strstr(dev->bus_id, ":mt"))) { 
+                        return 1;
+                }
+	}
+        return 0;
+}
+
+
+static struct bus_type scsi_bus_type = {
+        .name		= "scsi",
+        .match		= scsi_bus_match,
+};
+
+
+int scsi_sysfs_register(void)
+{
+	bus_register(&scsi_bus_type);
+	devclass_register(&shost_devclass);
+
+	return 0;
+}
+
+void scsi_sysfs_unregister(void)
+{
+	devclass_unregister(&shost_devclass);
+	bus_unregister(&scsi_bus_type);
+}
+
+/**
+ * scsi_upper_driver_register - register upper level driver.
+ * @sdev_tp:	Upper level driver to register with the scsi bus.
+ *
+ * Return value:
+ * 	0 on Success / non-zero on Failure
+ **/
+int scsi_upper_driver_register(struct Scsi_Device_Template *sdev_tp)
+{
+	int error = 0;
+
+	sdev_tp->scsi_driverfs_driver.bus = &scsi_bus_type;
+	error = driver_register(&sdev_tp->scsi_driverfs_driver);
+
+	return error;
+}
+
+/**
+ * scsi_upper_driver_unregister - unregister upper level driver 
+ * @sdev_tp:	Upper level driver to unregister with the scsi bus.
+ *
+ **/
+void scsi_upper_driver_unregister(struct Scsi_Device_Template *sdev_tp)
+{
+	driver_unregister(&sdev_tp->scsi_driverfs_driver);
+}
+
+
+/*
+ * show_function: macro to create an attr function that can be used to
+ * show a non-bit field.
+ */
+#define show_function(field, format_string)				\
+static ssize_t								\
+show_##field (struct device *dev, char *buf, size_t count, loff_t off)	\
+{									\
+	struct scsi_device *sdev;					\
+	if (off)							\
+		return 0;						\
+	sdev = to_scsi_device(dev);					\
+	return snprintf (buf, count, format_string, sdev->field);	\
+}									\
+
+/*
+ * sdev_rd_attr: macro to create a function and attribute variable for a
+ * read only field.
+ */
+#define sdev_rd_attr(field, format_string)				\
+	show_function(field, format_string)				\
+static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL)
+
+
+/*
+ * sdev_rd_attr: create a function and attribute variable for a
+ * read/write field.
+ */
+#define sdev_rw_attr(field, format_string)				\
+	show_function(field, format_string)				\
+									\
+static ssize_t								\
+store_##field (struct device *dev, const char *buf, size_t count, loff_t off)\
+{									\
+	struct scsi_device *sdev;					\
+									\
+	if (off)							\
+		return 0;						\
+	sdev = to_scsi_device(dev);					\
+	return snscanf (buf, count, format_string, &sdev->field);	\
+}									\
+static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, show_##field, store_##field)
+
+/*
+ * sdev_rd_attr: create a function and attribute variable for a
+ * read/write bit field.
+ */
+#define sdev_rw_attr_bit(field)						\
+	show_function(field, "%d\n")					\
+									\
+static ssize_t								\
+store_##field (struct device *dev, const char *buf, size_t count, loff_t off)\
+{									\
+	int ret;							\
+	struct scsi_device *sdev;					\
+									\
+	if (off)							\
+		return 0;						\
+	ret = scsi_sdev_check_buf_bit(buf);				\
+	if (ret >= 0)	{						\
+		sdev = to_scsi_device(dev);				\
+		sdev->field = ret;					\
+		ret = count;						\
+	}								\
+	return ret;							\
+}									\
+static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, show_##field, store_##field)
+
+/*
+ * scsi_sdev_check_buf_bit: return 0 if buf is "0", return 1 if buf is "1",
+ * else return -EINVAL.
+ */
+static int scsi_sdev_check_buf_bit(const char *buf)
+{
+	if ((buf[1] == '\0') || ((buf[1] == '\n') && (buf[2] == '\0'))) {
+		if (buf[0] == '1')
+			return 1;
+		else if (buf[0] == '0')
+			return 0;
+		else 
+			return -EINVAL;
+	} else
+		return -EINVAL;
+}
+
+/*
+ * Create the actual show/store functions and data structures.
+ */
+sdev_rd_attr (device_blocked, "%d\n");
+sdev_rd_attr (current_queue_depth, "%d\n");
+sdev_rd_attr (new_queue_depth, "%d\n");
+sdev_rd_attr (type, "%d\n");
+sdev_rd_attr (access_count, "%d\n");
+sdev_rd_attr (vendor, "%.8s\n");
+sdev_rd_attr (model, "%.16s\n");
+sdev_rd_attr (rev, "%.4s\n");
+sdev_rw_attr_bit (online);
+
+static struct device_attribute * const sdev_attrs[] = {
+	&dev_attr_device_blocked,
+	&dev_attr_current_queue_depth,
+	&dev_attr_new_queue_depth,
+	&dev_attr_type,
+	&dev_attr_access_count,
+	&dev_attr_vendor,
+	&dev_attr_model,
+	&dev_attr_rev,
+	&dev_attr_online,
+};
+
+/**
+ * scsi_device_register - register a scsi device with the scsi bus
+ * @sdev:	scsi_device to register
+ *
+ * Return value:
+ * 	0 on Success / non-zero on Failure
+ **/
+int scsi_device_register(struct scsi_device *sdev)
+{
+	int error = 0, i;
+
+	sprintf(sdev->sdev_driverfs_dev.bus_id,"%d:%d:%d:%d",
+		sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
+	sdev->sdev_driverfs_dev.parent = sdev->host->host_gendev;
+	sdev->sdev_driverfs_dev.bus = &scsi_bus_type;
+
+	error = device_register(&sdev->sdev_driverfs_dev);
+	if (error)
+		return error;
+
+	for (i = 0; !error && i < ARRAY_SIZE(sdev_attrs); i++)
+		error = device_create_file(&sdev->sdev_driverfs_dev,
+					   sdev_attrs[i]);
+
+	if (error)
+		scsi_device_unregister(sdev);
+
+	return error;
+}
+
+/**
+ * scsi_device_unregister - unregister a device from the scsi bus
+ * @sdev:	scsi_device to unregister
+ **/
+void scsi_device_unregister(struct scsi_device *sdev)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(sdev_attrs); i++)
+		device_remove_file(&sdev->sdev_driverfs_dev, sdev_attrs[i]);
+	device_unregister(&sdev->sdev_driverfs_dev);
+}
diff -Nru a/drivers/scsi/sd.c b/drivers/scsi/sd.c
--- a/drivers/scsi/sd.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/scsi/sd.c	Mon Dec  9 18:46:50 2002
@@ -29,8 +29,6 @@
  *	than the level indicated above to trigger output.	
  */
 
-#define MAJOR_NR SCSI_DISK0_MAJOR
-
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/fs.h>
@@ -57,8 +55,8 @@
 /*
  * Remaining dev_t-handling stuff
  */
-#define SD_MAJORS	8
-#define SD_MAJOR(i)	((i) ? SCSI_DISK1_MAJOR-1+(i) : SCSI_DISK0_MAJOR)
+#define SD_MAJORS	16
+#define SD_DISKS	(SD_MAJORS << 4)
 
 /*
  * Time out in seconds for disks and Magneto-opticals (which are slower).
@@ -77,18 +75,18 @@
 	struct scsi_device *device;
 	struct gendisk	*disk;
 	sector_t	capacity;	/* size in 512-byte sectors */
+	u32		index;
 	u8		media_present;
 	u8		write_prot;
 	unsigned	WCE : 1;	/* state of disk WCE bit */
 	unsigned	RCD : 1;	/* state of disk RCD bit */
 };
 
-static int sd_nr_dev;	/* XXX(hch) bad hack, we want a bitmap instead */
 static LIST_HEAD(sd_devlist);
 static spinlock_t sd_devlist_lock = SPIN_LOCK_UNLOCKED;
 
-static int check_scsidisk_media_change(struct gendisk *);
-static int sd_revalidate(struct gendisk *);
+static unsigned long sd_index_bits[SD_DISKS / BITS_PER_LONG];
+static spinlock_t sd_index_lock = SPIN_LOCK_UNLOCKED;
 
 static void sd_init_onedisk(struct scsi_disk * sdkp, struct gendisk *disk);
 static void sd_rw_intr(struct scsi_cmnd * SCpnt);
@@ -105,13 +103,30 @@
 	.module		= THIS_MODULE,
 	.list		= LIST_HEAD_INIT(sd_template.list),
 	.name		= "disk",
-	.tag		= "sd",
 	.scsi_type	= TYPE_DISK,
 	.attach		= sd_attach,
 	.detach		= sd_detach,
 	.init_command	= sd_init_command,
+	.scsi_driverfs_driver = {
+		.name   = "sd",
+	},
 };
 
+static int sd_major(int major_idx)
+{
+	switch (major_idx) {
+	case 0:
+		return SCSI_DISK0_MAJOR;
+	case 1 ... 7:
+		return SCSI_DISK1_MAJOR + major_idx - 1;
+	case 8 ... 15:
+		return SCSI_DISK8_MAJOR + major_idx;
+	default:
+		BUG();
+		return 0;	/* shut up gcc */
+	}
+}
+
 static struct scsi_disk *sd_find_by_sdev(Scsi_Device *sd)
 {
 	struct scsi_disk *sdkp;
@@ -148,91 +163,6 @@
 }
 
 /**
- *	sd_ioctl - process an ioctl
- *	@inode: only i_rdev member may be used
- *	@filp: only f_mode and f_flags may be used
- *	@cmd: ioctl command number
- *	@arg: this is third argument given to ioctl(2) system call.
- *	Often contains a pointer.
- *
- *	Returns 0 if successful (some ioctls return postive numbers on
- *	success as well). Returns a negated errno value in case of error.
- *
- *	Note: most ioctls are forward onto the block subsystem or further
- *	down in the scsi subsytem.
- **/
-static int sd_ioctl(struct inode * inode, struct file * filp, 
-		    unsigned int cmd, unsigned long arg)
-{
-	struct block_device *bdev = inode->i_bdev;
-	struct gendisk *disk = bdev->bd_disk;
-	struct scsi_disk *sdkp = scsi_disk(disk);
-	struct scsi_device *sdp = sdkp->device;
-	sector_t capacity = sdkp->capacity;
-	struct Scsi_Host *host;
-	int diskinfo[4];
-	int error;
-    
-	SCSI_LOG_IOCTL(1, printk("sd_ioctl: disk=%s, cmd=0x%x\n",
-						disk->disk_name, cmd));
-	if (!sdp)
-		return -ENODEV;
-	/*
-	 * If we are in the middle of error recovery, don't let anyone
-	 * else try and use this device.  Also, if error recovery fails, it
-	 * may try and take the device offline, in which case all further
-	 * access to the device is prohibited.
-	 */
-
-	if (!scsi_block_when_processing_errors(sdp))
-		return -ENODEV;
-
-	error = scsi_cmd_ioctl(bdev, cmd, arg);
-	if (error != -ENOTTY)
-		return error;
-
-	switch (cmd) {
-		case HDIO_GETGEO:   /* Return BIOS disk parameters */
-		{
-			struct hd_geometry *loc = (struct hd_geometry *)arg;
-
-			if (!loc)
-				return -EINVAL;
-
-			host = sdp->host;
-	
-			/* default to most commonly used values */
-	
-		        diskinfo[0] = 0x40;	/* 1 << 6 */
-	        	diskinfo[1] = 0x20;	/* 1 << 5 */
-	        	diskinfo[2] = sdkp->capacity >> 11;
-	
-			/* override with calculated, extended default, 
-			   or driver values */
-	
-			if (host->hostt->bios_param) {
-				host->hostt->bios_param(sdp, bdev,
-							capacity, diskinfo);
-			} else
-				scsicam_bios_param(bdev, capacity, diskinfo);
-
-			if (put_user(diskinfo[0], &loc->heads))
-				return -EFAULT;
-			if (put_user(diskinfo[1], &loc->sectors))
-				return -EFAULT;
-			if (put_user(diskinfo[2], &loc->cylinders))
-				return -EFAULT;
-			if (put_user((unsigned)get_start_sect(bdev),
-				     (unsigned long *)&loc->start))
-				return -EFAULT;
-			return 0;
-		}
-		default:
-			return scsi_ioctl(sdp, cmd, (void *)arg);
-	}
-}
-
-/**
  *	sd_init_command - build a scsi (read or write) command from
  *	information in the request structure.
  *	@SCpnt: pointer to mid-level's per scsi command structure that
@@ -434,68 +364,61 @@
 {
 	struct gendisk *disk = inode->i_bdev->bd_disk;
 	struct scsi_disk *sdkp = scsi_disk(disk);
-	struct scsi_device * sdp = sdkp->device;
-	int retval = -ENXIO;
+	struct scsi_device *sdev = sdkp->device;
+	int retval;
 
 	SCSI_LOG_HLQUEUE(3, printk("sd_open: disk=%s\n", disk->disk_name));
 
-	if (!sdkp)
-		return -ENXIO;	/* No such device */
+	retval = scsi_device_get(sdev);
+	if (retval)
+		return retval;
 
 	/*
 	 * If the device is in error recovery, wait until it is done.
 	 * If the device is offline, then disallow any access to it.
 	 */
-	if (!scsi_block_when_processing_errors(sdp))
-		return -ENXIO;
-	/*
-	 * The following code can sleep.
-	 * Module unloading must be prevented
-	 */
-	if(!try_module_get(sdp->host->hostt->module))
-		return -ENOMEM;
-	sdp->access_count++;
+	retval = -ENXIO;
+	if (!scsi_block_when_processing_errors(sdev))
+		goto error_out;
 
-	if (sdp->removable) {
+	if (sdev->removable) {
 		check_disk_change(inode->i_bdev);
 
 		/*
 		 * If the drive is empty, just let the open fail.
 		 */
-		if ((!sdkp->media_present) && !(filp->f_flags & O_NDELAY)) {
-			retval = -ENOMEDIUM;
+		retval = -ENOMEDIUM;
+		if ((!sdkp->media_present) && !(filp->f_flags & O_NDELAY))
 			goto error_out;
-		}
 
 		/*
 		 * Similarly, if the device has the write protect tab set,
 		 * have the open fail if the user expects to be able to write
 		 * to the thing.
 		 */
-		if ((sdkp->write_prot) && (filp->f_mode & FMODE_WRITE)) {
-			retval = -EROFS;
+		retval = -EROFS;
+		if ((sdkp->write_prot) && (filp->f_mode & FMODE_WRITE))
 			goto error_out;
-		}
 	}
+
 	/*
-	 * It is possible that the disk changing stuff resulted in the device
-	 * being taken offline.  If this is the case, report this to the user,
-	 * and don't pretend that the open actually succeeded.
+	 * It is possible that the disk changing stuff resulted in
+	 * the device being taken offline.  If this is the case,
+	 * report this to the user, and don't pretend that the
+	 * open actually succeeded.
 	 */
-	if (!sdp->online) {
+	retval = -ENXIO;
+	if (!sdev->online)
 		goto error_out;
-	}
 
-	if (sdp->removable)
-		if (sdp->access_count==1)
-			if (scsi_block_when_processing_errors(sdp))
-				scsi_set_medium_removal(sdp, SCSI_REMOVAL_PREVENT);
+	if (sdev->removable && sdev->access_count == 1)
+		if (scsi_block_when_processing_errors(sdev))
+			scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
 
 	return 0;
 
 error_out:
-	sdp->access_count--;
-	module_put(sdp->host->hostt->module);
+	scsi_device_put(sdev);
 	return retval;	
 }
 
@@ -513,36 +436,189 @@
 static int sd_release(struct inode *inode, struct file *filp)
 {
 	struct gendisk *disk = inode->i_bdev->bd_disk;
-	struct scsi_disk *sdkp = scsi_disk(disk);
-	struct scsi_device *sdp = sdkp->device;
+	struct scsi_device *sdev = scsi_disk(disk)->device;
 
 	SCSI_LOG_HLQUEUE(3, printk("sd_release: disk=%s\n", disk->disk_name));
-	if (!sdp)
-		return -ENODEV; /* open uses ENXIO ?? */
 
-	/* ... and what if there are packets in flight and this close()
-	 * is followed by a "rmmod sd_mod" */
+	if (sdev->removable && sdev->access_count == 1)
+		if (scsi_block_when_processing_errors(sdev))
+			scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW);
 
-	sdp->access_count--;
+	/*
+	 * XXX and what if there are packets in flight and this close()
+	 * XXX is followed by a "rmmod sd_mod"?
+	 */
+	scsi_device_put(sdev);
+	return 0;
+}
 
-	if (sdp->removable) {
-		if (!sdp->access_count)
-			if (scsi_block_when_processing_errors(sdp))
-				scsi_set_medium_removal(sdp, SCSI_REMOVAL_ALLOW);
-	}
-	module_put(sdp->host->hostt->module);
+static int sd_hdio_getgeo(struct block_device *bdev, struct hd_geometry *loc)
+{
+	struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk);
+	struct scsi_device *sdp = sdkp->device;
+	struct Scsi_Host *host = sdp->host;
+	int diskinfo[4];
 
+	/* default to most commonly used values */
+        diskinfo[0] = 0x40;	/* 1 << 6 */
+       	diskinfo[1] = 0x20;	/* 1 << 5 */
+       	diskinfo[2] = sdkp->capacity >> 11;
+	
+	/* override with calculated, extended default, or driver values */
+	if (host->hostt->bios_param)
+		host->hostt->bios_param(sdp, bdev, sdkp->capacity, diskinfo);
+	else
+		scsicam_bios_param(bdev, sdkp->capacity, diskinfo);
+
+	if (put_user(diskinfo[0], &loc->heads))
+		return -EFAULT;
+	if (put_user(diskinfo[1], &loc->sectors))
+		return -EFAULT;
+	if (put_user(diskinfo[2], &loc->cylinders))
+		return -EFAULT;
+	if (put_user((unsigned)get_start_sect(bdev),
+	             (unsigned long *)&loc->start))
+		return -EFAULT;
 	return 0;
 }
 
-static struct block_device_operations sd_fops =
+/**
+ *	sd_ioctl - process an ioctl
+ *	@inode: only i_rdev/i_bdev members may be used
+ *	@filp: only f_mode and f_flags may be used
+ *	@cmd: ioctl command number
+ *	@arg: this is third argument given to ioctl(2) system call.
+ *	Often contains a pointer.
+ *
+ *	Returns 0 if successful (some ioctls return postive numbers on
+ *	success as well). Returns a negated errno value in case of error.
+ *
+ *	Note: most ioctls are forward onto the block subsystem or further
+ *	down in the scsi subsytem.
+ **/
+static int sd_ioctl(struct inode * inode, struct file * filp, 
+		    unsigned int cmd, unsigned long arg)
+{
+	struct block_device *bdev = inode->i_bdev;
+	struct gendisk *disk = bdev->bd_disk;
+	struct scsi_device *sdp = scsi_disk(disk)->device;
+	int error;
+    
+	SCSI_LOG_IOCTL(1, printk("sd_ioctl: disk=%s, cmd=0x%x\n",
+						disk->disk_name, cmd));
+
+	/*
+	 * If we are in the middle of error recovery, don't let anyone
+	 * else try and use this device.  Also, if error recovery fails, it
+	 * may try and take the device offline, in which case all further
+	 * access to the device is prohibited.
+	 */
+	if (!scsi_block_when_processing_errors(sdp))
+		return -ENODEV;
+
+	if (cmd == HDIO_GETGEO) {
+		if (!arg)
+			return -EINVAL;
+		return sd_hdio_getgeo(bdev, (struct hd_geometry *)arg);
+	}
+
+	error = scsi_cmd_ioctl(bdev, cmd, arg);
+	if (error != -ENOTTY)
+		return error;
+	return scsi_ioctl(sdp, cmd, (void *)arg);
+}
+
+static void set_media_not_present(struct scsi_disk *sdkp)
+{
+	sdkp->media_present = 0;
+	sdkp->capacity = 0;
+	sdkp->device->changed = 1;
+}
+
+/**
+ *	sd_media_changed - check if our medium changed
+ *	@disk: kernel device descriptor 
+ *
+ *	Returns 0 if not applicable or no change; 1 if change
+ *
+ *	Note: this function is invoked from the block subsystem.
+ **/
+static int sd_media_changed(struct gendisk *disk)
+{
+	struct scsi_disk *sdkp = scsi_disk(disk);
+	struct scsi_device *sdp = sdkp->device;
+	int retval;
+
+	SCSI_LOG_HLQUEUE(3, printk("sd_media_changed: disk=%s\n",
+						disk->disk_name));
+
+	if (!sdp->removable)
+		return 0;
+
+	/*
+	 * If the device is offline, don't send any commands - just pretend as
+	 * if the command failed.  If the device ever comes back online, we
+	 * can deal with it then.  It is only because of unrecoverable errors
+	 * that we would ever take a device offline in the first place.
+	 */
+	if (!sdp->online)
+		goto not_present;
+
+	/*
+	 * Using TEST_UNIT_READY enables differentiation between drive with
+	 * no cartridge loaded - NOT READY, drive with changed cartridge -
+	 * UNIT ATTENTION, or with same cartridge - GOOD STATUS.
+	 *
+	 * Drives that auto spin down. eg iomega jaz 1G, will be started
+	 * by sd_spinup_disk() from sd_init_onedisk(), which happens whenever
+	 * sd_revalidate() is called.
+	 */
+	retval = -ENODEV;
+	if (scsi_block_when_processing_errors(sdp))
+		retval = scsi_ioctl(sdp, SCSI_IOCTL_TEST_UNIT_READY, NULL);
+
+	/*
+	 * Unable to test, unit probably not ready.   This usually
+	 * means there is no disc in the drive.  Mark as changed,
+	 * and we will figure it out later once the drive is
+	 * available again.
+	 */
+	if (retval)
+		 goto not_present;
+
+	/*
+	 * For removable scsi disk we have to recognise the presence
+	 * of a disk in the drive. This is kept in the struct scsi_disk
+	 * struct and tested at open !  Daniel Roche (dan@lectra.fr)
+	 */
+	sdkp->media_present = 1;
+
+	retval = sdp->changed;
+	sdp->changed = 0;
+
+	return retval;
+
+not_present:
+	set_media_not_present(sdkp);
+	return 1;
+}
+
+static int sd_revalidate_disk(struct gendisk *disk)
 {
-	.owner		= THIS_MODULE,
-	.open		= sd_open,
-	.release	= sd_release,
-	.ioctl		= sd_ioctl,
-	.media_changed	= check_scsidisk_media_change,
-	.revalidate_disk= sd_revalidate
+	struct scsi_disk *sdkp = scsi_disk(disk);
+
+	sd_init_onedisk(sdkp, disk);
+	set_capacity(disk, sdkp->capacity);
+	return 0;
+}
+
+static struct block_device_operations sd_fops = {
+	.owner			= THIS_MODULE,
+	.open			= sd_open,
+	.release		= sd_release,
+	.ioctl			= sd_ioctl,
+	.media_changed		= sd_media_changed,
+	.revalidate_disk	= sd_revalidate_disk,
 };
 
 /**
@@ -647,99 +723,20 @@
 	scsi_io_completion(SCpnt, good_sectors, block_sectors);
 }
 
-static void
-sd_set_media_not_present(struct scsi_disk *sdkp) {
-	sdkp->media_present = 0;
-	sdkp->capacity = 0;
-	sdkp->device->changed = 1;
-}
-
-/**
- *	check_scsidisk_media_change - self descriptive
- *	@full_dev: kernel device descriptor (kdev_t)
- *
- *	Returns 0 if not applicable or no change; 1 if change
- *
- *	Note: this function is invoked from the block subsystem.
- **/
-static int check_scsidisk_media_change(struct gendisk *disk)
+static int media_not_present(struct scsi_disk *sdkp, struct scsi_request *srp)
 {
-	struct scsi_disk *sdkp = scsi_disk(disk);
-	struct scsi_device *sdp = sdkp->device;
-	int retval;
-	int flag = 0;	/* <<<< what is this for?? */
-
-	SCSI_LOG_HLQUEUE(3, printk("check_scsidisk_media_change: "
-			    "disk=%s\n", disk->disk_name));
-	if (!sdp) {
-		printk(KERN_ERR "check_scsidisk_media_change: disk=%s, "
-		       "invalid device\n", disk->disk_name);
+	if (!srp->sr_result)
 		return 0;
-	}
-	if (!sdp->removable)
+	if (!(driver_byte(srp->sr_result) & DRIVER_SENSE))
+		return 0;
+	if (srp->sr_sense_buffer[2] != NOT_READY &&
+	    srp->sr_sense_buffer[2] != UNIT_ATTENTION)
+	    	return 0;
+	if (srp->sr_sense_buffer[12] != 0x3A) /* medium not present */
 		return 0;
 
-	/*
-	 * If the device is offline, don't send any commands - just pretend as
-	 * if the command failed.  If the device ever comes back online, we
-	 * can deal with it then.  It is only because of unrecoverable errors
-	 * that we would ever take a device offline in the first place.
-	 */
-	if (sdp->online == FALSE) {
-		sd_set_media_not_present(sdkp);
-		return 1;	/* This will force a flush, if called from
-				 * check_disk_change */
-	}
-
-	/* Using TEST_UNIT_READY enables differentiation between drive with
-	 * no cartridge loaded - NOT READY, drive with changed cartridge -
-	 * UNIT ATTENTION, or with same cartridge - GOOD STATUS.
-	 *
-	 * Drives that auto spin down. eg iomega jaz 1G, will be started
-	 * by sd_spinup_disk() from sd_init_onedisk(), which happens whenever
-	 * sd_revalidate() is called.
-	 */
-	retval = -ENODEV;
-	if (scsi_block_when_processing_errors(sdp))
-		retval = scsi_ioctl(sdp, SCSI_IOCTL_TEST_UNIT_READY, NULL);
-
-	if (retval) {		/* Unable to test, unit probably not ready.
-				 * This usually means there is no disc in the
-				 * drive.  Mark as changed, and we will figure
-				 * it out later once the drive is available
-				 * again.  */
-
-		sd_set_media_not_present(sdkp);
-		return 1;	/* This will force a flush, if called from
-				 * check_disk_change */
-	}
-	/*
-	 * For removable scsi disk we have to recognise the presence
-	 * of a disk in the drive. This is kept in the struct scsi_disk
-	 * struct and tested at open !  Daniel Roche ( dan@lectra.fr )
-	 */
-
-	sdkp->media_present = 1;
-
-	retval = sdp->changed;
-	if (!flag)
-		sdp->changed = 0;
-	return retval;
-}
-
-static int
-sd_media_not_present(struct scsi_disk *sdkp, struct scsi_request *SRpnt) {
-	int the_result = SRpnt->sr_result;
-
-	if (the_result != 0
-	    && (driver_byte(the_result) & DRIVER_SENSE) != 0
-	    && (SRpnt->sr_sense_buffer[2] == NOT_READY ||
-		SRpnt->sr_sense_buffer[2] == UNIT_ATTENTION)
-	    && SRpnt->sr_sense_buffer[12] == 0x3A /* medium not present */) {
-		sd_set_media_not_present(sdkp);
-		return 1;
-	}
-	return 0;
+	set_media_not_present(sdkp);
+	return 1;
 }
 
 /*
@@ -783,7 +780,7 @@
 		 * any media in it, don't bother with any of the rest of
 		 * this crap.
 		 */
-		if (sd_media_not_present(sdkp, SRpnt))
+		if (media_not_present(sdkp, SRpnt))
 			return;
 
 		/* Look for devices that return NOT_READY.
@@ -926,7 +923,7 @@
 		scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer,
 			      8, SD_TIMEOUT, SD_MAX_RETRIES);
 
-		if (sd_media_not_present(sdkp, SRpnt))
+		if (media_not_present(sdkp, SRpnt))
 			return;
 
 		the_result = SRpnt->sr_result;
@@ -1175,19 +1172,22 @@
  **/
 static int sd_attach(struct scsi_device * sdp)
 {
-	struct scsi_disk *sdkp = NULL;	/* shut up lame gcc warning */
-	int dsk_nr;
+	struct scsi_disk *sdkp;
 	struct gendisk *gd;
+	u32 index;
+	int error;
 
 	if ((sdp->type != TYPE_DISK) && (sdp->type != TYPE_MOD))
-		return 0;
+		return 1;
 
 	SCSI_LOG_HLQUEUE(3, printk("sd_attach: scsi device: <%d,%d,%d,%d>\n", 
 			 sdp->host->host_no, sdp->channel, sdp->id, sdp->lun));
 
-	if (scsi_slave_attach(sdp))
+	error = scsi_slave_attach(sdp);
+	if (error)
 		goto out;
 
+	error = -ENOMEM;
 	sdkp = kmalloc(sizeof(*sdkp), GFP_KERNEL);
 	if (!sdkp)
 		goto out_detach;
@@ -1196,28 +1196,33 @@
 	if (!gd)
 		goto out_free;
 
-	/*
-	 * XXX  This doesn't make us better than the previous code in the
-	 * XXX  end (not worse either, though..).
-	 * XXX  To properly support hotplugging we should have a bitmap and
-	 * XXX  use find_first_zero_bit on it.  This will happen at the
-	 * XXX  same time template->nr_* goes away.		--hch
-	 */
-	dsk_nr = sd_nr_dev++;
+	spin_lock(&sd_index_lock);
+	index = find_first_zero_bit(sd_index_bits, SD_DISKS);
+	if (index == SD_DISKS) {
+		spin_unlock(&sd_index_lock);
+		error = -EBUSY;
+		goto out_put;
+	}
+	__set_bit(index, sd_index_bits);
+	spin_unlock(&sd_index_lock);
 
 	sdkp->device = sdp;
 	sdkp->driver = &sd_template;
 	sdkp->disk = gd;
+	sdkp->index = index;
 
 	gd->de = sdp->de;
-	gd->major = SD_MAJOR(dsk_nr>>4);
-	gd->first_minor = (dsk_nr & 15)<<4;
+	gd->major = sd_major(index >> 4);
+	gd->first_minor = (index & 15) << 4;
 	gd->minors = 16;
 	gd->fops = &sd_fops;
-	if (dsk_nr > 26)
-		sprintf(gd->disk_name, "sd%c%c",'a'+dsk_nr/26-1,'a'+dsk_nr%26);
-	else
-		sprintf(gd->disk_name, "sd%c",'a'+dsk_nr%26);
+
+	if (index > 26) {
+		sprintf(gd->disk_name, "sd%c%c",
+			'a' + index/26-1,'a' + index % 26);
+	} else {
+		sprintf(gd->disk_name, "sd%c", 'a' + index % 26);
+	}
 
 	sd_init_onedisk(sdkp, gd);
 
@@ -1239,24 +1244,14 @@
 
 	return 0;
 
+out_put:
+	put_disk(gd);
 out_free:
 	kfree(sdkp);
 out_detach:
 	scsi_slave_detach(sdp);
 out:
-	return 1;
-}
-
-static int sd_revalidate(struct gendisk *disk)
-{
-	struct scsi_disk *sdkp = scsi_disk(disk);
-
-	if (!sdkp->device)
-		return -ENODEV;
-
-	sd_init_onedisk(sdkp, disk);
-	set_capacity(disk, sdkp->capacity);
-	return 0;
+	return error;
 }
 
 /**
@@ -1292,7 +1287,11 @@
 	sd_devlist_remove(sdkp);
 	del_gendisk(sdkp->disk);
 	scsi_slave_detach(sdp);
-	sd_nr_dev--;
+
+	spin_lock(&sd_index_lock);
+	clear_bit(sdkp->index, sd_index_bits);
+	spin_unlock(&sd_index_lock);
+
 	put_disk(sdkp->disk);
 	kfree(sdkp);
 }
@@ -1310,10 +1309,10 @@
 	SCSI_LOG_HLQUEUE(3, printk("init_sd: sd driver entry point\n"));
 
 	for (i = 0; i < SD_MAJORS; i++) {
-		if (register_blkdev(SD_MAJOR(i), "sd", &sd_fops))
+		if (register_blkdev(sd_major(i), "sd", &sd_fops))
 			printk(KERN_NOTICE
 			       "Unable to get major %d for SCSI disk\n",
-			       SD_MAJOR(i));
+			       sd_major(i));
 		else
 			majors++;
 	}
@@ -1342,8 +1341,7 @@
 	unregister_reboot_notifier(&sd_notifier_block);
 	scsi_unregister_device(&sd_template);
 	for (i = 0; i < SD_MAJORS; i++)
-		unregister_blkdev(SD_MAJOR(i), "sd");
-	driver_unregister(&sd_template.scsi_driverfs_driver);
+		unregister_blkdev(sd_major(i), "sd");
 }
 
 /*
diff -Nru a/drivers/scsi/sg.c b/drivers/scsi/sg.c
--- a/drivers/scsi/sg.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/scsi/sg.c	Mon Dec  9 18:46:36 2002
@@ -122,10 +122,12 @@
 	.module = THIS_MODULE,
 	.list = LIST_HEAD_INIT(sg_template.list),
 	.name = "generic",
-	.tag = "sg",
 	.scsi_type = 0xff,
 	.attach = sg_attach,
-	.detach = sg_detach
+	.detach = sg_detach,
+	.scsi_driverfs_driver = {
+		.name = "sg",
+	},
 };
 
 typedef struct sg_scatter_hold { /* holding area for scsi scatter gather info */
@@ -259,9 +261,9 @@
 
 	/* This driver's module count bumped by fops_get in <linux/fs.h> */
 	/* Prevent the device driver from vanishing while we sleep */
-	if (!try_module_get(sdp->device->host->hostt->module))
-		return -ENXIO;
-	sdp->device->access_count++;
+	retval = scsi_device_get(sdp->device);
+	if (retval)
+		return retval;
 
 	if (!((flags & O_NONBLOCK) ||
 	      scsi_block_when_processing_errors(sdp->device))) {
@@ -314,8 +316,7 @@
 	return 0;
 
       error_out:
-	sdp->device->access_count--;
-	module_put(sdp->device->host->hostt->module);
+	scsi_device_put(sdp->device);
 	return retval;
 }
 
@@ -332,8 +333,7 @@
 	sg_fasync(-1, filp, 0);	/* remove filp from async notification list */
 	if (0 == sg_remove_sfp(sdp, sfp)) {	/* Returns 1 when sdp gone */
 		if (!sdp->detached) {
-			sdp->device->access_count--;
-			module_put(sdp->device->host->hostt->module);
+			scsi_device_put(sdp->device);
 		}
 		sdp->exclude = 0;
 		wake_up_interruptible(&sdp->o_excl_wait);
@@ -1296,8 +1296,7 @@
 		if (NULL == sfp->headrp) {
 			SCSI_LOG_TIMEOUT(1, printk("sg...bh: already closed, final cleanup\n"));
 			if (0 == sg_remove_sfp(sdp, sfp)) {	/* device still present */
-				sdp->device->access_count--;
-				module_put(sdp->device->host->hostt->module);
+				scsi_device_put(sdp->device);
 			}
 			sfp = NULL;
 		}
@@ -1372,15 +1371,19 @@
 static int
 sg_attach(Scsi_Device * scsidp)
 {
-	struct gendisk *disk = alloc_disk(1);
+	struct gendisk *disk;
 	Sg_device *sdp = NULL;
 	unsigned long iflags;
-	int k;
+	int k, error;
 
+	disk = alloc_disk(1);
 	if (!disk)
-		return 1;
-	if (scsi_slave_attach(scsidp))
-		return 1;
+		return -ENOMEM;
+
+	error = scsi_slave_attach(scsidp);
+	if (error)
+		goto out_put;
+		
 	write_lock_irqsave(&sg_dev_arr_lock, iflags);
 	if (sg_nr_dev >= sg_dev_max) {	/* try to resize */
 		Sg_device **tmp_da;
@@ -1392,9 +1395,8 @@
 		if (NULL == tmp_da) {
 			printk(KERN_ERR
 			       "sg_attach: device array cannot be resized\n");
-			put_disk(disk);
-			scsi_slave_detach(scsidp);
-			return 1;
+			error = -ENOMEM;
+			goto out_detach;
 		}
 		write_lock_irqsave(&sg_dev_arr_lock, iflags);
 		memset(tmp_da, 0, tmp_dev_max * sizeof (Sg_device *));
@@ -1418,9 +1420,8 @@
 		       scsidp->lun, scsidp->type, SG_MAX_DEVS_MASK);
 		if (NULL != sdp)
 			vfree((char *) sdp);
-		put_disk(disk);
-		scsi_slave_detach(scsidp);
-		return 1;
+		error = -ENODEV;
+		goto out_detach;
 	}
 	if (k < sg_dev_max) {
 		if (NULL == sdp) {
@@ -1435,9 +1436,8 @@
 	if (NULL == sdp) {
 		write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
 		printk(KERN_ERR "sg_attach: Sg_device cannot be allocated\n");
-		put_disk(disk);
-		scsi_slave_detach(scsidp);
-		return 1;
+		error = -ENOMEM;
+		goto out_detach;
 	}
 
 	SCSI_LOG_TIMEOUT(3, printk("sg_attach: dev=%d \n", k));
@@ -1462,7 +1462,7 @@
 	sprintf(sdp->sg_driverfs_dev.name, "%sgeneric",
 		scsidp->sdev_driverfs_dev.name);
 	sdp->sg_driverfs_dev.parent = &scsidp->sdev_driverfs_dev;
-	sdp->sg_driverfs_dev.bus = &scsi_driverfs_bus_type;
+	sdp->sg_driverfs_dev.bus = scsidp->sdev_driverfs_dev.bus;
 
 	sg_nr_dev++;
 	sg_dev_arr[k] = sdp;
@@ -1490,6 +1490,12 @@
 		       scsidp->lun, scsidp->type);
 	}
 	return 0;
+
+out_detach:
+	scsi_slave_detach(scsidp);
+out_put:
+	put_disk(disk);
+	return error;
 }
 
 static void
@@ -1521,8 +1527,7 @@
 						sg_finish_rem_req(srp);
 				}
 				if (sfp->closed) {
-					sdp->device->access_count--;
-					module_put(sdp->device->host->hostt->module);
+					scsi_device_put(sdp->device);
 					__sg_remove_sfp(sdp, sfp);
 				} else {
 					delay = 1;
@@ -2510,8 +2515,7 @@
 		/* MOD_INC's to inhibit unloading sg and associated adapter driver */
 		/* only bump the access_count if we actually succeeded in
 		 * throwing another counter on the host module */
-		if(try_module_get(sdp->device->host->hostt->module))
-			sdp->device->access_count++;
+		scsi_device_get(sdp->device);	/* XXX: retval ignored? */	
 		sfp->closed = 1;	/* flag dirty state on this fd */
 		SCSI_LOG_TIMEOUT(1, printk("sg_remove_sfp: worrisome, %d writes pending\n",
 				  dirty));
diff -Nru a/drivers/scsi/sim710.h b/drivers/scsi/sim710.h
--- a/drivers/scsi/sim710.h	Mon Dec  9 18:46:37 2002
+++ b/drivers/scsi/sim710.h	Mon Dec  9 18:46:37 2002
@@ -14,8 +14,6 @@
 int sim710_bus_reset(Scsi_Cmnd * SCpnt);
 int sim710_dev_reset(Scsi_Cmnd * SCpnt);
 int sim710_host_reset(Scsi_Cmnd * SCpnt);
-int sim710_biosparam(struct scsi_device *, struct block_device *,
-		sector_t, int*);
 #ifdef MODULE
 int sim710_release(struct Scsi_Host *);
 #else
diff -Nru a/drivers/scsi/sr.c b/drivers/scsi/sr.c
--- a/drivers/scsi/sr.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/scsi/sr.c	Mon Dec  9 18:46:35 2002
@@ -32,8 +32,6 @@
  *	check resource allocation in sr_init and some cleanups
  */
 
-#define MAJOR_NR SCSI_CDROM_MAJOR
-
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/kernel.h>
@@ -57,6 +55,9 @@
 
 MODULE_PARM(xa_test, "i");	/* see sr_ioctl.c */
 
+
+#define SR_DISKS	(1 << KDEV_MINOR_BITS)
+
 #define MAX_RETRIES	3
 #define SR_TIMEOUT	(30 * HZ)
 #define SR_CAPABILITIES \
@@ -73,18 +74,24 @@
 	.module		= THIS_MODULE,
 	.list		= LIST_HEAD_INIT(sr_template.list),
 	.name		= "cdrom",
-	.tag		= "sr",
 	.scsi_type	= TYPE_ROM,
 	.attach		= sr_attach,
 	.detach		= sr_detach,
-	.init_command	= sr_init_command
+	.init_command	= sr_init_command,
+	.scsi_driverfs_driver = {
+		.name   = "sr",
+	},
 };
 
-static int sr_nr_dev;	/* XXX(hch) bad hack, we want a bitmap instead */
 static LIST_HEAD(sr_devlist);
 static spinlock_t sr_devlist_lock = SPIN_LOCK_UNLOCKED;
 
+static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG];
+static spinlock_t sr_index_lock = SPIN_LOCK_UNLOCKED;
+
 static int sr_open(struct cdrom_device_info *, int);
+static void sr_release(struct cdrom_device_info *);
+
 static void get_sectorsize(struct scsi_cd *);
 static void get_capabilities(struct scsi_cd *);
 
@@ -122,16 +129,6 @@
 	spin_unlock(&sr_devlist_lock);
 }
 
-static void sr_release(struct cdrom_device_info *cdi)
-{
-	struct scsi_cd *cd = cdi->handle;
-
-	if (cd->device->sector_size > 2048)
-		sr_set_blocklength(cd, 2048);
-	cd->device->access_count--;
-	module_put(cd->device->host->hostt->module);
-}
-
 static struct cdrom_device_ops sr_dops = {
 	.open			= sr_open,
 	.release	 	= sr_release,
@@ -458,43 +455,59 @@
 static int sr_open(struct cdrom_device_info *cdi, int purpose)
 {
 	struct scsi_cd *cd = cdi->handle;
+	struct scsi_device *sdev = cd->device;
+	int retval;
 
-	if (!cd->device)
-		return -ENXIO;	/* No such device */
+	retval = scsi_device_get(sdev);
+	if (retval)
+		return retval;
+	
 	/*
 	 * If the device is in error recovery, wait until it is done.
 	 * If the device is offline, then disallow any access to it.
 	 */
-	if (!scsi_block_when_processing_errors(cd->device)) {
-		return -ENXIO;
-	}
-	if(!try_module_get(cd->device->host->hostt->module))
-		return -ENXIO;
-	cd->device->access_count++;
+	retval = -ENXIO;
+	if (!scsi_block_when_processing_errors(sdev))
+		goto error_out;
 
-	/* If this device did not have media in the drive at boot time, then
+	/*
+	 * If this device did not have media in the drive at boot time, then
 	 * we would have been unable to get the sector size.  Check to see if
 	 * this is the case, and try again.
 	 */
-
 	if (cd->needs_sector_size)
 		get_sectorsize(cd);
-
 	return 0;
+
+error_out:
+	scsi_device_put(sdev);
+	return retval;	
+}
+
+static void sr_release(struct cdrom_device_info *cdi)
+{
+	struct scsi_cd *cd = cdi->handle;
+
+	if (cd->device->sector_size > 2048)
+		sr_set_blocklength(cd, 2048);
+
+	scsi_device_put(cd->device);
 }
 
 static int sr_attach(struct scsi_device *sdev)
 {
 	struct gendisk *disk;
 	struct scsi_cd *cd;
-	int minor;
+	int minor, error;
 
 	if (sdev->type != TYPE_ROM && sdev->type != TYPE_WORM)
 		return 1;
 
-	if (scsi_slave_attach(sdev))
-		return 1;
+	error = scsi_slave_attach(sdev);
+	if (error)
+		return error;
 
+	error = -ENOMEM;
 	cd = kmalloc(sizeof(*cd), GFP_KERNEL);
 	if (!cd)
 		goto fail;
@@ -504,16 +517,17 @@
 	if (!disk)
 		goto fail_free;
 
-	/*
-	 * XXX  This doesn't make us better than the previous code in the
-	 * XXX  end (not worse either, though..).
-	 * XXX  To properly support hotplugging we should have a bitmap and
-	 * XXX  use find_first_zero_bit on it.  This will happen at the
-	 * XXX  same time template->nr_* goes away.		--hch
-	 */
-	minor = sr_nr_dev++;
+	spin_lock(&sr_index_lock);
+	minor = find_first_zero_bit(sr_index_bits, SR_DISKS);
+	if (minor == SR_DISKS) {
+		spin_unlock(&sr_index_lock);
+		error = -EBUSY;
+		goto fail_put;
+	}
+	__set_bit(minor, sr_index_bits);
+	spin_unlock(&sr_index_lock);
 
-	disk->major = MAJOR_NR;
+	disk->major = SCSI_CDROM_MAJOR;
 	disk->first_minor = minor;
 	sprintf(disk->disk_name, "sr%d", minor);
 	disk->fops = &sr_bdops;
@@ -560,11 +574,13 @@
 	    sdev->id, sdev->lun);
 	return 0;
 
+fail_put:
+	put_disk(disk);
 fail_free:
 	kfree(cd);
 fail:
 	scsi_slave_detach(sdev);
-	return 1;
+	return error;
 }
 
 
@@ -792,13 +808,15 @@
 		return;
 
 	sr_devlist_remove(cd);
+	scsi_slave_detach(SDp);
 	del_gendisk(cd->disk);
-	put_disk(cd->disk);
-	unregister_cdrom(&cd->cdi);
 
-	scsi_slave_detach(SDp);
-	sr_nr_dev--;
+	spin_lock(&sr_index_lock);
+	clear_bit(cd->disk->first_minor, sr_index_bits);
+	spin_unlock(&sr_index_lock);
 
+	put_disk(cd->disk);
+	unregister_cdrom(&cd->cdi);
 	kfree(cd);
 }
 
@@ -806,7 +824,7 @@
 {
 	int rc;
 
-	rc = register_blkdev(MAJOR_NR, "sr", &sr_bdops);
+	rc = register_blkdev(SCSI_CDROM_MAJOR, "sr", &sr_bdops);
 	if (rc)
 		return rc;
 	return scsi_register_device(&sr_template);
@@ -815,7 +833,7 @@
 static void __exit exit_sr(void)
 {
 	scsi_unregister_device(&sr_template);
-	unregister_blkdev(MAJOR_NR, "sr");
+	unregister_blkdev(SCSI_CDROM_MAJOR, "sr");
 }
 
 module_init(init_sr);
diff -Nru a/drivers/scsi/st.c b/drivers/scsi/st.c
--- a/drivers/scsi/st.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/scsi/st.c	Mon Dec  9 18:46:50 2002
@@ -33,7 +33,7 @@
 #include <linux/ioctl.h>
 #include <linux/fcntl.h>
 #include <linux/spinlock.h>
-#include <linux/smp_lock.h>
+#include <linux/blk.h>
 #include <asm/uaccess.h>
 #include <asm/dma.h>
 #include <asm/system.h>
@@ -54,9 +54,6 @@
 #define DEBC(a)
 #endif
 
-#define MAJOR_NR SCSI_TAPE_MAJOR
-#define DEVICE_NR(device) (minor(device) & 0x7f)
-#include <linux/blk.h>
 
 #include "scsi.h"
 #include "hosts.h"
@@ -176,10 +173,12 @@
 	.module =	THIS_MODULE,
 	.list =		LIST_HEAD_INIT(st_template.list),
 	.name =		"tape", 
-	.tag =		"st", 
 	.scsi_type =	TYPE_TAPE,
 	.attach =	st_attach, 
-	.detach =	st_detach
+	.detach =	st_detach,
+	.scsi_driverfs_driver = {
+		.name = "st",
+	},
 };
 
 static int st_compression(Scsi_Tape *, int);
@@ -991,9 +990,9 @@
 		DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); )
 		return (-EBUSY);
 	}
-	if(!try_module_get(STp->device->host->hostt->module))
+
+	if(!scsi_device_get(STp->device))
 		return (-ENXIO);
-	STp->device->access_count++;
 	STp->in_use = 1;
 	write_unlock(&st_dev_arr_lock);
 	STp->rew_at_close = STp->autorew_dev = (minor(inode->i_rdev) & 0x80) == 0;
@@ -1038,8 +1037,7 @@
  err_out:
 	normalize_buffer(STp->buffer);
 	STp->in_use = 0;
-	STp->device->access_count--;
-	module_put(STp->device->host->hostt->module);
+	scsi_device_put(STp->device);
 	return retval;
 
 }
@@ -1172,8 +1170,7 @@
 	write_lock(&st_dev_arr_lock);
 	STp->in_use = 0;
 	write_unlock(&st_dev_arr_lock);
-	STp->device->access_count--;
-	module_put(STp->device->host->hostt->module);
+	scsi_device_put(STp->device);
 
 	return result;
 }
@@ -3768,13 +3765,14 @@
 	tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma;
 	bounce_limit = BLK_BOUNCE_HIGH; /* Borrowed from scsi_merge.c */
 	if (SDp->host->highmem_io) {
+		struct device *dev = scsi_get_device(SDp->host);
 		if (!PCI_DMA_BUS_IS_PHYS)
 			/* Platforms with virtual-DMA translation
 			 * hardware have no practical limit.
 			 */
 			bounce_limit = BLK_BOUNCE_ANY;
-		else if (SDp->host->pci_dev)
-			bounce_limit = SDp->host->pci_dev->dma_mask;
+		else if (dev && dev->dma_mask)
+			bounce_limit = *dev->dma_mask;
 	} else if (SDp->host->unchecked_isa_dma)
 		bounce_limit = BLK_BOUNCE_ISA;
 	bounce_limit >>= PAGE_SHIFT;
@@ -3826,7 +3824,7 @@
 	    sprintf(tpnt->driverfs_dev_r[mode].name, "%s%s", 
 		    SDp->sdev_driverfs_dev.name, name);
 	    tpnt->driverfs_dev_r[mode].parent = &SDp->sdev_driverfs_dev;
-	    tpnt->driverfs_dev_r[mode].bus = &scsi_driverfs_bus_type;
+	    tpnt->driverfs_dev_r[mode].bus = SDp->sdev_driverfs_dev.bus;
 	    tpnt->driverfs_dev_r[mode].driver_data =
 			(void *)(long)__mkdev(SCSI_TAPE_MAJOR, dev_num + (mode << 5));
 	    device_register(&tpnt->driverfs_dev_r[mode]);
@@ -3845,7 +3843,7 @@
 	    sprintf(tpnt->driverfs_dev_n[mode].name, "%s%s", 
 		    SDp->sdev_driverfs_dev.name, name);
 	    tpnt->driverfs_dev_n[mode].parent= &SDp->sdev_driverfs_dev;
-	    tpnt->driverfs_dev_n[mode].bus = &scsi_driverfs_bus_type;
+	    tpnt->driverfs_dev_n[mode].bus = SDp->sdev_driverfs_dev.bus;
 	    tpnt->driverfs_dev_n[mode].driver_data =
 			(void *)(long)__mkdev(SCSI_TAPE_MAJOR, dev_num + (mode << 5) + 128);
 	    device_register(&tpnt->driverfs_dev_n[mode]);
diff -Nru a/drivers/serial/8250.c b/drivers/serial/8250.c
--- a/drivers/serial/8250.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/serial/8250.c	Mon Dec  9 18:46:34 2002
@@ -517,7 +517,7 @@
 	unsigned char save_lcr, save_mcr;
 	unsigned long flags;
 
-	if (!up->port.iobase && !up->port.membase)
+	if (!up->port.iobase && !up->port.mapbase && !up->port.membase)
 		return;
 
 	DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04x, 0x%08lx): ",
@@ -1031,7 +1031,7 @@
 
 		ret = request_irq(up->port.irq, serial8250_interrupt,
 				  irq_flags, "serial", i);
-		if (ret)
+		if (ret < 0)
 			serial_do_unlink(i, up);
 	}
 
@@ -1623,7 +1623,7 @@
 	if (up->port.flags & UPF_RESOURCES) {
 		if (up->port.type == PORT_RSA) {
 			ret = serial8250_request_rsa_resource(up, &res_rsa);
-			if (ret)
+			if (ret < 0)
 				return ret;
 		}
 
@@ -1641,7 +1641,7 @@
 			ret = -ENOMEM;
 	}
 
-	if (ret) {
+	if (ret < 0) {
 		if (res_rsa)
 			release_resource(res_rsa);
 		if (res)
@@ -1671,11 +1671,11 @@
 	 */
 	if (up->port.flags & UPF_RESOURCES) {
 		ret = serial8250_request_std_resource(up, &res_std);
-		if (ret)
+		if (ret < 0)
 			return;
 
 		ret = serial8250_request_rsa_resource(up, &res_rsa);
-		if (ret)
+		if (ret < 0)
 			probeflags &= ~PROBE_RSA;
 	} else {
 		probeflags &= ~PROBE_RSA;
@@ -1950,6 +1950,7 @@
 	port.regshift = req->iomem_reg_shift;
 	port.iotype   = req->io_type;
 	port.flags    = req->flags | UPF_BOOT_AUTOCONF;
+	port.mapbase  = req->iomap_base;
 	port.line     = line;
 
 	if (share_irqs)
@@ -2029,11 +2030,10 @@
 		spin_lock_init(&irq_lists[i].lock);
 
 	ret = uart_register_driver(&serial8250_reg);
-	if (ret)
-		return ret;
+	if (ret >= 0)
+		serial8250_register_ports(&serial8250_reg);
 
-	serial8250_register_ports(&serial8250_reg);
-	return 0;
+	return ret;
 }
 
 static void __exit serial8250_exit(void)
diff -Nru a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
--- a/drivers/serial/8250_pci.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/serial/8250_pci.c	Mon Dec  9 18:46:50 2002
@@ -176,6 +176,7 @@
 		return 0;
 	}
 	req->io_type = SERIAL_IO_MEM;
+	req->iomap_base = port;
 	req->iomem_base = ioremap(port, board->uart_offset);
 	if (req->iomem_base == NULL)
 		return -ENOMEM;
@@ -262,12 +263,14 @@
  * 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.
+ *
+ * Note: some SIIG cards are probed by the parport_serial object.
  */
 
 #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, int enable)
+int pci_siig10x_fn(struct pci_dev *dev, int enable)
 {
 	u16 data, *p;
 
@@ -295,10 +298,12 @@
 	return 0;
 }
 
+EXPORT_SYMBOL(pci_siig10x_fn);
+
 #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, int enable)
+int pci_siig20x_fn(struct pci_dev *dev, int enable)
 {
 	u8 data;
 
@@ -317,6 +322,8 @@
 	}
 	return 0;
 }
+
+EXPORT_SYMBOL(pci_siig20x_fn);
 
 /* Added for EKF Intel i960 serial boards */
 static int __devinit pci_inteli960ni_fn(struct pci_dev *dev, int enable)
diff -Nru a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
--- a/drivers/serial/8250_pnp.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/serial/8250_pnp.c	Mon Dec  9 18:46:34 2002
@@ -33,12 +33,7 @@
 #define UNKNOWN_DEV 0x3000
 
 
-static const struct pnp_id pnp_card_table[] = {
-	{	"ANYDEVS",		0	},
-	{	"",			0	}
-};
-
-static const struct pnp_id pnp_dev_table[] = {
+static const struct pnp_device_id pnp_dev_table[] = {
 	/* Archtek America Corp. */
 	/* Archtek SmartLink Modem 3334BT Plug & Play */
 	{	"AAC000F",		0	},
@@ -316,6 +311,8 @@
 	{	"",			0	}
 };
 
+MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
+
 static void inline avoid_irq_share(struct pnp_dev *dev)
 {
 	unsigned int map = 0x1FF8;
@@ -384,7 +381,7 @@
 }
 
 static int
-serial_pnp_probe(struct pnp_dev * dev, const struct pnp_id *card_id, const struct pnp_id *dev_id)
+serial_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id)
 {
 	struct serial_struct serial_req;
 	int ret, line, flags = dev_id->driver_data;
@@ -393,10 +390,10 @@
 	if (flags & SPCI_FL_NO_SHIRQ)
 		avoid_irq_share(dev);
 	memset(&serial_req, 0, sizeof(serial_req));
-	serial_req.irq = dev->irq_resource[0].start;
-	serial_req.port = pci_resource_start(dev, 0);
+	serial_req.irq = pnp_irq(dev,0);
+	serial_req.port = pnp_port_start(dev, 0);
 	if (HIGH_BITS_OFFSET)
-		serial_req.port = dev->resource[0].start >> HIGH_BITS_OFFSET;
+		serial_req.port = pnp_port_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);
@@ -407,7 +404,7 @@
 	line = register_serial(&serial_req);
 
 	if (line >= 0)
-		dev->driver_data = (void *)(line + 1);
+		pnp_set_drvdata(dev, (void *)(line + 1));
 	return line >= 0 ? 0 : -ENODEV;
 
 }
@@ -419,7 +416,6 @@
 
 static struct pnp_driver serial_pnp_driver = {
 	.name		= "serial",
-	.card_id_table	= pnp_card_table,
 	.id_table	= pnp_dev_table,
 	.probe		= serial_pnp_probe,
 	.remove		= serial_pnp_remove,
@@ -442,5 +438,3 @@
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Generic 8250/16x50 PnP serial driver");
-/* FIXME */
-/*MODULE_DEVICE_TABLE(pnpbios, pnp_dev_table);*/
diff -Nru a/drivers/serial/Makefile b/drivers/serial/Makefile
--- a/drivers/serial/Makefile	Mon Dec  9 18:46:37 2002
+++ b/drivers/serial/Makefile	Mon Dec  9 18:46:37 2002
@@ -4,7 +4,7 @@
 #  $Id: Makefile,v 1.8 2002/07/21 21:32:30 rmk Exp $
 #
 
-export-objs	:= core.o 8250.o suncore.o
+export-objs	:= core.o 8250.o 8250_pci.o suncore.o
 
 serial-8250-y :=
 serial-8250-$(CONFIG_GSC) += 8250_gsc.o
diff -Nru a/drivers/serial/core.c b/drivers/serial/core.c
--- a/drivers/serial/core.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/serial/core.c	Mon Dec  9 18:46:35 2002
@@ -135,20 +135,6 @@
 #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.
@@ -167,10 +153,8 @@
 	 * once we have successfully opened the port.  Also set
 	 * up the tty->alt_speed kludge
 	 */
-	if (info->tty) {
+	if (info->tty)
 		set_bit(TTY_IO_ERROR, &info->tty->flags);
-		uart_update_altspeed(info);
-	}
 
 	if (port->type == PORT_UNKNOWN)
 		return 0;
@@ -276,43 +260,20 @@
 	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)
+/**
+ *	uart_update_timeout - update per-port FIFO timeout.
+ *	@port: uart_port structure describing the port.
+ *	@cflag: termios cflag value
+ *	@quot: uart clock divisor quotient
+ *
+ *	Set the port FIFO timeout value.  The @cflag value should
+ *	reflect the actual hardware settings.
+ */
+void
+uart_update_timeout(struct uart_port *port, unsigned int cflag,
+		    unsigned int quot)
 {
-	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;
+	unsigned int bits;
 
 	/* byte size and parity */
 	switch (cflag & CSIZE) {
@@ -335,12 +296,105 @@
 	if (cflag & PARENB)
 		bits++;
 
+	/*
+	 * The total number of bits to be transmitted in the fifo.
+	 */
+	bits = bits * port->fifosize;
+
+	/*
+	 * Figure the timeout to send the above number of bits.
+	 * Add .02 seconds of slop
+	 */
+	port->timeout = (HZ * bits) / (port->uartclk / (16 * quot)) + HZ/50;
+}
+
+EXPORT_SYMBOL(uart_update_timeout);
+
+/**
+ *	uart_get_baud_rate - return baud rate for a particular port
+ *	@port: uart_port structure describing the port in question.
+ *	@termios: desired termios settings.
+ *
+ *	Decode the termios structure into a numeric baud rate,
+ *	taking account of the magic 38400 baud rate (with spd_*
+ *	flags), and mapping the %B0 rate to 9600 baud.
+ */
+unsigned int
+uart_get_baud_rate(struct uart_port *port, struct termios *termios)
+{
+	unsigned int baud = tty_termios_baud_rate(termios);
+
+	/*
+	 * The spd_hi, spd_vhi, spd_shi, spd_warp kludge...
+	 * Die! Die! Die!
+	 */
+	if (baud == 38400) {
+		unsigned int flags = port->flags & UPF_SPD_MASK;
+
+		if (flags == UPF_SPD_HI)
+			baud = 57600;
+		if (flags == UPF_SPD_VHI)
+			baud = 115200;
+		if (flags == UPF_SPD_SHI)
+			baud = 230400;
+		if (flags == UPF_SPD_WARP)
+			baud = 460800;
+	}
+
+	/*
+	 * Special case: B0 rate.
+	 */
+	if (baud == 0)
+		baud = 9600;
+
+	return baud;
+}
+
+EXPORT_SYMBOL(uart_get_baud_rate);
+
+static inline unsigned int
+uart_calculate_quot(struct uart_port *port, unsigned int baud)
+{
+	unsigned int quot;
+
+	/*
+	 * Old custom speed handling.
+	 */
+	if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
+		quot = port->custom_divisor;
+	else
+		quot = port->uartclk / (16 * baud);
+
+	return quot;
+}
+
+/**
+ *	uart_get_divisor - return uart clock divisor
+ *	@port: uart_port structure describing the port.
+ *	@termios: desired termios settings
+ *	@old_termios: the original port settings, or NULL
+ *
+ *	Calculate the uart clock divisor for the port.  If the
+ *	divisor is invalid, try the old termios setting.  If
+ *	the divisor is still invalid, we try 9600 baud.
+ *
+ *	Update the @termios structure to reflect the baud rate
+ *	we're actually going to be using.
+ *
+ *	If 9600 baud fails, we return a zero divisor.
+ */
+unsigned int
+uart_get_divisor(struct uart_port *port, struct termios *termios,
+		 struct termios *old_termios)
+{
+	unsigned int quot, try;
+
 	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);
+		baud = uart_get_baud_rate(port, termios);
+		quot = uart_calculate_quot(port, baud);
 		if (quot)
 			break;
 
@@ -348,10 +402,9 @@
 		 * Oops, the quotient was zero.  Try again with
 		 * the old baud rate if possible.
 		 */
-		info->tty->termios->c_cflag &= ~CBAUD;
+		termios->c_cflag &= ~CBAUD;
 		if (old_termios) {
-			info->tty->termios->c_cflag |=
-				 (old_termios->c_cflag & CBAUD);
+			termios->c_cflag |= old_termios->c_cflag & CBAUD;
 			old_termios = NULL;
 			continue;
 		}
@@ -360,30 +413,48 @@
 		 * As a last resort, if the quotient is zero,
 		 * default to 9600 bps
 		 */
-		info->tty->termios->c_cflag |= B9600;
+		termios->c_cflag |= B9600;
 	}
 
+	return quot;
+}
+
+EXPORT_SYMBOL(uart_get_divisor);
+
+static void
+uart_change_speed(struct uart_info *info, struct termios *old_termios)
+{
+	struct tty_struct *tty = info->tty;
+	struct uart_port *port = info->port;
+	struct termios *termios;
+	unsigned int quot;
+
 	/*
-	 * The total number of bits to be transmitted in the fifo.
+	 * If we have no tty, termios, or the port does not exist,
+	 * then we can't set the parameters for this port.
 	 */
-	bits = bits * port->fifosize;
+	if (!tty || !tty->termios || port->type == PORT_UNKNOWN)
+		return;
+
+	termios = tty->termios;
 
 	/*
-	 * Figure the timeout to send the above number of bits.
-	 * Add .02 seconds of slop
+	 * Set flags based on termios cflag
 	 */
-	port->timeout = (HZ * bits) / (port->uartclk / (16 * quot)) + HZ/50;
-
-	if (cflag & CRTSCTS)
+	if (termios->c_cflag & CRTSCTS)
 		info->flags |= UIF_CTS_FLOW;
 	else
 		info->flags &= ~UIF_CTS_FLOW;
-	if (cflag & CLOCAL)
+
+	if (termios->c_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);
+	quot = uart_get_divisor(port, termios, old_termios);
+	uart_update_timeout(port, termios->c_cflag, quot);
+
+	port->ops->change_speed(port, termios->c_cflag, termios->c_iflag, quot);
 }
 
 static inline void
@@ -519,7 +590,7 @@
 	unsigned long flags;
 
 	DPRINTK("uart_flush_buffer(%d) called\n",
-	        MINOR(tty->device) - tty->driver.minor_start);
+	        minor(tty->device) - tty->driver.minor_start);
 
 	spin_lock_irqsave(&info->port->lock, flags);
 	uart_circ_clear(&info->xmit);
@@ -597,7 +668,7 @@
 	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.custom_divisor  = port->custom_divisor;
 	tmp.hub6	    = port->hub6;
 	tmp.io_type         = port->iotype;
 	tmp.iomem_reg_shift = port->regshift;
@@ -652,7 +723,7 @@
 		      new_serial.type != port->type;
 
 	old_flags = port->flags;
-	old_custom_divisor = state->custom_divisor;
+	old_custom_divisor = port->custom_divisor;
 
 	if (!capable(CAP_SYS_ADMIN)) {
 		retval = -EPERM;
@@ -665,7 +736,7 @@
 			goto exit;
 		port->flags = ((port->flags & ~UPF_USR_MASK) |
 			       (new_serial.flags & UPF_USR_MASK));
-		state->custom_divisor = new_serial.custom_divisor;
+		port->custom_divisor = new_serial.custom_divisor;
 		goto check_and_exit;
 	}
 
@@ -757,7 +828,7 @@
 	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;
+	port->custom_divisor   = new_serial.custom_divisor;
 	state->close_delay     = new_serial.close_delay * HZ / 100;
 	state->closing_wait    = new_serial.closing_wait * HZ / 100;
 	port->fifosize         = new_serial.xmit_fifo_size;
@@ -769,10 +840,8 @@
 		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);
+		    old_custom_divisor != port->custom_divisor)
 			uart_change_speed(info, NULL);
-		}
 	} else
 		retval = uart_startup(info, 1);
  exit:
@@ -1540,8 +1609,9 @@
 	 * Any failures from here onwards should not touch the count.
 	 */
 	tty->driver_data = info;
+	tty->low_latency = (info->port->flags & UPF_LOW_LATENCY) ? 1 : 0;
+	tty->alt_speed = 0;
 	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.
@@ -2009,7 +2079,7 @@
 	/*
 	 * If there isn't a port here, don't do anything further.
 	 */
-	if (!port->iobase && !port->mapbase)
+	if (!port->iobase && !port->mapbase && !port->membase)
 		return;
 
 	/*
@@ -2405,17 +2475,23 @@
 			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     = state - drv->state;
+		/*
+		 * If the port is already initialised, don't touch it.
+		 */
+		if (state->port->type == PORT_UNKNOWN) {
+			state->port->iobase   = port->iobase;
+			state->port->membase  = port->membase;
+			state->port->irq      = port->irq;
+			state->port->uartclk  = port->uartclk;
+			state->port->fifosize = port->fifosize;
+			state->port->regshift = port->regshift;
+			state->port->iotype   = port->iotype;
+			state->port->flags    = port->flags;
+			state->port->line     = state - drv->state;
+			state->port->mapbase  = port->mapbase;
 
-		__uart_register_port(drv, state, state->port);
+			__uart_register_port(drv, state, state->port);
+		}
 
 		ret = state->port->line;
 	} else
diff -Nru a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
--- a/drivers/serial/sunzilog.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/serial/sunzilog.c	Mon Dec  9 18:46:52 2002
@@ -1586,8 +1586,9 @@
 		} else {
 			/* Normal serial TTY. */
 			up->parity_mask = 0xff;
-			up->curregs[R3] = RxENAB;
-			up->curregs[R5] = TxENAB;
+			up->curregs[R4] = PAR_EVEN | X16CLK | SB1;
+			up->curregs[R3] = RxENAB | Rx8;
+			up->curregs[R5] = TxENAB | Tx8;
 			up->curregs[R9] = NV | MIE;
 			up->curregs[R10] = NRZ;
 			up->curregs[R11] = TCBR | RCBR;
diff -Nru a/drivers/sgi/char/ds1286.c b/drivers/sgi/char/ds1286.c
--- a/drivers/sgi/char/ds1286.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/sgi/char/ds1286.c	Mon Dec  9 18:46:35 2002
@@ -349,9 +349,7 @@
 int __init ds1286_init(void)
 {
 	printk(KERN_INFO "DS1286 Real Time Clock Driver v%s\n", DS1286_VERSION);
-	misc_register(&ds1286_dev);
-
-	return 0;
+	return misc_register(&ds1286_dev);
 }
 
 static char *days[] = {
diff -Nru a/drivers/sgi/char/shmiq.c b/drivers/sgi/char/shmiq.c
--- a/drivers/sgi/char/shmiq.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/sgi/char/shmiq.c	Mon Dec  9 18:46:50 2002
@@ -465,15 +465,15 @@
 void
 shmiq_init (void)
 {
+	static char names[3] = { "shmiq", "qcntl0", "qcntl1" };
+	int i;
 	printk ("SHMIQ setup\n");
 	register_chrdev(SHMIQ_MAJOR, "shmiq", &shmiq_fops);
-	devfs_register (NULL, "shmiq", DEVFS_FL_DEFAULT,
-			SHMIQ_MAJOR, 0, S_IFCHR | S_IRUSR | S_IWUSR,
+	for (i = 0; i < 3; i++) {
+		devfs_register (NULL, names[i], DEVFS_FL_DEFAULT,
+			SHMIQ_MAJOR, i, S_IFCHR | S_IRUSR | S_IWUSR,
 			&shmiq_fops, NULL);
-	devfs_register_series (NULL, "qcntl%u", 2, DEVFS_FL_DEFAULT,
-			       SHMIQ_MAJOR, 1,
-			       S_IFCHR | S_IRUSR | S_IWUSR,
-			       &shmiq_fops, NULL);
+	}
 }
 
 EXPORT_SYMBOL(shmiq_init);
diff -Nru a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c
--- a/drivers/usb/class/audio.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/usb/class/audio.c	Mon Dec  9 18:46:51 2002
@@ -890,7 +890,7 @@
 	return err ? -1 : 0;
 }
 
-static void usbin_completed(struct urb *urb)
+static void usbin_completed(struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_audiodev *as = (struct usb_audiodev *)urb->context;
 	struct usbin *u = &as->usbin;
@@ -956,7 +956,7 @@
 	return 0;
 }
 
-static void usbin_sync_completed(struct urb *urb)
+static void usbin_sync_completed(struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_audiodev *as = (struct usb_audiodev *)urb->context;
 	struct usbin *u = &as->usbin;
@@ -1250,7 +1250,7 @@
 	return 0;
 }
 
-static void usbout_completed(struct urb *urb)
+static void usbout_completed(struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_audiodev *as = (struct usb_audiodev *)urb->context;
 	struct usbout *u = &as->usbout;
@@ -1323,7 +1323,7 @@
 	return 0;
 }
 
-static void usbout_sync_completed(struct urb *urb)
+static void usbout_sync_completed(struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_audiodev *as = (struct usb_audiodev *)urb->context;
 	struct usbout *u = &as->usbout;
diff -Nru a/drivers/usb/class/bluetty.c b/drivers/usb/class/bluetty.c
--- a/drivers/usb/class/bluetty.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/usb/class/bluetty.c	Mon Dec  9 18:46:50 2002
@@ -216,10 +216,10 @@
 static int  bluetooth_ioctl		(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
 static void bluetooth_set_termios	(struct tty_struct *tty, struct termios *old);
 
-static void bluetooth_int_callback		(struct urb *urb);
-static void bluetooth_ctrl_callback		(struct urb *urb);
-static void bluetooth_read_bulk_callback	(struct urb *urb);
-static void bluetooth_write_bulk_callback	(struct urb *urb);
+static void bluetooth_int_callback		(struct urb *urb, struct pt_regs *regs);
+static void bluetooth_ctrl_callback		(struct urb *urb, struct pt_regs *regs);
+static void bluetooth_read_bulk_callback	(struct urb *urb, struct pt_regs *regs);
+static void bluetooth_write_bulk_callback	(struct urb *urb, struct pt_regs *regs);
 
 static int usb_bluetooth_probe (struct usb_interface *intf, 
 				const struct usb_device_id *id);
@@ -760,7 +760,7 @@
  *****************************************************************************/
 
 
-static void bluetooth_int_callback (struct urb *urb)
+static void bluetooth_int_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__);
 	unsigned char *data = urb->transfer_buffer;
@@ -871,7 +871,7 @@
 }
 
 
-static void bluetooth_ctrl_callback (struct urb *urb)
+static void bluetooth_ctrl_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__);
 
@@ -889,7 +889,7 @@
 }
 
 
-static void bluetooth_read_bulk_callback (struct urb *urb)
+static void bluetooth_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__);
 	unsigned char *data = urb->transfer_buffer;
@@ -1006,7 +1006,7 @@
 }
 
 
-static void bluetooth_write_bulk_callback (struct urb *urb)
+static void bluetooth_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__);
 
diff -Nru a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
--- a/drivers/usb/class/cdc-acm.c	Mon Dec  9 18:46:49 2002
+++ b/drivers/usb/class/cdc-acm.c	Mon Dec  9 18:46:49 2002
@@ -181,7 +181,7 @@
  * Interrupt handler for various ACM control events
  */
 
-static void acm_ctrl_irq(struct urb *urb)
+static void acm_ctrl_irq(struct urb *urb, struct pt_regs *regs)
 {
 	struct acm *acm = urb->context;
 	struct usb_ctrlrequest *dr = urb->transfer_buffer;
@@ -245,7 +245,7 @@
 		     __FUNCTION__, status);
 }
 
-static void acm_read_bulk(struct urb *urb)
+static void acm_read_bulk(struct urb *urb, struct pt_regs *regs)
 {
 	struct acm *acm = urb->context;
 	struct tty_struct *tty = acm->tty;
@@ -282,7 +282,7 @@
 		dbg("failed resubmitting read urb");
 }
 
-static void acm_write_bulk(struct urb *urb)
+static void acm_write_bulk(struct urb *urb, struct pt_regs *regs)
 {
 	struct acm *acm = (struct acm *)urb->context;
 
@@ -424,7 +424,7 @@
 	if (!ACM_READY(acm)) return;
 	acm->throttle = 0;
 	if (acm->readurb->status != -EINPROGRESS)
-		acm_read_bulk(acm->readurb);
+		acm_read_bulk(acm->readurb, NULL);
 }
 
 static void acm_tty_break_ctl(struct tty_struct *tty, int state)
diff -Nru a/drivers/usb/class/usb-midi.c b/drivers/usb/class/usb-midi.c
--- a/drivers/usb/class/usb-midi.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/usb/class/usb-midi.c	Mon Dec  9 18:46:34 2002
@@ -308,7 +308,7 @@
 
 /* ------------------------------------------------------------------------- */
 
-static void usb_write_callback(struct urb *urb)
+static void usb_write_callback(struct urb *urb, struct pt_regs *regs)
 {
 	struct midi_out_endpoint *ep = (struct midi_out_endpoint *)urb->context;
 
@@ -331,7 +331,7 @@
 	d = ep->usbdev;
 	pipe = usb_sndbulkpipe(d, ep->endpoint);
 	usb_fill_bulk_urb( ep->urb, d, pipe, (unsigned char*)buf, len,
-		       (usb_complete_t)usb_write_callback, ep );
+		       usb_write_callback, ep );
 
 	status = usb_submit_urb(ep->urb, GFP_KERNEL);
     
@@ -364,7 +364,7 @@
  *
  **/
 
-static void usb_bulk_read(struct urb *urb)
+static void usb_bulk_read(struct urb *urb, struct pt_regs *regs)
 {
 	struct midi_in_endpoint *ep = (struct midi_in_endpoint *)(urb->context);
 	unsigned char *data = urb->transfer_buffer;
@@ -1048,7 +1048,7 @@
 	usb_fill_bulk_urb( ep->urb, d, 
 		       usb_rcvbulkpipe(d, endPoint),
 		       (unsigned char *)ep->recvBuf, bufSize,
-		       (usb_complete_t)usb_bulk_read, ep );
+		       usb_bulk_read, ep );
 
 	/* ep->bufRdPtr     = 0; */
 	/* ep->bufWrPtr     = 0; */
diff -Nru a/drivers/usb/class/usb-midi.h b/drivers/usb/class/usb-midi.h
--- a/drivers/usb/class/usb-midi.h	Mon Dec  9 18:46:38 2002
+++ b/drivers/usb/class/usb-midi.h	Mon Dec  9 18:46:38 2002
@@ -123,8 +123,8 @@
 /* for Hot-Plugging */
 
 static struct usb_device_id usb_midi_ids [] = {
-	{ match_flags: (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS),
-	  bInterfaceClass: USB_CLASS_AUDIO, bInterfaceSubClass: USB_SUBCLASS_MIDISTREAMING},
+	{ .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS),
+	  .bInterfaceClass = USB_CLASS_AUDIO, .bInterfaceSubClass = USB_SUBCLASS_MIDISTREAMING},
 	{ USB_DEVICE( USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_UM1    ) },
 	{ USB_DEVICE( USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_UM2    ) },
 	{ USB_DEVICE( USB_VENDOR_ID_ROLAND, USBMIDI_ROLAND_UA100G ) },
diff -Nru a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
--- a/drivers/usb/class/usblp.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/usb/class/usblp.c	Mon Dec  9 18:46:35 2002
@@ -260,7 +260,7 @@
  * URB callback.
  */
 
-static void usblp_bulk_read(struct urb *urb)
+static void usblp_bulk_read(struct urb *urb, struct pt_regs *regs)
 {
 	struct usblp *usblp = urb->context;
 
@@ -274,7 +274,7 @@
 	wake_up_interruptible(&usblp->wait);
 }
 
-static void usblp_bulk_write(struct urb *urb)
+static void usblp_bulk_write(struct urb *urb, struct pt_regs *regs)
 {
 	struct usblp *usblp = urb->context;
 
diff -Nru a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
--- a/drivers/usb/core/devio.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/usb/core/devio.c	Mon Dec  9 18:46:37 2002
@@ -239,23 +239,19 @@
 {
         unsigned long flags;
         struct async *as;
-        struct list_head *p;
 
         spin_lock_irqsave(&ps->lock, flags);
-        for (p = ps->async_pending.next; p != &ps->async_pending; ) {
-                as = list_entry(p, struct async, asynclist);
-                p = p->next;
-                if (as->userurb != userurb)
-                        continue;
-                list_del_init(&as->asynclist);
-                spin_unlock_irqrestore(&ps->lock, flags);
-                return as;
-        }
+	list_for_each_entry(as, &ps->async_pending, asynclist)
+		if (as->userurb == userurb) {
+			list_del_init(&as->asynclist);
+			spin_unlock_irqrestore(&ps->lock, flags);
+			return as;
+		}
         spin_unlock_irqrestore(&ps->lock, flags);
         return NULL;
 }
 
-static void async_completed(struct urb *urb)
+static void async_completed(struct urb *urb, struct pt_regs *regs)
 {
         struct async *as = (struct async *)urb->context;
         struct dev_state *ps = as->ps;
@@ -295,19 +291,14 @@
 
 static void destroy_async_on_interface (struct dev_state *ps, unsigned int intf)
 {
-	struct async *as;
-	struct list_head *p, hitlist;
+	struct list_head *p, *q, hitlist;
 	unsigned long flags;
 
 	INIT_LIST_HEAD(&hitlist);
 	spin_lock_irqsave(&ps->lock, flags);
-	for (p = ps->async_pending.next; p != &ps->async_pending; ) {
-		as = list_entry(p, struct async, asynclist);
-		p = p->next;
-
-		if (as->intf == intf)
-			list_move_tail(&as->asynclist, &hitlist);
-	}
+	list_for_each_safe(p, q, &ps->async_pending)
+		if (intf == list_entry(p, struct async, asynclist)->intf)
+			list_move_tail(p, &hitlist);
 	spin_unlock_irqrestore(&ps->lock, flags);
 	destroy_async(ps, &hitlist);
 }
@@ -493,14 +484,17 @@
 	 * and the hub thread have the kernel lock
 	 * (still acquire the kernel lock for safety)
 	 */
+	ret = -ENOMEM;
+	if (!(ps = kmalloc(sizeof(struct dev_state), GFP_KERNEL)))
+		goto out_nolock;
+
 	lock_kernel();
 	ret = -ENOENT;
 	dev = inode->u.generic_ip;
-	if (!dev)
-		goto out;
-	ret = -ENOMEM;
-	if (!(ps = kmalloc(sizeof(struct dev_state), GFP_KERNEL)))
+	if (!dev) {
+		kfree(ps);
 		goto out;
+	}
 	ret = 0;
 	ps->dev = dev;
 	ps->file = file;
@@ -518,6 +512,7 @@
 	file->private_data = ps;
  out:
 	unlock_kernel();
+ out_nolock:
         return ret;
 }
 
@@ -869,7 +864,7 @@
 		if (uurb.buffer_length > 16384)
 			return -EINVAL;
 		if (!access_ok((uurb.endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb.buffer, uurb.buffer_length))
-			return -EFAULT;   
+			return -EFAULT;
 		break;
 
 	default:
@@ -964,10 +959,10 @@
 	if (!(usb_pipeisoc(urb->pipe)))
 		return 0;
 	for (i = 0; i < urb->number_of_packets; i++) {
-		if (put_user(urb->iso_frame_desc[i].actual_length, 
+		if (put_user(urb->iso_frame_desc[i].actual_length,
 			     &((struct usbdevfs_urb *)as->userurb)->iso_frame_desc[i].actual_length))
 			return -EFAULT;
-		if (put_user(urb->iso_frame_desc[i].status, 
+		if (put_user(urb->iso_frame_desc[i].status,
 			     &((struct usbdevfs_urb *)as->userurb)->iso_frame_desc[i].status))
 			return -EFAULT;
 	}
@@ -1099,12 +1094,10 @@
        else switch (ctrl.ioctl_code) {
 
        /* disconnect kernel driver from interface, leaving it unbound.  */
+       /* maybe unbound - you get no guarantee it stays unbound */
        case USBDEVFS_DISCONNECT:
-		/* this function is voodoo. */
-		/* which function ... usb_device_remove()?
-		 * FIXME either the module lock (BKL) should be involved
-		 * here too, or the 'default' case below is broken
-		 */
+		/* this function is misdesigned - retained for compatibility */
+		lock_kernel();
 		driver = ifp->driver;
 		if (driver) {
 			dbg ("disconnect '%s' from dev %d interface %d",
@@ -1112,11 +1105,14 @@
 			usb_device_remove(&ifp->dev);
 		} else
 			retval = -ENODATA;
+		unlock_kernel();
 		break;
 
 	/* let kernel drivers try to (re)bind to the interface */
 	case USBDEVFS_CONNECT:
+		lock_kernel();
 		retval = usb_device_probe (&ifp->dev);
+		unlock_kernel();
 		break;
 
 	/* talk directly to the interface's driver */
@@ -1131,20 +1127,17 @@
 			unlock_kernel();
 			retval = -ENOSYS;
 		} else {
-			if (driver->owner
-					&& !try_inc_mod_count (driver->owner)) {
+			if (!try_module_get (driver->owner)) {
 				unlock_kernel();
 				retval = -ENOSYS;
 				break;
 			}
 			unlock_kernel ();
 			retval = driver->ioctl (ifp, ctrl.ioctl_code, buf);
-			if (driver->owner)
-				__MOD_DEC_USE_COUNT (driver->owner);
+			if (retval == -ENOIOCTLCMD)
+				retval = -ENOTTY;
+			module_put (driver->owner);
 		}
-		
-		if (retval == -ENOIOCTLCMD)
-			retval = -ENOTTY;
 	}
 
 	/* cleanup and return */
@@ -1197,7 +1190,7 @@
 	case USBDEVFS_RESET:
 		ret = proc_resetdevice(ps);
 		break;
-	
+
 	case USBDEVFS_CLEAR_HALT:
 		ret = proc_clearhalt(ps, (void *)arg);
 		if (ret >= 0)
diff -Nru a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
--- a/drivers/usb/core/hcd-pci.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/usb/core/hcd-pci.c	Mon Dec  9 18:46:37 2002
@@ -146,7 +146,7 @@
 		goto clean_2;
 	}
 
-	info ("%s @ %s, %s", hcd->description,  dev->slot_name, dev->dev.name);
+	dev_info (*hcd->controller, "%s\n", hcd->product_desc);
 
 #ifndef __sparc__
 	sprintf (buf, "%d", dev->irq);
@@ -155,7 +155,8 @@
 #endif
 	if (request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ, hcd->description, hcd)
 			!= 0) {
-		err ("request interrupt %s failed", bufp);
+		dev_err (*hcd->controller,
+				"request interrupt %s failed\n", bufp);
 		retval = -EBUSY;
 		goto clean_3;
 	}
@@ -163,7 +164,7 @@
 
 	hcd->regs = base;
 	hcd->region = region;
-	info ("irq %s, %s %p", bufp,
+	dev_info (*hcd->controller, "irq %s, %s %p\n", bufp,
 		(driver->flags & HCD_MEMORY) ? "pci mem" : "io base",
 		base);
 
@@ -205,19 +206,20 @@
 	hcd = pci_get_drvdata(dev);
 	if (!hcd)
 		return;
-	info ("remove: %s, state %x", hcd->self.bus_name, hcd->state);
+	dev_info (*hcd->controller, "remove, state %x\n", hcd->state);
 
 	if (in_interrupt ()) BUG ();
 
 	hub = hcd->self.root_hub;
 	hcd->state = USB_STATE_QUIESCING;
 
-	dbg ("%s: roothub graceful disconnect", hcd->self.bus_name);
+	dev_dbg (*hcd->controller, "roothub graceful disconnect\n");
 	usb_disconnect (&hub);
 
 	hcd->driver->stop (hcd);
 	hcd_buffer_destroy (hcd);
 	hcd->state = USB_STATE_HALT;
+	pci_set_drvdata (dev, 0);
 
 	free_irq (hcd->irq, hcd);
 	if (hcd->driver->flags & HCD_MEMORY) {
@@ -230,9 +232,12 @@
 	}
 
 	usb_deregister_bus (&hcd->self);
-	if (atomic_read (&hcd->self.refcnt) != 1)
-		err ("usb_hcd_pci_remove %s, count != 1", hcd->self.bus_name);
-
+	if (atomic_read (&hcd->self.refcnt) != 1) {
+		dev_warn (*hcd->controller,
+			"dangling refs (%d) to bus %d!\n",
+			atomic_read (&hcd->self.refcnt) - 1,
+			hcd->self.busnum);
+	}
 	hcd->driver->hcd_free (hcd);
 }
 EXPORT_SYMBOL (usb_hcd_pci_remove);
@@ -279,7 +284,7 @@
 	int			retval;
 
 	hcd = pci_get_drvdata(dev);
-	info ("suspend %s to state %d", hcd->self.bus_name, state);
+	dev_info (*hcd->controller, "suspend to state %d\n", state);
 
 	pci_save_state (dev, hcd->pci_state);
 
@@ -308,19 +313,19 @@
 	int			retval;
 
 	hcd = pci_get_drvdata(dev);
-	info ("resume %s", hcd->self.bus_name);
+	dev_info (*hcd->controller, "resume\n");
 
 	/* guard against multiple resumes (APM bug?) */
 	atomic_inc (&hcd->resume_count);
 	if (atomic_read (&hcd->resume_count) != 1) {
-		err ("concurrent PCI resumes for %s", hcd->self.bus_name);
+		dev_err (*hcd->controller, "concurrent PCI resumes\n");
 		retval = 0;
 		goto done;
 	}
 
 	retval = -EBUSY;
 	if (hcd->state != USB_STATE_SUSPENDED) {
-		dbg ("can't resume, not suspended!");
+		dev_dbg (*hcd->controller, "can't resume, not suspended!\n");
 		goto done;
 	}
 	hcd->state = USB_STATE_RESUMING;
@@ -330,7 +335,7 @@
 
 	retval = hcd->driver->resume (hcd);
 	if (!HCD_IS_RUNNING (hcd->state)) {
-		dbg ("resume %s failure, retval %d", hcd->self.bus_name, retval);
+		dev_dbg (*hcd->controller, "resume fail, retval %d\n", retval);
 		usb_hc_died (hcd);
 // FIXME:  recover, reset etc.
 	} else {
diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/usb/core/hcd.c	Mon Dec  9 18:46:38 2002
@@ -80,6 +80,7 @@
 
 /* host controllers we manage */
 LIST_HEAD (usb_bus_list);
+EXPORT_SYMBOL_GPL (usb_bus_list);
 
 /* used when allocating bus numbers */
 #define USB_MAXBUS		64
@@ -90,6 +91,7 @@
 
 /* used when updating list of hcds */
 DECLARE_MUTEX (usb_bus_list_lock);	/* exported only for usbfs */
+EXPORT_SYMBOL_GPL (usb_bus_list_lock);
 
 /* used when updating hcd data */
 static spinlock_t hcd_data_lock = SPIN_LOCK_UNLOCKED;
@@ -433,7 +435,7 @@
 	}
 
 	/* any errors get returned through the urb completion */
-	usb_hcd_giveback_urb (hcd, urb);
+	usb_hcd_giveback_urb (hcd, urb, NULL);
 	return 0;
 }
 
@@ -494,7 +496,7 @@
 				urb->actual_length = length;
 				urb->status = 0;
 				urb->hcpriv = 0;
-				urb->complete (urb);
+				urb->complete (urb, NULL);
 				return;
 			}
 		} else
@@ -509,7 +511,7 @@
 		urb->hcpriv = 0;
 		spin_unlock_irqrestore (&urb->lock, flags);
 
-		usb_hcd_giveback_urb (hcd, urb);
+		usb_hcd_giveback_urb (hcd, urb, NULL);
 	}
 }
 
@@ -544,7 +546,7 @@
 	spin_unlock_irqrestore (&hcd_data_lock, flags);
 
 	/* we rely on RH callback code not unlinking its URB! */
-	usb_hcd_giveback_urb (hcd, urb);
+	usb_hcd_giveback_urb (hcd, urb, NULL);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -715,7 +717,8 @@
 	sprintf (&usb_dev->dev.bus_id[0], "usb%d", usb_dev->bus->busnum);
 	retval = usb_new_device (usb_dev, parent_dev);
 	if (retval)
-		err("%s - usb_new_device failed with value %d", __FUNCTION__, retval);
+		dev_err (*parent_dev, "can't register root hub for %s, %d\n",
+				usb_dev->dev.bus_id, retval);
 	return retval;
 }
 EXPORT_SYMBOL (usb_register_root_hub);
@@ -1059,11 +1062,11 @@
 	struct completion	done;
 
 	/* original urb data */
-	void			(*complete)(struct urb *);
+	usb_complete_t		complete;
 	void			*context;
 };
 
-static void unlink_complete (struct urb *urb)
+static void unlink_complete (struct urb *urb, struct pt_regs *regs)
 {
 	struct completion_splice	*splice;
 
@@ -1072,7 +1075,7 @@
 	/* issue original completion call */
 	urb->complete = splice->complete;
 	urb->context = splice->context;
-	urb->complete (urb);
+	urb->complete (urb, regs);
 
 	/* then let the synchronous unlink call complete */
 	complete (&splice->done);
@@ -1272,6 +1275,7 @@
  * usb_hcd_giveback_urb - return URB from HCD to device driver
  * @hcd: host controller returning the URB
  * @urb: urb being returned to the USB device driver.
+ * @regs: pt_regs, passed down to the URB completion handler
  * Context: in_interrupt()
  *
  * This hands the URB from HCD to its USB device driver, using its
@@ -1280,19 +1284,13 @@
  * the device driver won't cause problems if it frees, modifies,
  * or resubmits this URB.
  */
-void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb)
+void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs)
 {
 	urb_unlink (urb);
 
 	// NOTE:  a generic device/urb monitoring hook would go here.
 	// hcd_monitor_hook(MONITOR_URB_FINISH, urb, dev)
-	// It would catch exit/unlink paths for all urbs, but non-exit
-	// completions for periodic urbs need hooks inside the HCD.
-	// hcd_monitor_hook(MONITOR_URB_UPDATE, urb, dev)
-
-	if (urb->status)
-		dbg ("giveback urb %p status %d len %d",
-			urb, urb->status, urb->actual_length);
+	// It would catch exit/unlink paths for all urbs.
 
 	/* lower level hcd code should use *_dma exclusively */
 	if (!(urb->transfer_flags & URB_NO_DMA_MAP)) {
@@ -1309,7 +1307,7 @@
 	}
 
 	/* pass ownership to the completion handler */
-	urb->complete (urb);
+	urb->complete (urb, regs);
 	usb_put_urb (urb);
 }
 EXPORT_SYMBOL (usb_hcd_giveback_urb);
@@ -1320,7 +1318,7 @@
  * usb_hcd_irq - hook IRQs to HCD framework (bus glue)
  * @irq: the IRQ being raised
  * @__hcd: pointer to the HCD whose IRQ is beinng signaled
- * @r: saved hardware registers (not passed to HCD)
+ * @r: saved hardware registers
  *
  * When registering a USB bus through the HCD framework code, use this
  * to handle interrupts.  The PCI glue layer does so automatically; only
@@ -1334,7 +1332,7 @@
 	if (unlikely (hcd->state == USB_STATE_HALT))	/* irq sharing? */
 		return;
 
-	hcd->driver->irq (hcd);
+	hcd->driver->irq (hcd, r);
 	if (hcd->state != start && hcd->state == USB_STATE_HALT)
 		usb_hc_died (hcd);
 }
diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
--- a/drivers/usb/core/hcd.h	Mon Dec  9 18:46:35 2002
+++ b/drivers/usb/core/hcd.h	Mon Dec  9 18:46:35 2002
@@ -169,11 +169,13 @@
 
 /* each driver provides one of these, and hardware init support */
 
+struct pt_regs;
+
 struct hc_driver {
 	const char	*description;	/* "ehci-hcd" etc */
 
 	/* irq handler */
-	void	(*irq) (struct usb_hcd *hcd);
+	void	(*irq) (struct usb_hcd *hcd, struct pt_regs *regs);
 
 	int	flags;
 #define	HCD_MEMORY	0x0001		/* HC regs use memory (else I/O) */
@@ -216,7 +218,7 @@
 				char *buf, u16 wLength);
 };
 
-extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb);
+extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs);
 extern void usb_bus_init (struct usb_bus *bus);
 extern void usb_rh_status_dequeue (struct usb_hcd *hcd, struct urb *urb);
 
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/usb/core/hub.c	Mon Dec  9 18:46:37 2002
@@ -115,7 +115,7 @@
 }
 
 /* completion function, fires on port status changes and various faults */
-static void hub_irq(struct urb *urb)
+static void hub_irq(struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_hub *hub = (struct usb_hub *)urb->context;
 	unsigned long flags;
diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c
--- a/drivers/usb/core/message.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/usb/core/message.c	Mon Dec  9 18:46:35 2002
@@ -16,7 +16,7 @@
 	int done;
 };
 
-static void usb_api_blocking_completion(struct urb *urb)
+static void usb_api_blocking_completion(struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_api_data *awd = (struct usb_api_data *)urb->context;
 
@@ -210,7 +210,7 @@
 	io->dev = 0;
 }
 
-static void sg_complete (struct urb *urb)
+static void sg_complete (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_sg_request	*io = (struct usb_sg_request *) urb->context;
 	unsigned long		flags;
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/usb/core/usb.c	Mon Dec  9 18:46:37 2002
@@ -69,24 +69,23 @@
 	.probe = generic_probe,
 	.remove = generic_remove,
 };
-	
+
+/* needs to be called with BKL held */
 int usb_device_probe(struct device *dev)
 {
 	struct usb_interface * intf = to_usb_interface(dev);
 	struct usb_driver * driver = to_usb_driver(dev->driver);
 	const struct usb_device_id *id;
 	int error = -ENODEV;
-	int m;
 
 	dbg("%s", __FUNCTION__);
 
 	if (!driver->probe)
 		return error;
 
-	if (driver->owner) {
-		m = try_inc_mod_count(driver->owner);
-		if (m == 0)
-			return error;
+	if (!try_module_get(driver->owner)) {
+		err ("Can't get a module reference for %s", driver->name);
+		return error;
 	}
 
 	id = usb_match_id (intf, driver->id_table);
@@ -99,8 +98,7 @@
 	if (!error)
 		intf->driver = driver;
 
-	if (driver->owner)
-		__MOD_DEC_USE_COUNT(driver->owner);
+	module_put(driver->owner);
 
 	return error;
 }
@@ -109,7 +107,6 @@
 {
 	struct usb_interface *intf;
 	struct usb_driver *driver;
-	int m;
 
 	intf = list_entry(dev,struct usb_interface,dev);
 	driver = to_usb_driver(dev->driver);
@@ -120,14 +117,11 @@
 		return -ENODEV;
 	}
 
-	if (driver->owner) {
-		m = try_inc_mod_count(driver->owner);
-		if (m == 0) {
-			// FIXME this happens even when we just rmmod
-			// drivers that aren't in active use... 
-			err("Dieing driver still bound to device.\n");
-			return -EIO;
-		}
+	if (!try_module_get(driver->owner)) {
+		// FIXME this happens even when we just rmmod
+		// drivers that aren't in active use...
+		err("Dieing driver still bound to device.\n");
+		return -EIO;
 	}
 
 	/* if we sleep here on an umanaged driver 
@@ -143,8 +137,7 @@
 		usb_driver_release_interface(driver, intf);
 
 	up(&driver->serialize);
-	if (driver->owner)
-		__MOD_DEC_USE_COUNT(driver->owner);
+	module_put(driver->owner);
 
 	return 0;
 }
diff -Nru a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
--- a/drivers/usb/host/ehci-dbg.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/usb/host/ehci-dbg.c	Mon Dec  9 18:46:50 2002
@@ -18,6 +18,17 @@
 
 /* this file is part of ehci-hcd.c */
 
+#define ehci_dbg(ehci, fmt, args...) \
+	dev_dbg (*(ehci)->hcd.controller, fmt, ## args )
+
+#ifdef EHCI_VERBOSE_DEBUG
+#define ehci_vdbg(ehci, fmt, args...) \
+	dev_dbg (*(ehci)->hcd.controller, fmt, ## args )
+#else
+#define ehci_vdbg(ehci, fmt, args...) do { } while (0)
+#endif
+
+
 #ifdef EHCI_VERBOSE_DEBUG
 #	define vdbg dbg
 #else
@@ -34,7 +45,8 @@
 {
 	u32	params = readl (&ehci->caps->hcs_params);
 
-	dbg ("%s hcs_params 0x%x dbg=%d%s cc=%d pcc=%d%s%s ports=%d",
+	ehci_dbg (ehci,
+		"%s hcs_params 0x%x dbg=%d%s cc=%d pcc=%d%s%s ports=%d\n",
 		label, params,
 		HCS_DEBUG_PORT (params),
 		HCS_INDICATOR (params) ? " ind" : "",
@@ -56,9 +68,8 @@
 				((i & 0x1) ? ((byte)&0xf) : ((byte>>4)&0xf)));
 			strcat(buf, tmp);
 		}
-		dbg ("%s: %s portroute %s", 
-			hcd_to_bus (&ehci->hcd)->bus_name, label,
-			buf);
+		ehci_dbg (ehci, "%s portroute %s\n",
+				label, buf);
 	}
 }
 #else
@@ -77,19 +88,16 @@
 {
 	u32	params = readl (&ehci->caps->hcc_params);
 
-	if (HCC_EXT_CAPS (params)) {
-		// EHCI 0.96 ... could interpret these (legacy?)
-		dbg ("%s extended capabilities at pci %2x",
-			label, HCC_EXT_CAPS (params));
-	}
 	if (HCC_ISOC_CACHE (params)) {
-		dbg ("%s hcc_params %04x caching frame %s%s%s",
+		ehci_dbg (ehci,
+		     "%s hcc_params %04x caching frame %s%s%s\n",
 		     label, params,
 		     HCC_PGM_FRAMELISTLEN (params) ? "256/512/1024" : "1024",
 		     HCC_CANPARK (params) ? " park" : "",
 		     HCC_64BIT_ADDR (params) ? " 64 bit addr" : "");
 	} else {
-		dbg ("%s hcc_params %04x caching %d uframes %s%s%s",
+		ehci_dbg (ehci,
+		     "%s hcc_params %04x thresh %d uframes %s%s%s\n",
 		     label,
 		     params,
 		     HCC_ISOC_THRES (params),
@@ -235,19 +243,19 @@
 #define dbg_status(ehci, label, status) { \
 	char _buf [80]; \
 	dbg_status_buf (_buf, sizeof _buf, label, status); \
-	dbg ("%s", _buf); \
+	ehci_dbg (ehci, "%s\n", _buf); \
 }
 
 #define dbg_cmd(ehci, label, command) { \
 	char _buf [80]; \
 	dbg_command_buf (_buf, sizeof _buf, label, command); \
-	dbg ("%s", _buf); \
+	ehci_dbg (ehci, "%s\n", _buf); \
 }
 
-#define dbg_port(hcd, label, port, status) { \
+#define dbg_port(ehci, label, port, status) { \
 	char _buf [80]; \
 	dbg_port_buf (_buf, sizeof _buf, label, port, status); \
-	dbg ("%s", _buf); \
+	ehci_dbg (ehci, "%s\n", _buf); \
 }
 
 /*-------------------------------------------------------------------------*/
@@ -338,12 +346,8 @@
 	 * one QH per line, and TDs we know about
 	 */
 	spin_lock_irqsave (&ehci->lock, flags);
-	if (ehci->async) {
-		qh = ehci->async;
-		do {
-			qh_lines (qh, &next, &size);
-		} while ((qh = qh->qh_next.qh) != ehci->async);
-	}
+	for (qh = ehci->async->qh_next.qh; qh; qh = qh->qh_next.qh)
+		qh_lines (qh, &next, &size);
 	if (ehci->reclaim) {
 		temp = snprintf (next, size, "\nreclaim =\n");
 		size -= temp;
diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
--- a/drivers/usb/host/ehci-hcd.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/usb/host/ehci-hcd.c	Mon Dec  9 18:46:50 2002
@@ -17,6 +17,13 @@
  */
 
 #include <linux/config.h>
+
+#ifdef CONFIG_USB_DEBUG
+	#define DEBUG
+#else
+	#undef DEBUG
+#endif
+
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
@@ -31,12 +38,6 @@
 #include <linux/list.h>
 #include <linux/interrupt.h>
 
-#ifdef CONFIG_USB_DEBUG
-	#define DEBUG
-#else
-	#undef DEBUG
-#endif
-
 #include <linux/usb.h>
 
 #include <linux/version.h>
@@ -70,6 +71,7 @@
  *
  * HISTORY:
  *
+ * 2002-11-29	Correct handling for hw async_next register.
  * 2002-08-06	Handling for bulk and interrupt transfers is mostly shared;
  *	only scheduling is different, no arbitrary limitations.
  * 2002-07-25	Sanity check PCI reads, mostly for better cardbus support,
@@ -92,7 +94,7 @@
  * 2001-June	Works with usb-storage and NEC EHCI on 2.4
  */
 
-#define DRIVER_VERSION "2002-Sep-23"
+#define DRIVER_VERSION "2002-Nov-29"
 #define DRIVER_AUTHOR "David Brownell"
 #define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
 
@@ -114,7 +116,7 @@
 #define	EHCI_TUNE_MULT_TT	1
 
 #define EHCI_WATCHDOG_JIFFIES	(HZ/100)	/* arbitrary; ~10 msec */
-#define EHCI_ASYNC_JIFFIES	(HZ/3)		/* async idle timeout */
+#define EHCI_ASYNC_JIFFIES	(HZ/20)		/* async idle timeout */
 
 /* Initial IRQ latency:  lower than default */
 static int log2_irq_thresh = 0;		// 0 to 6
@@ -215,7 +217,7 @@
 
 	/* wait for any schedule enables/disables to take effect */
 	temp = 0;
-	if (ehci->async)
+	if (ehci->async->qh_next.qh)
 		temp = STS_ASS;
 	if (ehci->next_uframe != -1)
 		temp |= STS_PSS;
@@ -250,7 +252,7 @@
 
 static void ehci_tasklet (unsigned long param);
 
-static void ehci_irq (struct usb_hcd *hcd);
+static void ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs);
 
 static void ehci_watchdog (unsigned long param)
 {
@@ -259,8 +261,8 @@
 
 	spin_lock_irqsave (&ehci->lock, flags);
 	/* guard against lost IAA, which wedges everything */
-	ehci_irq (&ehci->hcd);
- 	/* unlink the last qh after it's idled a while */
+	ehci_irq (&ehci->hcd, NULL);
+ 	/* stop async processing after it's idled a while */
  	if (ehci->async_idle) {
  		start_unlink_async (ehci, ehci->async);
  		ehci->async_idle = 0;
@@ -287,12 +289,13 @@
 			pci_read_config_dword (ehci->hcd.pdev, where, &cap);
 		} while ((cap & (1 << 16)) && msec);
 		if (cap & (1 << 16)) {
-			info ("BIOS handoff failed (%d, %04x)", where, cap);
+			dev_info (*ehci->hcd.controller,
+				"BIOS handoff failed (%d, %04x)\n",
+				where, cap);
 			return 1;
 		} 
-		dbg ("BIOS handoff succeeded");
-	} else
-		dbg ("BIOS handoff not needed");
+		ehci_dbg (ehci, "BIOS handoff succeeded\n");
+	}
 	return 0;
 }
 
@@ -323,14 +326,15 @@
 		u32		cap;
 
 		pci_read_config_dword (ehci->hcd.pdev, temp, &cap);
-		dbg ("capability %04x at %02x", cap, temp);
+		ehci_dbg (ehci, "capability %04x at %02x\n", cap, temp);
 		switch (cap & 0xff) {
 		case 1:			/* BIOS/SMM/... handoff */
 			if (bios_handoff (ehci, temp, cap) != 0)
 				return -EOPNOTSUPP;
 			break;
 		case 0:			/* illegal reserved capability */
-			warn ("illegal capability!");
+			dev_warn (*ehci->hcd.controller,
+					"illegal capability!\n");
 			cap = 0;
 			/* FALLTHROUGH */
 		default:		/* unknown */
@@ -360,7 +364,6 @@
 	else					// N microframes cached
 		ehci->i_thresh = 2 + HCC_ISOC_THRES (hcc_params);
 
-	ehci->async = 0;
 	ehci->reclaim = 0;
 	ehci->next_uframe = -1;
 
@@ -375,6 +378,21 @@
 	writel (ehci->periodic_dma, &ehci->regs->frame_list);
 
 	/*
+	 * dedicate a qh for the async ring head, since we couldn't unlink
+	 * a 'real' qh without stopping the async schedule [4.8].  use it
+	 * as the 'reclamation list head' too.
+	 */
+	ehci->async->qh_next.qh = 0;
+	ehci->async->hw_next = QH_NEXT (ehci->async->qh_dma);
+	ehci->async->hw_info1 = cpu_to_le32 (QH_HEAD);
+	ehci->async->hw_token = cpu_to_le32 (QTD_STS_HALT);
+	ehci->async->hw_qtd_next = EHCI_LIST_END;
+	ehci->async->qh_state = QH_STATE_LINKED;
+	ehci_qtd_free (ehci, ehci->async->dummy);
+	ehci->async->dummy = 0;
+	writel ((u32)ehci->async->qh_dma, &ehci->regs->async_next);
+
+	/*
 	 * hcc_params controls whether ehci->regs->segment must (!!!)
 	 * be used; it constrains QH/ITD/SITD and QTD locations.
 	 * pci_pool consistent memory always uses segment zero.
@@ -388,7 +406,8 @@
 	if (HCC_64BIT_ADDR (hcc_params)) {
 		writel (0, &ehci->regs->segment);
 		if (!pci_set_dma_mask (ehci->hcd.pdev, 0xffffffffffffffffULL))
-			info ("enabled 64bit PCI DMA (DAC)");
+			dev_info (*ehci->hcd.controller,
+				"enabled 64bit PCI DMA (DAC)\n");
 	}
 
 	/* clear interrupt enables, set irq latency */
@@ -435,10 +454,10 @@
         /* PCI Serial Bus Release Number is at 0x60 offset */
 	pci_read_config_byte (hcd->pdev, 0x60, &tempbyte);
 	temp = readw (&ehci->caps->hci_version);
-	info ("USB %x.%x support enabled, EHCI rev %x.%02x, %s %s",
-	      ((tempbyte & 0xf0)>>4), (tempbyte & 0x0f),
-	       temp >> 8, temp & 0xff,
-	       hcd_name, DRIVER_VERSION);
+	dev_info (*hcd->controller,
+		"USB %x.%x enabled, EHCI %x.%02x, driver %s\n",
+		((tempbyte & 0xf0)>>4), (tempbyte & 0x0f),
+		temp >> 8, temp & 0xff, DRIVER_VERSION);
 
 	/*
 	 * From here on, khubd concurrently accesses the root
@@ -470,13 +489,13 @@
 {
 	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
 
-	dbg ("%s: stop", hcd_to_bus (hcd)->bus_name);
+	ehci_dbg (ehci, "stop\n");
 
 	/* no more interrupts ... */
 	if (hcd->state == USB_STATE_RUNNING)
 		ehci_ready (ehci);
 	if (in_interrupt ())		/* should not happen!! */
-		err ("stopped %s!", RUN_CONTEXT);
+		dev_err (*hcd->controller, "stopped %s!\n", RUN_CONTEXT);
 	else
 		del_timer_sync (&ehci->watchdog);
 	ehci_reset (ehci);
@@ -492,9 +511,9 @@
 	ehci_mem_cleanup (ehci);
 
 #ifdef	EHCI_STATS
-	dbg ("irq normal %ld err %ld reclaim %ld",
+	ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld\n",
 		ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim);
-	dbg ("complete %ld unlink %ld",
+	ehci_dbg (ehci, "complete %ld unlink %ld\n",
 		ehci->stats.complete, ehci->stats.unlink);
 #endif
 
@@ -616,7 +635,7 @@
 
 /*-------------------------------------------------------------------------*/
 
-static void ehci_irq (struct usb_hcd *hcd)
+static void ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs)
 {
 	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
 	u32			status = readl (&ehci->regs->status);
@@ -738,8 +757,8 @@
 	struct ehci_qh		*qh = (struct ehci_qh *) urb->hcpriv;
 	unsigned long		flags;
 
-	dbg ("%s urb_dequeue %p qh %p state %d",
-		hcd_to_bus (hcd)->bus_name, urb, qh, qh->qh_state);
+	ehci_vdbg (ehci, "urb_dequeue %p qh %p state %d\n",
+		urb, qh, qh->qh_state);
 
 	switch (usb_pipetype (urb->pipe)) {
 	// case PIPE_CONTROL:
@@ -982,7 +1001,6 @@
 
 static int __init init (void) 
 {
-	dbg (DRIVER_INFO);
 	if (usb_disabled())
 		return -ENODEV;
 
diff -Nru a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
--- a/drivers/usb/host/ehci-hub.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/usb/host/ehci-hub.c	Mon Dec  9 18:46:51 2002
@@ -40,18 +40,15 @@
 
 	/* if reset finished and it's still not enabled -- handoff */
 	if (!(port_status & PORT_PE)) {
-		dbg ("%s port %d full speed, give to companion, 0x%x",
-			hcd_to_bus (&ehci->hcd)->bus_name,
-			index + 1, port_status);
+		ehci_dbg (ehci, "port %d full speed --> companion\n",
+			index + 1);
 
 		// what happens if HCS_N_CC(params) == 0 ?
 		port_status |= PORT_OWNER;
 		writel (port_status, &ehci->regs->port_status [index]);
 
 	} else
-		dbg ("%s port %d high speed",
-			hcd_to_bus (&ehci->hcd)->bus_name,
-			index + 1);
+		ehci_dbg (ehci, "port %d high speed\n", index + 1);
 
 	return port_status;
 }
@@ -277,7 +274,7 @@
 #ifndef	EHCI_VERBOSE_DEBUG
 	if (status & ~0xffff)	/* only if wPortChange is interesting */
 #endif
-		dbg_port (hcd, "GetStatus", wIndex + 1, temp);
+		dbg_port (ehci, "GetStatus", wIndex + 1, temp);
 		// we "know" this alignment is good, caller used kmalloc()...
 		*((u32 *) buf) = cpu_to_le32 (status);
 		break;
@@ -313,14 +310,12 @@
 			/* line status bits may report this as low speed */
 			if ((temp & (PORT_PE|PORT_CONNECT)) == PORT_CONNECT
 					&& PORT_USB11 (temp)) {
-				dbg ("%s port %d low speed, give to companion",
-					hcd_to_bus (&ehci->hcd)->bus_name,
+				ehci_dbg (ehci,
+					"port %d low speed --> companion\n",
 					wIndex + 1);
 				temp |= PORT_OWNER;
 			} else {
-				vdbg ("%s port %d reset",
-					hcd_to_bus (&ehci->hcd)->bus_name,
-					wIndex + 1);
+				ehci_vdbg (ehci, "port %d reset", wIndex + 1);
 				temp |= PORT_RESET;
 				temp &= ~PORT_PE;
 
diff -Nru a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c
--- a/drivers/usb/host/ehci-mem.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/usb/host/ehci-mem.c	Mon Dec  9 18:46:51 2002
@@ -103,7 +103,7 @@
 	/* dummy td enables safe urb queuing */
 	qh->dummy = ehci_qtd_alloc (ehci, flags);
 	if (qh->dummy == 0) {
-		dbg ("no dummy td");
+		ehci_dbg (ehci, "no dummy td\n");
 		pci_pool_free (ehci->qh_pool, qh, qh->qh_dma);
 		qh = 0;
 	}
@@ -113,19 +113,17 @@
 /* to share a qh (cpu threads, or hc) */
 static inline struct ehci_qh *qh_get (/* ehci, */ struct ehci_qh *qh)
 {
-	// dbg ("get %p (%d++)", qh, qh->refcount.counter);
 	atomic_inc (&qh->refcount);
 	return qh;
 }
 
 static void qh_put (struct ehci_hcd *ehci, struct ehci_qh *qh)
 {
-	// dbg ("put %p (--%d)", qh, qh->refcount.counter);
 	if (!atomic_dec_and_test (&qh->refcount))
 		return;
 	/* clean qtds first, and know this is not linked */
 	if (!list_empty (&qh->qtd_list) || qh->qh_next.ptr) {
-		dbg ("unused qh not empty!");
+		ehci_dbg (ehci, "unused qh not empty!\n");
 		BUG ();
 	}
 	if (qh->dummy)
@@ -142,6 +140,10 @@
 
 static void ehci_mem_cleanup (struct ehci_hcd *ehci)
 {
+	if (ehci->async)
+		qh_put (ehci, ehci->async);
+	ehci->async = 0;
+
 	/* PCI consistent memory and pools */
 	if (ehci->qtd_pool)
 		pci_pool_destroy (ehci->qtd_pool);
@@ -183,20 +185,20 @@
 			32 /* byte alignment (for hw parts) */,
 			4096 /* can't cross 4K */);
 	if (!ehci->qtd_pool) {
-		dbg ("no qtd pool");
-		ehci_mem_cleanup (ehci);
-		return -ENOMEM;
+		goto fail;
 	}
 
-	/* QH for control/bulk/intr transfers */
+	/* QHs for control/bulk/intr transfers */
 	ehci->qh_pool = pci_pool_create ("ehci_qh", ehci->hcd.pdev,
 			sizeof (struct ehci_qh),
 			32 /* byte alignment (for hw parts) */,
 			4096 /* can't cross 4K */);
 	if (!ehci->qh_pool) {
-		dbg ("no qh pool");
-		ehci_mem_cleanup (ehci);
-		return -ENOMEM;
+		goto fail;
+	}
+	ehci->async = ehci_qh_alloc (ehci, flags);
+	if (!ehci->async) {
+		goto fail;
 	}
 
 	/* ITD for high speed ISO transfers */
@@ -205,9 +207,7 @@
 			32 /* byte alignment (for hw parts) */,
 			4096 /* can't cross 4K */);
 	if (!ehci->itd_pool) {
-		dbg ("no itd pool");
-		ehci_mem_cleanup (ehci);
-		return -ENOMEM;
+		goto fail;
 	}
 
 	/* SITD for full/low speed split ISO transfers */
@@ -216,9 +216,7 @@
 			32 /* byte alignment (for hw parts) */,
 			4096 /* can't cross 4K */);
 	if (!ehci->sitd_pool) {
-		dbg ("no sitd pool");
-		ehci_mem_cleanup (ehci);
-		return -ENOMEM;
+		goto fail;
 	}
 
 	/* Hardware periodic table */
@@ -227,9 +225,7 @@
 			ehci->periodic_size * sizeof (u32),
 			&ehci->periodic_dma);
 	if (ehci->periodic == 0) {
-		dbg ("no hw periodic table");
-		ehci_mem_cleanup (ehci);
-		return -ENOMEM;
+		goto fail;
 	}
 	for (i = 0; i < ehci->periodic_size; i++)
 		ehci->periodic [i] = EHCI_LIST_END;
@@ -237,11 +233,14 @@
 	/* software shadow of hardware table */
 	ehci->pshadow = kmalloc (ehci->periodic_size * sizeof (void *), flags);
 	if (ehci->pshadow == 0) {
-		dbg ("no shadow periodic table");
-		ehci_mem_cleanup (ehci);
-		return -ENOMEM;
+		goto fail;
 	}
 	memset (ehci->pshadow, 0, ehci->periodic_size * sizeof (void *));
 
 	return 0;
+
+fail:
+	ehci_dbg (ehci, "couldn't init memory\n");
+	ehci_mem_cleanup (ehci);
+	return -ENOMEM;
 }
diff -Nru a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
--- a/drivers/usb/host/ehci-q.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/usb/host/ehci-q.c	Mon Dec  9 18:46:50 2002
@@ -130,8 +130,9 @@
 		else	/* unknown */
 			urb->status = -EPROTO;
 
-		dbg ("ep %d-%s qtd token %08x --> status %d",
-			/* devpath */
+		ehci_vdbg (ehci,
+			"dev%d ep%d%s qtd token %08x --> status %d\n",
+			usb_pipedev (urb->pipe),
 			usb_pipeendpoint (urb->pipe),
 			usb_pipein (urb->pipe) ? "in" : "out",
 			token, urb->status);
@@ -190,7 +191,7 @@
 
 	/* complete() can reenter this HCD */
 	spin_unlock (&ehci->lock);
-	usb_hcd_giveback_urb (&ehci->hcd, urb);
+	usb_hcd_giveback_urb (&ehci->hcd, urb, NULL);
 
 	spin_lock (&ehci->lock);
 }
@@ -678,33 +679,33 @@
 static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
 {
 	u32		dma = QH_NEXT (qh->qh_dma);
-	struct ehci_qh	*q;
+	struct ehci_qh	*head;
 
-	if (unlikely (!(q = ehci->async))) {
+	/* (re)start the async schedule? */
+	head = ehci->async;
+	if (ehci->async_idle)
+		del_timer (&ehci->watchdog);
+	else if (!head->qh_next.qh) {
 		u32	cmd = readl (&ehci->regs->command);
 
-		/* in case a clear of CMD_ASE didn't take yet */
-		(void) handshake (&ehci->regs->status, STS_ASS, 0, 150);
-
-		qh->hw_info1 |= __constant_cpu_to_le32 (QH_HEAD); /* [4.8] */
-		qh->qh_next.qh = qh;
-		qh->hw_next = dma;
-		wmb ();
-		ehci->async = qh;
-		writel ((u32)qh->qh_dma, &ehci->regs->async_next);
-		cmd |= CMD_ASE | CMD_RUN;
-		writel (cmd, &ehci->regs->command);
-		ehci->hcd.state = USB_STATE_RUNNING;
-		/* posted write need not be known to HC yet ... */
-	} else {
-		/* splice right after "start" of ring */
-		qh->hw_info1 &= ~__constant_cpu_to_le32 (QH_HEAD); /* [4.8] */
-		qh->qh_next = q->qh_next;
-		qh->hw_next = q->hw_next;
-		wmb ();
-		q->qh_next.qh = qh;
-		q->hw_next = dma;
+		if (!(cmd & CMD_ASE)) {
+			/* in case a clear of CMD_ASE didn't take yet */
+			(void) handshake (&ehci->regs->status, STS_ASS, 0, 150);
+			cmd |= CMD_ASE | CMD_RUN;
+			writel (cmd, &ehci->regs->command);
+			ehci->hcd.state = USB_STATE_RUNNING;
+			/* posted write need not be known to HC yet ... */
+		}
 	}
+
+	/* splice right after start */
+	qh->qh_next = head->qh_next;
+	qh->hw_next = head->hw_next;
+	wmb ();
+
+	head->qh_next.qh = qh;
+	head->hw_next = dma;
+
 	qh->qh_state = QH_STATE_LINKED;
 	/* qtd completions reported later by interrupt */
 
@@ -897,6 +898,14 @@
 		qh_link_async (ehci, qh);
 	else
 		qh_put (ehci, qh);		// refcount from async list
+
+	/* it's not free to turn the async schedule on/off, so we leave it
+	 * active but idle for a while once it empties.
+	 */
+	if (!ehci->async->qh_next.qh && !timer_pending (&ehci->watchdog)) {
+		ehci->async_idle = 1;
+		mod_timer (&ehci->watchdog, jiffies + EHCI_ASYNC_JIFFIES);
+	}
 }
 
 /* makes sure the async qh will become idle */
@@ -909,7 +918,6 @@
 
 #ifdef DEBUG
 	if (ehci->reclaim
-			|| !ehci->async
 			|| qh->qh_state != QH_STATE_LINKED
 #ifdef CONFIG_SMP
 // this macro lies except on SMP compiles
@@ -919,31 +927,20 @@
 		BUG ();
 #endif
 
-	qh->qh_state = QH_STATE_UNLINK;
-	ehci->reclaim = qh = qh_get (qh);
-
-	// dbg_qh ("start unlink", ehci, qh);
-
-	/* Remove the last QH (qhead)?  Stop async schedule first. */
-	if (unlikely (qh == ehci->async && qh->qh_next.qh == qh)) {
+	/* stop async schedule right now? */
+	if (unlikely (qh == ehci->async)) {
 		/* can't get here without STS_ASS set */
 		if (ehci->hcd.state != USB_STATE_HALT) {
 			writel (cmd & ~CMD_ASE, &ehci->regs->command);
-			(void) handshake (&ehci->regs->status, STS_ASS, 0, 150);
-#if 0
-			// one VT8235 system wants to die with STS_FATAL
-			// unless this qh is leaked here. others seem ok...
-			qh = qh_get (qh);
-			dbg_qh ("async/off", ehci, qh);
-#endif
+			wmb ();
+			// handshake later, if we need to
 		}
-		qh->qh_next.qh = ehci->async = 0;
-
-		ehci->reclaim_ready = 1;
-		tasklet_schedule (&ehci->tasklet);
 		return;
 	} 
 
+	qh->qh_state = QH_STATE_UNLINK;
+	ehci->reclaim = qh = qh_get (qh);
+
 	if (unlikely (ehci->hcd.state == USB_STATE_HALT)) {
 		ehci->reclaim_ready = 1;
 		tasklet_schedule (&ehci->tasklet);
@@ -951,13 +948,9 @@
 	}
 
 	prev = ehci->async;
-	while (prev->qh_next.qh != qh && prev->qh_next.qh != ehci->async)
+	while (prev->qh_next.qh != qh)
 		prev = prev->qh_next.qh;
 
-	if (qh->hw_info1 & __constant_cpu_to_le32 (QH_HEAD)) {
-		ehci->async = prev;
-		prev->hw_info1 |= __constant_cpu_to_le32 (QH_HEAD);
-	}
 	prev->hw_next = qh->hw_next;
 	prev->qh_next = qh->qh_next;
 	wmb ();
@@ -979,37 +972,34 @@
 	unsigned		count;
 
 rescan:
-	qh = ehci->async;
+	qh = ehci->async->qh_next.qh;
 	count = 0;
 	if (likely (qh != 0)) {
 		do {
 			/* clean any finished work for this qh */
 			if (!list_empty (&qh->qtd_list)) {
-				// dbg_qh ("scan_async", ehci, qh);
-				qh = qh_get (qh);
+				int temp;
 
-				/* concurrent unlink could happen here */
-				count += qh_completions (ehci, qh);
+				/* unlinks could happen here; completion
+				 * reporting drops the lock.
+				 */
+				qh = qh_get (qh);
+				temp = qh_completions (ehci, qh);
 				qh_put (ehci, qh);
+				if (temp != 0) {
+					count += temp;
+					goto rescan;
+				}
 			}
 
 			/* unlink idle entries, reducing HC PCI usage as
-			 * well as HCD schedule-scanning costs.  removing
-			 * the last qh is deferred, since it's costly.
+			 * well as HCD schedule-scanning costs.
 			 *
 			 * FIXME don't unlink idle entries so quickly; it
 			 * can penalize (common) half duplex protocols.
 			 */
 			if (list_empty (&qh->qtd_list) && !ehci->reclaim) {
-				if (qh->qh_next.qh != qh) {
-					// dbg ("irq/empty");
-					start_unlink_async (ehci, qh);
-				} else if (!timer_pending (&ehci->watchdog)) {
-					/* can't use IAA for last entry */
-					ehci->async_idle = 1;
-					mod_timer (&ehci->watchdog,
-						jiffies + EHCI_ASYNC_JIFFIES);
-				}
+				start_unlink_async (ehci, qh);
 			}
 
 			/* keep latencies down: let any irqs in */
@@ -1021,8 +1011,6 @@
 			}
 
 			qh = qh->qh_next.qh;
-			if (!qh)		/* unlinked? */
-				goto rescan;
-		} while (qh != ehci->async);
+		} while (qh);
 	}
 }
diff -Nru a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
--- a/drivers/usb/host/ehci-sched.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/usb/host/ehci-sched.c	Mon Dec  9 18:46:35 2002
@@ -922,7 +922,7 @@
 
 	/* complete() can reenter this HCD */
 	spin_unlock (&ehci->lock);
-	usb_hcd_giveback_urb (&ehci->hcd, urb);
+	usb_hcd_giveback_urb (&ehci->hcd, urb, NULL);
 	spin_lock (&ehci->lock);
 
 	/* defer stopping schedule; completion can submit */
diff -Nru a/drivers/usb/host/hc_simple.c b/drivers/usb/host/hc_simple.c
--- a/drivers/usb/host/hc_simple.c	Mon Dec  9 18:46:52 2002
+++ b/drivers/usb/host/hc_simple.c	Mon Dec  9 18:46:52 2002
@@ -106,7 +106,7 @@
 	urb->dev = urb->hcpriv = NULL;
 
 	if (urb->complete) {
-		urb->complete (urb);	/* call complete */
+		urb->complete (urb, NULL);	/* call complete */
 	}
 
 	if (resubmit) {
@@ -254,7 +254,7 @@
 		if (urb->complete && (urb->transfer_flags & URB_ASYNC_UNLINK)) {
 			urb->status = -ENOENT;
 			urb->actual_length = 0;
-			urb->complete (urb);
+			urb->complete (urb, NULL);
 			urb->status = 0;
 		} else {
 			urb->status = -ENOENT;
diff -Nru a/drivers/usb/host/hc_sl811_rh.c b/drivers/usb/host/hc_sl811_rh.c
--- a/drivers/usb/host/hc_sl811_rh.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/usb/host/hc_sl811_rh.c	Mon Dec  9 18:46:50 2002
@@ -193,7 +193,7 @@
 					   usb_pipeout (urb->pipe));
 
 			if (urb->complete) {
-				urb->complete (urb);
+				urb->complete (urb, NULL);
 			}
 		}
 	}
@@ -506,7 +506,7 @@
 	urb->hcpriv = NULL;
 	urb->dev = NULL;
 	if (urb->complete) {
-		urb->complete (urb);
+		urb->complete (urb, NULL);
 	}
 
 	return 0;
@@ -537,7 +537,7 @@
 		if (urb->transfer_flags & URB_ASYNC_UNLINK) {
 			urb->status = -ECONNRESET;
 			if (urb->complete) {
-				urb->complete (urb);
+				urb->complete (urb, NULL);
 			}
 		} else
 			urb->status = -ENOENT;
diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
--- a/drivers/usb/host/ohci-hcd.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/usb/host/ohci-hcd.c	Mon Dec  9 18:46:34 2002
@@ -295,7 +295,7 @@
 		 * with HC dead, we won't respect hc queue pointers
 		 * any more ... just clean up every urb's memory.
 		 */
-		finish_urb (ohci, urb);
+		finish_urb (ohci, urb, NULL);
 	}
 	return 0;
 }
@@ -531,7 +531,7 @@
 
 /* an interrupt happens */
 
-static void ohci_irq (struct usb_hcd *hcd)
+static void ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
 {
 	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
 	struct ohci_regs	*regs = ohci->regs;
@@ -570,7 +570,7 @@
   
 	if (ints & OHCI_INTR_WDH) {
 		writel (OHCI_INTR_WDH, &regs->intrdisable);	
-		dl_done_list (ohci, dl_reverse_done_list (ohci));
+		dl_done_list (ohci, dl_reverse_done_list (ohci), ptregs);
 		writel (OHCI_INTR_WDH, &regs->intrenable); 
 	}
   
@@ -581,7 +581,7 @@
 	 */
 	spin_lock (&ohci->lock);
 	if (ohci->ed_rm_list)
-		finish_unlinks (ohci, le16_to_cpu (ohci->hcca->frame_no));
+		finish_unlinks (ohci, le16_to_cpu (ohci->hcca->frame_no), ptregs);
 	if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list)
 		writel (OHCI_INTR_SF, &regs->intrdisable);	
 	spin_unlock (&ohci->lock);
diff -Nru a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
--- a/drivers/usb/host/ohci-pci.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/usb/host/ohci-pci.c	Mon Dec  9 18:46:50 2002
@@ -271,7 +271,7 @@
 			enable_irq (hcd->pdev->irq);
 #endif
 		if (ohci->hcca->done_head)
-			dl_done_list (ohci, dl_reverse_done_list (ohci));
+			dl_done_list (ohci, dl_reverse_done_list (ohci), NULL);
 		writel (OHCI_INTR_WDH, &ohci->regs->intrenable); 
 
 		/* assume there are TDs on the bulk and control lists */
diff -Nru a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
--- a/drivers/usb/host/ohci-q.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/usb/host/ohci-q.c	Mon Dec  9 18:46:51 2002
@@ -32,7 +32,7 @@
  * It's completely gone from HC data structures.
  * PRECONDITION:  no locks held  (Giveback can call into HCD.)
  */
-static void finish_urb (struct ohci_hcd *ohci, struct urb *urb)
+static void finish_urb (struct ohci_hcd *ohci, struct urb *urb, struct pt_regs *regs)
 {
 	unsigned long	flags;
 
@@ -59,7 +59,7 @@
 #ifdef OHCI_VERBOSE_DEBUG
 	urb_print (urb, "RET", usb_pipeout (urb->pipe));
 #endif
-	usb_hcd_giveback_urb (&ohci->hcd, urb);
+	usb_hcd_giveback_urb (&ohci->hcd, urb, regs);
 }
 
 
@@ -848,7 +848,7 @@
 #define tick_before(t1,t2) ((((s16)(t1))-((s16)(t2))) < 0)
 
 /* there are some urbs/eds to unlink; called in_irq(), with HCD locked */
-static void finish_unlinks (struct ohci_hcd *ohci, u16 tick)
+static void finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *regs)
 {
 	struct ed	*ed, **last;
 
@@ -913,7 +913,7 @@
 			if (urb_priv->td_cnt == urb_priv->length) {
 				modified = completed = 1;
 				spin_unlock (&ohci->lock);
-				finish_urb (ohci, urb);
+				finish_urb (ohci, urb, regs);
 				spin_lock (&ohci->lock);
 			}
 		}
@@ -976,7 +976,7 @@
  * path is finish_unlinks(), which unlinks URBs using ed_rm_list, instead of
  * scanning the (re-reversed) donelist as this does.
  */
-static void dl_done_list (struct ohci_hcd *ohci, struct td *td)
+static void dl_done_list (struct ohci_hcd *ohci, struct td *td, struct pt_regs *regs)
 {
 	unsigned long	flags;
 
@@ -994,7 +994,7 @@
 		/* If all this urb's TDs are done, call complete() */
   		if (urb_priv->td_cnt == urb_priv->length) {
      			spin_unlock_irqrestore (&ohci->lock, flags);
-  			finish_urb (ohci, urb);
+  			finish_urb (ohci, urb, regs);
   			spin_lock_irqsave (&ohci->lock, flags);
   		}
 
diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
--- a/drivers/usb/host/uhci-hcd.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/usb/host/uhci-hcd.c	Mon Dec  9 18:46:51 2002
@@ -90,7 +90,6 @@
 static int uhci_get_current_frame_number(struct uhci_hcd *uhci);
 static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb);
 static void uhci_unlink_generic(struct uhci_hcd *uhci, struct urb *urb);
-static void uhci_finish_urb(struct usb_hcd *hcd, struct urb *urb);
 
 static int  ports_active(struct uhci_hcd *uhci);
 static void suspend_hc(struct uhci_hcd *uhci);
@@ -1051,10 +1050,6 @@
 
 td_error:
 	ret = uhci_map_status(status, uhci_packetout(td_token(td)));
-	if (ret == -EPIPE)
-		/* endpoint has stalled - mark it halted */
-		usb_endpoint_halt(urb->dev, uhci_endpoint(td_token(td)),
-	    			uhci_packetout(td_token(td)));
 
 err:
 	if ((debug == 1 && ret != -EPIPE) || debug > 1) {
@@ -1802,7 +1797,7 @@
 	spin_unlock_irqrestore(&uhci->qh_remove_list_lock, flags);
 }
 
-static void uhci_finish_urb(struct usb_hcd *hcd, struct urb *urb)
+static void uhci_finish_urb(struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs)
 {
 	struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
 	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
@@ -1817,10 +1812,10 @@
 		urb->status = status;
 	spin_unlock_irqrestore(&urb->lock, flags);
 
-	usb_hcd_giveback_urb(hcd, urb);
+	usb_hcd_giveback_urb(hcd, urb, regs);
 }
 
-static void uhci_finish_completion(struct usb_hcd *hcd)
+static void uhci_finish_completion(struct usb_hcd *hcd, struct pt_regs *regs)
 {
 	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
 	struct list_head *tmp, *head;
@@ -1836,7 +1831,7 @@
 		list_del_init(&urbp->complete_list);
 		spin_unlock_irqrestore(&uhci->complete_list_lock, flags);
 
-		uhci_finish_urb(hcd, urb);
+		uhci_finish_urb(hcd, urb, regs);
 
 		spin_lock_irqsave(&uhci->complete_list_lock, flags);
 		head = &uhci->complete_list;
@@ -1868,7 +1863,7 @@
 	spin_unlock_irqrestore(&uhci->urb_remove_list_lock, flags);
 }
 
-static void uhci_irq(struct usb_hcd *hcd)
+static void uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
 {
 	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
 	unsigned int io_addr = uhci->io_addr;
@@ -1919,7 +1914,7 @@
 	}
 	spin_unlock(&uhci->urb_list_lock);
 
-	uhci_finish_completion(hcd);
+	uhci_finish_completion(hcd, regs);
 }
 
 static void reset_hc(struct uhci_hcd *uhci)
@@ -2078,7 +2073,7 @@
 	struct proc_dir_entry *ent;
 #endif
 
-	uhci->io_addr = (unsigned) hcd->regs;
+	uhci->io_addr = (unsigned long) hcd->regs;
 	io_size = pci_resource_len(hcd->pdev, hcd->region);
 
 #ifdef CONFIG_PROC_FS
diff -Nru a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
--- a/drivers/usb/host/uhci-hcd.h	Mon Dec  9 18:46:50 2002
+++ b/drivers/usb/host/uhci-hcd.h	Mon Dec  9 18:46:50 2002
@@ -299,7 +299,7 @@
 #endif
 
 	/* Grabbed from PCI */
-	unsigned int io_addr;
+	unsigned long io_addr;
 
 	struct pci_pool *qh_pool;
 	struct pci_pool *td_pool;
diff -Nru a/drivers/usb/image/hpusbscsi.c b/drivers/usb/image/hpusbscsi.c
--- a/drivers/usb/image/hpusbscsi.c	Mon Dec  9 18:46:52 2002
+++ b/drivers/usb/image/hpusbscsi.c	Mon Dec  9 18:46:52 2002
@@ -275,7 +275,7 @@
 static int hpusbscsi_scsi_queuecommand (Scsi_Cmnd *srb, scsi_callback callback)
 {
 	struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->host->hostdata[0]);
-	usb_urb_callback usb_callback;
+	usb_complete_t usb_callback;
 	int res;
 
 	/* we don't answer for anything but our single device on any faked host controller */
@@ -382,7 +382,7 @@
 	hpusbscsi->state = HP_STATE_FREE;
 }
 
-static void  control_interrupt_callback (struct urb *u)
+static void  control_interrupt_callback (struct urb *u, struct pt_regs *regs)
 {
 	struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
 	u8 scsi_state;
@@ -435,7 +435,7 @@
 	}
 }
 
-static void simple_command_callback(struct urb *u)
+static void simple_command_callback(struct urb *u, struct pt_regs *regs)
 {
 	struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
 	if (unlikely(u->status<0)) {
@@ -454,11 +454,11 @@
 	}
 }
 
-static void scatter_gather_callback(struct urb *u)
+static void scatter_gather_callback(struct urb *u, struct pt_regs *regs)
 {
 	struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
         struct scatterlist *sg = hpusbscsi->srb->buffer;
-        usb_urb_callback callback;
+        usb_complete_t callback;
         int res;
 
         DEBUG("Going through scatter/gather\n");
@@ -494,7 +494,7 @@
 	TRACE_STATE;
 }
 
-static void simple_done (struct urb *u)
+static void simple_done (struct urb *u, struct pt_regs *regs)
 {
 	struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
 
@@ -521,7 +521,7 @@
 	}
 }
 
-static void simple_payload_callback (struct urb *u)
+static void simple_payload_callback (struct urb *u, struct pt_regs *regs)
 {
 	struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
 	int res;
@@ -553,7 +553,7 @@
 	} 
 }
 
-static void request_sense_callback (struct urb *u)
+static void request_sense_callback (struct urb *u, struct pt_regs *regs)
 {
 	struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
 
diff -Nru a/drivers/usb/image/hpusbscsi.h b/drivers/usb/image/hpusbscsi.h
--- a/drivers/usb/image/hpusbscsi.h	Mon Dec  9 18:46:34 2002
+++ b/drivers/usb/image/hpusbscsi.h	Mon Dec  9 18:46:34 2002
@@ -6,7 +6,6 @@
 
 /* A big thanks to Jose for untiring testing */
 
-typedef void (*usb_urb_callback) (struct urb *);
 typedef void (*scsi_callback)(Scsi_Cmnd *);
 
 #define SENSE_COMMAND_SIZE 6
@@ -54,34 +53,34 @@
 #define DIRECTION_IS_IN(x) ((scsi_command_direction[x>>3] >> (x & 7)) & 1)
 
 static int hpusbscsi_scsi_detect (struct SHT * sht);
-static void simple_command_callback(struct urb *u);
-static void scatter_gather_callback(struct urb *u);
-static void simple_payload_callback (struct urb *u);
-static void request_sense_callback (struct urb *u);
-static void control_interrupt_callback (struct urb *u);
-static void simple_done (struct urb *u);
+static void simple_command_callback(struct urb *u, struct pt_regs *regs);
+static void scatter_gather_callback(struct urb *u, struct pt_regs *regs);
+static void simple_payload_callback (struct urb *u, struct pt_regs *regs);
+static void request_sense_callback (struct urb *u, struct pt_regs *regs);
+static void control_interrupt_callback (struct urb *u, struct pt_regs *regs);
+static void simple_done (struct urb *u, struct pt_regs *regs);
 static int hpusbscsi_scsi_queuecommand (Scsi_Cmnd *srb, scsi_callback callback);
 static int hpusbscsi_scsi_host_reset (Scsi_Cmnd *srb);
 static int hpusbscsi_scsi_abort (Scsi_Cmnd *srb);
 static void issue_request_sense (struct hpusbscsi *hpusbscsi);
 
 static Scsi_Host_Template hpusbscsi_scsi_host_template = {
-	name:           "hpusbscsi",
-	detect:		hpusbscsi_scsi_detect,
-//	release:	hpusbscsi_scsi_release,
-	queuecommand:	hpusbscsi_scsi_queuecommand,
-
-	eh_abort_handler:	hpusbscsi_scsi_abort,
-	eh_host_reset_handler:	hpusbscsi_scsi_host_reset,
-
-	sg_tablesize:		SG_ALL,
-	can_queue:		1,
-	this_id:		-1,
-	cmd_per_lun:		1,
-	present:		0,
-	unchecked_isa_dma:	FALSE,
-	use_clustering:		TRUE,
-	emulated:		TRUE
+	.name			= "hpusbscsi",
+	.detect			= hpusbscsi_scsi_detect,
+//	.release		= hpusbscsi_scsi_release,
+	.queuecommand		= hpusbscsi_scsi_queuecommand,
+
+	.eh_abort_handler	= hpusbscsi_scsi_abort,
+	.eh_host_reset_handler	= hpusbscsi_scsi_host_reset,
+
+	.sg_tablesize		= SG_ALL,
+	.can_queue		= 1,
+	.this_id		= -1,
+	.cmd_per_lun		= 1,
+	.present		= 0,
+	.unchecked_isa_dma	= FALSE,
+	.use_clustering		= TRUE,
+	.emulated		= TRUE
 };
 
 /* defines for internal driver state */
diff -Nru a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c
--- a/drivers/usb/image/mdc800.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/usb/image/mdc800.c	Mon Dec  9 18:46:38 2002
@@ -248,7 +248,7 @@
 /*
  * USB IRQ Handler for InputLine
  */
-static void mdc800_usb_irq (struct urb *urb)
+static void mdc800_usb_irq (struct urb *urb, struct pt_regs *res)
 {
 	int data_received=0, wake_up;
 	unsigned char* b=urb->transfer_buffer;
@@ -351,7 +351,7 @@
 /*
  * The write_urb callback function
  */
-static void mdc800_usb_write_notify (struct urb *urb)
+static void mdc800_usb_write_notify (struct urb *urb, struct pt_regs *res)
 {
 	struct mdc800_data* mdc800=urb->context;
 
@@ -371,7 +371,7 @@
 /*
  * The download_urb callback function
  */
-static void mdc800_usb_download_notify (struct urb *urb)
+static void mdc800_usb_download_notify (struct urb *urb, struct pt_regs *res)
 {
 	struct mdc800_data* mdc800=urb->context;
 
diff -Nru a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
--- a/drivers/usb/image/microtek.c	Mon Dec  9 18:46:52 2002
+++ b/drivers/usb/image/microtek.c	Mon Dec  9 18:46:52 2002
@@ -470,7 +470,7 @@
 int mts_scsi_queuecommand (Scsi_Cmnd *srb, mts_scsi_cmnd_callback callback );
 
 static void mts_transfer_cleanup( struct urb *transfer );
-static void mts_do_sg(struct urb * transfer);
+static void mts_do_sg(struct urb * transfer, struct pt_regs *regs);
 
 
 inline static
@@ -478,7 +478,7 @@
 			int pipe,
 			void* data,
 			unsigned length,
-			mts_usb_urb_callback callback )
+			usb_complete_t callback )
 /* Interrupt context! */
 
 /* Holding transfer->context->lock! */
@@ -518,7 +518,7 @@
 
 }
 
-static void mts_transfer_done( struct urb *transfer )
+static void mts_transfer_done( struct urb *transfer, struct pt_regs *regs )
 {
 	MTS_INT_INIT();
 
@@ -544,7 +544,7 @@
 			   mts_transfer_done );
 }
 
-static void mts_data_done( struct urb* transfer )
+static void mts_data_done( struct urb* transfer, struct pt_regs *regs )
 /* Interrupt context! */
 {
 	MTS_INT_INIT();
@@ -561,7 +561,7 @@
 }
 
 
-static void mts_command_done( struct urb *transfer )
+static void mts_command_done( struct urb *transfer, struct pt_regs *regs )
 /* Interrupt context! */
 {
 	MTS_INT_INIT();
@@ -602,7 +602,7 @@
 	return;
 }
 
-static void mts_do_sg (struct urb* transfer)
+static void mts_do_sg (struct urb* transfer, struct pt_regs *regs)
 {
 	struct scatterlist * sg;
 	MTS_INT_INIT();
diff -Nru a/drivers/usb/image/microtek.h b/drivers/usb/image/microtek.h
--- a/drivers/usb/image/microtek.h	Mon Dec  9 18:46:35 2002
+++ b/drivers/usb/image/microtek.h	Mon Dec  9 18:46:35 2002
@@ -9,7 +9,6 @@
  */
 
 typedef void (*mts_scsi_cmnd_callback)(Scsi_Cmnd *);
-typedef void (*mts_usb_urb_callback) (struct urb *);
 
 
 struct mts_transfer_context
diff -Nru a/drivers/usb/image/scanner.c b/drivers/usb/image/scanner.c
--- a/drivers/usb/image/scanner.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/usb/image/scanner.c	Mon Dec  9 18:46:35 2002
@@ -354,7 +354,7 @@
 #include "scanner.h"
 
 static void
-irq_scanner(struct urb *urb)
+irq_scanner(struct urb *urb, struct pt_regs *regs)
 {
 
 /*
diff -Nru a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
--- a/drivers/usb/input/aiptek.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/usb/input/aiptek.c	Mon Dec  9 18:46:50 2002
@@ -104,7 +104,7 @@
 	int y_max;
 	int pressure_min;
 	int pressure_max;
-	void (*irq) (struct urb * urb);
+	usb_complete_t irq;
 	unsigned long evbit;
 	unsigned long absbit;
 	unsigned long relbit;
@@ -125,7 +125,7 @@
 };
 
 static void
-aiptek_irq(struct urb *urb)
+aiptek_irq(struct urb *urb, struct pt_regs *regs)
 {
 	struct aiptek *aiptek = urb->context;
 	unsigned char *data = aiptek->data;
diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
--- a/drivers/usb/input/hid-core.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/usb/input/hid-core.c	Mon Dec  9 18:46:38 2002
@@ -898,7 +898,7 @@
  * Input interrupt completion handler.
  */
 
-static void hid_irq_in(struct urb *urb)
+static void hid_irq_in(struct urb *urb, struct pt_regs *regs)
 {
 	struct hid_device	*hid = urb->context;
 	int			status;
@@ -1090,7 +1090,7 @@
  * Output interrupt completion handler.
  */
 
-static void hid_irq_out(struct urb *urb)
+static void hid_irq_out(struct urb *urb, struct pt_regs *regs)
 {
 	struct hid_device *hid = urb->context;
 	unsigned long flags;
@@ -1119,7 +1119,7 @@
  * Control pipe completion handler.
  */
 
-static void hid_ctrl(struct urb *urb)
+static void hid_ctrl(struct urb *urb, struct pt_regs *regs)
 {
 	struct hid_device *hid = urb->context;
 	unsigned long flags;
diff -Nru a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
--- a/drivers/usb/input/hiddev.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/usb/input/hiddev.c	Mon Dec  9 18:46:36 2002
@@ -781,6 +781,6 @@
 
 void __exit hiddev_exit(void)
 {
-	devfs_unregister(hiddev_devfs_handle);
 	usb_deregister(&hiddev_driver);
+	devfs_remove("usb/hid");
 }
diff -Nru a/drivers/usb/input/pid.c b/drivers/usb/input/pid.c
--- a/drivers/usb/input/pid.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/usb/input/pid.c	Mon Dec  9 18:46:51 2002
@@ -46,7 +46,7 @@
 	(hid_pid)->effects[(i)].owner == current->pid))
 
 /* Called when a transfer is completed */
-static void hid_pid_ctrl_out(struct urb *u)
+static void hid_pid_ctrl_out(struct urb *u, struct pt_regs *regs)
 {
 #ifdef DEBUG
     printk("hid_pid_ctrl_out - Transfer Completed\n");
diff -Nru a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c
--- a/drivers/usb/input/powermate.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/usb/input/powermate.c	Mon Dec  9 18:46:38 2002
@@ -72,10 +72,10 @@
 static char pm_name_powermate[] = "Griffin PowerMate";
 static char pm_name_soundknob[] = "Griffin SoundKnob";
 
-static void powermate_config_complete(struct urb *urb); /* forward declararation of callback */
+static void powermate_config_complete(struct urb *urb, struct pt_regs *regs);
 
 /* Callback for data arriving from the PowerMate over the USB interrupt pipe */
-static void powermate_irq(struct urb *urb)
+static void powermate_irq(struct urb *urb, struct pt_regs *regs)
 {
 	struct powermate_device *pm = urb->context;
 	int retval;
@@ -182,7 +182,7 @@
 }
 
 /* Called when our asynchronous control message completes. We may need to issue another immediately */
-static void powermate_config_complete(struct urb *urb)
+static void powermate_config_complete(struct urb *urb, struct pt_regs *regs)
 {
 	struct powermate_device *pm = urb->context;
 
diff -Nru a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c
--- a/drivers/usb/input/usbkbd.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/usb/input/usbkbd.c	Mon Dec  9 18:46:51 2002
@@ -82,7 +82,7 @@
 	dma_addr_t leds_dma;
 };
 
-static void usb_kbd_irq(struct urb *urb)
+static void usb_kbd_irq(struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_kbd *kbd = urb->context;
 	int i;
@@ -156,7 +156,7 @@
 	return 0;
 }
 
-static void usb_kbd_led(struct urb *urb)
+static void usb_kbd_led(struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_kbd *kbd = urb->context;
 
diff -Nru a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c
--- a/drivers/usb/input/usbmouse.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/usb/input/usbmouse.c	Mon Dec  9 18:46:51 2002
@@ -57,7 +57,7 @@
 	dma_addr_t data_dma;
 };
 
-static void usb_mouse_irq(struct urb *urb)
+static void usb_mouse_irq(struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_mouse *mouse = urb->context;
 	signed char *data = mouse->data;
diff -Nru a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
--- a/drivers/usb/input/wacom.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/usb/input/wacom.c	Mon Dec  9 18:46:34 2002
@@ -86,7 +86,7 @@
 	int pressure_max;
 	int distance_max;
 	int type;
-	void (*irq)(struct urb *urb);
+	usb_complete_t irq;
 };
 
 struct wacom {
@@ -102,7 +102,7 @@
 	char phys[32];
 };
 
-static void wacom_pl_irq(struct urb *urb)
+static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
 {
 	struct wacom *wacom = urb->context;
 	unsigned char *data = wacom->data;
@@ -157,7 +157,7 @@
 		     __FUNCTION__, retval);
 }
 
-static void wacom_penpartner_irq(struct urb *urb)
+static void wacom_penpartner_irq(struct urb *urb, struct pt_regs *regs)
 {
 	struct wacom *wacom = urb->context;
 	unsigned char *data = wacom->data;
@@ -194,7 +194,7 @@
 		     __FUNCTION__, retval);
 }
 
-static void wacom_graphire_irq(struct urb *urb)
+static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs)
 {
 	struct wacom *wacom = urb->context;
 	unsigned char *data = wacom->data;
@@ -267,7 +267,7 @@
 		     __FUNCTION__, retval);
 }
 
-static void wacom_intuos_irq(struct urb *urb)
+static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs)
 {
 	struct wacom *wacom = urb->context;
 	unsigned char *data = wacom->data;
diff -Nru a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
--- a/drivers/usb/input/xpad.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/usb/input/xpad.c	Mon Dec  9 18:46:37 2002
@@ -163,7 +163,7 @@
 	input_sync(dev);
 }
 
-static void xpad_irq_in(struct urb *urb)
+static void xpad_irq_in(struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_xpad *xpad = urb->context;
 	int retval;
diff -Nru a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c
--- a/drivers/usb/media/dabusb.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/usb/media/dabusb.c	Mon Dec  9 18:46:38 2002
@@ -171,7 +171,7 @@
 	return 0;
 }
 /*-------------------------------------------------------------------*/
-static void dabusb_iso_complete (struct urb *purb)
+static void dabusb_iso_complete (struct urb *purb, struct pt_regs *regs)
 {
 	pbuff_t b = purb->context;
 	pdabusb_t s = b->s;
diff -Nru a/drivers/usb/media/dsbr100.c b/drivers/usb/media/dsbr100.c
--- a/drivers/usb/media/dsbr100.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/usb/media/dsbr100.c	Mon Dec  9 18:46:36 2002
@@ -265,7 +265,8 @@
 		case VIDIOCSFREQ:
 		{
 			int *freq = arg;
-			*freq = radio->curfreq;
+
+			radio->curfreq = *freq;
 			if (dsbr100_setfreq(radio, radio->curfreq)==-1)
 				warn("set frequency failed");
 			return 0;
diff -Nru a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c
--- a/drivers/usb/media/konicawc.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/usb/media/konicawc.c	Mon Dec  9 18:46:34 2002
@@ -332,7 +332,7 @@
 }
 
 
-static void konicawc_isoc_irq(struct urb *urb)
+static void konicawc_isoc_irq(struct urb *urb, struct pt_regs *regs)
 {
 	struct uvd *uvd = urb->context;
 	struct konicawc *cam = (struct konicawc *)uvd->user_data;
diff -Nru a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c
--- a/drivers/usb/media/ov511.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/usb/media/ov511.c	Mon Dec  9 18:46:35 2002
@@ -3843,7 +3843,7 @@
 }
 
 static void
-ov51x_isoc_irq(struct urb *urb)
+ov51x_isoc_irq(struct urb *urb, struct pt_regs *regs)
 {
 	int i;
 	struct usb_ov511 *ov;
diff -Nru a/drivers/usb/media/pwc-if.c b/drivers/usb/media/pwc-if.c
--- a/drivers/usb/media/pwc-if.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/usb/media/pwc-if.c	Mon Dec  9 18:46:50 2002
@@ -598,7 +598,7 @@
 /* This gets called for the Isochronous pipe (video). This is done in
  * interrupt time, so it has to be fast, not crash, and not stall. Neat.
  */
-static void pwc_isoc_handler(struct urb *urb)
+static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs)
 {
 	struct pwc_device *pdev;
 	int i, fst, flen;
diff -Nru a/drivers/usb/media/se401.c b/drivers/usb/media/se401.c
--- a/drivers/usb/media/se401.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/usb/media/se401.c	Mon Dec  9 18:46:35 2002
@@ -425,7 +425,7 @@
 }
 
 /* irq handler for snapshot button */
-static void se401_button_irq(struct urb *urb)
+static void se401_button_irq(struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_se401 *se401 = urb->context;
 	int status;
@@ -461,7 +461,7 @@
 		     __FUNCTION__, status);
 }
 
-static void se401_video_irq(struct urb *urb)
+static void se401_video_irq(struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_se401 *se401 = urb->context;
 	int length = urb->actual_length;
diff -Nru a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c
--- a/drivers/usb/media/stv680.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/usb/media/stv680.c	Mon Dec  9 18:46:50 2002
@@ -673,7 +673,7 @@
 	return 0;
 }
 
-static void stv680_video_irq (struct urb *urb)
+static void stv680_video_irq (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_stv *stv680 = urb->context;
 	int length = urb->actual_length;
diff -Nru a/drivers/usb/media/usbvideo.c b/drivers/usb/media/usbvideo.c
--- a/drivers/usb/media/usbvideo.c	Mon Dec  9 18:46:52 2002
+++ b/drivers/usb/media/usbvideo.c	Mon Dec  9 18:46:52 2002
@@ -1820,7 +1820,7 @@
 	return totlen;
 }
 
-static void usbvideo_IsocIrq(struct urb *urb)
+static void usbvideo_IsocIrq(struct urb *urb, struct pt_regs *regs)
 {
 	int i, ret, len;
 	struct uvd *uvd = urb->context;
diff -Nru a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
--- a/drivers/usb/misc/auerswald.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/usb/misc/auerswald.c	Mon Dec  9 18:46:36 2002
@@ -287,7 +287,7 @@
 
 /*-------------------------------------------------------------------*/
 /* Forwards */
-static void auerswald_ctrlread_complete (struct urb * urb);
+static void auerswald_ctrlread_complete (struct urb * urb, struct pt_regs *regs);
 static void auerswald_removeservice (pauerswald_t cp, pauerscon_t scp);
 extern struct usb_driver auerswald_driver;
 
@@ -297,7 +297,7 @@
 /* --------------------------                                        */
 
 /* completion function for chained urbs */
-static void auerchain_complete (struct urb * urb)
+static void auerchain_complete (struct urb * urb, struct pt_regs *regs)
 {
 	unsigned long flags;
         int result;
@@ -316,7 +316,7 @@
            NOTE: this function may lead to more urbs submitted into the chain.
                  (no chain lock at calling complete()!)
                  acp->active != NULL is protecting us against recursion.*/
-        urb->complete (urb);
+        urb->complete (urb, regs);
 
         /* detach element from chain data structure */
 	spin_lock_irqsave (&acp->lock, flags);
@@ -351,7 +351,7 @@
                         urb->status = result;
                         dbg("auerchain_complete: usb_submit_urb with error code %d", result);
                         /* and do error handling via *this* completion function (recursive) */
-                        auerchain_complete( urb);
+                        auerchain_complete( urb, NULL);
                 }
         } else {
                 /* simple return without submitting a new urb.
@@ -428,7 +428,7 @@
                         urb->status = result;
                         dbg("auerchain_submit_urb: usb_submit_urb with error code %d", result);
                         /* and do error handling via completion function */
-                        auerchain_complete( urb);
+                        auerchain_complete( urb, NULL);
                 }
         }
 
@@ -468,7 +468,7 @@
                         spin_unlock_irqrestore (&acp->lock, flags);
                         dbg ("unlink waiting urb");
                         urb->status = -ENOENT;
-                        urb->complete (urb);
+                        urb->complete (urb, NULL);
                         return 0;
                 }
         }
@@ -525,7 +525,7 @@
                 spin_unlock_irqrestore (&acp->lock, flags);
                 dbg ("unlink waiting urb");
                 urbp->status = -ENOENT;
-                urbp->complete (urbp);
+                urbp->complete (urbp, NULL);
                 spin_lock_irqsave (&acp->lock, flags);
         }
         spin_unlock_irqrestore (&acp->lock, flags);
@@ -612,7 +612,7 @@
 
 
 /* completion handler for synchronous chained URBs */
-static void auerchain_blocking_completion (struct urb *urb)
+static void auerchain_blocking_completion (struct urb *urb, struct pt_regs *regs)
 {
 	pauerchain_chs_t pchs = (pauerchain_chs_t)urb->context;
 	pchs->done = 1;
@@ -718,7 +718,7 @@
 	dr->wLength = cpu_to_le16 (size);
 
 	usb_fill_control_urb (urb, dev, pipe, (unsigned char*)dr, data, size,    /* build urb */
-		          (usb_complete_t)auerchain_blocking_completion,0);
+		          auerchain_blocking_completion,0);
 	ret = auerchain_start_wait_urb (acp, urb, timeout, &length);
 
 	usb_free_urb (urb);
@@ -881,7 +881,7 @@
 }
 
 /* Completion of asynchronous write block */
-static void auerchar_ctrlwrite_complete (struct urb * urb)
+static void auerchar_ctrlwrite_complete (struct urb * urb, struct pt_regs *regs)
 {
 	pauerbuf_t bp = (pauerbuf_t) urb->context;
 	pauerswald_t cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl)));
@@ -894,7 +894,7 @@
 }
 
 /* Completion handler for dummy retry packet */
-static void auerswald_ctrlread_wretcomplete (struct urb * urb)
+static void auerswald_ctrlread_wretcomplete (struct urb * urb, struct pt_regs *regs)
 {
         pauerbuf_t bp = (pauerbuf_t) urb->context;
         pauerswald_t cp;
@@ -921,19 +921,19 @@
 	/* bp->dr->index    = channel id;          remains */
 	usb_fill_control_urb (bp->urbp, cp->usbdev, usb_rcvctrlpipe (cp->usbdev, 0),
                           (unsigned char*)bp->dr, bp->bufp, le16_to_cpu (bp->dr->wLength),
-		          (usb_complete_t)auerswald_ctrlread_complete,bp);
+		          auerswald_ctrlread_complete,bp);
 
 	/* submit the control msg as next paket */
 	ret = auerchain_submit_urb_list (&cp->controlchain, bp->urbp, 1);
         if (ret) {
         	dbg ("auerswald_ctrlread_complete: nonzero result of auerchain_submit_urb_list %d", ret);
         	bp->urbp->status = ret;
-        	auerswald_ctrlread_complete (bp->urbp);
+        	auerswald_ctrlread_complete (bp->urbp, NULL);
     	}
 }
 
 /* completion handler for receiving of control messages */
-static void auerswald_ctrlread_complete (struct urb * urb)
+static void auerswald_ctrlread_complete (struct urb * urb, struct pt_regs *regs)
 {
         unsigned int  serviceid;
         pauerswald_t  cp;
@@ -969,14 +969,14 @@
 		bp->dr->wLength      = cpu_to_le16 (32); /* >= 8 bytes */
 		usb_fill_control_urb (bp->urbp, cp->usbdev, usb_sndctrlpipe (cp->usbdev, 0),
   			(unsigned char*)bp->dr, bp->bufp, 32,
-	   		(usb_complete_t)auerswald_ctrlread_wretcomplete,bp);
+	   		auerswald_ctrlread_wretcomplete,bp);
 
 		/* submit the control msg as next paket */
        		ret = auerchain_submit_urb_list (&cp->controlchain, bp->urbp, 1);
        		if (ret) {
                		dbg ("auerswald_ctrlread_complete: nonzero result of auerchain_submit_urb_list %d", ret);
                		bp->urbp->status = ret;
-               		auerswald_ctrlread_wretcomplete (bp->urbp);
+               		auerswald_ctrlread_wretcomplete (bp->urbp, regs);
 		}
                 return;
         }
@@ -1005,7 +1005,7 @@
    messages from the USB device.
 */
 /* int completion handler. */
-static void auerswald_int_complete (struct urb * urb)
+static void auerswald_int_complete (struct urb * urb, struct pt_regs *regs)
 {
         unsigned long flags;
         unsigned  int channelid;
@@ -1097,14 +1097,14 @@
 	bp->dr->wLength      = cpu_to_le16 (bytecount);
 	usb_fill_control_urb (bp->urbp, cp->usbdev, usb_rcvctrlpipe (cp->usbdev, 0),
                           (unsigned char*)bp->dr, bp->bufp, bytecount,
-		          (usb_complete_t)auerswald_ctrlread_complete,bp);
+		          auerswald_ctrlread_complete,bp);
 
         /* submit the control msg */
         ret = auerchain_submit_urb (&cp->controlchain, bp->urbp);
         if (ret) {
                 dbg ("auerswald_int_complete: nonzero result of auerchain_submit_urb %d", ret);
                 bp->urbp->status = ret;
-                auerswald_ctrlread_complete( bp->urbp);
+                auerswald_ctrlread_complete( bp->urbp, NULL);
 		/* here applies the same problem as above: device locking! */
         }
 exit:
diff -Nru a/drivers/usb/misc/brlvger.c b/drivers/usb/misc/brlvger.c
--- a/drivers/usb/misc/brlvger.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/usb/misc/brlvger.c	Mon Dec  9 18:46:37 2002
@@ -118,7 +118,7 @@
 			 unsigned cmd, unsigned long arg);
 static unsigned brlvger_poll(struct file *file, poll_table *wait);
 static loff_t brlvger_llseek(struct file * file, loff_t offset, int orig);
-static void intr_callback(struct urb *urb);
+static void intr_callback(struct urb *urb, struct pt_regs *regs);
 struct brlvger_priv;
 static int brlvger_get_hw_version(struct brlvger_priv *priv,
 				  unsigned char *verbuf);
@@ -842,7 +842,7 @@
 }
 
 static void
-intr_callback(struct urb *urb)
+intr_callback(struct urb *urb, struct pt_regs *regs)
 {
 	struct brlvger_priv *priv = urb->context;
 	int intr_idx, read_idx;
diff -Nru a/drivers/usb/misc/speedtouch.c b/drivers/usb/misc/speedtouch.c
--- a/drivers/usb/misc/speedtouch.c	Mon Dec  9 18:46:52 2002
+++ b/drivers/usb/misc/speedtouch.c	Mon Dec  9 18:46:52 2002
@@ -570,7 +570,7 @@
 	struct atm_vcc *vcc;
 };
 
-static void udsl_usb_send_data_complete (struct urb *urb)
+static void udsl_usb_send_data_complete (struct urb *urb, struct pt_regs *regs)
 {
 	struct udsl_usb_send_data_context *ctx = (struct udsl_usb_send_data_context *) urb->context;
 	struct udsl_instance_data *instance = ctx->instance;
@@ -596,7 +596,7 @@
 		       instance->usb_dev,
 		       usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT),
 		       (unsigned char *) ctx->skb->data,
-		       ctx->skb->len, (usb_complete_t) udsl_usb_send_data_complete, ctx);
+		       ctx->skb->len, udsl_usb_send_data_complete, ctx);
 
 	err = usb_submit_urb (urb, GFP_KERNEL);
 
@@ -678,7 +678,7 @@
 		       usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT),
 		       (unsigned char *) skb->data,
 		       skb->len,
-		       (usb_complete_t) udsl_usb_send_data_complete, &(instance->send_ctx[i])
+		       udsl_usb_send_data_complete, &(instance->send_ctx[i])
 	    );
 
 	err = usb_submit_urb (urb, GFP_KERNEL);
@@ -691,7 +691,7 @@
 }
 
 /********* receive *******/
-void udsl_usb_data_receive (struct urb *urb)
+void udsl_usb_data_receive (struct urb *urb, struct pt_regs *regs)
 {
 	struct udsl_data_ctx *ctx;
 	struct udsl_instance_data *instance;
@@ -746,7 +746,7 @@
 		       instance->usb_dev,
 		       usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN),
 		       (unsigned char *) ctx->skb->data,
-		       UDSL_RECEIVE_BUFFER_SIZE, (usb_complete_t) udsl_usb_data_receive, ctx);
+		       UDSL_RECEIVE_BUFFER_SIZE, udsl_usb_data_receive, ctx);
 	usb_submit_urb (urb, GFP_KERNEL);
 	return;
 };
@@ -795,7 +795,7 @@
 			       usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN),
 			       (unsigned char *) ctx->skb->data,
 			       UDSL_RECEIVE_BUFFER_SIZE,
-			       (usb_complete_t) udsl_usb_data_receive, ctx);
+			       udsl_usb_data_receive, ctx);
 
 
 		ctx->instance = instance;
diff -Nru a/drivers/usb/misc/tiglusb.c b/drivers/usb/misc/tiglusb.c
--- a/drivers/usb/misc/tiglusb.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/usb/misc/tiglusb.c	Mon Dec  9 18:46:34 2002
@@ -15,16 +15,11 @@
  * 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
+ *   1.0x, Romain & Julien: initial submit.
+ *   1.03, Greg Kroah: modifications.
+ *   1.04, Julien: clean-up & fixes; Romain: 2.4 backport.
+ *   1.05, Randy Dunlap: bug fix with the timeout parameter (divide-by-zero).
+ *   1.06, Romain: synched with 2.5, version/firmware changed (confusing).
  */
 
 #include <linux/module.h>
@@ -44,7 +39,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "1.04"
+#define DRIVER_VERSION "1.06"
 #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"
@@ -54,8 +49,6 @@
 static tiglusb_t tiglusb[MAXTIGL];
 static int timeout = TIMAXTIME;	/* timeout in tenth of seconds     */
 
-static devfs_handle_t devfs_handle;
-
 /*---------- misc functions ------------------------------------------- */
 
 /*
@@ -334,7 +327,7 @@
 	int minor = -1;
 	int i;
 	ptiglusb_t s;
-	char name[8];
+	char name[32];
 
 	dbg ("probing vendor id 0x%x, device id 0x%x",
 	     dev->descriptor.idVendor, dev->descriptor.idProduct);
@@ -378,16 +371,15 @@
 	up (&s->mutex);
 	dbg ("bound to interface");
 
-	sprintf (name, "%d", s->minor);
+	sprintf (name, "ticables/usb/%d", s->minor);
 	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);
+	devfs_register(NULL, name, DEVFS_FL_DEFAULT, TIUSB_MAJOR,
+		       TIUSB_MINOR + s->minor, S_IFCHR | S_IRUGO | S_IWUGO,
+		       &tiglusb_fops, NULL);
 
 	/* Display firmware version */
-	info ("link cable version %i.%02x",
+	info ("firmware revision %i.%02x",
 		dev->descriptor.bcdDevice >> 8,
 		dev->descriptor.bcdDevice & 0xff);
 
@@ -398,6 +390,8 @@
 static void
 tiglusb_disconnect (struct usb_interface *intf)
 {
+	char name[32];
+
 	ptiglusb_t s = dev_get_drvdata (&intf->dev);
 
 	dev_set_drvdata (&intf->dev, NULL);
@@ -414,8 +408,7 @@
 	s->dev = NULL;
 	s->opened = 0;
 
-	devfs_unregister (s->devfs);
-	s->devfs = NULL;
+	devfs_remove (name, "ticables/usb/%d", s->minor);
 
 	info ("device %d removed", s->minor);
 
@@ -453,7 +446,7 @@
 	if (ints[0] > 0) {
 		timeout = ints[1];
 	}
-	if (!timeout)
+	if (timeout <= 0)
 		timeout = TIMAXTIME;
 
 	return 1;
@@ -485,7 +478,7 @@
 	}
 
 	/* Use devfs, tree: /dev/ticables/usb/[0..3] */
-	devfs_handle = devfs_mk_dir (NULL, "ticables/usb", NULL);
+	devfs_mk_dir (NULL, "ticables/usb", NULL);
 
 	/* register USB module */
 	result = usb_register (&tiglusb_driver);
@@ -494,9 +487,9 @@
 		return -1;
 	}
 
-	info (DRIVER_DESC ", " DRIVER_VERSION);
+	info (DRIVER_DESC ", version " DRIVER_VERSION);
 
-	if (!timeout)
+	if (timeout <= 0)
 		timeout = TIMAXTIME;
 
 	return 0;
@@ -506,7 +499,7 @@
 tiglusb_cleanup (void)
 {
 	usb_deregister (&tiglusb_driver);
-	devfs_unregister (devfs_handle);
+	devfs_remove("ticables/usb");
 	unregister_chrdev (TIUSB_MAJOR, "tiglusb");
 }
 
diff -Nru a/drivers/usb/misc/tiglusb.h b/drivers/usb/misc/tiglusb.h
--- a/drivers/usb/misc/tiglusb.h	Mon Dec  9 18:46:52 2002
+++ b/drivers/usb/misc/tiglusb.h	Mon Dec  9 18:46:52 2002
@@ -38,7 +38,6 @@
 	wait_queue_head_t	remove_ok;
 
 	int		minor;			/* which minor dev #? */
-	devfs_handle_t	devfs;			/* devfs device */
 
 	driver_state_t	state;			/* started/stopped */
 	int		opened;			/* tru if open */
diff -Nru a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
--- a/drivers/usb/misc/usbtest.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/usb/misc/usbtest.c	Mon Dec  9 18:46:51 2002
@@ -85,7 +85,7 @@
  * them with non-zero test data (or test for it) when appropriate.
  */
 
-static void simple_callback (struct urb *urb)
+static void simple_callback (struct urb *urb, struct pt_regs *regs)
 {
 	complete ((struct completion *) urb->context);
 }
@@ -550,7 +550,7 @@
 
 /*-------------------------------------------------------------------------*/
 
-static void unlink1_callback (struct urb *urb)
+static void unlink1_callback (struct urb *urb, struct pt_regs *regs)
 {
 	int	status = urb->status;
 
diff -Nru a/drivers/usb/net/catc.c b/drivers/usb/net/catc.c
--- a/drivers/usb/net/catc.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/usb/net/catc.c	Mon Dec  9 18:46:37 2002
@@ -221,7 +221,7 @@
  * Receive routines.
  */
 
-static void catc_rx_done(struct urb *urb)
+static void catc_rx_done(struct urb *urb, struct pt_regs *regs)
 {
 	struct catc *catc = urb->context;
 	u8 *pkt_start = urb->transfer_buffer;
@@ -287,7 +287,7 @@
 	}
 }
 
-static void catc_irq_done(struct urb *urb)
+static void catc_irq_done(struct urb *urb, struct pt_regs *regs)
 {
 	struct catc *catc = urb->context;
 	u8 *data = urb->transfer_buffer;
@@ -374,7 +374,7 @@
 	catc->netdev->trans_start = jiffies;
 }
 
-static void catc_tx_done(struct urb *urb)
+static void catc_tx_done(struct urb *urb, struct pt_regs *regs)
 {
 	struct catc *catc = urb->context;
 	unsigned long flags;
@@ -486,7 +486,7 @@
 		err("submit(ctrl_urb) status %d", status);
 }
 
-static void catc_ctrl_done(struct urb *urb)
+static void catc_ctrl_done(struct urb *urb, struct pt_regs *regs)
 {
 	struct catc *catc = urb->context;
 	struct ctrl_queue *q;
diff -Nru a/drivers/usb/net/cdc-ether.c b/drivers/usb/net/cdc-ether.c
--- a/drivers/usb/net/cdc-ether.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/usb/net/cdc-ether.c	Mon Dec  9 18:46:34 2002
@@ -52,7 +52,7 @@
 // Callback routines from USB device /////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
-static void read_bulk_callback( struct urb *urb )
+static void read_bulk_callback( struct urb *urb, struct pt_regs *regs )
 {
 	ether_dev_t *ether_dev = urb->context;
 	struct net_device *net;
@@ -140,7 +140,7 @@
 	ether_dev->flags &= ~CDC_ETHER_RX_BUSY;
 }
 
-static void write_bulk_callback( struct urb *urb )
+static void write_bulk_callback( struct urb *urb, struct pt_regs *regs )
 {
 	ether_dev_t *ether_dev = urb->context;
 
diff -Nru a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c
--- a/drivers/usb/net/kaweth.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/usb/net/kaweth.c	Mon Dec  9 18:46:50 2002
@@ -462,13 +462,13 @@
 	return result;
 }
 
-static void kaweth_usb_receive(struct urb *);
+static void kaweth_usb_receive(struct urb *, struct pt_regs *regs);
 static int kaweth_resubmit_rx_urb(struct kaweth_device *, int);
 
 /****************************************************************
 	int_callback
 *****************************************************************/
-static void int_callback(struct urb *u)
+static void int_callback(struct urb *u, struct pt_regs *regs)
 {
 	struct kaweth_device *kaweth = u->context;
 	int act_state, status;
@@ -538,7 +538,7 @@
 /****************************************************************
  *     kaweth_usb_receive
  ****************************************************************/
-static void kaweth_usb_receive(struct urb *urb)
+static void kaweth_usb_receive(struct urb *urb, struct pt_regs *regs)
 {
 	struct kaweth_device *kaweth = urb->context;
 	struct net_device *net = kaweth->net;
@@ -699,7 +699,7 @@
 /****************************************************************
  *     kaweth_usb_transmit_complete
  ****************************************************************/
-static void kaweth_usb_transmit_complete(struct urb *urb)
+static void kaweth_usb_transmit_complete(struct urb *urb, struct pt_regs *regs)
 {
 	struct kaweth_device *kaweth = urb->context;
 	struct sk_buff *skb = kaweth->tx_skb;
@@ -1135,7 +1135,7 @@
 /*-------------------------------------------------------------------*
  * completion handler for compatibility wrappers (sync control/bulk) *
  *-------------------------------------------------------------------*/
-static void usb_api_blocking_completion(struct urb *urb)
+static void usb_api_blocking_completion(struct urb *urb, struct pt_regs *regs)
 {
         struct usb_api_data *awd = (struct usb_api_data *)urb->context;
 
@@ -1208,7 +1208,7 @@
                 return -ENOMEM;
 
         usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char*)cmd, data,
-			 len, (usb_complete_t)usb_api_blocking_completion,0);
+			 len, usb_api_blocking_completion,0);
 
         retv = usb_start_wait_urb(urb, timeout, &length);
         if (retv < 0) {
diff -Nru a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c
--- a/drivers/usb/net/pegasus.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/usb/net/pegasus.c	Mon Dec  9 18:46:51 2002
@@ -87,7 +87,7 @@
 
 static int update_eth_regs_async(pegasus_t *);
 /* Aargh!!! I _really_ hate such tweaks */
-static void ctrl_callback(struct urb *urb)
+static void ctrl_callback(struct urb *urb, struct pt_regs *regs)
 {
 	pegasus_t *pegasus = urb->context;
 
@@ -524,7 +524,7 @@
 	return NULL;
 }
 
-static void read_bulk_callback(struct urb *urb)
+static void read_bulk_callback(struct urb *urb, struct pt_regs *regs)
 {
 	pegasus_t *pegasus = urb->context;
 	struct net_device *net;
@@ -644,7 +644,7 @@
 	}
 }
 
-static void write_bulk_callback(struct urb *urb)
+static void write_bulk_callback(struct urb *urb, struct pt_regs *regs)
 {
 	pegasus_t *pegasus = urb->context;
 
@@ -661,7 +661,7 @@
 	netif_wake_queue(pegasus->net);
 }
 
-static void intr_callback(struct urb *urb)
+static void intr_callback(struct urb *urb, struct pt_regs *regs)
 {
 	pegasus_t *pegasus = urb->context;
 	struct net_device *net;
@@ -1092,7 +1092,7 @@
 	}
 
 	pegasus->flags |= ETH_REGS_CHANGE;
-	ctrl_callback(pegasus->ctrl_urb);
+	ctrl_callback(pegasus->ctrl_urb, NULL);
 
 	netif_wake_queue(net);
 }
diff -Nru a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c
--- a/drivers/usb/net/rtl8150.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/usb/net/rtl8150.c	Mon Dec  9 18:46:38 2002
@@ -143,7 +143,7 @@
 			       indx, 0, data, size, HZ / 2);
 }
 
-static void ctrl_callback(struct urb *urb)
+static void ctrl_callback(struct urb *urb, struct pt_regs *regs)
 {
 	rtl8150_t *dev;
 
@@ -336,7 +336,7 @@
 	usb_unlink_urb(dev->ctrl_urb);
 }
 
-static void read_bulk_callback(struct urb *urb)
+static void read_bulk_callback(struct urb *urb, struct pt_regs *regs)
 {
 	rtl8150_t *dev;
 	unsigned pkt_len, res;
@@ -435,7 +435,7 @@
 	tasklet_schedule(&dev->tl);
 }
 
-static void write_bulk_callback(struct urb *urb)
+static void write_bulk_callback(struct urb *urb, struct pt_regs *regs)
 {
 	rtl8150_t *dev;
 
@@ -451,7 +451,7 @@
 	netif_wake_queue(dev->netdev);
 }
 
-void intr_callback(struct urb *urb)
+void intr_callback(struct urb *urb, struct pt_regs *regs)
 {
 	rtl8150_t *dev;
 	int status;
diff -Nru a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
--- a/drivers/usb/net/usbnet.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/usb/net/usbnet.c	Mon Dec  9 18:46:38 2002
@@ -445,7 +445,7 @@
 	return retval;
 }
 
-static void gl_interrupt_complete (struct urb *urb)
+static void gl_interrupt_complete (struct urb *urb, struct pt_regs *regs)
 {
 	int status = urb->status;
 	
@@ -1437,7 +1437,7 @@
 
 /*-------------------------------------------------------------------------*/
 
-static void rx_complete (struct urb *urb);
+static void rx_complete (struct urb *urb, struct pt_regs *regs);
 
 static void rx_submit (struct usbnet *dev, struct urb *urb, int flags)
 {
@@ -1549,7 +1549,7 @@
 
 /*-------------------------------------------------------------------------*/
 
-static void rx_complete (struct urb *urb)
+static void rx_complete (struct urb *urb, struct pt_regs *regs)
 {
 	struct sk_buff		*skb = (struct sk_buff *) urb->context;
 	struct skb_data		*entry = (struct skb_data *) skb->cb;
@@ -1874,7 +1874,7 @@
 
 /*-------------------------------------------------------------------------*/
 
-static void tx_complete (struct urb *urb)
+static void tx_complete (struct urb *urb, struct pt_regs *regs)
 {
 	struct sk_buff		*skb = (struct sk_buff *) urb->context;
 	struct skb_data		*entry = (struct skb_data *) skb->cb;
diff -Nru a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
--- a/drivers/usb/serial/Kconfig	Mon Dec  9 18:46:50 2002
+++ b/drivers/usb/serial/Kconfig	Mon Dec  9 18:46:50 2002
@@ -326,6 +326,25 @@
 	  The module will be called kl5kusb105.o. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
+config USB_SERIAL_KOBIL_SCT
+        tristate "USB KOBIL chipcard reader (EXPERIMENTAL)"
+        depends on USB_SERIAL && EXPERIMENTAL
+        ---help---
+          Say Y here if you want to use one of the following KOBIL USB chipcard
+          readers:
+
+            - USB TWIN
+            - KAAN Standard Plus
+            - SecOVID Reader Plus
+            - B1 Professional
+            - KAAN Professional
+
+          Note that you need a current CT-API.
+          This code is also available as a module ( = code which can be
+          inserted in and removed from the running kernel whenever you want).
+          The module will be called kobil_sct.o. If you want to compile it as
+          a module, say M here and read <file:Documentation/modules.txt>.
+
 config USB_SERIAL_MCT_U232
 	tristate "USB MCT Single Port Serial Driver"
 	depends on USB_SERIAL
diff -Nru a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
--- a/drivers/usb/serial/Makefile	Mon Dec  9 18:46:35 2002
+++ b/drivers/usb/serial/Makefile	Mon Dec  9 18:46:35 2002
@@ -24,6 +24,7 @@
 obj-$(CONFIG_USB_SERIAL_EDGEPORT)		+= io_edgeport.o
 obj-$(CONFIG_USB_SERIAL_EDGEPORT_TI)		+= io_ti.o
 obj-$(CONFIG_USB_SERIAL_PL2303)			+= pl2303.o
+obj-$(CONFIG_USB_SERIAL_KOBIL_SCT)		+= kobil_sct.o
 obj-$(CONFIG_USB_SERIAL_CYBERJACK)		+= cyberjack.o
 obj-$(CONFIG_USB_SERIAL_IR)			+= ir-usb.o
 obj-$(CONFIG_USB_SERIAL_KLSI)			+= kl5kusb105.o
diff -Nru a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
--- a/drivers/usb/serial/belkin_sa.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/usb/serial/belkin_sa.c	Mon Dec  9 18:46:38 2002
@@ -97,7 +97,7 @@
 static void belkin_sa_shutdown		(struct usb_serial *serial);
 static int  belkin_sa_open		(struct usb_serial_port *port, struct file *filp);
 static void belkin_sa_close		(struct usb_serial_port *port, struct file *filp);
-static void belkin_sa_read_int_callback (struct urb *urb);
+static void belkin_sa_read_int_callback (struct urb *urb, struct pt_regs *regs);
 static void belkin_sa_set_termios	(struct usb_serial_port *port, struct termios * old);
 static int  belkin_sa_ioctl		(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
 static void belkin_sa_break_ctl		(struct usb_serial_port *port, int break_state );
@@ -252,7 +252,7 @@
 } /* belkin_sa_close */
 
 
-static void belkin_sa_read_int_callback (struct urb *urb)
+static void belkin_sa_read_int_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 	struct belkin_sa_private *priv;
diff -Nru a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
--- a/drivers/usb/serial/cyberjack.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/usb/serial/cyberjack.c	Mon Dec  9 18:46:51 2002
@@ -62,9 +62,9 @@
 static void cyberjack_close (struct usb_serial_port *port, struct file *filp);
 static int cyberjack_write (struct usb_serial_port *port, int from_user,
 	const unsigned char *buf, int count);
-static void cyberjack_read_int_callback( struct urb *urb );
-static void cyberjack_read_bulk_callback (struct urb *urb);
-static void cyberjack_write_bulk_callback (struct urb *urb);
+static void cyberjack_read_int_callback (struct urb *urb, struct pt_regs *regs);
+static void cyberjack_read_bulk_callback (struct urb *urb, struct pt_regs *regs);
+static void cyberjack_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
 
 static struct usb_device_id id_table [] = {
 	{ USB_DEVICE(CYBERJACK_VENDOR_ID, CYBERJACK_PRODUCT_ID) },
@@ -276,7 +276,7 @@
 	return (count);
 } 
 
-static void cyberjack_read_int_callback( struct urb *urb )
+static void cyberjack_read_int_callback( struct urb *urb, struct pt_regs *regs )
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 	struct cyberjack_private *priv = (struct cyberjack_private *)port->private;
@@ -330,7 +330,7 @@
 	}
 }
 
-static void cyberjack_read_bulk_callback (struct urb *urb)
+static void cyberjack_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 	struct cyberjack_private *priv = (struct cyberjack_private *)port->private;
@@ -385,7 +385,7 @@
 	}
 }
 
-static void cyberjack_write_bulk_callback (struct urb *urb)
+static void cyberjack_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 	struct cyberjack_private *priv = (struct cyberjack_private *)port->private;
diff -Nru a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
--- a/drivers/usb/serial/digi_acceleport.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/usb/serial/digi_acceleport.c	Mon Dec  9 18:46:37 2002
@@ -462,7 +462,7 @@
 	unsigned int cmd, unsigned long arg );
 static int digi_write( struct usb_serial_port *port, int from_user,
 	const unsigned char *buf, int count );
-static void digi_write_bulk_callback( struct urb *urb );
+static void digi_write_bulk_callback( struct urb *urb, struct pt_regs *regs );
 static int digi_write_room( struct usb_serial_port *port );
 static int digi_chars_in_buffer( struct usb_serial_port *port );
 static int digi_open( struct usb_serial_port *port, struct file *filp );
@@ -470,7 +470,7 @@
 static int digi_startup_device( struct usb_serial *serial );
 static int digi_startup( struct usb_serial *serial );
 static void digi_shutdown( struct usb_serial *serial );
-static void digi_read_bulk_callback( struct urb *urb );
+static void digi_read_bulk_callback( struct urb *urb, struct pt_regs *regs );
 static int digi_read_inb_callback( struct urb *urb );
 static int digi_read_oob_callback( struct urb *urb );
 
@@ -1347,7 +1347,7 @@
 } 
 
 
-static void digi_write_bulk_callback( struct urb *urb )
+static void digi_write_bulk_callback( struct urb *urb, struct pt_regs *regs )
 {
 
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
@@ -1766,7 +1766,7 @@
 }
 
 
-static void digi_read_bulk_callback( struct urb *urb )
+static void digi_read_bulk_callback( struct urb *urb, struct pt_regs *regs )
 {
 
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
diff -Nru a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
--- a/drivers/usb/serial/empeg.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/usb/serial/empeg.c	Mon Dec  9 18:46:51 2002
@@ -100,8 +100,8 @@
 					unsigned int cmd,
 					unsigned long arg);
 static void empeg_set_termios		(struct usb_serial_port *port, struct termios *old_termios);
-static void empeg_write_bulk_callback	(struct urb *urb);
-static void empeg_read_bulk_callback	(struct urb *urb);
+static void empeg_write_bulk_callback	(struct urb *urb, struct pt_regs *regs);
+static void empeg_read_bulk_callback	(struct urb *urb, struct pt_regs *regs);
 
 static struct usb_device_id id_table [] = {
 	{ USB_DEVICE(EMPEG_VENDOR_ID, EMPEG_PRODUCT_ID) },
@@ -348,7 +348,7 @@
 }
 
 
-static void empeg_write_bulk_callback (struct urb *urb)
+static void empeg_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 
@@ -366,7 +366,7 @@
 }
 
 
-static void empeg_read_bulk_callback (struct urb *urb)
+static void empeg_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
diff -Nru a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
--- a/drivers/usb/serial/ftdi_sio.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/usb/serial/ftdi_sio.c	Mon Dec  9 18:46:50 2002
@@ -170,8 +170,8 @@
 static void ftdi_sio_close		(struct usb_serial_port *port, struct file *filp);
 static int  ftdi_sio_write		(struct usb_serial_port *port, int from_user, const unsigned char *buf, int count);
 static int  ftdi_sio_write_room		(struct usb_serial_port *port);
-static void ftdi_sio_write_bulk_callback (struct urb *urb);
-static void ftdi_sio_read_bulk_callback	(struct urb *urb);
+static void ftdi_sio_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
+static void ftdi_sio_read_bulk_callback	(struct urb *urb, struct pt_regs *regs);
 static void ftdi_sio_set_termios	(struct usb_serial_port *port, struct termios * old);
 static int  ftdi_sio_ioctl		(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
 static void ftdi_sio_break_ctl		(struct usb_serial_port *port, int break_state );
@@ -464,7 +464,7 @@
 	return (count - data_offset);
 } /* ftdi_sio_write */
 
-static void ftdi_sio_write_bulk_callback (struct urb *urb)
+static void ftdi_sio_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 	struct usb_serial *serial;
@@ -504,7 +504,7 @@
 } /* ftdi_sio_write_room */
 
 
-static void ftdi_sio_read_bulk_callback (struct urb *urb)
+static void ftdi_sio_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
 { /* ftdi_sio_serial_buld_callback */
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 	struct usb_serial *serial;
diff -Nru a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
--- a/drivers/usb/serial/generic.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/usb/serial/generic.c	Mon Dec  9 18:46:34 2002
@@ -218,7 +218,7 @@
 	return (chars);
 }
 
-void usb_serial_generic_read_bulk_callback (struct urb *urb)
+void usb_serial_generic_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
@@ -268,7 +268,7 @@
 		err("%s - failed resubmitting read urb, error %d", __FUNCTION__, result);
 }
 
-void usb_serial_generic_write_bulk_callback (struct urb *urb)
+void usb_serial_generic_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
diff -Nru a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
--- a/drivers/usb/serial/io_edgeport.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/usb/serial/io_edgeport.c	Mon Dec  9 18:46:34 2002
@@ -435,10 +435,10 @@
 /* local function prototypes */
 
 /* function prototypes for all URB callbacks */
-static void edge_interrupt_callback	(struct urb *urb);
-static void edge_bulk_in_callback	(struct urb *urb);
-static void edge_bulk_out_data_callback	(struct urb *urb);
-static void edge_bulk_out_cmd_callback	(struct urb *urb);
+static void edge_interrupt_callback	(struct urb *urb, struct pt_regs *regs);
+static void edge_bulk_in_callback	(struct urb *urb, struct pt_regs *regs);
+static void edge_bulk_out_data_callback	(struct urb *urb, struct pt_regs *regs);
+static void edge_bulk_out_cmd_callback	(struct urb *urb, struct pt_regs *regs);
 
 /* function prototypes for the usbserial callbacks */
 static int  edge_open			(struct usb_serial_port *port, struct file *filp);
@@ -753,7 +753,7 @@
  *	this is the callback function for when we have received data on the 
  *	interrupt endpoint.
  *****************************************************************************/
-static void edge_interrupt_callback (struct urb *urb)
+static void edge_interrupt_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct edgeport_serial	*edge_serial = (struct edgeport_serial *)urb->context;
 	struct edgeport_port *edge_port;
@@ -850,7 +850,7 @@
  *	this is the callback function for when we have received data on the 
  *	bulk in endpoint.
  *****************************************************************************/
-static void edge_bulk_in_callback (struct urb *urb)
+static void edge_bulk_in_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct edgeport_serial	*edge_serial = (struct edgeport_serial *)urb->context;
 	unsigned char		*data = urb->transfer_buffer;
@@ -901,7 +901,7 @@
  *	this is the callback function for when we have finished sending serial data
  *	on the bulk out endpoint.
  *****************************************************************************/
-static void edge_bulk_out_data_callback (struct urb *urb)
+static void edge_bulk_out_data_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct edgeport_port *edge_port = (struct edgeport_port *)urb->context;
 	struct tty_struct *tty;
@@ -941,7 +941,7 @@
  *	this is the callback function for when we have finished sending a command
  *	on the bulk out endpoint.
  *****************************************************************************/
-static void edge_bulk_out_cmd_callback (struct urb *urb)
+static void edge_bulk_out_cmd_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct edgeport_port *edge_port = (struct edgeport_port *)urb->context;
 	struct tty_struct *tty;
diff -Nru a/drivers/usb/serial/io_tables.h b/drivers/usb/serial/io_tables.h
--- a/drivers/usb/serial/io_tables.h	Mon Dec  9 18:46:49 2002
+++ b/drivers/usb/serial/io_tables.h	Mon Dec  9 18:46:49 2002
@@ -98,91 +98,91 @@
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_serial_device_type edgeport_1port_device = {
-	owner:			THIS_MODULE,
-	name:			"Edgeport 1 port adapter",
-	id_table:		edgeport_1port_id_table,
-	num_interrupt_in:	1,
-	num_bulk_in:		1,
-	num_bulk_out:		1,
-	num_ports:		1,
-	open:			edge_open,
-	close:			edge_close,
-	throttle:		edge_throttle,
-	unthrottle:		edge_unthrottle,
-	attach:			edge_startup,
-	shutdown:		edge_shutdown,
-	ioctl:			edge_ioctl,
-	set_termios:		edge_set_termios,
-	write:			edge_write,
-	write_room:		edge_write_room,
-	chars_in_buffer:	edge_chars_in_buffer,
-	break_ctl:		edge_break,
+	.owner			= THIS_MODULE,
+	.name			= "Edgeport 1 port adapter",
+	.id_table		= edgeport_1port_id_table,
+	.num_interrupt_in	= 1,
+	.num_bulk_in		= 1,
+	.num_bulk_out		= 1,
+	.num_ports		= 1,
+	.open			= edge_open,
+	.close			= edge_close,
+	.throttle		= edge_throttle,
+	.unthrottle		= edge_unthrottle,
+	.attach			= edge_startup,
+	.shutdown		= edge_shutdown,
+	.ioctl			= edge_ioctl,
+	.set_termios		= edge_set_termios,
+	.write			= edge_write,
+	.write_room		= edge_write_room,
+	.chars_in_buffer	= edge_chars_in_buffer,
+	.break_ctl		= edge_break,
 };
 
 static struct usb_serial_device_type edgeport_2port_device = {
-	owner:			THIS_MODULE,
-	name:			"Edgeport 2 port adapter",
-	id_table:		edgeport_2port_id_table,
-	num_interrupt_in:	1,
-	num_bulk_in:		1,
-	num_bulk_out:		1,
-	num_ports:		2,
-	open:			edge_open,
-	close:			edge_close,
-	throttle:		edge_throttle,
-	unthrottle:		edge_unthrottle,
-	attach:			edge_startup,
-	shutdown:		edge_shutdown,
-	ioctl:			edge_ioctl,
-	set_termios:		edge_set_termios,
-	write:			edge_write,
-	write_room:		edge_write_room,
-	chars_in_buffer:	edge_chars_in_buffer,
-	break_ctl:		edge_break,
+	.owner			= THIS_MODULE,
+	.name			= "Edgeport 2 port adapter",
+	.id_table		= edgeport_2port_id_table,
+	.num_interrupt_in	= 1,
+	.num_bulk_in		= 1,
+	.num_bulk_out		= 1,
+	.num_ports		= 2,
+	.open			= edge_open,
+	.close			= edge_close,
+	.throttle		= edge_throttle,
+	.unthrottle		= edge_unthrottle,
+	.attach			= edge_startup,
+	.shutdown		= edge_shutdown,
+	.ioctl			= edge_ioctl,
+	.set_termios		= edge_set_termios,
+	.write			= edge_write,
+	.write_room		= edge_write_room,
+	.chars_in_buffer	= edge_chars_in_buffer,
+	.break_ctl		= edge_break,
 };
 
 static struct usb_serial_device_type edgeport_4port_device = {
-	owner:			THIS_MODULE,
-	name:			"Edgeport 4 port adapter",
-	id_table:		edgeport_4port_id_table,
-	num_interrupt_in:	1,
-	num_bulk_in:		1,
-	num_bulk_out:		1,
-	num_ports:		4,
-	open:			edge_open,
-	close:			edge_close,
-	throttle:		edge_throttle,
-	unthrottle:		edge_unthrottle,
-	attach:			edge_startup,
-	shutdown:		edge_shutdown,
-	ioctl:			edge_ioctl,
-	set_termios:		edge_set_termios,
-	write:			edge_write,
-	write_room:		edge_write_room,
-	chars_in_buffer:	edge_chars_in_buffer,
-	break_ctl:		edge_break,
+	.owner			= THIS_MODULE,
+	.name			= "Edgeport 4 port adapter",
+	.id_table		= edgeport_4port_id_table,
+	.num_interrupt_in	= 1,
+	.num_bulk_in		= 1,
+	.num_bulk_out		= 1,
+	.num_ports		= 4,
+	.open			= edge_open,
+	.close			= edge_close,
+	.throttle		= edge_throttle,
+	.unthrottle		= edge_unthrottle,
+	.attach			= edge_startup,
+	.shutdown		= edge_shutdown,
+	.ioctl			= edge_ioctl,
+	.set_termios		= edge_set_termios,
+	.write			= edge_write,
+	.write_room		= edge_write_room,
+	.chars_in_buffer	= edge_chars_in_buffer,
+	.break_ctl		= edge_break,
 };
 
 static struct usb_serial_device_type edgeport_8port_device = {
-	owner:			THIS_MODULE,
-	name:			"Edgeport 8 port adapter",
-	id_table:		edgeport_8port_id_table,
-	num_interrupt_in:	1,
-	num_bulk_in:		1,
-	num_bulk_out:		1,
-	num_ports:		8,
-	open:			edge_open,
-	close:			edge_close,
-	throttle:		edge_throttle,
-	unthrottle:		edge_unthrottle,
-	attach:			edge_startup,
-	shutdown:		edge_shutdown,
-	ioctl:			edge_ioctl,
-	set_termios:		edge_set_termios,
-	write:			edge_write,
-	write_room:		edge_write_room,
-	chars_in_buffer:	edge_chars_in_buffer,
-	break_ctl:		edge_break,
+	.owner			= THIS_MODULE,
+	.name			= "Edgeport 8 port adapter",
+	.id_table		= edgeport_8port_id_table,
+	.num_interrupt_in	= 1,
+	.num_bulk_in		= 1,
+	.num_bulk_out		= 1,
+	.num_ports		= 8,
+	.open			= edge_open,
+	.close			= edge_close,
+	.throttle		= edge_throttle,
+	.unthrottle		= edge_unthrottle,
+	.attach			= edge_startup,
+	.shutdown		= edge_shutdown,
+	.ioctl			= edge_ioctl,
+	.set_termios		= edge_set_termios,
+	.write			= edge_write,
+	.write_room		= edge_write_room,
+	.chars_in_buffer	= edge_chars_in_buffer,
+	.break_ctl		= edge_break,
 };
 
 #endif
diff -Nru a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
--- a/drivers/usb/serial/io_ti.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/usb/serial/io_ti.c	Mon Dec  9 18:46:51 2002
@@ -1614,7 +1614,7 @@
 }
 
 
-static void edge_interrupt_callback (struct urb *urb)
+static void edge_interrupt_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct edgeport_serial	*edge_serial = (struct edgeport_serial *)urb->context;
 	struct usb_serial_port *port;
@@ -1713,7 +1713,7 @@
 		     __FUNCTION__, status);
 }
 
-static void edge_bulk_in_callback (struct urb *urb)
+static void edge_bulk_in_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct edgeport_port *edge_port = (struct edgeport_port *)urb->context;
 	unsigned char *data = urb->transfer_buffer;
@@ -1781,7 +1781,7 @@
 		     __FUNCTION__, status);
 }
 
-static void edge_bulk_out_callback (struct urb *urb)
+static void edge_bulk_out_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
diff -Nru a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
--- a/drivers/usb/serial/ipaq.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/usb/serial/ipaq.c	Mon Dec  9 18:46:50 2002
@@ -84,8 +84,8 @@
 static int ipaq_write_bulk(struct usb_serial_port *port, int from_user, const unsigned char *buf,
 			   int count);
 static void ipaq_write_gather(struct usb_serial_port *port);
-static void ipaq_read_bulk_callback (struct urb *urb);
-static void ipaq_write_bulk_callback(struct urb *urb);
+static void ipaq_read_bulk_callback (struct urb *urb, struct pt_regs *regs);
+static void ipaq_write_bulk_callback(struct urb *urb, struct pt_regs *regs);
 static int ipaq_write_room(struct usb_serial_port *port);
 static int ipaq_chars_in_buffer(struct usb_serial_port *port);
 static void ipaq_destroy_lists(struct usb_serial_port *port);
@@ -277,7 +277,7 @@
 	/* info ("Bytes In = %d  Bytes Out = %d", bytes_in, bytes_out); */
 }
 
-static void ipaq_read_bulk_callback(struct urb *urb)
+static void ipaq_read_bulk_callback(struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port	*port = (struct usb_serial_port *)urb->context;
 	struct usb_serial	*serial = get_usb_serial (port, __FUNCTION__);
@@ -445,7 +445,7 @@
 	return;
 }
 
-static void ipaq_write_bulk_callback(struct urb *urb)
+static void ipaq_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port	*port = (struct usb_serial_port *)urb->context;
 	struct ipaq_private	*priv = (struct ipaq_private *)port->private;
diff -Nru a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
--- a/drivers/usb/serial/ir-usb.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/usb/serial/ir-usb.c	Mon Dec  9 18:46:37 2002
@@ -111,8 +111,8 @@
 static int  ir_open (struct usb_serial_port *port, struct file *filep);
 static void ir_close (struct usb_serial_port *port, struct file *filep);
 static int  ir_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count);
-static void ir_write_bulk_callback (struct urb *urb);
-static void ir_read_bulk_callback (struct urb *urb);
+static void ir_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
+static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs);
 static void ir_set_termios (struct usb_serial_port *port, struct termios *old_termios);
 
 static u8 ir_baud = 0;
@@ -406,7 +406,7 @@
 	return result;
 }
 
-static void ir_write_bulk_callback (struct urb *urb)
+static void ir_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 
@@ -429,7 +429,7 @@
 	schedule_work(&port->work);
 }
 
-static void ir_read_bulk_callback (struct urb *urb)
+static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
diff -Nru a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
--- a/drivers/usb/serial/keyspan.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/usb/serial/keyspan.c	Mon Dec  9 18:46:34 2002
@@ -383,7 +383,7 @@
 	return count - left;
 }
 
-static void	usa26_indat_callback(struct urb *urb)
+static void	usa26_indat_callback(struct urb *urb, struct pt_regs *regs)
 {
 	int			i, err;
 	int			endpoint;
@@ -438,7 +438,7 @@
 }
 
 	/* Outdat handling is common for usa26, usa28 and usa49 messages */
-static void	usa2x_outdat_callback(struct urb *urb)
+static void	usa2x_outdat_callback(struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port;
 	struct keyspan_port_private *p_priv;
@@ -451,13 +451,13 @@
 		schedule_work(&port->work);
 }
 
-static void	usa26_inack_callback(struct urb *urb)
+static void	usa26_inack_callback(struct urb *urb, struct pt_regs *regs)
 {
 	dbg ("%s", __FUNCTION__); 
 	
 }
 
-static void	usa26_outcont_callback(struct urb *urb)
+static void	usa26_outcont_callback(struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port;
 	struct keyspan_port_private *p_priv;
@@ -471,7 +471,7 @@
 	}
 }
 
-static void	usa26_instat_callback(struct urb *urb)
+static void	usa26_instat_callback(struct urb *urb, struct pt_regs *regs)
 {
 	unsigned char 				*data = urb->transfer_buffer;
 	struct keyspan_usa26_portStatusMessage	*msg;
@@ -533,14 +533,14 @@
 exit: ;
 }
 
-static void	usa26_glocont_callback(struct urb *urb)
+static void	usa26_glocont_callback(struct urb *urb, struct pt_regs *regs)
 {
 	dbg ("%s", __FUNCTION__);
 	
 }
 
 
-static void     usa28_indat_callback(struct urb *urb)
+static void     usa28_indat_callback(struct urb *urb, struct pt_regs *regs)
 {
 	int                     i, err;
 	struct usb_serial_port  *port;
@@ -588,12 +588,12 @@
 	} while (urb->status != -EINPROGRESS);
 }
 
-static void	usa28_inack_callback(struct urb *urb)
+static void	usa28_inack_callback(struct urb *urb, struct pt_regs *regs)
 {
 	dbg ("%s", __FUNCTION__);
 }
 
-static void	usa28_outcont_callback(struct urb *urb)
+static void	usa28_outcont_callback(struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port;
 	struct keyspan_port_private *p_priv;
@@ -607,7 +607,7 @@
 	}
 }
 
-static void	usa28_instat_callback(struct urb *urb)
+static void	usa28_instat_callback(struct urb *urb, struct pt_regs *regs)
 {
 	int					err;
 	unsigned char 				*data = urb->transfer_buffer;
@@ -668,13 +668,13 @@
 exit: ;
 }
 
-static void	usa28_glocont_callback(struct urb *urb)
+static void	usa28_glocont_callback(struct urb *urb, struct pt_regs *regs)
 {
 	dbg ("%s", __FUNCTION__);
 }
 
 
-static void	usa49_glocont_callback(struct urb *urb)
+static void	usa49_glocont_callback(struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial *serial;
 	struct usb_serial_port *port;
@@ -698,7 +698,7 @@
 
 	/* This is actually called glostat in the Keyspan
 	   doco */
-static void	usa49_instat_callback(struct urb *urb)
+static void	usa49_instat_callback(struct urb *urb, struct pt_regs *regs)
 {
 	int					err;
 	unsigned char 				*data = urb->transfer_buffer;
@@ -761,12 +761,12 @@
 exit:	;
 }
 
-static void	usa49_inack_callback(struct urb *urb)
+static void	usa49_inack_callback(struct urb *urb, struct pt_regs *regs)
 {
 	dbg ("%s", __FUNCTION__);
 }
 
-static void	usa49_indat_callback(struct urb *urb)
+static void	usa49_indat_callback(struct urb *urb, struct pt_regs *regs)
 {
 	int			i, err;
 	int			endpoint;
@@ -819,7 +819,7 @@
 }
 
 /* not used, usa-49 doesn't have per-port control endpoints */
-static void	usa49_outcont_callback(struct urb *urb)
+static void	usa49_outcont_callback(struct urb *urb, struct pt_regs *regs)
 {
 	dbg ("%s", __FUNCTION__);
 }
@@ -1070,7 +1070,7 @@
 /* Helper functions used by keyspan_setup_urbs */
 static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint,
 				      int dir, void *ctx, char *buf, int len,
-				      void (*callback)(struct urb *))
+				      void (*callback)(struct urb *, struct pt_regs *regs))
 {
 	struct urb *urb;
 
@@ -1093,12 +1093,12 @@
 }
 
 static struct callbacks {
-	void	(*instat_callback)(struct urb *);
-	void	(*glocont_callback)(struct urb *);
-	void	(*indat_callback)(struct urb *);
-	void	(*outdat_callback)(struct urb *);
-	void	(*inack_callback)(struct urb *);
-	void	(*outcont_callback)(struct urb *);
+	void	(*instat_callback)(struct urb *, struct pt_regs *regs);
+	void	(*glocont_callback)(struct urb *, struct pt_regs *regs);
+	void	(*indat_callback)(struct urb *, struct pt_regs *regs);
+	void	(*outdat_callback)(struct urb *, struct pt_regs *regs);
+	void	(*inack_callback)(struct urb *, struct pt_regs *regs);
+	void	(*outcont_callback)(struct urb *, struct pt_regs *regs);
 } keyspan_callbacks[] = {
 	{
 		/* msg_usa26 callbacks */
diff -Nru a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h
--- a/drivers/usb/serial/keyspan.h	Mon Dec  9 18:46:50 2002
+++ b/drivers/usb/serial/keyspan.h	Mon Dec  9 18:46:50 2002
@@ -249,149 +249,149 @@
    in Keyspan's documentation) */
 
 static const struct keyspan_device_details usa18x_device_details = {
-	product_id:		keyspan_usa18x_product_id,
-	msg_format:		msg_usa26,
-	num_ports:		1,
-	indat_endp_flip:	0,
-	outdat_endp_flip:	1,
-	indat_endpoints:	{0x81},
-	outdat_endpoints:	{0x01},
-	inack_endpoints:	{0x85},
-	outcont_endpoints:	{0x05},
-	instat_endpoint:	0x87,
-	glocont_endpoint:	0x07,
-	calculate_baud_rate:	keyspan_usa19w_calc_baud,
-	baudclk:		KEYSPAN_USA18X_BAUDCLK,
+	.product_id		= keyspan_usa18x_product_id,
+	.msg_format		= msg_usa26,
+	.num_ports		= 1,
+	.indat_endp_flip	= 0,
+	.outdat_endp_flip	= 1,
+	.indat_endpoints	= {0x81},
+	.outdat_endpoints	= {0x01},
+	.inack_endpoints	= {0x85},
+	.outcont_endpoints	= {0x05},
+	.instat_endpoint	= 0x87,
+	.glocont_endpoint	= 0x07,
+	.calculate_baud_rate	= keyspan_usa19w_calc_baud,
+	.baudclk		= KEYSPAN_USA18X_BAUDCLK,
 };
 
 static const struct keyspan_device_details usa19_device_details = {
-	product_id:		keyspan_usa19_product_id,
-	msg_format:		msg_usa28,
-	num_ports:		1,
-	indat_endp_flip:	1,
-	outdat_endp_flip:	1,
-	indat_endpoints:	{0x81},
-	outdat_endpoints:	{0x01},
-	inack_endpoints:	{0x83},
-	outcont_endpoints:	{0x03},
-	instat_endpoint:	0x84,
-	glocont_endpoint:	-1,
-	calculate_baud_rate:	keyspan_usa19_calc_baud,
-	baudclk:		KEYSPAN_USA19_BAUDCLK,
+	.product_id		= keyspan_usa19_product_id,
+	.msg_format		= msg_usa28,
+	.num_ports		= 1,
+	.indat_endp_flip	= 1,
+	.outdat_endp_flip	= 1,
+	.indat_endpoints	= {0x81},
+	.outdat_endpoints	= {0x01},
+	.inack_endpoints	= {0x83},
+	.outcont_endpoints	= {0x03},
+	.instat_endpoint	= 0x84,
+	.glocont_endpoint	= -1,
+	.calculate_baud_rate	= keyspan_usa19_calc_baud,
+	.baudclk		= KEYSPAN_USA19_BAUDCLK,
 };
 
 static const struct keyspan_device_details usa19qi_device_details = {
-	product_id:		keyspan_usa19qi_product_id,
-	msg_format:		msg_usa28,
-	num_ports:		1,
-	indat_endp_flip:	1,
-	outdat_endp_flip:	1,
-	indat_endpoints:	{0x81},
-	outdat_endpoints:	{0x01},
-	inack_endpoints:	{0x83},
-	outcont_endpoints:	{0x03},
-	instat_endpoint:	0x84,
-	glocont_endpoint:	-1,
-	calculate_baud_rate:	keyspan_usa28_calc_baud,
-	baudclk:		KEYSPAN_USA19_BAUDCLK,
+	.product_id		= keyspan_usa19qi_product_id,
+	.msg_format		= msg_usa28,
+	.num_ports		= 1,
+	.indat_endp_flip	= 1,
+	.outdat_endp_flip	= 1,
+	.indat_endpoints	= {0x81},
+	.outdat_endpoints	= {0x01},
+	.inack_endpoints	= {0x83},
+	.outcont_endpoints	= {0x03},
+	.instat_endpoint	= 0x84,
+	.glocont_endpoint	= -1,
+	.calculate_baud_rate	= keyspan_usa28_calc_baud,
+	.baudclk		= KEYSPAN_USA19_BAUDCLK,
 };
 
 static const struct keyspan_device_details usa19qw_device_details = {
-	product_id:		keyspan_usa19qw_product_id,
-	msg_format:		msg_usa26,
-	num_ports:		1,
-	indat_endp_flip:	0,
-	outdat_endp_flip:	1,
-	indat_endpoints:	{0x81},
-	outdat_endpoints:	{0x01},
-	inack_endpoints:	{0x85},
-	outcont_endpoints:	{0x05},
-	instat_endpoint:	0x87,
-	glocont_endpoint:	0x07,
-	calculate_baud_rate:	keyspan_usa19w_calc_baud,
-	baudclk:		KEYSPAN_USA19W_BAUDCLK,
+	.product_id		= keyspan_usa19qw_product_id,
+	.msg_format		= msg_usa26,
+	.num_ports		= 1,
+	.indat_endp_flip	= 0,
+	.outdat_endp_flip	= 1,
+	.indat_endpoints	= {0x81},
+	.outdat_endpoints	= {0x01},
+	.inack_endpoints	= {0x85},
+	.outcont_endpoints	= {0x05},
+	.instat_endpoint	= 0x87,
+	.glocont_endpoint	= 0x07,
+	.calculate_baud_rate	= keyspan_usa19w_calc_baud,
+	.baudclk		= KEYSPAN_USA19W_BAUDCLK,
 };
 
 static const struct keyspan_device_details usa19w_device_details = {
-	product_id:		keyspan_usa19w_product_id,
-	msg_format:		msg_usa26,
-	num_ports:		1,
-	indat_endp_flip:	0,
-	outdat_endp_flip:	1,
-	indat_endpoints:	{0x81},
-	outdat_endpoints:	{0x01},
-	inack_endpoints:	{0x85},
-	outcont_endpoints:	{0x05},
-	instat_endpoint:	0x87,
-	glocont_endpoint:	0x07,
-	calculate_baud_rate:	keyspan_usa19w_calc_baud,
-	baudclk:		KEYSPAN_USA19W_BAUDCLK,
+	.product_id		= keyspan_usa19w_product_id,
+	.msg_format		= msg_usa26,
+	.num_ports		= 1,
+	.indat_endp_flip	= 0,
+	.outdat_endp_flip	= 1,
+	.indat_endpoints	= {0x81},
+	.outdat_endpoints	= {0x01},
+	.inack_endpoints	= {0x85},
+	.outcont_endpoints	= {0x05},
+	.instat_endpoint	= 0x87,
+	.glocont_endpoint	= 0x07,
+	.calculate_baud_rate	= keyspan_usa19w_calc_baud,
+	.baudclk		= KEYSPAN_USA19W_BAUDCLK,
 };
 
 static const struct keyspan_device_details usa28_device_details = {
-	product_id:		keyspan_usa28_product_id,
-	msg_format:		msg_usa28,
-	num_ports:		2,
-	indat_endp_flip:	1,
-	outdat_endp_flip:	1,
-	indat_endpoints:	{0x81, 0x83},
-	outdat_endpoints:	{0x01, 0x03},
-	inack_endpoints:	{0x85, 0x86},
-	outcont_endpoints:	{0x05, 0x06},
-	instat_endpoint:	0x87,
-	glocont_endpoint:	0x07,
-	calculate_baud_rate:	keyspan_usa28_calc_baud,
-	baudclk:		KEYSPAN_USA28_BAUDCLK,		
+	.product_id		= keyspan_usa28_product_id,
+	.msg_format		= msg_usa28,
+	.num_ports		= 2,
+	.indat_endp_flip	= 1,
+	.outdat_endp_flip	= 1,
+	.indat_endpoints	= {0x81, 0x83},
+	.outdat_endpoints	= {0x01, 0x03},
+	.inack_endpoints	= {0x85, 0x86},
+	.outcont_endpoints	= {0x05, 0x06},
+	.instat_endpoint	= 0x87,
+	.glocont_endpoint	= 0x07,
+	.calculate_baud_rate	= keyspan_usa28_calc_baud,
+	.baudclk		= KEYSPAN_USA28_BAUDCLK,		
 };
 
 static const struct keyspan_device_details usa28x_device_details = {
-	product_id:		keyspan_usa28x_product_id,
-	msg_format:		msg_usa26,
-	num_ports:		2,
-	indat_endp_flip:	0,
-	outdat_endp_flip:	1,
-	indat_endpoints:	{0x81, 0x83},
-	outdat_endpoints:	{0x01, 0x03},
-	inack_endpoints:	{0x85, 0x86},
-	outcont_endpoints:	{0x05, 0x06},
-	instat_endpoint:	0x87,
-	glocont_endpoint:	0x07,
-	calculate_baud_rate:	keyspan_usa19w_calc_baud,
-	baudclk:		KEYSPAN_USA28X_BAUDCLK,
+	.product_id		= keyspan_usa28x_product_id,
+	.msg_format		= msg_usa26,
+	.num_ports		= 2,
+	.indat_endp_flip	= 0,
+	.outdat_endp_flip	= 1,
+	.indat_endpoints	= {0x81, 0x83},
+	.outdat_endpoints	= {0x01, 0x03},
+	.inack_endpoints	= {0x85, 0x86},
+	.outcont_endpoints	= {0x05, 0x06},
+	.instat_endpoint	= 0x87,
+	.glocont_endpoint	= 0x07,
+	.calculate_baud_rate	= keyspan_usa19w_calc_baud,
+	.baudclk		= KEYSPAN_USA28X_BAUDCLK,
 };
 
 static const struct keyspan_device_details usa28xa_device_details = {
-	product_id:		keyspan_usa28xa_product_id,
-	msg_format:		msg_usa26,
-	num_ports:		2,
-	indat_endp_flip:	0,
-	outdat_endp_flip:	1,
-	indat_endpoints:	{0x81, 0x83},
-	outdat_endpoints:	{0x01, 0x03},
-	inack_endpoints:	{0x85, 0x86},
-	outcont_endpoints:	{0x05, 0x06},
-	instat_endpoint:	0x87,
-	glocont_endpoint:	0x07,
-	calculate_baud_rate:	keyspan_usa19w_calc_baud,
-	baudclk:		KEYSPAN_USA28X_BAUDCLK,
+	.product_id		= keyspan_usa28xa_product_id,
+	.msg_format		= msg_usa26,
+	.num_ports		= 2,
+	.indat_endp_flip	= 0,
+	.outdat_endp_flip	= 1,
+	.indat_endpoints	= {0x81, 0x83},
+	.outdat_endpoints	= {0x01, 0x03},
+	.inack_endpoints	= {0x85, 0x86},
+	.outcont_endpoints	= {0x05, 0x06},
+	.instat_endpoint	= 0x87,
+	.glocont_endpoint	= 0x07,
+	.calculate_baud_rate	= keyspan_usa19w_calc_baud,
+	.baudclk		= KEYSPAN_USA28X_BAUDCLK,
 };
 
 /* We don't need a separate entry for the usa28xb as it appears as a 28x anyway */
 
 static const struct keyspan_device_details usa49w_device_details = {
-	product_id:		keyspan_usa49w_product_id,
-	msg_format:		msg_usa49,
-	num_ports:		4,
-	indat_endp_flip:	0,
-	outdat_endp_flip:	0,
-	indat_endpoints:	{0x81, 0x82, 0x83, 0x84},
-	outdat_endpoints:	{0x01, 0x02, 0x03, 0x04},
-	inack_endpoints:	{-1, -1, -1, -1},
-	outcont_endpoints:	{-1, -1, -1, -1},
-	instat_endpoint:	0x87,
-	glocont_endpoint:	0x07,
-	calculate_baud_rate:	keyspan_usa19w_calc_baud,
-	baudclk:		KEYSPAN_USA49W_BAUDCLK,
+	.product_id		= keyspan_usa49w_product_id,
+	.msg_format		= msg_usa49,
+	.num_ports		= 4,
+	.indat_endp_flip	= 0,
+	.outdat_endp_flip	= 0,
+	.indat_endpoints	= {0x81, 0x82, 0x83, 0x84},
+	.outdat_endpoints	= {0x01, 0x02, 0x03, 0x04},
+	.inack_endpoints	= {-1, -1, -1, -1},
+	.outcont_endpoints	= {-1, -1, -1, -1},
+	.instat_endpoint	= 0x87,
+	.glocont_endpoint	= 0x07,
+	.calculate_baud_rate	= keyspan_usa19w_calc_baud,
+	.baudclk		= KEYSPAN_USA49W_BAUDCLK,
 };
 
 static const struct keyspan_device_details *keyspan_devices[] = {
@@ -479,80 +479,80 @@
 
 /* Structs for the devices, pre and post renumeration. */
 static struct usb_serial_device_type keyspan_pre_device = {
-	owner:			THIS_MODULE,
-	name:			"Keyspan - (without firmware)",
-	id_table:		keyspan_pre_ids,
-	num_interrupt_in:	NUM_DONT_CARE,
-	num_bulk_in:		NUM_DONT_CARE,
-	num_bulk_out:		NUM_DONT_CARE,
-	num_ports:		1,
-	attach:			keyspan_fake_startup,
+	.owner			= THIS_MODULE,
+	.name			= "Keyspan - (without firmware)",
+	.id_table		= keyspan_pre_ids,
+	.num_interrupt_in	= NUM_DONT_CARE,
+	.num_bulk_in		= NUM_DONT_CARE,
+	.num_bulk_out		= NUM_DONT_CARE,
+	.num_ports		= 1,
+	.attach			= keyspan_fake_startup,
 };
 
 static struct usb_serial_device_type keyspan_1port_device = {
-	owner:			THIS_MODULE,
-	name:			"Keyspan 1 port adapter",
-	id_table:		keyspan_1port_ids,
-	num_interrupt_in:	NUM_DONT_CARE,
-	num_bulk_in:		3,
-	num_bulk_out:		4,
-	num_ports:		1,
-	open:			keyspan_open,
-	close:			keyspan_close,
-	write:			keyspan_write,
-	write_room:		keyspan_write_room,
-	chars_in_buffer:	keyspan_chars_in_buffer,
-	throttle:		keyspan_rx_throttle,
-	unthrottle:		keyspan_rx_unthrottle,
-	ioctl:			keyspan_ioctl,
-	set_termios:		keyspan_set_termios,
-	break_ctl:		keyspan_break_ctl,
-	attach:			keyspan_startup,
-	shutdown:		keyspan_shutdown,
+	.owner			= THIS_MODULE,
+	.name			= "Keyspan 1 port adapter",
+	.id_table		= keyspan_1port_ids,
+	.num_interrupt_in	= NUM_DONT_CARE,
+	.num_bulk_in		= 3,
+	.num_bulk_out		= 4,
+	.num_ports		= 1,
+	.open			= keyspan_open,
+	.close			= keyspan_close,
+	.write			= keyspan_write,
+	.write_room		= keyspan_write_room,
+	.chars_in_buffer	= keyspan_chars_in_buffer,
+	.throttle		= keyspan_rx_throttle,
+	.unthrottle		= keyspan_rx_unthrottle,
+	.ioctl			= keyspan_ioctl,
+	.set_termios		= keyspan_set_termios,
+	.break_ctl		= keyspan_break_ctl,
+	.attach			= keyspan_startup,
+	.shutdown		= keyspan_shutdown,
 };
 
 static struct usb_serial_device_type keyspan_2port_device = {
-	owner:			THIS_MODULE,
-	name:			"Keyspan 2 port adapter",
-	id_table:		keyspan_2port_ids,
-	num_interrupt_in:	NUM_DONT_CARE,
-	num_bulk_in:		NUM_DONT_CARE,
-	num_bulk_out:		NUM_DONT_CARE,
-	num_ports:		2,
-	open:			keyspan_open,
-	close:			keyspan_close,
-	write:			keyspan_write,
-	write_room:		keyspan_write_room,
-	chars_in_buffer:	keyspan_chars_in_buffer,
-	throttle:		keyspan_rx_throttle,
-	unthrottle:		keyspan_rx_unthrottle,
-	ioctl:			keyspan_ioctl,
-	set_termios:		keyspan_set_termios,
-	break_ctl:		keyspan_break_ctl,
-	attach:			keyspan_startup,
-	shutdown:		keyspan_shutdown,
+	.owner			= THIS_MODULE,
+	.name			= "Keyspan 2 port adapter",
+	.id_table		= keyspan_2port_ids,
+	.num_interrupt_in	= NUM_DONT_CARE,
+	.num_bulk_in		= NUM_DONT_CARE,
+	.num_bulk_out		= NUM_DONT_CARE,
+	.num_ports		= 2,
+	.open			= keyspan_open,
+	.close			= keyspan_close,
+	.write			= keyspan_write,
+	.write_room		= keyspan_write_room,
+	.chars_in_buffer	= keyspan_chars_in_buffer,
+	.throttle		= keyspan_rx_throttle,
+	.unthrottle		= keyspan_rx_unthrottle,
+	.ioctl			= keyspan_ioctl,
+	.set_termios		= keyspan_set_termios,
+	.break_ctl		= keyspan_break_ctl,
+	.attach			= keyspan_startup,
+	.shutdown		= keyspan_shutdown,
 };
 
 static struct usb_serial_device_type keyspan_4port_device = {
-	owner:			THIS_MODULE,
-	name:			"Keyspan 4 port adapter",
-	id_table:		keyspan_4port_ids,
-	num_interrupt_in:	NUM_DONT_CARE,
-	num_bulk_in:		5,
-	num_bulk_out:		5,
-	num_ports:		4,
-	open:			keyspan_open,
-	close:			keyspan_close,
-	write:			keyspan_write,
-	write_room:		keyspan_write_room,
-	chars_in_buffer:	keyspan_chars_in_buffer,
-	throttle:		keyspan_rx_throttle,
-	unthrottle:		keyspan_rx_unthrottle,
-	ioctl:			keyspan_ioctl,
-	set_termios:		keyspan_set_termios,
-	break_ctl:		keyspan_break_ctl,
-	attach:			keyspan_startup,
-	shutdown:		keyspan_shutdown,
+	.owner			= THIS_MODULE,
+	.name			= "Keyspan 4 port adapter",
+	.id_table		= keyspan_4port_ids,
+	.num_interrupt_in	= NUM_DONT_CARE,
+	.num_bulk_in		= 5,
+	.num_bulk_out		= 5,
+	.num_ports		= 4,
+	.open			= keyspan_open,
+	.close			= keyspan_close,
+	.write			= keyspan_write,
+	.write_room		= keyspan_write_room,
+	.chars_in_buffer	= keyspan_chars_in_buffer,
+	.throttle		= keyspan_rx_throttle,
+	.unthrottle		= keyspan_rx_unthrottle,
+	.ioctl			= keyspan_ioctl,
+	.set_termios		= keyspan_set_termios,
+	.break_ctl		= keyspan_break_ctl,
+	.attach			= keyspan_startup,
+	.shutdown		= keyspan_shutdown,
 };
 
 #endif
diff -Nru a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
--- a/drivers/usb/serial/keyspan_pda.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/usb/serial/keyspan_pda.c	Mon Dec  9 18:46:50 2002
@@ -222,7 +222,7 @@
 }
 
 
-static void keyspan_pda_rx_interrupt (struct urb *urb)
+static void keyspan_pda_rx_interrupt (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 	struct usb_serial *serial;
@@ -637,7 +637,7 @@
 }
 
 
-static void keyspan_pda_write_bulk_callback (struct urb *urb)
+static void keyspan_pda_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 	struct usb_serial *serial;
diff -Nru a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
--- a/drivers/usb/serial/kl5kusb105.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/usb/serial/kl5kusb105.c	Mon Dec  9 18:46:38 2002
@@ -88,11 +88,11 @@
 					  int from_user,
 					  const unsigned char *buf,
 					  int count);
-static void klsi_105_write_bulk_callback (struct urb *urb);
+static void klsi_105_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
 static int  klsi_105_chars_in_buffer     (struct usb_serial_port *port);
 static int  klsi_105_write_room          (struct usb_serial_port *port);
 
-static void klsi_105_read_bulk_callback  (struct urb *urb);
+static void klsi_105_read_bulk_callback  (struct urb *urb, struct pt_regs *regs);
 static void klsi_105_set_termios         (struct usb_serial_port *port,
 					  struct termios * old);
 static int  klsi_105_ioctl	         (struct usb_serial_port *port,
@@ -558,7 +558,7 @@
 	return bytes_sent;	/* that's how much we wrote */
 } /* klsi_105_write */
 
-static void klsi_105_write_bulk_callback ( struct urb *urb)
+static void klsi_105_write_bulk_callback ( struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 	struct usb_serial *serial = port->serial;
@@ -627,7 +627,7 @@
 
 
 
-static void klsi_105_read_bulk_callback (struct urb *urb)
+static void klsi_105_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 	struct usb_serial *serial = port->serial;
diff -Nru a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/usb/serial/kobil_sct.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,727 @@
+/*
+ *  KOBIL USB Smart Card Terminal Driver
+ *
+ *  Copyright (C) 2002  KOBIL Systems GmbH 
+ *  Author: Thomas Wahrenbruch
+ *
+ *  Contact: linuxusb@kobil.de
+ *
+ *  This program is largely derived from work by the linux-usb group
+ *  and associated source files.  Please see the usb/serial files for
+ *  individual credits and copyrights.
+ *
+ *  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.
+ *
+ *  Thanks to Greg Kroah-Hartman (greg@kroah.com) for his help and
+ *  patience.
+ *
+ * Supported readers: USB TWIN, KAAN Standard Plus and SecOVID Reader Plus
+ * (Adapter K), B1 Professional and KAAN Professional (Adapter B)
+ * 
+ * TODO: High baudrates
+ *
+ * (12/09/2002) tw
+ *      Adapted to 2.5.
+ *
+ * (11/08/2002) tw
+ *      Initial version.
+ */
+
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <asm/uaccess.h>
+#include <linux/usb.h>
+#include <linux/ioctl.h>
+
+
+#include "kobil_sct.h"
+//#include "../core/usb-debug.c"
+
+#ifdef CONFIG_USB_SERIAL_DEBUG
+	static int debug = 1;
+#else
+	static int debug;
+#endif
+
+#include "usb-serial.h"
+
+/* Version Information */
+#define DRIVER_VERSION "12/09/2002"
+#define DRIVER_AUTHOR "KOBIL Systems GmbH - http://www.kobil.com"
+#define DRIVER_DESC "KOBIL USB Smart Card Terminal Driver (experimental)"
+
+#define KOBIL_VENDOR_ID			0x0D46
+#define KOBIL_ADAPTER_B_PRODUCT_ID	0x2011
+#define KOBIL_ADAPTER_K_PRODUCT_ID	0x2012
+#define KOBIL_USBTWIN_PRODUCT_ID	0x0078
+
+#define KOBIL_TIMEOUT		500
+#define KOBIL_BUF_LENGTH	300
+
+
+/* Function prototypes */
+static int  kobil_startup (struct usb_serial *serial);
+static void kobil_shutdown (struct usb_serial *serial);
+static int  kobil_open (struct usb_serial_port *port, struct file *filp);
+static void kobil_close (struct usb_serial_port *port, struct file *filp);
+static int  kobil_write (struct usb_serial_port *port, int from_user, 
+			 const unsigned char *buf, int count);
+static int  kobil_write_room(struct usb_serial_port *port);
+static int  kobil_ioctl(struct usb_serial_port *port, struct file *file,
+			unsigned int cmd, unsigned long arg);
+static void kobil_read_int_callback( struct urb *urb, struct pt_regs *regs );
+static void kobil_write_callback( struct urb *purb, struct pt_regs *regs );
+
+
+static struct usb_device_id id_table [] = {
+	{ USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_ADAPTER_B_PRODUCT_ID) },
+	{ USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_ADAPTER_K_PRODUCT_ID) },
+	{ USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_USBTWIN_PRODUCT_ID) },
+	{ }			/* Terminating entry */
+};
+
+
+MODULE_DEVICE_TABLE (usb, id_table);
+
+struct usb_serial_device_type kobil_device = {
+	.owner =		THIS_MODULE,
+	.name =			"KOBIL USB smart card terminal",
+	.id_table =		id_table,
+	.num_interrupt_in =	NUM_DONT_CARE,
+	.num_bulk_in =		0,
+	.num_bulk_out =		0,
+	.num_ports =		1,
+	.attach =		kobil_startup,
+	.shutdown =		kobil_shutdown,
+	.ioctl =		kobil_ioctl,
+	.open =			kobil_open,
+	.close =		kobil_close,
+	.write =		kobil_write,
+	.write_room =		kobil_write_room,
+	.read_int_callback =	kobil_read_int_callback,
+};
+
+
+struct kobil_private {
+	int write_int_endpoint_address;
+	int read_int_endpoint_address;
+	unsigned char buf[KOBIL_BUF_LENGTH]; // buffer for the APDU to send
+	int filled;  // index of the last char in buf
+	int cur_pos; // index of the next char to send in buf
+	__u16 device_type;
+	int line_state;
+	struct termios internal_termios;
+};
+
+
+static int kobil_startup (struct usb_serial *serial)
+{
+	int i;
+	struct kobil_private *priv;
+	struct usb_device *pdev;
+	struct usb_host_config *actconfig;
+	struct usb_interface *interface;
+	struct usb_host_interface *altsetting;
+	struct usb_host_endpoint *endpoint;
+
+	serial->port->private = kmalloc(sizeof(struct kobil_private), GFP_KERNEL);
+	if (!serial->port->private){
+		return -1;
+	}
+
+	priv = (struct kobil_private *) serial->port->private;
+	priv->filled = 0;
+	priv->cur_pos = 0;
+	priv->device_type = serial->product;
+	priv->line_state = 0;
+
+	switch (priv->device_type){
+	case KOBIL_ADAPTER_B_PRODUCT_ID:
+		printk(KERN_DEBUG "KOBIL B1 PRO / KAAN PRO detected\n");
+		break;
+	case KOBIL_ADAPTER_K_PRODUCT_ID:
+		printk(KERN_DEBUG "KOBIL KAAN Standard Plus / SecOVID Reader Plus detected\n");
+		break;
+	case KOBIL_USBTWIN_PRODUCT_ID:
+		printk(KERN_DEBUG "KOBIL USBTWIN detected\n");
+		break;
+	}
+
+	// search for the neccessary endpoints
+	pdev = serial->dev;
+ 	actconfig = pdev->actconfig;
+ 	interface = actconfig->interface;
+	altsetting = interface->altsetting;
+ 	endpoint = altsetting->endpoint;
+  
+ 	for (i = 0; i < altsetting->desc.bNumEndpoints; i++) {
+		endpoint = &altsetting->endpoint[i];
+		if (((endpoint->desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) && 
+ 		    ((endpoint->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
+		 	dbg("%s Found interrupt out endpoint. Address: %d", __FUNCTION__, endpoint->desc.bEndpointAddress);
+		 	priv->write_int_endpoint_address = endpoint->desc.bEndpointAddress;
+ 		}
+ 		if (((endpoint->desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) && 
+ 		    ((endpoint->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
+		 	dbg("%s Found interrupt in  endpoint. Address: %d", __FUNCTION__, endpoint->desc.bEndpointAddress);
+		 	priv->read_int_endpoint_address = endpoint->desc.bEndpointAddress;
+	 	}
+	}
+	return 0;
+}
+
+
+static void kobil_shutdown (struct usb_serial *serial)
+{
+	int i;
+	dbg("%s - port %d", __FUNCTION__, serial->port->number);
+
+	for (i=0; i < serial->num_ports; ++i) {
+		while (serial->port[i].open_count > 0) {
+			kobil_close (&serial->port[i], NULL);
+		}
+		if (serial->port[i].private) {
+			kfree(serial->port[i].private);
+		}
+	}
+}
+
+
+static int kobil_open (struct usb_serial_port *port, struct file *filp)
+{
+	int i, result = 0;
+	struct kobil_private *priv;
+	unsigned char *transfer_buffer;
+	int transfer_buffer_length = 8;
+	int write_urb_transfer_buffer_length = 8;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+	priv = (struct kobil_private *) port->private;
+	priv->line_state = 0;
+
+	if (port_paranoia_check (port, __FUNCTION__))
+		return -ENODEV;
+
+	// someone sets the dev to 0 if the close method has been called
+	port->interrupt_in_urb->dev = port->serial->dev;
+
+
+	/* force low_latency on so that our tty_push actually forces
+	 * the data through, otherwise it is scheduled, and with high
+	 * data rates (like with OHCI) data can get lost.
+	 */
+	port->tty->low_latency = 1;
+
+	// without this, every push_tty_char is echoed :-(  
+	port->tty->termios->c_lflag = 0;
+	port->tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE);
+	port->tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF;
+	port->tty->termios->c_oflag &= ~ONLCR; // do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D)
+	
+	// set up internal termios structure 
+	priv->internal_termios.c_iflag = port->tty->termios->c_iflag;
+	priv->internal_termios.c_oflag = port->tty->termios->c_oflag;
+	priv->internal_termios.c_cflag = port->tty->termios->c_cflag;
+	priv->internal_termios.c_lflag = port->tty->termios->c_lflag;
+
+	for (i=0; i<NCCS; i++) {
+		priv->internal_termios.c_cc[i] = port->tty->termios->c_cc[i];
+	}
+	
+	// allocate memory for transfer buffer
+	transfer_buffer = (unsigned char *) kmalloc(transfer_buffer_length, GFP_KERNEL);  
+	if (! transfer_buffer) {
+		return -1;
+	} else {
+		memset(transfer_buffer, 0, transfer_buffer_length);
+	}
+	
+	// allocate write_urb
+	if (!port->write_urb) { 
+		dbg("%s - port %d  Allocating port->write_urb", __FUNCTION__, port->number);
+		port->write_urb = usb_alloc_urb(0, GFP_KERNEL);  
+		if (!port->write_urb) {
+			dbg("%s - port %d usb_alloc_urb failed", __FUNCTION__, port->number);
+			return -1;
+		}
+	}
+
+	// allocate memory for write_urb transfer buffer
+	port->write_urb->transfer_buffer = (unsigned char *) kmalloc(write_urb_transfer_buffer_length, GFP_KERNEL);
+	if (! port->write_urb->transfer_buffer) {
+		return -1;
+	} 
+
+	// get hardware version
+	result = usb_control_msg( port->serial->dev, 
+				  usb_rcvctrlpipe(port->serial->dev, 0 ), 
+				  SUSBCRequest_GetMisc,
+				  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
+				  SUSBCR_MSC_GetHWVersion,
+				  0,
+				  transfer_buffer,
+				  transfer_buffer_length,
+				  KOBIL_TIMEOUT
+		);
+	dbg("%s - port %d Send get_HW_version URB returns: %i", __FUNCTION__, port->number, result);
+	dbg("Harware version: %i.%i.%i", transfer_buffer[0], transfer_buffer[1], transfer_buffer[2] );
+	
+	// get firmware version
+	result = usb_control_msg( port->serial->dev, 
+				  usb_rcvctrlpipe(port->serial->dev, 0 ), 
+				  SUSBCRequest_GetMisc,
+				  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
+				  SUSBCR_MSC_GetFWVersion,
+				  0,
+				  transfer_buffer,
+				  transfer_buffer_length,
+				  KOBIL_TIMEOUT
+		);
+	dbg("%s - port %d Send get_FW_version URB returns: %i", __FUNCTION__, port->number, result);
+	dbg("Firmware version: %i.%i.%i", transfer_buffer[0], transfer_buffer[1], transfer_buffer[2] );
+
+	if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID || priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) {
+		// Setting Baudrate, Parity and Stopbits
+		result = usb_control_msg( port->serial->dev, 
+					  usb_rcvctrlpipe(port->serial->dev, 0 ), 
+					  SUSBCRequest_SetBaudRateParityAndStopBits,
+					  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
+					  SUSBCR_SBR_9600 | SUSBCR_SPASB_EvenParity | SUSBCR_SPASB_1StopBit,
+					  0,
+					  transfer_buffer,
+					  0,
+					  KOBIL_TIMEOUT
+			);
+		dbg("%s - port %d Send set_baudrate URB returns: %i", __FUNCTION__, port->number, result);
+		
+		// reset all queues
+		result = usb_control_msg( port->serial->dev, 
+					  usb_rcvctrlpipe(port->serial->dev, 0 ), 
+					  SUSBCRequest_Misc,
+					  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
+					  SUSBCR_MSC_ResetAllQueues,
+					  0,
+					  transfer_buffer,
+					  0,
+					  KOBIL_TIMEOUT
+			);
+		dbg("%s - port %d Send reset_all_queues URB returns: %i", __FUNCTION__, port->number, result);
+	}
+
+	kfree(transfer_buffer);
+	return 0;
+}
+
+
+static void kobil_close (struct usb_serial_port *port, struct file *filp)
+{
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	if (port->write_urb){
+		usb_unlink_urb( port->write_urb );
+		usb_free_urb( port->write_urb );
+		port->write_urb = 0;
+	}
+	if (port->interrupt_in_urb){
+		usb_unlink_urb (port->interrupt_in_urb);
+	}
+}
+
+
+static void kobil_read_int_callback( struct urb *purb, struct pt_regs *regs)
+{
+	int i;
+	int result;
+	struct usb_serial_port *port = (struct usb_serial_port *) purb->context;
+	struct tty_struct *tty;
+	unsigned char *data = purb->transfer_buffer;
+	char *dbg_data;
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
+
+	if (purb->status) {
+		dbg("%s - port %d Read int status not zero: %d", __FUNCTION__, port->number, purb->status);
+		return;
+	}
+	
+	tty = port->tty; 
+	if (purb->actual_length) {
+		
+		// BEGIN DEBUG
+		dbg_data = (unsigned char *) kmalloc((3 *  purb->actual_length + 10) * sizeof(char), GFP_KERNEL);  
+		if (! dbg_data) {
+			return;
+		}
+		memset(dbg_data, 0, (3 *  purb->actual_length + 10));
+		for (i = 0; i < purb->actual_length; i++) { 
+			sprintf(dbg_data +3*i, "%02X ", data[i]); 
+		}
+		dbg(" <-- %s", dbg_data );
+		kfree(dbg_data);
+		// END DEBUG
+
+		for (i = 0; i < purb->actual_length; ++i) {
+			// if we insert more than TTY_FLIPBUF_SIZE characters, we drop them.
+			if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
+				tty_flip_buffer_push(tty);
+			}
+			// this doesn't actually push the data through unless tty->low_latency is set
+			tty_insert_flip_char(tty, data[i], 0);
+		}
+		tty_flip_buffer_push(tty);
+	}
+
+	// someone sets the dev to 0 if the close method has been called
+	port->interrupt_in_urb->dev = port->serial->dev;
+
+	// usb_dump_urb(port->interrupt_in_urb);
+
+	result = usb_submit_urb( port->interrupt_in_urb, GFP_ATOMIC ); 
+	dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result);
+}
+
+
+static void kobil_write_callback( struct urb *purb, struct pt_regs *regs )
+{
+}
+
+
+static int kobil_write (struct usb_serial_port *port, int from_user, 
+			const unsigned char *buf, int count)
+{
+	int length = 0;
+	int result = 0;
+	int todo = 0;
+	struct kobil_private * priv;
+	int i;
+	char *data;
+
+	if (count == 0) {
+		dbg("%s - port %d write request of 0 bytes", __FUNCTION__, port->number);
+		return 0;
+	}
+
+	priv = (struct kobil_private *) port->private;
+
+	if (count > (KOBIL_BUF_LENGTH - priv->filled)) {
+		dbg("%s - port %d Error: write request bigger than buffer size", __FUNCTION__, port->number);
+		return -ENOMEM;
+	}
+
+	// BEGIN DEBUG
+	data = (unsigned char *) kmalloc((3 * count + 10) * sizeof(char), GFP_KERNEL);  
+	if (! data) {
+		return (-1);
+	}
+	memset(data, 0, (3 * count + 10));
+	for (i = 0; i < count; i++) { 
+		sprintf(data +3*i, "%02X ", buf[i]); 
+	} 
+	dbg(" %d --> %s", port->number, data );
+	kfree(data);
+	// END DEBUG
+
+	// Copy data to buffer
+	if (from_user) {
+		if (copy_from_user(priv->buf + priv->filled, buf, count)) {
+			return -EFAULT;
+		}
+	} else {
+		memcpy (priv->buf + priv->filled, buf, count);
+	}
+
+	priv->filled = priv->filled + count;
+
+
+	// only send complete block. TWIN and adapter K use the same protocol.
+	if ( ((priv->device_type != KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 2) && (priv->filled >= (priv->buf[1] + 3))) || 
+	     ((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 3) && (priv->filled >= (priv->buf[2] + 4))) ) {
+		
+		todo = priv->filled - priv->cur_pos;
+
+		while(todo > 0) {
+			// max 8 byte in one urb (endpoint size)
+			length = (todo < 8) ? todo : 8;
+			// copy data to transfer buffer
+			memcpy(port->write_urb->transfer_buffer, priv->buf + priv->cur_pos, length );
+			
+			usb_fill_bulk_urb( port->write_urb,
+					   port->serial->dev,
+					   usb_sndbulkpipe( port->serial->dev, priv->write_int_endpoint_address),
+					   port->write_urb->transfer_buffer,
+					   length,
+					   kobil_write_callback,
+					   port
+				);
+
+			priv->cur_pos = priv->cur_pos + length;
+			result = usb_submit_urb( port->write_urb, GFP_ATOMIC );
+			dbg("%s - port %d Send write URB returns: %i", __FUNCTION__, port->number, result);
+			todo = priv->filled - priv->cur_pos;
+
+			if (todo > 0) {
+				//mdelay(16);
+				set_current_state(TASK_UNINTERRUPTIBLE);
+				schedule_timeout(24 * HZ / 1000);
+			}
+
+		} // end while
+		
+		priv->filled = 0;
+		priv->cur_pos = 0;
+
+		// someone sets the dev to 0 if the close method has been called
+		port->interrupt_in_urb->dev = port->serial->dev;
+		
+		// start reading
+		//usb_dump_urb(port->interrupt_in_urb);
+
+		result = usb_submit_urb( port->interrupt_in_urb, GFP_ATOMIC ); 
+		dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result);
+	}
+	return count;
+}
+
+
+static int kobil_write_room (struct usb_serial_port *port)
+{
+	//dbg(__FUNCTION__ " - port %d", port->number);
+	return 8;
+}
+
+
+static int  kobil_ioctl(struct usb_serial_port *port, struct file *file,
+			unsigned int cmd, unsigned long arg)
+{
+	struct kobil_private * priv;
+	int mask;
+	int result;
+	unsigned short urb_val = 0;
+	unsigned char *transfer_buffer;
+	int transfer_buffer_length = 8;
+	char *settings;
+
+	priv = (struct kobil_private *) port->private;
+	if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) {
+		// This device doesn't support ioctl calls
+		return 0;
+	}
+
+	switch (cmd) {
+	case TCGETS:   // 0x5401
+		result = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct termios));
+		if (result) {
+			dbg("%s - port %d Error in verify_area", __FUNCTION__, port->number);
+			return(result);
+		}
+		kernel_termios_to_user_termios((struct termios *)arg, &priv->internal_termios);
+		return 0;
+
+	case TCSETS:   // 0x5402
+		if (! &port->tty->termios) {
+			dbg("%s - port %d Error: port->tty->termios is NULL", __FUNCTION__, port->number);
+			return -ENOTTY;
+		}
+		result = verify_area(VERIFY_READ, (void *)arg, sizeof(struct termios));
+		if (result) {
+			dbg("%s - port %d Error in verify_area", __FUNCTION__, port->number);
+			return result;
+		}
+		user_termios_to_kernel_termios( &priv->internal_termios, (struct termios *)arg);
+		
+		settings = (unsigned char *) kmalloc(50, GFP_KERNEL);  
+		if (! settings) {
+			return -ENOBUFS;
+		}
+		memset(settings, 0, 50);
+
+		switch (priv->internal_termios.c_cflag & CBAUD) {
+		case B1200:
+			urb_val = SUSBCR_SBR_1200;
+			strcat(settings, "1200 ");
+			break;
+		case B9600:
+		default:
+			urb_val = SUSBCR_SBR_9600;
+			strcat(settings, "9600 ");
+			break;
+		}
+
+		urb_val |= (priv->internal_termios.c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : SUSBCR_SPASB_1StopBit;
+		strcat(settings, (priv->internal_termios.c_cflag & CSTOPB) ? "2 StopBits " : "1 StopBit ");
+
+		if (priv->internal_termios.c_cflag & PARENB) {
+			if  (priv->internal_termios.c_cflag & PARODD) {
+				urb_val |= SUSBCR_SPASB_OddParity;
+				strcat(settings, "Odd Parity");
+			} else {
+				urb_val |= SUSBCR_SPASB_EvenParity;
+				strcat(settings, "Even Parity");
+			}
+		} else {
+			urb_val |= SUSBCR_SPASB_NoParity;
+			strcat(settings, "No Parity");
+		}
+		dbg("%s - port %d setting port to: %s", __FUNCTION__, port->number, settings );
+
+		result = usb_control_msg( port->serial->dev, 
+					  usb_rcvctrlpipe(port->serial->dev, 0 ), 
+					  SUSBCRequest_SetBaudRateParityAndStopBits,
+					  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
+					  urb_val,
+					  0,
+					  settings,
+					  0,
+					  KOBIL_TIMEOUT
+			);
+
+		dbg("%s - port %d Send set_baudrate URB returns: %i", __FUNCTION__, port->number, result);
+		kfree(settings);
+		return 0;
+
+	case TCFLSH:   // 0x540B
+		transfer_buffer = (unsigned char *) kmalloc(transfer_buffer_length, GFP_KERNEL);
+		if (! transfer_buffer) {
+		 	return -ENOBUFS;
+		}
+
+		result = usb_control_msg( port->serial->dev, 
+		 			  usb_rcvctrlpipe(port->serial->dev, 0 ), 
+					  SUSBCRequest_Misc,
+					  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
+					  SUSBCR_MSC_ResetAllQueues,
+					  0,
+					  NULL,//transfer_buffer,
+					  0,
+					  KOBIL_TIMEOUT
+			);
+		
+		dbg("%s - port %d Send reset_all_queues (FLUSH) URB returns: %i", __FUNCTION__, port->number, result);
+
+		kfree(transfer_buffer);
+		return ((result < 0) ? -EFAULT : 0);
+
+	case TIOCMGET: // 0x5415
+		// allocate memory for transfer buffer
+		transfer_buffer = (unsigned char *) kmalloc(transfer_buffer_length, GFP_KERNEL);  
+		if (! transfer_buffer) {
+			return -ENOBUFS;
+		} else {
+			memset(transfer_buffer, 0, transfer_buffer_length);
+		}
+
+		result = usb_control_msg( port->serial->dev, 
+					  usb_rcvctrlpipe(port->serial->dev, 0 ), 
+					  SUSBCRequest_GetStatusLineState,
+					  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
+					  0,
+					  0,
+					  transfer_buffer,
+					  transfer_buffer_length,
+					  KOBIL_TIMEOUT
+			);
+
+		dbg("%s - port %d Send get_status_line_state (TIOCMGET) URB returns: %i. Statusline: %02x", 
+		    __FUNCTION__, port->number, result, transfer_buffer[0]);
+
+		if ((transfer_buffer[0] & SUSBCR_GSL_DSR) != 0) {
+			priv->line_state |= TIOCM_DSR;
+		} else {
+			priv->line_state &= ~TIOCM_DSR; 
+		}
+
+		kfree(transfer_buffer);
+		return put_user(priv->line_state, (unsigned long *) arg);
+
+	case TIOCMSET: // 0x5418
+		if (get_user(mask, (unsigned long *) arg)){
+			return -EFAULT;
+		}
+		// allocate memory for transfer buffer
+		transfer_buffer = (unsigned char *) kmalloc(transfer_buffer_length, GFP_KERNEL);
+		if (! transfer_buffer) {
+			return -ENOBUFS;
+		} else {
+			memset(transfer_buffer, 0, transfer_buffer_length);
+		}
+
+		if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) {
+			if ((mask & TIOCM_DTR) != 0){
+				dbg("%s - port %d Setting DTR", __FUNCTION__, port->number);
+			} else {
+				dbg("%s - port %d Clearing DTR", __FUNCTION__, port->number);
+			} 
+			result = usb_control_msg( port->serial->dev, 
+						  usb_rcvctrlpipe(port->serial->dev, 0 ), 
+						  SUSBCRequest_SetStatusLinesOrQueues,
+						  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
+						  ( ((mask & TIOCM_DTR) != 0) ? SUSBCR_SSL_SETDTR : SUSBCR_SSL_CLRDTR),
+						  0,
+						  transfer_buffer,
+						  0,
+						  KOBIL_TIMEOUT
+				);
+			
+		} else {
+			if ((mask & TIOCM_RTS) != 0){
+				dbg("%s - port %d Setting RTS", __FUNCTION__, port->number);
+			} else {
+				dbg("%s - port %d Clearing RTS", __FUNCTION__, port->number);
+			}
+			result = usb_control_msg( port->serial->dev, 
+						  usb_rcvctrlpipe(port->serial->dev, 0 ), 
+						  SUSBCRequest_SetStatusLinesOrQueues,
+						  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
+						  (((mask & TIOCM_RTS) != 0) ? SUSBCR_SSL_SETRTS : SUSBCR_SSL_CLRRTS),
+						  0,
+						  transfer_buffer,
+						  0,
+						  KOBIL_TIMEOUT
+				);
+		}
+		dbg("%s - port %d Send set_status_line (TIOCMSET) URB returns: %i", __FUNCTION__, port->number, result);
+
+		kfree(transfer_buffer);
+		return ((result < 0) ? -EFAULT : 0);
+	}
+	return 0;
+}
+
+
+static int __init kobil_init (void)
+{
+	usb_serial_register (&kobil_device);
+
+	info(DRIVER_VERSION " " DRIVER_AUTHOR);
+	info(DRIVER_DESC);
+
+	return 0;
+}
+
+
+static void __exit kobil_exit (void)
+{
+	usb_serial_deregister (&kobil_device);
+}
+
+module_init(kobil_init);
+module_exit(kobil_exit);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE( "GPL" );
+
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug enabled or not");
diff -Nru a/drivers/usb/serial/kobil_sct.h b/drivers/usb/serial/kobil_sct.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/usb/serial/kobil_sct.h	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,60 @@
+#define SUSBCRequest_SetBaudRateParityAndStopBits       1
+#define SUSBCR_SBR_MASK				0xFF00
+#define SUSBCR_SBR_1200				0x0100
+#define SUSBCR_SBR_9600				0x0200
+#define SUSBCR_SBR_19200			0x0400
+#define SUSBCR_SBR_28800			0x0800
+#define SUSBCR_SBR_38400			0x1000
+#define SUSBCR_SBR_57600			0x2000
+#define SUSBCR_SBR_115200			0x4000
+
+#define SUSBCR_SPASB_MASK			0x0070
+#define SUSBCR_SPASB_NoParity			0x0010
+#define SUSBCR_SPASB_OddParity			0x0020
+#define SUSBCR_SPASB_EvenParity			0x0040
+
+#define SUSBCR_SPASB_STPMASK			0x0003
+#define SUSBCR_SPASB_1StopBit			0x0001
+#define SUSBCR_SPASB_2StopBits			0x0002
+
+#define SUSBCRequest_SetStatusLinesOrQueues	2
+#define SUSBCR_SSL_SETRTS			0x0001
+#define SUSBCR_SSL_CLRRTS			0x0002
+#define SUSBCR_SSL_SETDTR			0x0004
+#define SUSBCR_SSL_CLRDTR			0x0010
+
+#define SUSBCR_SSL_PURGE_TXABORT		0x0100  // Kill the pending/current writes to the comm port.
+#define SUSBCR_SSL_PURGE_RXABORT		0x0200  // Kill the pending/current reads to the comm port.
+#define SUSBCR_SSL_PURGE_TXCLEAR		0x0400  // Kill the transmit queue if there.
+#define SUSBCR_SSL_PURGE_RXCLEAR		0x0800  // Kill the typeahead buffer if there.
+
+#define SUSBCRequest_GetStatusLineState		4
+#define SUSBCR_GSL_RXCHAR			0x0001  // Any Character received
+#define SUSBCR_GSL_TXEMPTY			0x0004  // Transmitt Queue Empty
+#define SUSBCR_GSL_CTS				0x0008  // CTS changed state
+#define SUSBCR_GSL_DSR				0x0010  // DSR changed state
+#define SUSBCR_GSL_RLSD				0x0020  // RLSD changed state
+#define SUSBCR_GSL_BREAK			0x0040  // BREAK received
+#define SUSBCR_GSL_ERR				0x0080  // Line status error occurred
+#define SUSBCR_GSL_RING				0x0100  // Ring signal detected
+
+#define SUSBCRequest_Misc			8
+#define SUSBCR_MSC_ResetReader			0x0001	// use a predefined reset sequence
+#define SUSBCR_MSC_ResetAllQueues		0x0002	// use a predefined sequence to reset the internal queues
+
+#define SUSBCRequest_GetMisc			0x10
+#define SUSBCR_MSC_GetFWVersion			0x0001	/* get the firmware version from device,
+							   coded like this 0xHHLLBBPP
+							   with HH = Firmware Version High Byte
+							   LL = Firmware Version Low Byte
+							   BB = Build Number
+							   PP = Further Attributes
+							*/
+
+#define SUSBCR_MSC_GetHWVersion			0x0002	/* get the hardware version from device
+							   coded like this 0xHHLLPPRR
+							   with HH = Software Version High Byte
+							   LL = Software Version Low Byte
+							   PP = Further Attributes
+							   RR = Reserved for the hardware ID 
+							*/
diff -Nru a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
--- a/drivers/usb/serial/mct_u232.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/usb/serial/mct_u232.c	Mon Dec  9 18:46:50 2002
@@ -114,9 +114,9 @@
 					  int from_user,
 					  const unsigned char *buf,
 					  int count);
-static void mct_u232_write_bulk_callback (struct urb *urb);
+static void mct_u232_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
 #endif
-static void mct_u232_read_int_callback   (struct urb *urb);
+static void mct_u232_read_int_callback   (struct urb *urb, struct pt_regs *regs);
 static void mct_u232_set_termios         (struct usb_serial_port *port,
 					  struct termios * old);
 static int  mct_u232_ioctl	         (struct usb_serial_port *port,
@@ -479,7 +479,7 @@
 	return bytes_sent;
 } /* mct_u232_write */
 
-static void mct_u232_write_bulk_callback (struct urb *urb)
+static void mct_u232_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 	struct usb_serial *serial = port->serial;
@@ -514,7 +514,7 @@
 } /* mct_u232_write_bulk_callback */
 #endif
 
-static void mct_u232_read_int_callback (struct urb *urb)
+static void mct_u232_read_int_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 	struct mct_u232_private *priv = (struct mct_u232_private *)port->private;
diff -Nru a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
--- a/drivers/usb/serial/omninet.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/usb/serial/omninet.c	Mon Dec  9 18:46:51 2002
@@ -70,8 +70,8 @@
 /* function prototypes */
 static int  omninet_open		(struct usb_serial_port *port, struct file *filp);
 static void omninet_close		(struct usb_serial_port *port, struct file *filp);
-static void omninet_read_bulk_callback	(struct urb *urb);
-static void omninet_write_bulk_callback	(struct urb *urb);
+static void omninet_read_bulk_callback	(struct urb *urb, struct pt_regs *regs);
+static void omninet_write_bulk_callback	(struct urb *urb, struct pt_regs *regs);
 static int  omninet_write		(struct usb_serial_port *port, int from_user, const unsigned char *buf, int count);
 static int  omninet_write_room		(struct usb_serial_port *port);
 static void omninet_shutdown		(struct usb_serial *serial);
@@ -214,7 +214,7 @@
 #define OMNINET_HEADERLEN	sizeof(struct omninet_header)
 #define OMNINET_BULKOUTSIZE 	(64 - OMNINET_HEADERLEN)
 
-static void omninet_read_bulk_callback (struct urb *urb)
+static void omninet_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port 	*port 	= (struct usb_serial_port *)urb->context;
 	struct usb_serial	*serial = get_usb_serial (port, __FUNCTION__);
@@ -336,7 +336,7 @@
 	return (room);
 }
 
-static void omninet_write_bulk_callback (struct urb *urb)
+static void omninet_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
 /*	struct omninet_header	*header = (struct omninet_header  *) urb->transfer_buffer; */
 	struct usb_serial_port 	*port   = (struct usb_serial_port *) urb->context;
diff -Nru a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
--- a/drivers/usb/serial/pl2303.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/usb/serial/pl2303.c	Mon Dec  9 18:46:36 2002
@@ -73,6 +73,7 @@
 	{ USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) },
 	{ USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID) },
 	{ USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) },
+	{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) },
 	{ }					/* Terminating entry */
 };
 
@@ -114,9 +115,9 @@
 				struct termios *old);
 static int pl2303_ioctl (struct usb_serial_port *port, struct file *file,
 			 unsigned int cmd, unsigned long arg);
-static void pl2303_read_int_callback (struct urb *urb);
-static void pl2303_read_bulk_callback (struct urb *urb);
-static void pl2303_write_bulk_callback (struct urb *urb);
+static void pl2303_read_int_callback (struct urb *urb, struct pt_regs *regs);
+static void pl2303_read_bulk_callback (struct urb *urb, struct pt_regs *regs);
+static void pl2303_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
 static int pl2303_write (struct usb_serial_port *port, int from_user,
 			 const unsigned char *buf, int count);
 static void pl2303_break_ctl(struct usb_serial_port *port,int break_state);
@@ -587,7 +588,7 @@
 }
 
 
-static void pl2303_read_int_callback (struct urb *urb)
+static void pl2303_read_int_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
 	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
@@ -625,7 +626,7 @@
 }
 
 
-static void pl2303_read_bulk_callback (struct urb *urb)
+static void pl2303_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
 	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
@@ -690,7 +691,7 @@
 
 
 
-static void pl2303_write_bulk_callback (struct urb *urb)
+static void pl2303_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
 	int result;
diff -Nru a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
--- a/drivers/usb/serial/pl2303.h	Mon Dec  9 18:46:38 2002
+++ b/drivers/usb/serial/pl2303.h	Mon Dec  9 18:46:38 2002
@@ -25,3 +25,6 @@
 
 #define MA620_VENDOR_ID		0x0df7
 #define MA620_PRODUCT_ID	0x0620
+
+#define RATOC_VENDOR_ID		0x0584
+#define RATOC_PRODUCT_ID	0xb000
diff -Nru a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c
--- a/drivers/usb/serial/safe_serial.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/usb/serial/safe_serial.c	Mon Dec  9 18:46:35 2002
@@ -132,13 +132,13 @@
 
 
 #define MY_USB_DEVICE(vend,prod,dc,ic,isc) \
-        match_flags: USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_CLASS | \
+        .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_CLASS | \
                 USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS, \
-        idVendor: (vend), \
-        idProduct: (prod),\
-        bDeviceClass: (dc),\
-        bInterfaceClass: (ic), \
-        bInterfaceSubClass: (isc),
+        .idVendor = (vend), \
+        .idProduct = (prod),\
+        .bDeviceClass = (dc),\
+        .bInterfaceClass = (ic), \
+        .bInterfaceSubClass = (isc),
 
 static struct usb_device_id id_table[] = {
 	{MY_USB_DEVICE (0x49f, 0xffff, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},	// Itsy
@@ -206,7 +206,7 @@
 	return fcs;
 }
 
-static void safe_read_bulk_callback (struct urb *urb)
+static void safe_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
 	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
diff -Nru a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
--- a/drivers/usb/serial/usb-serial.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/usb/serial/usb-serial.c	Mon Dec  9 18:46:36 2002
@@ -467,9 +467,12 @@
 	down (&port->sem);
 	port->tty = tty;
 	 
-	/* lock this module before we call it */
-	if (serial->type->owner)
-		__MOD_INC_USE_COUNT(serial->type->owner);
+	/* lock this module before we call it,
+	   this may, which means we must bail out, safe because we are called with BKL held */
+	if (!try_module_get(serial->type->owner)) {
+		retval = -ENODEV;
+		goto bailout;
+	}
 
 	++port->open_count;
 	if (port->open_count == 1) {
@@ -481,10 +484,10 @@
 			retval = usb_serial_generic_open(port, filp);
 		if (retval) {
 			port->open_count = 0;
-			if (serial->type->owner)
-				__MOD_DEC_USE_COUNT(serial->type->owner);
+			module_put(serial->type->owner);
 		}
 	}
+bailout:
 
 	up (&port->sem);
 	return retval;
@@ -508,8 +511,7 @@
 		port->open_count = 0;
 	}
 
-	if (port->serial->type->owner)
-		__MOD_DEC_USE_COUNT(port->serial->type->owner);
+	module_put(port->serial->type->owner);
 }
 
 static void serial_close(struct tty_struct *tty, struct file * filp)
@@ -899,11 +901,13 @@
 
 	/* if this device type has a probe function, call it */
 	if (type->probe) {
-		if (type->owner)
-			__MOD_INC_USE_COUNT(type->owner);
+		if (!try_module_get(type->owner)) {
+			err ("module get failed, exiting");
+			kfree (serial);
+			return -EIO;
+		}
 		retval = type->probe (serial);
-		if (type->owner)
-			__MOD_DEC_USE_COUNT(type->owner);
+		module_put(type->owner);
 
 		if (retval < 0) {
 			dbg ("sub driver rejected device");
@@ -996,11 +1000,13 @@
 	if (!num_ports) {
 		/* if this device type has a calc_num_ports function, call it */
 		if (type->calc_num_ports) {
-			if (type->owner)
-				__MOD_INC_USE_COUNT(type->owner);
+			if (!try_module_get(type->owner)) {
+				err ("module get failed, exiting");
+				kfree (serial);
+				return -EIO;
+			}
 			num_ports = type->calc_num_ports (serial);
-			if (type->owner)
-				__MOD_DEC_USE_COUNT(type->owner);
+			module_put(type->owner);
 		}
 		if (!num_ports)
 			num_ports = type->num_ports;
@@ -1110,11 +1116,12 @@
 
 	/* if this device type has an attach function, call it */
 	if (type->attach) {
-		if (type->owner)
-			__MOD_INC_USE_COUNT(type->owner);
+		if (!try_module_get(type->owner)) {
+			err ("module get failed, exiting");
+			goto probe_error;
+		}
 		retval = type->attach (serial);
-		if (type->owner)
-			__MOD_DEC_USE_COUNT(type->owner);
+		module_put(type->owner);
 		if (retval < 0)
 			goto probe_error;
 		if (retval > 0) {
diff -Nru a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h
--- a/drivers/usb/serial/usb-serial.h	Mon Dec  9 18:46:52 2002
+++ b/drivers/usb/serial/usb-serial.h	Mon Dec  9 18:46:52 2002
@@ -225,9 +225,9 @@
 	void (*throttle)	(struct usb_serial_port *port);
 	void (*unthrottle)	(struct usb_serial_port *port);
 
-	void (*read_int_callback)(struct urb *urb);
-	void (*read_bulk_callback)(struct urb *urb);
-	void (*write_bulk_callback)(struct urb *urb);
+	void (*read_int_callback)(struct urb *urb, struct pt_regs *regs);
+	void (*read_bulk_callback)(struct urb *urb, struct pt_regs *regs);
+	void (*write_bulk_callback)(struct urb *urb, struct pt_regs *regs);
 };
 
 extern int  usb_serial_register(struct usb_serial_device_type *new_device);
@@ -256,8 +256,8 @@
 extern void usb_serial_generic_close (struct usb_serial_port *port, struct file *filp);
 extern int usb_serial_generic_write_room (struct usb_serial_port *port);
 extern int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port);
-extern void usb_serial_generic_read_bulk_callback (struct urb *urb);
-extern void usb_serial_generic_write_bulk_callback (struct urb *urb);
+extern void usb_serial_generic_read_bulk_callback (struct urb *urb, struct pt_regs *regs);
+extern void usb_serial_generic_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
 extern void usb_serial_generic_shutdown (struct usb_serial *serial);
 extern int usb_serial_generic_register (int debug);
 extern void usb_serial_generic_deregister (void);
diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
--- a/drivers/usb/serial/visor.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/usb/serial/visor.c	Mon Dec  9 18:46:35 2002
@@ -173,8 +173,9 @@
 static void visor_shutdown	(struct usb_serial *serial);
 static int  visor_ioctl		(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
 static void visor_set_termios	(struct usb_serial_port *port, struct termios *old_termios);
-static void visor_write_bulk_callback	(struct urb *urb);
-static void visor_read_bulk_callback	(struct urb *urb);
+static void visor_write_bulk_callback	(struct urb *urb, struct pt_regs *regs);
+static void visor_read_bulk_callback	(struct urb *urb, struct pt_regs *regs);
+static void visor_read_int_callback	(struct urb *urb, struct pt_regs *regs);
 static int  clie_3_5_startup	(struct usb_serial *serial);
 
 
@@ -189,6 +190,7 @@
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID) },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID) },
 	{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
+	{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID) },
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) },
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID) },
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID) },
@@ -203,6 +205,7 @@
 
 static struct usb_device_id id_table_combined [] = {
 	{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
+	{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID) },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) },
 	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID) },
@@ -232,9 +235,9 @@
 /* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */
 static struct usb_serial_device_type handspring_device = {
 	.owner =		THIS_MODULE,
-	.name =			"Handspring Visor / Palm 4.0 / Clié 4.x",
+	.name =			"Handspring Visor / Treo / Palm 4.0 / Clié 4.x",
 	.id_table =		id_table,
-	.num_interrupt_in =	0,
+	.num_interrupt_in =	NUM_DONT_CARE,
 	.num_bulk_in =		2,
 	.num_bulk_out =		2,
 	.num_ports =		2,
@@ -252,6 +255,7 @@
 	.chars_in_buffer =	visor_chars_in_buffer,
 	.write_bulk_callback =	visor_write_bulk_callback,
 	.read_bulk_callback =	visor_read_bulk_callback,
+	.read_int_callback =	visor_read_int_callback,
 };
 
 /* device info for the Sony Clie OS version 3.5 */
@@ -320,9 +324,20 @@
 			   port->read_urb->transfer_buffer_length,
 			   visor_read_bulk_callback, port);
 	result = usb_submit_urb(port->read_urb, GFP_KERNEL);
-	if (result)
-		err("%s - failed submitting read urb, error %d", __FUNCTION__, result);
+	if (result) {
+		err("%s - failed submitting read urb, error %d",
+		    __FUNCTION__, result);
+		goto exit;
+	}
 	
+	if (port->interrupt_in_urb) {
+		dbg("%s - adding interrupt input for treo", __FUNCTION__);
+		result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
+		if (result)
+			err("%s - failed submitting interrupt urb, error %d",
+			    __FUNCTION__, result);
+	}
+exit:	
 	return result;
 }
 
@@ -358,6 +373,9 @@
 		}
 		/* shutdown our bulk read */
 		usb_unlink_urb (port->read_urb);
+
+		if (port->interrupt_in_urb)
+			usb_unlink_urb (port->interrupt_in_urb);
 	}
 	/* Uncomment the following line if you want to see some statistics in your syslog */
 	/* info ("Bytes In = %d  Bytes Out = %d", bytes_in, bytes_out); */
@@ -449,7 +467,7 @@
 }
 
 
-static void visor_write_bulk_callback (struct urb *urb)
+static void visor_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 
@@ -470,7 +488,7 @@
 }
 
 
-static void visor_read_bulk_callback (struct urb *urb)
+static void visor_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
@@ -523,6 +541,43 @@
 	return;
 }
 
+static void visor_read_int_callback (struct urb *urb, struct pt_regs *regs)
+{
+	int result;
+
+	switch (urb->status) {
+	case 0:
+		/* success */
+		break;
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+		/* this urb is terminated, clean up */
+		dbg("%s - urb shutting down with status: %d",
+		    __FUNCTION__, urb->status);
+		return;
+	default:
+		dbg("%s - nonzero urb status received: %d",
+		    __FUNCTION__, urb->status);
+		goto exit;
+	}
+
+	/*
+	 * This information is still unknown what it can be used for.
+	 * If anyone has an idea, please let the author know...
+	 *
+	 * Rumor has it this endpoint is used to notify when data
+	 * is ready to be read from the bulk ones.
+	 */
+	usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length,
+			       urb->transfer_buffer);
+
+exit:
+	result = usb_submit_urb (urb, GFP_ATOMIC);
+	if (result)
+		err("%s - Error %d submitting interrupt urb",
+		    __FUNCTION__, result);
+}
 
 static void visor_throttle (struct usb_serial_port *port)
 {
diff -Nru a/drivers/usb/serial/visor.h b/drivers/usb/serial/visor.h
--- a/drivers/usb/serial/visor.h	Mon Dec  9 18:46:35 2002
+++ b/drivers/usb/serial/visor.h	Mon Dec  9 18:46:35 2002
@@ -19,6 +19,7 @@
 
 #define HANDSPRING_VENDOR_ID		0x082d
 #define HANDSPRING_VISOR_ID		0x0100
+#define HANDSPRING_TREO_ID		0x0200
 
 #define PALM_VENDOR_ID			0x0830
 #define PALM_M500_ID			0x0001
diff -Nru a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
--- a/drivers/usb/serial/whiteheat.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/usb/serial/whiteheat.c	Mon Dec  9 18:46:35 2002
@@ -150,8 +150,8 @@
 static int  whiteheat_chars_in_buffer	(struct usb_serial_port *port);
 static void whiteheat_throttle		(struct usb_serial_port *port);
 static void whiteheat_unthrottle	(struct usb_serial_port *port);
-static void whiteheat_read_callback	(struct urb *urb);
-static void whiteheat_write_callback	(struct urb *urb);
+static void whiteheat_read_callback	(struct urb *urb, struct pt_regs *regs);
+static void whiteheat_write_callback	(struct urb *urb, struct pt_regs *regs);
 
 static struct usb_serial_device_type whiteheat_fake_device = {
 	.owner =		THIS_MODULE,
@@ -225,8 +225,8 @@
 /* local function prototypes */
 static int start_command_port(struct usb_serial *serial);
 static void stop_command_port(struct usb_serial *serial);
-static void command_port_write_callback(struct urb *urb);
-static void command_port_read_callback(struct urb *urb);
+static void command_port_write_callback(struct urb *urb, struct pt_regs *regs);
+static void command_port_read_callback(struct urb *urb, struct pt_regs *regs);
 
 static int start_port_read(struct usb_serial_port *port);
 static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb, struct list_head *head);
@@ -957,7 +957,7 @@
 /*****************************************************************************
  * Connect Tech's White Heat callback routines
  *****************************************************************************/
-static void command_port_write_callback (struct urb *urb)
+static void command_port_write_callback (struct urb *urb, struct pt_regs *regs)
 {
 	dbg("%s", __FUNCTION__);
 
@@ -972,7 +972,7 @@
 }
 
 
-static void command_port_read_callback (struct urb *urb)
+static void command_port_read_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *command_port = (struct usb_serial_port *)urb->context;
 	struct usb_serial *serial = get_usb_serial (command_port, __FUNCTION__);
@@ -1028,7 +1028,7 @@
 }
 
 
-static void whiteheat_read_callback(struct urb *urb)
+static void whiteheat_read_callback(struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
@@ -1079,7 +1079,7 @@
 }
 
 
-static void whiteheat_write_callback(struct urb *urb)
+static void whiteheat_write_callback(struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
--- a/drivers/usb/storage/transport.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/usb/storage/transport.c	Mon Dec  9 18:46:36 2002
@@ -401,7 +401,7 @@
 /* This is the completion handler which will wake us up when an URB
  * completes.
  */
-static void usb_stor_blocking_completion(struct urb *urb)
+static void usb_stor_blocking_completion(struct urb *urb, struct pt_regs *regs)
 {
 	struct completion *urb_done_ptr = (struct completion *)urb->context;
 
@@ -503,6 +503,35 @@
 	return status;
 }
 
+/* This is our function to submit interrupt URBs with enough control
+ * to make aborts/resets/timeouts work
+ *
+ * This routine always uses us->recv_intr_pipe as the pipe and
+ * us->ep_bInterval as the interrupt interval.
+ */
+int usb_stor_interrupt_msg(struct us_data *us, void *data,
+			unsigned int len, unsigned int *act_len)
+{
+	unsigned int pipe = us->recv_intr_pipe;
+	unsigned int maxp;
+	int status;
+
+	/* calculate the max packet size */
+	maxp = usb_maxpacket(us->pusb_dev, pipe, usb_pipeout(pipe));
+	if (maxp > len)
+		maxp = len;
+
+	/* fill and submit the URB */
+	usb_fill_int_urb(us->current_urb, us->pusb_dev, pipe, data,
+			maxp, usb_stor_blocking_completion, NULL,
+			us->ep_bInterval);
+	status = usb_stor_msg_common(us);
+
+	/* store the actual length of the data transferred */
+	*act_len = us->current_urb->actual_length;
+	return status;
+}
+
 /* This is a version of usb_clear_halt() that doesn't read the status from
  * the device -- this is because some devices crash their internal firmware
  * when the status is requested after a halt.
@@ -532,8 +561,6 @@
 	if (result < 0)
 		return result;
 
-	printk(KERN_ERR "usb_stor_clear_halt() WORKED!\n");
-
 	/* reset the toggles and endpoint flags */
 	usb_endpoint_running(us->pusb_dev, usb_pipeendpoint(pipe),
 		usb_pipeout(pipe));
@@ -629,6 +656,29 @@
 }
 
 /*
+ * Receive one buffer via interrupt transfer
+ *
+ * This function does basically the same thing as usb_stor_interrupt_msg()
+ * above, except that return codes are USB_STOR_XFER_xxx rather than the
+ * urb status.
+ */
+int usb_stor_intr_transfer(struct us_data *us, void *buf,
+		unsigned int length, unsigned int *act_len)
+{
+	int result;
+	unsigned int partial;
+
+	/* transfer the data */
+	US_DEBUGP("usb_stor_intr_transfer(): xfer %u bytes\n", length);
+	result = usb_stor_interrupt_msg(us, buf, length, &partial);
+	if (act_len)
+		*act_len = partial;
+
+	return interpret_urb_result(us, us->recv_intr_pipe,
+			length, result, partial);
+}
+
+/*
  * Transfer one buffer via bulk transfer
  *
  * This function does basically the same thing as usb_stor_bulk_msg()
@@ -949,7 +999,7 @@
 	host = us->srb->host;
 	scsi_unlock(host);
 
-	/* If the state machine is blocked waiting for an URB or an IRQ,
+	/* If the state machine is blocked waiting for an URB,
 	 * let's wake it up */
 
 	/* If we have an URB pending, cancel it.  The test_and_clear_bit()
@@ -966,12 +1016,6 @@
 		usb_sg_cancel(us->current_sg);
 	}
 
-	/* If we are waiting for an IRQ, simulate it */
-	if (test_bit(US_FLIDX_IP_WANTED, &us->flags)) {
-		US_DEBUGP("-- simulating missing IRQ\n");
-		usb_stor_CBI_irq(us->irq_urb);
-	}
-
 	/* Wait for the aborted command to finish */
 	wait_for_completion(&us->notify);
 
@@ -983,94 +1027,11 @@
  * Control/Bulk/Interrupt transport
  */
 
-/* The interrupt handler for CBI devices */
-void usb_stor_CBI_irq(struct urb *urb)
-{
-	struct us_data *us = (struct us_data *)urb->context;
-	int status;
-
-	US_DEBUGP("USB IRQ received for device on host %d\n", us->host_no);
-	US_DEBUGP("-- IRQ data length is %d\n", urb->actual_length);
-	US_DEBUGP("-- IRQ state is %d\n", urb->status);
-	US_DEBUGP("-- Interrupt Status (0x%x, 0x%x)\n",
-			us->irqbuf[0], us->irqbuf[1]);
-
-	/* has the current command been aborted? */
-	if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
-
-		/* was this a wanted interrupt? */
-		if (!test_and_clear_bit(US_FLIDX_IP_WANTED, &us->flags)) {
-			US_DEBUGP("ERROR: Unwanted interrupt received!\n");
-			goto exit;
-		}
-		US_DEBUGP("-- command aborted\n");
-
-		/* wake up the command thread */
-		up(&us->ip_waitq);
-		goto exit;
-	}
-
-	/* is the device removed? */
-	if (urb->status == -ENOENT) {
-		US_DEBUGP("-- device has been removed\n");
-
-		/* was this a wanted interrupt? */
-		if (!test_and_clear_bit(US_FLIDX_IP_WANTED, &us->flags))
-			return;
-
-		/* indicate a transport error -- this is the best we can do */
-		us->irqdata[0] = us->irqdata[1] = 0xFF;
-
-		/* wake up the command thread */
-		up(&us->ip_waitq);
-		return;
-	}
-
-	/* reject improper IRQs */
-	if (urb->actual_length != 2) {
-		US_DEBUGP("-- IRQ too short\n");
-		goto exit;
-	}
-
-	/* was this a command-completion interrupt? */
-	if (us->irqbuf[0] && (us->subclass != US_SC_UFI)) {
-		US_DEBUGP("-- not a command-completion IRQ\n");
-		goto exit;
-	}
-
-	/* was this a wanted interrupt? */
-	if (!test_and_clear_bit(US_FLIDX_IP_WANTED, &us->flags)) {
-		US_DEBUGP("ERROR: Unwanted interrupt received!\n");
-		goto exit;
-	}
-		
-	/* copy the valid data */
-	us->irqdata[0] = us->irqbuf[0];
-	us->irqdata[1] = us->irqbuf[1];
-
-	/* wake up the command thread */
-	up(&(us->ip_waitq));
-
-exit:
-	/* resubmit the urb */
-	status = usb_submit_urb (urb, GFP_ATOMIC);
-	if (status)
-		err ("%s - usb_submit_urb failed with result %d",
-		     __FUNCTION__, status);
-}
-
 int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us)
 {
 	unsigned int transfer_length = usb_stor_transfer_length(srb);
 	int result;
 
-	/* re-initialize the mutex so that we avoid any races with
-	 * early/late IRQs from previous commands */
-	init_MUTEX_LOCKED(&(us->ip_waitq));
-
-	/* Set up for status notification */
-	set_bit(US_FLIDX_IP_WANTED, &us->flags);
-
 	/* COMMAND STAGE */
 	/* let's send the command via the control pipe */
 	result = usb_stor_ctrl_transfer(us, us->send_ctrl_pipe,
@@ -1081,8 +1042,6 @@
 	/* check the return code for the command */
 	US_DEBUGP("Call to usb_stor_ctrl_transfer() returned %d\n", result);
 	if (result != USB_STOR_XFER_GOOD) {
-		/* Reset flag for status notification */
-		clear_bit(US_FLIDX_IP_WANTED, &us->flags);
 		/* Uh oh... serious problem here */
 		return USB_STOR_TRANSPORT_ERROR;
 	}
@@ -1095,25 +1054,17 @@
 		result = usb_stor_bulk_transfer_srb(us, pipe, srb,
 					transfer_length);
 		US_DEBUGP("CBI data stage result is 0x%x\n", result);
-		if (result == USB_STOR_XFER_ERROR) {
-			clear_bit(US_FLIDX_IP_WANTED, &us->flags);
+		if (result == USB_STOR_XFER_ERROR)
 			return USB_STOR_TRANSPORT_ERROR;
-		}
 	}
 
 	/* STATUS STAGE */
-
-	/* go to sleep until we get this interrupt */
-	down(&(us->ip_waitq));
-
-	/* has the current command been aborted? */
-	if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
-		US_DEBUGP("CBI interrupt aborted\n");
-		return USB_STOR_TRANSPORT_ERROR;
-	}
-
+	result = usb_stor_intr_transfer(us, us->irqdata,
+					sizeof(us->irqdata), NULL);
 	US_DEBUGP("Got interrupt data (0x%x, 0x%x)\n", 
 			us->irqdata[0], us->irqdata[1]);
+	if (result != USB_STOR_XFER_GOOD)
+		return USB_STOR_TRANSPORT_ERROR;
 
 	/* UFI gives us ASC and ASCQ, like a request sense
 	 *
diff -Nru a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h
--- a/drivers/usb/storage/transport.h	Mon Dec  9 18:46:36 2002
+++ b/drivers/usb/storage/transport.h	Mon Dec  9 18:46:36 2002
@@ -145,7 +145,6 @@
 
 #define US_CBI_ADSC		0
 
-extern void usb_stor_CBI_irq(struct urb*);
 extern int usb_stor_CBI_transport(Scsi_Cmnd*, struct us_data*);
 
 extern int usb_stor_CB_transport(Scsi_Cmnd*, struct us_data*);
@@ -164,11 +163,15 @@
 extern int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
 		u8 request, u8 requesttype, u16 value, u16 index,
 		void *data, u16 size);
+extern int usb_stor_interrupt_msg(struct us_data *us, void *data,
+		unsigned int len, unsigned int *act_len);
 
 extern int usb_stor_clear_halt(struct us_data*, unsigned int pipe);
 extern int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe,
 		u8 request, u8 requesttype, u16 value, u16 index,
 		void *data, u16 size);
+extern int usb_stor_intr_transfer(struct us_data *us, void *buf,
+		unsigned int length, unsigned int *act_len);
 extern int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe,
 		void *buf, unsigned int length, unsigned int *act_len);
 extern int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
diff -Nru a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
--- a/drivers/usb/storage/usb.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/usb/storage/usb.c	Mon Dec  9 18:46:35 2002
@@ -174,7 +174,7 @@
 	.productName = product_name,	\
 	.useProtocol = use_protocol,	\
 	.useTransport = use_transport,	\
-	initFunction : init_function,	\
+	.initFunction = init_function,	\
 	.flags = Flags, \
 }
 
@@ -477,24 +477,20 @@
 	return 0;
 }	
 
-/* Set up the URB, the usb_ctrlrequest, and the IRQ pipe and handler.
+/* Set up the URB and the usb_ctrlrequest.
  * ss->dev_semaphore must already be locked.
  * Note that this function assumes that all the data in the us_data
- * strucuture is current.  This includes the ep_int field, which gives us
- * the endpoint for the interrupt.
+ * structure is current.
  * Returns non-zero on failure, zero on success
  */ 
 static int usb_stor_allocate_urbs(struct us_data *ss)
 {
-	unsigned int pipe;
-	int maxp;
-	int result;
-
 	/* calculate and store the pipe values */
-	ss->send_bulk_pipe = usb_sndbulkpipe(ss->pusb_dev, ss->ep_out);
-	ss->recv_bulk_pipe = usb_rcvbulkpipe(ss->pusb_dev, ss->ep_in);
 	ss->send_ctrl_pipe = usb_sndctrlpipe(ss->pusb_dev, 0);
 	ss->recv_ctrl_pipe = usb_rcvctrlpipe(ss->pusb_dev, 0);
+	ss->send_bulk_pipe = usb_sndbulkpipe(ss->pusb_dev, ss->ep_out);
+	ss->recv_bulk_pipe = usb_rcvbulkpipe(ss->pusb_dev, ss->ep_in);
+	ss->recv_intr_pipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int);
 
 	/* allocate the usb_ctrlrequest for control packets */
 	US_DEBUGP("Allocating usb_ctrlrequest\n");
@@ -519,45 +515,6 @@
 		return 5;
 	}
 
-	/* allocate the IRQ URB, if it is needed */
-	if (ss->protocol == US_PR_CBI) {
-		US_DEBUGP("Allocating IRQ for CBI transport\n");
-
-		/* lock access to the data structure */
-		down(&(ss->irq_urb_sem));
-
-		/* allocate the URB */
-		ss->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
-		if (!ss->irq_urb) {
-			up(&(ss->irq_urb_sem));
-			US_DEBUGP("couldn't allocate interrupt URB");
-			return 3;
-		}
-
-		/* calculate the pipe and max packet size */
-		pipe = usb_rcvintpipe(ss->pusb_dev,
-		    ss->ep_int->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
-		maxp = usb_maxpacket(ss->pusb_dev, pipe, usb_pipeout(pipe));
-		if (maxp > sizeof(ss->irqbuf))
-			maxp = sizeof(ss->irqbuf);
-
-		/* fill in the URB with our data */
-		usb_fill_int_urb(ss->irq_urb, ss->pusb_dev, pipe, ss->irqbuf,
-			maxp, usb_stor_CBI_irq, ss, ss->ep_int->bInterval); 
-
-		/* submit the URB for processing */
-		result = usb_submit_urb(ss->irq_urb, GFP_KERNEL);
-		US_DEBUGP("usb_submit_urb() returns %d\n", result);
-		if (result) {
-			up(&(ss->irq_urb_sem));
-			return 4;
-		}
-
-		/* unlock the data structure */
-		up(&(ss->irq_urb_sem));
-
-	} /* ss->protocol == US_PR_CBI */
-
 	return 0;	/* success */
 }
 
@@ -568,17 +525,6 @@
 {
 	int result;
 
-	/* release the IRQ, if we have one */
-	down(&(ss->irq_urb_sem));
-	if (ss->irq_urb) {
-		US_DEBUGP("-- releasing irq URB\n");
-		result = usb_unlink_urb(ss->irq_urb);
-		US_DEBUGP("-- usb_unlink_urb() returned %d\n", result);
-		usb_free_urb(ss->irq_urb);
-		ss->irq_urb = NULL;
-	}
-	up(&(ss->irq_urb_sem));
-
 	/* free the scatter-gather request block */
 	if (ss->current_sg) {
 		kfree(ss->current_sg);
@@ -782,7 +728,9 @@
 			USB_ENDPOINT_NUMBER_MASK;
 		ss->ep_out = ep_out->bEndpointAddress & 
 			USB_ENDPOINT_NUMBER_MASK;
-		ss->ep_int = ep_int;
+		ss->ep_int = ep_int->bEndpointAddress & 
+			USB_ENDPOINT_NUMBER_MASK;
+		ss->ep_bInterval = ep_int->bInterval;
 
 		/* allocate the URB, the usb_ctrlrequest, and the IRQ URB */
 		if (usb_stor_allocate_urbs(ss))
@@ -810,8 +758,6 @@
 
 		/* Initialize the mutexes only when the struct is new */
 		init_completion(&(ss->notify));
-		init_MUTEX_LOCKED(&(ss->ip_waitq));
-		init_MUTEX(&(ss->irq_urb_sem));
 		init_MUTEX_LOCKED(&(ss->dev_semaphore));
 
 		/* copy over the subclass and protocol data */
@@ -825,7 +771,9 @@
 			USB_ENDPOINT_NUMBER_MASK;
 		ss->ep_out = ep_out->bEndpointAddress & 
 			USB_ENDPOINT_NUMBER_MASK;
-		ss->ep_int = ep_int;
+		ss->ep_int = ep_int->bEndpointAddress & 
+			USB_ENDPOINT_NUMBER_MASK;
+		ss->ep_bInterval = ep_int->bInterval;
 
 		/* establish the connection to the new device */
 		ss->ifnum = ifnum;
diff -Nru a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
--- a/drivers/usb/storage/usb.h	Mon Dec  9 18:46:50 2002
+++ b/drivers/usb/storage/usb.h	Mon Dec  9 18:46:50 2002
@@ -105,7 +105,6 @@
 #define US_FL_FIX_CAPACITY    0x00000080 /* READ CAPACITY response too big  */
 
 #define US_FL_DEV_ATTACHED    0x00010000 /* is the device attached?	    */
-#define US_FLIDX_IP_WANTED   17  /* 0x00020000	is an IRQ expected?	    */
 #define US_FLIDX_CAN_CANCEL  18  /* 0x00040000  okay to cancel current_urb? */
 #define US_FLIDX_CANCEL_SG   19  /* 0x00080000	okay to cancel current_sg?  */
 
@@ -139,6 +138,7 @@
 	unsigned int		recv_bulk_pipe;
 	unsigned int		send_ctrl_pipe;
 	unsigned int		recv_ctrl_pipe;
+	unsigned int		recv_intr_pipe;
 
 	/* information about the device -- always good */
 	char			vendor[USB_STOR_STRING_LEN];
@@ -154,7 +154,8 @@
 	u8			ifnum;		 /* interface number   */
 	u8			ep_in;		 /* bulk in endpoint   */
 	u8			ep_out;		 /* bulk out endpoint  */
-	struct usb_endpoint_descriptor *ep_int;	 /* interrupt endpoint */ 
+	u8			ep_int;		 /* interrupt endpoint */ 
+	u8			ep_bInterval;	 /* interrupt interval */ 
 
 	/* function pointers for this device */
 	trans_cmnd		transport;	 /* transport function	   */
@@ -173,13 +174,7 @@
 	int			pid;		 /* control thread	 */
 	atomic_t		sm_state;	 /* what we are doing	 */
 
-	/* interrupt info for CBI devices -- only good if attached */
-	struct semaphore	ip_waitq;	 /* for CBI interrupts	 */
-
 	/* interrupt communications data */
-	struct semaphore	irq_urb_sem;	 /* to protect irq_urb	 */
-	struct urb		*irq_urb;	 /* for USB int requests */
-	unsigned char		irqbuf[2];	 /* buffer for USB IRQ	 */
 	unsigned char		irqdata[2];	 /* data from USB IRQ	 */
 
 	/* control and bulk communications data */
diff -Nru a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
--- a/drivers/usb/usb-skeleton.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/usb/usb-skeleton.c	Mon Dec  9 18:46:37 2002
@@ -137,7 +137,7 @@
 static int skel_probe		(struct usb_interface *intf, const struct usb_device_id *id);
 static void skel_disconnect	(struct usb_interface *intf);
 
-static void skel_write_bulk_callback	(struct urb *urb);
+static void skel_write_bulk_callback	(struct urb *urb, struct pt_regs *regs);
 
 
 /* array of pointers to our devices that are currently connected */
@@ -487,7 +487,7 @@
 /**
  *	skel_write_bulk_callback
  */
-static void skel_write_bulk_callback (struct urb *urb)
+static void skel_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_skel *dev = (struct usb_skel *)urb->context;
 
diff -Nru a/drivers/video/68328fb.c b/drivers/video/68328fb.c
--- a/drivers/video/68328fb.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/video/68328fb.c	Mon Dec  9 18:46:50 2002
@@ -26,7 +26,6 @@
  * for more details.
  */
 
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -41,81 +40,28 @@
 #include <asm/irq.h>
 #include <asm/pgtable.h>
 #include <linux/fb.h>
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-
 
 #define arraysize(x)    (sizeof(x)/sizeof(*(x)))
 
-struct mc68328_fb_par {
-   int xres;
-   int yres;
-   int bpp;
-};
-
-static struct mc68328_fb_par current_par;
-
-static int current_par_valid = 0;
-static int currcon = 0;
-
-static struct display disp[MAX_NR_CONSOLES];
 static struct fb_info fb_info;
 
-static int node;        /* node of the /dev/fb?current file */
-
-
-   /*
-    *    Switch for Chipset Independency
-    */
-
-static struct fb_hwswitch {
-
-   /* Initialisation */
-
-   int (*init)(void);
-
-   /* Display Control */
-
-   int (*encode_fix)(struct fb_fix_screeninfo *fix, struct mc68328_fb_par *par);
-   int (*decode_var)(struct fb_var_screeninfo *var, struct mc68328_fb_par *par);
-   int (*encode_var)(struct fb_var_screeninfo *var, struct mc68328_fb_par *par);
-   int (*getcolreg)(u_int regno, u_int *red, u_int *green, u_int *blue,
-                    u_int *transp);
-   int (*setcolreg)(u_int regno, u_int red, u_int green, u_int blue,
-                    u_int transp);
-   void (*blank)(int blank);
-} *fbhw;
-
-
-   /*
-    *    Frame Buffer Name
-    */
-
-static char mc68328_fb_name[16] = "mc68328";
-
-
    /*
     *    mc68328vision Graphics Board
     */
 
 #define CYBER8_WIDTH 1152
 #define CYBER8_HEIGHT 886
-#define CYBER8_PIXCLOCK 12500    /* ++Geert: Just a guess */
+#define CYBER8_PIXCLOCK 12500	/* ++Geert: Just a guess */
 
 #define CYBER16_WIDTH 800
 #define CYBER16_HEIGHT 600
-#define CYBER16_PIXCLOCK 25000   /* ++Geert: Just a guess */
+#define CYBER16_PIXCLOCK 25000	/* ++Geert: Just a guess */
 
 #define PALM_WIDTH 160
 #define PALM_HEIGHT 160
 
-
 /*static int mc68328Key = 0;
 static u_char mc68328_colour_table [256][4];*/
-static unsigned long mc68328Mem;
-static unsigned long mc68328Size;
-
 
    /*
     *    Predefined Video Mode Names
@@ -123,34 +69,37 @@
 
 static char *mc68328_fb_modenames[] = {
 
-   /*
-    *    Autodetect (Default) Video Mode
-    */
-
-   "default",
-
-   /*
-    *    Predefined Video Modes
-    */
-    
-   "Palm",            /* Palm Pilot devices, 1.0 and higher */
-   "Palm Grey",            /* Palm Pilot devices, 1.0 and higher */
-
-   /*
-    *    Dummy Video Modes
-    */
-
-   "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
-   "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
-   "dummy", "dummy", "dummy", "dummy",
-
-   /*
-    *    User Defined Video Modes
-    *
-    *    This doesn't work yet!!
-    */
+	/*
+	 *    Autodetect (Default) Video Mode
+	 */
+
+	"default",
+
+	/*
+	 *    Predefined Video Modes
+	 */
+
+	"Palm",			/* Palm Pilot devices, 1.0 and higher */
+	"Palm Grey",		/* Palm Pilot devices, 1.0 and higher */
+
+	/*
+	 *    Dummy Video Modes
+	 */
+
+	"dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
+	    "dummy",
+	"dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
+	    "dummy",
+	"dummy", "dummy", "dummy", "dummy",
+
+	/*
+	 *    User Defined Video Modes
+	 *
+	 *    This doesn't work yet!!
+	 */
 
-   "user0", "user1", "user2", "user3", "user4", "user5", "user6", "user7"
+	"user0", "user1", "user2", "user3", "user4", "user5", "user6",
+	    "user7"
 };
 
 
@@ -160,68 +109,70 @@
 
 static struct fb_var_screeninfo mc68328_fb_predefined[] = {
 
-   /*
-    *    Autodetect (Default) Video Mode
-    */
-
-   { 0, },
-
-   /*
-    *    Predefined Video Modes
-    */
-    
-   {
-      /* Palm */
-      PALM_WIDTH, PALM_HEIGHT, PALM_WIDTH, PALM_HEIGHT, 
-      0, 0, 
-      1, -1,
-      {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 0, 0},
-      0, 0, 
-      -1, -1, /* phys height, width */
-      FB_ACCEL_NONE, 
-      0, 0, 0, 0, 0, 0, 0, /* timing */
-      0, /* sync */
-      FB_VMODE_NONINTERLACED
-   },
-   {
-      /* Palm Grey */
-      PALM_WIDTH, PALM_HEIGHT, PALM_WIDTH, PALM_HEIGHT, 
-      0, 0, 
-      2, -1,
-      {0, 2, 0}, {0, 2, 0}, {0, 2, 0}, {0, 0, 0},
-      0, 0, 
-      -1, -1, /* phys height, width */
-      FB_ACCEL_NONE, 
-      0, 0, 0, 0, 0, 0, 0, /* timing */
-      0, /* sync */
-      FB_VMODE_NONINTERLACED
-   },
-
-   /*
-    *    Dummy Video Modes
-    */
-
-   { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, },
-   { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, },
-   { 0, }, { 0, },
+	/*
+	 *    Autodetect (Default) Video Mode
+	 */
+
+	{0,},
+
+	/*
+	 *    Predefined Video Modes
+	 */
+
+	{
+	 /* Palm */
+	 PALM_WIDTH, PALM_HEIGHT, PALM_WIDTH, PALM_HEIGHT,
+	 0, 0,
+	 1, -1,
+	 {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 0, 0},
+	 0, 0,
+	 -1, -1,		/* phys height, width */
+	 FB_ACCEL_NONE,
+	 0, 0, 0, 0, 0, 0, 0,	/* timing */
+	 0,			/* sync */
+	 FB_VMODE_NONINTERLACED},
+	{
+	 /* Palm Grey */
+	 PALM_WIDTH, PALM_HEIGHT, PALM_WIDTH, PALM_HEIGHT,
+	 0, 0,
+	 2, -1,
+	 {0, 2, 0}, {0, 2, 0}, {0, 2, 0}, {0, 0, 0},
+	 0, 0,
+	 -1, -1,		/* phys height, width */
+	 FB_ACCEL_NONE,
+	 0, 0, 0, 0, 0, 0, 0,	/* timing */
+	 0,			/* sync */
+	 FB_VMODE_NONINTERLACED},
+
+	/*
+	 *    Dummy Video Modes
+	 */
+
+	{0,}, {0,}, {0,}, {0,}, {0,}, {0,}, {0,}, {0,}, {0,},
+	{0,}, {0,}, {0,}, {0,}, {0,}, {0,}, {0,}, {0,}, {0,},
+	{0,}, {0,},
+
+	/*
+	 *    User Defined Video Modes
+	 */
 
-   /*
-    *    User Defined Video Modes
-    */
-
-   { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }
+	{0,}, {0,}, {0,}, {0,}, {0,}, {0,}, {0,}, {0,}
 };
 
+static struct fb_fix_screeninfo mc68328_fix __initdata = {
+	.id		= "mc68328";
+	.smem_len 	= 160 * 160 /8;
+	.type 		= FB_TYPE_PACKED_PIXELS;
+	.accel 		= FB_ACCEL_NONE;
+};
 
 #define NUM_TOTAL_MODES    arraysize(mc68328_fb_predefined)
 #define NUM_PREDEF_MODES   (3)
 
-
 static int mc68328fb_inverse = 0;
 static int mc68328fb_mode = 0;
 static int mc68328fbCursorMode = 0;
 
-
    /*
     *    Some default modes
     */
@@ -229,34 +180,14 @@
 #define PALM_DEFMODE     (1)
 #define CYBER16_DEFMODE    (2)
 
-
    /*
     *    Interface used by the world
     */
-
-static int mc68328_fb_get_fix(struct fb_fix_screeninfo *fix, int con,
-		struct fb_info *info);
-static int mc68328_fb_get_var(struct fb_var_screeninfo *var, int con,
-		struct fb_info *info);
-static int mc68328_fb_set_var(struct fb_var_screeninfo *var, int con,
-		struct fb_info *info);
-static int mc68328_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-		struct fb_info *info);
-static int mc68328_fb_pan_display(struct fb_var_screeninfo *var, int con,
-		struct fb_info *info);
-static int mc68328_fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-		u_long arg, int con, struct fb_info *info);
-
-
-   /*
-    *    Interface to the low level console driver
-    */
-
 int mc68328_fb_init(void);
-static int mc68328fb_switch(int con, struct fb_info *info);
-static int mc68328fb_updatevar(int con);
-static void mc68328fb_blank(int blank);
 
+static int mc68328fb_setcolreg(u_int regno, u_int red, u_int green,
+			       u_int blue, u_int transp);
+static void mc68328fb_blank(int blank, struct fb_info *info);
 
    /*
     *    Accelerated Functions used by the low level console driver
@@ -264,239 +195,57 @@
 
 void mc68328_WaitQueue(u_short fifo);
 void mc68328_WaitBlit(void);
-void mc68328_BitBLT(u_short curx, u_short cury, u_short destx, u_short desty,
-                  u_short width, u_short height, u_short mode);
+void mc68328_BitBLT(u_short curx, u_short cury, u_short destx,
+		    u_short desty, u_short width, u_short height,
+		    u_short mode);
 void mc68328_RectFill(u_short x, u_short y, u_short width, u_short height,
-                    u_short mode, u_short color);
+		      u_short mode, u_short color);
 void mc68328_MoveCursor(u_short x, u_short y);
 
-
-   /*
-    *   Hardware Specific Routines
-    */
-
-static int mc68328_init(void);
-static int mc68328_encode_fix(struct fb_fix_screeninfo *fix,
-                          struct mc68328_fb_par *par);
-static int mc68328_decode_var(struct fb_var_screeninfo *var,
-                          struct mc68328_fb_par *par);
-static int mc68328_encode_var(struct fb_var_screeninfo *var,
-                          struct mc68328_fb_par *par);
-static int mc68328_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-                         u_int *transp);
-static int mc68328_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-                         u_int transp);
-static void mc68328_blank(int blank);
-
-
    /*
     *    Internal routines
     */
-
-static void mc68328_fb_get_par(struct mc68328_fb_par *par);
-static void mc68328_fb_set_par(struct mc68328_fb_par *par);
-static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive);
-static struct fb_cmap *get_default_colormap(int bpp);
-static void memcpy_fs(int fsfromto, void *to, void *from, int len);
-static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto);
-static int alloc_cmap(struct fb_cmap *cmap, int len, int transp);
-static void mc68328_fb_set_disp(int con, struct fb_info *info);
 static int get_video_mode(const char *name);
 
-
-/* -------------------- Hardware specific routines -------------------------- */
-
-
-   /*
-    *    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.
-    */
-
-static int mc68328_init(void)
-{
-	/*int i;
-	char size;
-	volatile u_long *CursorBase;
-	unsigned long board_addr;
-	struct ConfigDev *cd;*/
-
-	if (mc68328fb_mode == -1)
-		mc68328fb_mode = PALM_DEFMODE;
-
-	mc68328Mem = (*(volatile unsigned long*)0xFFFFFA00);
-	/*kernel_map (board_addr + 0x01400000, 0x00400000,*/
-	mc68328Size = 160*160/8;
-
-	return (0);
-}
-
-
-   /*
-    *    This function should fill in the `fix' structure based on the
-    *    values in the `par' structure.
-    */
-
-static int mc68328_encode_fix(struct fb_fix_screeninfo *fix,
-                          struct mc68328_fb_par *par)
-{
-   int i;
-
-   strcpy(fix->id, mc68328_fb_name);
-   fix->smem_start = mc68328Mem;
-   fix->smem_len = mc68328Size;
-
-   fix->type = FB_TYPE_PACKED_PIXELS;
-   fix->type_aux = 0;
-   if (par->bpp == 1)
-      fix->visual = FB_VISUAL_MONO01;
-   else
-      fix->visual = FB_VISUAL_DIRECTCOLOR;
-
-   fix->xpanstep = 0;
-   fix->ypanstep = 0;
-   fix->ywrapstep = 0;
-
-   for (i = 0; i < arraysize(fix->reserved); i++)
-      fix->reserved[i] = 0;
-
-   fix->accel = FB_ACCEL_NONE;
-
-   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.
-    */
-
-static int mc68328_decode_var(struct fb_var_screeninfo *var,
-                          struct mc68328_fb_par *par)
-{
-   par->xres = PALM_WIDTH;
-   par->yres = PALM_HEIGHT;
-   par->bpp = 1;
-   return(0);
-}
-
-
-   /*
-    *    Fill the `var' structure based on the values in `par' and maybe
-    *    other values read out of the hardware.
-    */
-
-static int mc68328_encode_var(struct fb_var_screeninfo *var,
-                          struct mc68328_fb_par *par)
-{
-   int i;
-
-   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 = -1;
-
-   var->red.offset = 0;
-   var->red.length = par->bpp;
-   var->red.msb_right = 0;
-   var->blue = var->green = var->red;
-
-   var->transp.offset = 0;
-   var->transp.length = 0;
-   var->transp.msb_right = 0;
-
-   var->nonstd = 0;
-   var->activate = 0;
-
-   var->height = -1;
-   var->width = -1;
-   var->vmode = FB_VMODE_NONINTERLACED;
-
-   /* Dummy values */
-
-   var->pixclock = 0;
-   var->sync = 0;
-   var->left_margin = 0;
-   var->right_margin = 0;
-   var->upper_margin = 0;
-   var->lower_margin = 0;
-   var->hsync_len = 0;
-   var->vsync_len = 0;
-
-   for (i = 0; i < arraysize(var->reserved); i++)
-      var->reserved[i] = 0;
-
-   return(0);
-}
-
-
    /*
     *    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 mc68328_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-                         u_int transp)
+static int mc68328fb_setcolreg(u_int regno, u_int red, u_int green,
+			       u_int blue, u_int transp)
 {
 	return 1;
 #if 0
-if (regno > 255)
-  return (1);
+	if (regno > 255)
+		return (1);
 
-*(mc68328Regs + 0x3c8) = (char)regno;
-mc68328_colour_table [regno][0] = red & 0xff;
-mc68328_colour_table [regno][1] = green & 0xff;
-mc68328_colour_table [regno][2] = blue & 0xff;
-mc68328_colour_table [regno][3] = transp;
-
-*(mc68328Regs + 0x3c9) = (red & 0xff) >> 2;
-*(mc68328Regs + 0x3c9) = (green & 0xff) >> 2;
-*(mc68328Regs + 0x3c9) = (blue & 0xff) >> 2;
+	*(mc68328Regs + 0x3c8) = (char) regno;
+	mc68328_colour_table[regno][0] = red & 0xff;
+	mc68328_colour_table[regno][1] = green & 0xff;
+	mc68328_colour_table[regno][2] = blue & 0xff;
+	mc68328_colour_table[regno][3] = transp;
+
+	*(mc68328Regs + 0x3c9) = (red & 0xff) >> 2;
+	*(mc68328Regs + 0x3c9) = (green & 0xff) >> 2;
+	*(mc68328Regs + 0x3c9) = (blue & 0xff) >> 2;
 
-return (0);
-#endif
-}
-
-
-   /*
-    *    Read a single color register and split it into
-    *    colors/transparent. Return != 0 for invalid regno.
-    */
-
-static int mc68328_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-                         u_int *transp)
-{
-	return 1;
-#if 0
-if (regno >= 256)
-  return (1);
-*red    = mc68328_colour_table [regno][0];
-*green  = mc68328_colour_table [regno][1];
-*blue   = mc68328_colour_table [regno][2];
-*transp = mc68328_colour_table [regno][3];
-return (0);
+	return (0);
 #endif
 }
 
-
    /*
     *    (Un)Blank the screen
     */
 
-void mc68328_blank(int blank)
+static void mc68328fb_blank(int blank, struct fb_info *info)
 {
 #if 0
 	if (blank)
-		(*(volatile unsigned char*)0xFFFFFA27) &= ~128;
+		(*(volatile unsigned char *) 0xFFFFFA27) &= ~128;
 	else
-		(*(volatile unsigned char*)0xFFFFFA27) |= 128;
+		(*(volatile unsigned char *) 0xFFFFFA27) |= 128;
 #endif
 }
 
@@ -504,86 +253,91 @@
 /**************************************************************
  * We are waiting for "fifo" FIFO-slots empty
  */
-void mc68328_WaitQueue (u_short fifo)
+void mc68328_WaitQueue(u_short fifo)
 {
 }
 
 /**************************************************************
  * We are waiting for Hardware (Graphics Engine) not busy
  */
-void mc68328_WaitBlit (void)
+void mc68328_WaitBlit(void)
 {
 }
 
 /**************************************************************
  * BitBLT - Through the Plane
  */
-void mc68328_BitBLT (u_short curx, u_short cury, u_short destx, u_short desty,
-                   u_short width, u_short height, u_short mode)
+void mc68328_BitBLT(u_short curx, u_short cury, u_short destx,
+		    u_short desty, u_short width, u_short height,
+		    u_short mode)
 {
 #if 0
-u_short blitcmd = S3_BITBLT;
+	u_short blitcmd = S3_BITBLT;
 
 /* Set drawing direction */
 /* -Y, X maj, -X (default) */
-if (curx > destx)
-  blitcmd |= 0x0020;  /* Drawing direction +X */
-else
-  {
-  curx  += (width - 1);
-  destx += (width - 1);
-  }
-
-if (cury > desty)
-  blitcmd |= 0x0080;  /* Drawing direction +Y */
-else
-  {
-  cury  += (height - 1);
-  desty += (height - 1);
-  }
-
-mc68328_WaitQueue (0x8000);
-
-*((u_short volatile *)(mc68328Regs + S3_PIXEL_CNTL)) = 0xa000;
-*((u_short volatile *)(mc68328Regs + S3_FRGD_MIX)) = (0x0060 | mode);
-
-*((u_short volatile *)(mc68328Regs + S3_CUR_X)) = curx;
-*((u_short volatile *)(mc68328Regs + S3_CUR_Y)) = cury;
-
-*((u_short volatile *)(mc68328Regs + S3_DESTX_DIASTP)) = destx;
-*((u_short volatile *)(mc68328Regs + S3_DESTY_AXSTP)) = desty;
+	if (curx > destx)
+		blitcmd |= 0x0020;	/* Drawing direction +X */
+	else {
+		curx += (width - 1);
+		destx += (width - 1);
+	}
+
+	if (cury > desty)
+		blitcmd |= 0x0080;	/* Drawing direction +Y */
+	else {
+		cury += (height - 1);
+		desty += (height - 1);
+	}
+
+	mc68328_WaitQueue(0x8000);
+
+	*((u_short volatile *) (mc68328Regs + S3_PIXEL_CNTL)) = 0xa000;
+	*((u_short volatile *) (mc68328Regs + S3_FRGD_MIX)) =
+	    (0x0060 | mode);
+
+	*((u_short volatile *) (mc68328Regs + S3_CUR_X)) = curx;
+	*((u_short volatile *) (mc68328Regs + S3_CUR_Y)) = cury;
+
+	*((u_short volatile *) (mc68328Regs + S3_DESTX_DIASTP)) = destx;
+	*((u_short volatile *) (mc68328Regs + S3_DESTY_AXSTP)) = desty;
+
+	*((u_short volatile *) (mc68328Regs + S3_MIN_AXIS_PCNT)) =
+	    height - 1;
+	*((u_short volatile *) (mc68328Regs + S3_MAJ_AXIS_PCNT)) =
+	    width - 1;
 
-*((u_short volatile *)(mc68328Regs + S3_MIN_AXIS_PCNT)) = height - 1;
-*((u_short volatile *)(mc68328Regs + S3_MAJ_AXIS_PCNT)) = width  - 1;
-
-*((u_short volatile *)(mc68328Regs + S3_CMD)) = blitcmd;
+	*((u_short volatile *) (mc68328Regs + S3_CMD)) = blitcmd;
 #endif
 }
 
 /**************************************************************
  * Rectangle Fill Solid
  */
-void mc68328_RectFill (u_short x, u_short y, u_short width, u_short height,
-                     u_short mode, u_short color)
+void mc68328_RectFill(u_short x, u_short y, u_short width, u_short height,
+		      u_short mode, u_short color)
 {
 #if 0
-u_short blitcmd = S3_FILLEDRECT;
+	u_short blitcmd = S3_FILLEDRECT;
 
-mc68328_WaitQueue (0x8000);
+	mc68328_WaitQueue(0x8000);
 
-*((u_short volatile *)(mc68328Regs + S3_PIXEL_CNTL)) = 0xa000;
-*((u_short volatile *)(mc68328Regs + S3_FRGD_MIX)) = (0x0020 | mode);
+	*((u_short volatile *) (mc68328Regs + S3_PIXEL_CNTL)) = 0xa000;
+	*((u_short volatile *) (mc68328Regs + S3_FRGD_MIX)) =
+	    (0x0020 | mode);
 
-*((u_short volatile *)(mc68328Regs + S3_MULT_MISC)) = 0xe000;
-*((u_short volatile *)(mc68328Regs + S3_FRGD_COLOR)) = color;
+	*((u_short volatile *) (mc68328Regs + S3_MULT_MISC)) = 0xe000;
+	*((u_short volatile *) (mc68328Regs + S3_FRGD_COLOR)) = color;
 
-*((u_short volatile *)(mc68328Regs + S3_CUR_X)) = x;
-*((u_short volatile *)(mc68328Regs + S3_CUR_Y)) = y;
+	*((u_short volatile *) (mc68328Regs + S3_CUR_X)) = x;
+	*((u_short volatile *) (mc68328Regs + S3_CUR_Y)) = y;
 
-*((u_short volatile *)(mc68328Regs + S3_MIN_AXIS_PCNT)) = height - 1;
-*((u_short volatile *)(mc68328Regs + S3_MAJ_AXIS_PCNT)) = width  - 1;
+	*((u_short volatile *) (mc68328Regs + S3_MIN_AXIS_PCNT)) =
+	    height - 1;
+	*((u_short volatile *) (mc68328Regs + S3_MAJ_AXIS_PCNT)) =
+	    width - 1;
 
-*((u_short volatile *)(mc68328Regs + S3_CMD)) = blitcmd;
+	*((u_short volatile *) (mc68328Regs + S3_CMD)) = blitcmd;
 #endif
 }
 
@@ -591,97 +345,54 @@
 /**************************************************************
  * Move cursor to x, y
  */
-void mc68328_MoveCursor (u_short x, u_short y)
+void mc68328_MoveCursor(u_short x, u_short y)
 {
-	(*(volatile unsigned short*)0xFFFFFA18) = (mc68328fbCursorMode << 14) | x;
-	(*(volatile unsigned short*)0xFFFFFA1A) = y;
+	(*(volatile unsigned short *) 0xFFFFFA18) =
+	    (mc68328fbCursorMode << 14) | x;
+	(*(volatile unsigned short *) 0xFFFFFA1A) = y;
 #if 0
-*(mc68328Regs + S3_CRTC_ADR)  = 0x39;
-*(mc68328Regs + S3_CRTC_DATA) = 0xa0;
+	*(mc68328Regs + S3_CRTC_ADR) = 0x39;
+	*(mc68328Regs + S3_CRTC_DATA) = 0xa0;
 
-*(mc68328Regs + S3_CRTC_ADR)  = S3_HWGC_ORGX_H;
-*(mc68328Regs + S3_CRTC_DATA) = (char)((x & 0x0700) >> 8);
-*(mc68328Regs + S3_CRTC_ADR)  = S3_HWGC_ORGX_L;
-*(mc68328Regs + S3_CRTC_DATA) = (char)(x & 0x00ff);
-
-*(mc68328Regs + S3_CRTC_ADR)  = S3_HWGC_ORGY_H;
-*(mc68328Regs + S3_CRTC_DATA) = (char)((y & 0x0700) >> 8);
-*(mc68328Regs + S3_CRTC_ADR)  = S3_HWGC_ORGY_L;
-*(mc68328Regs + S3_CRTC_DATA) = (char)(y & 0x00ff);
+	*(mc68328Regs + S3_CRTC_ADR) = S3_HWGC_ORGX_H;
+	*(mc68328Regs + S3_CRTC_DATA) = (char) ((x & 0x0700) >> 8);
+	*(mc68328Regs + S3_CRTC_ADR) = S3_HWGC_ORGX_L;
+	*(mc68328Regs + S3_CRTC_DATA) = (char) (x & 0x00ff);
+
+	*(mc68328Regs + S3_CRTC_ADR) = S3_HWGC_ORGY_H;
+	*(mc68328Regs + S3_CRTC_DATA) = (char) ((y & 0x0700) >> 8);
+	*(mc68328Regs + S3_CRTC_ADR) = S3_HWGC_ORGY_L;
+	*(mc68328Regs + S3_CRTC_DATA) = (char) (y & 0x00ff);
 #endif
 }
 
-
-/* -------------------- Interfaces to hardware functions -------------------- */
-
-
-static struct fb_hwswitch mc68328_switch = {
-   mc68328_init, mc68328_encode_fix, mc68328_decode_var, mc68328_encode_var,
-   mc68328_getcolreg, mc68328_setcolreg, mc68328_blank
-};
-
-
 /* -------------------- Generic routines ------------------------------------ */
 
-
-   /*
-    *    Fill the hardware's `par' structure.
-    */
-
-static void mc68328_fb_get_par(struct mc68328_fb_par *par)
-{
-   if (current_par_valid)
-      *par = current_par;
-   else
-      fbhw->decode_var(&mc68328_fb_predefined[mc68328fb_mode], par);
-}
-
-
-static void mc68328_fb_set_par(struct mc68328_fb_par *par)
-{
-   current_par = *par;
-   current_par_valid = 1;
-}
-
-
-static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive)
-{
-   int err, activate;
-   struct mc68328_fb_par par;
-
-   if ((err = fbhw->decode_var(var, &par)))
-      return(err);
-   activate = var->activate;
-   if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive)
-      mc68328_fb_set_par(&par);
-   fbhw->encode_var(var, &par);
-   var->activate = activate;
-   return(0);
-}
-
-
    /*
     *    Default Colormaps
     */
 
 static u_short red16[] =
-   { 0xc000, 0x0000, 0x0000, 0x0000, 0xc000, 0xc000, 0xc000, 0x0000,
-     0x8000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff};
+    { 0xc000, 0x0000, 0x0000, 0x0000, 0xc000, 0xc000, 0xc000, 0x0000,
+	0x8000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff
+};
 static u_short green16[] =
-   { 0xc000, 0x0000, 0xc000, 0xc000, 0x0000, 0x0000, 0xc000, 0x0000,
-     0x8000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff};
+    { 0xc000, 0x0000, 0xc000, 0xc000, 0x0000, 0x0000, 0xc000, 0x0000,
+	0x8000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff
+};
 static u_short blue16[] =
-   { 0xc000, 0x0000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0x0000,
-     0x8000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff};
+    { 0xc000, 0x0000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0x0000,
+	0x8000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff
+};
 
 
 static struct fb_cmap default_16_colors =
-   { 0, 16, red16, green16, blue16, NULL };
+    { 0, 16, red16, green16, blue16, NULL };
 
 
 static struct fb_cmap *get_default_colormap(int bpp)
 {
-   return(&default_16_colors);
+	return (&default_16_colors);
 }
 
 
@@ -689,216 +400,13 @@
 #define CNVT_FROMHW(val,width)   (((width) ? ((((val)<<16)-(val)) / \
                                               ((1<<(width))-1)) : 0))
 
-
-static void memcpy_fs(int fsfromto, void *to, void *from, int len)
-{
-   switch (fsfromto) {
-      case 0:
-         memcpy(to, from, len);
-         return;
-      case 1:
-         copy_from_user(to, from, len);
-         return;
-      case 2:
-         copy_to_user(to, from, len);
-         return;
-   }
-}
-
-
-static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto)
-{
-   int size;
-   int tooff = 0, fromoff = 0;
-
-   if (to->start > from->start)
-      fromoff = to->start-from->start;
-   else
-      tooff = from->start-to->start;
-   size = to->len-tooff;
-   if (size > from->len-fromoff)
-      size = from->len-fromoff;
-   if (size < 0)
-      return;
-   size *= sizeof(u_short);
-   memcpy_fs(fsfromto, to->red+tooff, from->red+fromoff, size);
-   memcpy_fs(fsfromto, to->green+tooff, from->green+fromoff, size);
-   memcpy_fs(fsfromto, to->blue+tooff, from->blue+fromoff, size);
-   if (from->transp && to->transp)
-      memcpy_fs(fsfromto, to->transp+tooff, from->transp+fromoff, size);
-}
-
-
-static int alloc_cmap(struct fb_cmap *cmap, int len, int transp)
-{
-   int size = len*sizeof(u_short);
-
-   if (cmap->len != len) {
-      if (cmap->red)
-         kfree(cmap->red);
-      if (cmap->green)
-         kfree(cmap->green);
-      if (cmap->blue)
-         kfree(cmap->blue);
-      if (cmap->transp)
-         kfree(cmap->transp);
-      cmap->red = cmap->green = cmap->blue = cmap->transp = NULL;
-      cmap->len = 0;
-      if (!len)
-         return(0);
-      if (!(cmap->red = kmalloc(size, GFP_ATOMIC)))
-         return(-1);
-      if (!(cmap->green = kmalloc(size, GFP_ATOMIC)))
-         return(-1);
-      if (!(cmap->blue = kmalloc(size, GFP_ATOMIC)))
-         return(-1);
-      if (transp) {
-         if (!(cmap->transp = kmalloc(size, GFP_ATOMIC)))
-            return(-1);
-      } else
-         cmap->transp = NULL;
-   }
-   cmap->start = 0;
-   cmap->len = len;
-   copy_cmap(get_default_colormap(len), cmap, 0);
-   return(0);
-}
-
-
-   /*
-    *    Get the Fixed Part of the Display
-    */
-
-static int mc68328_fb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
-{
-   struct mc68328_fb_par par;
-   int error = 0;
-
-   if (con == -1)
-      mc68328_fb_get_par(&par);
-   else
-      error = fbhw->decode_var(&disp[con].var, &par);
-   return(error ? error : fbhw->encode_fix(fix, &par));
-}
-
-
-   /*
-    *    Get the User Defined Part of the Display
-    */
-
-static int mc68328_fb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
-{
-   struct mc68328_fb_par par;
-   int error = 0;
-
-   if (con == -1) {
-      mc68328_fb_get_par(&par);
-      error = fbhw->encode_var(var, &par);
-   } else
-      *var = disp[con].var;
-   return(error);
-}
-
-
-static void mc68328_fb_set_disp(int con, struct fb_info *info)
-{
-   struct fb_fix_screeninfo fix;
-
-   mc68328_fb_get_fix(&fix, con, info);
-   if (con == -1)
-      con = 0;
-   info->screen_base = (u_char *)fix.smem_start;
-   disp[con].visual = fix.visual;
-   disp[con].type = fix.type;
-   disp[con].type_aux = fix.type_aux;
-   disp[con].ypanstep = fix.ypanstep;
-   disp[con].ywrapstep = fix.ywrapstep;
-   disp[con].can_soft_blank = 1;
-   disp[con].inverse = mc68328fb_inverse;
-}
-
-
-   /*
-    *    Set the User Defined Part of the Display
-    */
-
-static int mc68328_fb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
-{
-   int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp;
-
-   if ((err = do_fb_set_var(var, con == currcon)))
-      return(err);
-   if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
-      oldxres = disp[con].var.xres;
-      oldyres = disp[con].var.yres;
-      oldvxres = disp[con].var.xres_virtual;
-      oldvyres = disp[con].var.yres_virtual;
-      oldbpp = disp[con].var.bits_per_pixel;
-      disp[con].var = *var;
-      if (oldxres != var->xres || oldyres != var->yres ||
-          oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
-          oldbpp != var->bits_per_pixel) {
-         mc68328_fb_set_disp(con, info);
-         (*fb_info.changevar)(con);
-         alloc_cmap(&disp[con].cmap, 0, 0);
-         do_install_cmap(con, info);
-      }
-   }
-   var->activate = 0;
-   return(0);
-}
-
-
-   /*
-    *    Get the Colormap
-    */
-
-static int mc68328_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
-{
-   if (con == currcon) /* current console? */
-      return(fb_get_cmap(cmap, kspc, fbhw->getcolreg, info));
-   else if (disp[con].cmap.len) /* non default colormap? */
-      copy_cmap(&disp[con].cmap, cmap, kspc ? 0 : 2);
-   else
-      copy_cmap(get_default_colormap(disp[con].var.bits_per_pixel), cmap,
-                kspc ? 0 : 2);
-   return(0);
-}
-
-
-
-   /*
-    *    Pan or Wrap the Display
-    *
-    *    This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
-    */
-
-static int mc68328_fb_pan_display(struct fb_var_screeninfo *var, int con, struct fb_info *info)
-{
-   return(-EINVAL);
-}
-
-
-   /*
-    *    mc68328 Frame Buffer Specific ioctls
-    */
-
-static int mc68328_fb_ioctl(struct inode *inode, struct file *file,
-                          u_int cmd, u_long arg, int con, struct fb_info *info)
-{
-   return(-EINVAL);
-}
-
-
 static struct fb_ops mc68328_fb_ops = {
-	owner:		THIS_MODULE,
-	fb_get_fix:	mc68328_fb_get_fix,
-	fb_get_var:	mc68328_fb_get_var,
-	fb_set_var:	mc68328_fb_set_var,
-	fb_get_cmap:	mc68328_fb_get_cmap,
-	fb_set_cmap:	gen_set_cmap,
-	fb_pan_display:	mc68328_fb_pan_display,
-	fb_ioctl:	mc68328_fb_ioctl,
+	.owner:		THIS_MODULE,
+	.fb_setcolreg:	mc68328fb_setcolreg,
+	.fb_fillrect:	cfbfillrect,
+	.fb_copyarea:	cfbcopyarea,
+	.fb_imageblit:	cfbimgblt,
+	.fb_cursor:	softcursor,
 };
 
 
@@ -908,79 +416,34 @@
 
 int __init mc68328_fb_init(void)
 {
-   int err;
-   struct mc68328_fb_par par;
-
-   fbhw = &mc68328_switch;
-
-   err = register_framebuffer(&fb_info);
-   if (err < 0)
-      panic("Cannot register frame buffer\n");
-
-   fbhw->init();
-   fbhw->decode_var(&mc68328_fb_predefined[mc68328fb_mode], &par);
-   fbhw->encode_var(&mc68328_fb_predefined[0], &par);
-
-   strcpy(fb_info.modename, mc68328_fb_name);
-   fb_info.disp = disp;
-   fb_info.switch_con = &mc68328fb_switch;
-   fb_info.updatevar = &mc68328fb_updatevar;
-
-   do_fb_set_var(&mc68328_fb_predefined[0], 1);
-   mc68328_fb_get_var(&disp[0].var, -1, &fb_info);
-   mc68328_fb_set_disp(-1, &fb_info);
-   do_install_cmap(0, &fb_info);
-   return(0);
-}
-
-
-static int mc68328fb_switch(int con, struct fb_info *info)
-{
-   /* Do we have to save the colormap? */
-   if (disp[currcon].cmap.len)
-      fb_get_cmap(&disp[currcon].cmap, 1, &disp[currcon].var, info);
-
-   do_fb_set_var(&disp[con].var, 1);
-   currcon = con;
-   /* Install new colormap */
-   do_install_cmap(con, info);
-   return(0);
-}
-
-
-   /*
-    *    Update the `var' structure (called by fbcon.c)
-    *
-    *    This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'.
-    *    Since it's called by a kernel driver, no range checking is done.
-    */
-
-static int mc68328fb_updatevar(int con)
-{
-   return(0);
-}
-
-
-   /*
-    *    Blank the display.
-    */
-
-static void mc68328fb_blank(int blank)
-{
-   fbhw->blank(blank);
+	if (mc68328fb_mode == -1)
+		mc68328fb_mode = PALM_DEFMODE;
+	mc68328_fix.smem_start = (*(volatile unsigned long *) 0xFFFFFA00);
+	/*kernel_map (board_addr + 0x01400000, 0x00400000, */
+	
+	info->var = mc68328_fb_predefined[mc68328fb_mode];
+	
+	if (info->var.bits_per_pixel == 1)
+		fix->visual = FB_VISUAL_MONO01;
+	else
+		fix->visual = FB_VISUAL_DIRECTCOLOR;
+	info->screen_base = (u_char *) mc68328_fix.smem_start;
+	
+	if (register_framebuffer(&fb_info) < 0)
+		panic("Cannot register frame buffer\n");
+	return 0;
 }
 
-
    /*
     *    Get a Video Mode
     */
 
 static int get_video_mode(const char *name)
 {
-   int i;
+	int i;
 
-   for (i = 1; i < NUM_PREDEF_MODES; i++)
-      if (!strcmp(name, mc68328_fb_modenames[i]))
-         return(i);
-   return(0);
+	for (i = 1; i < NUM_PREDEF_MODES; i++)
+		if (!strcmp(name, mc68328_fb_modenames[i]))
+			return (i);
+	return (0);
 }
diff -Nru a/drivers/video/Kconfig b/drivers/video/Kconfig
--- a/drivers/video/Kconfig	Mon Dec  9 18:46:34 2002
+++ b/drivers/video/Kconfig	Mon Dec  9 18:46:34 2002
@@ -2,10 +2,10 @@
 # Video configuration
 #
 
-menu "Frame-buffer support"
+menu "Graphics support"
 
 config FB
-	bool "Support for frame buffer devices (EXPERIMENTAL)"
+	bool "Support for frame buffer devices"
 	---help---
 	  The frame buffer device provides an abstraction for the graphics
 	  hardware. It represents the frame buffer of some video hardware and
@@ -38,14 +38,9 @@
 	  (e.g. an accelerated X server) and that are not frame buffer
 	  device-aware may cause unexpected results. If unsure, say N.
 
-config DUMMY_CONSOLE
-	bool
-	depends on FB
-	default y
-
 config FB_CLGEN
-	tristate "Cirrus Logic support (EXPERIMENTAL)"
-	depends on FB && EXPERIMENTAL && (AMIGA || PCI)
+	tristate "Cirrus Logic support"
+	depends on FB && (AMIGA || PCI)
 	---help---
 	  This enables support for Cirrus Logic GD542x/543x based boards on
 	  Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum.
@@ -59,8 +54,8 @@
 	  before you next recompile the kernel.
 
 config FB_PM2
-	tristate "Permedia2 support (EXPERIMENTAL)"
-	depends on FB && EXPERIMENTAL && (AMIGA || PCI)
+	tristate "Permedia2 support"
+	depends on FB && (AMIGA || PCI)
 	help
 	  This is the frame buffer device driver for the Permedia2 AGP frame
 	  buffer card from ASK, aka `Graphic Blaster Exxtreme'.  There is a
@@ -206,8 +201,8 @@
 	  Cybervision 64 3D card, as they use incompatible video chips.
 
 config FB_VIRGE
-	bool "Amiga CyberVision3D support (EXPERIMENTAL)"
-	depends on FB && ZORRO && EXPERIMENTAL
+	bool "Amiga CyberVision3D support "
+	depends on FB && ZORRO
 	help
 	  This enables support for the Cybervision 64/3D graphics card from
 	  Phase5. Please note that its use is not all that intuitive (i.e. if
@@ -217,16 +212,16 @@
 	  Cybervision 64 card, as they use incompatible video chips.
 
 config FB_RETINAZ3
-	tristate "Amiga RetinaZ3 support (EXPERIMENTAL)"
-	depends on FB && ZORRO && EXPERIMENTAL
+	tristate "Amiga RetinaZ3 support"
+	depends on FB && ZORRO
 	help
 	  This enables support for the Retina Z3 graphics card. Say N unless
 	  you have a Retina Z3 or plan to get one before you next recompile
 	  the kernel.
 
 config FB_FM2
-	bool "Amiga FrameMaster II/Rainbow II support (EXPERIMENTAL)"
-	depends on FB && ZORRO && EXPERIMENTAL
+	bool "Amiga FrameMaster II/Rainbow II support"
+	depends on FB && ZORRO
 	help
 	  This is the frame buffer device driver for the Amiga FrameMaster
 	  card from BSC (exhibited 1992 but not shipped as a CBM product).
@@ -238,33 +233,6 @@
 	  This is the frame buffer device driver for the builtin graphics
 	  chipset found in Ataris.
 
-config FB_ATY
-	tristate "ATI Mach64 display support (EXPERIMENTAL)" if EXPERIMENTAL && PCI
-	depends on FB
-	help
-	  This driver supports graphics boards with the ATI Mach64 chips.
-	  Say Y if you have such a graphics board.
-
-	  The driver is also available as a module ( = code which can be
-	  inserted and removed from the running kernel whenever you want). The
-	  module will be called atyfb.o. If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt>.
-
-config FB_ATY
-	prompt "ATI Mach64 display support"
-	depends on FB && (SPARC64 && PCI && FB_PCI || ATARI)
-
-config FB_ATY_GX
-	bool "Mach64 GX support (EXPERIMENTAL)" if EXPERIMENTAL && PCI
-	depends on FB_ATY
-	default y if ATARI
-	help
-	  Say Y here to support use of the ATI Mach64 Graphics Expression
-	  board (or other boards based on the Mach64 GX chipset) as a
-	  framebuffer device.  The ATI product support page for these boards
-	  is at
-	  <http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
-
 config FB_OF
 	bool "Open Firmware frame buffer device support"
 	depends on FB && PPC && ALL_PPC
@@ -302,7 +270,7 @@
 
 config FB_IMSTT
 	bool "IMS Twin Turbo display support"
-	depends on FB && PPC
+	depends on FB && PCI
 	help
 	  The IMS Twin Turbo is a PCI-based frame buffer card bundled with
 	  many Macintosh and compatible computers.
@@ -368,15 +336,20 @@
 
 config FB_VESA
 	bool "VESA VGA graphics console"
-	depends on FB && X86
+	depends on FB && (X86 || X86_64)
 	help
 	  This is the frame buffer device driver for generic VESA 2.0
 	  compliant graphic cards. The older VESA 1.2 cards are not supported.
 	  You will get a boot time penguin logo at no additional cost. Please
 	  read <file:Documentation/fb/vesafb.txt>. If unsure, say Y.
 
+config VIDEO_SELECT
+	bool
+	depends on FB_VESA
+	default y
+
 config FB_HGA
-	tristate "Hercules mono graphics console (EXPERIMENTAL)"
+	tristate "Hercules mono graphics console"
 	depends on FB && X86
 	help
 	  Say Y here if you have a Hercules mono graphics card.
@@ -486,8 +459,8 @@
 	  discussion.
 
 config FB_RIVA
-	tristate "nVidia Riva support (EXPERIMENTAL)"
-	depends on FB && EXPERIMENTAL && PCI
+	tristate "nVidia Riva support"
+	depends on FB && PCI
 	help
 	  This driver supports graphics boards with the nVidia Riva/Geforce
 	  chips.
@@ -499,8 +472,8 @@
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config FB_MATROX
-	tristate "Matrox acceleration (EXPERIMENTAL)"
-	depends on FB && EXPERIMENTAL && PCI
+	tristate "Matrox acceleration"
+	depends on FB && PCI
 	---help---
 	  Say Y here if you have a Matrox Millennium, Matrox Millennium II,
 	  Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox
@@ -654,19 +627,9 @@
 	  There is no need for enabling 'Matrox multihead support' if you have
 	  only one Matrox card in the box.
 
-config FB_ATY_CT
-	bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support" if EXPERIMENTAL
-	depends on PCI && FB_ATY
-	default y if SPARC64 && FB_PCI
-	help
-	  Say Y here to support use of ATI's 64-bit Rage boards (or other
-	  boards based on the Mach64 CT, VT, GT, and LT chipsets) as a
-	  framebuffer device.  The ATI product support page for these boards
-	  is at <http://support.ati.com/products/pc/mach64/>.
-
 config FB_RADEON
-	tristate "ATI Radeon display support (EXPERIMENTAL)"
-	depends on FB && EXPERIMENTAL && PCI
+	tristate "ATI Radeon display support"
+	depends on FB && PCI
 	help
 	  Choose this option if you want to use an ATI Radeon graphics card as
 	  a framebuffer device.  There are both PCI and AGP versions.  You
@@ -675,8 +638,8 @@
 	  <http://www.ati.com/na/pages/products/pc/radeon32/index.html>.
 
 config FB_ATY128
-	tristate "ATI Rage128 display support (EXPERIMENTAL)"
-	depends on FB && EXPERIMENTAL && PCI
+	tristate "ATI Rage128 display support"
+	depends on FB && PCI
 	help
 	  This driver supports graphics boards with the ATI Rage128 chips.
 	  Say Y if you have such a graphics board and read
@@ -687,9 +650,42 @@
 	  module will be called aty128fb.o. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
+config FB_ATY
+	tristate "ATI Mach64 display support" if PCI || ATARI
+	depends on FB
+	help
+	  This driver supports graphics boards with the ATI Mach64 chips.
+	  Say Y if you have such a graphics board.
+
+	  The driver is also available as a module ( = code which can be
+	  inserted and removed from the running kernel whenever you want). The
+	  module will be called atyfb.o. If you want to compile it as a
+	  module, say M here and read <file:Documentation/modules.txt>.
+
+config FB_ATY_CT
+	bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support"
+	depends on PCI && FB_ATY
+	default y if SPARC64 && FB_PCI
+	help
+	  Say Y here to support use of ATI's 64-bit Rage boards (or other
+	  boards based on the Mach64 CT, VT, GT, and LT chipsets) as a
+	  framebuffer device.  The ATI product support page for these boards
+	  is at <http://support.ati.com/products/pc/mach64/>.
+
+config FB_ATY_GX
+	bool "Mach64 GX support" if PCI
+	depends on FB_ATY
+	default y if ATARI
+	help
+	  Say Y here to support use of the ATI Mach64 Graphics Expression
+	  board (or other boards based on the Mach64 GX chipset) as a
+	  framebuffer device.  The ATI product support page for these boards
+	  is at
+	  <http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
+
 config FB_SIS
-	tristate "SIS acceleration (EXPERIMENTAL)"
-	depends on FB && EXPERIMENTAL && PCI
+	tristate "SIS acceleration"
+	depends on FB && PCI
 	help
 	  This is the frame buffer device driver for the SiS 630 and 640 Super
 	  Socket 7 UMA cards.  Specs available at <http://www.sis.com.tw/>.
@@ -710,8 +706,8 @@
 	  card.  Specs available at <http://www.sis.com.tw/>.
 
 config FB_NEOMAGIC
-	tristate "NeoMagic display support (EXPERIMENTAL)"
-	depends on FB && EXPERIMENTAL && PCI
+	tristate "NeoMagic display support"
+	depends on FB && PCI
 	help
 	  This driver supports notebooks with NeoMagic PCI chips.
 	  Say Y if you have such a graphics card. 
@@ -722,8 +718,8 @@
 	  module, say M here and read Documentation/modules.txt.
 
 config FB_3DFX
-	tristate "3Dfx Banshee/Voodoo3 display support (EXPERIMENTAL)"
-	depends on FB && EXPERIMENTAL && PCI
+	tristate "3Dfx Banshee/Voodoo3 display support"
+	depends on FB && PCI
 	help
 	  This driver supports graphics boards with the 3Dfx Banshee/Voodoo3
 	  chips. Say Y if you have such a graphics board.
@@ -734,8 +730,8 @@
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config FB_VOODOO1
-	tristate "3Dfx Voodoo Graphics (sst1) support (EXPERIMENTAL)"
-	depends on FB && EXPERIMENTAL && PCI
+	tristate "3Dfx Voodoo Graphics (sst1) support"
+	depends on FB && PCI
 	---help---
 	  Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or 
 	  Voodoo2 (cvg) based graphics card.
@@ -751,8 +747,8 @@
 	  options and other important info  support.
 
 config FB_TRIDENT
-	tristate "Trident support (EXPERIMENTAL)"
-	depends on FB && EXPERIMENTAL && PCI
+	tristate "Trident support"
+	depends on FB && PCI
 	---help---
 	  This driver is supposed to support graphics boards with the
 	  Trident CyberXXXX/Image/CyberBlade chips mostly found in laptops
@@ -767,8 +763,8 @@
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config FB_PM3
-	tristate "Permedia3 support (EXPERIMENTAL)"
-	depends on FB && EXPERIMENTAL && PCI
+	tristate "Permedia3 support"
+	depends on FB && PCI
 	help
 	  This is the frame buffer device driver for the 3DLabs Permedia3
 	  chipset, used in Formac ProFormance III, 3DLabs Oxygen VX1 &
@@ -867,9 +863,16 @@
 
 	  Say Y here to enable kernel support for the on-board framebuffer.
 
+config FB_68328
+	bool "Motorola 68328 native frame buffer support"
+	depends on (M68328 || M68EZ328 || M68VZ328)
+	help
+	  Say Y here if you want to support the built-in frame buffer of
+	  the Motorola 68328 CPU family.
+
 config FB_VIRTUAL
-	tristate "Virtual Frame Buffer support (ONLY FOR TESTING!) (EXPERIMENTAL)"
-	depends on FB && EXPERIMENTAL
+	tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
+	depends on FB
 	---help---
 	  This is a `virtual' frame buffer device. It operates on a chunk of
 	  unswappable kernel memory instead of on the memory of a graphics
@@ -887,262 +890,7 @@
 
 	  If unsure, say N.
 
-config FBCON_ADVANCED
-	bool "Advanced low level driver options"
-	depends on FB
-	---help---
-	  The frame buffer console uses character drawing routines that are
-	  tailored to the specific organization of pixels in the memory of
-	  your graphics hardware. These are called the low level frame buffer
-	  console drivers. Note that they are used for text console output
-	  only; they are NOT needed for graphical applications.
-
-	  If you say N here, the needed low level drivers are automatically
-	  enabled, depending on what frame buffer devices you selected above.
-	  This is recommended for most users.
-
-	  If you say Y here, you have more fine-grained control over which low
-	  level drivers are enabled. You can e.g. leave out low level drivers
-	  for color depths you do not intend to use for text consoles.
-
-	  Low level frame buffer console drivers can be modules ( = code which
-	  can be inserted and removed from the running kernel whenever you
-	  want). The modules will be called fbcon-*.o. If you want to compile
-	  (some of) them as modules, read <file:Documentation/modules.txt>.
-
-	  If unsure, say N.
-
-config FBCON_MFB
-	tristate "Monochrome support" if FBCON_ADVANCED
-	depends on FB
-	default m if !FBCON_ADVANCED && !FB_ACORN && FB_AMIGA!=y && !FB_ATARI && FB_CYBER!=y && !FB_BWTWO && FB_RETINAZ3!=y && !FB_VIRGE && FB_CLGEN!=y && (FB_AMIGA=m || FB_CYBER=m || FB_RETINAZ3=m || FB_CLGEN=m)
-	default y if !FBCON_ADVANCED && (FB_ACORN || FB_AMIGA=y || FB_ATARI || FB_CYBER=y || FB_BWTWO || FB_RETINAZ3=y || FB_VIRGE || FB_CLGEN=y)
-	help
-	  This is the low level frame buffer console driver for monochrome
-	  (2 colors) packed pixels.
-
-config FBCON_CFB2
-	tristate "2 bpp packed pixels support" if FBCON_ADVANCED
-	depends on FB
-	default y if !FBCON_ADVANCED && (FB_ACORN || FB_SA1100)
-	help
-	  This is the low level frame buffer console driver for 2 bits per
-	  pixel (4 colors) packed pixels.
-
-config FBCON_CFB4
-	tristate "4 bpp packed pixels support" if FBCON_ADVANCED
-	depends on FB
-	default y if !FBCON_ADVANCED && (FB_ACORN || FB_SA1100)
-	help
-	  This is the low level frame buffer console driver for 4 bits per
-	  pixel (16 colors) packed pixels.
-
-config FBCON_CFB8
-	tristate "8 bpp packed pixels support" if FBCON_ADVANCED
-	depends on FB
-	default m if !FBCON_ADVANCED && !FB_ACORN && !FB_ATARI && !FB_P9100 && FB_CYBER2000!=y && FB_RADEON!=y && FB_TGA!=y && FB_SIS!=y && FB_PM3!=y && !FB_TCX && !FB_CGTHREE && !FB_CONTROL && FB_CLGEN!=y && !FB_CGFOURTEEN && FB_TRIDENT!=y && !FB_VIRGE && FB_CYBER!=y && !FB_VALKYRIE && !FB_PLATINUM && !FB_IGA && FB_MATROX!=y && !FB_CT65550 && FB_PM2!=y && !FB_SA1100 && (FB_CYBER2000=m || FB_RADEON=m || FB_TGA=m || FB_SIS=m || FB_PM3=m || FB_CLGEN=m || FB_TRIDENT=m || FB_CYBER=m || FB_MATROX=m || FB_PM2=m)
-	default y if !FBCON_ADVANCED && (FB_ACORN || FB_ATARI || FB_P9100 || FB_CYBER2000=y || FB_RADEON=y || FB_TGA=y || FB_SIS=y || FB_PM3=y || FB_TCX || FB_CGTHREE || FB_CONTROL || FB_CLGEN=y || FB_CGFOURTEEN || FB_TRIDENT=y || FB_VIRGE || FB_CYBER=y || FB_VALKYRIE || FB_PLATINUM || FB_IGA || FB_MATROX=y || FB_CT65550 || FB_PM2=y || FB_SA1100)
-	help
-	  This is the low level frame buffer console driver for 8 bits per
-	  pixel (256 colors) packed pixels.
-
-config FBCON_CFB16
-	tristate "16 bpp packed pixels support" if FBCON_ADVANCED
-	depends on FB
-	default m if !FBCON_ADVANCED && !FB_ATARI && FB_PM3!=y && FB_SIS!=y && FB_PVR2!=y && FB_TRIDENT!=y && !FB_TBOX && FB_VOODOO1!=y && FB_RADEON!=y && !FB_CONTROL && FB_CLGEN!=y && !FB_VIRGE && FB_CYBER!=y && !FB_VALKYRIE && !FB_PLATINUM && !FB_CT65550 && FB_MATROX!=y && FB_PM2!=y && FB_CYBER2000!=y && !FB_SA1100 && (FB_SIS=m || FB_RADEON=m || FB_PVR2=m || FB_TRIDENT=m || FB_VOODOO1=m || FB_PM3=m || FB_CLGEN=m || FB_CYBER=m || FB_MATROX=m || FB_PM2=m || FB_CYBER2000=m || FB_SA1100)
-	default y if !FBCON_ADVANCED && (FB_ATARI || FB_PM3=y || FB_SIS=y || FB_PVR2=y || FB_TRIDENT=y || FB_TBOX || FB_VOODOO1=y || FB_RADEON=y || FB_CONTROL || FB_CLGEN=y || FB_VIRGE || FB_CYBER=y || FB_VALKYRIE || FB_PLATINUM || FB_CT65550 || FB_MATROX=y || FB_PM2=y || FB_CYBER2000=y || FB_SA1100)
-	help
-	  This is the low level frame buffer console driver for 15 or 16 bits
-	  per pixel (32K or 64K colors, also known as `hicolor') packed
-	  pixels.
-
-config FBCON_CFB24
-	tristate "24 bpp packed pixels support" if FBCON_ADVANCED
-	depends on FB
-	default m if !FBCON_ADVANCED && FB_ATY!=y && FB_VIRTUAL!=y && FB_CLGEN!=y && !FB_VESA && FB_MATROX!=y && FB_PM2!=y && FB_ATY128!=y && FB_RADEON!=y && FB_CYBER2000!=y && FB_PVR2!=y && FB_VOODOO1!=y && FB_NEOMAGIC!=y && (FB_ATY=m || FB_VIRTUAL=m || FB_CLGEN=m || FB_MATROX=m || FB_PM2=m || FB_ATY128=m || FB_RADEON=m || FB_CYBER2000=m || FB_PVR2=m || FB_VOODOO1=m || FB_NEOMAGIC=y)
-	default y if !FBCON_ADVANCED && (FB_ATY=y || FB_VIRTUAL=y || FB_CLGEN=y || FB_VESA || FB_MATROX=y || FB_PM2=y || FB_ATY128=y || FB_RADEON=y || FB_CYBER2000=y || FB_PVR2=y || FB_VOODOO1=y || FB_NEOMAGIC=y)
-	help
-	  This is the low level frame buffer console driver for 24 bits per
-	  pixel (16M colors, also known as `truecolor') packed pixels. It is
-	  NOT for `sparse' 32 bits per pixel mode.
-
-config FBCON_CFB32
-	tristate "32 bpp packed pixels support" if FBCON_ADVANCED
-	depends on FB
-	default m if !FBCON_ADVANCED && !FB_ATARI && FB_RADEON!=y && FB_VOODOO1!=y && FB_TRIDENT!=y && !FB_CONTROL && FB_CLGEN!=y && FB_TGA!=y && !FB_PLATINUM && FB_MATROX!=y && FB_PM2!=y && FB_PVR2!=y && FB_PM3!=y && FB_SIS!=y && (FB_RADEON=m || FB_VOODOO1=m || FB_TRIDENT=m || FB_CLGEN=m || FB_TGA=m || FB_MATROX=m || FB_PM2=m || FB_SIS=m || FB_PVR2=m || FB_PM3=m)
-	default y if !FBCON_ADVANCED && (FB_ATARI || FB_RADEON=y || FB_VOODOO1=y || FB_TRIDENT=y || FB_CONTROL || FB_CLGEN=y || FB_TGA=y || FB_PLATINUM || FB_MATROX=y || FB_PM2=y || FB_PVR2=y || FB_PM3=y || FB_SIS=y)
-	help
-	  This is the low level frame buffer console driver for 32 bits per
-	  pixel (16M colors, also known as `truecolor') sparse packed pixels.
-
-config FBCON_ACCEL
-	tristate "Hardware acceleration support" if FBCON_ADVANCED
-	depends on FB
-	default m if !FBCON_ADVANCED && FB_NEOMAGIC!=y && !FB_VESA && !FB_FM2 && FB_HIT!=y && !FB_HP300 && !FB_Q40 && !FB_ANAKIN && !FB_G364 && FB_VIRTUAL!=y && !FB_CLPS711X && !FB_PMAG_BA && !FB_PMAGB_B && FB_3DFX!=y && !FB_TX3912 && !FB_MAXINE && !FB_APOLLO && FB_ATY!=y && !FB_MAC && FB_RIVA!=y && !FB_OF && FB_SGIVW!=y && (FB_NEOMAGIC=m || FB_HIT=m || FB_VIRTUAL=m || FB_3DFX=m || FB_RIVA=m || FB_SGIVW=m)
-	default y if !FBCON_ADVANCED && (FB_NEOMAGIC=y || FB_VESA || FB_FM2 || FB_HIT=y || FB_HP300 || FB_Q40 || FB_ANAKIN || FB_G364 || FB_VIRTUAL=y || FB_CLPS711X || FB_PMAG_BA || FB_PMAGB_B || FB_3DFX=y || FB_TX3912 || FB_MAXINE || FB_APOLLO || FB_ATY=y || FB_MAC || FB_RIVA=y || FB_OF || FB_SGIVW=y)
-
-config FBCON_AFB
-	tristate "Amiga bitplanes support" if FBCON_ADVANCED
-	depends on FB
-	default m if !FBCON_ADVANCED && FB_AMIGA=m
-	default y if !FBCON_ADVANCED && FB_AMIGA=y
-	help
-	  This is the low level frame buffer console driver for 1 to 8
-	  bitplanes (2 to 256 colors) on Amiga.
-
-config FBCON_ILBM
-	tristate "Amiga interleaved bitplanes support" if FBCON_ADVANCED
-	depends on FB
-	default m if !FBCON_ADVANCED && FB_AMIGA=m
-	default y if !FBCON_ADVANCED && FB_AMIGA=y
-	help
-	  This is the low level frame buffer console driver for 1 to 8
-	  interleaved bitplanes (2 to 256 colors) on Amiga.
-
-config FBCON_IPLAN2P2
-	tristate "Atari interleaved bitplanes (2 planes) support" if FBCON_ADVANCED
-	depends on FB
-	default y if !FBCON_ADVANCED && FB_ATARI
-	help
-	  This is the low level frame buffer console driver for 2 interleaved
-	  bitplanes (4 colors) on Atari.
-
-config FBCON_IPLAN2P4
-	tristate "Atari interleaved bitplanes (4 planes) support" if FBCON_ADVANCED
-	depends on FB
-	default y if !FBCON_ADVANCED && FB_ATARI
-	help
-	  This is the low level frame buffer console driver for 4 interleaved
-	  bitplanes (16 colors) on Atari.
-
-config FBCON_IPLAN2P8
-	tristate "Atari interleaved bitplanes (8 planes) support" if FBCON_ADVANCED
-	depends on FB
-	default y if !FBCON_ADVANCED && FB_ATARI
-	help
-	  This is the low level frame buffer console driver for 8 interleaved
-	  bitplanes (256 colors) on Atari.
-
-#      tristate '    Atari interleaved bitplanes (16 planes) support' CONFIG_FBCON_IPLAN2P16
-config FBCON_VGA_PLANES
-	tristate "VGA 16-color planar support" if FBCON_ADVANCED
-	depends on FB
-	default m if !FBCON_ADVANCED && FB_VGA16=m
-	default y if !FBCON_ADVANCED && FB_VGA16=y
-	help
-	  This low level frame buffer console driver enable the kernel to use
-	  the 16-color planar modes of the old VGA cards where the bits of
-	  each pixel are separated into 4 planes.
-
-	  Only answer Y here if you have a (very old) VGA card that isn't VESA
-	  2 compatible.
-
-config FBCON_HGA
-	tristate "HGA monochrome support (EXPERIMENTAL)" if FBCON_ADVANCED
-	depends on FB
-	default m if !FBCON_ADVANCED && FB_HGA=m
-	default y if !FBCON_ADVANCED && FB_HGA=y
-	help
-	  This is the low level frame buffer console driver for Hercules mono
-	  graphics cards.
-
-# Guess what we need
-config FBCON_STI
-	tristate
-	depends on !FBCON_ADVANCED && FB_STI
-	default y
-
-config FBCON_FONTWIDTH8_ONLY
-	bool "Support only 8 pixels wide fonts"
-	depends on FB
-	help
-	  Answer Y here will make the kernel provide only the 8x8 fonts (these
-	  are the less readable).
-
-	  If unsure, say N.
-
-config FONT_SUN8x16
-	bool "Sparc console 8x16 font"
-	depends on FB && (!SPARC32 && !SPARC64 && FBCON_FONTS || SPARC32 || SPARC64)
-	help
-	  This is the high resolution console font for Sun machines. Say Y.
-
-config FONT_SUN12x22
-	bool "Sparc console 12x22 font (not supported by all drivers)"
-	depends on FB && !FBCON_FONTWIDTH8_ONLY && (!SPARC32 && !SPARC64 && FBCON_FONTS || SPARC32 || SPARC64)
-	help
-	  This is the high resolution console font for Sun machines with very
-	  big letters (like the letters used in the SPARC PROM). If the
-	  standard font is unreadable for you, say Y, otherwise say N.
-
-config FBCON_FONTS
-	bool "Select other fonts" if SPARC32 || SPARC64
-	depends on FB
-	help
-	  Say Y here if you would like to use fonts other than the default
-	  your frame buffer console usually use.
-
-	  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 foreign fonts.
-
-	  If unsure, say N (the default choices are safe).
-
-config FBCON_FONTS
-	prompt "Select compiled-in fonts"
-	depends on FB && !SPARC32 && !SPARC64
-
-config FONT_8x8
-	bool "VGA 8x8 font" if FBCON_FONTS
-	depends on FB
-	default y if !SPARC32 && !SPARC64 && !FBCON_FONTS
-	help
-	  This is the "high resolution" font for the VGA frame buffer (the one
-	  provided by the text console 80x50 (and higher) modes).
-
-	  Note that this is a poor quality font. The VGA 8x16 font is quite a
-	  lot more readable.
-
-	  Given the resolution provided by the frame buffer device, answer N
-	  here is safe.
-
-config FONT_8x16
-	bool "VGA 8x16 font" if FBCON_FONTS
-	depends on FB
-	default y if !SPARC32 && !SPARC64 && !FBCON_FONTS
-	help
-	  This is the "high resolution" font for the VGA frame buffer (the one
-	  provided by the VGA text console 80x25 mode.
-
-	  If unsure, say Y.
-
-config FONT_6x11
-	bool "Mac console 6x11 font (not supported by all drivers)" if FBCON_FONTS
-	depends on FB && !FBCON_FONTWIDTH8_ONLY
-	default y if !SPARC32 && !SPARC64 && !FBCON_FONTS && MAC
-	help
-	  Small console font with Macintosh-style high-half glyphs.  Some Mac
-	  framebuffer drivers don't support this one at all.
-
-config FONT_PEARL_8x8
-	bool "Pearl (old m68k) console 8x8 font" if FBCON_FONTS
-	depends on FB
-	default y if !SPARC32 && !SPARC64 && !FBCON_FONTS && AMIGA
-	help
-	  Small console font with PC-style control-character and high-half
-	  glyphs.
-
-config FONT_ACORN_8x8
-	bool "Acorn console 8x8 font" if FBCON_FONTS
-	depends on FB
-	default y if !SPARC32 && !SPARC64 && !FBCON_FONTS && ARM && ARCH_ACORN
-	help
-	  Small console font with PC-style control characters and high-half
-	  glyphs.
-
-config FONT_MINI_4x6
-	bool "Mini 4x6 font"
-	depends on !SPARC32 && !SPARC64 && FBCON_FONTS
+source "drivers/video/console/Kconfig"
 
 endmenu
 
diff -Nru a/drivers/video/Makefile b/drivers/video/Makefile
--- a/drivers/video/Makefile	Mon Dec  9 18:46:34 2002
+++ b/drivers/video/Makefile	Mon Dec  9 18:46:34 2002
@@ -5,33 +5,15 @@
 # All of the (potential) objects that export symbols.
 # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
 
-export-objs    	:= fbmem.o fbcmap.o fbcon.o fbmon.o modedb.o \
-		   fbcon-afb.o fbcon-ilbm.o fbcon-accel.o cyber2000fb.o \
-		   fbcon-iplan2p2.o fbcon-iplan2p4.o fbgen.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-mfb.o fbcon-hga.o
+export-objs    	:= fbmem.o fbcmap.o fbmon.o modedb.o softcursor.o cfbfillrect.o \
+		   cfbcopyarea.o cfbimgblt.o cyber2000fb.o vgastate.o
 
 # Each configuration option enables a list of files.
 
-obj-$(CONFIG_DUMMY_CONSOLE)       += dummycon.o
-obj-$(CONFIG_SGI_NEWPORT_CONSOLE) += newport_con.o
-obj-$(CONFIG_PROM_CONSOLE)        += promcon.o promcon_tbl.o
-obj-$(CONFIG_STI_CONSOLE)         += sticon.o sticon-bmode.o sticore.o
-obj-$(CONFIG_VGA_CONSOLE)         += vgacon.o
-obj-$(CONFIG_MDA_CONSOLE)         += mdacon.o
-
-obj-$(CONFIG_FONT_SUN8x16)        += font_sun8x16.o
-obj-$(CONFIG_FONT_SUN12x22)       += font_sun12x22.o
-obj-$(CONFIG_FONT_8x8)            += font_8x8.o
-obj-$(CONFIG_FONT_8x16)           += font_8x16.o
-obj-$(CONFIG_FONT_6x11)           += font_6x11.o
-obj-$(CONFIG_FONT_PEARL_8x8)      += font_pearl_8x8.o
-obj-$(CONFIG_FONT_ACORN_8x8)      += font_acorn_8x8.o
-obj-$(CONFIG_FONT_MINI_4x6)       += font_mini_4x6.o
+obj-$(CONFIG_VT)		  += console/
 
 # Add fbmon.o back into obj-$(CONFIG_FB) in 2.5.x
-obj-$(CONFIG_FB)                  += fbmem.o fbcmap.o modedb.o fbcon.o fonts.o fbgen.o
+obj-$(CONFIG_FB)                  += fbmem.o fbcmap.o modedb.o softcursor.o
 # Only include macmodes.o if we have FB support and are PPC
 ifeq ($(CONFIG_FB),y)
 obj-$(CONFIG_PPC)                 += macmodes.o
@@ -44,10 +26,10 @@
 obj-$(CONFIG_FB_APOLLO)           += dnfb.o cfbfillrect.o cfbimgblt.o
 obj-$(CONFIG_FB_Q40)              += q40fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_ATARI)            += atafb.o
-obj-$(CONFIG_FB_ATY128)           += aty128fb.o
+obj-$(CONFIG_FB_ATY128)           += aty128fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_RADEON)		  += radeonfb.o
 obj-$(CONFIG_FB_NEOMAGIC)         += neofb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
-obj-$(CONFIG_FB_IGA)              += igafb.o
+obj-$(CONFIG_FB_IGA)              += igafb.o cfbfillrect.o cfbcopyarea.o cfbimgblit.o
 obj-$(CONFIG_FB_CONTROL)          += controlfb.o
 obj-$(CONFIG_FB_PLATINUM)         += platinumfb.o
 obj-$(CONFIG_FB_VALKYRIE)         += valkyriefb.o
@@ -68,7 +50,8 @@
 obj-$(CONFIG_FB_S3TRIO)           += S3triofb.o
 obj-$(CONFIG_FB_TGA)              += tgafb.o
 obj-$(CONFIG_FB_VESA)             += vesafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o 
-obj-$(CONFIG_FB_VGA16)            += vga16fb.o fbcon-vga-planes.o
+obj-$(CONFIG_FB_VGA16)            += vga16fb.o cfbfillrect.o cfbcopyarea.o \
+	                             cfbimgblt.o vgastate.o 
 obj-$(CONFIG_FB_VIRGE)            += virgefb.o
 obj-$(CONFIG_FB_G364)             += g364fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_FM2)              += fm2fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
@@ -80,44 +63,27 @@
 obj-$(CONFIG_FB_CGFOURTEEN)       += cgfourteenfb.o sbusfb.o
 obj-$(CONFIG_FB_P9100)            += p9100fb.o sbusfb.o
 obj-$(CONFIG_FB_LEO)              += leofb.o sbusfb.o
-obj-$(CONFIG_FB_STI)	          += stifb.o sticore.o
+obj-$(CONFIG_FB_STI)	          += stifb.o console/sticore.o
 obj-$(CONFIG_FB_PMAG_BA)          += pmag-ba-fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_PMAGB_B)          += pmagb-b-fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_MAXINE)           += maxinefb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_TX3912)           += tx3912fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 
 obj-$(CONFIG_FB_MATROX)		  += matrox/
-obj-$(CONFIG_FB_RIVA)		  += riva/
+obj-$(CONFIG_FB_RIVA)		  += riva/ cfbfillrect.o cfbcopyarea.o \
+	                             cfbimgblt.o vgastate.o
 obj-$(CONFIG_FB_SIS)		  += sis/
 obj-$(CONFIG_FB_ATY)		  += aty/ cfbimgblt.o
 
 obj-$(CONFIG_FB_SUN3)             += sun3fb.o
 obj-$(CONFIG_FB_BWTWO)            += bwtwofb.o
-obj-$(CONFIG_FB_HGA)              += hgafb.o  
+obj-$(CONFIG_FB_HGA)              += hgafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o 
 obj-$(CONFIG_FB_SA1100)           += sa1100fb.o
 obj-$(CONFIG_FB_VIRTUAL)          += vfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o 
 obj-$(CONFIG_FB_HIT)              += hitfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_E1355)            += epson1355fb.o
 obj-$(CONFIG_FB_PVR2)             += pvr2fb.o
 obj-$(CONFIG_FB_VOODOO1)          += sstfb.o
-
-# Generic Low Level Drivers
-
-obj-$(CONFIG_FBCON_AFB)           += fbcon-afb.o
-obj-$(CONFIG_FBCON_CFB2)          += fbcon-cfb2.o
-obj-$(CONFIG_FBCON_CFB4)          += fbcon-cfb4.o
-obj-$(CONFIG_FBCON_CFB8)          += fbcon-cfb8.o
-obj-$(CONFIG_FBCON_CFB16)         += fbcon-cfb16.o
-obj-$(CONFIG_FBCON_CFB24)         += fbcon-cfb24.o
-obj-$(CONFIG_FBCON_CFB32)         += fbcon-cfb32.o
-obj-$(CONFIG_FBCON_ILBM)          += fbcon-ilbm.o
-obj-$(CONFIG_FBCON_IPLAN2P2)      += fbcon-iplan2p2.o
-obj-$(CONFIG_FBCON_IPLAN2P4)      += fbcon-iplan2p4.o
-obj-$(CONFIG_FBCON_IPLAN2P8)      += fbcon-iplan2p8.o
-obj-$(CONFIG_FBCON_MFB)           += fbcon-mfb.o
-obj-$(CONFIG_FBCON_HGA)           += fbcon-hga.o
-obj-$(CONFIG_FBCON_STI)           += fbcon-sti.o
-obj-$(CONFIG_FBCON_ACCEL)	  += fbcon-accel.o
 
 # Files generated that shall be removed upon make clean
 clean-files := promcon_tbl.c
diff -Nru a/drivers/video/S3triofb.c b/drivers/video/S3triofb.c
--- a/drivers/video/S3triofb.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/video/S3triofb.c	Mon Dec  9 18:46:51 2002
@@ -542,7 +542,7 @@
 	return;
 
     printk("fb%d: S3 Trio frame buffer device on %s\n",
-	   GET_FB_IDX(fb_info.node), dp->full_name);
+	   minor(fb_info.node), dp->full_name);
 }
 
 
diff -Nru a/drivers/video/amifb.c b/drivers/video/amifb.c
--- a/drivers/video/amifb.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/video/amifb.c	Mon Dec  9 18:46:51 2002
@@ -1771,7 +1771,7 @@
 	}
 
 	printk("fb%d: %s frame buffer device, using %ldK of video memory\n",
-	       GET_FB_IDX(fb_info.node), fb_info.modename,
+	       minor(fb_info.node), fb_info.modename,
 	       videomemorysize>>10);
 
 	return 0;
diff -Nru a/drivers/video/anakinfb.c b/drivers/video/anakinfb.c
--- a/drivers/video/anakinfb.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/video/anakinfb.c	Mon Dec  9 18:46:38 2002
@@ -20,35 +20,32 @@
 
 #include <asm/io.h>
 
-#include <video/fbcon.h>
-
-static u32 colreg[16];
+static u32 colreg[17];
 static struct fb_info fb_info;
-static struct display display;
 
 static struct fb_var_screeninfo anakinfb_var = {
-	.xres =		400,
-	.yres =		234,
-	.xres_virtual =	400,
-	.yres_virtual =	234,
-	.bits_per_pixel =16,
-	.red =		{ 11, 5, 0 },
-	.green =	{  5, 6, 0 }, 
-	.blue =		{  0, 5, 0 },
-	.activate	FB_ACTIVATE_NOW,
-	.height		-1,
-	.width		-1,
-	.vmode		FB_VMODE_NONINTERLACED,
+	.xres 		= 400,
+	.yres 		= 234,
+	.xres_virtual 	= 400,
+	.yres_virtual 	= 234,
+	.bits_per_pixel = 16,
+	.red 		= { 11, 5, 0 },
+	.green 		= {  5, 6, 0 }, 
+	.blue 		= {  0, 5, 0 },
+	.activate	= FB_ACTIVATE_NOW,
+	.height		= -1,
+	.width		= -1,
+	.vmode		= FB_VMODE_NONINTERLACED,
 };
 
 static struct fb_fix_screeninfo anakinfb_fix = {
-	.id =		"AnakinFB",
-	.smem_start =	VGA_START,
-	.smem_len =	VGA_SIZE,
-	.type =		FB_TYPE_PACKED_PIXELS,
-	.visual =	FB_VISUAL_TRUECOLOR,
-	.line_length =	400*2,
-	.accel =	FB_ACCEL_NONE,
+	.id 		= "AnakinFB",
+	.smem_start 	= VGA_START,
+	.smem_len 	= VGA_SIZE,
+	.type 		= FB_TYPE_PACKED_PIXELS,
+	.visual 	= FB_VISUAL_TRUECOLOR,
+	.line_length 	= 400*2,
+	.accel 		= FB_ACCEL_NONE,
 };
 
 static int
@@ -58,40 +55,30 @@
 	if (regno > 15)
 		return 1;
 
-	colreg[regno] = (red & 0xf800) | (green & 0xfc00 >> 5) |
-			(blue & 0xf800 >> 11);
+	((u16 *)(info->pseudo_palette))[regno] = (red & 0xf800) | (green & 0xfc00 >> 5) | (blue & 0xf800 >> 11);
 	return 0;
 }
 
 static struct fb_ops anakinfb_ops = {
 	.owner		= THIS_MODULE,
-	.fb_set_var	= gen_set_var,
-	.fb_get_cmap	= gen_get_cmap,
-	.fb_set_cmap	= gen_set_cmap,
 	.fb_setcolreg	= anakinfb_setcolreg,
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
+	.fb_cursor	= soft_cursor,
 };
 
 int __init
 anakinfb_init(void)
 {
 	memset(&fb_info, 0, sizeof(struct fb_info));
-	memset(&display, 0, sizeof(struct display));
 
-	strcpy(fb_info.modename, anakinfb_fix.id);
 	fb_info.node = NODEV;
-	fb_info.currcon = -1;
 	fb_info.flags = FBINFO_FLAG_DEFAULT;
 	fb_info.fbops = &anakinfb_ops;
 	fb_info.var = anakinfb_var;
 	fb_info.fix = anakinfb_fix;
-	fb_info.disp = &display;
-	strcpy(fb_info.fontname, "VGA8x16");
-	fb_info.changevar = NULL;
-	fb_info.switch_con = gen_switch_con;
-	fb_info.updatevar = gen_update_var;
+	fb_info.psuedo_palette = colreg;
 	if (!(request_mem_region(VGA_START, VGA_SIZE, "vga")))
 		return -ENOMEM;
 	if (fb_info.screen_base = ioremap(VGA_START, VGA_SIZE)) {
@@ -100,10 +87,9 @@
 	}
 
 	fb_alloc_cmap(&fb_info.cmap, 16, 0);
-	gen_set_disp(-1, &fb_info);
 
 	if (register_framebuffer(&fb_info) < 0) {
-		iounmap(display.screen_base);
+		iounmap(fb_info.screen_base);
 		release_mem_region(VGA_START, VGA_SIZE);
 		return -EINVAL;
 	}
diff -Nru a/drivers/video/atafb.c b/drivers/video/atafb.c
--- a/drivers/video/atafb.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/video/atafb.c	Mon Dec  9 18:46:34 2002
@@ -2816,7 +2816,7 @@
 	   printk("   virtual %dx%d\n",
 			  disp.var.xres_virtual, disp.var.yres_virtual);
 	printk("fb%d: %s frame buffer device, using %dK of video memory\n",
-	       GET_FB_IDX(fb_info.node), fb_info.modename, screen_len>>10);
+	       minor(fb_info.node), fb_info.modename, screen_len>>10);
 
 	/* TODO: This driver cannot be unloaded yet */
 	MOD_INC_USE_COUNT;
diff -Nru a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h
--- a/drivers/video/aty/atyfb.h	Mon Dec  9 18:46:50 2002
+++ b/drivers/video/aty/atyfb.h	Mon Dec  9 18:46:50 2002
@@ -3,8 +3,6 @@
  */
 
 #include <linux/config.h>
-#include <video/fbcon.h>
-
     /*
      *  Elements of the hardware specific atyfb_par structure
      */
@@ -59,19 +57,9 @@
      */
 
 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;
 };
 
 struct atyfb_par {
@@ -93,8 +81,6 @@
 	u8 blitter_may_be_busy;
 #ifdef __sparc__
 	struct pci_mmap_map *mmap_map;
-	int consolecnt;
-	int vtconsole;
 	u8 mmaped;
 	int open;
 #endif
@@ -251,11 +237,9 @@
      */
 
 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 int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor);
 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);
-
 
     /*
      *  Hardware acceleration
diff -Nru a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
--- a/drivers/video/aty/atyfb_base.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/video/aty/atyfb_base.c	Mon Dec  9 18:46:50 2002
@@ -65,9 +65,6 @@
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
-#include <video/fbcon.h>
-#include "../fbcon-accel.h"
-
 #include <video/mach64.h>
 #include "atyfb.h"
 
@@ -149,11 +146,11 @@
 static int atyfb_set_par(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 *info);
-static int atyfb_pan_display(struct fb_var_screeninfo *var, int con,
+static int atyfb_pan_display(struct fb_var_screeninfo *var,
 			     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);
+		       u_long arg, struct fb_info *info);
 extern void atyfb_fillrect(struct fb_info *info, struct fb_fillrect *rect);
 extern void atyfb_copyarea(struct fb_info *info, struct fb_copyarea *area);
 extern void atyfb_imageblit(struct fb_info *info, struct fb_image *image);
@@ -161,7 +158,7 @@
 static int atyfb_mmap(struct fb_info *info, struct file *file,
 		      struct vm_area_struct *vma);
 #endif
-static int atyfb_rasterimg(struct fb_info *info, int start);
+static int atyfb_sync(struct fb_info *info);
 
     /*
      *  Internal routines
@@ -198,21 +195,12 @@
 int atyfb_setup(char *);
 #endif
 
-int gen_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
-{
-        *var = info->var;
-        return 0;
-}
-
 static struct fb_ops atyfb_ops = {
 	.owner		= THIS_MODULE,
 	.fb_open	= atyfb_open,
 	.fb_release	= atyfb_release,
-	.fb_set_var	= gen_set_var,
 	.fb_check_var	= atyfb_check_var,
 	.fb_set_par	= atyfb_set_par,
-	.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,
@@ -220,13 +208,13 @@
 	.fb_fillrect	= atyfb_fillrect,
 	.fb_copyarea	= atyfb_copyarea,
 	.fb_imageblit	= atyfb_imageblit,
+	.fb_cursor	= soft_cursor,
 #ifdef __sparc__
 	.fb_mmap	= atyfb_mmap,
 #endif
-	.fb_rasterimg	= atyfb_rasterimg,
+	.fb_sync	= atyfb_sync,
 };
 
-static char fontname[40] __initdata = { 0 };
 static char curblink __initdata = 1;
 static char noaccel __initdata = 0;
 static u32 default_vram __initdata = 0;
@@ -944,9 +932,6 @@
 	if (user) {
 		par->open++;
 		par->mmaped = 0;
-		par->vtconsole = -1;
-	} else {
-		par->consolecnt++;
 	}
 #endif
 	return (0);
@@ -973,9 +958,6 @@
 			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;
@@ -1005,9 +987,7 @@
 				gen_set_var(&var, -1, info);
 			}
 		}
-	} else {
-		par->consolecnt--;
-	}
+	} 
 #endif
 	return (0);
 }
@@ -1018,7 +998,7 @@
      *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
      */
 
-static int atyfb_pan_display(struct fb_var_screeninfo *var, int con,
+static int atyfb_pan_display(struct fb_var_screeninfo *var,
 			     struct fb_info *info)
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
@@ -1060,7 +1040,7 @@
 #endif
 
 static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-		       u_long arg, int con, struct fb_info *info)
+		       u_long arg, struct fb_info *info)
 {
 #if defined(__sparc__) || (defined(DEBUG) && defined(CONFIG_FB_ATY_CT))
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
@@ -1150,7 +1130,7 @@
 	return 0;
 }
 
-static int atyfb_rasterimg(struct fb_info *info, int start)
+static int atyfb_sync(struct fb_info *info)
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
 
@@ -1228,18 +1208,8 @@
 
 	vma->vm_flags |= VM_IO;
 
-	if (!par->mmaped) {
-		int lastconsole = 0;
-
-		if (info->display_fg)
-			lastconsole = info->display_fg->vc_num;
+	if (!par->mmaped)
 		par->mmaped = 1;
-		if (par->consolecnt
-		    && fb_display[lastconsole].fb_info == info) {
-			par->vtconsole = lastconsole;
-			vt_cons[lastconsole]->vc_mode = KD_GRAPHICS;
-		}
-	}
 	return 0;
 }
 
@@ -1562,7 +1532,6 @@
 	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;
@@ -1843,18 +1812,9 @@
 	fb_memset((void *) info->screen_base, 0,
 		  info->fix.smem_len);
 
-	disp = info->disp;
-
-	strcpy(info->modename, info->fix.id);
 	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 = gen_update_var;
 	info->flags = FBINFO_FLAG_DEFAULT;
 
 #ifdef CONFIG_PMAC_BACKLIGHT
@@ -1965,29 +1925,20 @@
 #endif
 
 #ifdef CONFIG_FB_ATY_CT
-	if (curblink && M64_HAS(INTEGRATED)) {
+	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 */
 	info->var = var;
 
 	fb_alloc_cmap(&info->cmap, 256, 0);
 
-	gen_set_var(&var, -1, info);
-
 	if (register_framebuffer(info) < 0)
 		return 0;
 
 	fb_list = info;
 
 	printk("fb%d: %s frame buffer device on %s\n",
-	       GET_FB_IDX(info->node), info->fix.id, name);
+	       minor(info->node), info->fix.id, name);
 	return 1;
 }
 
@@ -2028,16 +1979,13 @@
 				continue;
 
 			info =
-			    kmalloc(sizeof(struct fb_info) +
-				    sizeof(struct display), GFP_ATOMIC);
+			    kmalloc(sizeof(struct fb_info), 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));
+			memset(info, 0, sizeof(struct fb_info));
 
 			default_par =
 			    kmalloc(sizeof(struct atyfb_par), GFP_ATOMIC);
@@ -2049,7 +1997,6 @@
 			}
 			memset(default_par, 0, sizeof(struct atyfb_par));
 
-			info->disp = (struct display *) (info + 1);
 			info->fix = atyfb_fix;
 			info->par = default_par;
 
@@ -2460,17 +2407,7 @@
 		return 0;
 
 	while ((this_opt = strsep(&options, ",")) != NULL) {
-		if (!strncmp(this_opt, "font:", 5)) {
-			char *p;
-			int i;
-
-			p = this_opt + 5;
-			for (i = 0; i < sizeof(fontname) - 1; i++)
-				if (!*p || *p == ' ' || *p == ',')
-					break;
-			memcpy(fontname, this_opt + 5, i);
-			fontname[i] = 0;
-		} else if (!strncmp(this_opt, "noblink", 7)) {
+		if (!strncmp(this_opt, "noblink", 7)) {
 			curblink = 0;
 		} else if (!strncmp(this_opt, "noaccel", 7)) {
 			noaccel = 1;
@@ -2694,12 +2631,8 @@
 		iounmap(info->cursor->ram);
 #endif
 #endif
-
-	if (info->cursor) {
-		if (info->cursor->timer)
-			kfree(info->cursor->timer);
+	if (info->cursor)
 		kfree(info->cursor);
-	}
 #ifdef __sparc__
 	if (par->mmap_map)
 		kfree(par->mmap_map);
diff -Nru a/drivers/video/aty/mach64_ct.c b/drivers/video/aty/mach64_ct.c
--- a/drivers/video/aty/mach64_ct.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/video/aty/mach64_ct.c	Mon Dec  9 18:46:34 2002
@@ -7,8 +7,6 @@
 
 #include <asm/io.h>
 
-#include <video/fbcon.h>
-
 #include <video/mach64.h>
 #include "atyfb.h"
 
diff -Nru a/drivers/video/aty/mach64_cursor.c b/drivers/video/aty/mach64_cursor.c
--- a/drivers/video/aty/mach64_cursor.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/video/aty/mach64_cursor.c	Mon Dec  9 18:46:51 2002
@@ -11,8 +11,6 @@
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
-#include <video/fbcon.h>
-
 #ifdef __sparc__
 #include <asm/pbm.h>
 #include <asm/fbio.h>
@@ -21,11 +19,6 @@
 #include <video/mach64.h>
 #include "atyfb.h"
 
-
-#define DEFAULT_CURSOR_BLINK_RATE	(20)
-#define CURSOR_DRAW_DELAY		(2)
-
-
     /*
      *  Hardware Cursor support.
      */
@@ -51,50 +44,48 @@
 	const u8 *red = cursor_color_map;
 	const u8 *green = cursor_color_map;
 	const u8 *blue = cursor_color_map;
-	int i;
+	u32 fg_color, bg_color;
 
 	if (!c)
 		return;
 
 #ifdef __sparc__
-	if (par->mmaped && (!info->display_fg
-			   || info->display_fg->vc_num ==
-			   par->vtconsole))
+	if (par->mmaped)
 		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];
-	}
+	fg_color = (u32) red[0] << 24;
+	fg_color |= (u32) green[0] << 16;
+	fg_color |= (u32) blue[0] << 8;
+	fg_color |= (u32) pixel[0];
+
+	bg_color = (u32) red[1] << 24;
+	bg_color |= (u32) green[1] << 16;
+	bg_color |= (u32) blue[1] << 8;
+	bg_color |= (u32) pixel[1];
 
 	wait_for_fifo(2, par);
-	aty_st_le32(CUR_CLR0, c->color[0], par);
-	aty_st_le32(CUR_CLR1, c->color[1], par);
+	aty_st_le32(CUR_CLR0, fg_color, par);
+	aty_st_le32(CUR_CLR1, bg_color, par);
 }
 
 void aty_set_cursor_shape(struct fb_info *info)
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	struct fb_cursor *cursor = &info->cursor;
 	struct aty_cursor *c = par->cursor;
 	u8 *ram, m, b;
 	int x, y;
 
 	if (!c)
 		return;
-
 #ifdef __sparc__
-	if (par->mmaped && (!info->display_fg
-			   || info->display_fg->vc_num ==
-			   par->vtconsole))
+	if (par->mmaped)
 		return;
 #endif
 
 	ram = c->ram;
-	for (y = 0; y < c->size.y; y++) {
-		for (x = 0; x < c->size.x >> 2; x++) {
+	for (y = 0; y < cursor->image.height; y++) {
+		for (x = 0; x < cursor->image.width >> 2; x++) {
 			m = c->mask[x][y];
 			b = c->bits[x][y];
 			fb_writeb(cursor_mask_lookup[m >> 4] |
@@ -108,12 +99,13 @@
 			fb_writeb(0xaa, ram++);
 		}
 	}
-	fb_memset(ram, 0xaa, (64 - c->size.y) * 16);
+	fb_memset(ram, 0xaa, (64 - cursor->image.height) * 16);
 }
 
-static void aty_set_cursor(struct fb_info *info, int on)
+static void aty_set_cursor(struct fb_info *info)
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	struct fb_cursor *cursor = &info->cursor;
 	struct aty_cursor *c = par->cursor;
 	u16 xoff, yoff;
 	int x, y;
@@ -122,14 +114,12 @@
 		return;
 
 #ifdef __sparc__
-	if (par->mmaped && (!info->display_fg
-			   || info->display_fg->vc_num ==
-			   par->vtconsole))
+	if (par->mmaped)
 		return;
 #endif
 
-	if (on) {
-		x = c->pos.x - c->hot.x - info->var.xoffset;
+	if (cursor->enable) {
+		x = cursor->image.dx - cursor->hot.x - info->var.xoffset;
 		if (x < 0) {
 			xoff = -x;
 			x = 0;
@@ -137,7 +127,7 @@
 			xoff = 0;
 		}
 
-		y = c->pos.y - c->hot.y - info->var.yoffset;
+		y = cursor->image.dy - cursor->hot.y - info->var.yoffset;
 		if (y < 0) {
 			yoff = -y;
 			y = 0;
@@ -146,10 +136,10 @@
 		}
 
 		wait_for_fifo(4, par);
-		aty_st_le32(CUR_OFFSET, (c->offset >> 3) + (yoff << 1),
+		aty_st_le32(CUR_OFFSET, (info->fix.smem_len >> 3) + (yoff << 1),
 			    par);
 		aty_st_le32(CUR_HORZ_VERT_OFF,
-			    ((u32) (64 - c->size.y + yoff) << 16) | xoff,
+			    ((u32) (64 - cursor->image.height + 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)
@@ -164,70 +154,25 @@
 		wait_for_idle(par);
 }
 
-static void aty_cursor_timer_handler(unsigned long dev_addr)
-{
-	struct fb_info *info = (struct fb_info *) dev_addr;
-	struct atyfb_par *par = (struct atyfb_par *) info->par;
-
-	if (!par->cursor)
-		return;
-
-	if (!par->cursor->enable)
-		goto out;
-
-	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:
-	par->cursor->timer->expires = jiffies + (HZ / 50);
-	add_timer(par->cursor->timer);
-}
-
-void atyfb_cursor(struct display *p, int mode, int x, int y)
+int atyfb_cursor(struct fb_info *info, struct fb_cursor *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;
+		return -1;
 
 #ifdef __sparc__
-	if (par->mmaped && (!info->display_fg
-			   || info->display_fg->vc_num ==
-			   par->vtconsole))
+	if (par->mmaped)
 		return;
 #endif
 
-	x *= fontwidth(p);
-	y *= fontheight(p);
-	if (c->pos.x == x && c->pos.y == y
-	    && (mode == CM_ERASE) == !c->enable)
-		return;
+	aty_set_cursor(info);
+	cursor->image.dx = info->cursor.image.dx;
+	cursor->image.dy = info->cursor.image.dy;
 
-	c->enable = 0;
-	if (c->on)
-		aty_set_cursor(info, 0);
-	c->pos.x = x;
-	c->pos.y = y;
-
-	switch (mode) {
-	case CM_ERASE:
-		c->on = 0;
-		break;
-
-	case CM_DRAW:
-	case CM_MOVE:
-		if (c->on)
-			aty_set_cursor(info, 1);
-		else
-			c->vbl_cnt = CURSOR_DRAW_DELAY;
-		c->enable = 1;
-		break;
-	}
+	aty_set_cursor(info);
+	return 0;
 }
 
 struct aty_cursor *__init aty_init_cursor(struct fb_info *info)
@@ -240,47 +185,31 @@
 		return 0;
 	memset(cursor, 0, sizeof(*cursor));
 
-	cursor->timer = kmalloc(sizeof(*cursor->timer), GFP_KERNEL);
-	if (!cursor->timer) {
-		kfree(cursor);
-		return 0;
-	}
-	memset(cursor->timer, 0, sizeof(*cursor->timer));
-
-	cursor->blink_rate = DEFAULT_CURSOR_BLINK_RATE;
 	info->fix.smem_len -= PAGE_SIZE;
-	cursor->offset = info->fix.smem_len;
 
 #ifdef __sparc__
-	addr = (unsigned long) info->screen_base - 0x800000 + cursor->offset;
+	addr = info->screen_base - 0x800000 + info->fix.smem_len;
 	cursor->ram = (u8 *) addr;
 #else
 #ifdef __BIG_ENDIAN
-	addr = info->fix.smem_start - 0x800000 + cursor->offset;
+	addr = info->fix.smem_start - 0x800000 + info->fix.smem_len;
 	cursor->ram = (u8 *) ioremap(addr, 1024);
 #else
-	addr = (unsigned long) info->screen_base + cursor->offset;
+	addr = (unsigned long) info->screen_base + info->fix.smem_len;
 	cursor->ram = (u8 *) addr;
 #endif
 #endif
-
 	if (!cursor->ram) {
 		kfree(cursor);
 		return NULL;
 	}
-
-	init_timer(cursor->timer);
-	cursor->timer->expires = jiffies + (HZ / 50);
-	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)
+int atyfb_set_font(struct fb_info *info, int width, int height)
 {
-	struct fb_info *info = d->fb_info;
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	struct fb_cursor *cursor = &info->cursor;
 	struct aty_cursor *c = par->cursor;
 	int i, j;
 
@@ -290,10 +219,10 @@
 			height = 16;
 		}
 
-		c->hot.x = 0;
-		c->hot.y = 0;
-		c->size.x = width;
-		c->size.y = height;
+		cursor->hot.x = 0;
+		cursor->hot.y = 0;
+		cursor->image.width = width;
+		cursor->image.height = height;
 
 		memset(c->bits, 0xff, sizeof(c->bits));
 		memset(c->mask, 0, sizeof(c->mask));
diff -Nru a/drivers/video/aty/mach64_gx.c b/drivers/video/aty/mach64_gx.c
--- a/drivers/video/aty/mach64_gx.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/video/aty/mach64_gx.c	Mon Dec  9 18:46:35 2002
@@ -9,8 +9,6 @@
 
 #include <asm/io.h>
 
-#include <video/fbcon.h>
-
 #include <video/mach64.h>
 #include "atyfb.h"
 
diff -Nru a/drivers/video/aty128fb.c b/drivers/video/aty128fb.c
--- a/drivers/video/aty128fb.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/video/aty128fb.c	Mon Dec  9 18:46:37 2002
@@ -7,13 +7,26 @@
  *                Ani Joshi / Jeff Garzik
  *                      - Code cleanup
  *
+ *                Michel Dänzer <michdaen@iiic.ethz.ch>
+ *                      - 15/16 bit cleanup
+ *                      - fix panning
+ *
+ *                Benjamin Herrenschmidt
+ *                      - pmac-specific PM stuff
+ *
  *                Andreas Hundt <andi@convergence.de>
  *                      - FB_ACTIVATE fixes
  *
+ *		  Paul Mackerras <paulus@samba.org>
+ *			- Convert to new framebuffer API,
+ *			  fix colormap setting at 16 bits/pixel (565)
+ *
+ *		  Paul Mundt 
+ *		  	- PCI hotplug
+ *
  *  Based off of Geert's atyfb.c and vfb.c.
  *
  *  TODO:
- *		- panning
  *		- monitor sensing (DDC)
  *              - virtual display
  *		- other platform support (only ppc/x86 supported)
@@ -49,7 +62,7 @@
 #include <linux/ioport.h>
 #include <asm/io.h>
 
-#ifdef CONFIG_PPC
+#ifdef CONFIG_ALL_PPC
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #include <video/macmodes.h>
@@ -71,12 +84,6 @@
 #include <asm/btext.h>
 #endif /* CONFIG_BOOTX_TEXT */
 
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb24.h>
-#include <video/fbcon-cfb32.h>
-
 #ifdef CONFIG_MTRR
 #include <asm/mtrr.h>
 #endif
@@ -92,27 +99,27 @@
 #define DBG(fmt, args...)
 #endif
 
-#ifndef CONFIG_PPC
+#ifndef CONFIG_ALL_PPC
 /* default mode */
 static struct fb_var_screeninfo default_var __initdata = {
-    /* 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
 };
 
-#else /* CONFIG_PPC */
+#else /* CONFIG_ALL_PPC */
 /* default to 1024x768 at 75Hz on PPC - this will work
  * on the iMac, the usual 640x480 @ 60Hz doesn't. */
 static struct fb_var_screeninfo default_var = {
-    /* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */
-    1024, 768, 1024, 768, 0, 0, 8, 0,
-    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-    0, 0, -1, -1, 0, 12699, 160, 32, 28, 1, 96, 3,
-    FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+	/* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */
+	1024, 768, 1024, 768, 0, 0, 8, 0,
+	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	0, 0, -1, -1, 0, 12699, 160, 32, 28, 1, 96, 3,
+	FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
 };
-#endif /* CONFIG_PPC */
+#endif /* CONFIG_ALL_PPC */
 
 /* default modedb mode */
 /* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */
@@ -131,13 +138,6 @@
 	.vmode =	FB_VMODE_NONINTERLACED
 };
 
-/* struct to hold chip description information */
-struct aty128_chip_info {
-    const char *name;
-    unsigned short device;
-    int chip_gen;
-};
-
 /* Chip generations */
 enum {
 	rage_128,
@@ -145,20 +145,46 @@
 	rage_M3
 };
 
+/*
+ * PCI driver prototypes
+ */
+static int aty128_probe(struct pci_dev *pdev,
+                               const struct pci_device_id *ent);
+static void aty128_remove(struct pci_dev *pdev);
+
 /* supported Rage128 chipsets */
-static struct aty128_chip_info aty128_pci_probe_list[] __initdata =
-{
-    {"Rage128 RE (PCI)", PCI_DEVICE_ID_ATI_RAGE128_RE, rage_128},
-    {"Rage128 RF (AGP)", PCI_DEVICE_ID_ATI_RAGE128_RF, rage_128},
-    {"Rage128 RK (PCI)", PCI_DEVICE_ID_ATI_RAGE128_RK, rage_128},
-    {"Rage128 RL (AGP)", PCI_DEVICE_ID_ATI_RAGE128_RL, rage_128},
-    {"Rage128 Pro PF (AGP)", PCI_DEVICE_ID_ATI_RAGE128_PF, rage_128_pro},
-    {"Rage128 Pro PR (PCI)", PCI_DEVICE_ID_ATI_RAGE128_PR, rage_128_pro},
-    {"Rage128 Pro TR (AGP)", PCI_DEVICE_ID_ATI_RAGE128_U3, rage_128_pro},	
-    {"Rage Mobility M3 (PCI)", PCI_DEVICE_ID_ATI_RAGE128_LE, rage_M3},
-    {"Rage Mobility M3 (AGP)", PCI_DEVICE_ID_ATI_RAGE128_LF, rage_M3},
-    {NULL, 0, rage_128}
- };
+static struct pci_device_id aty128_pci_tbl[] __devinitdata = {
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RE,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RF,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RK,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RL,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PF,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PR,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_U3,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_U1,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_LE,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M3 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_LF,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M3 },
+	{ 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, aty128_pci_tbl);
+
+static struct pci_driver aty128fb_driver = {
+	name:		"aty128fb",
+	id_table:	aty128_pci_tbl,
+	probe:		aty128_probe,
+	remove:		__devexit_p(aty128_remove),
+};
 
 /* packed BIOS settings */
 #ifndef CONFIG_PPC
@@ -190,241 +216,190 @@
 
 /* onboard memory information */
 struct aty128_meminfo {
-    u8 ML;
-    u8 MB;
-    u8 Trcd;
-    u8 Trp;
-    u8 Twr;
-    u8 CL;
-    u8 Tr2w;
-    u8 LoopLatency;
-    u8 DspOn;
-    u8 Rloop;
-    const char *name;
+	u8 ML;
+	u8 MB;
+	u8 Trcd;
+	u8 Trp;
+	u8 Twr;
+	u8 CL;
+	u8 Tr2w;
+	u8 LoopLatency;
+	u8 DspOn;
+	u8 Rloop;
+	const char *name;
 };
 
 /* various memory configurations */
 static const struct aty128_meminfo sdr_128   =
-    { 4, 4, 3, 3, 1, 3, 1, 16, 30, 16, "128-bit SDR SGRAM (1:1)" };
+	{ 4, 4, 3, 3, 1, 3, 1, 16, 30, 16, "128-bit SDR SGRAM (1:1)" };
 static const struct aty128_meminfo sdr_64    =
-    { 4, 8, 3, 3, 1, 3, 1, 17, 46, 17, "64-bit SDR SGRAM (1:1)" };
+	{ 4, 8, 3, 3, 1, 3, 1, 17, 46, 17, "64-bit SDR SGRAM (1:1)" };
 static const struct aty128_meminfo sdr_sgram =
-    { 4, 4, 1, 2, 1, 2, 1, 16, 24, 16, "64-bit SDR SGRAM (2:1)" };
+	{ 4, 4, 1, 2, 1, 2, 1, 16, 24, 16, "64-bit SDR SGRAM (2:1)" };
 static const struct aty128_meminfo ddr_sgram =
-    { 4, 4, 3, 3, 2, 3, 1, 16, 31, 16, "64-bit DDR SGRAM" };
+	{ 4, 4, 3, 3, 2, 3, 1, 16, 31, 16, "64-bit DDR SGRAM" };
 
-static const char *aty128fb_name = "ATY Rage128";
-static char fontname[40] __initdata = { 0 };
+static struct fb_fix_screeninfo aty128fb_fix __initdata = {
+	.id		= "ATY Rage128",
+	.type		= FB_TYPE_PACKED_PIXELS,
+	.visual		= FB_VISUAL_PSEUDOCOLOR,
+	.xpanstep	= 8,
+	.ypanstep	= 1,
+	.mmio_len	= 0x2000,
+	.accel		= FB_ACCEL_ATI_RAGE128,
+};
 
-static int  noaccel __initdata = 0;
 #ifdef MODULE
-static char *font __initdata = NULL;
 static char *mode __initdata = NULL;
 #ifdef CONFIG_MTRR
 static int  nomtrr __initdata = 0;
-#endif
+#endif /* CONFIG_MTRR */
 #endif /* MODULE */
 
 static char *mode_option __initdata = NULL;
 
-#ifdef CONFIG_PPC
+#ifdef CONFIG_ALL_PPC
 static int default_vmode __initdata = VMODE_1024_768_60;
 static int default_cmode __initdata = CMODE_8;
 #endif
 
+#ifdef CONFIG_PMAC_PBOOK
+static int default_crt_on __initdata = 0;
+static int default_lcd_on __initdata = 1;
+#endif
+
 #ifdef CONFIG_MTRR
 static int mtrr = 1;
 #endif
 
 /* PLL constants */
 struct aty128_constants {
-    u32 dotclock;
-    u32 ppll_min;
-    u32 ppll_max;
-    u32 ref_divider;
-    u32 xclk;
-    u32 fifo_width;
-    u32 fifo_depth;
+	u32 dotclock;
+	u32 ppll_min;
+	u32 ppll_max;
+	u32 ref_divider;
+	u32 xclk;
+	u32 fifo_width;
+	u32 fifo_depth;
 };
 
 struct aty128_crtc {
-    u32 gen_cntl;
-    u32 ext_cntl;
-    u32 h_total, h_sync_strt_wid;
-    u32 v_total, v_sync_strt_wid;
-    u32 pitch;
-    u32 offset, offset_cntl;
-    u32 xoffset, yoffset;
-    u32 vxres, vyres;
-    u32 bpp;
+	u32 gen_cntl;
+	u32 ext_cntl;
+	u32 h_total, h_sync_strt_wid;
+	u32 v_total, v_sync_strt_wid;
+	u32 pitch;
+	u32 offset, offset_cntl;
+	u32 xoffset, yoffset;
+	u32 vxres, vyres;
+	u32 depth, bpp;
 };
 
 struct aty128_pll {
-    u32 post_divider;
-    u32 feedback_divider;
-    u32 vclk;
+	u32 post_divider;
+	u32 feedback_divider;
+	u32 vclk;
 };
 
 struct aty128_ddafifo {
-    u32 dda_config;
-    u32 dda_on_off;
+	u32 dda_config;
+	u32 dda_on_off;
 };
 
 /* register values for a specific mode */
 struct aty128fb_par {
-    struct aty128_crtc crtc;
-    struct aty128_pll pll;
-    struct aty128_ddafifo fifo_reg;
-    u32 accel_flags;
-};
-
-struct fb_info_aty128 {
-    struct fb_info fb_info;
-    struct fb_info_aty128 *next;
-    struct aty128_constants constants;  /* PLL and others      */
-    unsigned long regbase_phys;         /* physical mmio       */
-    void *regbase;                      /* remapped mmio       */
-    unsigned long frame_buffer_phys;    /* physical fb memory  */
-    void *frame_buffer;                 /* remaped framebuffer */
-    u32 vram_size;                      /* onboard video ram   */
-    int chip_gen;
-    const struct aty128_meminfo *mem;   /* onboard mem info    */
-    struct aty128fb_par default_par, current_par;
-    struct display disp;
-    struct { u8 red, green, blue, pad; } palette[256];
-    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;
-#ifdef CONFIG_PCI
-    struct pci_dev *pdev;
-#endif
+	struct aty128_crtc crtc;
+	struct aty128_pll pll;
+	struct aty128_ddafifo fifo_reg;
+	u32 accel_flags;
+	struct aty128_constants constants;  /* PLL and others      */
+	void *regbase;                      /* remapped mmio       */
+	u32 vram_size;                      /* onboard video ram   */
+	int chip_gen;
+	const struct aty128_meminfo *mem;   /* onboard mem info    */
 #ifdef CONFIG_MTRR
-    struct { int vram; int vram_valid; } mtrr;
+	struct { int vram; int vram_valid; } mtrr;
 #endif
-    int blitter_may_be_busy;
-    int fifo_slots;                 /* free slots in FIFO (64 max) */
+	int blitter_may_be_busy;
+	int fifo_slots;                 /* free slots in FIFO (64 max) */
+#ifdef CONFIG_PMAC_PBOOK
+	unsigned char *save_framebuffer;
+	int	pm_reg;
+	int crt_on, lcd_on;
+#endif
+	unsigned char red[64];	/* see comments in aty128fb_setcolreg */
+	unsigned char green[64];
+	unsigned char blue[64];
 };
 
-static struct fb_info_aty128 *board_list = NULL;
+#ifdef CONFIG_PMAC_PBOOK
+int aty128_sleep_notify(struct pmu_sleep_notifier *self, int when);
+static struct pmu_sleep_notifier aty128_sleep_notifier = {
+	aty128_sleep_notify, SLEEP_LEVEL_VIDEO,
+};
+#endif
 
 #define round_div(n, d) ((n+(d/2))/d)
 
     /*
      *  Interface used by the world
      */
-
+int aty128fb_init(void);
 int aty128fb_setup(char *options);
 
-static int aty128fb_get_fix(struct fb_fix_screeninfo *fix, int con,
-		       struct fb_info *info);
-static int aty128fb_get_var(struct fb_var_screeninfo *var, int con,
-		       struct fb_info *info);
-static int aty128fb_set_var(struct fb_var_screeninfo *var, int con,
-		       struct fb_info *info);
-static int aty128fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			struct fb_info *info);
+static int aty128fb_check_var(struct fb_var_screeninfo *var,
+			      struct fb_info *info);
+static int aty128fb_set_par(struct fb_info *info);
 static int aty128fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 			      u_int transp, struct fb_info *info);
-static int aty128fb_pan_display(struct fb_var_screeninfo *var, int con,
+static int aty128fb_pan_display(struct fb_var_screeninfo *var,
 			   struct fb_info *fb);
 static int aty128fb_blank(int blank, struct fb_info *fb);
-static int aty128fb_rasterimg(struct fb_info *info, int start);
-
-    /*
-     *  Interface to the low level console driver
-     */
-
-int aty128fb_init(void);
-static int aty128fbcon_switch(int con, struct fb_info *fb);
+static int aty128fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+			  u_long arg, struct fb_info *info);
+static int aty128fb_sync(struct fb_info *info);
 
     /*
      *  Internal routines
      */
 
-static void aty128_encode_fix(struct fb_fix_screeninfo *fix,
-				struct aty128fb_par *par,
-				const struct fb_info_aty128 *info);
-static void aty128_set_dispsw(struct display *disp,
-			struct fb_info_aty128 *info, int bpp, int accel);
-static int aty128_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-				u_int *transp, struct fb_info *info);
 static int aty128_encode_var(struct fb_var_screeninfo *var,
-                             const struct aty128fb_par *par,
-                             const struct fb_info_aty128 *info);
+                             const struct aty128fb_par *par);
 static int aty128_decode_var(struct fb_var_screeninfo *var,
-                             struct aty128fb_par *par,
-                             const struct fb_info_aty128 *info);
-static int aty128_pci_register(struct pci_dev *pdev,
-                               const struct aty128_chip_info *aci);
-static struct fb_info_aty128 *aty128_board_list_add(struct fb_info_aty128
-				*board_list, struct fb_info_aty128 *new_node);
+                             struct aty128fb_par *par);
 #if !defined(CONFIG_PPC) && !defined(__sparc__)
-static void __init aty128_get_pllinfo(struct fb_info_aty128 *info,
-			char *bios_seg);
-static char __init *aty128find_ROM(struct fb_info_aty128 *info);
-#endif
-static void aty128_timings(struct fb_info_aty128 *info);
-static void aty128_init_engine(const struct aty128fb_par *par, 
-				struct fb_info_aty128 *info);
-static void aty128_reset_engine(const struct fb_info_aty128 *info);
-static void aty128_flush_pixel_cache(const struct fb_info_aty128 *info);
-static void do_wait_for_fifo(u16 entries, struct fb_info_aty128 *info);
-static void wait_for_fifo(u16 entries, struct fb_info_aty128 *info);
-static void wait_for_idle(struct fb_info_aty128 *info);
-static u32 bpp_to_depth(u32 bpp);
-
-#ifdef FBCON_HAS_CFB8
-static struct display_switch fbcon_aty128_8;
-static void fbcon_aty8_putc(struct vc_data *conp, struct display *p,
-                            int c, int yy, int xx);
-static void fbcon_aty8_putcs(struct vc_data *conp, struct display *p,
-                             const unsigned short *s, int count,
-                             int yy, int xx);
-#endif
-#ifdef FBCON_HAS_CFB16
-static struct display_switch fbcon_aty128_16;
-static void fbcon_aty16_putc(struct vc_data *conp, struct display *p,
-                            int c, int yy, int xx);
-static void fbcon_aty16_putcs(struct vc_data *conp, struct display *p,
-                             const unsigned short *s, int count,
-                             int yy, int xx);
-#endif
-#ifdef FBCON_HAS_CFB24
-static struct display_switch fbcon_aty128_24;
-static void fbcon_aty24_putc(struct vc_data *conp, struct display *p,
-                            int c, int yy, int xx);
-static void fbcon_aty24_putcs(struct vc_data *conp, struct display *p,
-                             const unsigned short *s, int count,
-                             int yy, int xx);
-#endif
-#ifdef FBCON_HAS_CFB32
-static struct display_switch fbcon_aty128_32;
-static void fbcon_aty32_putc(struct vc_data *conp, struct display *p,
-                            int c, int yy, int xx);
-static void fbcon_aty32_putcs(struct vc_data *conp, struct display *p,
-                             const unsigned short *s, int count,
-                             int yy, int xx);
-#endif
+static void __init aty128_get_pllinfo(struct aty128fb_par *par,
+				      char *bios_seg);
+static char __init *aty128find_ROM(void);
+#endif
+static void aty128_timings(struct aty128fb_par *par);
+static void aty128_init_engine(struct aty128fb_par *par);
+static void aty128_reset_engine(const struct aty128fb_par *par);
+static void aty128_flush_pixel_cache(const struct aty128fb_par *par);
+static void do_wait_for_fifo(u16 entries, struct aty128fb_par *par);
+static void wait_for_fifo(u16 entries, struct aty128fb_par *par);
+static void wait_for_idle(struct aty128fb_par *par);
+static u32 depth_to_dst(u32 depth);
 
 static struct fb_ops aty128fb_ops = {
-	.owner =	THIS_MODULE,
-	.fb_get_fix =	aty128fb_get_fix,
-	.fb_get_var =	aty128fb_get_var,
-	.fb_set_var =	aty128fb_set_var,
-	.fb_get_cmap =	aty128fb_get_cmap,
-	.fb_set_cmap =	gen_set_cmap,
-	.fb_setcolreg =	aty128fb_setcolreg,
-	.fb_pan_display =aty128fb_pan_display,
-	.fb_blank =	aty128fb_blank,
-	.fb_rasterimg =	aty128fb_rasterimg,
+	.owner		= THIS_MODULE,
+	.fb_check_var	= aty128fb_check_var,
+	.fb_set_par	= aty128fb_set_par,
+	.fb_setcolreg	= aty128fb_setcolreg,
+	.fb_pan_display = aty128fb_pan_display,
+	.fb_blank	= aty128fb_blank,
+	.fb_ioctl	= aty128fb_ioctl,
+	.fb_sync	= aty128fb_sync,
+#if 0
+	.fb_fillrect	= aty128fb_fillrect,
+	.fb_copyarea	= aty128fb_copyarea,
+	.fb_imageblit	= aty128fb_imageblit,
+#else
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit,
+#endif
+	.fb_cursor	= soft_cursor,
 };
 
 #ifdef CONFIG_PMAC_BACKLIGHT
@@ -443,1379 +418,1208 @@
      *    using the other register aperture. TODO.
      */
 static inline u32
-_aty_ld_le32(volatile unsigned int regindex, 
-                              const struct fb_info_aty128 *info)
+_aty_ld_le32(volatile unsigned int regindex, const struct aty128fb_par *par)
 {
-    u32 val;
+	u32 val;
 
 #if defined(__powerpc__)
-    asm("lwbrx %0,%1,%2;eieio" : "=r"(val) : "b"(regindex), "r"(info->regbase));
+	asm("lwbrx %0,%1,%2;eieio" : "=r"(val) : "b"(regindex), "r"(par->regbase));
 #else
-    val = readl (info->regbase + regindex);
+	val = readl (par->regbase + regindex);
 #endif
 
-    return val;
+	return val;
 }
 
 static inline void
 _aty_st_le32(volatile unsigned int regindex, u32 val, 
-                               const struct fb_info_aty128 *info)
+                               const struct aty128fb_par *par)
 {
 #if defined(__powerpc__)
-    asm("stwbrx %0,%1,%2;eieio" : : "r"(val), "b"(regindex),
-                "r"(info->regbase) : "memory");
+	asm("stwbrx %0,%1,%2;eieio" : : "r"(val), "b"(regindex),
+	    "r"(par->regbase) : "memory");
 #else
-    writel (val, info->regbase + regindex);
+	writel (val, par->regbase + regindex);
 #endif
 }
 
 static inline u8
-_aty_ld_8(unsigned int regindex, const struct fb_info_aty128 *info)
+_aty_ld_8(unsigned int regindex, const struct aty128fb_par *par)
 {
-    return readb (info->regbase + regindex);
+	return readb (par->regbase + regindex);
 }
 
 static inline void
-_aty_st_8(unsigned int regindex, u8 val, const struct fb_info_aty128 *info)
+_aty_st_8(unsigned int regindex, u8 val, const struct aty128fb_par *par)
 {
-    writeb (val, info->regbase + regindex);
+	writeb (val, par->regbase + regindex);
 }
 
-#define aty_ld_le32(regindex)		_aty_ld_le32(regindex, info)
-#define aty_st_le32(regindex, val)	_aty_st_le32(regindex, val, info)
-#define aty_ld_8(regindex)		_aty_ld_8(regindex, info)
-#define aty_st_8(regindex, val)		_aty_st_8(regindex, val, info)
+#define aty_ld_le32(regindex)		_aty_ld_le32(regindex, par)
+#define aty_st_le32(regindex, val)	_aty_st_le32(regindex, val, par)
+#define aty_ld_8(regindex)		_aty_ld_8(regindex, par)
+#define aty_st_8(regindex, val)		_aty_st_8(regindex, val, par)
 
     /*
      * Functions to read from/write to the pll registers
      */
 
-#define aty_ld_pll(pll_index)		_aty_ld_pll(pll_index, info)
-#define aty_st_pll(pll_index, val)	_aty_st_pll(pll_index, val, info)
+#define aty_ld_pll(pll_index)		_aty_ld_pll(pll_index, par)
+#define aty_st_pll(pll_index, val)	_aty_st_pll(pll_index, val, par)
 
 
 static u32
 _aty_ld_pll(unsigned int pll_index,
-			const struct fb_info_aty128 *info)
+			const struct aty128fb_par *par)
 {       
-    aty_st_8(CLOCK_CNTL_INDEX, pll_index & 0x1F);
-    return aty_ld_le32(CLOCK_CNTL_DATA);
+	aty_st_8(CLOCK_CNTL_INDEX, pll_index & 0x3F);
+	return aty_ld_le32(CLOCK_CNTL_DATA);
 }
 
     
 static void
 _aty_st_pll(unsigned int pll_index, u32 val,
-			const struct fb_info_aty128 *info)
+			const struct aty128fb_par *par)
 {
-    aty_st_8(CLOCK_CNTL_INDEX, (pll_index & 0x1F) | PLL_WR_EN);
-    aty_st_le32(CLOCK_CNTL_DATA, val);
+	aty_st_8(CLOCK_CNTL_INDEX, (pll_index & 0x3F) | PLL_WR_EN);
+	aty_st_le32(CLOCK_CNTL_DATA, val);
 }
 
 
 /* return true when the PLL has completed an atomic update */
 static int
-aty_pll_readupdate(const struct fb_info_aty128 *info)
+aty_pll_readupdate(const struct aty128fb_par *par)
 {
-    return !(aty_ld_pll(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R);
+	return !(aty_ld_pll(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R);
 }
 
 
 static void
-aty_pll_wait_readupdate(const struct fb_info_aty128 *info)
+aty_pll_wait_readupdate(const struct aty128fb_par *par)
 {
-    unsigned long timeout = jiffies + HZ/100;	// should be more than enough
-    int reset = 1;
+	unsigned long timeout = jiffies + HZ/100; // should be more than enough
+	int reset = 1;
 
-    while (time_before(jiffies, timeout))
-	if (aty_pll_readupdate(info)) {
-	    reset = 0;
-	    break;
-	}
+	while (time_before(jiffies, timeout))
+		if (aty_pll_readupdate(par)) {
+			reset = 0;
+			break;
+		}
 
-    if (reset)	/* reset engine?? */
-	printk(KERN_DEBUG "aty128fb: PLL write timeout!\n");
+	if (reset)	/* reset engine?? */
+		printk(KERN_DEBUG "aty128fb: PLL write timeout!\n");
 }
 
 
 /* tell PLL to update */
 static void
-aty_pll_writeupdate(const struct fb_info_aty128 *info)
+aty_pll_writeupdate(const struct aty128fb_par *par)
 {
-    aty_pll_wait_readupdate(info);
+	aty_pll_wait_readupdate(par);
 
-    aty_st_pll(PPLL_REF_DIV,
-	aty_ld_pll(PPLL_REF_DIV) | PPLL_ATOMIC_UPDATE_W);
+	aty_st_pll(PPLL_REF_DIV,
+		   aty_ld_pll(PPLL_REF_DIV) | PPLL_ATOMIC_UPDATE_W);
 }
 
 
 /* write to the scratch register to test r/w functionality */
 static int __init
-register_test(const struct fb_info_aty128 *info)
+register_test(const struct aty128fb_par *par)
 {
-    u32 val;
-    int flag = 0;
+	u32 val;
+	int flag = 0;
 
-    val = aty_ld_le32(BIOS_0_SCRATCH);
+	val = aty_ld_le32(BIOS_0_SCRATCH);
 
-    aty_st_le32(BIOS_0_SCRATCH, 0x55555555);
-    if (aty_ld_le32(BIOS_0_SCRATCH) == 0x55555555) {
-	aty_st_le32(BIOS_0_SCRATCH, 0xAAAAAAAA);
+	aty_st_le32(BIOS_0_SCRATCH, 0x55555555);
+	if (aty_ld_le32(BIOS_0_SCRATCH) == 0x55555555) {
+		aty_st_le32(BIOS_0_SCRATCH, 0xAAAAAAAA);
 
-	if (aty_ld_le32(BIOS_0_SCRATCH) == 0xAAAAAAAA)
-	    flag = 1; 
-    }
+		if (aty_ld_le32(BIOS_0_SCRATCH) == 0xAAAAAAAA)
+			flag = 1; 
+	}
 
-    aty_st_le32(BIOS_0_SCRATCH, val);	// restore value
-    return flag;
+	aty_st_le32(BIOS_0_SCRATCH, val);	// restore value
+	return flag;
 }
 
 
-    /*
-     * Accelerator engine functions
-     */
+/*
+ * Accelerator engine functions
+ */
 static void
-do_wait_for_fifo(u16 entries, struct fb_info_aty128 *info)
+do_wait_for_fifo(u16 entries, struct aty128fb_par *par)
 {
-    int i;
+	int i;
 
-    for (;;) {
-        for (i = 0; i < 2000000; i++) {
-            info->fifo_slots = aty_ld_le32(GUI_STAT) & 0x0fff;
-            if (info->fifo_slots >= entries)
-                return;
-        }
-	aty128_reset_engine(info);
-    }
+	for (;;) {
+		for (i = 0; i < 2000000; i++) {
+			par->fifo_slots = aty_ld_le32(GUI_STAT) & 0x0fff;
+			if (par->fifo_slots >= entries)
+				return;
+		}
+		aty128_reset_engine(par);
+	}
 }
 
 
 static void
-wait_for_idle(struct fb_info_aty128 *info)
+wait_for_idle(struct aty128fb_par *par)
 {
-    int i;
+	int i;
 
-    do_wait_for_fifo(64, info);
+	do_wait_for_fifo(64, par);
 
-    for (;;) {
-        for (i = 0; i < 2000000; i++) {
-            if (!(aty_ld_le32(GUI_STAT) & (1 << 31))) {
-                aty128_flush_pixel_cache(info);
-                info->blitter_may_be_busy = 0;
-                return;
-            }
-        }
-        aty128_reset_engine(info);
-    }
+	for (;;) {
+		for (i = 0; i < 2000000; i++) {
+			if (!(aty_ld_le32(GUI_STAT) & (1 << 31))) {
+				aty128_flush_pixel_cache(par);
+				par->blitter_may_be_busy = 0;
+				return;
+			}
+		}
+		aty128_reset_engine(par);
+	}
 }
 
 
 static void
-wait_for_fifo(u16 entries, struct fb_info_aty128 *info)
+wait_for_fifo(u16 entries, struct aty128fb_par *par)
 {
-    if (info->fifo_slots < entries)
-        do_wait_for_fifo(64, info);
-    info->fifo_slots -= entries;
+	if (par->fifo_slots < entries)
+		do_wait_for_fifo(64, par);
+	par->fifo_slots -= entries;
 }
 
 
 static void
-aty128_flush_pixel_cache(const struct fb_info_aty128 *info)
+aty128_flush_pixel_cache(const struct aty128fb_par *par)
 {
-    int i;
-    u32 tmp;
+	int i;
+	u32 tmp;
 
-    tmp = aty_ld_le32(PC_NGUI_CTLSTAT);
-    tmp &= ~(0x00ff);
-    tmp |= 0x00ff;
-    aty_st_le32(PC_NGUI_CTLSTAT, tmp);
-
-    for (i = 0; i < 2000000; i++)
-        if (!(aty_ld_le32(PC_NGUI_CTLSTAT) & PC_BUSY))
-            break;
+	tmp = aty_ld_le32(PC_NGUI_CTLSTAT);
+	tmp &= ~(0x00ff);
+	tmp |= 0x00ff;
+	aty_st_le32(PC_NGUI_CTLSTAT, tmp);
+
+	for (i = 0; i < 2000000; i++)
+		if (!(aty_ld_le32(PC_NGUI_CTLSTAT) & PC_BUSY))
+			break;
 }
 
 
 static void
-aty128_reset_engine(const struct fb_info_aty128 *info)
+aty128_reset_engine(const struct aty128fb_par *par)
 {
-    u32 gen_reset_cntl, clock_cntl_index, mclk_cntl;
+	u32 gen_reset_cntl, clock_cntl_index, mclk_cntl;
 
-    aty128_flush_pixel_cache(info);
+	aty128_flush_pixel_cache(par);
 
-    clock_cntl_index = aty_ld_le32(CLOCK_CNTL_INDEX);
-    mclk_cntl = aty_ld_pll(MCLK_CNTL);
+	clock_cntl_index = aty_ld_le32(CLOCK_CNTL_INDEX);
+	mclk_cntl = aty_ld_pll(MCLK_CNTL);
 
-    aty_st_pll(MCLK_CNTL, mclk_cntl | 0x00030000);
+	aty_st_pll(MCLK_CNTL, mclk_cntl | 0x00030000);
 
-    gen_reset_cntl = aty_ld_le32(GEN_RESET_CNTL);
-    aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl | SOFT_RESET_GUI);
-    aty_ld_le32(GEN_RESET_CNTL);
-    aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl & ~(SOFT_RESET_GUI));
-    aty_ld_le32(GEN_RESET_CNTL);
+	gen_reset_cntl = aty_ld_le32(GEN_RESET_CNTL);
+	aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl | SOFT_RESET_GUI);
+	aty_ld_le32(GEN_RESET_CNTL);
+	aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl & ~(SOFT_RESET_GUI));
+	aty_ld_le32(GEN_RESET_CNTL);
 
-    aty_st_pll(MCLK_CNTL, mclk_cntl);
-    aty_st_le32(CLOCK_CNTL_INDEX, clock_cntl_index);
-    aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl);
+	aty_st_pll(MCLK_CNTL, mclk_cntl);
+	aty_st_le32(CLOCK_CNTL_INDEX, clock_cntl_index);
+	aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl);
 
-    /* use old pio mode */
-    aty_st_le32(PM4_BUFFER_CNTL, PM4_BUFFER_CNTL_NONPM4);
+	/* use old pio mode */
+	aty_st_le32(PM4_BUFFER_CNTL, PM4_BUFFER_CNTL_NONPM4);
 
-    DBG("engine reset");
+	DBG("engine reset");
 }
 
 
 static void
-aty128_init_engine(const struct aty128fb_par *par,
-		struct fb_info_aty128 *info)
+aty128_init_engine(struct aty128fb_par *par)
 {
-    u32 pitch_value;
+	u32 pitch_value;
 
-    wait_for_idle(info);
+	wait_for_idle(par);
 
-    /* 3D scaler not spoken here */
-    wait_for_fifo(1, info);
-    aty_st_le32(SCALE_3D_CNTL, 0x00000000);
+	/* 3D scaler not spoken here */
+	wait_for_fifo(1, par);
+	aty_st_le32(SCALE_3D_CNTL, 0x00000000);
 
-    aty128_reset_engine(info);
+	aty128_reset_engine(par);
 
-    pitch_value = par->crtc.pitch;
-    if (par->crtc.bpp == 24) {
-        pitch_value = pitch_value * 3;
-    }
+	pitch_value = par->crtc.pitch;
+	if (par->crtc.bpp == 24) {
+		pitch_value = pitch_value * 3;
+	}
 
-    wait_for_fifo(4, info);
-    /* setup engine offset registers */
-    aty_st_le32(DEFAULT_OFFSET, 0x00000000);
-
-    /* setup engine pitch registers */
-    aty_st_le32(DEFAULT_PITCH, pitch_value);
-
-    /* set the default scissor register to max dimensions */
-    aty_st_le32(DEFAULT_SC_BOTTOM_RIGHT, (0x1FFF << 16) | 0x1FFF);
-
-    /* set the drawing controls registers */
-    aty_st_le32(DP_GUI_MASTER_CNTL,
-		GMC_SRC_PITCH_OFFSET_DEFAULT		|
-		GMC_DST_PITCH_OFFSET_DEFAULT		|
-		GMC_SRC_CLIP_DEFAULT			|
-		GMC_DST_CLIP_DEFAULT			|
-		GMC_BRUSH_SOLIDCOLOR			|
-		(bpp_to_depth(par->crtc.bpp) << 8)	|
-		GMC_SRC_DSTCOLOR			|
-		GMC_BYTE_ORDER_MSB_TO_LSB		|
-		GMC_DP_CONVERSION_TEMP_6500		|
-		ROP3_PATCOPY				|
-		GMC_DP_SRC_RECT				|
-		GMC_3D_FCN_EN_CLR			|
-		GMC_DST_CLR_CMP_FCN_CLEAR		|
-		GMC_AUX_CLIP_CLEAR			|
-		GMC_WRITE_MASK_SET);
-
-    wait_for_fifo(8, info);
-    /* clear the line drawing registers */
-    aty_st_le32(DST_BRES_ERR, 0);
-    aty_st_le32(DST_BRES_INC, 0);
-    aty_st_le32(DST_BRES_DEC, 0);
-
-    /* set brush color registers */
-    aty_st_le32(DP_BRUSH_FRGD_CLR, 0xFFFFFFFF); /* white */
-    aty_st_le32(DP_BRUSH_BKGD_CLR, 0x00000000); /* black */
-
-    /* set source color registers */
-    aty_st_le32(DP_SRC_FRGD_CLR, 0xFFFFFFFF);   /* white */
-    aty_st_le32(DP_SRC_BKGD_CLR, 0x00000000);   /* black */
-
-    /* default write mask */
-    aty_st_le32(DP_WRITE_MASK, 0xFFFFFFFF);
+	wait_for_fifo(4, par);
+	/* setup engine offset registers */
+	aty_st_le32(DEFAULT_OFFSET, 0x00000000);
+
+	/* setup engine pitch registers */
+	aty_st_le32(DEFAULT_PITCH, pitch_value);
+
+	/* set the default scissor register to max dimensions */
+	aty_st_le32(DEFAULT_SC_BOTTOM_RIGHT, (0x1FFF << 16) | 0x1FFF);
+
+	/* set the drawing controls registers */
+	aty_st_le32(DP_GUI_MASTER_CNTL,
+		    GMC_SRC_PITCH_OFFSET_DEFAULT		|
+		    GMC_DST_PITCH_OFFSET_DEFAULT		|
+		    GMC_SRC_CLIP_DEFAULT			|
+		    GMC_DST_CLIP_DEFAULT			|
+		    GMC_BRUSH_SOLIDCOLOR			|
+		    (depth_to_dst(par->crtc.depth) << 8)	|
+		    GMC_SRC_DSTCOLOR			|
+		    GMC_BYTE_ORDER_MSB_TO_LSB		|
+		    GMC_DP_CONVERSION_TEMP_6500		|
+		    ROP3_PATCOPY				|
+		    GMC_DP_SRC_RECT				|
+		    GMC_3D_FCN_EN_CLR			|
+		    GMC_DST_CLR_CMP_FCN_CLEAR		|
+		    GMC_AUX_CLIP_CLEAR			|
+		    GMC_WRITE_MASK_SET);
+
+	wait_for_fifo(8, par);
+	/* clear the line drawing registers */
+	aty_st_le32(DST_BRES_ERR, 0);
+	aty_st_le32(DST_BRES_INC, 0);
+	aty_st_le32(DST_BRES_DEC, 0);
+
+	/* set brush color registers */
+	aty_st_le32(DP_BRUSH_FRGD_CLR, 0xFFFFFFFF); /* white */
+	aty_st_le32(DP_BRUSH_BKGD_CLR, 0x00000000); /* black */
+
+	/* set source color registers */
+	aty_st_le32(DP_SRC_FRGD_CLR, 0xFFFFFFFF);   /* white */
+	aty_st_le32(DP_SRC_BKGD_CLR, 0x00000000);   /* black */
+
+	/* default write mask */
+	aty_st_le32(DP_WRITE_MASK, 0xFFFFFFFF);
 
-    /* Wait for all the writes to be completed before returning */
-    wait_for_idle(info);
+	/* Wait for all the writes to be completed before returning */
+	wait_for_idle(par);
 }
 
 
-/* convert bpp values to their register representation */
+/* convert depth values to their register representation */
 static u32
-bpp_to_depth(u32 bpp)
+depth_to_dst(u32 depth)
 {
-    if (bpp <= 8)
-	return DST_8BPP;
-    else if (bpp <= 16)
-        return DST_15BPP;
-    else if (bpp <= 24)
-	return DST_24BPP;
-    else if (bpp <= 32)
-	return DST_32BPP;
+	if (depth <= 8)
+		return DST_8BPP;
+	else if (depth <= 15)
+		return DST_15BPP;
+	else if (depth == 16)
+		return DST_16BPP;
+	else if (depth <= 24)
+		return DST_24BPP;
+	else if (depth <= 32)
+		return DST_32BPP;
 
-    return -EINVAL;
+	return -EINVAL;
 }
 
 
-    /*
+/*
      * CRTC programming
      */
 
 /* Program the CRTC registers */
 static void
 aty128_set_crtc(const struct aty128_crtc *crtc,
-		const struct fb_info_aty128 *info)
+		const struct aty128fb_par *par)
 {
-    aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl);
-    aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_total);
-    aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid);
-    aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_total);
-    aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid);
-    aty_st_le32(CRTC_PITCH, crtc->pitch);
-    aty_st_le32(CRTC_OFFSET, crtc->offset);
-    aty_st_le32(CRTC_OFFSET_CNTL, crtc->offset_cntl);
-    /* Disable ATOMIC updating.  Is this the right place?
-     * -- BenH: Breaks on my G4
-     */
-#if 0
-    aty_st_le32(PPLL_CNTL, aty_ld_le32(PPLL_CNTL) & ~(0x00030000));
-#endif
+	aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl);
+	aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_total);
+	aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid);
+	aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_total);
+	aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid);
+	aty_st_le32(CRTC_PITCH, crtc->pitch);
+	aty_st_le32(CRTC_OFFSET, crtc->offset);
+	aty_st_le32(CRTC_OFFSET_CNTL, crtc->offset_cntl);
+	/* Disable ATOMIC updating.  Is this the right place? */
+	aty_st_pll(PPLL_CNTL, aty_ld_pll(PPLL_CNTL) & ~(0x00030000));
 }
 
 
 static int
 aty128_var_to_crtc(const struct fb_var_screeninfo *var,
-			struct aty128_crtc *crtc,
-			const struct fb_info_aty128 *info)
+		   struct aty128_crtc *crtc,
+		   const struct aty128fb_par *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_wid, h_sync_pol;
-    u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
-    u32 depth, bytpp;
-    u8 hsync_strt_pix[5] = { 0, 0x12, 9, 6, 5 };
-    u8 mode_bytpp[7] = { 0, 0, 1, 2, 2, 3, 4 };
-
-    /* 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;
-
-    /* check for mode eligibility
-     * accept only non interlaced modes */
-    if ((vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
-	return -EINVAL;
+	u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp, dst;
+	u32 left, right, upper, lower, hslen, vslen, sync, vmode;
+	u32 h_total, h_disp, h_sync_strt, h_sync_wid, h_sync_pol;
+	u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
+	u32 depth, bytpp;
+	u8 mode_bytpp[7] = { 0, 0, 1, 2, 2, 3, 4 };
+
+	/* 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;
-
-    if (vxres < xres + xoffset)
-	vxres = xres + xoffset;
-
-    if (vyres < yres + yoffset)
-	vyres = yres + yoffset;
-
-    /* convert bpp into ATI register depth */
-    depth = bpp_to_depth(bpp);
-
-    /* make sure we didn't get an invalid depth */
-    if (depth == -EINVAL) {
-        printk(KERN_ERR "aty128fb: Invalid depth\n");
-        return -EINVAL;
-    }
+	if (bpp != 16)
+		depth = bpp;
+	else
+		depth = (var->green.length == 6) ? 16 : 15;
 
-    /* convert depth to bpp */
-    bytpp = mode_bytpp[depth];
+	/* check for mode eligibility
+	 * accept only non interlaced modes */
+	if ((vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
+		return -EINVAL;
 
-    /* make sure there is enough video ram for the mode */
-    if ((u32)(vxres * vyres * bytpp) > info->vram_size) {
-        printk(KERN_ERR "aty128fb: Not enough memory for mode\n");
-        return -EINVAL;
-    }
+	/* convert (and round up) and validate */
+	xres = (xres + 7) & ~7;
+	xoffset = (xoffset + 7) & ~7;
 
-    h_disp = (xres >> 3) - 1;
-    h_total = (((xres + right + hslen + left) >> 3) - 1) & 0xFFFFL;
+	if (vxres < xres + xoffset)
+		vxres = xres + xoffset;
 
-    v_disp = yres - 1;
-    v_total = (yres + upper + vslen + lower - 1) & 0xFFFFL;
+	if (vyres < yres + yoffset)
+		vyres = yres + yoffset;
 
-    /* check to make sure h_total and v_total are in range */
-    if (((h_total >> 3) - 1) > 0x1ff || (v_total - 1) > 0x7FF) {
-        printk(KERN_ERR "aty128fb: invalid width ranges\n");
-        return -EINVAL;
-    }
+	/* convert depth into ATI register depth */
+	dst = depth_to_dst(depth);
 
-    h_sync_wid = (hslen + 7) >> 3;
-    if (h_sync_wid == 0)
-	h_sync_wid = 1;
-    else if (h_sync_wid > 0x3f)        /* 0x3f = max hwidth */
-	h_sync_wid = 0x3f;
-
-    h_sync_strt = h_disp + (right >> 3);
-
-    v_sync_wid = vslen;
-    if (v_sync_wid == 0)
-	v_sync_wid = 1;
-    else if (v_sync_wid > 0x1f)        /* 0x1f = max vwidth */
-	v_sync_wid = 0x1f;
+	if (dst == -EINVAL) {
+		printk(KERN_ERR "aty128fb: Invalid depth or RGBA\n");
+		return -EINVAL;
+	}
+
+	/* convert register depth to bytes per pixel */
+	bytpp = mode_bytpp[dst];
+
+	/* make sure there is enough video ram for the mode */
+	if ((u32)(vxres * vyres * bytpp) > par->vram_size) {
+		printk(KERN_ERR "aty128fb: Not enough memory for mode\n");
+		return -EINVAL;
+	}
+
+	h_disp = (xres >> 3) - 1;
+	h_total = (((xres + right + hslen + left) >> 3) - 1) & 0xFFFFL;
+
+	v_disp = yres - 1;
+	v_total = (yres + upper + vslen + lower - 1) & 0xFFFFL;
+
+	/* check to make sure h_total and v_total are in range */
+	if (((h_total >> 3) - 1) > 0x1ff || (v_total - 1) > 0x7FF) {
+		printk(KERN_ERR "aty128fb: invalid width ranges\n");
+		return -EINVAL;
+	}
+
+	h_sync_wid = (hslen + 7) >> 3;
+	if (h_sync_wid == 0)
+		h_sync_wid = 1;
+	else if (h_sync_wid > 0x3f)        /* 0x3f = max hwidth */
+		h_sync_wid = 0x3f;
+
+	h_sync_strt = (h_disp << 3) + right;
+
+	v_sync_wid = vslen;
+	if (v_sync_wid == 0)
+		v_sync_wid = 1;
+	else if (v_sync_wid > 0x1f)        /* 0x1f = max vwidth */
+		v_sync_wid = 0x1f;
     
-    v_sync_strt = v_disp + lower;
+	v_sync_strt = v_disp + lower;
 
-    h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
-    v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
+	h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
+	v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
     
-    c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0;
+	c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0;
 
-    crtc->gen_cntl = 0x3000000L | c_sync | (depth << 8);
+	crtc->gen_cntl = 0x3000000L | c_sync | (dst << 8);
 
-    crtc->h_total = h_total | (h_disp << 16);
-    crtc->v_total = v_total | (v_disp << 16);
+	crtc->h_total = h_total | (h_disp << 16);
+	crtc->v_total = v_total | (v_disp << 16);
 
-    crtc->h_sync_strt_wid = hsync_strt_pix[bytpp] | (h_sync_strt << 3) |
-                (h_sync_wid << 16) | (h_sync_pol << 23);
-    crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid << 16) |
+	crtc->h_sync_strt_wid = h_sync_strt | (h_sync_wid << 16) |
+	        (h_sync_pol << 23);
+	crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid << 16) |
                 (v_sync_pol << 23);
 
-    crtc->pitch = vxres >> 3;
+	crtc->pitch = vxres >> 3;
+
+	crtc->offset = 0;
 
-    crtc->offset = 0;
+	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
+		crtc->offset_cntl = 0x00010000;
+	else
+		crtc->offset_cntl = 0;
 
-    if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
- 	 crtc->offset_cntl = 0x00010000;
-    else
-	 crtc->offset_cntl = 0;
-
-    crtc->vxres = vxres;
-    crtc->vyres = vyres;
-    crtc->xoffset = xoffset;
-    crtc->yoffset = yoffset;
-    crtc->bpp = bpp;
+	crtc->vxres = vxres;
+	crtc->vyres = vyres;
+	crtc->xoffset = xoffset;
+	crtc->yoffset = yoffset;
+	crtc->depth = depth;
+	crtc->bpp = bpp;
 
-    return 0;
+	return 0;
 }
 
 
 static int
-aty128_bpp_to_var(int pix_width, struct fb_var_screeninfo *var)
+aty128_pix_width_to_var(int pix_width, struct fb_var_screeninfo *var)
 {
 
-    /* fill in pixel info */
-    switch (pix_width) {
-    case CRTC_PIX_WIDTH_8BPP:
-        var->bits_per_pixel = 8;
-	var->red.offset = 0;
-	var->red.length = 8;
-	var->green.offset = 0;
-	var->green.length = 8;
+	/* fill in pixel info */
+	var->red.msb_right = 0;
+	var->green.msb_right = 0;
 	var->blue.offset = 0;
-	var->blue.length = 8;
+	var->blue.msb_right = 0;
 	var->transp.offset = 0;
 	var->transp.length = 0;
-	break;
-    case CRTC_PIX_WIDTH_15BPP:
-    case CRTC_PIX_WIDTH_16BPP:
-	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 CRTC_PIX_WIDTH_24BPP:
-        var->bits_per_pixel = 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:
-        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;
-    default:
-        printk(KERN_ERR "aty128fb: Invalid pixel width\n");
-        return -EINVAL;
-    }
+	var->transp.msb_right = 0;
+	switch (pix_width) {
+	case CRTC_PIX_WIDTH_8BPP:
+		var->bits_per_pixel = 8;
+		var->red.offset = 0;
+		var->red.length = 8;
+		var->green.offset = 0;
+		var->green.length = 8;
+		var->blue.length = 8;
+		break;
+	case CRTC_PIX_WIDTH_15BPP:
+		var->bits_per_pixel = 16;
+		var->red.offset = 10;
+		var->red.length = 5;
+		var->green.offset = 5;
+		var->green.length = 5;
+		var->blue.length = 5;
+		break;
+	case CRTC_PIX_WIDTH_16BPP:
+		var->bits_per_pixel = 16;
+		var->red.offset = 11;
+		var->red.length = 5;
+		var->green.offset = 5;
+		var->green.length = 6;
+		var->blue.length = 5;
+		break;
+	case CRTC_PIX_WIDTH_24BPP:
+		var->bits_per_pixel = 24;
+		var->red.offset = 16;
+		var->red.length = 8;
+		var->green.offset = 8;
+		var->green.length = 8;
+		var->blue.length = 8;
+		break;
+	case CRTC_PIX_WIDTH_32BPP:
+		var->bits_per_pixel = 32;
+		var->red.offset = 16;
+		var->red.length = 8;
+		var->green.offset = 8;
+		var->green.length = 8;
+		var->blue.length = 8;
+		var->transp.offset = 24;
+		var->transp.length = 8;
+		break;
+	default:
+		printk(KERN_ERR "aty128fb: Invalid pixel width\n");
+		return -EINVAL;
+	}
 
-    return 0;
+	return 0;
 }
 
 
 static int
 aty128_crtc_to_var(const struct aty128_crtc *crtc,
-			struct fb_var_screeninfo *var)
+		   struct fb_var_screeninfo *var)
+{
+	u32 xres, yres, 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;
+
+	/* fun with masking */
+	h_total     = crtc->h_total & 0x1ff;
+	h_disp      = (crtc->h_total >> 16) & 0xff;
+	h_sync_strt = (crtc->h_sync_strt_wid >> 3) & 0x1ff;
+	h_sync_dly  = crtc->h_sync_strt_wid & 0x7;
+	h_sync_wid  = (crtc->h_sync_strt_wid >> 16) & 0x3f;
+	h_sync_pol  = (crtc->h_sync_strt_wid >> 23) & 0x1;
+	v_total     = crtc->v_total & 0x7ff;
+	v_disp      = (crtc->v_total >> 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 >> 23) & 0x1;
+	c_sync      = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0;
+	pix_width   = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;
+
+	/* do conversions */
+	xres  = (h_disp + 1) << 3;
+	yres  = v_disp + 1;
+	left  = ((h_total - h_sync_strt - h_sync_wid) << 3) - h_sync_dly;
+	right = ((h_sync_strt - h_disp) << 3) + h_sync_dly;
+	hslen = h_sync_wid << 3;
+	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);
+
+	aty128_pix_width_to_var(pix_width, var);
+
+	var->xres = xres;
+	var->yres = yres;
+	var->xres_virtual = crtc->vxres;
+	var->yres_virtual = crtc->vyres;
+	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;
+}
+
+#ifdef CONFIG_PMAC_PBOOK
+static void
+aty128_set_crt_enable(struct aty128fb_par *par, int on)
 {
-    u32 xres, yres, 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;
-
-    /* fun with masking */
-    h_total     = crtc->h_total & 0x1ff;
-    h_disp      = (crtc->h_total >> 16) & 0xff;
-    h_sync_strt = (crtc->h_sync_strt_wid >> 3) & 0x1ff;
-    h_sync_dly  = crtc->h_sync_strt_wid & 0x7;
-    h_sync_wid  = (crtc->h_sync_strt_wid >> 16) & 0x3f;
-    h_sync_pol  = (crtc->h_sync_strt_wid >> 23) & 0x1;
-    v_total     = crtc->v_total & 0x7ff;
-    v_disp      = (crtc->v_total >> 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 >> 23) & 0x1;
-    c_sync      = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0;
-    pix_width   = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;
-
-    /* do conversions */
-    xres  = (h_disp + 1) << 3;
-    yres  = v_disp + 1;
-    left  = ((h_total - h_sync_strt - h_sync_wid) << 3) - h_sync_dly;
-    right = ((h_sync_strt - h_disp) << 3) + h_sync_dly;
-    hslen = h_sync_wid << 3;
-    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);
-
-    aty128_bpp_to_var(pix_width, var);
-
-    var->xres = xres;
-    var->yres = yres;
-    var->xres_virtual = crtc->vxres;
-    var->yres_virtual = crtc->vyres;
-    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;
+	if (on) {
+		aty_st_le32(CRTC_EXT_CNTL, aty_ld_le32(CRTC_EXT_CNTL) | CRT_CRTC_ON);
+		aty_st_le32(DAC_CNTL, (aty_ld_le32(DAC_CNTL) | DAC_PALETTE2_SNOOP_EN));
+	} else
+		aty_st_le32(CRTC_EXT_CNTL, aty_ld_le32(CRTC_EXT_CNTL) & ~CRT_CRTC_ON);
+}
 
-    return 0;
+static void
+aty128_set_lcd_enable(struct aty128fb_par *par, int on)
+{
+	u32 reg;
+
+	if (on) {
+		reg = aty_ld_le32(LVDS_GEN_CNTL);
+		reg |= LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGION;
+		reg &= ~LVDS_DISPLAY_DIS;
+		aty_st_le32(LVDS_GEN_CNTL, reg);
+#ifdef CONFIG_PMAC_BACKLIGHT
+		aty128_set_backlight_enable(get_backlight_enable(),
+					    get_backlight_level(), par);
+#endif	
+	} else {
+#ifdef CONFIG_PMAC_BACKLIGHT
+		aty128_set_backlight_enable(0, 0, par);
+#endif	
+		reg = aty_ld_le32(LVDS_GEN_CNTL);
+		reg |= LVDS_DISPLAY_DIS;
+		aty_st_le32(LVDS_GEN_CNTL, reg);
+		mdelay(100);
+		reg &= ~(LVDS_ON /*| LVDS_EN*/);
+		aty_st_le32(LVDS_GEN_CNTL, reg);
+	}
 }
+#endif
 
 static void
-aty128_set_pll(struct aty128_pll *pll, const struct fb_info_aty128 *info)
+aty128_set_pll(struct aty128_pll *pll, const struct aty128fb_par *par)
 {
-    u32 div3;
+	u32 div3;
 
-    unsigned char post_conv[] =	/* register values for post dividers */
+	unsigned char post_conv[] =	/* register values for post dividers */
         { 2, 0, 1, 4, 2, 2, 6, 2, 3, 2, 2, 2, 7 };
 
-    /* select PPLL_DIV_3 */
-    aty_st_le32(CLOCK_CNTL_INDEX, aty_ld_le32(CLOCK_CNTL_INDEX) | (3 << 8));
+	/* select PPLL_DIV_3 */
+	aty_st_le32(CLOCK_CNTL_INDEX, aty_ld_le32(CLOCK_CNTL_INDEX) | (3 << 8));
 
-    /* reset PLL */
-    aty_st_pll(PPLL_CNTL,
-		aty_ld_pll(PPLL_CNTL) | PPLL_RESET | PPLL_ATOMIC_UPDATE_EN);
-
-    /* write the reference divider */
-    aty_pll_wait_readupdate(info);
-    aty_st_pll(PPLL_REF_DIV, info->constants.ref_divider & 0x3ff);
-    aty_pll_writeupdate(info);
-
-    div3 = aty_ld_pll(PPLL_DIV_3);
-    div3 &= ~PPLL_FB3_DIV_MASK;
-    div3 |= pll->feedback_divider;
-    div3 &= ~PPLL_POST3_DIV_MASK;
-    div3 |= post_conv[pll->post_divider] << 16;
-
-    /* write feedback and post dividers */
-    aty_pll_wait_readupdate(info);
-    aty_st_pll(PPLL_DIV_3, div3);
-    aty_pll_writeupdate(info);
-
-    aty_pll_wait_readupdate(info);
-    aty_st_pll(HTOTAL_CNTL, 0);	/* no horiz crtc adjustment */
-    aty_pll_writeupdate(info);
+	/* reset PLL */
+	aty_st_pll(PPLL_CNTL,
+		   aty_ld_pll(PPLL_CNTL) | PPLL_RESET | PPLL_ATOMIC_UPDATE_EN);
+
+	/* write the reference divider */
+	aty_pll_wait_readupdate(par);
+	aty_st_pll(PPLL_REF_DIV, par->constants.ref_divider & 0x3ff);
+	aty_pll_writeupdate(par);
+
+	div3 = aty_ld_pll(PPLL_DIV_3);
+	div3 &= ~PPLL_FB3_DIV_MASK;
+	div3 |= pll->feedback_divider;
+	div3 &= ~PPLL_POST3_DIV_MASK;
+	div3 |= post_conv[pll->post_divider] << 16;
+
+	/* write feedback and post dividers */
+	aty_pll_wait_readupdate(par);
+	aty_st_pll(PPLL_DIV_3, div3);
+	aty_pll_writeupdate(par);
+
+	aty_pll_wait_readupdate(par);
+	aty_st_pll(HTOTAL_CNTL, 0);	/* no horiz crtc adjustment */
+	aty_pll_writeupdate(par);
 
-    /* clear the reset, just in case */
-    aty_st_pll(PPLL_CNTL, aty_ld_pll(PPLL_CNTL) & ~PPLL_RESET);
+	/* clear the reset, just in case */
+	aty_st_pll(PPLL_CNTL, aty_ld_pll(PPLL_CNTL) & ~PPLL_RESET);
 }
 
 
 static int
 aty128_var_to_pll(u32 period_in_ps, struct aty128_pll *pll,
-			const struct fb_info_aty128 *info)
+		  const struct aty128fb_par *par)
 {
-    const struct aty128_constants c = info->constants;
-    unsigned char post_dividers[] = {1,2,4,8,3,6,12};
-    u32 output_freq;
-    u32 vclk;        /* in .01 MHz */
-    int i;
-    u32 n, d;
-
-    vclk = 100000000 / period_in_ps;	/* convert units to 10 kHz */
-
-    /* adjust pixel clock if necessary */
-    if (vclk > c.ppll_max)
-	vclk = c.ppll_max;
-    if (vclk * 12 < c.ppll_min)
-	vclk = c.ppll_min/12;
-
-    /* now, find an acceptable divider */
-    for (i = 0; i < sizeof(post_dividers); i++) {
-	output_freq = post_dividers[i] * vclk;
-	if (output_freq >= c.ppll_min && output_freq <= c.ppll_max)
-	    break;
-    }
+	const struct aty128_constants c = par->constants;
+	unsigned char post_dividers[] = {1,2,4,8,3,6,12};
+	u32 output_freq;
+	u32 vclk;        /* in .01 MHz */
+	int i;
+	u32 n, d;
+
+	vclk = 100000000 / period_in_ps;	/* convert units to 10 kHz */
+
+	/* adjust pixel clock if necessary */
+	if (vclk > c.ppll_max)
+		vclk = c.ppll_max;
+	if (vclk * 12 < c.ppll_min)
+		vclk = c.ppll_min/12;
+
+	/* now, find an acceptable divider */
+	for (i = 0; i < sizeof(post_dividers); i++) {
+		output_freq = post_dividers[i] * vclk;
+		if (output_freq >= c.ppll_min && output_freq <= c.ppll_max)
+			break;
+	}
 
-    /* calculate feedback divider */
-    n = c.ref_divider * output_freq;
-    d = c.dotclock;
-
-    pll->post_divider = post_dividers[i];
-    pll->feedback_divider = round_div(n, d);
-    pll->vclk = vclk;
-
-    DBG("post %d feedback %d vlck %d output %d ref_divider %d "
-			"vclk_per: %d\n", pll->post_divider,
-			pll->feedback_divider, vclk, output_freq,
-			c.ref_divider, period_in_ps);
+	/* calculate feedback divider */
+	n = c.ref_divider * output_freq;
+	d = c.dotclock;
+
+	pll->post_divider = post_dividers[i];
+	pll->feedback_divider = round_div(n, d);
+	pll->vclk = vclk;
+
+	DBG("post %d feedback %d vlck %d output %d ref_divider %d "
+	    "vclk_per: %d\n", pll->post_divider,
+	    pll->feedback_divider, vclk, output_freq,
+	    c.ref_divider, period_in_ps);
 
-    return 0;
+	return 0;
 }
 
 
 static int
-aty128_pll_to_var(const struct aty128_pll *pll, struct fb_var_screeninfo *var,
-		const struct fb_info_aty128 *info)
+aty128_pll_to_var(const struct aty128_pll *pll, struct fb_var_screeninfo *var)
 {
-    var->pixclock = 100000000 / pll->vclk;
+	var->pixclock = 100000000 / pll->vclk;
 
-    return 0;
+	return 0;
 }
 
 
 static void
 aty128_set_fifo(const struct aty128_ddafifo *dsp,
-			const struct fb_info_aty128 *info)
+		const struct aty128fb_par *par)
 {
-    aty_st_le32(DDA_CONFIG, dsp->dda_config);
-    aty_st_le32(DDA_ON_OFF, dsp->dda_on_off);
+	aty_st_le32(DDA_CONFIG, dsp->dda_config);
+	aty_st_le32(DDA_ON_OFF, dsp->dda_on_off);
 }
 
 
 static int
 aty128_ddafifo(struct aty128_ddafifo *dsp,
-		const struct aty128_pll *pll,
-		u32 bpp,
-		const struct fb_info_aty128 *info)
-{
-    const struct aty128_meminfo *m = info->mem;
-    u32 xclk = info->constants.xclk;
-    u32 fifo_width = info->constants.fifo_width;
-    u32 fifo_depth = info->constants.fifo_depth;
-    s32 x, b, p, ron, roff;
-    u32 n, d;
-
-    /* 15bpp is really 16bpp */
-    if (bpp == 15)
-	bpp = 16;
-
-    n = xclk * fifo_width;
-    d = pll->vclk * bpp;
-    x = round_div(n, d);
-
-    ron = 4 * m->MB +
-	3 * ((m->Trcd - 2 > 0) ? m->Trcd - 2 : 0) +
-	2 * m->Trp +
-	m->Twr +
-	m->CL +
-	m->Tr2w +
-	x;
-
-    DBG("x %x\n", x);
-
-    b = 0;
-    while (x) {
-	x >>= 1;
-	b++;
-    }
-    p = b + 1;
+	       const struct aty128_pll *pll,
+	       u32 depth,
+	       const struct aty128fb_par *par)
+{
+	const struct aty128_meminfo *m = par->mem;
+	u32 xclk = par->constants.xclk;
+	u32 fifo_width = par->constants.fifo_width;
+	u32 fifo_depth = par->constants.fifo_depth;
+	s32 x, b, p, ron, roff;
+	u32 n, d, bpp;
+
+	/* round up to multiple of 8 */
+	bpp = (depth+7) & ~7;
+
+	n = xclk * fifo_width;
+	d = pll->vclk * bpp;
+	x = round_div(n, d);
+
+	ron = 4 * m->MB +
+		3 * ((m->Trcd - 2 > 0) ? m->Trcd - 2 : 0) +
+		2 * m->Trp +
+		m->Twr +
+		m->CL +
+		m->Tr2w +
+		x;
+
+	DBG("x %x\n", x);
+
+	b = 0;
+	while (x) {
+		x >>= 1;
+		b++;
+	}
+	p = b + 1;
 
-    ron <<= (11 - p);
+	ron <<= (11 - p);
 
-    n <<= (11 - p);
-    x = round_div(n, d);
-    roff = x * (fifo_depth - 4);
+	n <<= (11 - p);
+	x = round_div(n, d);
+	roff = x * (fifo_depth - 4);
 
-    if ((ron + m->Rloop) >= roff) {
-	printk(KERN_ERR "aty128fb: Mode out of range!\n");
-	return -EINVAL;
-    }
+	if ((ron + m->Rloop) >= roff) {
+		printk(KERN_ERR "aty128fb: Mode out of range!\n");
+		return -EINVAL;
+	}
 
-    DBG("p: %x rloop: %x x: %x ron: %x roff: %x\n",
-			p, m->Rloop, x, ron, roff);
+	DBG("p: %x rloop: %x x: %x ron: %x roff: %x\n",
+	    p, m->Rloop, x, ron, roff);
 
-    dsp->dda_config = p << 16 | m->Rloop << 20 | x;
-    dsp->dda_on_off = ron << 16 | roff;
+	dsp->dda_config = p << 16 | m->Rloop << 20 | x;
+	dsp->dda_on_off = ron << 16 | roff;
 
-    return 0;
+	return 0;
 }
 
 
 /*
  * This actually sets the video mode.
  */
-static void
-aty128_set_par(struct aty128fb_par *par,
-			struct fb_info_aty128 *info)
+static int
+aty128fb_set_par(struct fb_info *info)
 { 
-    u32 config;
-
-    info->current_par = *par;
+	struct aty128fb_par *par = info->par;
+	u32 config;
     
-    if (info->blitter_may_be_busy)
-        wait_for_idle(info);
+	if (par->blitter_may_be_busy)
+		wait_for_idle(par);
 
-    /* clear all registers that may interfere with mode setting */
-    aty_st_le32(OVR_CLR, 0);
-    aty_st_le32(OVR_WID_LEFT_RIGHT, 0);
-    aty_st_le32(OVR_WID_TOP_BOTTOM, 0);
-    aty_st_le32(OV0_SCALE_CNTL, 0);
-    aty_st_le32(MPP_TB_CONFIG, 0);
-    aty_st_le32(MPP_GP_CONFIG, 0);
-    aty_st_le32(SUBPIC_CNTL, 0);
-    aty_st_le32(VIPH_CONTROL, 0);
-    aty_st_le32(I2C_CNTL_1, 0);         /* turn off i2c */
-    aty_st_le32(GEN_INT_CNTL, 0);	/* turn off interrupts */
-    aty_st_le32(CAP0_TRIG_CNTL, 0);
-    aty_st_le32(CAP1_TRIG_CNTL, 0);
-
-    aty_st_8(CRTC_EXT_CNTL + 1, 4);	/* turn video off */
-
-    aty128_set_crtc(&par->crtc, info);
-    aty128_set_pll(&par->pll, info);
-    aty128_set_fifo(&par->fifo_reg, info);
+	/* clear all registers that may interfere with mode setting */
+	aty_st_le32(OVR_CLR, 0);
+	aty_st_le32(OVR_WID_LEFT_RIGHT, 0);
+	aty_st_le32(OVR_WID_TOP_BOTTOM, 0);
+	aty_st_le32(OV0_SCALE_CNTL, 0);
+	aty_st_le32(MPP_TB_CONFIG, 0);
+	aty_st_le32(MPP_GP_CONFIG, 0);
+	aty_st_le32(SUBPIC_CNTL, 0);
+	aty_st_le32(VIPH_CONTROL, 0);
+	aty_st_le32(I2C_CNTL_1, 0);         /* turn off i2c */
+	aty_st_le32(GEN_INT_CNTL, 0);	/* turn off interrupts */
+	aty_st_le32(CAP0_TRIG_CNTL, 0);
+	aty_st_le32(CAP1_TRIG_CNTL, 0);
+
+	aty_st_8(CRTC_EXT_CNTL + 1, 4);	/* turn video off */
+
+	aty128_set_crtc(&par->crtc, par);
+	aty128_set_pll(&par->pll, par);
+	aty128_set_fifo(&par->fifo_reg, par);
 
-    config = aty_ld_le32(CONFIG_CNTL) & ~3;
+	config = aty_ld_le32(CONFIG_CNTL) & ~3;
 
 #if defined(__BIG_ENDIAN)
-    if (par->crtc.bpp >= 24)
-	config |= 2;	/* make aperture do 32 byte swapping */
-    else if (par->crtc.bpp > 8)
-	config |= 1;	/* make aperture do 16 byte swapping */
-#endif
-
-    aty_st_le32(CONFIG_CNTL, config);
-    aty_st_8(CRTC_EXT_CNTL + 1, 0);	/* turn the video back on */
-
-    if (par->accel_flags & FB_ACCELF_TEXT)
-        aty128_init_engine(par, info);
-
-#if defined(CONFIG_BOOTX_TEXT)
-	btext_update_display(info->frame_buffer_phys,
-			(((par->crtc.h_total>>16) & 0xff)+1)*8,
-			((par->crtc.v_total>>16) & 0x7ff)+1,
-			par->crtc.bpp,
-			par->crtc.vxres*par->crtc.bpp/8);
+	if (par->crtc.bpp == 32)
+		config |= 2;	/* make aperture do 32 bit swapping */
+	else if (par->crtc.bpp == 16)
+		config |= 1;	/* make aperture do 16 bit swapping */
+#endif
+
+	aty_st_le32(CONFIG_CNTL, config);
+	aty_st_8(CRTC_EXT_CNTL + 1, 0);	/* turn the video back on */
+
+	info->fix.line_length = (par->crtc.vxres * par->crtc.bpp) >> 3;
+	info->fix.visual = par->crtc.bpp == 8 ? FB_VISUAL_PSEUDOCOLOR
+		: FB_VISUAL_DIRECTCOLOR;
+
+#ifdef CONFIG_PMAC_PBOOK
+	if (par->chip_gen == rage_M3) {
+		aty128_set_crt_enable(par, par->crt_on);
+		aty128_set_lcd_enable(par, par->lcd_on);
+	}
+#endif
+	if (par->accel_flags & FB_ACCELF_TEXT)
+		aty128_init_engine(par);
+
+#ifdef CONFIG_BOOTX_TEXT
+	btext_update_display(info->fix.smem_start,
+			     (((par->crtc.h_total>>16) & 0xff)+1)*8,
+			     ((par->crtc.v_total>>16) & 0x7ff)+1,
+			     par->crtc.bpp,
+			     par->crtc.vxres*par->crtc.bpp/8);
 #endif /* CONFIG_BOOTX_TEXT */
+
+	return 0;
 }
 
-    /*
-     *  encode/decode the User Defined Part of the Display
-     */
+/*
+ *  encode/decode the User Defined Part of the Display
+ */
 
 static int
-aty128_decode_var(struct fb_var_screeninfo *var, struct aty128fb_par *par,
-			const struct fb_info_aty128 *info)
+aty128_decode_var(struct fb_var_screeninfo *var, struct aty128fb_par *par)
 {
-    int err;
-
-    if ((err = aty128_var_to_crtc(var, &par->crtc, info)))
-	return err;
+	int err;
 
-    if ((err = aty128_var_to_pll(var->pixclock, &par->pll, info)))
-	return err;
+	if ((err = aty128_var_to_crtc(var, &par->crtc, par)))
+		return err;
 
-    if ((err = aty128_ddafifo(&par->fifo_reg, &par->pll, par->crtc.bpp, info)))
-	return err;
+	if ((err = aty128_var_to_pll(var->pixclock, &par->pll, par)))
+		return err;
 
-    if (var->accel_flags & FB_ACCELF_TEXT)
-	par->accel_flags = FB_ACCELF_TEXT;
-    else
-	par->accel_flags = 0;
+	if ((err = aty128_ddafifo(&par->fifo_reg, &par->pll, par->crtc.depth, par)))
+		return err;
+	par->accel_flags = var->accel_flags;
 
-    return 0;
+	return 0;
 }
 
 
 static int
 aty128_encode_var(struct fb_var_screeninfo *var,
-			const struct aty128fb_par *par,
-			const struct fb_info_aty128 *info)
+		  const struct aty128fb_par *par)
 {
-    int err;
-
-    if ((err = aty128_crtc_to_var(&par->crtc, var)))
-	return err;
+	int err;
 
-    if ((err = aty128_pll_to_var(&par->pll, var, info)))
-	return err;
+	if ((err = aty128_crtc_to_var(&par->crtc, var)))
+		return err;
 
-    var->red.msb_right = 0;
-    var->green.msb_right = 0;
-    var->blue.msb_right = 0;
-    var->transp.msb_right = 0;
+	if ((err = aty128_pll_to_var(&par->pll, var)))
+		return err;
 
-    var->nonstd = 0;
-    var->activate = 0;
+	var->nonstd = 0;
+	var->activate = 0;
 
-    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;
 }           
 
 
-    /*
-     *  Get the User Defined Part of the Display
-     */
-
-static int
-aty128fb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *fb)
-{
-    const struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
-
-    if (con == -1)
-	aty128_encode_var(var, &info->default_par, info); 
-    else
-	*var = fb_display[con].var;
-    return 0;
-}
-
-
-    /*
-     *  Set the User Defined Part of the Display
-     */
-
 static int
-aty128fb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *fb)
+aty128fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
-    struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
-    struct aty128fb_par par;
-    struct display *display;
-    int oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel;
-    int accel, err;
-
-    display = (con >= 0) ? &fb_display[con] : fb->disp;
-
-    /* basic (in)sanity checks */
-    if (!var->xres)
-        var->xres = 1;
-    if (!var->yres)
-        var->yres = 1;
-    if (var->xres > var->xres_virtual)
-        var->xres_virtual = var->xres;
-    if (var->yres > var->yres_virtual)
-        var->yres_virtual = var->yres;
-
-    switch (var->bits_per_pixel) {
-        case 0 ... 8:
-            var->bits_per_pixel = 8;
-            break;
-        case 9 ... 16:
-            var->bits_per_pixel = 16;
-            break;
-        case 17 ... 24:
-            var->bits_per_pixel = 24;
-            break;
-        case 25 ... 32:
-            var->bits_per_pixel = 32;
-            break;
-        default:
-            return -EINVAL;
-    }
-
-    if ((err = aty128_decode_var(var, &par, info)))
-	return err;
-
-    aty128_encode_var(var, &par, info);
+	struct aty128fb_par *par = info->par;
+	int err;
 
-    if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST)
+	if ((err = aty128_decode_var(var, par)) != 0)
+		return err;
+	aty128_encode_var(var, par);
 	return 0;
-
-    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;
-    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;
-
-	aty128_encode_fix(&fix, &par, info);
-        fb->screen_base = 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;
-
-	accel = var->accel_flags & FB_ACCELF_TEXT;
-        aty128_set_dispsw(display, info, par.crtc.bpp, accel);
-
-	if (accel)
-	    display->scrollmode = SCROLL_YNOMOVE;
-	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)
-	aty128_set_par(&par, info);
-
-    if (oldbpp != var->bits_per_pixel) {
-	if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
-	    return err;
-	do_install_cmap(con, &info->fb_info);
-    } 
-
-    return 0;
 }
 
 
-static void
-aty128_set_dispsw(struct display *disp,
-			struct fb_info_aty128 *info, int bpp, int accel)
-{
-    switch (bpp) {
-#ifdef FBCON_HAS_CFB8
-    case 8:
-	disp->dispsw = accel ? &fbcon_aty128_8 : &fbcon_cfb8;
-	break;
-#endif
-#ifdef FBCON_HAS_CFB16
-    case 15:
-    case 16:
-	disp->dispsw = accel ? &fbcon_aty128_16 : &fbcon_cfb16;
-	disp->dispsw_data = info->fbcon_cmap.cfb16;
-	break;
-#endif
-#ifdef FBCON_HAS_CFB24
-    case 24:
-	disp->dispsw = accel ? &fbcon_aty128_24 : &fbcon_cfb24;
-	disp->dispsw_data = info->fbcon_cmap.cfb24;
-	break;
-#endif
-#ifdef FBCON_HAS_CFB32
-    case 32:
-	disp->dispsw = accel ? &fbcon_aty128_32 : &fbcon_cfb32;
-	disp->dispsw_data = info->fbcon_cmap.cfb32;
-	break;
-#endif
-    default:
-	disp->dispsw = &fbcon_dummy;
-    }
-}
-
-
-static void
-aty128_encode_fix(struct fb_fix_screeninfo *fix,
-			struct aty128fb_par *par,
-			const struct fb_info_aty128 *info)
-{
-    memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-    
-    strcpy(fix->id, aty128fb_name);
-
-    fix->smem_start = (unsigned long)info->frame_buffer_phys;
-    fix->mmio_start = (unsigned long)info->regbase_phys;
-
-    fix->smem_len = info->vram_size;
-    fix->mmio_len = 0x1fff;
-
-    fix->type        = FB_TYPE_PACKED_PIXELS;
-    fix->type_aux    = 0;
-    fix->line_length = (par->crtc.vxres * par->crtc.bpp) >> 3;
-    fix->visual      = par->crtc.bpp <= 8 ? FB_VISUAL_PSEUDOCOLOR
-                                          : FB_VISUAL_DIRECTCOLOR;
-    fix->ywrapstep = 0;
-    fix->xpanstep  = 8;
-    fix->ypanstep  = 1;
-
-    fix->accel = FB_ACCEL_ATI_RAGE128;
-
-    return;
-}
-
-
-    /*
-     *  Get the Fixed Part of the Display
-     */
+/*
+ *  Pan or Wrap the Display
+ */
 static int
-aty128fb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *fb)
+aty128fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fb) 
 {
-    const struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
-    struct aty128fb_par par;
+	struct aty128fb_par *par = fb->par;
+	u32 xoffset, yoffset;
+	u32 offset;
+	u32 xres, yres;
 
-    if (con == -1)
-	par = info->default_par;
-    else
-	aty128_decode_var(&fb_display[con].var, &par, info); 
+	xres = (((par->crtc.h_total >> 16) & 0xff) + 1) << 3;
+	yres = ((par->crtc.v_total >> 16) & 0x7ff) + 1;
 
-    aty128_encode_fix(fix, &par, info);
+	xoffset = (var->xoffset +7) & ~7;
+	yoffset = var->yoffset;
 
-    return 0;            
-}
+	if (xoffset+xres > par->crtc.vxres || yoffset+yres > par->crtc.vyres)
+		return -EINVAL;
 
+	par->crtc.xoffset = xoffset;
+	par->crtc.yoffset = yoffset;
 
-    /*
-     *  Pan or Wrap the Display
-     *
-     *  Not supported (yet!)
-     */
-static int
-aty128fb_pan_display(struct fb_var_screeninfo *var, int con,
-			   struct fb_info *fb)
-{
-    struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
-    struct aty128fb_par *par = &info->current_par;
-    u32 xoffset, yoffset;
-    u32 offset;
-    u32 xres, yres;
+	offset = ((yoffset * par->crtc.vxres + xoffset)*(par->crtc.bpp >> 3)) & ~7;
 
-    xres = (((par->crtc.h_total >> 16) & 0xff) + 1) << 3;
-    yres = ((par->crtc.v_total >> 16) & 0x7ff) + 1;
+	if (par->crtc.bpp == 24)
+		offset += 8 * (offset % 3); /* Must be multiple of 8 and 3 */
 
-    xoffset = (var->xoffset +7) & ~7;
-    yoffset = var->yoffset;
+	aty_st_le32(CRTC_OFFSET, offset);
 
-    if (xoffset+xres > par->crtc.vxres || yoffset+yres > par->crtc.vyres)
-        return -EINVAL;
-
-    par->crtc.xoffset = xoffset;
-    par->crtc.yoffset = yoffset;
-
-    offset = ((yoffset * par->crtc.vxres + xoffset) * par->crtc.bpp) >> 6;
-
-    aty_st_le32(CRTC_OFFSET, offset);
-
-    return 0;
+	return 0;
 }
 
 
-    /*
-     *  Get the Colormap
-     */
-
-static int
-aty128fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			struct fb_info *info)
+/*
+ *  Helper function to store a single palette register
+ */
+static void
+aty128_st_pal(u_int regno, u_int red, u_int green, u_int blue,
+	      struct aty128fb_par *par)
 {
-#if 1
-    fb_copy_cmap(&info->cmap, cmap, kspc ? 0 : 2);
-#else
-    struct fb_info_aty128 fb = (struct fb_info_aty128 *)info;
-
-    if (con == info->currcon) /* current console? */
-	return fb_get_cmap(cmap, kspc, aty128_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 <= 8) ? 256 : 32;
-	fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
-    }
+	if (par->chip_gen == rage_M3) {
+#if 0
+		/* Note: For now, on M3, we set palette on both heads, which may
+		 * be useless. Can someone with a M3 check this ?
+		 * 
+		 * This code would still be useful if using the second CRTC to 
+		 * do mirroring
+		 */
+
+		aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PALETTE_ACCESS_CNTL);
+		aty_st_8(PALETTE_INDEX, regno);
+		aty_st_le32(PALETTE_DATA, (red<<16)|(green<<8)|blue);
 #endif
+		aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & ~DAC_PALETTE_ACCESS_CNTL);
+	}
 
-    return 0;
+	aty_st_8(PALETTE_INDEX, regno);
+	aty_st_le32(PALETTE_DATA, (red<<16)|(green<<8)|blue);
 }
 
 static int
-aty128fb_rasterimg(struct fb_info *info, int start)
+aty128fb_sync(struct fb_info *info)
 {
-    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)info;
+	struct aty128fb_par *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;
 }
 
-
 int __init
 aty128fb_setup(char *options)
 {
-    char *this_opt;
+	char *this_opt;
 
-    if (!options || !*options)
-	return 0;
+	if (!options || !*options)
+		return 0;
 
-    while ((this_opt = strsep(&options, ",")) != NULL) {
-	if (!strncmp(this_opt, "font:", 5)) {
-	    char *p;
-	    int i;
-	    
-	    p = this_opt +5;
-	    for (i = 0; i < sizeof(fontname) - 1; i++)
-		if (!*p || *p == ' ' || *p == ',')
-		    break;
-	    memcpy(fontname, this_opt + 5, i);
-	    fontname[i] = 0;
-	} else if (!strncmp(this_opt, "noaccel", 7)) {
-	    noaccel = 1;
-        }
+	while ((this_opt = strsep(&options, ",")) != NULL) {
+#ifdef CONFIG_PMAC_PBOOK
+		if (!strncmp(this_opt, "lcd:", 4)) {
+			default_lcd_on = simple_strtoul(this_opt+4, NULL, 0);
+		} else if (!strncmp(this_opt, "crt:", 4)) {
+			default_crt_on = simple_strtoul(this_opt+4, NULL, 0);
+		}
+#endif
 #ifdef CONFIG_MTRR
-        else if(!strncmp(this_opt, "nomtrr", 6)) {
-            mtrr = 0;
-        }
-#endif
-#ifdef CONFIG_PPC
-        /* vmode and cmode depreciated */
-	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 /* CONFIG_PPC */
-        else
-            mode_option = this_opt;
-    }
-    return 0;
+		if(!strncmp(this_opt, "nomtrr", 6)) {
+			mtrr = 0;
+		}
+#endif
+#ifdef CONFIG_ALL_PPC
+		/* vmode and cmode depreciated */
+		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 /* CONFIG_ALL_PPC */
+		else
+			mode_option = this_opt;
+	}
+	return 0;
 }
 
 
-    /*
-     *  Initialisation
-     */
+/*
+ *  Initialisation
+ */
 
 static int __init
-aty128_init(struct fb_info_aty128 *info, const char *name)
+aty128_init(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-    struct fb_var_screeninfo var;
-    u32 dac;
-    int j, k, size;
-    u8 chip_rev;
-    const struct aty128_chip_info *aci = &aty128_pci_probe_list[0];
-    char *video_card = "Rage128";
-
-    if (!info->vram_size)	/* may have already been probed */
-	info->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
-
-    /* Get the chip revision */
-    chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F;
-
-    /* put a name with the face */
-    while (aci->name && info->pdev->device != aci->device) { aci++; }
-    video_card = (char *)aci->name;
-    info->chip_gen = aci->chip_gen;
-
-    printk(KERN_INFO "aty128fb: %s [chip rev 0x%x] ", video_card, chip_rev);
-
-    if (info->vram_size % (1024 * 1024) == 0)
-	printk("%dM %s\n", info->vram_size / (1024*1024), info->mem->name);
-    else
-	printk("%dk %s\n", info->vram_size / 1024, info->mem->name);
-
-    /* fill in info */
-    strcpy(info->fb_info.modename, aty128fb_name);
-    info->fb_info.node  = NODEV;
-    info->fb_info.fbops = &aty128fb_ops;
-    info->fb_info.disp  = &info->disp;
-    strcpy(info->fb_info.fontname, fontname);
-    info->fb_info.changevar  = NULL;
-    info->fb_info.switch_con = &aty128fbcon_switch;
-    info->fb_info.updatevar  = NULL;
-    info->fb_info.flags = FBINFO_FLAG_DEFAULT;
-
-    var = default_var;
-#ifdef CONFIG_PPC
-    if (_machine == _MACH_Pmac) {
-        if (mode_option) {
-            if (!mac_find_mode(&var, &info->fb_info, mode_option, 8))
-                var = default_var;
-        } else {
-            if (default_vmode <= 0 || default_vmode > VMODE_MAX)
-                default_vmode = VMODE_1024_768_60;
-
-	    /* iMacs need that resolution
-	     * PowerMac2,1 first r128 iMacs
-	     * PowerMac2,2 summer 2000 iMacs
-	     * PowerMac4,1 january 2001 iMacs "flower power"
-	     */
-	    if (machine_is_compatible("PowerMac2,1") ||
-		machine_is_compatible("PowerMac2,2") ||
-		machine_is_compatible("PowerMac4,1"))
-		default_vmode = VMODE_1024_768_75;
-
-	    /* iBook SE */
-	    if (machine_is_compatible("PowerBook2,2"))
-		default_vmode = VMODE_800_600_60;
-
-	    /* PowerBook Firewire (Pismo), iBook Dual USB */
-	    if (machine_is_compatible("PowerBook3,1") ||
-		machine_is_compatible("PowerBook4,1"))
-		default_vmode = VMODE_1024_768_60;
-
-	    /* PowerBook Titanium */
-	    if (machine_is_compatible("PowerBook3,2"))
-		default_vmode = VMODE_1152_768_60;
-	
-            if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
-                default_cmode = CMODE_8;
+	struct fb_info *info = pci_get_drvdata(pdev);
+	struct aty128fb_par *par = info->par;
+	struct fb_var_screeninfo var;
+	char video_card[25];
+	u8 chip_rev;
+	u32 dac;
+
+	if (!par->vram_size)	/* may have already been probed */
+		par->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
+
+	/* Get the chip revision */
+	chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F;
+
+	switch (pdev->device) {
+		case PCI_DEVICE_ID_ATI_RAGE128_RE:
+			strcpy(video_card, "Rage128 RE (PCI)");
+			break;
+		case PCI_DEVICE_ID_ATI_RAGE128_RF:
+			strcpy(video_card, "Rage128 RF (AGP)");
+			break;
+		case PCI_DEVICE_ID_ATI_RAGE128_RK:
+			strcpy(video_card, "Rage128 RK (PCI)");
+			break;
+		case PCI_DEVICE_ID_ATI_RAGE128_RL:
+			strcpy(video_card, "Rage128 RL (AGP)");
+			break;
+		case PCI_DEVICE_ID_ATI_RAGE128_PF:
+			strcpy(video_card, "Rage128 Pro PF (AGP)");
+			break;
+		case PCI_DEVICE_ID_ATI_RAGE128_PR:
+			strcpy(video_card, "Rage128 Pro PR (PCI)");
+			break;
+		case PCI_DEVICE_ID_ATI_RAGE128_U3:
+			strcpy(video_card, "Rage128 Pro TR (AGP)");
+			break;
+		case PCI_DEVICE_ID_ATI_RAGE128_U1:
+			strcpy(video_card, "Rage128 Pro TF (AGP)");
+			break;
+		case PCI_DEVICE_ID_ATI_RAGE128_LE:
+			strcpy(video_card, "Rage Mobility M3 (PCI)");
+			break;
+		case PCI_DEVICE_ID_ATI_RAGE128_LF:
+			strcpy(video_card, "Rage Mobility M3 (AGP)");
+			break;
+		default:
+			return -ENODEV;
+	}
 
-            if (mac_vmode_to_var(default_vmode, default_cmode, &var))
-                var = default_var;
-        }
-    } else
-#endif /* CONFIG_PPC */
-    {
-        if (fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0,
-                          &defaultmode, 8) == 0)
-            var = default_var;
-    }
+	printk(KERN_INFO "aty128fb: %s [chip rev 0x%x] ", video_card, chip_rev);
 
-    if (noaccel)
-        var.accel_flags &= ~FB_ACCELF_TEXT;
-    else
-        var.accel_flags |= FB_ACCELF_TEXT;
+	if (par->vram_size % (1024 * 1024) == 0)
+		printk("%dM %s\n", par->vram_size / (1024*1024), par->mem->name);
+	else
+		printk("%dk %s\n", par->vram_size / 1024, par->mem->name);
 
-    if (aty128_decode_var(&var, &info->default_par, info)) {
-	printk(KERN_ERR "aty128fb: Cannot set default mode.\n");
-	return 0;
-    }
+	par->chip_gen = ent->driver_data;
 
-    /* load up the palette with default colors */
-    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];
-    }
+	/* fill in info */
+	info->node  = NODEV;
+	info->fbops = &aty128fb_ops;
+	info->flags = FBINFO_FLAG_DEFAULT;
+
+#ifdef CONFIG_PMAC_PBOOK
+	par->lcd_on = default_lcd_on;
+	par->crt_on = default_crt_on;
+#endif
+
+	var = default_var;
+#ifdef CONFIG_ALL_PPC
+	if (_machine == _MACH_Pmac) {
+		if (mode_option) {
+			if (!mac_find_mode(&var, info, mode_option, 8))
+				var = default_var;
+		} else {
+			if (default_vmode <= 0 || default_vmode > VMODE_MAX)
+				default_vmode = VMODE_1024_768_60;
+
+			/* iMacs need that resolution
+			 * PowerMac2,1 first r128 iMacs
+			 * PowerMac2,2 summer 2000 iMacs
+			 * PowerMac4,1 january 2001 iMacs "flower power"
+			 */
+			if (machine_is_compatible("PowerMac2,1") ||
+			    machine_is_compatible("PowerMac2,2") ||
+			    machine_is_compatible("PowerMac4,1"))
+				default_vmode = VMODE_1024_768_75;
+
+			/* iBook SE */
+			if (machine_is_compatible("PowerBook2,2"))
+				default_vmode = VMODE_800_600_60;
+
+			/* PowerBook Firewire (Pismo), iBook Dual USB */
+			if (machine_is_compatible("PowerBook3,1") ||
+			    machine_is_compatible("PowerBook4,1"))
+				default_vmode = VMODE_1024_768_60;
+
+			/* PowerBook Titanium */
+			if (machine_is_compatible("PowerBook3,2"))
+				default_vmode = VMODE_1152_768_60;
+	
+			if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
+				default_cmode = CMODE_8;
 
-    /* setup the DAC the way we like it */
-    dac = aty_ld_le32(DAC_CNTL);
-    dac |= (DAC_8BIT_EN | DAC_RANGE_CNTL);
-    dac |= DAC_MASK;
-    aty_st_le32(DAC_CNTL, dac);
+			if (mac_vmode_to_var(default_vmode, default_cmode, &var))
+				var = default_var;
+		}
+	} else
+#endif /* CONFIG_ALL_PPC */
+	{
+		if (fb_find_mode(&var, info, mode_option, NULL, 0,
+				 &defaultmode, 8) == 0)
+			var = default_var;
+	}
 
-    /* turn off bus mastering, just in case */
-    aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL) | BUS_MASTER_DIS);
+	var.accel_flags &= ~FB_ACCELF_TEXT;
+//	var.accel_flags |= FB_ACCELF_TEXT;/* FIXME Will add accel later */
 
-    aty128fb_set_var(&var, -1, &info->fb_info);
-    aty128_init_engine(&info->default_par, info);
+	if (aty128fb_check_var(&var, info)) {
+		printk(KERN_ERR "aty128fb: Cannot set default mode.\n");
+		return 0;
+	}
 
-    board_list = aty128_board_list_add(board_list, info);
+	/* setup the DAC the way we like it */
+	dac = aty_ld_le32(DAC_CNTL);
+	dac |= (DAC_8BIT_EN | DAC_RANGE_CNTL);
+	dac |= DAC_MASK;
+	if (par->chip_gen == rage_M3)
+		dac |= DAC_PALETTE2_SNOOP_EN;
+	aty_st_le32(DAC_CNTL, dac);
+
+	/* turn off bus mastering, just in case */
+	aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL) | BUS_MASTER_DIS);
+
+	info->var = var;
+	fb_alloc_cmap(&info->cmap, 256, 0);
 
-    size = (var.bits_per_pixel <= 8) ? 256 : 32;
-    fb_alloc_cmap(&info->fb_info.cmap, size, 0);	
+	var.activate = FB_ACTIVATE_NOW;
 
-    if (register_framebuffer(&info->fb_info) < 0)
-	return 0;
+	aty128_init_engine(par);
+
+	if (register_framebuffer(info) < 0)
+		return 0;
 
 #ifdef CONFIG_PMAC_BACKLIGHT
-    /* Could be extended to Rage128Pro LVDS output too */
-    if (info->chip_gen == rage_M3)
-    	register_backlight_controller(&aty128_backlight_controller, info, "ati");
+	/* Could be extended to Rage128Pro LVDS output too */
+	if (par->chip_gen == rage_M3)
+		register_backlight_controller(&aty128_backlight_controller, par, "ati");
 #endif /* CONFIG_PMAC_BACKLIGHT */
-
-    printk(KERN_INFO "fb%d: %s frame buffer device on %s\n",
-	   GET_FB_IDX(info->fb_info.node), aty128fb_name, name);
-
-    return 1;	/* success! */
-}
-
-
-/* add a new card to the list  ++ajoshi */
-static struct
-fb_info_aty128 *aty128_board_list_add(struct fb_info_aty128 *board_list,
-                                       struct fb_info_aty128 *new_node)
-{
-    struct fb_info_aty128 *i_p = board_list;
-
-    new_node->next = NULL;
-    if(board_list == NULL)
-	return new_node;
-    while(i_p->next != NULL)
-	i_p = i_p->next;
-    i_p->next = new_node;
-
-    return board_list;
-}
-
-
-int __init
-aty128fb_init(void)
-{
-#ifdef CONFIG_PCI
-    struct pci_dev *pdev = NULL;
-    const struct aty128_chip_info *aci = &aty128_pci_probe_list[0];
-
-    while (aci->name != NULL) {
-        pdev = pci_find_device(PCI_VENDOR_ID_ATI, aci->device, pdev);
-        while (pdev != NULL) {
-            if (aty128_pci_register(pdev, aci) == 0)
-                return 0;
-            pdev = pci_find_device(PCI_VENDOR_ID_ATI, aci->device, pdev);
-        }
-	aci++;
-    }
+#ifdef CONFIG_PMAC_PBOOK
+	par->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM);
+	pmu_register_sleep_notifier(&aty128_sleep_notifier);
 #endif
 
-    return 0;
-}
+	printk(KERN_INFO "fb%d: %s frame buffer device on %s\n",
+	       minor(info->node), info->fix.id, video_card);
 
+	return 1;	/* success! */
+}
 
 #ifdef CONFIG_PCI
 /* register a card    ++ajoshi */
 static int __init
-aty128_pci_register(struct pci_dev *pdev,
-                               const struct aty128_chip_info *aci)
+aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-	struct fb_info_aty128 *info = NULL;
 	unsigned long fb_addr, reg_addr;
-	int err;
+	struct aty128fb_par *par;
+	struct fb_info *info;
+	int err, size;
 #if !defined(CONFIG_PPC) && !defined(__sparc__)
 	char *bios_seg = NULL;
 #endif
@@ -1824,7 +1628,7 @@
 	if ((err = pci_enable_device(pdev))) {
 		printk(KERN_ERR "aty128fb: Cannot enable PCI device: %d\n",
 				err);
-		goto err_out;
+		return -ENODEV;
 	}
 
 	fb_addr = pci_resource_start(pdev, 0);
@@ -1843,62 +1647,71 @@
 	}
 
 	/* We have the resources. Now virtualize them */
-	if (!(info = kmalloc(sizeof(struct fb_info_aty128), GFP_ATOMIC))) {
+	size = sizeof(struct fb_info) + sizeof(struct aty128fb_par) +
+			 sizeof(u32)*16;
+	if (!(info = kmalloc(size, GFP_ATOMIC))) {
 		printk(KERN_ERR "aty128fb: can't alloc fb_info_aty128\n");
 		goto err_unmap_out;
 	}
-	memset(info, 0, sizeof(struct fb_info_aty128));
+	memset(info, 0, size);
 
-	/* Copy PCI device info into info->pdev */
-	info->pdev = pdev;
+	par = (struct aty128fb_par *)(info + 1);
+	info->pseudo_palette = (void *) (par + 1);
 
-	info->fb_info.currcon = -1;
+	memset(info, 0, sizeof(struct fb_info));
 
-	/* Virtualize mmio region */
-	info->regbase_phys = reg_addr;
-	info->regbase = ioremap(reg_addr, 0x1FFF);
+	info->par = par;
+	info->fix = aty128fb_fix;
 
-	if (!info->regbase)
+	/* Virtualize mmio region */
+	info->fix.mmio_start = reg_addr;
+	par->regbase = ioremap(reg_addr, 0x2000);
+	if (!par->regbase)
 		goto err_free_info;
 
 	/* Grab memory size from the card */
-	info->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
+	par->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
 
 	/* Virtualize the framebuffer */
-	info->frame_buffer_phys = fb_addr;
-	info->frame_buffer = ioremap(fb_addr, info->vram_size);
-
-	if (!info->frame_buffer) {
-		iounmap((void *)info->regbase);
+	info->screen_base = ioremap(fb_addr, par->vram_size);
+	if (!info->screen_base) {
+		iounmap(par->regbase);
 		goto err_free_info;
 	}
 
+	/* Set up info->fix */
+	info->fix = aty128fb_fix;
+	info->fix.smem_start = fb_addr;
+	info->fix.smem_len = par->vram_size;
+	info->fix.mmio_start = reg_addr;
+
 	/* If we can't test scratch registers, something is seriously wrong */
-	if (!register_test(info)) {
+	if (!register_test(par)) {
 		printk(KERN_ERR "aty128fb: Can't write to video register!\n");
 		goto err_out;
 	}
 
 #if !defined(CONFIG_PPC) && !defined(__sparc__)
-	if (!(bios_seg = aty128find_ROM(info)))
+	if (!(bios_seg = aty128find_ROM()))
 		printk(KERN_INFO "aty128fb: Rage128 BIOS not located. "
 					"Guessing...\n");
 	else {
 		printk(KERN_INFO "aty128fb: Rage128 BIOS located at "
 				"segment %4.4X\n", (unsigned int)bios_seg);
-		aty128_get_pllinfo(info, bios_seg);
+		aty128_get_pllinfo(par, bios_seg);
 	}
 #endif
-	aty128_timings(info);
+	aty128_timings(par);
+	pci_set_drvdata(pdev, info);
 
-	if (!aty128_init(info, "PCI"))
+	if (!aty128_init(pdev, ent))
 		goto err_out;
 
 #ifdef CONFIG_MTRR
 	if (mtrr) {
-		info->mtrr.vram = mtrr_add(info->frame_buffer_phys,
-				info->vram_size, MTRR_TYPE_WRCOMB, 1);
-		info->mtrr.vram_valid = 1;
+		par->mtrr.vram = mtrr_add(info->fix.smem_start,
+				par->vram_size, MTRR_TYPE_WRCOMB, 1);
+		par->mtrr.vram_valid = 1;
 		/* let there be speed */
 		printk(KERN_INFO "aty128fb: Rage128 MTRR set to ON\n");
 	}
@@ -1906,8 +1719,8 @@
 	return 0;
 
 err_out:
-	iounmap(info->frame_buffer);
-	iounmap(info->regbase);
+	iounmap(info->screen_base);
+	iounmap(par->regbase);
 err_free_info:
 	kfree(info);
 err_unmap_out:
@@ -1921,21 +1734,48 @@
 			pci_resource_len(pdev, 1));
 	return -ENODEV;
 }
-#endif /* CONFIG_PCI */
 
+static void __devexit aty128_remove(struct pci_dev *pdev)
+{
+	struct fb_info *info = pci_get_drvdata(pdev);
+	struct aty128fb_par *par = info->par;
+
+	if (!info)
+		return;
+
+	unregister_framebuffer(info);
+#ifdef CONFIG_MTRR
+	if (par->mtrr.vram_valid)
+		mtrr_del(par->mtrr.vram, info->fix.smem_start,
+			 par->vram_size);
+#endif /* CONFIG_MTRR */
+	iounmap(par->regbase);
+	iounmap(info->screen_base);
+
+	release_mem_region(pci_resource_start(pdev, 0),
+			   pci_resource_len(pdev, 0));
+	release_mem_region(pci_resource_start(pdev, 1),
+			   pci_resource_len(pdev, 1));
+	release_mem_region(pci_resource_start(pdev, 2),
+			   pci_resource_len(pdev, 2));
+	kfree(info);
+}
+#endif /* CONFIG_PCI */
 
 /* PPC and Sparc cannot read video ROM */
 #if !defined(CONFIG_PPC) && !defined(__sparc__)
-static char __init
-*aty128find_ROM(struct fb_info_aty128 *info)
+static char * __init aty128find_ROM(void)
 {
 	u32  segstart;
 	char *rom_base;
 	char *rom;
 	int  stage;
-	int  i;
+	int  i, j;
 	char aty_rom_sig[] = "761295520";   /* ATI ROM Signature      */
-	char R128_sig[] = "R128";           /* Rage128 ROM identifier */
+	char *R128_sig[] = {
+		"R128",		/* Rage128 ROM identifier */
+		"128b"
+	};
 
 	for (segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
         	stage = 1;
@@ -1966,26 +1806,28 @@
 
 		/* ATI signature found.  Let's see if it's a Rage128 */
 		for (i = 0; (i < 512) && (stage != 4); i++) {
-			if (R128_sig[0] == *rom)
-				if (strncmp(R128_sig, rom, 
-						strlen(R128_sig)) == 0)
-					stage = 4;
+			for (j = 0; j < sizeof(R128_sig)/sizeof(char *);j++) {
+				if (R128_sig[j][0] == *rom)
+					if (strncmp(R128_sig[j], rom, 
+					    strlen(R128_sig[j])) == 0) {
+						stage = 4;
+						break;
+					}
+			}
 			rom++;
 		}
 		if (stage != 4) {
 			iounmap(rom_base);
 			continue;
 		}
-
 		return rom_base;
 	}
-
 	return NULL;
 }
 
 
 static void __init
-aty128_get_pllinfo(struct fb_info_aty128 *info, char *bios_seg)
+aty128_get_pllinfo(struct aty128fb_par *par, char *bios_seg)
 {
 	void *bios_header;
 	void *header_ptr;
@@ -2005,16 +1847,16 @@
 
 	memcpy_fromio(&pll, header_ptr, 50);
 
-	info->constants.ppll_max = pll.PCLK_max_freq;
-	info->constants.ppll_min = pll.PCLK_min_freq;
-	info->constants.xclk = (u32)pll.XCLK;
-	info->constants.ref_divider = (u32)pll.PCLK_ref_divider;
-	info->constants.dotclock = (u32)pll.PCLK_ref_freq;
+	par->constants.ppll_max = pll.PCLK_max_freq;
+	par->constants.ppll_min = pll.PCLK_min_freq;
+	par->constants.xclk = (u32)pll.XCLK;
+	par->constants.ref_divider = (u32)pll.PCLK_ref_divider;
+	par->constants.dotclock = (u32)pll.PCLK_ref_freq;
 
 	DBG("ppll_max %d ppll_min %d xclk %d ref_divider %d dotclock %d\n",
-			info->constants.ppll_max, info->constants.ppll_min,
-			info->constants.xclk, info->constants.ref_divider,
-			info->constants.dotclock);
+			par->constants.ppll_max, par->constants.ppll_min,
+			par->constants.xclk, par->constants.ref_divider,
+			par->constants.dotclock);
 
 }           
 #endif /* !CONFIG_PPC */
@@ -2022,244 +1864,212 @@
 
 /* fill in known card constants if pll_block is not available */
 static void __init
-aty128_timings(struct fb_info_aty128 *info)
+aty128_timings(struct aty128fb_par *par)
 {
-#ifdef CONFIG_PPC
-    /* instead of a table lookup, assume OF has properly
-     * setup the PLL registers and use their values
-     * to set the XCLK values and reference divider values */
+#ifdef CONFIG_ALL_PPC
+	/* instead of a table lookup, assume OF has properly
+	 * setup the PLL registers and use their values
+	 * to set the XCLK values and reference divider values */
 
-    u32 x_mpll_ref_fb_div;
-    u32 xclk_cntl;
-    u32 Nx, M;
-    unsigned PostDivSet[] =
-        { 0, 1, 2, 4, 8, 3, 6, 12 };
+	u32 x_mpll_ref_fb_div;
+	u32 xclk_cntl;
+	u32 Nx, M;
+	unsigned PostDivSet[] = { 0, 1, 2, 4, 8, 3, 6, 12 };
 #endif
 
-    if (!info->constants.dotclock)
-        info->constants.dotclock = 2950;
+	if (!par->constants.dotclock)
+		par->constants.dotclock = 2950;
 
-#ifdef CONFIG_PPC
-    x_mpll_ref_fb_div = aty_ld_pll(X_MPLL_REF_FB_DIV);
-    xclk_cntl = aty_ld_pll(XCLK_CNTL) & 0x7;
-    Nx = (x_mpll_ref_fb_div & 0x00ff00) >> 8;
-    M  = x_mpll_ref_fb_div & 0x0000ff;
+#ifdef CONFIG_ALL_PPC
+	x_mpll_ref_fb_div = aty_ld_pll(X_MPLL_REF_FB_DIV);
+	xclk_cntl = aty_ld_pll(XCLK_CNTL) & 0x7;
+	Nx = (x_mpll_ref_fb_div & 0x00ff00) >> 8;
+	M  = x_mpll_ref_fb_div & 0x0000ff;
 
-    info->constants.xclk = round_div((2 * Nx *
-        info->constants.dotclock), (M * PostDivSet[xclk_cntl]));
+	par->constants.xclk = round_div((2 * Nx * par->constants.dotclock),
+					(M * PostDivSet[xclk_cntl]));
 
-    info->constants.ref_divider =
-        aty_ld_pll(PPLL_REF_DIV) & PPLL_REF_DIV_MASK;
+	par->constants.ref_divider =
+		aty_ld_pll(PPLL_REF_DIV) & PPLL_REF_DIV_MASK;
 #endif
 
-    if (!info->constants.ref_divider) {
-        info->constants.ref_divider = 0x3b;
-
-        aty_st_pll(X_MPLL_REF_FB_DIV, 0x004c4c1e);
-        aty_pll_writeupdate(info);
-    }
-    aty_st_pll(PPLL_REF_DIV, info->constants.ref_divider);
-    aty_pll_writeupdate(info);
-
-    /* from documentation */
-    if (!info->constants.ppll_min)
-        info->constants.ppll_min = 12500;
-    if (!info->constants.ppll_max)
-        info->constants.ppll_max = 25000;    /* 23000 on some cards? */
-    if (!info->constants.xclk)
-        info->constants.xclk = 0x1d4d;	     /* same as mclk */
-
-    info->constants.fifo_width = 128;
-    info->constants.fifo_depth = 32;
-
-    switch (aty_ld_le32(MEM_CNTL) & 0x3) {
-    case 0:
-	info->mem = &sdr_128;
-	break;
-    case 1:
-	info->mem = &sdr_sgram;
-	break;
-    case 2:
-	info->mem = &ddr_sgram;
-	break;
-    default:
-	info->mem = &sdr_sgram;
-    }
-}
-
+	if (!par->constants.ref_divider) {
+		par->constants.ref_divider = 0x3b;
 
-static int
-aty128fbcon_switch(int con, struct fb_info *fb)
-{
-    struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
-    struct aty128fb_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,
-			aty128_getcolreg, fb);
-
-    /* set the current console */
-    fb->currcon = con;
-
-    aty128_decode_var(&fb_display[con].var, &par, info);
-    aty128_set_par(&par, info);
-
-    aty128_set_dispsw(&fb_display[con], info, par.crtc.bpp,
-        par.accel_flags & FB_ACCELF_TEXT);
-
-    do_install_cmap(con, fb);
+		aty_st_pll(X_MPLL_REF_FB_DIV, 0x004c4c1e);
+		aty_pll_writeupdate(par);
+	}
+	aty_st_pll(PPLL_REF_DIV, par->constants.ref_divider);
+	aty_pll_writeupdate(par);
 
-    return 1;
+	/* from documentation */
+	if (!par->constants.ppll_min)
+		par->constants.ppll_min = 12500;
+	if (!par->constants.ppll_max)
+		par->constants.ppll_max = 25000;    /* 23000 on some cards? */
+	if (!par->constants.xclk)
+		par->constants.xclk = 0x1d4d;	     /* same as mclk */
+
+	par->constants.fifo_width = 128;
+	par->constants.fifo_depth = 32;
+
+	switch (aty_ld_le32(MEM_CNTL) & 0x3) {
+	case 0:
+		par->mem = &sdr_128;
+		break;
+	case 1:
+		par->mem = &sdr_sgram;
+		break;
+	case 2:
+		par->mem = &ddr_sgram;
+		break;
+	default:
+		par->mem = &sdr_sgram;
+	}
 }
 
 
     /*
      *  Blank the display.
      */
-static int 
+static int
 aty128fb_blank(int blank, struct fb_info *fb)
 {
-    struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
-    u8 state = 0;
+	struct aty128fb_par *par = fb->par;
+	u8 state = 0;
 
 #ifdef CONFIG_PMAC_BACKLIGHT
-    if ((_machine == _MACH_Pmac) && blank)
-    	set_backlight_enable(0);
+	if ((_machine == _MACH_Pmac) && blank)
+		set_backlight_enable(0);
 #endif /* CONFIG_PMAC_BACKLIGHT */
 
-    if (blank & VESA_VSYNC_SUSPEND)
-	state |= 2;
-    if (blank & VESA_HSYNC_SUSPEND)
-	state |= 1;
-    if (blank & VESA_POWERDOWN)
-	state |= 4;
-
-    aty_st_8(CRTC_EXT_CNTL+1, state);
-
+	if (blank & VESA_VSYNC_SUSPEND)
+		state |= 2;
+	if (blank & VESA_HSYNC_SUSPEND)
+		state |= 1;
+	if (blank & VESA_POWERDOWN)
+		state |= 4;
+
+	aty_st_8(CRTC_EXT_CNTL+1, state);
+
+#ifdef CONFIG_PMAC_PBOOK
+	if (par->chip_gen == rage_M3) {
+		aty128_set_crt_enable(par, par->crt_on && !blank);
+		aty128_set_lcd_enable(par, par->lcd_on && !blank);
+	}
+#endif	
 #ifdef CONFIG_PMAC_BACKLIGHT
-    if ((_machine == _MACH_Pmac) && !blank)
-    	set_backlight_enable(1);
+	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
-aty128_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-                         u_int *transp, struct fb_info *fb)
-{
-    struct fb_info_aty128 *info = (struct fb_info_aty128 *) 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;
+	return 0;
 }
 
-    /*
-     *  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.
-     */
+/*
+ *  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
 aty128fb_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_aty128 *info = (struct fb_info_aty128 *)fb;
-    u32 col;
+	struct aty128fb_par *par = info->par;
 
-    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;
-
-    /* Note: For now, on M3, we set palette on both heads, which may
-     * be useless. Can someone with a M3 check this ? */
-
-    /* initialize gamma ramp for hi-color+ */
-
-    if ((info->current_par.crtc.bpp > 8) && (regno == 0)) {
-        int i;
-
-        if (info->chip_gen == rage_M3)
-            aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & ~DAC_PALETTE_ACCESS_CNTL);
-
-        for (i=16; i<256; i++) {
-            aty_st_8(PALETTE_INDEX, i);
-            col = (i << 16) | (i << 8) | i;
-            aty_st_le32(PALETTE_DATA, col);
-        }
-
-        if (info->chip_gen == rage_M3) {
-            aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PALETTE_ACCESS_CNTL);
-
-            for (i=16; i<256; i++) {
-                aty_st_8(PALETTE_INDEX, i);
-                col = (i << 16) | (i << 8) | i;
-                aty_st_le32(PALETTE_DATA, col);
-            }
-        }
-    }
+	if (regno > 255
+	    || (par->crtc.depth == 16 && regno > 63)
+	    || (par->crtc.depth == 15 && regno > 31))
+		return 1;
+
+	red >>= 8;
+	green >>= 8;
+	blue >>= 8;
+
+	if (regno < 16) {
+		int i;
+		switch (par->crtc.depth) {
+		case 15:
+			((u16 *) (info->pseudo_palette))[regno] =
+			    (regno << 10) | (regno << 5) | regno;
+			break;
+		case 16:
+			((u16 *) (info->pseudo_palette))[regno] =
+			    (regno << 11) | (regno << 6) | 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;
+		}
+	}
 
-    /* initialize palette */
+	if (par->crtc.depth == 16) {
+		/*
+		 * With the 5-6-5 split of bits for RGB at 16 bits/pixel, we
+		 * have 32 slots for R and B values but 64 slots for G values.
+		 * Thus the R and B values go in one slot but the G value
+		 * goes in a different slot, and we have to avoid disturbing
+		 * the other fields in the slots we touch.
+		 */
+		par->red[regno] = red;
+		par->green[regno] = green;
+		par->blue[regno] = blue;
+		if (regno > 0 && regno < 32)
+			aty128_st_pal(regno * 8, red, par->green[regno*2],
+				      blue, par);
+		red = par->red[regno/2];
+		blue = par->blue[regno/2];
+		regno <<= 2;
+	} else if (par->crtc.bpp == 16)
+		regno <<= 3;
+	aty128_st_pal(regno, red, green, blue, par);
 
-    if (info->chip_gen == rage_M3)
-        aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & ~DAC_PALETTE_ACCESS_CNTL);
+	return 0;
+}
 
-    if (info->current_par.crtc.bpp == 16)
-        aty_st_8(PALETTE_INDEX, (regno << 3));
-    else
-        aty_st_8(PALETTE_INDEX, regno);
-    col = (red << 16) | (green << 8) | blue;
-    aty_st_le32(PALETTE_DATA, col);
-    if (info->chip_gen == rage_M3) {
-    	aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PALETTE_ACCESS_CNTL);
-        if (info->current_par.crtc.bpp == 16)
-            aty_st_8(PALETTE_INDEX, (regno << 3));
-        else
-            aty_st_8(PALETTE_INDEX, regno);
-        aty_st_le32(PALETTE_DATA, col);
-    }
+#define ATY_MIRROR_LCD_ON	0x00000001
+#define ATY_MIRROR_CRT_ON	0x00000002
 
-    if (regno < 16)
-	switch (info->current_par.crtc.bpp) {
-#ifdef FBCON_HAS_CFB16
-	case 9 ... 16:
-	    info->fbcon_cmap.cfb16[regno] = (regno << 10) | (regno << 5) |
-                regno;
-	    break;
-#endif
-#ifdef FBCON_HAS_CFB24
-	case 17 ... 24:
-	    info->fbcon_cmap.cfb24[regno] = (regno << 16) | (regno << 8) |
-		regno;
-	    break;
-#endif
-#ifdef FBCON_HAS_CFB32
-	case 25 ... 32: {
-            u32 i;
-
-            i = (regno << 8) | regno;
-            info->fbcon_cmap.cfb32[regno] = (i << 16) | i;
-	    break;
-        }
-#endif
+/* out param: u32*	backlight value: 0 to 15 */
+#define FBIO_ATY128_GET_MIRROR	_IOR('@', 1, sizeof(__u32*))
+/* in param: u32*	backlight value: 0 to 15 */
+#define FBIO_ATY128_SET_MIRROR	_IOW('@', 2, sizeof(__u32*))
+
+static int aty128fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+			  u_long arg, struct fb_info *info)
+{
+#ifdef CONFIG_PMAC_PBOOK
+	struct aty128fb_par *par = info->par;
+	u32 value;
+	int rc;
+    
+	switch (cmd) {
+	case FBIO_ATY128_SET_MIRROR:
+		if (par->chip_gen != rage_M3)
+			return -EINVAL;
+		rc = get_user(value, (__u32*)arg);
+		if (rc)
+			return rc;
+		par->lcd_on = (value & 0x01) != 0;
+		par->crt_on = (value & 0x02) != 0;
+		if (!par->crt_on && !par->lcd_on)
+			par->lcd_on = 1;
+		aty128_set_crt_enable(par, par->crt_on);	
+		aty128_set_lcd_enable(par, par->lcd_on);	
+		return 0;
+	case FBIO_ATY128_GET_MIRROR:
+		if (par->chip_gen != rage_M3)
+			return -EINVAL;
+		value = (par->crt_on << 1) | par->lcd_on;
+		return put_user(value, (__u32*)arg);
 	}
-    return 0;
+#endif
+	return -EINVAL;
 }
 
 #ifdef CONFIG_PMAC_BACKLIGHT
@@ -2268,21 +2078,58 @@
 	0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24
 };
 
+/* We turn off the LCD completely instead of just dimming the backlight.
+ * This provides greater power saving and the display is useless without
+ * backlight anyway
+ */
+#define BACKLIGHT_LVDS_OFF
+/* That one prevents proper CRT output with LCD off */
+#undef BACKLIGHT_DAC_OFF
+
 static int
-aty128_set_backlight_enable(int on, int level, void* data)
+aty128_set_backlight_enable(int on, int level, void *data)
 {
-	struct fb_info_aty128 *info = (struct fb_info_aty128 *)data;
+	struct aty128fb_par *par = data;
 	unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL);
-	
+
+	if (!par->lcd_on)
+		on = 0;
 	reg |= LVDS_BL_MOD_EN | LVDS_BLON;
 	if (on && level > BACKLIGHT_OFF) {
+		reg |= LVDS_DIGION;
+		if (!reg & LVDS_ON) {
+			reg &= ~LVDS_BLON;
+			aty_st_le32(LVDS_GEN_CNTL, reg);
+			(void)aty_ld_le32(LVDS_GEN_CNTL);
+			mdelay(10);
+			reg |= LVDS_BLON;
+			aty_st_le32(LVDS_GEN_CNTL, reg);
+		}
 		reg &= ~LVDS_BL_MOD_LEVEL_MASK;
 		reg |= (backlight_conv[level] << LVDS_BL_MOD_LEVEL_SHIFT);
+#ifdef BACKLIGHT_LVDS_OFF
+		reg |= LVDS_ON | LVDS_EN;
+		reg &= ~LVDS_DISPLAY_DIS;
+#endif
+		aty_st_le32(LVDS_GEN_CNTL, reg);
+#ifdef BACKLIGHT_DAC_OFF
+		aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & (~DAC_PDWN));
+#endif		
 	} else {
 		reg &= ~LVDS_BL_MOD_LEVEL_MASK;
 		reg |= (backlight_conv[0] << LVDS_BL_MOD_LEVEL_SHIFT);
+#ifdef BACKLIGHT_LVDS_OFF
+		reg |= LVDS_DISPLAY_DIS;
+		aty_st_le32(LVDS_GEN_CNTL, reg);
+		(void)aty_ld_le32(LVDS_GEN_CNTL);
+		udelay(10);
+		reg &= ~(LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGION);
+#endif		
+		aty_st_le32(LVDS_GEN_CNTL, reg);
+#ifdef BACKLIGHT_DAC_OFF
+		aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PDWN);
+#endif		
 	}
-	aty_st_le32(LVDS_GEN_CNTL, reg);
 
 	return 0;
 }
@@ -2294,6 +2141,7 @@
 }
 #endif /* CONFIG_PMAC_BACKLIGHT */
 
+#if 0
     /*
      *  Accelerated functions
      */
@@ -2301,39 +2149,39 @@
 static inline void
 aty128_rectcopy(int srcx, int srcy, int dstx, int dsty,
 		u_int width, u_int height,
-		struct fb_info_aty128 *info)
+		struct fb_info_aty128 *par)
 {
-    u32 save_dp_datatype, save_dp_cntl, bppval;
+    u32 save_dp_datatype, save_dp_cntl, dstval;
 
     if (!width || !height)
         return;
 
-    bppval = bpp_to_depth(info->current_par.crtc.bpp);
-    if (bppval == DST_24BPP) {
+    dstval = depth_to_dst(par->current_par.crtc.depth);
+    if (dstval == DST_24BPP) {
         srcx *= 3;
         dstx *= 3;
         width *= 3;
-    } else if (bppval == -EINVAL) {
-        printk("aty128fb: invalid depth\n");
+    } else if (dstval == -EINVAL) {
+        printk("aty128fb: invalid depth or RGBA\n");
         return;
     }
 
-    wait_for_fifo(2, info);
+    wait_for_fifo(2, par);
     save_dp_datatype = aty_ld_le32(DP_DATATYPE);
     save_dp_cntl     = aty_ld_le32(DP_CNTL);
 
-    wait_for_fifo(6, info);
+    wait_for_fifo(6, par);
     aty_st_le32(SRC_Y_X, (srcy << 16) | srcx);
     aty_st_le32(DP_MIX, ROP3_SRCCOPY | DP_SRC_RECT);
     aty_st_le32(DP_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
-    aty_st_le32(DP_DATATYPE, save_dp_datatype | bppval | SRC_DSTCOLOR);
+    aty_st_le32(DP_DATATYPE, save_dp_datatype | dstval | SRC_DSTCOLOR);
 
     aty_st_le32(DST_Y_X, (dsty << 16) | dstx);
     aty_st_le32(DST_HEIGHT_WIDTH, (height << 16) | width);
 
-    info->blitter_may_be_busy = 1;
+    par->blitter_may_be_busy = 1;
 
-    wait_for_fifo(2, info);
+    wait_for_fifo(2, par);
     aty_st_le32(DP_DATATYPE, save_dp_datatype);
     aty_st_le32(DP_CNTL, save_dp_cntl); 
 }
@@ -2357,209 +2205,129 @@
     aty128_rectcopy(sx, sy, dx, dy, width, height,
 			(struct fb_info_aty128 *)p->fb_info);
 }
+#endif /* 0 */
 
-
-#ifdef FBCON_HAS_CFB8
-static void fbcon_aty8_putc(struct vc_data *conp, struct display *p,
-                            int c, int yy, int xx)
-{
-    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
-
-    if (fb->blitter_may_be_busy)
-        wait_for_idle(fb);
-
-    fbcon_cfb8_putc(conp, p, c, yy, xx);
-}
-
-
-static void fbcon_aty8_putcs(struct vc_data *conp, struct display *p,
-                             const unsigned short *s, int count,
-                             int yy, int xx)
-{
-    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
-
-    if (fb->blitter_may_be_busy)
-        wait_for_idle(fb);
-
-    fbcon_cfb8_putcs(conp, p, s, count, yy, xx);
-}
-
-
-static void fbcon_aty8_clear_margins(struct vc_data *conp,
-                                     struct display *p, int bottom_only)
-{
-    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
-
-    if (fb->blitter_may_be_busy)
-        wait_for_idle(fb);
-
-    fbcon_cfb8_clear_margins(conp, p, bottom_only);
-}
-
-static struct display_switch fbcon_aty128_8 = {
-    setup:		fbcon_cfb8_setup,
-    bmove:		fbcon_aty128_bmove,
-    clear:		fbcon_cfb8_clear,
-    putc:		fbcon_aty8_putc,
-    putcs:		fbcon_aty8_putcs,
-    revc:		fbcon_cfb8_revc,
-    clear_margins:	fbcon_aty8_clear_margins,
-    fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif
-#ifdef FBCON_HAS_CFB16
-static void fbcon_aty16_putc(struct vc_data *conp, struct display *p,
-                            int c, int yy, int xx)
-{
-    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
-
-    if (fb->blitter_may_be_busy)
-        wait_for_idle(fb);
-
-    fbcon_cfb16_putc(conp, p, c, yy, xx);
-}
-
-
-static void fbcon_aty16_putcs(struct vc_data *conp, struct display *p,
-                             const unsigned short *s, int count,
-                             int yy, int xx)
-{
-    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
-
-    if (fb->blitter_may_be_busy)
-        wait_for_idle(fb);
-
-    fbcon_cfb16_putcs(conp, p, s, count, yy, xx);
-}
-
-
-static void fbcon_aty16_clear_margins(struct vc_data *conp,
-                                     struct display *p, int bottom_only)
-{
-    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
-
-    if (fb->blitter_may_be_busy)
-        wait_for_idle(fb);
-
-    fbcon_cfb16_clear_margins(conp, p, bottom_only);
-}
-
-static struct display_switch fbcon_aty128_16 = {
-    setup:		fbcon_cfb16_setup,
-    bmove:		fbcon_aty128_bmove,
-    clear:		fbcon_cfb16_clear,
-    putc:		fbcon_aty16_putc,
-    putcs:		fbcon_aty16_putcs,
-    revc:		fbcon_cfb16_revc,
-    clear_margins:	fbcon_aty16_clear_margins,
-    fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif
-#ifdef FBCON_HAS_CFB24
-static void fbcon_aty24_putc(struct vc_data *conp, struct display *p,
-                            int c, int yy, int xx)
-{
-    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
-
-    if (fb->blitter_may_be_busy)
-        wait_for_idle(fb);
-
-    fbcon_cfb24_putc(conp, p, c, yy, xx);
-}
-
-
-static void fbcon_aty24_putcs(struct vc_data *conp, struct display *p,
-                             const unsigned short *s, int count,
-                             int yy, int xx)
-{
-    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
-
-    if (fb->blitter_may_be_busy)
-        wait_for_idle(fb);
-
-    fbcon_cfb24_putcs(conp, p, s, count, yy, xx);
-}
-
-
-static void fbcon_aty24_clear_margins(struct vc_data *conp,
-                                     struct display *p, int bottom_only)
+#ifdef CONFIG_PMAC_PBOOK
+static void
+aty128_set_suspend(struct aty128fb_par *par, int suspend)
 {
-    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
+	u32	pmgt;
+	u16	pwr_command;
 
-    if (fb->blitter_may_be_busy)
-        wait_for_idle(fb);
-
-    fbcon_cfb24_clear_margins(conp, p, bottom_only);
+	if (!par->pm_reg)
+		return;
+		
+	/* Set the chip into the appropriate suspend mode (we use D2,
+	 * D3 would require a complete re-initialisation of the chip,
+	 * including PCI config registers, clocks, AGP configuration, ...)
+	 */
+	if (suspend) {
+		/* Make sure CRTC2 is reset. Remove that the day we decide to
+		 * actually use CRTC2 and replace it with real code for disabling
+		 * the CRTC2 output during sleep
+		 */
+		aty_st_le32(CRTC2_GEN_CNTL, aty_ld_le32(CRTC2_GEN_CNTL) &
+			~(CRTC2_EN));
+
+		/* Set the power management mode to be PCI based */
+		/* Use this magic value for now */
+		pmgt = 0x0c005407;
+		aty_st_pll(POWER_MANAGEMENT, pmgt);
+		(void)aty_ld_pll(POWER_MANAGEMENT);
+		aty_st_le32(BUS_CNTL1, 0x00000010);
+		aty_st_le32(MEM_POWER_MISC, 0x0c830000);
+		mdelay(100);
+		pci_read_config_word(par->pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
+		/* Switch PCI power management to D2 */
+		pci_write_config_word(par->pdev, par->pm_reg+PCI_PM_CTRL,
+			(pwr_command & ~PCI_PM_CTRL_STATE_MASK) | 2);
+		pci_read_config_word(par->pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
+	} else {
+		/* Switch back PCI power management to D0 */
+		mdelay(100);
+		pci_write_config_word(par->pdev, par->pm_reg+PCI_PM_CTRL, 0);
+		mdelay(100);
+		pci_read_config_word(par->pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
+		mdelay(100);
+	}
 }
 
-static struct display_switch fbcon_aty128_24 = {
-    setup:		fbcon_cfb24_setup,
-    bmove:		fbcon_aty128_bmove,
-    clear:		fbcon_cfb24_clear,
-    putc:		fbcon_aty24_putc,
-    putcs:		fbcon_aty24_putcs,
-    revc:		fbcon_cfb24_revc,
-    clear_margins:	fbcon_aty24_clear_margins,
-    fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif
-#ifdef FBCON_HAS_CFB32
-static void fbcon_aty32_putc(struct vc_data *conp, struct display *p,
-                            int c, int yy, int xx)
+/*
+ * Save the contents of the frame buffer when we go to sleep,
+ * and restore it when we wake up again.
+ */
+int
+aty128_sleep_notify(struct pmu_sleep_notifier *self, int when)
 {
-    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
-
-    if (fb->blitter_may_be_busy)
-        wait_for_idle(fb);
+ 	int result = PBOOK_SLEEP_OK, nb;
+	struct fb_info *info = info;	/* FIXME!!! How do find which framebuffer  */
+	struct aty128fb_par *par = info->par;
+
+	nb = info->var.yres * info->fix.line_length;
+
+	switch (when) {
+	case PBOOK_SLEEP_REQUEST:
+		par->save_framebuffer = vmalloc(nb);
+		if (par->save_framebuffer == NULL)
+			return PBOOK_SLEEP_REFUSE;
+		break;
+	case PBOOK_SLEEP_REJECT:
+		if (par->save_framebuffer) {
+			vfree(par->save_framebuffer);
+			par->save_framebuffer = 0;
+		}
+		break;
+	case PBOOK_SLEEP_NOW:
+		wait_for_idle(par);
+		aty128_reset_engine(par);
+		wait_for_idle(par);
+
+		/* Backup fb content */	
+		if (par->save_framebuffer)
+			memcpy_fromio(par->save_framebuffer,
+			       info->screen_base, nb);
+
+		/* Blank display and LCD */
+		aty128fb_blank(VESA_POWERDOWN, info);
+			
+		/* Sleep the chip */
+		aty128_set_suspend(par, 1);
 
-    fbcon_cfb32_putc(conp, p, c, yy, xx);
+		break;
+	case PBOOK_WAKE:
+		/* Wake the chip */
+		aty128_set_suspend(par, 0);
+		
+		aty128_reset_engine(par);
+		wait_for_idle(par);
+
+		/* Restore fb content */			
+		if (par->save_framebuffer) {
+			memcpy_toio(info->screen_base,
+			       par->save_framebuffer, nb);
+			vfree(par->save_framebuffer);
+			par->save_framebuffer = 0;
+		}
+		aty128fb_blank(0, info);
+		break;
+	}
+	return result;
 }
+#endif /* CONFIG_PMAC_PBOOK */
 
-
-static void fbcon_aty32_putcs(struct vc_data *conp, struct display *p,
-                             const unsigned short *s, int count,
-                             int yy, int xx)
+int __init aty128fb_init(void)
 {
-    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
-
-    if (fb->blitter_may_be_busy)
-        wait_for_idle(fb);
-
-    fbcon_cfb32_putcs(conp, p, s, count, yy, xx);
+	return pci_module_init(&aty128fb_driver);
 }
 
-
-static void fbcon_aty32_clear_margins(struct vc_data *conp,
-                                     struct display *p, int bottom_only)
+static void __exit aty128fb_exit(void)
 {
-    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
-
-    if (fb->blitter_may_be_busy)
-        wait_for_idle(fb);
-
-    fbcon_cfb32_clear_margins(conp, p, bottom_only);
+	pci_unregister_driver(&aty128fb_driver);
 }
 
-static struct display_switch fbcon_aty128_32 = {
-    setup:		fbcon_cfb32_setup,
-    bmove:		fbcon_aty128_bmove,
-    clear:		fbcon_cfb32_clear,
-    putc:		fbcon_aty32_putc,
-    putcs:		fbcon_aty32_putcs,
-    revc:		fbcon_cfb32_revc,
-    clear_margins:	fbcon_aty32_clear_margins,
-    fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif
-
-#ifdef MODULE
 MODULE_AUTHOR("(c)1999-2000 Brad Douglas <brad@neruo.com>");
 MODULE_DESCRIPTION("FBDev driver for ATI Rage128 / Pro cards");
 MODULE_LICENSE("GPL");
-MODULE_PARM(noaccel, "i");
-MODULE_PARM_DESC(noaccel, "Disable hardware acceleration (0 or 1=disabled) (default=0)");
-MODULE_PARM(font, "s");
-MODULE_PARM_DESC(font, "Specify one of the compiled-in fonts (default=none)");
 MODULE_PARM(mode, "s");
 MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
 #ifdef CONFIG_MTRR
@@ -2567,58 +2335,3 @@
 MODULE_PARM_DESC(nomtrr, "Disable MTRR support (0 or 1=disabled) (default=0)");
 #endif
 
-int __init
-init_module(void)
-{
-    if (noaccel) {
-        noaccel = 1;
-        printk(KERN_INFO "aty128fb: Parameter NOACCEL set\n");
-    }
-    if (font) {
-        strncpy(fontname, font, sizeof(fontname)-1);
-        printk(KERN_INFO "aty128fb: Parameter FONT set to %s\n", font);
-    }
-    if (mode) {
-        mode_option = mode;
-        printk(KERN_INFO "aty128fb: Parameter MODE set to %s\n", mode);
-    }
-#ifdef CONFIG_MTRR
-    if (nomtrr) {
-        mtrr = 0;
-        printk(KERN_INFO "aty128fb: Parameter NOMTRR set\n");
-    }
-#endif
-    
-    aty128fb_init();
-    return 0;
-}
-
-void __exit
-cleanup_module(void)
-{
-    struct fb_info_aty128 *info = board_list;
-
-    while (board_list) {
-        info = board_list;
-        board_list = board_list->next;
-
-        unregister_framebuffer(&info->fb_info);
-#ifdef CONFIG_MTRR
-        if (info->mtrr.vram_valid)
-            mtrr_del(info->mtrr.vram, info->frame_buffer_phys,
-                     info->vram_size);
-#endif /* CONFIG_MTRR */
-        iounmap(info->regbase);
-        iounmap(info->frame_buffer);
-
-        release_mem_region(pci_resource_start(info->pdev, 0),
-                           pci_resource_len(info->pdev, 0));
-        release_mem_region(pci_resource_start(info->pdev, 1),
-                           pci_resource_len(info->pdev, 1));
-        release_mem_region(pci_resource_start(info->pdev, 2),
-                           pci_resource_len(info->pdev, 2));
-
-        kfree(info);
-    }
-}
-#endif /* MODULE */
diff -Nru a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c
--- a/drivers/video/cfbcopyarea.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/video/cfbcopyarea.c	Mon Dec  9 18:46:51 2002
@@ -20,30 +20,322 @@
  *  the native cpu endians. I also need to deal with MSB position in the word.
  *  
  */
+#include <linux/config.h>
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/fb.h>
 #include <linux/slab.h>
 #include <asm/types.h>
 #include <asm/io.h>
-#include <video/fbcon.h>
+
+#define LONG_MASK  (BITS_PER_LONG - 1)
 
 #if BITS_PER_LONG == 32
-#define FB_READ		fb_readl
-#define FB_WRITE	fb_writel
+#define FB_WRITEL fb_writel
+#define FB_READL  fb_readl
+#define SHIFT_PER_LONG 5
+#define BYTES_PER_LONG 4
 #else
-#define FB_READ		fb_readq
-#define FB_WRITE	fb_writeq
+#define FB_WRITEL fb_writeq
+#define FB_READL  fb_readq(x)
+#define SHIFT_PER_LONG 6
+#define BYTES_PER_LONG 8
 #endif
 
+static void bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
+		   int src_idx, unsigned long n)
+{
+	unsigned long first, last;
+	int shift = dst_idx-src_idx, left, right;
+	unsigned long d0, d1;
+	int m;
+	
+	if (!n)
+		return;
+	
+	shift = dst_idx-src_idx;
+	first = ~0UL >> dst_idx;
+	last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
+	
+	if (!shift) {
+		// Same alignment for source and dest
+		
+		if (dst_idx+n <= BITS_PER_LONG) {
+			// Single word
+			if (last)
+				first &= last;
+			FB_WRITEL((*src & first) | (FB_READL(dst) & ~first), dst);
+		} else {
+			// Multiple destination words
+			// Leading bits
+			if (first) {
+				
+				FB_WRITEL((*src & first) | (FB_READL(dst) & ~first), dst);
+				dst++;
+				src++;
+				n -= BITS_PER_LONG-dst_idx;
+			}
+			
+			// Main chunk
+			n /= BITS_PER_LONG;
+			while (n >= 8) {
+				FB_WRITEL(*src++, dst++);
+				FB_WRITEL(*src++, dst++);
+				FB_WRITEL(*src++, dst++);
+				FB_WRITEL(*src++, dst++);
+				FB_WRITEL(*src++, dst++);
+				FB_WRITEL(*src++, dst++);
+				FB_WRITEL(*src++, dst++);
+				FB_WRITEL(*src++, dst++);
+				n -= 8;
+			}
+			while (n--)
+				FB_WRITEL(*src++, dst++);
+			// Trailing bits
+			if (last)
+				FB_WRITEL((*src & last) | (FB_READL(dst) & ~last), dst);
+		}
+	} else {
+		// Different alignment for source and dest
+		
+		right = shift & (BITS_PER_LONG-1);
+		left = -shift & (BITS_PER_LONG-1);
+		
+		if (dst_idx+n <= BITS_PER_LONG) {
+			// Single destination word
+			if (last)
+				first &= last;
+			if (shift > 0) {
+				// Single source word
+				FB_WRITEL(((*src >> right) & first) | (FB_READL(dst) & ~first), dst);
+			} else if (src_idx+n <= BITS_PER_LONG) {
+				// Single source word
+				FB_WRITEL(((*src << left) & first) | (FB_READL(dst) & ~first), dst);
+			} else {
+				// 2 source words
+				d0 = *src++;
+				d1 = *src;
+				FB_WRITEL(((d0 << left | d1 >> right) & first) | (FB_READL(dst) & ~first), dst);
+			}
+		} else {
+			// Multiple destination words
+			d0 = *src++;
+			// Leading bits
+			if (shift > 0) {
+				// Single source word
+				FB_WRITEL(((d0 >> right) & first) | (FB_READL(dst) & ~first), dst);
+				dst++;
+				n -= BITS_PER_LONG-dst_idx;
+			} else {
+				// 2 source words
+				d1 = *src++;
+				FB_WRITEL(((d0 << left | d1 >> right) & first) | (FB_READL(dst) & ~first), dst);
+				d0 = d1;
+				dst++;
+				n -= BITS_PER_LONG-dst_idx;
+			}
+			
+			// Main chunk
+			m = n % BITS_PER_LONG;
+			n /= BITS_PER_LONG;
+			while (n >= 4) {
+				d1 = *src++;
+				FB_WRITEL(d0 << left | d1 >> right, dst++);
+				d0 = d1;
+				d1 = *src++;
+				FB_WRITEL(d0 << left | d1 >> right, dst++);
+				d0 = d1;
+				d1 = *src++;
+				FB_WRITEL(d0 << left | d1 >> right, dst++);
+				d0 = d1;
+				d1 = *src++;
+				FB_WRITEL(d0 << left | d1 >> right, dst++);
+				d0 = d1;
+				n -= 4;
+			}
+			while (n--) {
+				d1 = *src++;
+				FB_WRITEL(d0 << left | d1 >> right, dst++);
+				d0 = d1;
+			}
+			
+			// Trailing bits
+			if (last) {
+				if (m <= right) {
+					// Single source word
+					FB_WRITEL(((d0 << left) & last) | (FB_READL(dst) & ~last), dst);
+				} else {
+					// 2 source words
+					d1 = *src;
+					FB_WRITEL(((d0 << left | d1 >> right) & last) | (FB_READL(dst) & ~last), dst);
+				}
+			}
+		}
+	}
+}
+
+static void bitcpy_rev(unsigned long *dst, int dst_idx,
+		       const unsigned long *src, int src_idx, unsigned long n)
+{
+	unsigned long first, last;
+	int shift = dst_idx-src_idx, left, right;
+	unsigned long d0, d1;
+	int m;
+	
+	if (!n)
+		return;
+	
+	dst += (n-1)/BITS_PER_LONG;
+	src += (n-1)/BITS_PER_LONG;
+	if ((n-1) % BITS_PER_LONG) {
+		dst_idx += (n-1) % BITS_PER_LONG;
+		dst += dst_idx >> SHIFT_PER_LONG;
+		dst_idx &= BITS_PER_LONG-1;
+		src_idx += (n-1) % BITS_PER_LONG;
+		src += src_idx >> SHIFT_PER_LONG;
+		src_idx &= BITS_PER_LONG-1;
+	}
+	
+	shift = dst_idx-src_idx;
+	first = ~0UL << (BITS_PER_LONG-1-dst_idx);
+	last = ~(~0UL << (BITS_PER_LONG-1-((dst_idx-n) % BITS_PER_LONG)));
+	
+	if (!shift) {
+		// Same alignment for source and dest
+		
+		if ((unsigned long)dst_idx+1 >= n) {
+			// Single word
+			if (last)
+				first &= last;
+			FB_WRITEL((*src & first) | (FB_READL(dst) & ~first), dst);
+		} else {
+			// Multiple destination words
+			// Leading bits
+			if (first) {
+				FB_WRITEL((*src & first) | (FB_READL(dst) & ~first), dst);
+				dst--;
+				src--;
+				n -= dst_idx+1;
+			}
+			
+			// Main chunk
+			n /= BITS_PER_LONG;
+			while (n >= 8) {
+				FB_WRITEL(*src--, dst--);
+				FB_WRITEL(*src--, dst--);
+				FB_WRITEL(*src--, dst--);
+				FB_WRITEL(*src--, dst--);
+				FB_WRITEL(*src--, dst--);
+				FB_WRITEL(*src--, dst--);
+				FB_WRITEL(*src--, dst--);
+				FB_WRITEL(*src--, dst--);
+				n -= 8;
+			}
+			while (n--)
+				FB_WRITEL(*src--, dst--);
+			
+			// Trailing bits
+			if (last)
+				FB_WRITEL((*src & last) | (FB_READL(dst) & ~last), dst);
+		}
+	} else {
+		// Different alignment for source and dest
+		
+		right = shift & (BITS_PER_LONG-1);
+		left = -shift & (BITS_PER_LONG-1);
+		
+		if ((unsigned long)dst_idx+1 >= n) {
+			// Single destination word
+			if (last)
+				first &= last;
+			if (shift < 0) {
+				// Single source word
+				FB_WRITEL((*src << left & first) | (FB_READL(dst) & ~first), dst);
+			} else if (1+(unsigned long)src_idx >= n) {
+				// Single source word
+				FB_WRITEL(((*src >> right) & first) | (FB_READL(dst) & ~first), dst);
+			} else {
+				// 2 source words
+				d0 = *src--;
+				d1 = *src;
+				FB_WRITEL(((d0 >> right | d1 << left) & first) | (FB_READL(dst) & ~first), dst);
+			}
+		} else {
+			// Multiple destination words
+			d0 = *src--;
+			// Leading bits
+			if (shift < 0) {
+				// Single source word
+				FB_WRITEL(((d0 << left) & first) | (FB_READL(dst) & ~first), dst);
+				dst--;
+				n -= dst_idx+1;
+			} else {
+				// 2 source words
+				d1 = *src--;
+				FB_WRITEL(((d0 >> right | d1 << left) & first) | (FB_READL(dst) & ~first), dst);
+				d0 = d1;
+				dst--;
+				n -= dst_idx+1;
+			}
+			
+			// Main chunk
+			m = n % BITS_PER_LONG;
+			n /= BITS_PER_LONG;
+			while (n >= 4) {
+				d1 = *src--;
+				FB_WRITEL(d0 >> right | d1 << left, dst--);
+				d0 = d1;
+				d1 = *src--;
+				FB_WRITEL(d0 >> right | d1 << left, dst--);
+				d0 = d1;
+				d1 = *src--;
+				FB_WRITEL(d0 >> right | d1 << left, dst--);
+				d0 = d1;
+				d1 = *src--;
+				FB_WRITEL(d0 >> right | d1 << left, dst--);
+				d0 = d1;
+				n -= 4;
+			}
+			while (n--) {
+				d1 = *src--;
+				FB_WRITEL(d0 >> right | d1 << left, dst--);
+				d0 = d1;
+			}
+			
+			// Trailing bits
+			if (last) {
+				if (m <= left) {
+					// Single source word
+					FB_WRITEL(((d0 >> right) & last) | (FB_READL(dst) & ~last), dst);
+				} else {
+					// 2 source words
+					d1 = *src;
+					FB_WRITEL(((d0 >> right | d1 << left) & last) |
+						  (FB_READL(dst) & ~last), dst);
+				}
+			}
+		}
+	}
+}
+
 void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area)
 {
-	int x2, y2, lineincr, shift, shift_right, shift_left, old_dx, old_dy;
-	int j, linesize = p->fix.line_length, bpl = sizeof(unsigned long);
-	unsigned long start_index, end_index, start_mask, end_mask, last;
+	int x2, y2, old_dx, old_dy, vxres, vyres;
+	unsigned long next_line = p->fix.line_length;
+	int dst_idx = 0, src_idx = 0, rev_copy = 0;
 	unsigned long *dst = NULL, *src = NULL;
-	char *src1, *dst1;
-	int tmp, height;
+
+	/* We want rotation but lack hardware to do it for us. */
+	if (!p->fbops->fb_rotate && p->var.rotate) {
+	}	
+	
+	vxres = p->var.xres_virtual;
+	vyres = p->var.yres_virtual;
+
+	if (area->dx > vxres || area->sx > vxres || 
+	    area->dy > vyres || area->sy > vyres)
+		return;
 
 	/* clip the destination */
 	old_dx = area->dx;
@@ -57,8 +349,8 @@
 	y2 = area->dy + area->height;
 	area->dx = area->dx > 0 ? area->dx : 0;
 	area->dy = area->dy > 0 ? area->dy : 0;
-	x2 = x2 < p->var.xres_virtual ? x2 : p->var.xres_virtual;
-	y2 = y2 < p->var.yres_virtual ? y2 : p->var.yres_virtual;
+	x2 = x2 < vxres ? x2 : vxres;
+	y2 = y2 < vyres ? y2 : vyres;
 	area->width = x2 - area->dx;
 	area->height = y2 - area->dy;
 
@@ -66,165 +358,56 @@
 	area->sx += (area->dx - old_dx);
 	area->sy += (area->dy - old_dy);
 
-	height = area->height;
-
 	/* the source must be completely inside the virtual screen */
 	if (area->sx < 0 || area->sy < 0 ||
-	    (area->sx + area->width) > p->var.xres_virtual ||
-	    (area->sy + area->height) > p->var.yres_virtual)
+	    (area->sx + area->width) > vxres ||
+	    (area->sy + area->height) > vyres)
 		return;
+	
+	if (area->dy > area->sy || (area->dy == area->sy && area->dx > area->sx)) {
+		area->dy += area->height;
+		area->sy += area->height;
+		rev_copy = 1;
+	}
 
-	if (area->dy < area->sy
-	    || (area->dy == area->sy && area->dx < area->sx)) {
-		/* start at the top */
-		src1 = p->screen_base + area->sy * linesize +
-		    ((area->sx * p->var.bits_per_pixel) >> 3);
-		dst1 = p->screen_base + area->dy * linesize +
-		    ((area->dx * p->var.bits_per_pixel) >> 3);
-		lineincr = linesize;
+	dst = src = (unsigned long *)((unsigned long)p->screen_base & ~(BYTES_PER_LONG-1));
+	dst_idx = src_idx = (unsigned long)p->screen_base & (BYTES_PER_LONG-1);
+	dst_idx += area->dy*next_line*8 + area->dx*p->var.bits_per_pixel;
+	src_idx += area->sy*next_line*8 + area->sx*p->var.bits_per_pixel;
+	
+	if (rev_copy) {
+		while (area->height--) {
+			dst_idx -= next_line*8;
+			src_idx -= next_line*8;
+			dst += dst_idx >> SHIFT_PER_LONG;
+			dst_idx &= (BYTES_PER_LONG-1);
+			src += src_idx >> SHIFT_PER_LONG;
+			src_idx &= (BYTES_PER_LONG-1);
+			bitcpy_rev((unsigned long*)dst, dst_idx, (unsigned long *)src,
+					src_idx, area->width*p->var.bits_per_pixel);
+		}	
 	} else {
-		/* start at the bottom */
-		src1 = p->screen_base + (area->sy + area->height-1) * linesize
-			+ (((area->sx + area->width - 1) * p->var.bits_per_pixel) >> 3);
-		dst1 = p->screen_base + (area->dy + area->height-1) * linesize
-			+ (((area->dx + area->width - 1) * p->var.bits_per_pixel) >> 3);
-		lineincr = -linesize;
+		while (area->height--) {
+			dst += dst_idx >> SHIFT_PER_LONG;
+			dst_idx &= (BYTES_PER_LONG-1);
+			src += src_idx >> SHIFT_PER_LONG;
+			src_idx &= (BYTES_PER_LONG-1);
+			bitcpy((unsigned long*)dst, dst_idx, (unsigned long *)src,
+				   src_idx, area->width*p->var.bits_per_pixel);
+			dst_idx += next_line*8;
+			src_idx += next_line*8;
+		}	
 	}
+}
 
-	if ((BITS_PER_LONG % p->var.bits_per_pixel) == 0) {
-		int ppw = BITS_PER_LONG / p->var.bits_per_pixel;
-		int n = ((area->width * p->var.bits_per_pixel) >> 3);
-
-		start_index = ((unsigned long) src1 & (bpl - 1));
-		end_index = ((unsigned long) (src1 + n) & (bpl - 1));
-		shift = ((unsigned long) dst1 & (bpl - 1)) -
-		    	((unsigned long) src1 & (bpl - 1));
-		start_mask = end_mask = 0;
-
-		if (start_index) {
-			start_mask = -1 >> (start_index << 3);
-			n -= (bpl - start_index);
-		}
+#ifdef MODULE
+int init_module(void) { return 0; };
+void cleanup_module(void) {};
+#endif
 
-		if (end_index) {
-			end_mask = -1 << ((bpl - end_index) << 3);
-			n -= end_index;
-		}
-		n /= bpl;
+EXPORT_SYMBOL(cfb_copyarea);
 
-		if (n <= 0) {
-			if (start_mask) {
-				if (end_mask)
-					end_mask &= start_mask;
-				else
-					end_mask = start_mask;
-				start_mask = 0;
-			}
-			n = 0;
-		}
+MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
+MODULE_DESCRIPTION("Generic software accelerated copyarea");
+MODULE_LICENSE("GPL");
 
-		if (shift) {
-			if (shift > 0) {
-				/* dest is over to right more */
-				shift_right =
-				    shift * p->var.bits_per_pixel;
-				shift_left =
-				    (ppw - shift) * p->var.bits_per_pixel;
-			} else {
-				/* source is to the right more */
-				shift_right =
-				    (ppw + shift) * p->var.bits_per_pixel;
-				shift_left =
-				    -shift * p->var.bits_per_pixel;
-			}
-			/* general case, positive increment */
-			if (lineincr > 0) {
-				if (shift < 0)
-					n++;
-				do {
-					dst = (unsigned long *) dst1;
-					src = (unsigned long *) src1;
-
-					last = (FB_READ(src) & start_mask);
-
-					if (shift > 0)
-						FB_WRITE(FB_READ(dst) | (last >> shift_right), dst);
-					for (j = 0; j < n; j++) {
-						dst++;
-						tmp = FB_READ(src);
-						src++;
-						FB_WRITE((last << shift_left) | (tmp >> shift_right), dst);
-						last = tmp;
-						src++;
-					}
-					FB_WRITE(FB_READ(dst) | (last << shift_left), dst);
-					src1 += lineincr;
-					dst1 += lineincr;
-				} while (--height);
-			} else {
-				/* general case, negative increment */
-				if (shift > 0)
-					n++;
-				do {
-					dst = (unsigned long *) dst1;
-					src = (unsigned long *) src1;
-
-					last = (FB_READ(src) & end_mask);
-
-					if (shift < 0)
-						FB_WRITE(FB_READ(dst) | (last >> shift_right), dst);
-					for (j = 0; j < n; j++) {
-						dst--;
-						tmp = FB_READ(src);
-						src--;
-						FB_WRITE((tmp << shift_left) | (last >> shift_right), dst);
-						last = tmp;
-						src--;
-					}
-					FB_WRITE(FB_READ(dst) | (last >> shift_right), dst);
-					src1 += lineincr;
-					dst1 += lineincr;
-				} while (--height);
-			}
-		} else {
-			/* no shift needed */
-			if (lineincr > 0) {
-				/* positive increment */
-				do {
-					dst = (unsigned long *) (dst1 - start_index);
-					src = (unsigned long *) (src1 - start_index);
-
-					if (start_mask)
-						FB_WRITE(FB_READ(src) | start_mask, dst);
-
-					for (j = 0; j < n; j++) {
-						FB_WRITE(FB_READ(src), dst);
-						dst++;
-						src++;
-					}
-
-					if (end_mask)
-						FB_WRITE(FB_READ(src) | end_mask, dst);
-					src1 += lineincr;
-					dst1 += lineincr;
-				} while (--height);
-			} else {
-				/* negative increment */
-				do {
-					dst = (unsigned long *) dst1;
-					src = (unsigned long *) src1;
-
-					if (start_mask)
-						FB_WRITE(FB_READ(src) | start_mask, dst);
-					for (j = 0; j < n; j++) {
-						FB_WRITE(FB_READ(src), dst);
-						dst--;
-						src--;
-					}
-					src1 += lineincr;
-					dst1 += lineincr;
-				} while (--height);
-			}
-		}
-	}
-}
diff -Nru a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c
--- a/drivers/video/cfbfillrect.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/video/cfbfillrect.c	Mon Dec  9 18:46:38 2002
@@ -17,173 +17,439 @@
  *  the native cpu endians. I also need to deal with MSB position in the word.
  *
  */
+#include <linux/config.h>
+#include <linux/module.h>
 #include <linux/string.h>
 #include <linux/fb.h>
 #include <asm/types.h>
-#include <video/fbcon.h>
 
 #if BITS_PER_LONG == 32
-#define FB_READ		fb_readl
-#define FB_WRITE	fb_writel
+#define FB_WRITEL fb_writel
+#define FB_READL  fb_readl
+#define BYTES_PER_LONG 4
+#define SHIFT_PER_LONG 5
 #else
-#define FB_READ		fb_readq
-#define FB_WRITE	fb_writeq
+#define FB_WRITEL fb_writeq
+#define FB_READL  fb_readq
+#define BYTES_PER_LONG 8
+#define SHIFT_PER_LONG 6
 #endif
 
-void cfb_fillrect(struct fb_info *p, struct fb_fillrect *rect)
+#define EXP1(x)		0xffffffffU*x
+#define EXP2(x)		0x55555555U*x
+#define EXP4(x)		0x11111111U*0x ## x
+
+typedef u32 pixel_t;
+
+static const u32 bpp1tab[2] = {
+    EXP1(0), EXP1(1)
+};
+
+static const u32 bpp2tab[4] = {
+    EXP2(0), EXP2(1), EXP2(2), EXP2(3)
+};
+
+static const u32 bpp4tab[16] = {
+    EXP4(0), EXP4(1), EXP4(2), EXP4(3), EXP4(4), EXP4(5), EXP4(6), EXP4(7),
+    EXP4(8), EXP4(9), EXP4(a), EXP4(b), EXP4(c), EXP4(d), EXP4(e), EXP4(f)
+};
+
+    /*
+     *  Compose two values, using a bitmask as decision value
+     *  This is equivalent to (a & mask) | (b & ~mask)
+     */
+
+static inline unsigned long comp(unsigned long a, unsigned long b,
+				 unsigned long mask)
 {
-	unsigned long start_index, end_index, start_mask = 0, end_mask = 0;
-	unsigned long height, ppw, fg, fgcolor;
-	int i, n, x2, y2, linesize = p->fix.line_length;
-	int bpl = sizeof(unsigned long);
-	unsigned long *dst;
-	char *dst1;
+    return ((a ^ b) & mask) ^ b;
+}
 
-	if (!rect->width || !rect->height)
-		return;
+static inline u32 pixel_to_pat32(const struct fb_info *p, pixel_t pixel)
+{
+    u32 pat = pixel;
 
-	/* We could use hardware clipping but on many cards you get around
-	 * hardware clipping by writing to framebuffer directly. */
-	x2 = rect->dx + rect->width;
-	y2 = rect->dy + rect->height;
-	x2 = x2 < p->var.xres_virtual ? x2 : p->var.xres_virtual;
-	y2 = y2 < p->var.yres_virtual ? y2 : p->var.yres_virtual;
-	rect->width = x2 - rect->dx;
-	height = y2 - rect->dy;
+    switch (p->var.bits_per_pixel) {
+	case 1:
+	    pat = bpp1tab[pat];
+	    break;
+
+	case 2:
+	    pat = bpp2tab[pat];
+	    break;
+
+	case 4:
+	    pat = bpp4tab[pat];
+	    break;
+
+	case 8:
+	    pat |= pat << 8;
+	    // Fall through
+	case 16:
+	    pat |= pat << 16;
+	    // Fall through
+	case 32:
+	    break;
+    }
+    return pat;
+}
 
-	/* Size of the scanline in bytes */
-	n = (rect->width * (p->var.bits_per_pixel >> 3));
-	ppw = BITS_PER_LONG / p->var.bits_per_pixel;
-
-	dst1 = p->screen_base + (rect->dy * linesize) +
-	    	(rect->dx * (p->var.bits_per_pixel >> 3));
-	start_index = ((unsigned long) dst1 & (bpl - 1));
-	end_index = ((unsigned long) (dst1 + n) & (bpl - 1));
+    /*
+     *  Expand a pixel value to a generic 32/64-bit pattern and rotate it to
+     *  the correct start position
+     */
 
-	if (p->fix.visual == FB_VISUAL_TRUECOLOR)
-		fg = fgcolor = ((u32 *) (p->pseudo_palette))[rect->color];
-	else
-		fg = fgcolor = rect->color;
+static inline unsigned long pixel_to_pat(const struct fb_info *p, pixel_t pixel, int left)
+{
+    unsigned long pat = pixel;
+    u32 bpp = p->var.bits_per_pixel;
+    int i;
+
+    /* expand pixel value */
+    for (i = bpp; i < BITS_PER_LONG; i *= 2)
+	pat |= pat << i;
+
+    /* rotate pattern to correct start position */
+    pat = pat << left | pat >> (bpp-left);
+    return pat;
+}
 
-	for (i = 0; i < ppw - 1; i++) {
-		fg <<= p->var.bits_per_pixel;
-		fg |= fgcolor;
+    /*
+     *  Unaligned 32-bit pattern fill using 32/64-bit memory accesses
+     */
+
+void bitfill32(unsigned long *dst, int dst_idx, u32 pat, u32 n)
+{
+	unsigned long val = pat;
+	unsigned long first, last;
+	
+	if (!n)
+		return;
+	
+#if BITS_PER_LONG == 64
+	val |= val << 32;
+#endif
+	
+	first = ~0UL >> dst_idx;
+	last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
+	
+	if (dst_idx+n <= BITS_PER_LONG) {
+		// Single word
+		if (last)
+			first &= last;
+		FB_WRITEL(comp(val, FB_READL(dst), first), dst);
+	} else {
+		// Multiple destination words
+		// Leading bits
+		if (first) {
+			FB_WRITEL(comp(val, FB_READL(dst), first), dst);
+			dst++;
+			n -= BITS_PER_LONG-dst_idx;
+		}
+		
+		// Main chunk
+		n /= BITS_PER_LONG;
+		while (n >= 8) {
+			FB_WRITEL(val, dst++);
+			FB_WRITEL(val, dst++);
+			FB_WRITEL(val, dst++);
+			FB_WRITEL(val, dst++);
+			FB_WRITEL(val, dst++);
+			FB_WRITEL(val, dst++);
+			FB_WRITEL(val, dst++);
+			FB_WRITEL(val, dst++);
+			n -= 8;
+		}
+		while (n--)
+			FB_WRITEL(val, dst++);
+		
+		// Trailing bits
+		if (last)
+			FB_WRITEL(comp(val, FB_READL(dst), first), dst);
 	}
+}
+
+
+    /*
+     *  Unaligned generic pattern fill using 32/64-bit memory accesses
+     *  The pattern must have been expanded to a full 32/64-bit value
+     *  Left/right are the appropriate shifts to convert to the pattern to be
+     *  used for the next 32/64-bit word
+     */
 
-	if (start_index) {
-		start_mask = fg << (start_index << 3);
-		n -= (bpl - start_index);
+void bitfill(unsigned long *dst, int dst_idx, unsigned long pat, int left,
+	     int right, u32 n)
+{
+	unsigned long first, last;
+
+	if (!n)
+		return;
+	
+	first = ~0UL >> dst_idx;
+	last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
+	
+	if (dst_idx+n <= BITS_PER_LONG) {
+		// Single word
+		if (last)
+			first &= last;
+		FB_WRITEL(comp(pat, FB_READL(dst), first), dst);
+	} else {
+		// Multiple destination words
+		// Leading bits
+		if (first) {
+			FB_WRITEL(comp(pat, FB_READL(dst), first), dst);
+			dst++;
+			pat = pat << left | pat >> right;
+			n -= BITS_PER_LONG-dst_idx;
+		}
+		
+		// Main chunk
+		n /= BITS_PER_LONG;
+		while (n >= 4) {
+			FB_WRITEL(pat, dst++);
+			pat = pat << left | pat >> right;
+			FB_WRITEL(pat, dst++);
+			pat = pat << left | pat >> right;
+			FB_WRITEL(pat, dst++);
+			pat = pat << left | pat >> right;
+			FB_WRITEL(pat, dst++);
+			pat = pat << left | pat >> right;
+			n -= 4;
+		}
+		while (n--) {
+			FB_WRITEL(pat, dst++);
+			pat = pat << left | pat >> right;
+		}
+		
+		// Trailing bits
+		if (last)
+			FB_WRITEL(comp(pat, FB_READL(dst), first), dst);
 	}
+}
 
-	if (end_index) {
-		end_mask = fg >> ((bpl - end_index) << 3);
-		n -= end_index;
+void bitfill32_rev(unsigned long *dst, int dst_idx, u32 pat, u32 n)
+{
+	unsigned long val = pat, dat;
+	unsigned long first, last;
+	
+	if (!n)
+		return;
+	
+#if BITS_PER_LONG == 64
+	val |= val << 32;
+#endif
+	
+	first = ~0UL >> dst_idx;
+	last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
+	
+	if (dst_idx+n <= BITS_PER_LONG) {
+		// Single word
+		if (last)
+			first &= last;
+		dat = FB_READL(dst);
+		FB_WRITEL(comp(dat ^ val, dat, first), dst);
+	} else {
+		// Multiple destination words
+		// Leading bits
+		if (first) {
+			dat = FB_READL(dst);
+			FB_WRITEL(comp(dat ^ val, dat, first), dst);
+			dst++;
+			n -= BITS_PER_LONG-dst_idx;
+		}
+		
+		// Main chunk
+		n /= BITS_PER_LONG;
+		while (n >= 8) {
+			FB_WRITEL(FB_READL(dst) ^ val, dst);
+			dst++;
+			FB_WRITEL(FB_READL(dst) ^ val, dst);
+			dst++;
+			FB_WRITEL(FB_READL(dst) ^ val, dst);
+			dst++;
+			FB_WRITEL(FB_READL(dst) ^ val, dst);
+			dst++;
+			FB_WRITEL(FB_READL(dst) ^ val, dst);
+			dst++;
+			FB_WRITEL(FB_READL(dst) ^ val, dst);
+			dst++;
+			FB_WRITEL(FB_READL(dst) ^ val, dst);
+			dst++;
+			FB_WRITEL(FB_READL(dst) ^ val, dst);
+			dst++;
+			n -= 8;
+		}
+		while (n--) {
+			FB_WRITEL(FB_READL(dst) ^ val, dst);
+			dst++;
+		}		
+		// Trailing bits
+		if (last) {
+			dat = FB_READL(dst);
+			FB_WRITEL(comp(dat ^ val, dat, first), dst);
+		}
 	}
+}
+
+
+    /*
+     *  Unaligned generic pattern fill using 32/64-bit memory accesses
+     *  The pattern must have been expanded to a full 32/64-bit value
+     *  Left/right are the appropriate shifts to convert to the pattern to be
+     *  used for the next 32/64-bit word
+     */
 
-	n = n / bpl;
+void bitfill_rev(unsigned long *dst, int dst_idx, unsigned long pat, int left,
+	     int right, u32 n)
+{
+	unsigned long first, last, dat;
 
-	if (n <= 0) {
-		if (start_mask) {
-			if (end_mask)
-				end_mask &= start_mask;
-			else
-				end_mask = start_mask;
-			start_mask = 0;
+	if (!n)
+		return;
+	
+	first = ~0UL >> dst_idx;
+	last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
+	
+	if (dst_idx+n <= BITS_PER_LONG) {
+		// Single word
+		if (last)
+			first &= last;
+		dat = FB_READL(dst);
+		FB_WRITEL(comp(dat ^ pat, dat, first), dst);
+	} else {
+		// Multiple destination words
+		// Leading bits
+		if (first) {
+			dat = FB_READL(dst);
+			FB_WRITEL(comp(dat ^ pat, dat, first), dst);
+			dst++;
+			pat = pat << left | pat >> right;
+			n -= BITS_PER_LONG-dst_idx;
+		}
+		
+		// Main chunk
+		n /= BITS_PER_LONG;
+		while (n >= 4) {
+			FB_WRITEL(FB_READL(dst) ^ pat, dst);
+			dst++;
+			pat = pat << left | pat >> right;
+			FB_WRITEL(FB_READL(dst) ^ pat, dst);
+			dst++;
+			pat = pat << left | pat >> right;
+			FB_WRITEL(FB_READL(dst) ^ pat, dst);
+			dst++;
+			pat = pat << left | pat >> right;
+			FB_WRITEL(FB_READL(dst) ^ pat, dst);
+			dst++;
+			pat = pat << left | pat >> right;
+			n -= 4;
+		}
+		while (n--) {
+			FB_WRITEL(FB_READL(dst) ^ pat, dst);
+			dst++;
+			pat = pat << left | pat >> right;
+		}
+		
+		// Trailing bits
+		if (last) {
+			dat = FB_READL(dst);
+			FB_WRITEL(comp(dat ^ pat, dat, first), dst);
 		}
-		n = 0;
 	}
+}
 
-	if ((BITS_PER_LONG % p->var.bits_per_pixel) == 0) {
-		switch (rect->rop) {
-		case ROP_COPY:
-			do {
-				/* Word align to increases performace :-) */
-				dst = (unsigned long *) (dst1 - start_index);
-
-				if (start_mask) {
-					FB_WRITE(FB_READ(dst) |
-						  start_mask, dst);
-					dst++;
-				}
-
-				for (i = 0; i < n; i++) {
-					FB_WRITE(fg, dst);
-					dst++;
-				}
-
-				if (end_mask)
-					FB_WRITE(FB_READ(dst) | end_mask,
-						  dst);
-				dst1 += linesize;
-			} while (--height);
-			break;
-		case ROP_XOR:
-			do {
-				dst = (unsigned long *) (dst1 - start_index);
+void cfb_fillrect(struct fb_info *p, struct fb_fillrect *rect)
+{
+	unsigned long height, fg;
+	unsigned long x2, y2, vxres, vyres;
+	unsigned long *dst;
+	int dst_idx, left;
+	u32 bpp = p->var.bits_per_pixel;
 
-				if (start_mask) {
-					FB_WRITE(FB_READ(dst) ^
-						  start_mask, dst);
-					dst++;
-				}
-
-				for (i = 0; i < n; i++) {
-					FB_WRITE(FB_READ(dst) ^ fg, dst);
-					dst++;
-				}
-
-				if (end_mask) {
-					FB_WRITE(FB_READ(dst) ^ end_mask,
-						  dst);
-				}
-				dst1 += linesize;
-			} while (--height);
-			break;
-		}
-	} else {
-		/* Odd modes like 24 or 80 bits per pixel */
-		start_mask = fg >> (start_index * p->var.bits_per_pixel);
-		end_mask = fg << (end_index * p->var.bits_per_pixel);
-		/* start_mask =& PFILL24(x1,fg);
-		   end_mask_or = end_mask & PFILL24(x1+width-1,fg); */
+	/* We want rotation but lack hardware to do it for us. */
+	if (!p->fbops->fb_rotate && p->var.rotate) {
+	}	
+	
+	vxres = p->var.xres_virtual;
+	vyres = p->var.yres_virtual;
 
-		n = (rect->width - start_index - end_index) / ppw;
+	if (!rect->width || !rect->height || rect->dx > vxres || rect->dy > vyres)
+		return;
 
+	/* We could use hardware clipping but on many cards you get around
+	 * hardware clipping by writing to framebuffer directly. */
+	
+	x2 = rect->dx + rect->width;
+	y2 = rect->dy + rect->height;
+	x2 = x2 < vxres ? x2 : vxres;
+	y2 = y2 < vyres ? y2 : vyres;
+	rect->width = x2 - rect->dx;
+	height = y2 - rect->dy;
+	
+	if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
+	    p->fix.visual == FB_VISUAL_DIRECTCOLOR )
+		fg = ((u32 *) (p->pseudo_palette))[rect->color];
+	else
+		fg = rect->color;
+	
+	dst = (unsigned long *)((unsigned long)p->screen_base & ~(BYTES_PER_LONG-1));
+	dst_idx = ((unsigned long)p->screen_base & (BYTES_PER_LONG-1))*8;
+	dst_idx += rect->dy*p->fix.line_length*8+rect->dx*bpp;
+	/* FIXME For now we support 1-32 bpp only */
+	left = BITS_PER_LONG % bpp;
+	if (!left) {
+		u32 pat = pixel_to_pat32(p, fg);
+		void (*fill_op32)(unsigned long *dst, int dst_idx, u32 pat, u32 n) = NULL;
+		
 		switch (rect->rop) {
+		case ROP_XOR:
+			fill_op32 = bitfill32_rev;
+			break;
 		case ROP_COPY:
-			do {
-				dst = (unsigned long *) dst1;
-				if (start_mask)
-					*dst |= start_mask;
-				if ((start_index + rect->width) > ppw)
-					dst++;
-
-				/* XXX: slow */
-				for (i = 0; i < n; i++) {
-					*dst++ = fg;
-				}
-				if (end_mask)
-					*dst |= end_mask;
-				dst1 += linesize;
-			} while (--height);
+		default:
+			fill_op32 = bitfill32;
 			break;
+		}
+		while (height--) {
+			dst += dst_idx >> SHIFT_PER_LONG;
+			dst_idx &= (BITS_PER_LONG-1);
+			fill_op32(dst, dst_idx, pat, rect->width*bpp);
+			dst_idx += p->fix.line_length*8;
+		}
+	} else {
+		unsigned long pat = pixel_to_pat(p, fg, (left-dst_idx) % bpp);
+		int right = bpp-left;
+		int r;
+		void (*fill_op)(unsigned long *dst, int dst_idx, unsigned long pat, 
+				int left, int right, u32 n) = NULL;
+		
+		switch (rect->rop) {
 		case ROP_XOR:
-			do {
-				dst = (unsigned long *) dst1;
-				if (start_mask)
-					*dst ^= start_mask;
-				if ((start_mask + rect->width) > ppw)
-					dst++;
-
-				for (i = 0; i < n; i++) {
-					*dst++ ^= fg;	/* PFILL24(fg,x1+i); */
-				}
-				if (end_mask)
-					*dst ^= end_mask;
-				dst1 += linesize;
-			} while (--height);
+			fill_op = bitfill_rev;
+			break;
+		case ROP_COPY:
+		default:
+			fill_op = bitfill;
 			break;
 		}
+		while (height--) {
+			dst += dst_idx >> SHIFT_PER_LONG;
+			dst_idx &= (BITS_PER_LONG-1);
+			fill_op(dst, dst_idx, pat, left, right, rect->width*bpp);
+			r = (p->fix.line_length*8) % bpp;
+			pat = pat << (bpp-r) | pat >> r;
+			dst_idx += p->fix.line_length*8;
+		}
 	}
-	return;
 }
+
+#ifdef MODULE
+int init_module(void) { return 0; };
+void cleanup_module(void) {};
+#endif
+
+EXPORT_SYMBOL(cfb_fillrect);
+
+MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
+MODULE_DESCRIPTION("Generic software accelerated fill rectangle");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
--- a/drivers/video/cfbimgblt.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/video/cfbimgblt.c	Mon Dec  9 18:46:38 2002
@@ -22,17 +22,24 @@
  *  FIXME
  *  The code for 24 bit is horrible. It copies byte by byte size instead of
  *  longs like the other sizes. Needs to be optimized.
+ *  
+ *  Tony: 
+ *  Incorporate mask tables similar to fbcon-cfb*.c in 2.4 API.  This speeds 
+ *  up the code significantly.
+ *  
+ *  Code for depths not multiples of BITS_PER_LONG is still kludgy, which is
+ *  still processed a bit at a time.   
  *
  *  Also need to add code to deal with cards endians that are different than
  *  the native cpu endians. I also need to deal with MSB position in the word.
  *
  */
+#include <linux/config.h>
+#include <linux/module.h>
 #include <linux/string.h>
 #include <linux/fb.h>
 #include <asm/types.h>
 
-#include <video/fbcon.h>
-
 #define DEBUG
 
 #ifdef DEBUG
@@ -41,91 +48,308 @@
 #define DPRINTK(fmt, args...)
 #endif
 
+static u32 cfb_tab8[] = {
+#if defined(__BIG_ENDIAN)
+    0x00000000,0x000000ff,0x0000ff00,0x0000ffff,
+    0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff,
+    0xff000000,0xff0000ff,0xff00ff00,0xff00ffff,
+    0xffff0000,0xffff00ff,0xffffff00,0xffffffff
+#elif defined(__LITTLE_ENDIAN)
+    0x00000000,0xff000000,0x00ff0000,0xffff0000,
+    0x0000ff00,0xff00ff00,0x00ffff00,0xffffff00,
+    0x000000ff,0xff0000ff,0x00ff00ff,0xffff00ff,
+    0x0000ffff,0xff00ffff,0x00ffffff,0xffffffff
+#else
+#error FIXME: No endianness??
+#endif
+};
+
+static u32 cfb_tab16[] = {
+#if defined(__BIG_ENDIAN)
+    0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
+#elif defined(__LITTLE_ENDIAN)
+    0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff
+#else
+#error FIXME: No endianness??
+#endif
+};
+
+static u32 cfb_tab32[] = {
+	0x00000000, 0xffffffff
+};
+
+#if BITS_PER_LONG == 32
+#define FB_WRITEL fb_writel
+#define FB_READL  fb_readl
+#else
+#define FB_WRITEL fb_writeq
+#define FB_READL  fb_readq
+#endif 
+
+#if defined (__BIG_ENDIAN)
+#define LEFT_POS(bpp)          (BITS_PER_LONG - bpp)
+#define NEXT_POS(pos, bpp)     ((pos) -= (bpp))
+#define SHIFT_HIGH(val, bits)  ((val) >> (bits))
+#define SHIFT_LOW(val, bits)   ((val) << (bits))
+#else
+#define LEFT_POS(bpp)          (0)
+#define NEXT_POS(pos, bpp)     ((pos) += (bpp))
+#define SHIFT_HIGH(val, bits)  ((val) << (bits))
+#define SHIFT_LOW(val, bits)   ((val) >> (bits))
+#endif
+
+static inline void color_imageblit(struct fb_image *image, struct fb_info *p, u8 *dst1, 
+				   unsigned long start_index, unsigned long pitch_index)
+{
+	/* Draw the penguin */
+	int i, n;
+	unsigned long bitmask = SHIFT_LOW(~0UL, BITS_PER_LONG - p->var.bits_per_pixel);
+	unsigned long *palette = (unsigned long *) p->pseudo_palette;
+	unsigned long *dst, *dst2, color = 0, val, shift;
+	unsigned long null_bits = BITS_PER_LONG - p->var.bits_per_pixel; 
+	u8 *src = image->data;
+
+	dst2 = (unsigned long *) dst1;
+	for (i = image->height; i--; ) {
+		n = image->width;
+		dst = (unsigned long *) dst1;
+		shift = 0;
+		val = 0;
+		
+		if (start_index) {
+			unsigned long start_mask = ~(SHIFT_HIGH(~0UL, start_index));
+
+			val = FB_READL(dst) & start_mask;
+			shift = start_index;
+		}
+		while (n--) {
+			if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
+			    p->fix.visual == FB_VISUAL_DIRECTCOLOR )
+				color = palette[*src] & bitmask;
+			else
+				color = *src & bitmask;	
+			val |= SHIFT_HIGH(color, shift);
+			if (shift >= null_bits) {
+				FB_WRITEL(val, dst++);
+				if (shift == null_bits)
+					val = 0;
+				else
+					val = SHIFT_LOW(color, BITS_PER_LONG - shift);
+			}
+			shift += p->var.bits_per_pixel;
+			shift &= (BITS_PER_LONG - 1);
+			src++;
+		}
+		if (shift) {
+			unsigned long  end_mask = SHIFT_HIGH(~0UL, shift);
+
+			FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
+		}
+		dst1 += p->fix.line_length;
+		if (pitch_index) {
+			dst2 += p->fix.line_length;
+			dst1 = (char *) dst2;
+			(unsigned long) dst1 &= ~(sizeof(unsigned long) - 1);
+
+			start_index += pitch_index;
+			start_index &= BITS_PER_LONG - 1;
+		}
+	}
+}
+
+static inline void slow_imageblit(struct fb_image *image, struct fb_info *p, u8 *dst1,
+				  unsigned long fgcolor, unsigned long bgcolor, 
+				  unsigned long start_index, unsigned long pitch_index)
+{
+	unsigned long i, j, l = 8;
+	unsigned long shift, color, bpp = p->var.bits_per_pixel;
+	unsigned long *dst, *dst2, val, pitch = p->fix.line_length;
+	unsigned long null_bits = BITS_PER_LONG - bpp;
+	u8 *src = image->data;
+	
+	dst2 = (unsigned long *) dst1;
+
+	for (i = image->height; i--; ) {
+		shift = 0;
+		val = 0;
+		j = image->width;
+		dst = (unsigned long *) dst1;
+
+		/* write leading bits */
+		if (start_index) {
+			unsigned long start_mask = ~(SHIFT_HIGH(~0UL, start_index));
+
+			val = FB_READL(dst) & start_mask;
+			shift = start_index;
+		}
+		while (j--) {
+			l--;
+			if (*src & (1 << l)) 
+				color = fgcolor;
+			else 
+				color = bgcolor;
+			val |= SHIFT_HIGH(color, shift);
+			
+			/* Did the bitshift spill bits to the next long? */
+			if (shift >= null_bits) {
+				FB_WRITEL(val, dst++);
+				if (shift == null_bits)
+					val = 0;
+				else
+					val = SHIFT_LOW(color, BITS_PER_LONG - shift);
+			}
+			shift += bpp;
+			shift &= (BITS_PER_LONG - 1);
+			if (!l) { l = 8; src++; };
+		}
+		/* write trailing bits */
+ 		if (shift) {
+			unsigned long end_mask = SHIFT_HIGH(~0UL, shift);
+
+			FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
+		}
+		dst1 += pitch;	
+
+		if (pitch_index) {
+			dst2 += pitch;
+			dst1 = (char *) dst2;
+			(unsigned long) dst1 &= ~(sizeof(unsigned long) - 1);
+
+			start_index += pitch_index;
+			start_index &= BITS_PER_LONG - 1;
+		}
+		
+	}
+}
+
+static inline void fast_imageblit(struct fb_image *image, struct fb_info *p, u8 *dst1, 
+				  unsigned long fgcolor, unsigned long bgcolor) 
+{
+	int i, j, k, l = 8, n;
+	unsigned long bit_mask, end_mask, eorx; 
+	unsigned long fgx = fgcolor, bgx = bgcolor, pad, bpp = p->var.bits_per_pixel;
+	unsigned long tmp = (1 << bpp) - 1;
+	unsigned long ppw = BITS_PER_LONG/bpp, ppos;
+	unsigned long *dst;
+	u32 *tab = NULL;
+	char *src = image->data;
+		
+	switch (ppw) {
+	case 4:
+		tab = cfb_tab8;
+		break;
+	case 2:
+		tab = cfb_tab16;
+		break;
+	case 1:
+		tab = cfb_tab32;
+		break;
+	}
+
+	for (i = ppw-1; i--; ) {
+		fgx <<= bpp;
+		bgx <<= bpp;
+		fgx |= fgcolor;
+		bgx |= bgcolor;
+	}
+	
+	n = ((image->width + 7) / 8);
+	pad = (n * 8) - image->width;
+	n = image->width % ppw;
+	
+	bit_mask = (1 << ppw) - 1;
+	eorx = fgx ^ bgx;
+
+	k = image->width/ppw;
+
+	for (i = image->height; i--; ) {
+		dst = (unsigned long *) dst1;
+		
+		for (j = k; j--; ) {
+			l -= ppw;
+			end_mask = tab[(*src >> l) & bit_mask]; 
+			FB_WRITEL((end_mask & eorx)^bgx, dst++);
+			if (!l) { l = 8; src++; }
+		}
+		if (n) {
+			end_mask = 0;	
+			ppos = LEFT_POS(bpp);
+			for (j = n; j > 0; j--) {
+				l--;
+				if (*src & (1 << l))
+					end_mask |= tmp << ppos;
+				NEXT_POS(ppos, bpp);
+				if (!l) { l = 8; src++; }
+			}
+			FB_WRITEL((end_mask & eorx)^bgx, dst++);
+		}
+		l -= pad;		
+		dst1 += p->fix.line_length;	
+	}
+}	
+	
 void cfb_imageblit(struct fb_info *p, struct fb_image *image)
 {
-	int pad, ppw;
-	int x2, y2, n, i, j, k, l = 7;
-	unsigned long tmp = ~0 << (BITS_PER_LONG - p->var.bits_per_pixel);
-	unsigned long fgx, bgx, fgcolor, bgcolor, eorx;	
-	unsigned long end_mask;
-	unsigned long *dst = NULL;
+	int x2, y2, vxres, vyres;
+	unsigned long fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
+	unsigned long bpl = sizeof(unsigned long), bpp = p->var.bits_per_pixel;
 	u8 *dst1;
-	u8 *src;
 
+	vxres = p->var.xres_virtual;
+	vyres = p->var.yres_virtual;
 	/* 
 	 * We could use hardware clipping but on many cards you get around hardware
 	 * clipping by writing to framebuffer directly like we are doing here. 
 	 */
+	if (image->dx > vxres ||
+	    image->dy > vyres)
+		return;
+
 	x2 = image->dx + image->width;
 	y2 = image->dy + image->height;
 	image->dx = image->dx > 0 ? image->dx : 0;
 	image->dy = image->dy > 0 ? image->dy : 0;
-	x2 = x2 < p->var.xres_virtual ? x2 : p->var.xres_virtual;
-	y2 = y2 < p->var.yres_virtual ? y2 : p->var.yres_virtual;
+	x2 = x2 < vxres ? x2 : vxres;
+	y2 = y2 < vyres ? y2 : vyres;
 	image->width  = x2 - image->dx;
 	image->height = y2 - image->dy;
-  
-	dst1 = p->screen_base + image->dy * p->fix.line_length + 
-		((image->dx * p->var.bits_per_pixel) >> 3);
-  
-	ppw = BITS_PER_LONG/p->var.bits_per_pixel;
 
-	src = image->data;	
+	bitstart = (image->dy * p->fix.line_length * 8) + (image->dx * bpp);
+	start_index = bitstart & (BITS_PER_LONG - 1);
+	pitch_index = (p->fix.line_length & (bpl - 1)) * 8;
 
-	if (image->depth == 1) {
+	bitstart /= 8;
+	bitstart &= ~(bpl - 1);
+	dst1 = p->screen_base + bitstart;
 
-		if (p->fix.visual == FB_VISUAL_TRUECOLOR) {
-			fgx = fgcolor = ((u32 *)(p->pseudo_palette))[image->fg_color];
-			bgx = bgcolor = ((u32 *)(p->pseudo_palette))[image->bg_color];
+	if (image->depth == 1) {
+		if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
+		    p->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+			fgcolor = ((u32 *)(p->pseudo_palette))[image->fg_color];
+			bgcolor = ((u32 *)(p->pseudo_palette))[image->bg_color];
 		} else {
-			fgx = fgcolor = image->fg_color;
-			bgx = bgcolor = image->bg_color;
+			fgcolor = image->fg_color;
+			bgcolor = image->bg_color;
 		}	
- 
-		for (i = 0; i < ppw-1; i++) {
-			fgx <<= p->var.bits_per_pixel;
-			bgx <<= p->var.bits_per_pixel;
-			fgx |= fgcolor;
-			bgx |= bgcolor;
-		}
-		eorx = fgx ^ bgx;
-		n = ((image->width + 7) >> 3);
-		pad = (n << 3) - image->width;
-		n = image->width % ppw;
-
-		for (i = 0; i < image->height; i++) {
-			dst = (unsigned long *) dst1;
 		
-			for (j = image->width/ppw; j > 0; j--) {
-				end_mask = 0;
-		
-				for (k = ppw; k > 0; k--) {
-					if (test_bit(l, (unsigned long *) src))
-						end_mask |= (tmp >> (p->var.bits_per_pixel*(k-1)));
-					l--;
-					if (l < 0) { l = 7; src++; }
-				}
-				fb_writel((end_mask & eorx)^bgx, dst);
-				dst++;
-			}
-		
-			if (n) {
-				end_mask = 0;	
-				for (j = n; j > 0; j--) {
-					if (test_bit(l, (unsigned long *) src))
-						end_mask |= (tmp >> (p->var.bits_per_pixel*(j-1)));
-					l--;
-					if (l < 0) { l = 7; src++; }
-				}
-				fb_writel((end_mask & eorx)^bgx, dst);
-				dst++;
-			}
-			l -= pad;		
-			dst1 += p->fix.line_length;	
-		}	
-	} else {
-		/* Draw the penguin */
-		n = ((image->width * p->var.bits_per_pixel) >> 3);
-		end_mask = 0;
+		if (BITS_PER_LONG % bpp == 0 && !start_index && !pitch_index && 
+		    bpp >= 8 && bpp <= 32 && (image->width & 7) == 0) 
+			fast_imageblit(image, p, dst1, fgcolor, bgcolor);
+		else 
+			slow_imageblit(image, p, dst1, fgcolor, bgcolor, start_index, pitch_index);
 	}
+	else if (image->depth == bpp) 
+		color_imageblit(image, p, dst1, start_index, pitch_index);
 }
+
+#ifdef MODULE
+int init_module(void) { return 0; };
+void cleanup_module(void) {};
+#endif
+
+EXPORT_SYMBOL(cfb_imageblit);
+
+MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
+MODULE_DESCRIPTION("Generic software accelerated imaging drawing");
+MODULE_LICENSE("GPL");
+
diff -Nru a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c
--- a/drivers/video/chipsfb.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/video/chipsfb.c	Mon Dec  9 18:46:36 2002
@@ -562,7 +562,7 @@
 	}
 
 	printk("fb%d: Chips 65550 frame buffer (%dK RAM detected)\n",
-		GET_FB_IDX(p->info.node), p->fix.smem_len / 1024);
+		minor(p->info.node), p->fix.smem_len / 1024);
 
 	chips_hw_init(p);
 
diff -Nru a/drivers/video/clps711xfb.c b/drivers/video/clps711xfb.c
--- a/drivers/video/clps711xfb.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/video/clps711xfb.c	Mon Dec  9 18:46:35 2002
@@ -27,8 +27,6 @@
 #include <linux/proc_fs.h>
 #include <linux/delay.h>
 
-#include <video/fbcon.h>
-
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/uaccess.h>
@@ -216,14 +214,12 @@
 	.owner		= THIS_MODULE,
 	.fb_check_var	= clps7111fb_check_var,
 	.fb_set_par	= clps7111fb_set_par,
-	.fb_set_var	= gen_set_var,
-	.fb_set_cmap	= gen_set_cmap,
-	.fb_get_cmap	= gen_get_cmap,
 	.fb_setcolreg	= clps7111fb_setcolreg,
 	.fb_blank	= clps7111fb_blank,
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
+	.fb_cursor	= soft_cursor,
 };
 
 static int 
@@ -368,20 +364,15 @@
 {
 	int err = -ENOMEM;
 
-	cfb = kmalloc(sizeof(*cfb) + sizeof(struct display), GFP_KERNEL);
+	cfb = kmalloc(sizeof(*cfb), GFP_KERNEL);
 	if (!cfb)
 		goto out;
 
-	memset(cfb, 0, sizeof(*cfb) + sizeof(struct display));
+	memset(cfb, 0, sizeof(*cfb));
 	strcpy(cfb->fix.id, "clps711x");
 
-	cfb->currcon		= -1;
 	cfb->fbops		= &clps7111fb_ops;
-	cfb->changevar		= NULL;
-	cfb->switch_con		= gen_switch;
-	cfb->updatevar		= gen_update_var;
 	cfb->flags		= FBINFO_FLAG_DEFAULT;
-	cfb->disp		= (struct display *)(cfb + 1);
 
 	clps711x_guess_lcd_params(cfb);
 
@@ -422,7 +413,6 @@
 		clps_writeb(clps_readb(PDDR) | EDB_PD3_LCDBL, PDDR);
 	}
 
-	gen_set_var(&cfb->var, -1, cfb);
 	err = register_framebuffer(cfb);
 
 out:	return err;
diff -Nru a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/Kconfig	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,221 @@
+#
+# Video configuration
+#
+
+menu "Console display driver support"
+
+config VGA_CONSOLE
+	bool "VGA text console"
+	depends on !ARCH_ACORN && !ARCH_EBSA110 || !4xx && !8xx
+	help
+	  Saying Y here will allow you to use Linux in text mode through a
+	  display that complies with the generic VGA standard. Virtually
+	  everyone wants that.
+
+	  The program SVGATextMode can be used to utilize SVGA video cards to
+	  their full potential in text mode. Download it from
+	  <ftp://ibiblio.org/pub/Linux/utils/console/>.
+
+	  Say Y.
+
+#	if [ "$CONFIG_PCI" = "y" -a "$CONFIG_VGA_CONSOLE" = "y" ]; then
+#	   bool '   Allow VGA on any bus?' CONFIG_VGA_HOSE
+#	   if [ "$CONFIG_VGA_HOSE" = "y" ]; then
+#	      define_bool CONFIG_DUMMY_CONSOLE y
+#	   fi
+#	fi
+
+config VIDEO_SELECT
+	bool "Video mode selection support"
+	depends on  (X86 || X86_64) && VGA_CONSOLE
+	---help---
+	  This enables support for text mode selection on kernel startup. If
+	  you want to take advantage of some high-resolution text mode your
+	  card's BIOS offers, but the traditional Linux utilities like
+	  SVGATextMode don't, you can say Y here and set the mode using the
+	  "vga=" option from your boot loader (lilo or loadlin) or set
+	  "vga=ask" which brings up a video mode menu on kernel startup. (Try
+	  "man bootparam" or see the documentation of your boot loader about
+	  how to pass options to the kernel.)
+
+	  Read the file <file:Documentation/svga.txt> for more information
+	  about the Video mode selection support. If unsure, say N.
+
+config MDA_CONSOLE
+	tristate "MDA text console (dual-headed) (EXPERIMENTAL)"
+	---help---
+	  Say Y here if you have an old MDA or monochrome Hercules graphics
+	  adapter in your system acting as a second head ( = video card). You
+	  will then be able to use two monitors with your Linux system. Do not
+	  say Y here if your MDA card is the primary card in your system; the
+	  normal VGA driver will handle it.
+
+	  This driver is also available as a module ( = code which can be
+	  inserted and removed from the running kernel whenever you want).
+	  The module will be called mdacon.o. If you want to compile it as
+	  a module, say M here and read <file:Documentation/modules.txt>.
+
+	  If unsure, say N.
+
+config SGI_NEWPORT_CONSOLE
+        tristate "SGI Newport Console support"
+        depends on SGI_IP22  
+        help
+          Say Y here if you want the console on the Newport aka XL graphics
+          card of your Indy.  Most people say Y here.
+
+#  bool 'IODC console' CONFIG_IODC_CONSOLE
+config STI_CONSOLE
+        bool "STI console"
+        depends on PARISC
+	help
+          The STI console is the builtin display/keyboard on HP-PARISC
+          machines.  Say Y here to build support for it into your kernel.
+          The alternative is to use your primary serial port as a console.
+
+config PROM_CONSOLE
+	bool "PROM console"
+	depends on SPARC32 || SPARC64
+	help
+	  Say Y to build a console driver for Sun machines that uses the
+	  terminal emulation built into their console PROMS.
+
+config DUMMY_CONSOLE
+	bool
+	depends on !PROM_CONSOLE=y || VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y || !IODC_CONSOLE && GSC_PS2
+	default y
+
+config FRAMEBUFFER_CONSOLE
+	tristate "Framebuffer Console support"
+	depends on FB
+
+config PCI_CONSOLE
+	bool
+	depends on FRAMEBUFFER_CONSOLE
+	default y
+
+config FBCON_ADVANCED
+	bool "Advanced low level driver options"
+	depends on FRAMEBUFFER_CONSOLE
+	---help---
+	  The frame buffer console uses character drawing routines that are
+	  tailored to the specific organization of pixels in the memory of
+	  your graphics hardware. These are called the low level frame buffer
+	  console drivers. Note that they are used for text console output
+	  only; they are NOT needed for graphical applications.
+
+	  If you say N here, the needed low level drivers are automatically
+	  enabled, depending on what frame buffer devices you selected above.
+	  This is recommended for most users.
+
+	  If you say Y here, you have more fine-grained control over which low
+	  level drivers are enabled. You can e.g. leave out low level drivers
+	  for color depths you do not intend to use for text consoles.
+
+	  Low level frame buffer console drivers can be modules ( = code which
+	  can be inserted and removed from the running kernel whenever you
+	  want). The modules will be called fbcon-*.o. If you want to compile
+	  (some of) them as modules, read <file:Documentation/modules.txt>.
+
+	  If unsure, say N.
+
+# Guess what we need
+config FBCON_STI
+	tristate
+	depends on !FBCON_ADVANCED && FRAMEBUFFER_CONSOLE && FB_STI
+	default y
+
+config FONTWIDTH8_ONLY
+	bool "Support only 8 pixels wide fonts"
+	depends on FRAMEBUFFER_CONSOLE
+	help
+	  Answer Y here will make the kernel provide only the 8x8 fonts (these
+	  are the less readable).
+
+	  If unsure, say N.
+
+config FONT_SUN8x16
+	bool "Sparc console 8x16 font"
+	depends on FRAMEBUFFER_CONSOLE && (!SPARC32 && !SPARC64 && FONTS || SPARC32 || SPARC64)
+	help
+	  This is the high resolution console font for Sun machines. Say Y.
+
+config FONT_SUN12x22
+	bool "Sparc console 12x22 font (not supported by all drivers)"
+	depends on FRAMEBUFFER_CONSOLE && !FONTWIDTH8_ONLY && (!SPARC32 && !SPARC64 && FONTS || SPARC32 || SPARC64)
+	help
+	  This is the high resolution console font for Sun machines with very
+	  big letters (like the letters used in the SPARC PROM). If the
+	  standard font is unreadable for you, say Y, otherwise say N.
+
+config FONTS
+	bool "Select other fonts" if SPARC32 || SPARC64
+	depends on FRAMEBUFFER_CONSOLE
+	help
+	  Say Y here if you would like to use fonts other than the default
+	  your frame buffer console usually use.
+
+	  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 foreign fonts.
+
+	  If unsure, say N (the default choices are safe).
+
+config FONTS
+	prompt "Select compiled-in fonts"
+	depends on FRAMEBUFFER_CONSOLE && !SPARC32 && !SPARC64
+
+config FONT_8x8
+	bool "VGA 8x8 font" if FONTS
+	depends on FRAMEBUFFER_CONSOLE
+	default y if !SPARC32 && !SPARC64 && !FONTS
+	help
+	  This is the "high resolution" font for the VGA frame buffer (the one
+	  provided by the text console 80x50 (and higher) modes).
+
+	  Note that this is a poor quality font. The VGA 8x16 font is quite a
+	  lot more readable.
+
+	  Given the resolution provided by the frame buffer device, answer N
+	  here is safe.
+
+config FONT_8x16
+	bool "VGA 8x16 font" if FONTS
+	depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE=y
+	default y if !SPARC32 && !SPARC64 && !FONTS
+	help
+	  This is the "high resolution" font for the VGA frame buffer (the one
+	  provided by the VGA text console 80x25 mode.
+
+	  If unsure, say Y.
+
+config FONT_6x11
+	bool "Mac console 6x11 font (not supported by all drivers)" if FONTS
+	depends on FRAMEBUFFER_CONSOLE && !FONTWIDTH8_ONLY
+	default y if !SPARC32 && !SPARC64 && !FONTS && MAC
+	help
+	  Small console font with Macintosh-style high-half glyphs.  Some Mac
+	  framebuffer drivers don't support this one at all.
+
+config FONT_PEARL_8x8
+	bool "Pearl (old m68k) console 8x8 font" if FONTS
+	depends on FRAMEBUFFER_CONSOLE
+	default y if !SPARC32 && !SPARC64 && !FONTS && AMIGA
+	help
+	  Small console font with PC-style control-character and high-half
+	  glyphs.
+
+config FONT_ACORN_8x8
+	bool "Acorn console 8x8 font" if FONTS
+	depends on FRAMEBUFFER_CONSOLE
+	default y if !SPARC32 && !SPARC64 && !FONTS && ARM && ARCH_ACORN
+	help
+	  Small console font with PC-style control characters and high-half
+	  glyphs.
+
+config FONT_MINI_4x6
+	bool "Mini 4x6 font"
+	depends on !SPARC32 && !SPARC64 && FONTS
+
+endmenu
+
diff -Nru a/drivers/video/console/Makefile b/drivers/video/console/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/Makefile	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,61 @@
+# Makefile for the Linux graphics to console drivers.
+# 5 Aug 1999, James Simmons, <mailto:jsimmons@users.sf.net>
+# Rewritten to use lists instead of if-statements.
+
+# All of the (potential) objects that export symbols.
+# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
+
+export-objs    	:= fbcon.o fonts.o
+
+# Font handling
+font-objs := fonts.o
+
+ifeq ($(CONFIG_FONT_SUN8x16),y)
+	font-objs += font_sun8x16.o
+endif
+ifeq ($(CONFIG_FONT_SUN12x22),y)
+	font-objs += font_sun12x22.o
+endif	
+ifeq ($(CONFIG_FONT_8x8),y)
+	font-objs += font_8x8.o
+endif	
+ifeq ($(CONFIG_FONT_8x16),y)
+	font-objs += font_8x16.o
+endif	
+ifeq ($(CONFIG_FONT_6x11),y)
+	font-objs += font_6x11.o
+endif	
+ifeq ($(CONFIG_FONT_PEARL_8x8),y)
+	font-objs += font_pearl_8x8.o
+endif	
+ifeq ($(CONFIG_FONT_ACORN_8x8),y)
+	font-objs += font_acorn_8x8.o
+endif	
+ifeq ($(CONFIG_FONT_MINI_4x6),y)
+	font-objs += font_mini_4x6.o
+endif	
+
+# Each configuration option enables a list of files.
+
+obj-$(CONFIG_DUMMY_CONSOLE)       += dummycon.o
+obj-$(CONFIG_SGI_NEWPORT_CONSOLE) += newport_con.o
+obj-$(CONFIG_PROM_CONSOLE)        += promcon.o promcon_tbl.o
+obj-$(CONFIG_STI_CONSOLE)         += sticon.o sticore.o
+obj-$(CONFIG_VGA_CONSOLE)         += vgacon.o
+obj-$(CONFIG_MDA_CONSOLE)         += mdacon.o
+obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o font.o
+
+# Generic Low Level Drivers
+
+obj-$(CONFIG_FBCON_STI)           += fbcon-sti.o
+
+# Files generated that shall be removed upon make clean
+clean-files := promcon_tbl.c
+
+include $(TOPDIR)/Rules.make
+
+$(obj)/promcon_tbl.c: $(src)/prom.uni
+	$(objtree)/scripts/conmakehash $< | \
+	sed -e '/#include <[^>]*>/p' -e 's/types/init/' \
+	    -e 's/dfont\(_uni.*\]\)/promfont\1 __initdata/' > $@
+
diff -Nru a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/dummycon.c	Mon Dec  9 18:46:50 2002
@@ -0,0 +1,73 @@
+/*
+ *  linux/drivers/video/dummycon.c -- A dummy console driver
+ *
+ *  To be used if there's no other console driver (e.g. for plain VGA text)
+ *  available, usually until fbcon takes console over.
+ */
+
+#include <linux/types.h>
+#include <linux/kdev_t.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/vt_kern.h>
+#include <linux/init.h>
+
+/*
+ *  Dummy console driver
+ */
+
+#if defined(__arm__)
+#define DUMMY_COLUMNS	ORIG_VIDEO_COLS
+#define DUMMY_ROWS	ORIG_VIDEO_LINES
+#elif defined(__hppa__)
+#define DUMMY_COLUMNS	80	/* fixme ! (mine uses 160x64 at 1280x1024) */
+#define DUMMY_ROWS	25
+#else
+#define DUMMY_COLUMNS	80
+#define DUMMY_ROWS	25
+#endif
+
+static const char *dummycon_startup(void)
+{
+    return "dummy device";
+}
+
+static void dummycon_init(struct vc_data *vc, int init)
+{
+    vc->vc_can_do_color = 1;
+    if (init) {
+	vc->vc_cols = DUMMY_COLUMNS;
+	vc->vc_rows = DUMMY_ROWS;
+    } else
+	vc_resize(vc->vc_num, DUMMY_COLUMNS, DUMMY_ROWS);
+}
+
+static int dummycon_dummy(void)
+{
+    return 0;
+}
+
+#define DUMMY	(void *)dummycon_dummy
+
+/*
+ *  The console `switch' structure for the dummy console
+ *
+ *  Most of the operations are dummies.
+ */
+
+const struct consw dummy_con = {
+    .con_startup =	dummycon_startup,
+    .con_init =		dummycon_init,
+    .con_deinit =	DUMMY,
+    .con_clear =	DUMMY,
+    .con_putc =		DUMMY,
+    .con_putcs =	DUMMY,
+    .con_cursor =	DUMMY,
+    .con_scroll =	DUMMY,
+    .con_bmove =	DUMMY,
+    .con_switch =	DUMMY,
+    .con_blank =	DUMMY,
+    .con_font_op =	DUMMY,
+    .con_set_palette =	DUMMY,
+    .con_scrolldelta =	DUMMY,
+};
diff -Nru a/drivers/video/console/fbcon-sti.c b/drivers/video/console/fbcon-sti.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/fbcon-sti.c	Mon Dec  9 18:46:50 2002
@@ -0,0 +1,289 @@
+/*
+ * linux/drivers/video/fbcon-sti.c -- Low level frame buffer
+ *  	operations for generic HP video boards using STI (standard
+ *  	text interface) firmware
+ *
+ *  Based on linux/drivers/video/fbcon-artist.c
+ *	Created 5 Apr 1997 by Geert Uytterhoeven
+ *	Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive for
+ * more details.  */
+
+#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 <asm/gsc.h>		/* for gsc_read/write */
+#include <asm/types.h>
+
+#include <video/fbcon.h>
+#include <video/fbcon-mfb.h>
+
+#include "../sticore.h"
+
+static inline u32
+ram2log(void * addr)
+{
+	return (unsigned long) addr;
+}
+
+/* All those functions need better names. */
+
+static void
+memcpy_fromhp_tohp(void *dest, void *src, int count)
+{
+	unsigned long d = ram2log(dest);
+	unsigned long s = ram2log(src);
+
+	count += 3;
+	count &= ~3; /* XXX */
+
+	while(count) {
+		count --;
+		gsc_writel(~gsc_readl(s), d);
+		d += 32*4;
+		s += 32*4;
+	}
+}
+
+
+static void
+memset_tohp(void *dest, u32 word, int count)
+{
+	unsigned long d = ram2log(dest);
+
+	count += 3;
+	count &= ~3;
+
+	while(count) {
+		count--;
+		gsc_writel(word, d);
+		d += 32;
+	}
+}
+
+static u8
+readb_hp(void *src)
+{
+	unsigned long s = ram2log(src);
+
+	return ~gsc_readb(s);
+}
+
+static void
+writeb_hp(u8 b, void *dst)
+{
+	unsigned long d = ram2log(dst);
+
+	if((d&0xf0000000) != 0xf0000000) {
+		printk("writeb_hp %02x %p (%08lx) (%p)\n",
+			b, dst, d, __builtin_return_address(0));
+		return;
+	}
+
+	gsc_writeb(b, d);
+}
+
+static void
+fbcon_sti_setup(struct display *p)
+{
+	/* in kernel 2.5 the value of sadly line_length disapeared */
+	if (p->var.xres_virtual /*line_length*/)
+		p->next_line = p->var.xres_virtual>>3;
+	else
+		p->next_line = 2048; /* default STI value */
+	p->next_plane = 0;
+}
+
+static void
+fbcon_sti_bmove(struct display *p, int sy, int sx,
+		int dy, int dx,
+		int height, int width)
+{
+#if 0 /* Unfortunately, still broken */
+	sti_bmove(default_sti /* FIXME */, sy, sx, dy, dx, height, width);
+#else
+	u8 *src, *dest;
+	u_int rows;
+
+	if (sx == 0 && dx == 0 && width == p->next_line) {
+		src = p->fb_info->screen_base+sy*fontheight(p)*width;
+		dest = p->fb_info->screen_base+dy*fontheight(p)*width;
+		memcpy_fromhp_tohp(dest, src, height*fontheight(p)*width);
+	} else if (dy <= sy) {
+		src = p->fb_info->screen_base+sy*fontheight(p)*p->next_line+sx;
+		dest = p->fb_info->screen_base+dy*fontheight(p)*p->next_line+dx;
+		for (rows = height*fontheight(p); rows--;) {
+			memcpy_fromhp_tohp(dest, src, width);
+			src += p->next_line;
+			dest += p->next_line;
+		}
+	} else {
+		src = p->fb_info->screen_base+((sy+height)*fontheight(p)-1)*p->next_line+sx;
+		dest = p->fb_info->screen_base+((dy+height)*fontheight(p)-1)*p->next_line+dx;
+		for (rows = height*fontheight(p); rows--;) {
+			memcpy_fromhp_tohp(dest, src, width);
+			src -= p->next_line;
+			dest -= p->next_line;
+		}
+	}
+#endif
+}
+
+static void
+fbcon_sti_clear(struct vc_data *conp,
+		struct display *p, int sy, int sx,
+		int height, int width)
+{
+	u8 *dest;
+	u_int rows;
+	int inverse = conp ? attr_reverse(p,conp->vc_video_erase_char) : 0;
+
+	dest = p->fb_info->screen_base+sy*fontheight(p)*p->next_line+sx;
+
+	if (sx == 0 && width == p->next_line) {
+		if (inverse)
+			memset_tohp(dest, ~0, height*fontheight(p)*width);
+		else
+			memset_tohp(dest,  0, height*fontheight(p)*width);
+	} else
+		for (rows = height*fontheight(p); rows--; dest += p->next_line)
+			if (inverse)
+				memset_tohp(dest, 0xffffffff, width);
+			else
+				memset_tohp(dest, 0x00000000, width);
+}
+
+static void fbcon_sti_putc(struct vc_data *conp,
+			   struct display *p, int c,
+			   int yy, int xx)
+{
+	u8 *dest, *cdat;
+	u_int rows, bold, revs, underl;
+	u8 d;
+
+	dest = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
+	cdat = p->fontdata+(c&p->charmask)*fontheight(p);
+	bold = attr_bold(p,c);
+	revs = attr_reverse(p,c);
+	underl = attr_underline(p,c);
+
+	for (rows = fontheight(p); rows--; dest += p->next_line) {
+		d = *cdat++;
+		if (underl && !rows)
+			d = 0xff;
+		else if (bold)
+			d |= d>>1;
+		if (revs)
+			d = ~d;
+		writeb_hp (d, dest);
+	}
+}
+
+static void fbcon_sti_putcs(struct vc_data *conp,
+			    struct display *p, 
+			    const unsigned short *s,
+			    int count, int yy, int xx)
+{
+	u8 *dest, *dest0, *cdat;
+	u_int rows, bold, revs, underl;
+	u8 d;
+	u16 c;
+
+	if(((unsigned)xx > 200) || ((unsigned) yy > 200)) {
+		printk("refusing to putcs %p %p %p %d %d %d (%p)\n",
+			conp, p, s, count, yy, xx, __builtin_return_address(0));
+		return;
+	}	
+
+
+	dest0 = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
+	if(((u32)dest0&0xf0000000)!=0xf0000000) {
+		printk("refusing to putcs %p %p %p %d %d %d (%p) %p = %p + %d * %d * %ld + %d\n",
+			conp, p, s, count, yy, xx, __builtin_return_address(0),
+			dest0, p->fb_info->screen_base, yy, fontheight(p), p->next_line,
+			xx);
+		return;
+	}	
+
+	c = scr_readw(s);
+	bold = attr_bold(p, c);
+	revs = attr_reverse(p, c);
+	underl = attr_underline(p, c);
+
+	while (count--) {
+		c = scr_readw(s++) & p->charmask;
+		dest = dest0++;
+		cdat = p->fontdata+c*fontheight(p);
+		for (rows = fontheight(p); rows--; dest += p->next_line) {
+			d = *cdat++;
+			if (0 && underl && !rows)
+				d = 0xff;
+			else if (0 && bold)
+				d |= d>>1;
+			if (revs)
+				d = ~d;
+			writeb_hp (d, dest);
+		}
+	}
+}
+
+static void fbcon_sti_revc(struct display *p,
+			   int xx, int yy)
+{
+	u8 *dest, d;
+	u_int rows;
+
+	dest = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
+	for (rows = fontheight(p); rows--; dest += p->next_line) {
+		d = readb_hp(dest);
+		writeb_hp (~d, dest);
+	}
+}
+
+static void
+fbcon_sti_clear_margins(struct vc_data *conp,
+			struct display *p,
+			int bottom_only)
+{
+	u8 *dest;
+	int height, bottom;
+	int inverse = conp ? attr_reverse(p,conp->vc_video_erase_char) : 0;
+
+
+	/* XXX Need to handle right margin? */
+
+	height = p->var.yres - conp->vc_rows * fontheight(p);
+	if (!height)
+		return;
+	bottom = conp->vc_rows + p->yscroll;
+	if (bottom >= p->vrows)
+		bottom -= p->vrows;
+	dest = p->fb_info->screen_base + bottom * fontheight(p) * p->next_line;
+	if (inverse)
+		memset_tohp(dest, 0xffffffff, height * p->next_line);
+	else
+		memset_tohp(dest, 0x00000000, height * p->next_line);
+}
+
+
+    /*
+     *  `switch' for the low level operations
+     */
+
+struct display_switch fbcon_sti = {
+	.setup =	fbcon_sti_setup, 
+	.bmove =	fbcon_sti_bmove, 
+	.clear =	fbcon_sti_clear,
+	.putc =		fbcon_sti_putc, 
+	.putcs =	fbcon_sti_putcs, 
+	.revc =		fbcon_sti_revc,
+	.clear_margins =fbcon_sti_clear_margins,
+	.fontwidthmask =FONTWIDTH(8)
+};
+
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/fbcon.c	Mon Dec  9 18:46:50 2002
@@ -0,0 +1,2846 @@
+/*
+ *  linux/drivers/video/fbcon.c -- Low level frame buffer based console driver
+ *
+ *	Copyright (C) 1995 Geert Uytterhoeven
+ *
+ *
+ *  This file is based on the original Amiga console driver (amicon.c):
+ *
+ *	Copyright (C) 1993 Hamish Macdonald
+ *			   Greg Harp
+ *	Copyright (C) 1994 David Carter [carter@compsci.bristol.ac.uk]
+ *
+ *	      with work by William Rucklidge (wjr@cs.cornell.edu)
+ *			   Geert Uytterhoeven
+ *			   Jes Sorensen (jds@kom.auc.dk)
+ *			   Martin Apel
+ *
+ *  and on the original Atari console driver (atacon.c):
+ *
+ *	Copyright (C) 1993 Bjoern Brauel
+ *			   Roman Hodek
+ *
+ *	      with work by Guenther Kelleter
+ *			   Martin Schaller
+ *			   Andreas Schwab
+ *
+ *  Hardware cursor support added by Emmanuel Marty (core@ggi-project.org)
+ *  Smart redraw scrolling, arbitrary font width support, 512char font support
+ *  and software scrollback added by 
+ *                         Jakub Jelinek (jj@ultra.linux.cz)
+ *
+ *  Random hacking by Martin Mares <mj@ucw.cz>
+ *
+ *	2001 - Documented with DocBook
+ *	- Brad Douglas <brad@neruo.com>
+ *
+ *  The low level operations for the various display memory organizations are
+ *  now in separate source files.
+ *
+ *  Currently the following organizations are supported:
+ *
+ *    o afb			Amiga bitplanes
+ *    o cfb{2,4,8,16,24,32}	Packed pixels
+ *    o ilbm			Amiga interleaved bitplanes
+ *    o iplan2p[248]		Atari interleaved bitplanes
+ *    o mfb			Monochrome
+ *    o vga			VGA characters/attributes
+ *
+ *  To do:
+ *
+ *    - Implement 16 plane mode (iplan2p16)
+ *
+ *
+ *  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 FBCONDEBUG
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>	/* MSch: for IRQ probe */
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/string.h>
+#include <linux/kd.h>
+#include <linux/slab.h>
+#include <linux/fb.h>
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#ifdef CONFIG_AMIGA
+#include <asm/amigahw.h>
+#include <asm/amigaints.h>
+#endif				/* CONFIG_AMIGA */
+#ifdef CONFIG_ATARI
+#include <asm/atariints.h>
+#endif
+#ifdef CONFIG_MAC
+#include <asm/macints.h>
+#endif
+#if defined(__mc68000__) || defined(CONFIG_APUS)
+#include <asm/machdep.h>
+#include <asm/setup.h>
+#endif
+#define INCLUDE_LINUX_LOGO_DATA
+#include <asm/linux_logo.h>
+
+#include "fbcon.h"
+#include "font.h"
+
+#ifdef FBCONDEBUG
+#  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+#else
+#  define DPRINTK(fmt, args...)
+#endif
+
+#define LOGO_H			80
+#define LOGO_W			80
+#define LOGO_LINE	(LOGO_W/8)
+
+struct display fb_display[MAX_NR_CONSOLES];
+char con2fb_map[MAX_NR_CONSOLES];
+static int logo_lines;
+static int logo_shown = -1;
+/* Software scrollback */
+int fbcon_softback_size = 32768;
+static unsigned long softback_buf, softback_curr;
+static unsigned long softback_in;
+static unsigned long softback_top, softback_end;
+static int softback_lines;
+/* console mappings */
+static int first_fb_vc;
+static int last_fb_vc = MAX_NR_CONSOLES - 1;
+static int fbcon_is_default = 1; 
+
+#define REFCOUNT(fd)	(((int *)(fd))[-1])
+#define FNTSIZE(fd)	(((int *)(fd))[-2])
+#define FNTCHARCNT(fd)	(((int *)(fd))[-3])
+#define FNTSUM(fd)	(((int *)(fd))[-4])
+#define FONT_EXTRA_WORDS 4
+
+#define CM_SOFTBACK	(8)
+
+#define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * vc->vc_size_row)
+
+static void fbcon_free_font(struct display *);
+static int fbcon_set_origin(struct vc_data *);
+static int cursor_drawn;
+
+#define CURSOR_DRAW_DELAY		(1)
+
+/* # VBL ints between cursor state changes */
+#define ARM_CURSOR_BLINK_RATE		(10)
+#define AMIGA_CURSOR_BLINK_RATE		(20)
+#define ATARI_CURSOR_BLINK_RATE		(42)
+#define MAC_CURSOR_BLINK_RATE		(32)
+#define DEFAULT_CURSOR_BLINK_RATE	(20)
+
+static int vbl_cursor_cnt;
+static int cursor_on;
+static int cursor_blink_rate;
+
+static inline void cursor_undrawn(void)
+{
+	vbl_cursor_cnt = 0;
+	cursor_drawn = 0;
+}
+
+#define divides(a, b)	((!(a) || (b)%(a)) ? 0 : 1)
+
+/*
+ *  Interface used by the world
+ */
+
+static const char *fbcon_startup(void);
+static void fbcon_init(struct vc_data *vc, int init);
+static void fbcon_deinit(struct vc_data *vc);
+static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
+			int width);
+static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos);
+static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,
+			int count, int ypos, int xpos);
+static void fbcon_cursor(struct vc_data *vc, int mode);
+static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
+			int count);
+static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx,
+			int height, int width);
+static int fbcon_switch(struct vc_data *vc);
+static int fbcon_blank(struct vc_data *vc, int blank);
+static int fbcon_font_op(struct vc_data *vc, struct console_font_op *op);
+static int fbcon_set_palette(struct vc_data *vc, unsigned char *table);
+static int fbcon_scrolldelta(struct vc_data *vc, int lines);
+
+
+/*
+ *  Internal routines
+ */
+
+static int fbcon_changevar(int con);
+static void fbcon_set_display(int con, int init, int logo);
+static __inline__ int real_y(struct display *p, int ypos);
+static void fbcon_vbl_handler(int irq, void *dummy, struct pt_regs *fp);
+static __inline__ void updatescrollmode(struct display *p, struct vc_data *vc);
+static __inline__ void ywrap_up(struct display *p, struct vc_data *vc,
+				int count);
+static __inline__ void ywrap_down(struct display *p, struct vc_data *vc,
+				  int count);
+static __inline__ void ypan_up(struct display *p, struct vc_data *vc,
+			       int count);
+static __inline__ void ypan_down(struct display *p, struct vc_data *vc,
+				 int count);
+static void fbcon_bmove_rec(struct display *p, int sy, int sx, int dy,
+			    int dx, int height, int width, u_int y_break);
+
+static int fbcon_show_logo(void);
+
+#ifdef CONFIG_MAC
+/*
+ * On the Macintoy, there may or may not be a working VBL int. We need to probe
+ */
+static int vbl_detected;
+
+static void fbcon_vbl_detect(int irq, void *dummy, struct pt_regs *fp)
+{
+	vbl_detected++;
+}
+#endif
+
+static void cursor_timer_handler(unsigned long dev_addr);
+
+static struct timer_list cursor_timer =
+		TIMER_INITIALIZER(cursor_timer_handler, 0, 0);
+
+static void cursor_timer_handler(unsigned long dev_addr)
+{
+	fbcon_vbl_handler(0, NULL, NULL);
+	cursor_timer.expires = jiffies + HZ / 50;
+	add_timer(&cursor_timer);
+}
+
+int __init fb_console_setup(char *this_opt)
+{
+	int unit, i, j;
+	char *options;
+
+	if (!this_opt || !*this_opt)
+		return 0;
+
+	while ((options = strsep(&this_opt, ",")) != NULL) {
+		if (!strncmp(options, "font:", 5)) {
+			for (unit = 0; unit < MAX_NR_CONSOLES; unit++)
+				strcpy(fb_display[unit].fontname,
+				       options + 5);
+		}
+		
+		if (!strncmp(options, "scrollback:", 11)) {
+			options += 11;
+			if (*options) {
+				fbcon_softback_size = simple_strtoul(options, &options, 0);
+				if (*options == 'k' || *options == 'K') {
+					fbcon_softback_size *= 1024;
+					options++;
+				}
+				if (*options != ',')
+					return 0;
+				options++;
+			} else
+				return 0;
+		}
+		
+		if (!strncmp(options, "map:", 4)) {
+			options += 4;
+			if (*options)
+				for (i = 0, j = 0; i < MAX_NR_CONSOLES; i++) {
+					if (!options[j])
+						j = 0;
+					con2fb_map[i] = (options[j++]-'0') % FB_MAX;
+				}
+			return 0;
+		}
+
+		if (!strncmp(options, "vc:", 3)) {
+			options += 3;
+			if (*options)
+				first_fb_vc = simple_strtoul(options, &options, 10) - 1;
+			if (first_fb_vc < 0)
+				first_fb_vc = 0;
+			if (*options++ == '-')
+				last_fb_vc = simple_strtoul(options, &options, 10) - 1;
+			fbcon_is_default = 0; 
+		}	
+	}
+	return 0;
+}
+
+__setup("fbcon=", fb_console_setup);
+
+void gen_set_disp(int con, struct fb_info *info)
+{
+	struct display *display = fb_display + con;
+
+	display->can_soft_blank = info->fbops->fb_blank ? 1 : 0;
+	display->scrollmode = SCROLL_YNOMOVE;
+	fbcon_changevar(con);
+	return;
+}
+
+/**
+ *	set_con2fb_map - map console to frame buffer device
+ *	@unit: virtual console number to map
+ *	@newidx: frame buffer index to map virtual console to
+ *
+ *	Maps a virtual console @unit to a frame buffer device
+ *	@newidx.
+ *
+ */
+
+void set_con2fb_map(int unit, int newidx)
+{
+	int oldidx = con2fb_map[unit];
+	struct fb_info *oldfb, *newfb;
+	struct vc_data *vc;
+	char *fontdata;
+	int userfont;
+
+	if (newidx != con2fb_map[unit]) {
+		oldfb = registered_fb[oldidx];
+		newfb = registered_fb[newidx];
+		if (!try_module_get(newfb->fbops->owner))
+			return;
+		if (newfb->fbops->fb_open
+		    && newfb->fbops->fb_open(newfb, 0)) {
+			module_put(newfb->fbops->owner);
+			return;
+		}
+		if (oldfb->fbops->fb_release)
+			oldfb->fbops->fb_release(oldfb, 0);
+		module_put(oldfb->fbops->owner);
+		vc = fb_display[unit].conp;
+		fontdata = fb_display[unit].fontdata;
+		userfont = fb_display[unit].userfont;
+		con2fb_map[unit] = newidx;
+
+		fb_display[unit].conp = vc;
+		fb_display[unit].fontdata = fontdata;
+		fb_display[unit].userfont = userfont;
+		fb_display[unit].fb_info = newfb;
+		gen_set_disp(unit, newfb);
+		/* tell console var has changed */
+		fbcon_changevar(unit);
+	}
+}
+
+/*
+ * Accelerated handlers.
+ */
+void accel_bmove(struct display *p, int sy, int sx, int dy, int dx,
+			int height, int width)
+{
+	struct fb_info *info = p->fb_info;
+	struct vc_data *vc = p->conp;
+	struct fb_copyarea area;
+
+	area.sx = sx * vc->vc_font.width;
+	area.sy = sy * vc->vc_font.height;
+	area.dx = dx * vc->vc_font.width;
+	area.dy = dy * vc->vc_font.height;
+	area.height = height * vc->vc_font.height;
+	area.width = width * vc->vc_font.width;
+
+	info->fbops->fb_copyarea(info, &area);
+}
+
+void accel_clear(struct vc_data *vc, struct display *p, int sy,
+			int sx, int height, int width)
+{
+	struct fb_info *info = p->fb_info;
+	struct fb_fillrect region;
+
+	region.color = attr_bgcol_ec(p, vc);
+	region.dx = sx * vc->vc_font.width;
+	region.dy = sy * vc->vc_font.height;
+	region.width = width * vc->vc_font.width;
+	region.height = height * vc->vc_font.height;
+	region.rop = ROP_COPY;
+
+	info->fbops->fb_fillrect(info, &region);
+}	
+
+void accel_putcs(struct vc_data *vc, struct display *p,
+			const unsigned short *s, int count, int yy, int xx)
+{
+	struct fb_info *info = p->fb_info;
+	unsigned short charmask = p->charmask;
+	unsigned int width = ((vc->vc_font.width + 7)/8);
+	unsigned int cellsize = vc->vc_font.height * width;
+	struct fb_image image;
+	u16 c = scr_readw(s);
+	static u8 pixmap[8192];
+	
+	image.fg_color = attr_fgcol(p, c);
+	image.bg_color = attr_bgcol(p, c);
+	image.dx = xx * vc->vc_font.width;
+	image.dy = yy * vc->vc_font.height;
+	image.height = vc->vc_font.height;
+	image.depth = 1;
+
+/*	pixmap = kmalloc((info->var.bits_per_pixel + 7) >> 3 *
+				vc->vc_font.height, GFP_KERNEL); 
+*/
+				
+	if (!(vc->vc_font.width & 7) && pixmap != NULL) {
+		unsigned int pitch = width * count, i, j;
+		char *src, *dst, *dst0;
+
+		dst0 = pixmap;
+		image.width = vc->vc_font.width * count;
+		image.data = pixmap;
+		while (count--) {
+			src = p->fontdata + (scr_readw(s++) & charmask) * cellsize;
+			dst = dst0;
+			for (i = image.height; i--; ) {
+				for (j = 0; j < width; j++) 
+					dst[j] = *src++;
+				dst += pitch;
+			}
+			dst0 += width;
+		}
+		info->fbops->fb_imageblit(info, &image);
+		if (info->fbops->fb_sync)
+			info->fbops->fb_sync(info);
+	} else {
+		image.width = vc->vc_font.width;
+		while (count--) {
+			image.data = p->fontdata + 
+				(scr_readw(s++) & charmask) * vc->vc_font.height * width;
+			info->fbops->fb_imageblit(info, &image);
+			image.dx += vc->vc_font.width;
+		}	
+	}
+	/*
+	if (pixmap);
+		kfree(pixmap);
+	*/	
+}
+
+void accel_clear_margins(struct vc_data *vc, struct display *p,
+				int bottom_only)
+{
+	struct fb_info *info = p->fb_info;
+	unsigned int cw = vc->vc_font.width;
+	unsigned int ch = vc->vc_font.height;
+	unsigned int rw = info->var.xres % cw;
+	unsigned int bh = info->var.yres % ch;
+	unsigned int rs = info->var.xres - rw;
+	unsigned int bs = info->var.yres - bh;
+	struct fb_fillrect region;
+
+	region.color = attr_bgcol_ec(p, vc);
+	region.rop = ROP_COPY;
+
+	if (rw & !bottom_only) {
+		region.dx = info->var.xoffset + rs;
+		region.dy = 0;
+		region.width = rw;
+		region.height = info->var.yres_virtual;
+		info->fbops->fb_fillrect(info, &region);
+	}
+
+	if (bh) {
+		region.dx = info->var.xoffset;
+		region.dy = info->var.yoffset + bs;
+		region.width = rs;
+		region.height = bh;
+		info->fbops->fb_fillrect(info, &region);
+	}	
+}	
+
+void accel_cursor(struct display *p, int flags, int xx, int yy)
+{
+	static char mask[64], image[64], *dest;
+	struct vc_data *vc = p->conp;
+	static int fgcolor, bgcolor, shape, width, height;
+	struct fb_info *info = p->fb_info;
+	struct fb_cursor cursor;
+	char *font;
+	int c;
+
+	cursor.set = FB_CUR_SETPOS;
+	
+	if (width != vc->vc_font.width || height != vc->vc_font.height) {
+		width = vc->vc_font.width;
+		height = vc->vc_font.height;
+		cursor.set |= FB_CUR_SETSIZE;
+	}	
+
+	if ((vc->vc_cursor_type & 0x0f) != shape) {
+		shape = vc->vc_cursor_type & 0x0f;
+		cursor.set |= FB_CUR_SETSHAPE;
+	}
+
+	c = scr_readw((u16 *) vc->vc_pos);
+
+	if (fgcolor != (int) attr_fgcol(p, c) ||
+	    bgcolor != (int) attr_bgcol(p, c)) {
+		fgcolor = (int) attr_fgcol(p, c);
+		bgcolor = (int) attr_bgcol(p, c);
+		cursor.set |= FB_CUR_SETCMAP;
+	}
+	c &= p->charmask;
+	font = p->fontdata + (c * ((width + 7) / 8) * height);
+	if (font != dest) {
+		dest = font;
+		cursor.set |= FB_CUR_SETDEST;
+	}
+
+	if (flags & FB_CUR_SETCUR)
+		cursor.enable = 1;
+	else
+		cursor.enable = 0;
+
+	if (cursor.set & FB_CUR_SETSIZE) {
+		memset(image, 0xff, 64);
+		cursor.set |= FB_CUR_SETSHAPE;
+	}		
+
+	if (cursor.set & FB_CUR_SETSHAPE) {
+		int w, cur_height, size, i = 0;
+
+		w = (width + 7) / 8;
+
+		switch (shape) {
+			case CUR_NONE:
+				cur_height = 0;
+				break;
+			case CUR_UNDERLINE:
+				cur_height = (height < 10) ? 1 : 2;
+				break;
+			case CUR_LOWER_THIRD:
+				cur_height = height/3;
+				break;
+			case CUR_LOWER_HALF:
+				cur_height = height/2;
+				break;
+			case CUR_TWO_THIRDS:
+				cur_height = (height * 2)/3;
+				break;
+			case CUR_BLOCK:
+			default:
+				cur_height = height;
+				break;
+		}
+
+		size = (height - cur_height) * w;
+		while (size--)
+			mask[i++] = 0;
+		size = cur_height * w;
+		while (size--)
+			mask[i++] = 0xff;
+	}
+	
+	cursor.image.width = width;
+	cursor.image.height = height;
+	cursor.image.dx = xx * width;
+	cursor.image.dy = yy * height;
+	cursor.image.depth = 1;
+	cursor.image.data = image;
+	cursor.image.bg_color = bgcolor;
+	cursor.image.fg_color = fgcolor;
+	cursor.mask = mask;
+	cursor.dest = dest;
+	cursor.rop = ROP_XOR;
+
+	if (info->fbops->fb_cursor)
+		info->fbops->fb_cursor(info, &cursor);
+}
+	
+/*
+ *  Low Level Operations
+ */
+/* NOTE: fbcon cannot be __init: it may be called from take_over_console later */
+
+static const char *fbcon_startup(void)
+{
+	const char *display_desc = "frame buffer device";
+	struct font_desc *font = NULL;
+	struct module *owner;
+	struct fb_info *info;
+	struct vc_data *vc;
+	static int done = 0;
+	int irqres = 1;
+
+	/*
+	 *  If num_registered_fb is zero, this is a call for the dummy part.
+	 *  The frame buffer devices weren't initialized yet.
+	 */
+	if (!num_registered_fb || done)
+		return display_desc;
+	done = 1;
+
+	info = registered_fb[num_registered_fb-1];	
+	if (!info)	return NULL;
+	info->currcon = -1;
+	
+	owner = info->fbops->owner;
+	if (!try_module_get(owner))
+		return NULL;
+	if (info->fbops->fb_open && info->fbops->fb_open(info, 0))
+		module_put(owner);
+	
+	if (info->fix.type != FB_TYPE_TEXT) {
+		if (fbcon_softback_size) {
+			if (!softback_buf) {
+				softback_buf =
+				    (unsigned long)
+				    kmalloc(fbcon_softback_size,
+					    GFP_KERNEL);
+				if (!softback_buf) {
+					fbcon_softback_size = 0;
+					softback_top = 0;
+				}
+			}
+		} else {
+			if (softback_buf) {
+				kfree((void *) softback_buf);
+				softback_buf = 0;
+				softback_top = 0;
+			}
+		}
+		if (softback_buf)
+			softback_in = softback_top = softback_curr =
+			    softback_buf;
+		softback_lines = 0;
+	}
+
+	font = get_default_font(info->var.xres, info->var.yres);	
+
+	vc = (struct vc_data *) kmalloc(sizeof(struct vc_data), GFP_ATOMIC); 
+
+	/* Setup default font */
+	vc->vc_font.data = font->data;
+	vc->vc_font.width = font->width;
+	vc->vc_font.height = font->height;
+	vc->vc_font.charcount = 256; /* FIXME  Need to support more fonts */
+
+	vc->vc_cols = info->var.xres/vc->vc_font.width;
+	vc->vc_rows = info->var.yres/vc->vc_font.height;
+	
+	/* We trust the mode the driver supplies. */
+	if (info->fbops->fb_set_par)
+		info->fbops->fb_set_par(info);
+
+	DPRINTK("mode:   %s\n", info->fix.id);
+	DPRINTK("visual: %d\n", info->fix.visual);
+	DPRINTK("res:    %dx%d-%d\n", info->var.xres,
+		info->var.yres,
+		info->var.bits_per_pixel);
+
+	info->display_fg = vc;
+	
+#ifdef CONFIG_AMIGA
+	if (MACH_IS_AMIGA) {
+		cursor_blink_rate = AMIGA_CURSOR_BLINK_RATE;
+		irqres = request_irq(IRQ_AMIGA_VERTB, fbcon_vbl_handler, 0,
+				     "console/cursor", fbcon_vbl_handler);
+	}
+#endif				/* CONFIG_AMIGA */
+#ifdef CONFIG_ATARI
+	if (MACH_IS_ATARI) {
+		cursor_blink_rate = ATARI_CURSOR_BLINK_RATE;
+		irqres =
+		    request_irq(IRQ_AUTO_4, fbcon_vbl_handler,
+				IRQ_TYPE_PRIO, "console/cursor",
+				fbcon_vbl_handler);
+	}
+#endif				/* CONFIG_ATARI */
+
+#ifdef CONFIG_MAC
+	/*
+	 * On a Macintoy, the VBL interrupt may or may not be active. 
+	 * As interrupt based cursor is more reliable and race free, we 
+	 * probe for VBL interrupts.
+	 */
+	if (MACH_IS_MAC) {
+		int ct = 0;
+		/*
+		 * Probe for VBL: set temp. handler ...
+		 */
+		irqres = request_irq(IRQ_MAC_VBL, fbcon_vbl_detect, 0,
+				     "console/cursor", fbcon_vbl_detect);
+		vbl_detected = 0;
+
+		/*
+		 * ... and spin for 20 ms ...
+		 */
+		while (!vbl_detected && ++ct < 1000)
+			udelay(20);
+
+		if (ct == 1000)
+			printk
+			    ("fbcon_startup: No VBL detected, using timer based cursor.\n");
+
+		free_irq(IRQ_MAC_VBL, fbcon_vbl_detect);
+
+		if (vbl_detected) {
+			/*
+			 * interrupt based cursor ok
+			 */
+			cursor_blink_rate = MAC_CURSOR_BLINK_RATE;
+			irqres =
+			    request_irq(IRQ_MAC_VBL, fbcon_vbl_handler, 0,
+					"console/cursor",
+					fbcon_vbl_handler);
+		} else {
+			/*
+			 * VBL not detected: fall through, use timer based cursor
+			 */
+			irqres = 1;
+		}
+	}
+#endif				/* CONFIG_MAC */
+
+#if defined(__arm__) && defined(IRQ_VSYNCPULSE)
+	cursor_blink_rate = ARM_CURSOR_BLINK_RATE;
+	irqres = request_irq(IRQ_VSYNCPULSE, fbcon_vbl_handler, SA_SHIRQ,
+			     "console/cursor", fbcon_vbl_handler);
+#endif
+
+	if (irqres) {
+		cursor_blink_rate = DEFAULT_CURSOR_BLINK_RATE;
+		cursor_timer.expires = jiffies + HZ / 50;
+		add_timer(&cursor_timer);
+	}
+	return display_desc;
+}
+
+static void fbcon_init(struct vc_data *vc, int init)
+{
+	int unit = vc->vc_num;
+	struct fb_info *info;
+
+	/* on which frame buffer will we open this console? */
+	info = registered_fb[(int) con2fb_map[unit]];
+
+	gen_set_disp(unit, info);
+	fb_display[unit].conp = vc;
+	fb_display[unit].fb_info = info;
+
+	fbcon_set_display(unit, init, !init);
+}
+
+
+static void fbcon_deinit(struct vc_data *vc)
+{
+	int unit = vc->vc_num;
+	struct display *p = &fb_display[unit];
+
+	fbcon_free_font(p);
+	p->conp = 0;
+}
+
+#define fontwidthvalid(p,w) ((p)->fontwidthmask & FONTWIDTH(w))
+
+static int fbcon_changevar(int con)
+{
+	if (fb_display[con].conp) {
+		struct display *p = &fb_display[con];
+		struct fb_info *info = p->fb_info;
+		struct vc_data *vc = p->conp;
+		int nr_rows, nr_cols;
+		int old_rows, old_cols;
+		unsigned short *save = NULL, *q;
+		int i, charcnt = 256;
+		struct font_desc *font;
+
+		info->var.xoffset = info->var.yoffset = p->yscroll = 0;	/* reset wrap/pan */
+
+		for (i = 0; i < MAX_NR_CONSOLES; i++)
+			if (i != con && fb_display[i].fb_info == info &&
+		    		fb_display[i].conp && fb_display[i].fontdata)
+					break;
+
+		fbcon_free_font(p);
+		if (i < MAX_NR_CONSOLES) {
+			struct display *q = &fb_display[i];
+			struct vc_data *tmp = vc_cons[i].d;
+			
+			if (fontwidthvalid(p, vc->vc_font.width)) {
+				/* If we are not the first console on this
+				   fb, copy the font from that console */
+				tmp->vc_font.width = vc->vc_font.width;
+				tmp->vc_font.height = vc->vc_font.height;
+				p->fontdata = q->fontdata;
+				p->userfont = q->userfont;
+				if (p->userfont) {
+					REFCOUNT(p->fontdata)++;
+					charcnt = FNTCHARCNT(p->fontdata);
+				}
+				con_copy_unimap(con, i);
+			}
+		}
+
+		if (!p->fontdata) {
+			if (!p->fontname[0] || !(font = find_font(p->fontname)))
+			    	font = get_default_font(info->var.xres,
+						   		info->var.yres);
+			vc->vc_font.width = font->width;
+			vc->vc_font.height = font->height;
+			p->fontdata = font->data;
+		}
+
+#ifdef FONTWIDTH8_ONLY		
+		if (!fontwidthvalid(p, vc->vc_font.width)) {
+			/* ++Geert: changed from panic() to `correct and continue' */
+			printk(KERN_ERR
+		       		"fbcon_set_display: No support for fontwidth %d\n",
+		       		vc->vc_font.width);
+		}
+#endif		
+		updatescrollmode(p, vc);
+
+		old_cols = vc->vc_cols;
+		old_rows = vc->vc_rows;
+
+		nr_cols = info->var.xres / vc->vc_font.width;
+		nr_rows = info->var.yres / vc->vc_font.height;
+
+		/*
+	 	 *  ++guenther: console.c:vc_allocate() relies on initializing
+	 	 *  vc_{cols,rows}, but we must not set those if we are only
+	 	 *  resizing the console.
+	 	 */
+		p->vrows = info->var.yres_virtual / vc->vc_font.height;
+		if ((info->var.yres % vc->vc_font.height) &&
+	    	    (info->var.yres_virtual % vc->vc_font.height <
+	     	     info->var.yres % vc->vc_font.height))
+			p->vrows--;
+		vc->vc_can_do_color = info->var.bits_per_pixel != 1;
+		vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
+		if (charcnt == 256) {
+			vc->vc_hi_font_mask = 0;
+			p->fgshift = 8;
+			p->bgshift = 12;
+			p->charmask = 0xff;
+		} else {
+			vc->vc_hi_font_mask = 0x100;
+			if (vc->vc_can_do_color)
+				vc->vc_complement_mask <<= 1;
+			p->fgshift = 9;
+			p->bgshift = 13;
+			p->charmask = 0x1ff;
+		}
+
+		if (vc->vc_cols != nr_cols || vc->vc_rows != nr_rows)
+			vc_resize(con, nr_cols, nr_rows);
+		else if (CON_IS_VISIBLE(vc) &&
+		 	vt_cons[vc->vc_num]->vc_mode == KD_TEXT) {
+			accel_clear_margins(vc, p, 0);
+			update_screen(con);
+		}
+		if (save) {
+			q = (unsigned short *) (vc->vc_origin +
+						vc->vc_size_row *
+						old_rows);
+			scr_memcpyw(q, save, logo_lines * nr_cols * 2);
+			vc->vc_y += logo_lines;
+			vc->vc_pos += logo_lines * vc->vc_size_row;
+			kfree(save);
+		}
+
+		if (con == fg_console && softback_buf) {
+			int l = fbcon_softback_size / vc->vc_size_row;
+			if (l > 5)
+				softback_end = softback_buf + l * vc->vc_size_row;
+			else {
+				/* Smaller scrollback makes no sense, and 0 would screw
+			   	the operation totally */
+				softback_top = 0;
+			}
+		}
+	}	
+	return 0;
+}
+
+static __inline__ void updatescrollmode(struct display *p, struct vc_data *vc)
+{
+	struct fb_info *info = p->fb_info;
+
+	int m;
+	if (p->scrollmode & __SCROLL_YFIXED)
+		return;
+	if (divides(info->fix.ywrapstep, vc->vc_font.height) &&
+	    divides(vc->vc_font.height, info->var.yres_virtual))
+		m = __SCROLL_YWRAP;
+	else if (divides(info->fix.ypanstep, vc->vc_font.height) &&
+		 info->var.yres_virtual >= info->var.yres + vc->vc_font.height)
+		m = __SCROLL_YPAN;
+	else if (p->scrollmode & __SCROLL_YNOMOVE)
+		m = __SCROLL_YREDRAW;
+	else
+		m = __SCROLL_YMOVE;
+	p->scrollmode = (p->scrollmode & ~__SCROLL_YMASK) | m;
+}
+
+static void fbcon_set_display(int con, int init, int logo)
+{
+	struct display *p = &fb_display[con];
+	struct fb_info *info = p->fb_info;
+	struct vc_data *vc = p->conp;
+	int nr_rows, nr_cols;
+	int old_rows, old_cols;
+	unsigned short *save = NULL, *r, *q;
+	int i, charcnt = 256;
+	struct font_desc *font;
+
+	if (con != fg_console || (info->flags & FBINFO_FLAG_MODULE) ||
+	    info->fix.type == FB_TYPE_TEXT)
+		logo = 0;
+
+	info->var.xoffset = info->var.yoffset = p->yscroll = 0;	/* reset wrap/pan */
+
+	/*
+	 * FIXME: need to set this in order for KDFONTOP ioctl
+	 *        to work
+	 */
+	p->fontwidthmask = FONTWIDTHRANGE(1,16);
+
+	for (i = 0; i < MAX_NR_CONSOLES; i++)
+		if (i != con && fb_display[i].fb_info == info &&
+		    fb_display[i].conp && fb_display[i].fontdata)
+			break;
+
+	fbcon_free_font(p);
+	if (i < MAX_NR_CONSOLES) {
+		struct display *q = &fb_display[i];
+		struct vc_data *tmp = vc_cons[i].d;
+		
+		if (fontwidthvalid(p, vc->vc_font.width)) {
+			/* If we are not the first console on this
+			   fb, copy the font from that console */
+			tmp->vc_font.width = vc->vc_font.width;
+			tmp->vc_font.height = vc->vc_font.height;
+			p->fontdata = q->fontdata;
+			p->userfont = q->userfont;
+			if (p->userfont) {
+				REFCOUNT(p->fontdata)++;
+				charcnt = FNTCHARCNT(p->fontdata);
+			}
+			con_copy_unimap(con, i);
+		}
+	}
+
+	if (!p->fontdata) {
+		if (!p->fontname[0] || !(font = find_font(p->fontname)))
+			font = get_default_font(info->var.xres,
+						   info->var.yres);
+		vc->vc_font.width = font->width;
+		vc->vc_font.height = font->height;
+		p->fontdata = font->data;
+	}
+
+#ifdef FONTWIDTH8_ONLY		
+	if (!fontwidthvalid(p, vc->vc_font.width)) {
+		/* ++Geert: changed from panic() to `correct and continue' */
+		printk(KERN_ERR
+		       "fbcon_set_display: No support for fontwidth %d\n",
+		       vc->vc_font.width);
+	}
+#endif	
+	updatescrollmode(p, vc);
+
+	old_cols = vc->vc_cols;
+	old_rows = vc->vc_rows;
+
+	nr_cols = info->var.xres / vc->vc_font.width;
+	nr_rows = info->var.yres / vc->vc_font.height;
+
+	if (logo) {
+		/* Need to make room for the logo */
+		int cnt;
+		int step;
+
+		logo_lines = (LOGO_H + vc->vc_font.height - 1) / vc->vc_font.height;
+		q = (unsigned short *) (vc->vc_origin +
+					vc->vc_size_row * old_rows);
+		step = logo_lines * old_cols;
+		for (r = q - logo_lines * old_cols; r < q; r++)
+			if (scr_readw(r) != vc->vc_video_erase_char)
+				break;
+		if (r != q && nr_rows >= old_rows + logo_lines) {
+			save =
+			    kmalloc(logo_lines * nr_cols * 2, GFP_KERNEL);
+			if (save) {
+				int i =
+				    old_cols <
+				    nr_cols ? old_cols : nr_cols;
+				scr_memsetw(save, vc->vc_video_erase_char,
+					    logo_lines * nr_cols * 2);
+				r = q - step;
+				for (cnt = 0; cnt < logo_lines;
+				     cnt++, r += i)
+					scr_memcpyw(save + cnt * nr_cols,
+						    r, 2 * i);
+				r = q;
+			}
+		}
+		if (r == q) {
+			/* We can scroll screen down */
+			r = q - step - old_cols;
+			for (cnt = old_rows - logo_lines; cnt > 0; cnt--) {
+				scr_memcpyw(r + step, r, vc->vc_size_row);
+				r -= old_cols;
+			}
+			if (!save) {
+				vc->vc_y += logo_lines;
+				vc->vc_pos += logo_lines * vc->vc_size_row;
+			}
+		}
+		scr_memsetw((unsigned short *) vc->vc_origin,
+			    vc->vc_video_erase_char,
+			    vc->vc_size_row * logo_lines);
+	}
+
+	/*
+	 *  ++guenther: console.c:vc_allocate() relies on initializing
+	 *  vc_{cols,rows}, but we must not set those if we are only
+	 *  resizing the console.
+	 */
+	if (init) {
+		vc->vc_cols = nr_cols;
+		vc->vc_rows = nr_rows;
+	}
+	p->vrows = info->var.yres_virtual / vc->vc_font.height;
+	if ((info->var.yres % vc->vc_font.height) &&
+	    (info->var.yres_virtual % vc->vc_font.height <
+	     info->var.yres % vc->vc_font.height))
+		p->vrows--;
+	vc->vc_can_do_color = info->var.bits_per_pixel != 1;
+	vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
+	if (charcnt == 256) {
+		vc->vc_hi_font_mask = 0;
+		p->fgshift = 8;
+		p->bgshift = 12;
+		p->charmask = 0xff;
+	} else {
+		vc->vc_hi_font_mask = 0x100;
+		if (vc->vc_can_do_color)
+			vc->vc_complement_mask <<= 1;
+		p->fgshift = 9;
+		p->bgshift = 13;
+		p->charmask = 0x1ff;
+	}
+
+	if (!init) {
+		if (vc->vc_cols != nr_cols || vc->vc_rows != nr_rows)
+			vc_resize(con, nr_cols, nr_rows);
+		else if (CON_IS_VISIBLE(vc) &&
+			 vt_cons[vc->vc_num]->vc_mode == KD_TEXT) {
+			accel_clear_margins(vc, p, 0);
+			update_screen(con);
+		}
+		if (save) {
+			q = (unsigned short *) (vc->vc_origin +
+						vc->vc_size_row *
+						old_rows);
+			scr_memcpyw(q, save, logo_lines * nr_cols * 2);
+			vc->vc_y += logo_lines;
+			vc->vc_pos += logo_lines * vc->vc_size_row;
+			kfree(save);
+		}
+	}
+
+	if (logo) {
+		if (logo_lines > vc->vc_bottom) {
+			logo_shown = -1;
+			printk(KERN_INFO
+			       "fbcon_startup: disable boot-logo (boot-logo bigger than screen).\n");
+		} else {
+			logo_shown = -2;
+			vc->vc_top = logo_lines;
+		}
+	}
+
+	if (con == fg_console && softback_buf) {
+		int l = fbcon_softback_size / vc->vc_size_row;
+		if (l > 5)
+			softback_end = softback_buf + l * vc->vc_size_row;
+		else {
+			/* Smaller scrollback makes no sense, and 0 would screw
+			   the operation totally */
+			softback_top = 0;
+		}
+	}
+}
+
+
+/* ====================================================================== */
+
+/*  fbcon_XXX routines - interface used by the world
+ *
+ *  This system is now divided into two levels because of complications
+ *  caused by hardware scrolling. Top level functions:
+ *
+ *	fbcon_bmove(), fbcon_clear(), fbcon_putc()
+ *
+ *  handles y values in range [0, scr_height-1] that correspond to real
+ *  screen positions. y_wrap shift means that first line of bitmap may be
+ *  anywhere on this display. These functions convert lineoffsets to
+ *  bitmap offsets and deal with the wrap-around case by splitting blits.
+ *
+ *	fbcon_bmove_physical_8()    -- These functions fast implementations
+ *	fbcon_clear_physical_8()    -- of original fbcon_XXX fns.
+ *	fbcon_putc_physical_8()	    -- (fontwidth != 8) may be added later
+ *
+ *  WARNING:
+ *
+ *  At the moment fbcon_putc() cannot blit across vertical wrap boundary
+ *  Implies should only really hardware scroll in rows. Only reason for
+ *  restriction is simplicity & efficiency at the moment.
+ */
+
+static __inline__ int real_y(struct display *p, int ypos)
+{
+	int rows = p->vrows;
+
+	ypos += p->yscroll;
+	return ypos < rows ? ypos : ypos - rows;
+}
+
+
+static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
+			int width)
+{
+	int unit = vc->vc_num;
+	struct display *p = &fb_display[unit];
+	u_int y_break;
+	int redraw_cursor = 0;
+
+	if (!p->can_soft_blank && console_blanked)
+		return;
+
+	if (!height || !width)
+		return;
+
+	if ((sy <= p->cursor_y) && (p->cursor_y < sy + height) &&
+	    (sx <= p->cursor_x) && (p->cursor_x < sx + width)) {
+		cursor_undrawn();
+		redraw_cursor = 1;
+	}
+
+	/* Split blits that cross physical y_wrap boundary */
+
+	y_break = p->vrows - p->yscroll;
+	if (sy < y_break && sy + height - 1 >= y_break) {
+		u_int b = y_break - sy;
+		accel_clear(vc, p, real_y(p, sy), sx, b, width);
+		accel_clear(vc, p, real_y(p, sy + b), sx, height - b,
+				 width);
+	} else
+		accel_clear(vc, p, real_y(p, sy), sx, height, width);
+
+	if (redraw_cursor)
+		vbl_cursor_cnt = CURSOR_DRAW_DELAY;
+}
+
+
+static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
+{
+	struct display *p = &fb_display[vc->vc_num];
+	struct fb_info *info = p->fb_info;
+	unsigned short charmask = p->charmask;
+	unsigned int width = ((vc->vc_font.width + 7) >> 3);
+	struct fb_image image;
+	int redraw_cursor = 0;
+
+	if (!p->can_soft_blank && console_blanked)
+		return;
+
+	if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT)
+		return;
+
+	if ((p->cursor_x == xpos) && (p->cursor_y == ypos)) {
+		cursor_undrawn();
+		redraw_cursor = 1;
+	}
+
+	image.fg_color = attr_fgcol(p, c);
+	image.bg_color = attr_bgcol(p, c);
+	image.dx = xpos * vc->vc_font.width;
+	image.dy = real_y(p, ypos) * vc->vc_font.height;
+	image.width = vc->vc_font.width;
+	image.height = vc->vc_font.height;
+	image.depth = 1;
+	image.data = p->fontdata + (c & charmask) * vc->vc_font.height * width;
+
+	info->fbops->fb_imageblit(info, &image);
+
+	if (redraw_cursor)
+		vbl_cursor_cnt = CURSOR_DRAW_DELAY;
+}
+
+
+static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,
+			int count, int ypos, int xpos)
+{
+	int unit = vc->vc_num;
+	struct display *p = &fb_display[unit];
+	int redraw_cursor = 0;
+
+	if (!p->can_soft_blank && console_blanked)
+		return;
+
+	if (vt_cons[unit]->vc_mode != KD_TEXT)
+		return;
+
+	if ((p->cursor_y == ypos) && (xpos <= p->cursor_x) &&
+	    (p->cursor_x < (xpos + count))) {
+		cursor_undrawn();
+		redraw_cursor = 1;
+	}
+	accel_putcs(vc, p, s, count, real_y(p, ypos), xpos);
+	if (redraw_cursor)
+		vbl_cursor_cnt = CURSOR_DRAW_DELAY;
+}
+
+static void fbcon_cursor(struct vc_data *vc, int mode)
+{
+	struct display *p = &fb_display[vc->vc_num];
+	int y = vc->vc_y;
+
+	if (mode & CM_SOFTBACK) {
+		mode &= ~CM_SOFTBACK;
+		if (softback_lines) {
+			if (y + softback_lines >= vc->vc_rows)
+				mode = CM_ERASE;
+			else
+				y += softback_lines;
+		}
+	} else if (softback_lines)
+		fbcon_set_origin(vc);
+
+	/* Avoid flickering if there's no real change. */
+	if (p->cursor_x == vc->vc_x && p->cursor_y == y &&
+	    (mode == CM_ERASE) == !cursor_on)
+		return;
+
+	cursor_on = 0;
+	if (cursor_drawn)
+		accel_cursor(p, 0, p->cursor_x,
+				  real_y(p, p->cursor_y));
+
+	p->cursor_x = vc->vc_x;
+	p->cursor_y = y;
+	p->cursor_pos = vc->vc_pos;
+
+	switch (mode) {
+	case CM_ERASE:
+		cursor_drawn = 0;
+		break;
+	case CM_MOVE:
+	case CM_DRAW:
+		if (cursor_drawn)
+			accel_cursor(p, FB_CUR_SETCUR, p->cursor_x,
+					  real_y(p, p->cursor_y));
+		vbl_cursor_cnt = CURSOR_DRAW_DELAY;
+		cursor_on = 1;
+		break;
+	}
+
+}
+
+static void fbcon_vbl_handler(int irq, void *dummy, struct pt_regs *fp)
+{
+	struct display *p;
+
+	if (!cursor_on)
+		return;
+
+	if (vbl_cursor_cnt && --vbl_cursor_cnt == 0) {
+		int flag;
+
+		p = &fb_display[fg_console];
+		flag = 0;
+		if (!cursor_drawn)
+			flag = FB_CUR_SETCUR;
+		accel_cursor(p, flag, p->cursor_x,
+				  real_y(p, p->cursor_y));
+		cursor_drawn ^= 1;
+		vbl_cursor_cnt = cursor_blink_rate;
+	}
+}
+
+static int scrollback_phys_max = 0;
+static int scrollback_max = 0;
+static int scrollback_current = 0;
+
+int update_var(int con, struct fb_info *info)
+{
+	int err;
+
+	if (con == info->currcon) {
+		if (info->fbops->fb_pan_display) {
+			if ((err =
+			     info->fbops->fb_pan_display(&info->var,
+							 info)))
+				return err;
+		}
+	}
+	return 0;
+}
+
+static __inline__ void ywrap_up(struct display *p, struct vc_data *vc,
+				int count)
+{
+	struct fb_info *info = p->fb_info;
+
+	p->yscroll += count;
+	if (p->yscroll >= p->vrows)	/* Deal with wrap */
+		p->yscroll -= p->vrows;
+	info->var.xoffset = 0;
+	info->var.yoffset = p->yscroll * vc->vc_font.height;
+	info->var.vmode |= FB_VMODE_YWRAP;
+	update_var(vc->vc_num, info);
+	scrollback_max += count;
+	if (scrollback_max > scrollback_phys_max)
+		scrollback_max = scrollback_phys_max;
+	scrollback_current = 0;
+}
+
+static __inline__ void ywrap_down(struct display *p, struct vc_data *vc,
+				  int count)
+{
+	struct fb_info *info = p->fb_info;
+
+	p->yscroll -= count;
+	if (p->yscroll < 0)	/* Deal with wrap */
+		p->yscroll += p->vrows;
+	info->var.xoffset = 0;
+	info->var.yoffset = p->yscroll * vc->vc_font.height;
+	info->var.vmode |= FB_VMODE_YWRAP;
+	update_var(vc->vc_num, info);
+	scrollback_max -= count;
+	if (scrollback_max < 0)
+		scrollback_max = 0;
+	scrollback_current = 0;
+}
+
+static __inline__ void ypan_up(struct display *p, struct vc_data *vc,
+			       int count)
+{
+	struct fb_info *info = p->fb_info;
+
+	p->yscroll += count;
+	if (p->yscroll > p->vrows - vc->vc_rows) {
+		accel_bmove(p, p->vrows - vc->vc_rows, 0, 0, 0,
+				 vc->vc_rows, vc->vc_cols);
+		p->yscroll -= p->vrows - vc->vc_rows;
+	}
+	info->var.xoffset = 0;
+	info->var.yoffset = p->yscroll * vc->vc_font.height;
+	info->var.vmode &= ~FB_VMODE_YWRAP;
+	update_var(vc->vc_num, info);
+	accel_clear_margins(vc, p, 1);
+	scrollback_max += count;
+	if (scrollback_max > scrollback_phys_max)
+		scrollback_max = scrollback_phys_max;
+	scrollback_current = 0;
+}
+
+
+static __inline__ void ypan_down(struct display *p, struct vc_data *vc,
+				 int count)
+{
+	struct fb_info *info = p->fb_info;
+
+	p->yscroll -= count;
+	if (p->yscroll < 0) {
+		accel_bmove(p, 0, 0, p->vrows - vc->vc_rows, 0,
+				 vc->vc_rows, vc->vc_cols);
+		p->yscroll += p->vrows - vc->vc_rows;
+	}
+	info->var.xoffset = 0;
+	info->var.yoffset = p->yscroll * vc->vc_font.height;
+	info->var.vmode &= ~FB_VMODE_YWRAP;
+	update_var(vc->vc_num, info);
+	accel_clear_margins(vc, p, 1);
+	scrollback_max -= count;
+	if (scrollback_max < 0)
+		scrollback_max = 0;
+	scrollback_current = 0;
+}
+
+static void fbcon_redraw_softback(struct vc_data *vc, struct display *p,
+				  long delta)
+{
+	unsigned short *d, *s;
+	unsigned long n;
+	int line = 0;
+	int count = vc->vc_rows;
+
+	d = (u16 *) softback_curr;
+	if (d == (u16 *) softback_in)
+		d = (u16 *) vc->vc_origin;
+	n = softback_curr + delta * vc->vc_size_row;
+	softback_lines -= delta;
+	if (delta < 0) {
+		if (softback_curr < softback_top && n < softback_buf) {
+			n += softback_end - softback_buf;
+			if (n < softback_top) {
+				softback_lines -=
+				    (softback_top - n) / vc->vc_size_row;
+				n = softback_top;
+			}
+		} else if (softback_curr >= softback_top
+			   && n < softback_top) {
+			softback_lines -=
+			    (softback_top - n) / vc->vc_size_row;
+			n = softback_top;
+		}
+	} else {
+		if (softback_curr > softback_in && n >= softback_end) {
+			n += softback_buf - softback_end;
+			if (n > softback_in) {
+				n = softback_in;
+				softback_lines = 0;
+			}
+		} else if (softback_curr <= softback_in && n > softback_in) {
+			n = softback_in;
+			softback_lines = 0;
+		}
+	}
+	if (n == softback_curr)
+		return;
+	softback_curr = n;
+	s = (u16 *) softback_curr;
+	if (s == (u16 *) softback_in)
+		s = (u16 *) vc->vc_origin;
+	while (count--) {
+		unsigned short *start;
+		unsigned short *le;
+		unsigned short c;
+		int x = 0;
+		unsigned short attr = 1;
+
+		start = s;
+		le = advance_row(s, 1);
+		do {
+			c = scr_readw(s);
+			if (attr != (c & 0xff00)) {
+				attr = c & 0xff00;
+				if (s > start) {
+					accel_putcs(vc, p, start,
+							 s - start,
+							 real_y(p, line),
+							 x);
+					x += s - start;
+					start = s;
+				}
+			}
+			if (c == scr_readw(d)) {
+				if (s > start) {
+					accel_putcs(vc, p, start,
+							 s - start,
+							 real_y(p, line),
+							 x);
+					x += s - start + 1;
+					start = s + 1;
+				} else {
+					x++;
+					start++;
+				}
+			}
+			s++;
+			d++;
+		} while (s < le);
+		if (s > start)
+			accel_putcs(vc, p, start, s - start,
+					 real_y(p, line), x);
+		line++;
+		if (d == (u16 *) softback_end)
+			d = (u16 *) softback_buf;
+		if (d == (u16 *) softback_in)
+			d = (u16 *) vc->vc_origin;
+		if (s == (u16 *) softback_end)
+			s = (u16 *) softback_buf;
+		if (s == (u16 *) softback_in)
+			s = (u16 *) vc->vc_origin;
+	}
+}
+
+static void fbcon_redraw(struct vc_data *vc, struct display *p,
+			 int line, int count, int offset)
+{
+	unsigned short *d = (unsigned short *)
+	    (vc->vc_origin + vc->vc_size_row * line);
+	unsigned short *s = d + offset;
+
+	while (count--) {
+		unsigned short *start = s;
+		unsigned short *le = advance_row(s, 1);
+		unsigned short c;
+		int x = 0;
+		unsigned short attr = 1;
+
+		do {
+			c = scr_readw(s);
+			if (attr != (c & 0xff00)) {
+				attr = c & 0xff00;
+				if (s > start) {
+					accel_putcs(vc, p, start,
+							 s - start,
+							 real_y(p, line),
+							 x);
+					x += s - start;
+					start = s;
+				}
+			}
+			if (c == scr_readw(d)) {
+				if (s > start) {
+					accel_putcs(vc, p, start,
+							 s - start,
+							 real_y(p, line),
+							 x);
+					x += s - start + 1;
+					start = s + 1;
+				} else {
+					x++;
+					start++;
+				}
+			}
+			scr_writew(c, d);
+			console_conditional_schedule();
+			s++;
+			d++;
+		} while (s < le);
+		if (s > start)
+			accel_putcs(vc, p, start, s - start,
+					 real_y(p, line), x);
+		console_conditional_schedule();
+		if (offset > 0)
+			line++;
+		else {
+			line--;
+			/* NOTE: We subtract two lines from these pointers */
+			s -= vc->vc_size_row;
+			d -= vc->vc_size_row;
+		}
+	}
+}
+
+/**
+ *	fbcon_redraw_clear - clear area of the screen
+ *	@vc: stucture pointing to current active virtual console
+ *	@p: display structure
+ *	@sy: starting Y coordinate
+ *	@sx: starting X coordinate
+ *	@height: height of area to clear
+ *	@width: width of area to clear
+ *
+ *	Clears a specified area of the screen.  All dimensions are in
+ *	pixels.
+ *
+ */
+
+void fbcon_redraw_clear(struct vc_data *vc, struct display *p, int sy,
+			int sx, int height, int width)
+{
+	int x, y;
+	for (y = 0; y < height; y++)
+		for (x = 0; x < width; x++)
+			fbcon_putc(vc, ' ', sy + y, sx + x);
+}
+
+
+/**
+ *	fbcon_redraw_bmove - copy area of screen to another area
+ *	@p: display structure
+ *	@sy: origin Y coordinate
+ *	@sx: origin X coordinate
+ *	@dy: destination Y coordinate
+ *	@dx: destination X coordinate
+ *	@h: height of area to copy
+ *	@w: width of area to copy
+ *
+ *	Copies an area of the screen to another area of the same screen.
+ *	All dimensions are in pixels.
+ *
+ *	Note that this function cannot be used together with ypan or
+ *	ywrap.
+ *
+ */
+
+void fbcon_redraw_bmove(struct vc_data *vc, struct display *p, int sy, int sx, int dy, int dx,
+			int h, int w)
+{
+	if (sy != dy)
+		panic("fbcon_redraw_bmove width sy != dy");
+	/* h will be always 1, but it does not matter if we are more generic */
+
+	while (h-- > 0) {
+		unsigned short *d = (unsigned short *)
+		    (vc->vc_origin + vc->vc_size_row * dy + dx * 2);
+		unsigned short *s = d + (dx - sx);
+		unsigned short *start = d;
+		unsigned short *ls = d;
+		unsigned short *le = d + w;
+		unsigned short c;
+		int x = dx;
+		unsigned short attr = 1;
+
+		do {
+			c = scr_readw(d);
+			if (attr != (c & 0xff00)) {
+				attr = c & 0xff00;
+				if (d > start) {
+					accel_putcs(vc, p, start,
+							 d - start, dy, x);
+					x += d - start;
+					start = d;
+				}
+			}
+			if (s >= ls && s < le && c == scr_readw(s)) {
+				if (d > start) {
+					accel_putcs(vc, p, start,
+							 d - start, dy, x);
+					x += d - start + 1;
+					start = d + 1;
+				} else {
+					x++;
+					start++;
+				}
+			}
+			s++;
+			d++;
+		} while (d < le);
+		if (d > start)
+			accel_putcs(vc, p, start, d - start, dy, x);
+		sy++;
+		dy++;
+	}
+}
+
+static inline void fbcon_softback_note(struct vc_data *vc, int t,
+				       int count)
+{
+	unsigned short *p;
+
+	if (vc->vc_num != fg_console)
+		return;
+	p = (unsigned short *) (vc->vc_origin + t * vc->vc_size_row);
+
+	while (count) {
+		scr_memcpyw((u16 *) softback_in, p, vc->vc_size_row);
+		count--;
+		p = advance_row(p, 1);
+		softback_in += vc->vc_size_row;
+		if (softback_in == softback_end)
+			softback_in = softback_buf;
+		if (softback_in == softback_top) {
+			softback_top += vc->vc_size_row;
+			if (softback_top == softback_end)
+				softback_top = softback_buf;
+		}
+	}
+	softback_curr = softback_in;
+}
+
+static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
+			int count)
+{
+	int unit = vc->vc_num;
+	struct display *p = &fb_display[unit];
+	int scroll_partial = !(p->scrollmode & __SCROLL_YNOPARTIAL);
+
+	if (!p->can_soft_blank && console_blanked)
+		return 0;
+
+	if (!count || vt_cons[unit]->vc_mode != KD_TEXT)
+		return 0;
+
+	fbcon_cursor(vc, CM_ERASE);
+
+	/*
+	 * ++Geert: Only use ywrap/ypan if the console is in text mode
+	 * ++Andrew: Only use ypan on hardware text mode when scrolling the
+	 *           whole screen (prevents flicker).
+	 */
+
+	switch (dir) {
+	case SM_UP:
+		if (count > vc->vc_rows)	/* Maximum realistic size */
+			count = vc->vc_rows;
+		if (softback_top)
+			fbcon_softback_note(vc, t, count);
+		if (logo_shown >= 0)
+			goto redraw_up;
+		switch (p->scrollmode & __SCROLL_YMASK) {
+		case __SCROLL_YMOVE:
+			accel_bmove(p, t + count, 0, t, 0,
+					 b - t - count, vc->vc_cols);
+			accel_clear(vc, p, b - count, 0, count,
+					 vc->vc_cols);
+			break;
+
+		case __SCROLL_YWRAP:
+			if (b - t - count > 3 * vc->vc_rows >> 2) {
+				if (t > 0)
+					fbcon_bmove(vc, 0, 0, count, 0, t,
+						    vc->vc_cols);
+				ywrap_up(p, vc, count);
+				if (vc->vc_rows - b > 0)
+					fbcon_bmove(vc, b - count, 0, b, 0,
+						    vc->vc_rows - b,
+						    vc->vc_cols);
+			} else if (p->scrollmode & __SCROLL_YPANREDRAW)
+				goto redraw_up;
+			else
+				fbcon_bmove(vc, t + count, 0, t, 0,
+					    b - t - count, vc->vc_cols);
+			fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
+			break;
+
+		case __SCROLL_YPAN:
+			if ((p->yscroll + count <=
+			     2 * (p->vrows - vc->vc_rows))
+			    && ((!scroll_partial && (b - t == vc->vc_rows))
+				|| (scroll_partial
+				    && (b - t - count >
+					3 * vc->vc_rows >> 2)))) {
+				if (t > 0)
+					fbcon_bmove(vc, 0, 0, count, 0, t,
+						    vc->vc_cols);
+				ypan_up(p, vc, count);
+				if (vc->vc_rows - b > 0)
+					fbcon_bmove(vc, b - count, 0, b, 0,
+						    vc->vc_rows - b,
+						    vc->vc_cols);
+			} else if (p->scrollmode & __SCROLL_YPANREDRAW)
+				goto redraw_up;
+			else
+				fbcon_bmove(vc, t + count, 0, t, 0,
+					    b - t - count, vc->vc_cols);
+			fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
+			break;
+
+		case __SCROLL_YREDRAW:
+		      redraw_up:
+			fbcon_redraw(vc, p, t, b - t - count,
+				     count * vc->vc_cols);
+			accel_clear(vc, p, real_y(p, b - count), 0,
+					 count, vc->vc_cols);
+			scr_memsetw((unsigned short *) (vc->vc_origin +
+							vc->vc_size_row *
+							(b - count)),
+				    vc->vc_video_erase_char,
+				    vc->vc_size_row * count);
+			return 1;
+		}
+		break;
+
+	case SM_DOWN:
+		if (count > vc->vc_rows)	/* Maximum realistic size */
+			count = vc->vc_rows;
+		switch (p->scrollmode & __SCROLL_YMASK) {
+		case __SCROLL_YMOVE:
+			accel_bmove(p, t, 0, t + count, 0,
+					 b - t - count, vc->vc_cols);
+			accel_clear(vc, p, t, 0, count, vc->vc_cols);
+			break;
+
+		case __SCROLL_YWRAP:
+			if (b - t - count > 3 * vc->vc_rows >> 2) {
+				if (vc->vc_rows - b > 0)
+					fbcon_bmove(vc, b, 0, b - count, 0,
+						    vc->vc_rows - b,
+						    vc->vc_cols);
+				ywrap_down(p, vc, count);
+				if (t > 0)
+					fbcon_bmove(vc, count, 0, 0, 0, t,
+						    vc->vc_cols);
+			} else if (p->scrollmode & __SCROLL_YPANREDRAW)
+				goto redraw_down;
+			else
+				fbcon_bmove(vc, t, 0, t + count, 0,
+					    b - t - count, vc->vc_cols);
+			fbcon_clear(vc, t, 0, count, vc->vc_cols);
+			break;
+
+		case __SCROLL_YPAN:
+			if ((count - p->yscroll <= p->vrows - vc->vc_rows)
+			    && ((!scroll_partial && (b - t == vc->vc_rows))
+				|| (scroll_partial
+				    && (b - t - count >
+					3 * vc->vc_rows >> 2)))) {
+				if (vc->vc_rows - b > 0)
+					fbcon_bmove(vc, b, 0, b - count, 0,
+						    vc->vc_rows - b,
+						    vc->vc_cols);
+				ypan_down(p, vc, count);
+				if (t > 0)
+					fbcon_bmove(vc, count, 0, 0, 0, t,
+						    vc->vc_cols);
+			} else if (p->scrollmode & __SCROLL_YPANREDRAW)
+				goto redraw_down;
+			else
+				fbcon_bmove(vc, t, 0, t + count, 0,
+					    b - t - count, vc->vc_cols);
+			fbcon_clear(vc, t, 0, count, vc->vc_cols);
+			break;
+
+		case __SCROLL_YREDRAW:
+		      redraw_down:
+			fbcon_redraw(vc, p, b - 1, b - t - count,
+				     -count * vc->vc_cols);
+			accel_clear(vc, p, real_y(p, t), 0, count,
+					 vc->vc_cols);
+			scr_memsetw((unsigned short *) (vc->vc_origin +
+							vc->vc_size_row *
+							t),
+				    vc->vc_video_erase_char,
+				    vc->vc_size_row * count);
+			return 1;
+		}
+	}
+	return 0;
+}
+
+
+static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx,
+			int height, int width)
+{
+	int unit = vc->vc_num;
+	struct display *p = &fb_display[unit];
+
+	if (!p->can_soft_blank && console_blanked)
+		return;
+
+	if (!width || !height)
+		return;
+
+	if (((sy <= p->cursor_y) && (p->cursor_y < sy + height) &&
+	     (sx <= p->cursor_x) && (p->cursor_x < sx + width)) ||
+	    ((dy <= p->cursor_y) && (p->cursor_y < dy + height) &&
+	     (dx <= p->cursor_x) && (p->cursor_x < dx + width)))
+		fbcon_cursor(vc, CM_ERASE | CM_SOFTBACK);
+
+	/*  Split blits that cross physical y_wrap case.
+	 *  Pathological case involves 4 blits, better to use recursive
+	 *  code rather than unrolled case
+	 *
+	 *  Recursive invocations don't need to erase the cursor over and
+	 *  over again, so we use fbcon_bmove_rec()
+	 */
+	fbcon_bmove_rec(p, sy, sx, dy, dx, height, width,
+			p->vrows - p->yscroll);
+}
+
+static void fbcon_bmove_rec(struct display *p, int sy, int sx, int dy,
+			    int dx, int height, int width, u_int y_break)
+{
+	u_int b;
+
+	if (sy < y_break && sy + height > y_break) {
+		b = y_break - sy;
+		if (dy < sy) {	/* Avoid trashing self */
+			fbcon_bmove_rec(p, sy, sx, dy, dx, b, width,
+					y_break);
+			fbcon_bmove_rec(p, sy + b, sx, dy + b, dx,
+					height - b, width, y_break);
+		} else {
+			fbcon_bmove_rec(p, sy + b, sx, dy + b, dx,
+					height - b, width, y_break);
+			fbcon_bmove_rec(p, sy, sx, dy, dx, b, width,
+					y_break);
+		}
+		return;
+	}
+
+	if (dy < y_break && dy + height > y_break) {
+		b = y_break - dy;
+		if (dy < sy) {	/* Avoid trashing self */
+			fbcon_bmove_rec(p, sy, sx, dy, dx, b, width,
+					y_break);
+			fbcon_bmove_rec(p, sy + b, sx, dy + b, dx,
+					height - b, width, y_break);
+		} else {
+			fbcon_bmove_rec(p, sy + b, sx, dy + b, dx,
+					height - b, width, y_break);
+			fbcon_bmove_rec(p, sy, sx, dy, dx, b, width,
+					y_break);
+		}
+		return;
+	}
+	accel_bmove(p, real_y(p, sy), sx, real_y(p, dy), dx, height,
+			 width);
+}
+
+
+static int fbcon_switch(struct vc_data *vc)
+{
+	int unit = vc->vc_num;
+	struct display *p = &fb_display[unit];
+	struct fb_info *info = p->fb_info;
+
+	if (softback_top) {
+		int l = fbcon_softback_size / vc->vc_size_row;
+		if (softback_lines)
+			fbcon_set_origin(vc);
+		softback_top = softback_curr = softback_in = softback_buf;
+		softback_lines = 0;
+
+		if (l > 5)
+			softback_end = softback_buf + l * vc->vc_size_row;
+		else {
+			/* Smaller scrollback makes no sense, and 0 would screw
+			   the operation totally */
+			softback_top = 0;
+		}
+	}
+	if (logo_shown >= 0) {
+		struct vc_data *conp2 = vc_cons[logo_shown].d;
+
+		if (conp2->vc_top == logo_lines
+		    && conp2->vc_bottom == conp2->vc_rows)
+			conp2->vc_top = 0;
+		logo_shown = -1;
+	}
+	if (info)
+		info->var.yoffset = p->yscroll = 0;
+	switch (p->scrollmode & __SCROLL_YMASK) {
+	case __SCROLL_YWRAP:
+		scrollback_phys_max = p->vrows - vc->vc_rows;
+		break;
+	case __SCROLL_YPAN:
+		scrollback_phys_max = p->vrows - 2 * vc->vc_rows;
+		if (scrollback_phys_max < 0)
+			scrollback_phys_max = 0;
+		break;
+	default:
+		scrollback_phys_max = 0;
+		break;
+	}
+	scrollback_max = 0;
+	scrollback_current = 0;
+
+	info->currcon = unit;
+	
+	update_var(unit, info);
+	
+	if (vt_cons[unit]->vc_mode == KD_TEXT)
+		accel_clear_margins(vc, p, 0);
+	if (logo_shown == -2) {
+		logo_shown = fg_console;
+		fbcon_show_logo();	/* This is protected above by initmem_freed */
+		update_region(fg_console,
+			      vc->vc_origin + vc->vc_size_row * vc->vc_top,
+			      vc->vc_size_row * (vc->vc_bottom -
+						 vc->vc_top) / 2);
+		return 0;
+	}
+	return 1;
+}
+
+static int fbcon_blank(struct vc_data *vc, int blank)
+{
+	struct display *p = &fb_display[vc->vc_num];
+	struct fb_info *info = p->fb_info;
+
+	if (blank < 0)		/* Entering graphics mode */
+		return 0;
+
+	fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
+
+	if (!p->can_soft_blank) {
+		if (blank) {
+			unsigned short oldc;
+			u_int height;
+			u_int y_break;
+
+			oldc = vc->vc_video_erase_char;
+			vc->vc_video_erase_char &= p->charmask;
+			height = vc->vc_rows;
+			y_break = p->vrows - p->yscroll;
+			if (height > y_break) {
+				accel_clear(vc, p,
+						 real_y(p, 0), 0,
+						 y_break,
+						 vc->vc_cols);
+				accel_clear(vc, p,
+						 real_y(p,
+						y_break),
+						0,
+						 height - y_break,
+						 vc->vc_cols);
+			} else
+				accel_clear(vc, p,
+						 real_y(p, 0), 0,
+						 height,
+						 vc->vc_cols);
+			vc->vc_video_erase_char = oldc;
+		} else
+			update_screen(vc->vc_num);
+		return 0;
+	} else
+		return fb_blank(blank, info);
+}
+
+static void fbcon_free_font(struct display *p)
+{
+	if (p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0))
+		kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int));
+	p->fontdata = NULL;
+	p->userfont = 0;
+}
+
+static inline int fbcon_get_font(struct vc_data *vc, struct console_font_op *op)
+{
+	struct display *p = &fb_display[vc->vc_num];
+	u8 *data = op->data;
+	u8 *fontdata = p->fontdata;
+	int i, j;
+
+#ifdef CONFIG_FONTWIDTH8_ONLY
+	if (fontwidth(p) != 8)
+		return -EINVAL;
+#endif
+	op->width = vc->vc_font.width;
+	op->height = vc->vc_font.height;
+	op->charcount = (p->charmask == 0x1ff) ? 512 : 256;
+	if (!op->data)
+		return 0;
+
+	if (op->width <= 8) {
+		j = vc->vc_font.height;
+		for (i = 0; i < op->charcount; i++) {
+			memcpy(data, fontdata, j);
+			memset(data + j, 0, 32 - j);
+			data += 32;
+			fontdata += j;
+		}
+	}
+#ifndef CONFIG_FONTWIDTH8_ONLY
+	else if (op->width <= 16) {
+		j = vc->vc_font.height * 2;
+		for (i = 0; i < op->charcount; i++) {
+			memcpy(data, fontdata, j);
+			memset(data + j, 0, 64 - j);
+			data += 64;
+			fontdata += j;
+		}
+	} else if (op->width <= 24) {
+		for (i = 0; i < op->charcount; i++) {
+			for (j = 0; j < vc->vc_font.height; j++) {
+				*data++ = fontdata[0];
+				*data++ = fontdata[1];
+				*data++ = fontdata[2];
+				fontdata += sizeof(u32);
+			}
+			memset(data, 0, 3 * (32 - j));
+			data += 3 * (32 - j);
+		}
+	} else {
+		j = vc->vc_font.height * 4;
+		for (i = 0; i < op->charcount; i++) {
+			memcpy(data, fontdata, j);
+			memset(data + j, 0, 128 - j);
+			data += 128;
+			fontdata += j;
+		}
+	}
+#endif
+	return 0;
+}
+
+static int fbcon_do_set_font(struct vc_data *vc, struct console_font_op *op,
+			     u8 * data, int userfont)
+{
+	struct display *p = &fb_display[vc->vc_num];
+	struct fb_info *info = p->fb_info;
+	int resize;
+	int w = op->width;
+	int h = op->height;
+	int cnt;
+	char *old_data = NULL;
+
+	if (!fontwidthvalid(p, w)) {
+		if (userfont && op->op != KD_FONT_OP_COPY)
+			kfree(data - FONT_EXTRA_WORDS * sizeof(int));
+		return -ENXIO;
+	}
+
+	if (CON_IS_VISIBLE(vc) && softback_lines)
+		fbcon_set_origin(vc);
+
+	resize = (w != vc->vc_font.width) || (h != vc->vc_font.height);
+	if (p->userfont)
+		old_data = p->fontdata;
+	if (userfont)
+		cnt = FNTCHARCNT(data);
+	else
+		cnt = 256;
+	p->fontdata = data;
+	if ((p->userfont = userfont))
+		REFCOUNT(data)++;
+	vc->vc_font.width = w;
+	vc->vc_font.height = h;
+	if (vc->vc_hi_font_mask && cnt == 256) {
+		vc->vc_hi_font_mask = 0;
+		if (vc->vc_can_do_color)
+			vc->vc_complement_mask >>= 1;
+		p->fgshift--;
+		p->bgshift--;
+		p->charmask = 0xff;
+
+		/* ++Edmund: reorder the attribute bits */
+		if (vc->vc_can_do_color) {
+			unsigned short *cp =
+			    (unsigned short *) vc->vc_origin;
+			int count = vc->vc_screenbuf_size / 2;
+			unsigned short c;
+			for (; count > 0; count--, cp++) {
+				c = scr_readw(cp);
+				scr_writew(((c & 0xfe00) >> 1) |
+					   (c & 0xff), cp);
+			}
+			c = vc->vc_video_erase_char;
+			vc->vc_video_erase_char =
+			    ((c & 0xfe00) >> 1) | (c & 0xff);
+			vc->vc_attr >>= 1;
+		}
+
+	} else if (!vc->vc_hi_font_mask && cnt == 512) {
+		vc->vc_hi_font_mask = 0x100;
+		if (vc->vc_can_do_color)
+			vc->vc_complement_mask <<= 1;
+		p->fgshift++;
+		p->bgshift++;
+		p->charmask = 0x1ff;
+
+		/* ++Edmund: reorder the attribute bits */
+		{
+			unsigned short *cp =
+			    (unsigned short *) vc->vc_origin;
+			int count = vc->vc_screenbuf_size / 2;
+			unsigned short c;
+			for (; count > 0; count--, cp++) {
+				unsigned short newc;
+				c = scr_readw(cp);
+				if (vc->vc_can_do_color)
+					newc =
+					    ((c & 0xff00) << 1) | (c &
+								   0xff);
+				else
+					newc = c & ~0x100;
+				scr_writew(newc, cp);
+			}
+			c = vc->vc_video_erase_char;
+			if (vc->vc_can_do_color) {
+				vc->vc_video_erase_char =
+				    ((c & 0xff00) << 1) | (c & 0xff);
+				vc->vc_attr <<= 1;
+			} else
+				vc->vc_video_erase_char = c & ~0x100;
+		}
+
+	}
+
+	if (resize) {
+		/* reset wrap/pan */
+		info->var.xoffset = info->var.yoffset = p->yscroll = 0;
+		p->vrows = info->var.yres_virtual / h;
+		if ((info->var.yres % h)
+		    && (info->var.yres_virtual % h < info->var.yres % h))
+			p->vrows--;
+		updatescrollmode(p, vc);
+		vc_resize(vc->vc_num, info->var.xres / w, info->var.yres / h);
+		if (CON_IS_VISIBLE(vc) && softback_buf) {
+			int l = fbcon_softback_size / vc->vc_size_row;
+			if (l > 5)
+				softback_end =
+				    softback_buf + l * vc->vc_size_row;
+			else {
+				/* Smaller scrollback makes no sense, and 0 would screw
+				   the operation totally */
+				softback_top = 0;
+			}
+		}
+	} else if (CON_IS_VISIBLE(vc)
+		   && vt_cons[vc->vc_num]->vc_mode == KD_TEXT) {
+		accel_clear_margins(vc, p, 0);
+		update_screen(vc->vc_num);
+	}
+
+	if (old_data && (--REFCOUNT(old_data) == 0))
+		kfree(old_data - FONT_EXTRA_WORDS * sizeof(int));
+	return 0;
+}
+
+static inline int fbcon_copy_font(struct vc_data *vc, struct console_font_op *op)
+{
+	struct display *od, *p = &fb_display[vc->vc_num];
+	int h = op->height;
+
+	if (h < 0 || !vc_cons_allocated(h))
+		return -ENOTTY;
+	if (h == vc->vc_num)
+		return 0;	/* nothing to do */
+	od = &fb_display[h];
+	if (od->fontdata == p->fontdata)
+		return 0;	/* already the same font... */
+	op->width = vc->vc_font.width;
+	op->height = vc->vc_font.height;
+	return fbcon_do_set_font(vc, op, od->fontdata, od->userfont);
+}
+
+static inline int fbcon_set_font(struct vc_data *vc, struct console_font_op *op)
+{
+	int w = op->width;
+	int h = op->height;
+	int size = h;
+	int i, k;
+	u8 *new_data, *data = op->data, *p;
+
+#ifdef CONFIG_FONTWIDTH8_ONLY
+	if (w != 8)
+		return -EINVAL;
+#endif
+	if ((w <= 0) || (w > 32)
+	    || (op->charcount != 256 && op->charcount != 512))
+		return -EINVAL;
+
+	if (w > 8) {
+		if (w <= 16)
+			size *= 2;
+		else
+			size *= 4;
+	}
+	size *= op->charcount;
+
+	if (!
+	    (new_data =
+	     kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size, GFP_USER)))
+		return -ENOMEM;
+	new_data += FONT_EXTRA_WORDS * sizeof(int);
+	FNTSIZE(new_data) = size;
+	FNTCHARCNT(new_data) = op->charcount;
+	REFCOUNT(new_data) = 0;	/* usage counter */
+	p = new_data;
+	if (w <= 8) {
+		for (i = 0; i < op->charcount; i++) {
+			memcpy(p, data, h);
+			data += 32;
+			p += h;
+		}
+	}
+#ifndef CONFIG_FONTWIDTH8_ONLY
+	else if (w <= 16) {
+		h *= 2;
+		for (i = 0; i < op->charcount; i++) {
+			memcpy(p, data, h);
+			data += 64;
+			p += h;
+		}
+	} else if (w <= 24) {
+		for (i = 0; i < op->charcount; i++) {
+			int j;
+			for (j = 0; j < h; j++) {
+				memcpy(p, data, 3);
+				p[3] = 0;
+				data += 3;
+				p += sizeof(u32);
+			}
+			data += 3 * (32 - h);
+		}
+	} else {
+		h *= 4;
+		for (i = 0; i < op->charcount; i++) {
+			memcpy(p, data, h);
+			data += 128;
+			p += h;
+		}
+	}
+#endif
+	/* we can do it in u32 chunks because of charcount is 256 or 512, so
+	   font length must be multiple of 256, at least. And 256 is multiple
+	   of 4 */
+	k = 0;
+	while (p > new_data)
+		k += *--(u32 *) p;
+	FNTSUM(new_data) = k;
+	/* Check if the same font is on some other console already */
+	for (i = 0; i < MAX_NR_CONSOLES; i++) {
+		struct vc_data *tmp = vc_cons[i].d;
+		
+		if (fb_display[i].userfont &&
+		    fb_display[i].fontdata &&
+		    FNTSUM(fb_display[i].fontdata) == k &&
+		    FNTSIZE(fb_display[i].fontdata) == size &&
+		    tmp->vc_font.width == w &&
+		    !memcmp(fb_display[i].fontdata, new_data, size)) {
+			kfree(new_data - FONT_EXTRA_WORDS * sizeof(int));
+			new_data = fb_display[i].fontdata;
+			break;
+		}
+	}
+	return fbcon_do_set_font(vc, op, new_data, 1);
+}
+
+static inline int fbcon_set_def_font(struct vc_data *vc, struct console_font_op *op)
+{
+	char name[MAX_FONT_NAME];
+	struct font_desc *f;
+	struct display *p = &fb_display[vc->vc_num];
+	struct fb_info *info = p->fb_info;
+
+	if (!op->data)
+		f = get_default_font(info->var.xres, info->var.yres);
+	else if (strncpy_from_user(name, op->data, MAX_FONT_NAME - 1) < 0)
+		return -EFAULT;
+	else {
+		name[MAX_FONT_NAME - 1] = 0;
+		if (!(f = find_font(name)))
+			return -ENOENT;
+	}
+	op->width = f->width;
+	op->height = f->height;
+	return fbcon_do_set_font(vc, op, f->data, 0);
+}
+
+static int fbcon_font_op(struct vc_data *vc, struct console_font_op *op)
+{
+	switch (op->op) {
+	case KD_FONT_OP_SET:
+		return fbcon_set_font(vc, op);
+	case KD_FONT_OP_GET:
+		return fbcon_get_font(vc, op);
+	case KD_FONT_OP_SET_DEFAULT:
+		return fbcon_set_def_font(vc, op);
+	case KD_FONT_OP_COPY:
+		return fbcon_copy_font(vc, op);
+	default:
+		return -ENOSYS;
+	}
+}
+
+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
+};
+
+static int fbcon_set_palette(struct vc_data *vc, unsigned char *table)
+{
+	int unit = vc->vc_num;
+	struct display *p = &fb_display[unit];
+	struct fb_info *info = p->fb_info;
+	int i, j, k;
+	u8 val;
+
+	if (!vc->vc_can_do_color
+	    || (!p->can_soft_blank && console_blanked))
+		return -EINVAL;
+	for (i = j = 0; i < 16; i++) {
+		k = table[i];
+		val = vc->vc_palette[j++];
+		palette_red[k] = (val << 8) | val;
+		val = vc->vc_palette[j++];
+		palette_green[k] = (val << 8) | val;
+		val = vc->vc_palette[j++];
+		palette_blue[k] = (val << 8) | val;
+	}
+	if (info->var.bits_per_pixel <= 4)
+		palette_cmap.len = 1 << info->var.bits_per_pixel;
+	else
+		palette_cmap.len = 16;
+	palette_cmap.start = 0;
+	return fb_set_cmap(&palette_cmap, 1, info);
+}
+
+static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
+{
+	int line;
+	unsigned long p;
+
+	if (vc->vc_num != fg_console || !softback_lines)
+		return (u16 *) (vc->vc_origin + offset);
+	line = offset / vc->vc_size_row;
+	if (line >= softback_lines)
+		return (u16 *) (vc->vc_origin + offset -
+				softback_lines * vc->vc_size_row);
+	p = softback_curr + offset;
+	if (p >= softback_end)
+		p += softback_buf - softback_end;
+	return (u16 *) p;
+}
+
+static unsigned long fbcon_getxy(struct vc_data *vc, unsigned long pos,
+				 int *px, int *py)
+{
+	int x, y;
+	unsigned long ret;
+	if (pos >= vc->vc_origin && pos < vc->vc_scr_end) {
+		unsigned long offset = (pos - vc->vc_origin) / 2;
+
+		x = offset % vc->vc_cols;
+		y = offset / vc->vc_cols;
+		if (vc->vc_num == fg_console)
+			y += softback_lines;
+		ret = pos + (vc->vc_cols - x) * 2;
+	} else if (vc->vc_num == fg_console && softback_lines) {
+		unsigned long offset = pos - softback_curr;
+
+		if (pos < softback_curr)
+			offset += softback_end - softback_buf;
+		offset /= 2;
+		x = offset % vc->vc_cols;
+		y = offset / vc->vc_cols;
+		ret = pos + (vc->vc_cols - x) * 2;
+		if (ret == softback_end)
+			ret = softback_buf;
+		if (ret == softback_in)
+			ret = vc->vc_origin;
+	} else {
+		/* Should not happen */
+		x = y = 0;
+		ret = vc->vc_origin;
+	}
+	if (px)
+		*px = x;
+	if (py)
+		*py = y;
+	return ret;
+}
+
+/* As we might be inside of softback, we may work with non-contiguous buffer,
+   that's why we have to use a separate routine. */
+static void fbcon_invert_region(struct vc_data *vc, u16 * p, int cnt)
+{
+	while (cnt--) {
+		u16 a = scr_readw(p);
+		if (!vc->vc_can_do_color)
+			a ^= 0x0800;
+		else if (vc->vc_hi_font_mask == 0x100)
+			a = ((a) & 0x11ff) | (((a) & 0xe000) >> 4) |
+			    (((a) & 0x0e00) << 4);
+		else
+			a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) |
+			    (((a) & 0x0700) << 4);
+		scr_writew(a, p++);
+		if (p == (u16 *) softback_end)
+			p = (u16 *) softback_buf;
+		if (p == (u16 *) softback_in)
+			p = (u16 *) vc->vc_origin;
+	}
+}
+
+static int fbcon_scrolldelta(struct vc_data *vc, int lines)
+{
+	int unit, offset, limit, scrollback_old;
+	struct fb_info *info;
+	struct display *p;
+
+	unit = fg_console;
+	p = &fb_display[unit];
+	info = p->fb_info;
+
+	if (softback_top) {
+		if (vc->vc_num != unit)
+			return 0;
+		if (vt_cons[unit]->vc_mode != KD_TEXT || !lines)
+			return 0;
+		if (logo_shown >= 0) {
+			struct vc_data *conp2 = vc_cons[logo_shown].d;
+
+			if (conp2->vc_top == logo_lines
+			    && conp2->vc_bottom == conp2->vc_rows)
+				conp2->vc_top = 0;
+			if (logo_shown == unit) {
+				unsigned long p, q;
+				int i;
+
+				p = softback_in;
+				q = vc->vc_origin +
+				    logo_lines * vc->vc_size_row;
+				for (i = 0; i < logo_lines; i++) {
+					if (p == softback_top)
+						break;
+					if (p == softback_buf)
+						p = softback_end;
+					p -= vc->vc_size_row;
+					q -= vc->vc_size_row;
+					scr_memcpyw((u16 *) q, (u16 *) p,
+						    vc->vc_size_row);
+				}
+				softback_in = p;
+				update_region(unit, vc->vc_origin,
+					      logo_lines * vc->vc_cols);
+			}
+			logo_shown = -1;
+		}
+		fbcon_cursor(vc, CM_ERASE | CM_SOFTBACK);
+		fbcon_redraw_softback(vc, p, lines);
+		fbcon_cursor(vc, CM_DRAW | CM_SOFTBACK);
+		return 0;
+	}
+
+	if (!scrollback_phys_max)
+		return -ENOSYS;
+
+	scrollback_old = scrollback_current;
+	scrollback_current -= lines;
+	if (scrollback_current < 0)
+		scrollback_current = 0;
+	else if (scrollback_current > scrollback_max)
+		scrollback_current = scrollback_max;
+	if (scrollback_current == scrollback_old)
+		return 0;
+
+	if (!p->can_soft_blank &&
+	    (console_blanked || vt_cons[unit]->vc_mode != KD_TEXT
+	     || !lines))
+		return 0;
+	fbcon_cursor(vc, CM_ERASE);
+
+	offset = p->yscroll - scrollback_current;
+	limit = p->vrows;
+	switch (p->scrollmode && __SCROLL_YMASK) {
+	case __SCROLL_YWRAP:
+		info->var.vmode |= FB_VMODE_YWRAP;
+		break;
+	case __SCROLL_YPAN:
+		limit -= vc->vc_rows;
+		info->var.vmode &= ~FB_VMODE_YWRAP;
+		break;
+	}
+	if (offset < 0)
+		offset += limit;
+	else if (offset >= limit)
+		offset -= limit;
+	info->var.xoffset = 0;
+	info->var.yoffset = offset * vc->vc_font.height;
+	update_var(unit, info);
+	if (!scrollback_current)
+		fbcon_cursor(vc, CM_DRAW);
+	return 0;
+}
+
+static int fbcon_set_origin(struct vc_data *vc)
+{
+	if (softback_lines && !console_blanked)
+		fbcon_scrolldelta(vc, softback_lines);
+	return 0;
+}
+
+static inline unsigned safe_shift(unsigned d, int n)
+{
+	return n < 0 ? d >> -n : d << n;
+}
+
+static void __init fbcon_set_logocmap(struct fb_info *info)
+{
+	int i, j, n;
+
+	for (i = 0; i < LINUX_LOGO_COLORS; i += n) {
+		n = LINUX_LOGO_COLORS - i;
+		if (n > 16)
+			/* palette_cmap provides space for only 16 colors at once */
+			n = 16;
+		palette_cmap.start = 32 + i;
+		palette_cmap.len = n;
+		for (j = 0; j < n; ++j) {
+			palette_cmap.red[j] =
+				(linux_logo_red[i + j] << 8) |
+				linux_logo_red[i + j];
+			palette_cmap.green[j] =
+				(linux_logo_green[i + j] << 8) |
+				linux_logo_green[i + j];
+			palette_cmap.blue[j] =
+				(linux_logo_blue[i + j] << 8) |
+				linux_logo_blue[i + j];
+		}
+		fb_set_cmap(&palette_cmap, 1, info);
+	}
+}
+
+static void  __init fbcon_set_logo_truepalette(struct fb_info *info, u32 *palette)
+{
+	unsigned char mask[9] = { 0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff };
+	unsigned char redmask, greenmask, bluemask;
+	int redshift, greenshift, blueshift;
+	int i;
+	
+	/*
+	 * We have to create a temporary palette since console palette is only
+	 * 16 colors long.
+	 */
+	/* Bug: Doesn't obey msb_right ... (who needs that?) */
+	redmask   = mask[info->var.red.length   < 8 ? info->var.red.length   : 8];
+	greenmask = mask[info->var.green.length < 8 ? info->var.green.length : 8];
+	bluemask  = mask[info->var.blue.length  < 8 ? info->var.blue.length  : 8];
+	redshift   = info->var.red.offset   - (8 - info->var.red.length);
+	greenshift = info->var.green.offset - (8 - info->var.green.length);
+	blueshift  = info->var.blue.offset  - (8 - info->var.blue.length);
+	
+	
+	for ( i = 0; i < LINUX_LOGO_COLORS; i++) {
+		palette[i+32] = (safe_shift((linux_logo_red[i]   & redmask), redshift) |
+				 safe_shift((linux_logo_green[i] & greenmask), greenshift) |
+				 safe_shift((linux_logo_blue[i]  & bluemask), blueshift));
+	}
+}
+
+static void __init fbcon_set_logo_directpalette(struct fb_info *info, u32 *palette)
+{
+	int redshift, greenshift, blueshift;
+	int i;
+
+	redshift = info->var.red.offset;
+	greenshift = info->var.green.offset;
+	blueshift = info->var.blue.offset;
+	
+	for (i = 32; i < LINUX_LOGO_COLORS; i++) 
+		palette[i] = i << redshift | i << greenshift | i << blueshift;
+
+}
+	
+static void __init fbcon_set_logo(struct fb_info *info, u8 *logo, int needs_logo)
+{
+	int i, j;
+
+	switch (needs_logo) {
+	case 4:
+		for (i = 0; i < (LOGO_W * LOGO_H)/2; i++) {
+			logo[i*2] = linux_logo16[i] >> 4;
+			logo[(i*2)+1] = linux_logo16[i] & 0xf;
+		}
+		break;
+	case 1:
+	case ~1:
+	default:
+		for (i = 0; i < (LOGO_W * LOGO_H)/8; i++) 
+			for (j = 0; j < 8; j++) 
+				logo[i*2] = (linux_logo_bw[i] &  (7 - j)) ? 
+					((needs_logo == 1) ? 1 : 0) :
+					((needs_logo == 1) ? 0 : 1);
+				
+		break;
+	} 
+}	
+	
+/*
+ * Three (3) kinds of logo maps exist.  linux_logo (>16 colors), linux_logo_16 
+ * (16 colors) and linux_logo_bw (2 colors).  Depending on the visual format and
+ * color depth of the framebuffer, the DAC, the pseudo_palette, and the logo data
+ * will be adjusted accordingly.
+ *
+ * Case 1 - linux_logo:
+ * Color exceeds the number of console colors (16), thus we set the hardware DAC 
+ * using fb_set_cmap() appropriately.  The "needs_cmapreset"  flag will be set. 
+ *
+ * For visuals that require color info from the pseudo_palette, we also construct
+ * one for temporary use. The "needs_directpalette" or "needs_truepalette" flags
+ * will be set.
+ *
+ * Case 2 - linux_logo_16:
+ * The number of colors just matches the console colors, thus there is no need
+ * to set the DAC or the pseudo_palette.  However, the bitmap is packed, ie, 
+ * each byte contains color information for two pixels (upper and lower nibble).  
+ * To be consistent with fb_imageblit() usage, we therefore separate the two 
+ * nibbles into separate bytes. The "needs_logo" flag will be set to 4.
+ *
+ * Case 3 - linux_logo_bw:
+ * This is similar with Case 2.  Each byte contains information for 8 pixels.
+ * We isolate each bit and expand each into a byte. The "needs_logo" flag will
+ * be set to 1.
+ */
+static int __init fbcon_show_logo(void)
+	{
+		struct display *p = &fb_display[fg_console];	/* draw to vt in foreground */
+	struct fb_info *info = p->fb_info;
+	struct vc_data *vc = info->display_fg;
+	struct fb_image image;
+	u32 *palette = NULL, *saved_palette = NULL;
+	unsigned char *fb = info->screen_base, *logo_new = NULL;
+	int done = 0, x;
+	int needs_cmapreset = 0;
+	int needs_truepalette = 0;
+	int needs_directpalette = 0;
+	int needs_logo = 0;
+
+	/* Return if the frame buffer is not mapped */
+	if (!fb || !info->fbops->fb_imageblit)
+		return 0;
+
+	image.depth = info->var.bits_per_pixel;
+
+	/* reasonable default */
+	if (image.depth >= 8)
+		image.data = linux_logo;
+	else if (image.depth >= 4) 
+		image.data = linux_logo16;
+	else 
+		image.data = linux_logo_bw;
+
+	switch (info->fix.visual) {
+	case FB_VISUAL_TRUECOLOR:
+		needs_truepalette = 1;
+		if (image.depth >= 4 && image.depth <= 8)
+			needs_logo = 4;
+		else if (image.depth < 4)
+			needs_logo = 1;
+		break;
+	case FB_VISUAL_DIRECTCOLOR:
+		if (image.depth >= 24) {
+			needs_directpalette = 1;
+			needs_cmapreset = 1;
+		}
+		/* 16 colors */
+		else if (image.depth >= 16)
+			needs_logo = 4;
+		/* 2 colors */
+		else
+			needs_logo = 1;
+		break;
+	case FB_VISUAL_MONO01:
+		/* reversed 0 = fg, 1 = bg */
+		needs_logo = ~1;
+		break;
+	case FB_VISUAL_MONO10:
+		needs_logo = 1;
+		break;
+	case FB_VISUAL_PSEUDOCOLOR:
+	default:
+		if (image.depth >= 8)
+			needs_cmapreset = 1;
+		/* fall through */
+	case FB_VISUAL_STATIC_PSEUDOCOLOR:
+		/* 16 colors */
+		if (image.depth >= 4 && image.depth < 8)
+			needs_logo = 4;
+		/* 2 colors */
+		else if (image.depth < 4)
+			needs_logo = 1;
+		break;
+	}		    
+	
+	if (needs_cmapreset) 
+		fbcon_set_logocmap(info);
+	
+	if (needs_truepalette || needs_directpalette) {
+		palette = kmalloc(256 * 4, GFP_KERNEL);
+		if (palette == NULL)
+			return 1;
+
+		if (needs_truepalette)
+			fbcon_set_logo_truepalette(info, palette);
+		else
+			fbcon_set_logo_directpalette(info, palette);
+
+		saved_palette = info->pseudo_palette;
+		info->pseudo_palette = palette;
+	}
+	
+	if (needs_logo) {
+		logo_new = kmalloc(LOGO_W * LOGO_H, GFP_KERNEL);
+		if (logo_new == NULL) {
+			if (palette)
+				kfree(palette);
+			if (saved_palette)
+				info->pseudo_palette = saved_palette;
+			return 1;
+		}
+
+		image.data = logo_new;
+		fbcon_set_logo(info, logo_new, needs_logo);
+	}
+
+	image.width = LOGO_W;
+	image.height = LOGO_H;
+	image.dy = 0;
+
+	for (x = 0; x < num_online_cpus() * (LOGO_W + 8) &&
+	     x < info->var.xres - (LOGO_W + 8); x += (LOGO_W + 8)) {
+		image.dx = x;
+		info->fbops->fb_imageblit(info, &image);
+		done = 1;
+	}
+
+	if (palette != NULL)
+		kfree(palette);
+	if (saved_palette != NULL)
+		info->pseudo_palette = saved_palette;
+	if (logo_new != NULL)
+		kfree(logo_new);
+	/* 
+	 * Modes not yet supported: packed pixels with depth != 8 (does such a
+	 * thing exist in reality?) 
+	 */
+	return done ? (LOGO_H + vc->vc_font.height - 1) / vc->vc_font.height : 0;
+}
+
+/*
+ *  The console `switch' structure for the frame buffer based console
+ */
+
+const struct consw fb_con = {
+	.con_startup 		= fbcon_startup,
+	.con_init 		= fbcon_init,
+	.con_deinit 		= fbcon_deinit,
+	.con_clear 		= fbcon_clear,
+	.con_putc 		= fbcon_putc,
+	.con_putcs 		= fbcon_putcs,
+	.con_cursor 		= fbcon_cursor,
+	.con_scroll 		= fbcon_scroll,
+	.con_bmove 		= fbcon_bmove,
+	.con_switch 		= fbcon_switch,
+	.con_blank 		= fbcon_blank,
+	.con_font_op 		= fbcon_font_op,
+	.con_set_palette 	= fbcon_set_palette,
+	.con_scrolldelta 	= fbcon_scrolldelta,
+	.con_set_origin 	= fbcon_set_origin,
+	.con_invert_region 	= fbcon_invert_region,
+	.con_screen_pos 	= fbcon_screen_pos,
+	.con_getxy 		= fbcon_getxy,
+};
+
+int __init fb_console_init(void)
+{
+	if (!num_registered_fb)
+		return -ENODEV;
+	take_over_console(&fb_con, first_fb_vc, last_fb_vc, fbcon_is_default);
+	__unsafe(THIS_MODULE);
+	return 0;
+}
+
+void __exit fb_console_exit(void)
+{
+	give_up_console(&fb_con);
+}	
+
+module_init(fb_console_init);
+module_exit(fb_console_exit);
+
+/*
+ *  Visible symbols for modules
+ */
+
+EXPORT_SYMBOL(fb_display);
+EXPORT_SYMBOL(fbcon_redraw_bmove);
+EXPORT_SYMBOL(fbcon_redraw_clear);
+EXPORT_SYMBOL(fb_con);
+
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/fbcon.h	Mon Dec  9 18:46:50 2002
@@ -0,0 +1,142 @@
+/*
+ *  linux/drivers/video/console/fbcon.h -- Low level frame buffer based console driver
+ *
+ *	Copyright (C) 1997 Geert Uytterhoeven
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive
+ *  for more details.
+ */
+
+#ifndef _VIDEO_FBCON_H
+#define _VIDEO_FBCON_H
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/vt_buffer.h>
+#include <linux/vt_kern.h>
+
+#include <asm/io.h>
+
+   /*
+    *    This is the interface between the low-level console driver and the
+    *    low-level frame buffer device
+    */
+
+struct display {
+    /* Filled in by the frame buffer device */
+    u_short can_soft_blank;         /* zero if no hardware blanking */
+    u_short inverse;                /* != 0 text black on white as default */
+    struct display_switch *dispsw;  /* low level operations */
+
+    /* Filled in by the low-level console driver */
+    struct vc_data *conp;           /* pointer to console data */
+    struct fb_info *fb_info;        /* frame buffer for this console */
+    int vrows;                      /* number of virtual rows */
+    unsigned short cursor_x;        /* current cursor position */
+    unsigned short cursor_y;
+    unsigned long cursor_pos;
+    char fontname[40];              /* Font associated to this display */	
+    u_char *fontdata;
+    int userfont;                   /* != 0 if fontdata kmalloc()ed */
+    u_short scrollmode;             /* Scroll Method */
+    short yscroll;                  /* Hardware scrolling */
+    unsigned char fgshift, bgshift;
+    unsigned short charmask;        /* 0xff or 0x1ff */
+    unsigned int fontwidthmask;      /* 1 at (1 << (width - 1)) if width is supported */
+};
+
+/* drivers/video/console/fbcon.c */
+extern struct display fb_display[MAX_NR_CONSOLES];
+extern char con2fb_map[MAX_NR_CONSOLES];
+extern void set_con2fb_map(int unit, int newidx);
+
+#define fontheight(p) ((p)->_fontheight)
+
+#ifdef CONFIG_FONTWIDTH8_ONLY
+
+/* fontwidth w is supported by dispsw */
+#define FONTWIDTH(w)	(1 << ((8) - 1))
+/* fontwidths w1-w2 inclusive are supported by dispsw */
+#define FONTWIDTHRANGE(w1,w2)	FONTWIDTH(8)
+
+#define fontwidth(p) (8)
+
+#else
+
+/* fontwidth w is supported by dispsw */
+#define FONTWIDTH(w)	(1 << ((w) - 1))
+/* fontwidths w1-w2 inclusive are supported by dispsw */
+#define FONTWIDTHRANGE(w1,w2)	(FONTWIDTH(w2+1) - FONTWIDTH(w1))
+
+#define fontwidth(p) ((p)->_fontwidth)
+
+#endif
+
+    /*
+     *  Attribute Decoding
+     */
+
+/* Color */
+#define attr_fgcol(p,s)    \
+	(((s) >> ((p)->fgshift)) & 0x0f)
+#define attr_bgcol(p,s)    \
+	(((s) >> ((p)->bgshift)) & 0x0f)
+#define	attr_bgcol_ec(p,conp) \
+	((conp) ? (((conp)->vc_video_erase_char >> ((p)->bgshift)) & 0x0f) : 0)
+#define attr_fgcol_ec(p,vc) \
+	((vc) ? (((vc)->vc_video_erase_char >> ((p)->fgshift)) & 0x0f) : 0)
+
+/* Monochrome */
+#define attr_bold(p,s) \
+	((s) & 0x200)
+#define attr_reverse(p,s) \
+	(((s) & 0x800) ^ ((p)->inverse ? 0x800 : 0))
+#define attr_underline(p,s) \
+	((s) & 0x400)
+#define attr_blink(p,s) \
+	((s) & 0x8000)
+	
+    /*
+     *  Scroll Method
+     */
+     
+/* Internal flags */
+#define __SCROLL_YPAN		0x001
+#define __SCROLL_YWRAP		0x002
+#define __SCROLL_YMOVE		0x003
+#define __SCROLL_YREDRAW	0x004
+#define __SCROLL_YMASK		0x00f
+#define __SCROLL_YFIXED		0x010
+#define __SCROLL_YNOMOVE	0x020
+#define __SCROLL_YPANREDRAW	0x040
+#define __SCROLL_YNOPARTIAL	0x080
+
+/* Only these should be used by the drivers */
+/* Which one should you use? If you have a fast card and slow bus,
+   then probably just 0 to indicate fbcon should choose between
+   YWRAP/YPAN+MOVE/YMOVE. On the other side, if you have a fast bus
+   and even better if your card can do fonting (1->8/32bit painting),
+   you should consider either SCROLL_YREDRAW (if your card is
+   able to do neither YPAN/YWRAP), or SCROLL_YNOMOVE.
+   The best is to test it with some real life scrolling (usually, not
+   all lines on the screen are filled completely with non-space characters,
+   and REDRAW performs much better on such lines, so don't cat a file
+   with every line covering all screen columns, it would not be the right
+   benchmark).
+ */
+#define SCROLL_YREDRAW		(__SCROLL_YFIXED|__SCROLL_YREDRAW)
+#define SCROLL_YNOMOVE		(__SCROLL_YNOMOVE|__SCROLL_YPANREDRAW)
+
+/* SCROLL_YNOPARTIAL, used in combination with the above, is for video
+   cards which can not handle using panning to scroll a portion of the
+   screen without excessive flicker.  Panning will only be used for
+   whole screens.
+ */
+/* Namespace consistency */
+#define SCROLL_YNOPARTIAL	__SCROLL_YNOPARTIAL
+
+extern void fbcon_redraw_clear(struct vc_data *, struct display *, int, int, int, int);
+extern void fbcon_redraw_bmove(struct vc_data *, struct display *, int, int, int, int, int, int);
+
+#endif /* _VIDEO_FBCON_H */
diff -Nru a/drivers/video/console/font.h b/drivers/video/console/font.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/font.h	Mon Dec  9 18:46:36 2002
@@ -0,0 +1,53 @@
+/*
+ *  font.h -- `Soft' font definitions
+ *
+ *  Created 1995 by Geert Uytterhoeven
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive
+ *  for more details.
+ */
+
+#ifndef _VIDEO_FONT_H
+#define _VIDEO_FONT_H
+
+#include <linux/types.h>
+
+struct font_desc {
+    int idx;
+    char *name;
+    int width, height;
+    void *data;
+    int pref;
+};
+
+#define VGA8x8_IDX	0
+#define VGA8x16_IDX	1
+#define PEARL8x8_IDX	2
+#define VGA6x11_IDX	3
+#define SUN8x16_IDX	4
+#define SUN12x22_IDX	5
+#define ACORN8x8_IDX	6
+#define	MINI4x6_IDX	7
+
+extern struct font_desc	font_vga_8x8,
+			font_vga_8x16,
+			font_pearl_8x8,
+			font_vga_6x11,
+			font_sun_8x16,
+			font_sun_12x22,
+			font_acorn_8x8,
+			font_mini_4x6;
+
+/* Find a font with a specific name */
+
+extern struct font_desc *find_font(char *name);
+
+/* Get the default font for a specific screen size */
+
+extern struct font_desc *get_default_font(int xres, int yres);
+
+/* Max. length for the name of a predefined font */
+#define MAX_FONT_NAME	32
+
+#endif /* _VIDEO_FONT_H */
diff -Nru a/drivers/video/console/font_6x11.c b/drivers/video/console/font_6x11.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/font_6x11.c	Mon Dec  9 18:46:34 2002
@@ -0,0 +1,3351 @@
+/**********************************************/
+/*                                            */
+/*       Font file generated by rthelen       */
+/*                                            */
+/**********************************************/
+
+#include "font.h"
+
+#define FONTDATAMAX (11*256)
+
+static unsigned char fontdata_6x11[FONTDATAMAX] = {
+
+	/* 0 0x00 '^A' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 1 0x01 '^B' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 2 0x02 '^C' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 3 0x03 '^D' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 4 0x04 '^E' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 5 0x05 '^F' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 6 0x06 '^G' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 7 0x07 '^H' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 8 0x08 '^I' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 9 0x09 '^J' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 10 0x0a '^K' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 11 0x0b '^L' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 12 0x0c '^M' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 13 0x0d '^N' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 14 0x0e '^O' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 15 0x0f '^P' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 16 0x10 '^Q' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 17 0x11 '^R' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x28, /* 00 0 000 */
+	0x54, /* 0 0 0 00 */
+	0x38, /* 00   000 */
+	0x54, /* 0 0 0 00 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 18 0x12 '^S' */
+	0x04, /* 00000 00 */
+	0x04, /* 00000 00 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x50, /* 0 0 0000 */
+	0x50, /* 0 0 0000 */
+	0x20, /* 00 00000 */
+	0x20, /* 00 00000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 19 0x13 '^T' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x38, /* 00   000 */
+	0x7c, /* 0     00 */
+	0x38, /* 00   000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 20 0x14 '^U' */
+	0x18, /* 000  000 */
+	0x10, /* 000 0000 */
+	0x28, /* 00 0 000 */
+	0x7c, /* 0     00 */
+	0x78, /* 0    000 */
+	0x78, /* 0    000 */
+	0x7c, /* 0     00 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 21 0x15 '^V' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 22 0x16 '^W' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 23 0x17 '^X' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 24 0x18 '^Y' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 25 0x19 '^Z' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 26 0x1a '^[' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 27 0x1b '^\' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 28 0x1c '^]' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 29 0x1d '^^' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 30 0x1e '^_' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 31 0x1f '^`' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 32 0x20 ' ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 33 0x21 '!' */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 34 0x22 '"' */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 35 0x23 '#' */
+	0x00, /* 00000000 */
+	0x28, /* 00 0 000 */
+	0x7c, /* 0     00 */
+	0x28, /* 00 0 000 */
+	0x7c, /* 0     00 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 36 0x24 '$' */
+	0x10, /* 000 0000 */
+	0x38, /* 00   000 */
+	0x54, /* 0 0 0 00 */
+	0x50, /* 0 0 0000 */
+	0x38, /* 00   000 */
+	0x14, /* 000 0 00 */
+	0x54, /* 0 0 0 00 */
+	0x38, /* 00   000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 37 0x25 '%' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x54, /* 0 0 0 00 */
+	0x58, /* 0 0  000 */
+	0x28, /* 00 0 000 */
+	0x34, /* 00  0 00 */
+	0x54, /* 0 0 0 00 */
+	0x48, /* 0 00 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 38 0x26 '&' */
+	0x00, /* 00000000 */
+	0x30, /* 00  0000 */
+	0x48, /* 0 00 000 */
+	0x50, /* 0 0 0000 */
+	0x20, /* 00 00000 */
+	0x54, /* 0 0 0 00 */
+	0x48, /* 0 00 000 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 39 0x27 ''' */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 40 0x28 '(' */
+	0x04, /* 00000 00 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x04, /* 00000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 41 0x29 ')' */
+	0x20, /* 00 00000 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 42 0x2a '*' */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x54, /* 0 0 0 00 */
+	0x38, /* 00   000 */
+	0x54, /* 0 0 0 00 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 43 0x2b '+' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x7c, /* 0     00 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 44 0x2c ',' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x30, /* 00  0000 */
+	0x30, /* 00  0000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x00, /* 00000000 */
+
+	/* 45 0x2d '-' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 46 0x2e '.' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 000  000 */
+	0x18, /* 000  000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 47 0x2f '/' */
+	0x04, /* 00000 00 */
+	0x04, /* 00000 00 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x20, /* 00 00000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x00, /* 00000000 */
+
+	/* 48 0x30 '0' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x54, /* 0 0 0 00 */
+	0x64, /* 0  00 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 49 0x31 '1' */
+	0x00, /* 00000000 */
+	0x08, /* 0000 000 */
+	0x18, /* 000  000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x1c, /* 000   00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 50 0x32 '2' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x04, /* 00000 00 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 51 0x33 '3' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x04, /* 00000 00 */
+	0x18, /* 000  000 */
+	0x04, /* 00000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 52 0x34 '4' */
+	0x00, /* 00000000 */
+	0x08, /* 0000 000 */
+	0x18, /* 000  000 */
+	0x28, /* 00 0 000 */
+	0x48, /* 0 00 000 */
+	0x7c, /* 0     00 */
+	0x08, /* 0000 000 */
+	0x1c, /* 000   00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 53 0x35 '5' */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x40, /* 0 000000 */
+	0x78, /* 0    000 */
+	0x04, /* 00000 00 */
+	0x04, /* 00000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 54 0x36 '6' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x40, /* 0 000000 */
+	0x78, /* 0    000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 55 0x37 '7' */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x04, /* 00000 00 */
+	0x04, /* 00000 00 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 56 0x38 '8' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 57 0x39 '9' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x3c, /* 00    00 */
+	0x04, /* 00000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 58 0x3a ':' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 000  000 */
+	0x18, /* 000  000 */
+	0x00, /* 00000000 */
+	0x18, /* 000  000 */
+	0x18, /* 000  000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 59 0x3b ';' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x30, /* 00  0000 */
+	0x30, /* 00  0000 */
+	0x00, /* 00000000 */
+	0x30, /* 00  0000 */
+	0x30, /* 00  0000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x00, /* 00000000 */
+
+	/* 60 0x3c '<' */
+	0x00, /* 00000000 */
+	0x04, /* 00000 00 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x04, /* 00000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 61 0x3d '=' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 62 0x3e '>' */
+	0x00, /* 00000000 */
+	0x20, /* 00 00000 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x04, /* 00000 00 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 63 0x3f '?' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x04, /* 00000 00 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 64 0x40 '@' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x74, /* 0   0 00 */
+	0x54, /* 0 0 0 00 */
+	0x78, /* 0    000 */
+	0x40, /* 0 000000 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 65 0x41 'A' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 66 0x42 'B' */
+	0x00, /* 00000000 */
+	0x78, /* 0    000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x78, /* 0    000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x78, /* 0    000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 67 0x43 'C' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 68 0x44 'D' */
+	0x00, /* 00000000 */
+	0x78, /* 0    000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x78, /* 0    000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 69 0x45 'E' */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x78, /* 0    000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 70 0x46 'F' */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x78, /* 0    000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 71 0x47 'G' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x40, /* 0 000000 */
+	0x4c, /* 0 00  00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 72 0x48 'H' */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 73 0x49 'I' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 74 0x4a 'J' */
+	0x00, /* 00000000 */
+	0x04, /* 00000 00 */
+	0x04, /* 00000 00 */
+	0x04, /* 00000 00 */
+	0x04, /* 00000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 75 0x4b 'K' */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x48, /* 0 00 000 */
+	0x50, /* 0 0 0000 */
+	0x60, /* 0  00000 */
+	0x50, /* 0 0 0000 */
+	0x48, /* 0 00 000 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 76 0x4c 'L' */
+	0x00, /* 00000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 77 0x4d 'M' */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x6c, /* 0  0  00 */
+	0x54, /* 0 0 0 00 */
+	0x54, /* 0 0 0 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 78 0x4e 'N' */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x64, /* 0  00 00 */
+	0x54, /* 0 0 0 00 */
+	0x4c, /* 0 00  00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 79 0x4f 'O' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 80 0x50 'P' */
+	0x00, /* 00000000 */
+	0x78, /* 0    000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x78, /* 0    000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 81 0x51 'Q' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x54, /* 0 0 0 00 */
+	0x38, /* 00   000 */
+	0x04, /* 00000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 82 0x52 'R' */
+	0x00, /* 00000000 */
+	0x78, /* 0    000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x78, /* 0    000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 83 0x53 'S' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x40, /* 0 000000 */
+	0x38, /* 00   000 */
+	0x04, /* 00000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 84 0x54 'T' */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 85 0x55 'U' */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 86 0x56 'V' */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x28, /* 00 0 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 87 0x57 'W' */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x54, /* 0 0 0 00 */
+	0x54, /* 0 0 0 00 */
+	0x6c, /* 0  0  00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 88 0x58 'X' */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x28, /* 00 0 000 */
+	0x10, /* 000 0000 */
+	0x28, /* 00 0 000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 89 0x59 'Y' */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x28, /* 00 0 000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 90 0x5a 'Z' */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x04, /* 00000 00 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x40, /* 0 000000 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 91 0x5b '[' */
+	0x0c, /* 0000  00 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x0c, /* 0000  00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 92 0x5c '\' */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x20, /* 00 00000 */
+	0x20, /* 00 00000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x04, /* 00000 00 */
+	0x04, /* 00000 00 */
+	0x00, /* 00000000 */
+
+	/* 93 0x5d ']' */
+	0x30, /* 00  0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x30, /* 00  0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 94 0x5e '^' */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x28, /* 00 0 000 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 95 0x5f '_' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfc, /*       00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 96 0x60 '`' */
+	0x20, /* 00 00000 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 97 0x61 'a' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 98 0x62 'b' */
+	0x00, /* 00000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x78, /* 0    000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x78, /* 0    000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 99 0x63 'c' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x40, /* 0 000000 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 100 0x64 'd' */
+	0x00, /* 00000000 */
+	0x04, /* 00000 00 */
+	0x04, /* 00000 00 */
+	0x3c, /* 00    00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 101 0x65 'e' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x40, /* 0 000000 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 102 0x66 'f' */
+	0x00, /* 00000000 */
+	0x0c, /* 0000  00 */
+	0x10, /* 000 0000 */
+	0x38, /* 00   000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 103 0x67 'g' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x3c, /* 00    00 */
+	0x04, /* 00000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+
+	/* 104 0x68 'h' */
+	0x00, /* 00000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x78, /* 0    000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 105 0x69 'i' */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x30, /* 00  0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 106 0x6a 'j' */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x30, /* 00  0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x60, /* 0  00000 */
+	0x00, /* 00000000 */
+
+	/* 107 0x6b 'k' */
+	0x00, /* 00000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x48, /* 0 00 000 */
+	0x50, /* 0 0 0000 */
+	0x70, /* 0   0000 */
+	0x48, /* 0 00 000 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 108 0x6c 'l' */
+	0x00, /* 00000000 */
+	0x30, /* 00  0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 109 0x6d 'm' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x78, /* 0    000 */
+	0x54, /* 0 0 0 00 */
+	0x54, /* 0 0 0 00 */
+	0x54, /* 0 0 0 00 */
+	0x54, /* 0 0 0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 110 0x6e 'n' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x58, /* 0 0  000 */
+	0x64, /* 0  00 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 111 0x6f 'o' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 112 0x70 'p' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x78, /* 0    000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x78, /* 0    000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x00, /* 00000000 */
+
+	/* 113 0x71 'q' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x3c, /* 00    00 */
+	0x04, /* 00000 00 */
+	0x04, /* 00000 00 */
+	0x00, /* 00000000 */
+
+	/* 114 0x72 'r' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x58, /* 0 0  000 */
+	0x64, /* 0  00 00 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 115 0x73 's' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x40, /* 0 000000 */
+	0x38, /* 00   000 */
+	0x04, /* 00000 00 */
+	0x78, /* 0    000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 116 0x74 't' */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x38, /* 00   000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x0c, /* 0000  00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 117 0x75 'u' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 118 0x76 'v' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x28, /* 00 0 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 119 0x77 'w' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x54, /* 0 0 0 00 */
+	0x54, /* 0 0 0 00 */
+	0x54, /* 0 0 0 00 */
+	0x54, /* 0 0 0 00 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 120 0x78 'x' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x28, /* 00 0 000 */
+	0x10, /* 000 0000 */
+	0x28, /* 00 0 000 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 121 0x79 'y' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x3c, /* 00    00 */
+	0x04, /* 00000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+
+	/* 122 0x7a 'z' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 123 0x7b '{' */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x04, /* 00000 00 */
+	0x00, /* 00000000 */
+
+	/* 124 0x7c '|' */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 125 0x7d '}' */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x00, /* 00000000 */
+
+	/* 126 0x7e '~' */
+	0x00, /* 00000000 */
+	0x34, /* 00  0 00 */
+	0x58, /* 0 0  000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 127 0x7f '^?' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 128 0x80 '\200' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 129 0x81 '\201' */
+	0x28, /* 00 0 000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 130 0x82 '\202' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 131 0x83 '\203' */
+	0x10, /* 000 0000 */
+	0x7c, /* 0     00 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x78, /* 0    000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 132 0x84 '\204' */
+	0x58, /* 0 0  000 */
+	0x44, /* 0 000 00 */
+	0x64, /* 0  00 00 */
+	0x54, /* 0 0 0 00 */
+	0x4c, /* 0 00  00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 133 0x85 '\205' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 134 0x86 '\206' */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 135 0x87 '\207' */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 136 0x88 '\210' */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 137 0x89 '\211' */
+	0x10, /* 000 0000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 138 0x8a '\212' */
+	0x00, /* 00000000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 139 0x8b '\213' */
+	0x34, /* 00  0 00 */
+	0x58, /* 0 0  000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 140 0x8c '\214' */
+	0x18, /* 000  000 */
+	0x24, /* 00 00 00 */
+	0x18, /* 000  000 */
+	0x3c, /* 00    00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 141 0x8d '\215' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x3c, /* 00    00 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x00, /* 00000000 */
+
+	/* 142 0x8e '\216' */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x40, /* 0 000000 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 143 0x8f '\217' */
+	0x20, /* 00 00000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x40, /* 0 000000 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 144 0x90 '\220' */
+	0x10, /* 000 0000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x40, /* 0 000000 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 145 0x91 '\221' */
+	0x00, /* 00000000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x40, /* 0 000000 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 146 0x92 '\222' */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 147 0x93 '\223' */
+	0x20, /* 00 00000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 148 0x94 '\224' */
+	0x10, /* 000 0000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 149 0x95 '\225' */
+	0x00, /* 00000000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 150 0x96 '\226' */
+	0x34, /* 00  0 00 */
+	0x58, /* 0 0  000 */
+	0x00, /* 00000000 */
+	0x58, /* 0 0  000 */
+	0x64, /* 0  00 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 151 0x97 '\227' */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 152 0x98 '\230' */
+	0x20, /* 00 00000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 153 0x99 '\231' */
+	0x10, /* 000 0000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 154 0x9a '\232' */
+	0x00, /* 00000000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 155 0x9b '\233' */
+	0x34, /* 00  0 00 */
+	0x58, /* 0 0  000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 156 0x9c '\234' */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 157 0x9d '\235' */
+	0x20, /* 00 00000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 158 0x9e '\236' */
+	0x10, /* 000 0000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 159 0x9f '\237' */
+	0x00, /* 00000000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 160 0xa0 '\240' */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x38, /* 00   000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 161 0xa1 '\241' */
+	0x18, /* 000  000 */
+	0x24, /* 00 00 00 */
+	0x24, /* 00 00 00 */
+	0x18, /* 000  000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 162 0xa2 '\242' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x38, /* 00   000 */
+	0x54, /* 0 0 0 00 */
+	0x50, /* 0 0 0000 */
+	0x54, /* 0 0 0 00 */
+	0x38, /* 00   000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 163 0xa3 '\243' */
+	0x30, /* 00  0000 */
+	0x48, /* 0 00 000 */
+	0x40, /* 0 000000 */
+	0x70, /* 0   0000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x44, /* 0 000 00 */
+	0x78, /* 0    000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 164 0xa4 '\244' */
+	0x44, /* 0 000 00 */
+	0x24, /* 00 00 00 */
+	0x50, /* 0 0 0000 */
+	0x48, /* 0 00 000 */
+	0x24, /* 00 00 00 */
+	0x14, /* 000 0 00 */
+	0x48, /* 0 00 000 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 165 0xa5 '\245' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x7c, /* 0     00 */
+	0x7c, /* 0     00 */
+	0x7c, /* 0     00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 166 0xa6 '\246' */
+	0x3c, /* 00    00 */
+	0x54, /* 0 0 0 00 */
+	0x54, /* 0 0 0 00 */
+	0x54, /* 0 0 0 00 */
+	0x3c, /* 00    00 */
+	0x14, /* 000 0 00 */
+	0x14, /* 000 0 00 */
+	0x14, /* 000 0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 167 0xa7 '\247' */
+	0x18, /* 000  000 */
+	0x24, /* 00 00 00 */
+	0x44, /* 0 000 00 */
+	0x48, /* 0 00 000 */
+	0x48, /* 0 00 000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x58, /* 0 0  000 */
+	0x40, /* 0 000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 168 0xa8 '\250' */
+	0x00, /* 00000000 */
+	0x70, /* 0   0000 */
+	0x08, /* 0000 000 */
+	0x64, /* 0  00 00 */
+	0x54, /* 0 0 0 00 */
+	0x64, /* 0  00 00 */
+	0x58, /* 0 0  000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 169 0xa9 '\251' */
+	0x00, /* 00000000 */
+	0x70, /* 0   0000 */
+	0x08, /* 0000 000 */
+	0x34, /* 00  0 00 */
+	0x44, /* 0 000 00 */
+	0x34, /* 00  0 00 */
+	0x08, /* 0000 000 */
+	0x70, /* 0   0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 170 0xaa '\252' */
+	0x00, /* 00000000 */
+	0xf4, /*     0 00 */
+	0x5c, /* 0 0   00 */
+	0x5c, /* 0 0   00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 171 0xab '\253' */
+	0x00, /* 00000000 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 172 0xac '\254' */
+	0x00, /* 00000000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 173 0xad '\255' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x08, /* 0000 000 */
+	0x7c, /* 0     00 */
+	0x10, /* 000 0000 */
+	0x7c, /* 0     00 */
+	0x20, /* 00 00000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 174 0xae '\256' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x50, /* 0 0 0000 */
+	0x50, /* 0 0 0000 */
+	0x78, /* 0    000 */
+	0x50, /* 0 0 0000 */
+	0x50, /* 0 0 0000 */
+	0x5c, /* 0 0   00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 175 0xaf '\257' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x54, /* 0 0 0 00 */
+	0x64, /* 0  00 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 176 0xb0 '\260' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x6c, /* 0  0  00 */
+	0x54, /* 0 0 0 00 */
+	0x6c, /* 0  0  00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 177 0xb1 '\261' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x7c, /* 0     00 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 178 0xb2 '\262' */
+	0x00, /* 00000000 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 179 0xb3 '\263' */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x04, /* 00000 00 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x1c, /* 000   00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 180 0xb4 '\264' */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x28, /* 00 0 000 */
+	0x7c, /* 0     00 */
+	0x10, /* 000 0000 */
+	0x7c, /* 0     00 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 181 0xb5 '\265' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x48, /* 0 00 000 */
+	0x48, /* 0 00 000 */
+	0x48, /* 0 00 000 */
+	0x48, /* 0 00 000 */
+	0x74, /* 0   0 00 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x00, /* 00000000 */
+
+	/* 182 0xb6 '\266' */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x0c, /* 0000  00 */
+	0x14, /* 000 0 00 */
+	0x24, /* 00 00 00 */
+	0x24, /* 00 00 00 */
+	0x18, /* 000  000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 183 0xb7 '\267' */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x24, /* 00 00 00 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x24, /* 00 00 00 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 184 0xb8 '\270' */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 185 0xb9 '\271' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 186 0xba '\272' */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x60, /* 0  00000 */
+	0x00, /* 00000000 */
+
+	/* 187 0xbb '\273' */
+	0x00, /* 00000000 */
+	0x1c, /* 000   00 */
+	0x24, /* 00 00 00 */
+	0x24, /* 00 00 00 */
+	0x1c, /* 000   00 */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 188 0xbc '\274' */
+	0x00, /* 00000000 */
+	0x18, /* 000  000 */
+	0x24, /* 00 00 00 */
+	0x24, /* 00 00 00 */
+	0x18, /* 000  000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 189 0xbd '\275' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x28, /* 00 0 000 */
+	0x6c, /* 0  0  00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 190 0xbe '\276' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x54, /* 0 0 0 00 */
+	0x5c, /* 0 0   00 */
+	0x50, /* 0 0 0000 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 191 0xbf '\277' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x4c, /* 0 00  00 */
+	0x54, /* 0 0 0 00 */
+	0x64, /* 0  00 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 192 0xc0 '\300' */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x40, /* 0 000000 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 193 0xc1 '\301' */
+	0x00, /* 00000000 */
+	0x08, /* 0000 000 */
+	0x00, /* 00000000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 194 0xc2 '\302' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x04, /* 00000 00 */
+	0x04, /* 00000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 195 0xc3 '\303' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x0c, /* 0000  00 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x50, /* 0 0 0000 */
+	0x20, /* 00 00000 */
+	0x20, /* 00 00000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 196 0xc4 '\304' */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x38, /* 00   000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x60, /* 0  00000 */
+	0x00, /* 00000000 */
+
+	/* 197 0xc5 '\305' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x04, /* 00000 00 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x40, /* 0 000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 198 0xc6 '\306' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 199 0xc7 '\307' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x24, /* 00 00 00 */
+	0x48, /* 0 00 000 */
+	0x48, /* 0 00 000 */
+	0x24, /* 00 00 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 200 0xc8 '\310' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x48, /* 0 00 000 */
+	0x24, /* 00 00 00 */
+	0x24, /* 00 00 00 */
+	0x48, /* 0 00 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 201 0xc9 '\311' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x54, /* 0 0 0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 202 0xca '\312' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 203 0xcb '\313' */
+	0x10, /* 000 0000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 204 0xcc '\314' */
+	0x58, /* 0 0  000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 205 0xcd '\315' */
+	0x58, /* 0 0  000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 206 0xce '\316' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x50, /* 0 0 0000 */
+	0x50, /* 0 0 0000 */
+	0x58, /* 0 0  000 */
+	0x50, /* 0 0 0000 */
+	0x50, /* 0 0 0000 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 207 0xcf '\317' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x28, /* 00 0 000 */
+	0x54, /* 0 0 0 00 */
+	0x5c, /* 0 0   00 */
+	0x50, /* 0 0 0000 */
+	0x2c, /* 00 0  00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 208 0xd0 '\320' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 209 0xd1 '\321' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfc, /*       00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 210 0xd2 '\322' */
+	0x00, /* 00000000 */
+	0x14, /* 000 0 00 */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 211 0xd3 '\323' */
+	0x00, /* 00000000 */
+	0x14, /* 000 0 00 */
+	0x14, /* 000 0 00 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 212 0xd4 '\324' */
+	0x00, /* 00000000 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x18, /* 000  000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 213 0xd5 '\325' */
+	0x00, /* 00000000 */
+	0x18, /* 000  000 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 214 0xd6 '\326' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 215 0xd7 '\327' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x28, /* 00 0 000 */
+	0x44, /* 0 000 00 */
+	0x28, /* 00 0 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 216 0xd8 '\330' */
+	0x00, /* 00000000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x3c, /* 00    00 */
+	0x04, /* 00000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+
+	/* 217 0xd9 '\331' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfc, /*       00 */
+	0x00, /* 00000000 */
+	0xfc, /*       00 */
+	0x00, /* 00000000 */
+	0xfc, /*       00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 218 0xda '\332' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 219 0xdb '\333' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 220 0xdc '\334' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 221 0xdd '\335' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 222 0xde '\336' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 223 0xdf '\337' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 224 0xe0 '\340' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 225 0xe1 '\341' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 226 0xe2 '\342' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 227 0xe3 '\343' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 228 0xe4 '\344' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 229 0xe5 '\345' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 230 0xe6 '\346' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 231 0xe7 '\347' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 232 0xe8 '\350' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 233 0xe9 '\351' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 234 0xea '\352' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 235 0xeb '\353' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 236 0xec '\354' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 237 0xed '\355' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 238 0xee '\356' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 239 0xef '\357' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 240 0xf0 '\360' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 241 0xf1 '\361' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 242 0xf2 '\362' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 243 0xf3 '\363' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 244 0xf4 '\364' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 245 0xf5 '\365' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 246 0xf6 '\366' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 247 0xf7 '\367' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 248 0xf8 '\370' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 249 0xf9 '\371' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 250 0xfa '\372' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 251 0xfb '\373' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 252 0xfc '\374' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 253 0xfd '\375' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 254 0xfe '\376' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 255 0xff '\377' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+};
+
+
+struct font_desc font_vga_6x11 = {
+	VGA6x11_IDX,
+	"ProFont6x11",
+	6,
+	11,
+	fontdata_6x11,
+	-2000	/* Try avoiding this font if possible unless on MAC */
+};
diff -Nru a/drivers/video/console/font_8x16.c b/drivers/video/console/font_8x16.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/font_8x16.c	Mon Dec  9 18:46:50 2002
@@ -0,0 +1,4631 @@
+/**********************************************/
+/*                                            */
+/*       Font file generated by cpi2fnt       */
+/*                                            */
+/**********************************************/
+
+#include "font.h"
+
+#define FONTDATAMAX 4096
+
+static unsigned char fontdata_8x16[FONTDATAMAX] = {
+
+	/* 0 0x00 '^@' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 1 0x01 '^A' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x81, /* 10000001 */
+	0xa5, /* 10100101 */
+	0x81, /* 10000001 */
+	0x81, /* 10000001 */
+	0xbd, /* 10111101 */
+	0x99, /* 10011001 */
+	0x81, /* 10000001 */
+	0x81, /* 10000001 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 2 0x02 '^B' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0xff, /* 11111111 */
+	0xdb, /* 11011011 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xc3, /* 11000011 */
+	0xe7, /* 11100111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 3 0x03 '^C' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x6c, /* 01101100 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0x7c, /* 01111100 */
+	0x38, /* 00111000 */
+	0x10, /* 00010000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 4 0x04 '^D' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x7c, /* 01111100 */
+	0xfe, /* 11111110 */
+	0x7c, /* 01111100 */
+	0x38, /* 00111000 */
+	0x10, /* 00010000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 5 0x05 '^E' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0xe7, /* 11100111 */
+	0xe7, /* 11100111 */
+	0xe7, /* 11100111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 6 0x06 '^F' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 7 0x07 '^G' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 8 0x08 '^H' */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xe7, /* 11100111 */
+	0xc3, /* 11000011 */
+	0xc3, /* 11000011 */
+	0xe7, /* 11100111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+
+	/* 9 0x09 '^I' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x42, /* 01000010 */
+	0x42, /* 01000010 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 10 0x0a '^J' */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xc3, /* 11000011 */
+	0x99, /* 10011001 */
+	0xbd, /* 10111101 */
+	0xbd, /* 10111101 */
+	0x99, /* 10011001 */
+	0xc3, /* 11000011 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+
+	/* 11 0x0b '^K' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1e, /* 00011110 */
+	0x0e, /* 00001110 */
+	0x1a, /* 00011010 */
+	0x32, /* 00110010 */
+	0x78, /* 01111000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 12 0x0c '^L' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 13 0x0d '^M' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3f, /* 00111111 */
+	0x33, /* 00110011 */
+	0x3f, /* 00111111 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x70, /* 01110000 */
+	0xf0, /* 11110000 */
+	0xe0, /* 11100000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 14 0x0e '^N' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7f, /* 01111111 */
+	0x63, /* 01100011 */
+	0x7f, /* 01111111 */
+	0x63, /* 01100011 */
+	0x63, /* 01100011 */
+	0x63, /* 01100011 */
+	0x63, /* 01100011 */
+	0x67, /* 01100111 */
+	0xe7, /* 11100111 */
+	0xe6, /* 11100110 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 15 0x0f '^O' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xdb, /* 11011011 */
+	0x3c, /* 00111100 */
+	0xe7, /* 11100111 */
+	0x3c, /* 00111100 */
+	0xdb, /* 11011011 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 16 0x10 '^P' */
+	0x00, /* 00000000 */
+	0x80, /* 10000000 */
+	0xc0, /* 11000000 */
+	0xe0, /* 11100000 */
+	0xf0, /* 11110000 */
+	0xf8, /* 11111000 */
+	0xfe, /* 11111110 */
+	0xf8, /* 11111000 */
+	0xf0, /* 11110000 */
+	0xe0, /* 11100000 */
+	0xc0, /* 11000000 */
+	0x80, /* 10000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 17 0x11 '^Q' */
+	0x00, /* 00000000 */
+	0x02, /* 00000010 */
+	0x06, /* 00000110 */
+	0x0e, /* 00001110 */
+	0x1e, /* 00011110 */
+	0x3e, /* 00111110 */
+	0xfe, /* 11111110 */
+	0x3e, /* 00111110 */
+	0x1e, /* 00011110 */
+	0x0e, /* 00001110 */
+	0x06, /* 00000110 */
+	0x02, /* 00000010 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 18 0x12 '^R' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 19 0x13 '^S' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 20 0x14 '^T' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7f, /* 01111111 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0x7b, /* 01111011 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 21 0x15 '^U' */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0x60, /* 01100000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x0c, /* 00001100 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 22 0x16 '^V' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 23 0x17 '^W' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 24 0x18 '^X' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 25 0x19 '^Y' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 26 0x1a '^Z' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0xfe, /* 11111110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 27 0x1b '^[' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xfe, /* 11111110 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 28 0x1c '^\' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 29 0x1d '^]' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x28, /* 00101000 */
+	0x6c, /* 01101100 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x28, /* 00101000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 30 0x1e '^^' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x38, /* 00111000 */
+	0x7c, /* 01111100 */
+	0x7c, /* 01111100 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 31 0x1f '^_' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0x7c, /* 01111100 */
+	0x7c, /* 01111100 */
+	0x38, /* 00111000 */
+	0x38, /* 00111000 */
+	0x10, /* 00010000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 32 0x20 ' ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 33 0x21 '!' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 34 0x22 '"' */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x24, /* 00100100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 35 0x23 '#' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 36 0x24 '$' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc2, /* 11000010 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x86, /* 10000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 37 0x25 '%' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc2, /* 11000010 */
+	0xc6, /* 11000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc6, /* 11000110 */
+	0x86, /* 10000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 38 0x26 '&' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 39 0x27 ''' */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 40 0x28 '(' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 41 0x29 ')' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 42 0x2a '*' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0xff, /* 11111111 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 43 0x2b '+' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 44 0x2c ',' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 45 0x2d '-' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 46 0x2e '.' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 47 0x2f '/' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x02, /* 00000010 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0x80, /* 10000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 48 0x30 '0' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 49 0x31 '1' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x38, /* 00111000 */
+	0x78, /* 01111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 50 0x32 '2' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 51 0x33 '3' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x3c, /* 00111100 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 52 0x34 '4' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x0c, /* 00001100 */
+	0x1c, /* 00011100 */
+	0x3c, /* 00111100 */
+	0x6c, /* 01101100 */
+	0xcc, /* 11001100 */
+	0xfe, /* 11111110 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x1e, /* 00011110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 53 0x35 '5' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xfc, /* 11111100 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 54 0x36 '6' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xfc, /* 11111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 55 0x37 '7' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 56 0x38 '8' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 57 0x39 '9' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7e, /* 01111110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 58 0x3a ':' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 59 0x3b ';' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 60 0x3c '<' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x06, /* 00000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 61 0x3d '=' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 62 0x3e '>' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 63 0x3f '?' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 64 0x40 '@' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xde, /* 11011110 */
+	0xde, /* 11011110 */
+	0xde, /* 11011110 */
+	0xdc, /* 11011100 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 65 0x41 'A' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 66 0x42 'B' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfc, /* 11111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0xfc, /* 11111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 67 0x43 'C' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0xc2, /* 11000010 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc2, /* 11000010 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 68 0x44 'D' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xf8, /* 11111000 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 69 0x45 'E' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x66, /* 01100110 */
+	0x62, /* 01100010 */
+	0x68, /* 01101000 */
+	0x78, /* 01111000 */
+	0x68, /* 01101000 */
+	0x60, /* 01100000 */
+	0x62, /* 01100010 */
+	0x66, /* 01100110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 70 0x46 'F' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x66, /* 01100110 */
+	0x62, /* 01100010 */
+	0x68, /* 01101000 */
+	0x78, /* 01111000 */
+	0x68, /* 01101000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 71 0x47 'G' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0xc2, /* 11000010 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xde, /* 11011110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x66, /* 01100110 */
+	0x3a, /* 00111010 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 72 0x48 'H' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 73 0x49 'I' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 74 0x4a 'J' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1e, /* 00011110 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 75 0x4b 'K' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xe6, /* 11100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0x78, /* 01111000 */
+	0x78, /* 01111000 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 76 0x4c 'L' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xf0, /* 11110000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x62, /* 01100010 */
+	0x66, /* 01100110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 77 0x4d 'M' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xee, /* 11101110 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xd6, /* 11010110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 78 0x4e 'N' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xe6, /* 11100110 */
+	0xf6, /* 11110110 */
+	0xfe, /* 11111110 */
+	0xde, /* 11011110 */
+	0xce, /* 11001110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 79 0x4f 'O' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 80 0x50 'P' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfc, /* 11111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 81 0x51 'Q' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xd6, /* 11010110 */
+	0xde, /* 11011110 */
+	0x7c, /* 01111100 */
+	0x0c, /* 00001100 */
+	0x0e, /* 00001110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 82 0x52 'R' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfc, /* 11111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 83 0x53 'S' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x60, /* 01100000 */
+	0x38, /* 00111000 */
+	0x0c, /* 00001100 */
+	0x06, /* 00000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 84 0x54 'T' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x5a, /* 01011010 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 85 0x55 'U' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 86 0x56 'V' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x10, /* 00010000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 87 0x57 'W' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xfe, /* 11111110 */
+	0xee, /* 11101110 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 88 0x58 'X' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x7c, /* 01111100 */
+	0x38, /* 00111000 */
+	0x38, /* 00111000 */
+	0x7c, /* 01111100 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 89 0x59 'Y' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 90 0x5a 'Z' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0x86, /* 10000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc2, /* 11000010 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 91 0x5b '[' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 92 0x5c '\' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x80, /* 10000000 */
+	0xc0, /* 11000000 */
+	0xe0, /* 11100000 */
+	0x70, /* 01110000 */
+	0x38, /* 00111000 */
+	0x1c, /* 00011100 */
+	0x0e, /* 00001110 */
+	0x06, /* 00000110 */
+	0x02, /* 00000010 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 93 0x5d ']' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 94 0x5e '^' */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 95 0x5f '_' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 96 0x60 '`' */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 97 0x61 'a' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 98 0x62 'b' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xe0, /* 11100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x78, /* 01111000 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 99 0x63 'c' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 100 0x64 'd' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1c, /* 00011100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x3c, /* 00111100 */
+	0x6c, /* 01101100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 101 0x65 'e' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 102 0x66 'f' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1c, /* 00011100 */
+	0x36, /* 00110110 */
+	0x32, /* 00110010 */
+	0x30, /* 00110000 */
+	0x78, /* 01111000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 103 0x67 'g' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x7c, /* 01111100 */
+	0x0c, /* 00001100 */
+	0xcc, /* 11001100 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+
+	/* 104 0x68 'h' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xe0, /* 11100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x6c, /* 01101100 */
+	0x76, /* 01110110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 105 0x69 'i' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 106 0x6a 'j' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x00, /* 00000000 */
+	0x0e, /* 00001110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 107 0x6b 'k' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xe0, /* 11100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0x78, /* 01111000 */
+	0x78, /* 01111000 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 108 0x6c 'l' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 109 0x6d 'm' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xec, /* 11101100 */
+	0xfe, /* 11111110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 110 0x6e 'n' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 111 0x6f 'o' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 112 0x70 'p' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+
+	/* 113 0x71 'q' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x7c, /* 01111100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x1e, /* 00011110 */
+	0x00, /* 00000000 */
+
+	/* 114 0x72 'r' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x76, /* 01110110 */
+	0x66, /* 01100110 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 115 0x73 's' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0x60, /* 01100000 */
+	0x38, /* 00111000 */
+	0x0c, /* 00001100 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 116 0x74 't' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0xfc, /* 11111100 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x36, /* 00110110 */
+	0x1c, /* 00011100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 117 0x75 'u' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 118 0x76 'v' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 119 0x77 'w' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 120 0x78 'x' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x38, /* 00111000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 121 0x79 'y' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7e, /* 01111110 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+
+	/* 122 0x7a 'z' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xcc, /* 11001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 123 0x7b '{' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x0e, /* 00001110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x70, /* 01110000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x0e, /* 00001110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 124 0x7c '|' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 125 0x7d '}' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x70, /* 01110000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x0e, /* 00001110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 126 0x7e '~' */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 127 0x7f '' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 128 0x80 '€' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0xc2, /* 11000010 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc2, /* 11000010 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 129 0x81 '�' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 130 0x82 '‚' */
+	0x00, /* 00000000 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 131 0x83 'ƒ' */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 132 0x84 '„' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 133 0x85 '…' */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 134 0x86 '†' */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 135 0x87 '‡' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x18, /* 00011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 136 0x88 'ˆ' */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 137 0x89 '‰' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 138 0x8a 'Š' */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 139 0x8b '‹' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 140 0x8c 'Œ' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 141 0x8d '�' */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 142 0x8e 'Ž' */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 143 0x8f '�' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 144 0x90 '�' */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x66, /* 01100110 */
+	0x62, /* 01100010 */
+	0x68, /* 01101000 */
+	0x78, /* 01111000 */
+	0x68, /* 01101000 */
+	0x62, /* 01100010 */
+	0x66, /* 01100110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 145 0x91 '‘' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xec, /* 11101100 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x7e, /* 01111110 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0x6e, /* 01101110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 146 0x92 '’' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3e, /* 00111110 */
+	0x6c, /* 01101100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xfe, /* 11111110 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xce, /* 11001110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 147 0x93 '“' */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 148 0x94 '”' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 149 0x95 '•' */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 150 0x96 '–' */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x78, /* 01111000 */
+	0xcc, /* 11001100 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 151 0x97 '—' */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 152 0x98 '˜' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7e, /* 01111110 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+
+	/* 153 0x99 '™' */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 154 0x9a 'š' */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 155 0x9b '›' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 156 0x9c 'œ' */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x64, /* 01100100 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xe6, /* 11100110 */
+	0xfc, /* 11111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 157 0x9d '�' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 158 0x9e 'ž' */
+	0x00, /* 00000000 */
+	0xf8, /* 11111000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xf8, /* 11111000 */
+	0xc4, /* 11000100 */
+	0xcc, /* 11001100 */
+	0xde, /* 11011110 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 159 0x9f 'Ÿ' */
+	0x00, /* 00000000 */
+	0x0e, /* 00001110 */
+	0x1b, /* 00011011 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xd8, /* 11011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 160 0xa0 ' ' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 161 0xa1 '¡' */
+	0x00, /* 00000000 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 162 0xa2 '¢' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 163 0xa3 '£' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 164 0xa4 '¤' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 165 0xa5 '¥' */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xe6, /* 11100110 */
+	0xf6, /* 11110110 */
+	0xfe, /* 11111110 */
+	0xde, /* 11011110 */
+	0xce, /* 11001110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 166 0xa6 '¦' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x3e, /* 00111110 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 167 0xa7 '§' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 168 0xa8 '¨' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 169 0xa9 '©' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 170 0xaa 'ª' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 171 0xab '«' */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0xe0, /* 11100000 */
+	0x62, /* 01100010 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xdc, /* 11011100 */
+	0x86, /* 10000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x3e, /* 00111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 172 0xac '¬' */
+	0x00, /* 00000000 */
+	0x60, /* 01100000 */
+	0xe0, /* 11100000 */
+	0x62, /* 01100010 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x66, /* 01100110 */
+	0xce, /* 11001110 */
+	0x9a, /* 10011010 */
+	0x3f, /* 00111111 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 173 0xad '­' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 174 0xae '®' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x36, /* 00110110 */
+	0x6c, /* 01101100 */
+	0xd8, /* 11011000 */
+	0x6c, /* 01101100 */
+	0x36, /* 00110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 175 0xaf '¯' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xd8, /* 11011000 */
+	0x6c, /* 01101100 */
+	0x36, /* 00110110 */
+	0x6c, /* 01101100 */
+	0xd8, /* 11011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 176 0xb0 '°' */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+	0x11, /* 00010001 */
+	0x44, /* 01000100 */
+
+	/* 177 0xb1 '±' */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+
+	/* 178 0xb2 '²' */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+
+	/* 179 0xb3 '³' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 180 0xb4 '´' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 181 0xb5 'µ' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 182 0xb6 '¶' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf6, /* 11110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 183 0xb7 '·' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 184 0xb8 '¸' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 185 0xb9 '¹' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf6, /* 11110110 */
+	0x06, /* 00000110 */
+	0xf6, /* 11110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 186 0xba 'º' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 187 0xbb '»' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x06, /* 00000110 */
+	0xf6, /* 11110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 188 0xbc '¼' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf6, /* 11110110 */
+	0x06, /* 00000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 189 0xbd '½' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 190 0xbe '¾' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 191 0xbf '¿' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 192 0xc0 'À' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 193 0xc1 'Á' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 194 0xc2 'Â' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 195 0xc3 'Ã' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 196 0xc4 'Ä' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 197 0xc5 'Å' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 198 0xc6 'Æ' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 199 0xc7 'Ç' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x37, /* 00110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 200 0xc8 'È' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x37, /* 00110111 */
+	0x30, /* 00110000 */
+	0x3f, /* 00111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 201 0xc9 'É' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3f, /* 00111111 */
+	0x30, /* 00110000 */
+	0x37, /* 00110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 202 0xca 'Ê' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf7, /* 11110111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 203 0xcb 'Ë' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xf7, /* 11110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 204 0xcc 'Ì' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x37, /* 00110111 */
+	0x30, /* 00110000 */
+	0x37, /* 00110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 205 0xcd 'Í' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 206 0xce 'Î' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf7, /* 11110111 */
+	0x00, /* 00000000 */
+	0xf7, /* 11110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 207 0xcf 'Ï' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 208 0xd0 'Ð' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 209 0xd1 'Ñ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 210 0xd2 'Ò' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 211 0xd3 'Ó' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x3f, /* 00111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 212 0xd4 'Ô' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 213 0xd5 'Õ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 214 0xd6 'Ö' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3f, /* 00111111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 215 0xd7 '×' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xff, /* 11111111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 216 0xd8 'Ø' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 217 0xd9 'Ù' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 218 0xda 'Ú' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 219 0xdb 'Û' */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+
+	/* 220 0xdc 'Ü' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+
+	/* 221 0xdd 'Ý' */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+
+	/* 222 0xde 'Þ' */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+
+	/* 223 0xdf 'ß' */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 224 0xe0 'à' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0xdc, /* 11011100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 225 0xe1 'á' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xd8, /* 11011000 */
+	0xcc, /* 11001100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xcc, /* 11001100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 226 0xe2 'â' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 227 0xe3 'ã' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 228 0xe4 'ä' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 229 0xe5 'å' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 230 0xe6 'æ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+
+	/* 231 0xe7 'ç' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 232 0xe8 'è' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 233 0xe9 'é' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 234 0xea 'ê' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0xee, /* 11101110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 235 0xeb 'ë' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1e, /* 00011110 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x3e, /* 00111110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 236 0xec 'ì' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 237 0xed 'í' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x03, /* 00000011 */
+	0x06, /* 00000110 */
+	0x7e, /* 01111110 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0xf3, /* 11110011 */
+	0x7e, /* 01111110 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 238 0xee 'î' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1c, /* 00011100 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x7c, /* 01111100 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x1c, /* 00011100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 239 0xef 'ï' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 240 0xf0 'ð' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 241 0xf1 'ñ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 242 0xf2 'ò' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 243 0xf3 'ó' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 244 0xf4 'ô' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x0e, /* 00001110 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 245 0xf5 'õ' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 246 0xf6 'ö' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 247 0xf7 '÷' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 248 0xf8 'ø' */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 249 0xf9 'ù' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 250 0xfa 'ú' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 251 0xfb 'û' */
+	0x00, /* 00000000 */
+	0x0f, /* 00001111 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0xec, /* 11101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x3c, /* 00111100 */
+	0x1c, /* 00011100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 252 0xfc 'ü' */
+	0x00, /* 00000000 */
+	0x6c, /* 01101100 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 253 0xfd 'ý' */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x32, /* 00110010 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 254 0xfe 'þ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 255 0xff 'ÿ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+};
+
+
+struct font_desc font_vga_8x16 = {
+	VGA8x16_IDX,
+	"VGA8x16",
+	8,
+	16,
+	fontdata_8x16,
+	0
+};
diff -Nru a/drivers/video/console/font_8x8.c b/drivers/video/console/font_8x8.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/font_8x8.c	Mon Dec  9 18:46:51 2002
@@ -0,0 +1,2583 @@
+/**********************************************/
+/*                                            */
+/*       Font file generated by cpi2fnt       */
+/*                                            */
+/**********************************************/
+
+#include "font.h"
+
+#define FONTDATAMAX 2048
+
+static unsigned char fontdata_8x8[FONTDATAMAX] = {
+
+	/* 0 0x00 '^@' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 1 0x01 '^A' */
+	0x7e, /* 01111110 */
+	0x81, /* 10000001 */
+	0xa5, /* 10100101 */
+	0x81, /* 10000001 */
+	0xbd, /* 10111101 */
+	0x99, /* 10011001 */
+	0x81, /* 10000001 */
+	0x7e, /* 01111110 */
+
+	/* 2 0x02 '^B' */
+	0x7e, /* 01111110 */
+	0xff, /* 11111111 */
+	0xdb, /* 11011011 */
+	0xff, /* 11111111 */
+	0xc3, /* 11000011 */
+	0xe7, /* 11100111 */
+	0xff, /* 11111111 */
+	0x7e, /* 01111110 */
+
+	/* 3 0x03 '^C' */
+	0x6c, /* 01101100 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0x7c, /* 01111100 */
+	0x38, /* 00111000 */
+	0x10, /* 00010000 */
+	0x00, /* 00000000 */
+
+	/* 4 0x04 '^D' */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x7c, /* 01111100 */
+	0xfe, /* 11111110 */
+	0x7c, /* 01111100 */
+	0x38, /* 00111000 */
+	0x10, /* 00010000 */
+	0x00, /* 00000000 */
+
+	/* 5 0x05 '^E' */
+	0x38, /* 00111000 */
+	0x7c, /* 01111100 */
+	0x38, /* 00111000 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xd6, /* 11010110 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+
+	/* 6 0x06 '^F' */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x7c, /* 01111100 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0x7c, /* 01111100 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+
+	/* 7 0x07 '^G' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 8 0x08 '^H' */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xe7, /* 11100111 */
+	0xc3, /* 11000011 */
+	0xc3, /* 11000011 */
+	0xe7, /* 11100111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+
+	/* 9 0x09 '^I' */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x42, /* 01000010 */
+	0x42, /* 01000010 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 10 0x0a '^J' */
+	0xff, /* 11111111 */
+	0xc3, /* 11000011 */
+	0x99, /* 10011001 */
+	0xbd, /* 10111101 */
+	0xbd, /* 10111101 */
+	0x99, /* 10011001 */
+	0xc3, /* 11000011 */
+	0xff, /* 11111111 */
+
+	/* 11 0x0b '^K' */
+	0x0f, /* 00001111 */
+	0x07, /* 00000111 */
+	0x0f, /* 00001111 */
+	0x7d, /* 01111101 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x78, /* 01111000 */
+
+	/* 12 0x0c '^L' */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+
+	/* 13 0x0d '^M' */
+	0x3f, /* 00111111 */
+	0x33, /* 00110011 */
+	0x3f, /* 00111111 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x70, /* 01110000 */
+	0xf0, /* 11110000 */
+	0xe0, /* 11100000 */
+
+	/* 14 0x0e '^N' */
+	0x7f, /* 01111111 */
+	0x63, /* 01100011 */
+	0x7f, /* 01111111 */
+	0x63, /* 01100011 */
+	0x63, /* 01100011 */
+	0x67, /* 01100111 */
+	0xe6, /* 11100110 */
+	0xc0, /* 11000000 */
+
+	/* 15 0x0f '^O' */
+	0x18, /* 00011000 */
+	0xdb, /* 11011011 */
+	0x3c, /* 00111100 */
+	0xe7, /* 11100111 */
+	0xe7, /* 11100111 */
+	0x3c, /* 00111100 */
+	0xdb, /* 11011011 */
+	0x18, /* 00011000 */
+
+	/* 16 0x10 '^P' */
+	0x80, /* 10000000 */
+	0xe0, /* 11100000 */
+	0xf8, /* 11111000 */
+	0xfe, /* 11111110 */
+	0xf8, /* 11111000 */
+	0xe0, /* 11100000 */
+	0x80, /* 10000000 */
+	0x00, /* 00000000 */
+
+	/* 17 0x11 '^Q' */
+	0x02, /* 00000010 */
+	0x0e, /* 00001110 */
+	0x3e, /* 00111110 */
+	0xfe, /* 11111110 */
+	0x3e, /* 00111110 */
+	0x0e, /* 00001110 */
+	0x02, /* 00000010 */
+	0x00, /* 00000000 */
+
+	/* 18 0x12 '^R' */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+
+	/* 19 0x13 '^S' */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+
+	/* 20 0x14 '^T' */
+	0x7f, /* 01111111 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0x7b, /* 01111011 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x00, /* 00000000 */
+
+	/* 21 0x15 '^U' */
+	0x3e, /* 00111110 */
+	0x61, /* 01100001 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x86, /* 10000110 */
+	0x7c, /* 01111100 */
+
+	/* 22 0x16 '^V' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+
+	/* 23 0x17 '^W' */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+
+	/* 24 0x18 '^X' */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 25 0x19 '^Y' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 26 0x1a '^Z' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0xfe, /* 11111110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 27 0x1b '^[' */
+	0x00, /* 00000000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xfe, /* 11111110 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 28 0x1c '^\' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 29 0x1d '^]' */
+	0x00, /* 00000000 */
+	0x24, /* 00100100 */
+	0x66, /* 01100110 */
+	0xff, /* 11111111 */
+	0x66, /* 01100110 */
+	0x24, /* 00100100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 30 0x1e '^^' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 31 0x1f '^_' */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0x7e, /* 01111110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 32 0x20 ' ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 33 0x21 '!' */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 34 0x22 '"' */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x24, /* 00100100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 35 0x23 '#' */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+
+	/* 36 0x24 '$' */
+	0x18, /* 00011000 */
+	0x3e, /* 00111110 */
+	0x60, /* 01100000 */
+	0x3c, /* 00111100 */
+	0x06, /* 00000110 */
+	0x7c, /* 01111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 37 0x25 '%' */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xcc, /* 11001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x66, /* 01100110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 38 0x26 '&' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 39 0x27 ''' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 40 0x28 '(' */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x00, /* 00000000 */
+
+	/* 41 0x29 ')' */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+
+	/* 42 0x2a '*' */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0xff, /* 11111111 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 43 0x2b '+' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 44 0x2c ',' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+
+	/* 45 0x2d '-' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 46 0x2e '.' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 47 0x2f '/' */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0x80, /* 10000000 */
+	0x00, /* 00000000 */
+
+	/* 48 0x30 '0' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xd6, /* 11010110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+
+	/* 49 0x31 '1' */
+	0x18, /* 00011000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+
+	/* 50 0x32 '2' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0x06, /* 00000110 */
+	0x1c, /* 00011100 */
+	0x30, /* 00110000 */
+	0x66, /* 01100110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+
+	/* 51 0x33 '3' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0x06, /* 00000110 */
+	0x3c, /* 00111100 */
+	0x06, /* 00000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 52 0x34 '4' */
+	0x1c, /* 00011100 */
+	0x3c, /* 00111100 */
+	0x6c, /* 01101100 */
+	0xcc, /* 11001100 */
+	0xfe, /* 11111110 */
+	0x0c, /* 00001100 */
+	0x1e, /* 00011110 */
+	0x00, /* 00000000 */
+
+	/* 53 0x35 '5' */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xfc, /* 11111100 */
+	0x06, /* 00000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 54 0x36 '6' */
+	0x38, /* 00111000 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+	0xfc, /* 11111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 55 0x37 '7' */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+
+	/* 56 0x38 '8' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 57 0x39 '9' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7e, /* 01111110 */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+
+	/* 58 0x3a ':' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 59 0x3b ';' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+
+	/* 60 0x3c '<' */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x06, /* 00000110 */
+	0x00, /* 00000000 */
+
+	/* 61 0x3d '=' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 62 0x3e '>' */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x00, /* 00000000 */
+
+	/* 63 0x3f '?' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 64 0x40 '@' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xde, /* 11011110 */
+	0xde, /* 11011110 */
+	0xde, /* 11011110 */
+	0xc0, /* 11000000 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+
+	/* 65 0x41 'A' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 66 0x42 'B' */
+	0xfc, /* 11111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0xfc, /* 11111100 */
+	0x00, /* 00000000 */
+
+	/* 67 0x43 'C' */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 68 0x44 'D' */
+	0xf8, /* 11111000 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+
+	/* 69 0x45 'E' */
+	0xfe, /* 11111110 */
+	0x62, /* 01100010 */
+	0x68, /* 01101000 */
+	0x78, /* 01111000 */
+	0x68, /* 01101000 */
+	0x62, /* 01100010 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+
+	/* 70 0x46 'F' */
+	0xfe, /* 11111110 */
+	0x62, /* 01100010 */
+	0x68, /* 01101000 */
+	0x78, /* 01111000 */
+	0x68, /* 01101000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+
+	/* 71 0x47 'G' */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xce, /* 11001110 */
+	0x66, /* 01100110 */
+	0x3a, /* 00111010 */
+	0x00, /* 00000000 */
+
+	/* 72 0x48 'H' */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 73 0x49 'I' */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 74 0x4a 'J' */
+	0x1e, /* 00011110 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x78, /* 01111000 */
+	0x00, /* 00000000 */
+
+	/* 75 0x4b 'K' */
+	0xe6, /* 11100110 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0x78, /* 01111000 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+
+	/* 76 0x4c 'L' */
+	0xf0, /* 11110000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0x62, /* 01100010 */
+	0x66, /* 01100110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+
+	/* 77 0x4d 'M' */
+	0xc6, /* 11000110 */
+	0xee, /* 11101110 */
+	0xfe, /* 11111110 */
+	0xfe, /* 11111110 */
+	0xd6, /* 11010110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 78 0x4e 'N' */
+	0xc6, /* 11000110 */
+	0xe6, /* 11100110 */
+	0xf6, /* 11110110 */
+	0xde, /* 11011110 */
+	0xce, /* 11001110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 79 0x4f 'O' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 80 0x50 'P' */
+	0xfc, /* 11111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+
+	/* 81 0x51 'Q' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xce, /* 11001110 */
+	0x7c, /* 01111100 */
+	0x0e, /* 00001110 */
+
+	/* 82 0x52 'R' */
+	0xfc, /* 11111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x6c, /* 01101100 */
+	0x66, /* 01100110 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+
+	/* 83 0x53 'S' */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 84 0x54 'T' */
+	0x7e, /* 01111110 */
+	0x7e, /* 01111110 */
+	0x5a, /* 01011010 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 85 0x55 'U' */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 86 0x56 'V' */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+
+	/* 87 0x57 'W' */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+
+	/* 88 0x58 'X' */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 89 0x59 'Y' */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 90 0x5a 'Z' */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0x8c, /* 10001100 */
+	0x18, /* 00011000 */
+	0x32, /* 00110010 */
+	0x66, /* 01100110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+
+	/* 91 0x5b '[' */
+	0x3c, /* 00111100 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 92 0x5c '\' */
+	0xc0, /* 11000000 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x06, /* 00000110 */
+	0x02, /* 00000010 */
+	0x00, /* 00000000 */
+
+	/* 93 0x5d ']' */
+	0x3c, /* 00111100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 94 0x5e '^' */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 95 0x5f '_' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+
+	/* 96 0x60 '`' */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 97 0x61 'a' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 98 0x62 'b' */
+	0xe0, /* 11100000 */
+	0x60, /* 01100000 */
+	0x7c, /* 01111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+
+	/* 99 0x63 'c' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 100 0x64 'd' */
+	0x1c, /* 00011100 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 101 0x65 'e' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 102 0x66 'f' */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x60, /* 01100000 */
+	0xf8, /* 11111000 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+
+	/* 103 0x67 'g' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x7c, /* 01111100 */
+	0x0c, /* 00001100 */
+	0xf8, /* 11111000 */
+
+	/* 104 0x68 'h' */
+	0xe0, /* 11100000 */
+	0x60, /* 01100000 */
+	0x6c, /* 01101100 */
+	0x76, /* 01110110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+
+	/* 105 0x69 'i' */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 106 0x6a 'j' */
+	0x06, /* 00000110 */
+	0x00, /* 00000000 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+
+	/* 107 0x6b 'k' */
+	0xe0, /* 11100000 */
+	0x60, /* 01100000 */
+	0x66, /* 01100110 */
+	0x6c, /* 01101100 */
+	0x78, /* 01111000 */
+	0x6c, /* 01101100 */
+	0xe6, /* 11100110 */
+	0x00, /* 00000000 */
+
+	/* 108 0x6c 'l' */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 109 0x6d 'm' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xec, /* 11101100 */
+	0xfe, /* 11111110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0x00, /* 00000000 */
+
+	/* 110 0x6e 'n' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+
+	/* 111 0x6f 'o' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 112 0x70 'p' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+
+	/* 113 0x71 'q' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x7c, /* 01111100 */
+	0x0c, /* 00001100 */
+	0x1e, /* 00011110 */
+
+	/* 114 0x72 'r' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x76, /* 01110110 */
+	0x60, /* 01100000 */
+	0x60, /* 01100000 */
+	0xf0, /* 11110000 */
+	0x00, /* 00000000 */
+
+	/* 115 0x73 's' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x06, /* 00000110 */
+	0xfc, /* 11111100 */
+	0x00, /* 00000000 */
+
+	/* 116 0x74 't' */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0xfc, /* 11111100 */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x36, /* 00110110 */
+	0x1c, /* 00011100 */
+	0x00, /* 00000000 */
+
+	/* 117 0x75 'u' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 118 0x76 'v' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+
+	/* 119 0x77 'w' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xd6, /* 11010110 */
+	0xd6, /* 11010110 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+
+	/* 120 0x78 'x' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 121 0x79 'y' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7e, /* 01111110 */
+	0x06, /* 00000110 */
+	0xfc, /* 11111100 */
+
+	/* 122 0x7a 'z' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x4c, /* 01001100 */
+	0x18, /* 00011000 */
+	0x32, /* 00110010 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+
+	/* 123 0x7b '{' */
+	0x0e, /* 00001110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x70, /* 01110000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x0e, /* 00001110 */
+	0x00, /* 00000000 */
+
+	/* 124 0x7c '|' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 125 0x7d '}' */
+	0x70, /* 01110000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x0e, /* 00001110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+
+	/* 126 0x7e '~' */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 127 0x7f '' */
+	0x00, /* 00000000 */
+	0x10, /* 00010000 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+
+	/* 128 0x80 '€' */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x0c, /* 00001100 */
+	0x78, /* 01111000 */
+
+	/* 129 0x81 '�' */
+	0xcc, /* 11001100 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 130 0x82 '‚' */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 131 0x83 'ƒ' */
+	0x7c, /* 01111100 */
+	0x82, /* 10000010 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 132 0x84 '„' */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 133 0x85 '…' */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 134 0x86 '†' */
+	0x30, /* 00110000 */
+	0x30, /* 00110000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 135 0x87 '‡' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0x7e, /* 01111110 */
+	0x0c, /* 00001100 */
+	0x38, /* 00111000 */
+
+	/* 136 0x88 'ˆ' */
+	0x7c, /* 01111100 */
+	0x82, /* 10000010 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 137 0x89 '‰' */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 138 0x8a 'Š' */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 139 0x8b '‹' */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 140 0x8c 'Œ' */
+	0x7c, /* 01111100 */
+	0x82, /* 10000010 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 141 0x8d '�' */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 142 0x8e 'Ž' */
+	0xc6, /* 11000110 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 143 0x8f '�' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 144 0x90 '�' */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xf8, /* 11111000 */
+	0xc0, /* 11000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+
+	/* 145 0x91 '‘' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0xd8, /* 11011000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+
+	/* 146 0x92 '’' */
+	0x3e, /* 00111110 */
+	0x6c, /* 01101100 */
+	0xcc, /* 11001100 */
+	0xfe, /* 11111110 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xce, /* 11001110 */
+	0x00, /* 00000000 */
+
+	/* 147 0x93 '“' */
+	0x7c, /* 01111100 */
+	0x82, /* 10000010 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 148 0x94 '”' */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 149 0x95 '•' */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 150 0x96 '–' */
+	0x78, /* 01111000 */
+	0x84, /* 10000100 */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 151 0x97 '—' */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 152 0x98 '˜' */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7e, /* 01111110 */
+	0x06, /* 00000110 */
+	0xfc, /* 11111100 */
+
+	/* 153 0x99 '™' */
+	0xc6, /* 11000110 */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+
+	/* 154 0x9a 'š' */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 155 0x9b '›' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 156 0x9c 'œ' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x64, /* 01100100 */
+	0xf0, /* 11110000 */
+	0x60, /* 01100000 */
+	0x66, /* 01100110 */
+	0xfc, /* 11111100 */
+	0x00, /* 00000000 */
+
+	/* 157 0x9d '�' */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 158 0x9e 'ž' */
+	0xf8, /* 11111000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xfa, /* 11111010 */
+	0xc6, /* 11000110 */
+	0xcf, /* 11001111 */
+	0xc6, /* 11000110 */
+	0xc7, /* 11000111 */
+
+	/* 159 0x9f 'Ÿ' */
+	0x0e, /* 00001110 */
+	0x1b, /* 00011011 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0xd8, /* 11011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+
+	/* 160 0xa0 ' ' */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x7c, /* 01111100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 161 0xa1 '¡' */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x38, /* 00111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 162 0xa2 '¢' */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+
+	/* 163 0xa3 '£' */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 164 0xa4 '¤' */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0xdc, /* 11011100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x00, /* 00000000 */
+
+	/* 165 0xa5 '¥' */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0xe6, /* 11100110 */
+	0xf6, /* 11110110 */
+	0xde, /* 11011110 */
+	0xce, /* 11001110 */
+	0x00, /* 00000000 */
+
+	/* 166 0xa6 '¦' */
+	0x3c, /* 00111100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x3e, /* 00111110 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 167 0xa7 '§' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 168 0xa8 '¨' */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x63, /* 01100011 */
+	0x3e, /* 00111110 */
+	0x00, /* 00000000 */
+
+	/* 169 0xa9 '©' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 170 0xaa 'ª' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x06, /* 00000110 */
+	0x06, /* 00000110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 171 0xab '«' */
+	0x63, /* 01100011 */
+	0xe6, /* 11100110 */
+	0x6c, /* 01101100 */
+	0x7e, /* 01111110 */
+	0x33, /* 00110011 */
+	0x66, /* 01100110 */
+	0xcc, /* 11001100 */
+	0x0f, /* 00001111 */
+
+	/* 172 0xac '¬' */
+	0x63, /* 01100011 */
+	0xe6, /* 11100110 */
+	0x6c, /* 01101100 */
+	0x7a, /* 01111010 */
+	0x36, /* 00110110 */
+	0x6a, /* 01101010 */
+	0xdf, /* 11011111 */
+	0x06, /* 00000110 */
+
+	/* 173 0xad '­' */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 174 0xae '®' */
+	0x00, /* 00000000 */
+	0x33, /* 00110011 */
+	0x66, /* 01100110 */
+	0xcc, /* 11001100 */
+	0x66, /* 01100110 */
+	0x33, /* 00110011 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 175 0xaf '¯' */
+	0x00, /* 00000000 */
+	0xcc, /* 11001100 */
+	0x66, /* 01100110 */
+	0x33, /* 00110011 */
+	0x66, /* 01100110 */
+	0xcc, /* 11001100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 176 0xb0 '°' */
+	0x22, /* 00100010 */
+	0x88, /* 10001000 */
+	0x22, /* 00100010 */
+	0x88, /* 10001000 */
+	0x22, /* 00100010 */
+	0x88, /* 10001000 */
+	0x22, /* 00100010 */
+	0x88, /* 10001000 */
+
+	/* 177 0xb1 '±' */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+	0x55, /* 01010101 */
+	0xaa, /* 10101010 */
+
+	/* 178 0xb2 '²' */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+	0x77, /* 01110111 */
+	0xdd, /* 11011101 */
+
+	/* 179 0xb3 '³' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 180 0xb4 '´' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 181 0xb5 'µ' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 182 0xb6 '¶' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf6, /* 11110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 183 0xb7 '·' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 184 0xb8 '¸' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 185 0xb9 '¹' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf6, /* 11110110 */
+	0x06, /* 00000110 */
+	0xf6, /* 11110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 186 0xba 'º' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 187 0xbb '»' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x06, /* 00000110 */
+	0xf6, /* 11110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 188 0xbc '¼' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf6, /* 11110110 */
+	0x06, /* 00000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 189 0xbd '½' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 190 0xbe '¾' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 191 0xbf '¿' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xf8, /* 11111000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 192 0xc0 'À' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 193 0xc1 'Á' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 194 0xc2 'Â' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 195 0xc3 'Ã' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 196 0xc4 'Ä' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 197 0xc5 'Å' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 198 0xc6 'Æ' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 199 0xc7 'Ç' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x37, /* 00110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 200 0xc8 'È' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x37, /* 00110111 */
+	0x30, /* 00110000 */
+	0x3f, /* 00111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 201 0xc9 'É' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3f, /* 00111111 */
+	0x30, /* 00110000 */
+	0x37, /* 00110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 202 0xca 'Ê' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf7, /* 11110111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 203 0xcb 'Ë' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xf7, /* 11110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 204 0xcc 'Ì' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x37, /* 00110111 */
+	0x30, /* 00110000 */
+	0x37, /* 00110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 205 0xcd 'Í' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 206 0xce 'Î' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xf7, /* 11110111 */
+	0x00, /* 00000000 */
+	0xf7, /* 11110111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 207 0xcf 'Ï' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 208 0xd0 'Ð' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 209 0xd1 'Ñ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 210 0xd2 'Ò' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 211 0xd3 'Ó' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x3f, /* 00111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 212 0xd4 'Ô' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 213 0xd5 'Õ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 214 0xd6 'Ö' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3f, /* 00111111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 215 0xd7 '×' */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0xff, /* 11111111 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+
+	/* 216 0xd8 'Ø' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0xff, /* 11111111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 217 0xd9 'Ù' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xf8, /* 11111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 218 0xda 'Ú' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x1f, /* 00011111 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 219 0xdb 'Û' */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+
+	/* 220 0xdc 'Ü' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+
+	/* 221 0xdd 'Ý' */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+	0xf0, /* 11110000 */
+
+	/* 222 0xde 'Þ' */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+	0x0f, /* 00001111 */
+
+	/* 223 0xdf 'ß' */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0xff, /* 11111111 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 224 0xe0 'à' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0xc8, /* 11001000 */
+	0xdc, /* 11011100 */
+	0x76, /* 01110110 */
+	0x00, /* 00000000 */
+
+	/* 225 0xe1 'á' */
+	0x78, /* 01111000 */
+	0xcc, /* 11001100 */
+	0xcc, /* 11001100 */
+	0xd8, /* 11011000 */
+	0xcc, /* 11001100 */
+	0xc6, /* 11000110 */
+	0xcc, /* 11001100 */
+	0x00, /* 00000000 */
+
+	/* 226 0xe2 'â' */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0xc0, /* 11000000 */
+	0x00, /* 00000000 */
+
+	/* 227 0xe3 'ã' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x00, /* 00000000 */
+
+	/* 228 0xe4 'ä' */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+
+	/* 229 0xe5 'å' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0x70, /* 01110000 */
+	0x00, /* 00000000 */
+
+	/* 230 0xe6 'æ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x7c, /* 01111100 */
+	0xc0, /* 11000000 */
+
+	/* 231 0xe7 'ç' */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+
+	/* 232 0xe8 'è' */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x3c, /* 00111100 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+
+	/* 233 0xe9 'é' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xfe, /* 11111110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+
+	/* 234 0xea 'ê' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0xee, /* 11101110 */
+	0x00, /* 00000000 */
+
+	/* 235 0xeb 'ë' */
+	0x0e, /* 00001110 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x3e, /* 00111110 */
+	0x66, /* 01100110 */
+	0x66, /* 01100110 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+
+	/* 236 0xec 'ì' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 237 0xed 'í' */
+	0x06, /* 00000110 */
+	0x0c, /* 00001100 */
+	0x7e, /* 01111110 */
+	0xdb, /* 11011011 */
+	0xdb, /* 11011011 */
+	0x7e, /* 01111110 */
+	0x60, /* 01100000 */
+	0xc0, /* 11000000 */
+
+	/* 238 0xee 'î' */
+	0x1e, /* 00011110 */
+	0x30, /* 00110000 */
+	0x60, /* 01100000 */
+	0x7e, /* 01111110 */
+	0x60, /* 01100000 */
+	0x30, /* 00110000 */
+	0x1e, /* 00011110 */
+	0x00, /* 00000000 */
+
+	/* 239 0xef 'ï' */
+	0x00, /* 00000000 */
+	0x7c, /* 01111100 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0xc6, /* 11000110 */
+	0x00, /* 00000000 */
+
+	/* 240 0xf0 'ð' */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0xfe, /* 11111110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 241 0xf1 'ñ' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x7e, /* 01111110 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+
+	/* 242 0xf2 'ò' */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+
+	/* 243 0xf3 'ó' */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x18, /* 00011000 */
+	0x0c, /* 00001100 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+
+	/* 244 0xf4 'ô' */
+	0x0e, /* 00001110 */
+	0x1b, /* 00011011 */
+	0x1b, /* 00011011 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+
+	/* 245 0xf5 'õ' */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0xd8, /* 11011000 */
+	0xd8, /* 11011000 */
+	0x70, /* 01110000 */
+
+	/* 246 0xf6 'ö' */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x7e, /* 01111110 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 247 0xf7 '÷' */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0x76, /* 01110110 */
+	0xdc, /* 11011100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 248 0xf8 'ø' */
+	0x38, /* 00111000 */
+	0x6c, /* 01101100 */
+	0x6c, /* 01101100 */
+	0x38, /* 00111000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 249 0xf9 'ù' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 250 0xfa 'ú' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 00011000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 251 0xfb 'û' */
+	0x0f, /* 00001111 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0x0c, /* 00001100 */
+	0xec, /* 11101100 */
+	0x6c, /* 01101100 */
+	0x3c, /* 00111100 */
+	0x1c, /* 00011100 */
+
+	/* 252 0xfc 'ü' */
+	0x6c, /* 01101100 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x36, /* 00110110 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 253 0xfd 'ý' */
+	0x78, /* 01111000 */
+	0x0c, /* 00001100 */
+	0x18, /* 00011000 */
+	0x30, /* 00110000 */
+	0x7c, /* 01111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 254 0xfe 'þ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x3c, /* 00111100 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 255 0xff 'ÿ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+};
+
+
+struct font_desc font_vga_8x8 = {
+	VGA8x8_IDX,
+	"VGA8x8",
+	8,
+	8,
+	fontdata_8x8,
+	0
+};
diff -Nru a/drivers/video/console/font_acorn_8x8.c b/drivers/video/console/font_acorn_8x8.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/font_acorn_8x8.c	Mon Dec  9 18:46:36 2002
@@ -0,0 +1,277 @@
+/* Acorn-like font definition, with PC graphics characters */
+
+#include <linux/config.h>
+
+#include "font.h"
+
+static unsigned char acorndata_8x8[] = {
+/* 00 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ^@ */
+/* 01 */  0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, /* ^A */
+/* 02 */  0x7e, 0xff, 0xbd, 0xff, 0xc3, 0xe7, 0xff, 0x7e, /* ^B */
+/* 03 */  0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, /* ^C */
+/* 04 */  0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, /* ^D */
+/* 05 */  0x00, 0x18, 0x3c, 0xe7, 0xe7, 0x3c, 0x18, 0x00, /* ^E */
+/* 06 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 07 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 08 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 09 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0A */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0B */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0C */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0D */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0E */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0F */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 10 */  0x00, 0x60, 0x78, 0x7e, 0x7e, 0x78, 0x60, 0x00, /* |> */
+/* 11 */  0x00, 0x06, 0x1e, 0x7e, 0x7e, 0x1e, 0x06, 0x00, /* <| */
+/* 12 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 13 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 14 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 15 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 16 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 17 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 18 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 19 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 1A */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 1B */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 1C */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 1D */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 1E */  0x00, 0x18, 0x18, 0x3c, 0x3c, 0x7e, 0x7e, 0x00, /* /\ */
+/* 1F */  0x00, 0x7e, 0x7e, 0x3c, 0x3c, 0x18, 0x18, 0x00, /* \/ */
+/* 20 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*	 */
+/* 21 */  0x18, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x00, /* ! */
+/* 22 */  0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, /* " */
+/* 23 */  0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00, /* # */
+/* 24 */  0x0C, 0x3F, 0x68, 0x3E, 0x0B, 0x7E, 0x18, 0x00, /* $ */
+/* 25 */  0x60, 0x66, 0x0C, 0x18, 0x30, 0x66, 0x06, 0x00, /* % */
+/* 26 */  0x38, 0x6C, 0x6C, 0x38, 0x6D, 0x66, 0x3B, 0x00, /* & */
+/* 27 */  0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, /* ' */
+/* 28 */  0x0C, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x00, /* ( */
+/* 29 */  0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00, /* ) */
+/* 2A */  0x00, 0x18, 0x7E, 0x3C, 0x7E, 0x18, 0x00, 0x00, /* * */
+/* 2B */  0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, /* + */
+/* 2C */  0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, /* , */
+/* 2D */  0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, /* - */
+/* 2E */  0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, /* . */
+/* 2F */  0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, /* / */
+/* 30 */  0x3C, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x3C, 0x00, /* 0 */
+/* 31 */  0x18, 0x38, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, /* 1 */
+/* 32 */  0x3C, 0x66, 0x06, 0x0C, 0x18, 0x30, 0x7E, 0x00, /* 2 */
+/* 33 */  0x3C, 0x66, 0x06, 0x1C, 0x06, 0x66, 0x3C, 0x00, /* 3 */
+/* 34 */  0x0C, 0x1C, 0x3C, 0x6C, 0x7E, 0x0C, 0x0C, 0x00, /* 4 */
+/* 35 */  0x7E, 0x60, 0x7C, 0x06, 0x06, 0x66, 0x3C, 0x00, /* 5 */
+/* 36 */  0x1C, 0x30, 0x60, 0x7C, 0x66, 0x66, 0x3C, 0x00, /* 6 */
+/* 37 */  0x7E, 0x06, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00, /* 7 */
+/* 38 */  0x3C, 0x66, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00, /* 8 */
+/* 39 */  0x3C, 0x66, 0x66, 0x3E, 0x06, 0x0C, 0x38, 0x00, /* 9 */
+/* 3A */  0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, /* : */
+/* 3B */  0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x30, /* ; */
+/* 3C */  0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x00, /* < */
+/* 3D */  0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00, /* = */ 
+/* 3E */  0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x00, /* > */
+/* 3F */  0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00, /* ? */
+/* 40 */  0x3C, 0x66, 0x6E, 0x6A, 0x6E, 0x60, 0x3C, 0x00, /* @ */
+/* 41 */  0x3C, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, /* A */
+/* 42 */  0x7C, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x7C, 0x00, /* B */
+/* 43 */  0x3C, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3C, 0x00, /* C */
+/* 44 */  0x78, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0x78, 0x00, /* D */
+/* 45 */  0x7E, 0x60, 0x60, 0x7C, 0x60, 0x60, 0x7E, 0x00, /* E */
+/* 46 */  0x7E, 0x60, 0x60, 0x7C, 0x60, 0x60, 0x60, 0x00, /* F */
+/* 47 */  0x3C, 0x66, 0x60, 0x6E, 0x66, 0x66, 0x3C, 0x00, /* G */
+/* 48 */  0x66, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, /* H */
+/* 49 */  0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, /* I */
+/* 4A */  0x3E, 0x0C, 0x0C, 0x0C, 0x0C, 0x6C, 0x38, 0x00, /* J */
+/* 4B */  0x66, 0x6C, 0x78, 0x70, 0x78, 0x6C, 0x66, 0x00, /* K */
+/* 4C */  0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7E, 0x00, /* L */
+/* 4D */  0x63, 0x77, 0x7F, 0x6B, 0x6B, 0x63, 0x63, 0x00, /* M */
+/* 4E */  0x66, 0x66, 0x76, 0x7E, 0x6E, 0x66, 0x66, 0x00, /* N */
+/* 4F */  0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, /* O */
+/* 50 */  0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0x00, /* P */
+/* 51 */  0x3C, 0x66, 0x66, 0x66, 0x6A, 0x6C, 0x36, 0x00, /* Q */
+/* 52 */  0x7C, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0x66, 0x00, /* R */
+/* 53 */  0x3C, 0x66, 0x60, 0x3C, 0x06, 0x66, 0x3C, 0x00, /* S */
+/* 54 */  0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, /* T */
+/* 55 */  0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, /* U */
+/* 56 */  0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, /* V */
+/* 57 */  0x63, 0x63, 0x6B, 0x6B, 0x7F, 0x77, 0x63, 0x00, /* W */
+/* 58 */  0x66, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00, /* X */
+/* 59 */  0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00, /* Y */
+/* 5A */  0x7E, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x7E, 0x00, /* Z */
+/* 5B */  0x7C, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7C, 0x00, /* [ */
+/* 5C */  0x00, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00, 0x00, /* \ */
+/* 5D */  0x3E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3E, 0x00, /* ] */
+/* 5E */  0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ^ */
+/* 5F */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, /* _ */
+/* 60 */  0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ` */
+/* 61 */  0x00, 0x00, 0x3C, 0x06, 0x3E, 0x66, 0x3E, 0x00, /* a */
+/* 62 */  0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x7C, 0x00, /* b */
+/* 63 */  0x00, 0x00, 0x3C, 0x66, 0x60, 0x66, 0x3C, 0x00, /* c */
+/* 64 */  0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x3E, 0x00, /* d */
+/* 65 */  0x00, 0x00, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00, /* e */
+/* 66 */  0x1C, 0x30, 0x30, 0x7C, 0x30, 0x30, 0x30, 0x00, /* f */
+/* 67 */  0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x3C, /* g */
+/* 68 */  0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x00, /* h */
+/* 69 */  0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00, /* i */
+/* 6A */  0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x70, /* j */
+/* 6B */  0x60, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0x00, /* k */
+/* 6C */  0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, /* l */
+/* 6D */  0x00, 0x00, 0x36, 0x7F, 0x6B, 0x6B, 0x63, 0x00, /* m */
+/* 6E */  0x00, 0x00, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x00, /* n */
+/* 6F */  0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00, /* o */
+/* 70 */  0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60, /* p */
+/* 71 */  0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x07, /* q */
+/* 72 */  0x00, 0x00, 0x6C, 0x76, 0x60, 0x60, 0x60, 0x00, /* r */
+/* 73 */  0x00, 0x00, 0x3E, 0x60, 0x3C, 0x06, 0x7C, 0x00, /* s */
+/* 74 */  0x30, 0x30, 0x7C, 0x30, 0x30, 0x30, 0x1C, 0x00, /* t */
+/* 75 */  0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x00, /* u */
+/* 76 */  0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, /* v */
+/* 77 */  0x00, 0x00, 0x63, 0x6B, 0x6B, 0x7F, 0x36, 0x00, /* w */
+/* 78 */  0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00, /* x */
+/* 79 */  0x00, 0x00, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x3C, /* y */
+/* 7A */  0x00, 0x00, 0x7E, 0x0C, 0x18, 0x30, 0x7E, 0x00, /* z */
+/* 7B */  0x0C, 0x18, 0x18, 0x70, 0x18, 0x18, 0x0C, 0x00, /* { */
+/* 7C */  0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, /* | */
+/* 7D */  0x30, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x30, 0x00, /* } */
+/* 7E */  0x31, 0x6B, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, /* ~ */
+/* 7F */  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  /*  */
+/* 80 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 81 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 82 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 83 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 84 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 85 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 86 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 87 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 88 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 89 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 8A */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 8B */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 8C */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 8D */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 8E */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 8F */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 90 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 91 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 92 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 93 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 94 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 95 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 96 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 97 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 98 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 99 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 9A */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 9B */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 9C */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 9D */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 9E */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 9F */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* A0 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* A1 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* A2 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* A3 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* A4 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* A5 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* A6 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* A7 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* A8 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* A9 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* AA */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* AB */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* AC */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* AD */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* AE */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* AF */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* B0 */  0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88,
+/* B1 */  0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
+/* B2 */  0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
+/* B3 */  0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+/* B4 */  0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18,
+/* B5 */  0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18,
+/* B6 */  0x66, 0x66, 0x66, 0xe6, 0x66, 0x66, 0x66, 0x66,
+/* B7 */  0x00, 0x00, 0x00, 0xfe, 0x66, 0x66, 0x66, 0x66,
+/* B8 */  0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18,
+/* B9 */  0x66, 0x66, 0xe6, 0x06, 0xe6, 0x66, 0x66, 0x66,
+/* BA */  0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+/* BB */  0x00, 0x00, 0xfe, 0x06, 0xe6, 0x66, 0x66, 0x66,
+/* BC */  0x66, 0x66, 0xe6, 0x06, 0xfe, 0x00, 0x00, 0x00,
+/* BD */  0x66, 0x66, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
+/* BE */  0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00,
+/* BF */  0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18,
+/* C0 */  0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00,
+/* C1 */  0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00,
+/* C2 */  0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18,
+/* C3 */  0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
+/* C4 */  0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
+/* C5 */  0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18,
+/* C6 */  0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18,
+/* C7 */  0x66, 0x66, 0x66, 0x67, 0x66, 0x66, 0x66, 0x66,
+/* C8 */  0x66, 0x66, 0x67, 0x60, 0x7f, 0x00, 0x00, 0x00,
+/* C9 */  0x00, 0x00, 0x7f, 0x60, 0x67, 0x66, 0x66, 0x66,
+/* CA */  0x66, 0x66, 0xe7, 0x00, 0xff, 0x00, 0x00, 0x00,
+/* CB */  0x00, 0x00, 0xff, 0x00, 0xe7, 0x66, 0x66, 0x66,
+/* CC */  0x66, 0x66, 0x67, 0x60, 0x67, 0x66, 0x66, 0x66,
+/* CD */  0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
+/* CE */  0x66, 0x66, 0xe7, 0x00, 0xe7, 0x66, 0x66, 0x66,
+/* CF */  0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
+/* D0 */  0x66, 0x66, 0x66, 0xff, 0x00, 0x00, 0x00, 0x00,
+/* D1 */  0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18,
+/* D2 */  0x00, 0x00, 0x00, 0xff, 0x66, 0x66, 0x66, 0x66,
+/* D3 */  0x66, 0x66, 0x66, 0x7f, 0x00, 0x00, 0x00, 0x00,
+/* D4 */  0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00,
+/* D5 */  0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18,
+/* D6 */  0x00, 0x00, 0x00, 0x7f, 0x66, 0x66, 0x66, 0x66,
+/* D7 */  0x66, 0x66, 0x66, 0xff, 0x66, 0x66, 0x66, 0x66,
+/* D8 */  0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18,
+/* D9 */  0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00,
+/* DA */  0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18,
+/* DB */  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+/* DC */  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+/* DD */  0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+/* DE */  0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+/* DF */  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+/* E0 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* E1 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* E2 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* E3 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* E4 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* E5 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* E6 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* E7 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* E8 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* E9 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* EA */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* EB */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* EC */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* ED */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* EE */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* EF */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* F0 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* F1 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* F2 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* F3 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* F4 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* F5 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* F6 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* F7 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* F8 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* F9 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* FA */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* FB */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* FC */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* FD */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* FE */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* FF */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+struct font_desc font_acorn_8x8 = {
+	ACORN8x8_IDX,
+	"Acorn8x8",
+	8,
+	8,
+	acorndata_8x8,
+#ifdef CONFIG_ARCH_ACORN
+	20
+#else
+	0
+#endif
+};
diff -Nru a/drivers/video/console/font_mini_4x6.c b/drivers/video/console/font_mini_4x6.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/font_mini_4x6.c	Mon Dec  9 18:46:36 2002
@@ -0,0 +1,2158 @@
+
+/* Hand composed "Miniscule" 4x6 font, with binary data generated using
+ * Perl stub.
+ *
+ * Use 'perl -x mini_4x6.c < mini_4x6.c > new_version.c' to regenerate
+ * binary data.
+ *
+ * Created by Kenneth Albanowski.
+ * No rights reserved, released to the public domain.
+ *
+ * Version 1.0
+ */
+
+/*
+
+#!/usr/bin/perl -pn
+
+s{((0x)?[0-9a-fA-F]+)(.*\[([\*\ ]{4})\])}{
+
+	($num,$pat,$bits) = ($1,$3,$4);
+	
+	$bits =~ s/([^\s0])|(.)/ defined($1) + 0 /ge;
+	
+	$num = ord(pack("B8", $bits));
+	$num |= $num >> 4;
+	$num = sprintf("0x%.2x", $num);
+	
+	#print "$num,$pat,$bits\n";
+	
+	$num . $pat;
+}ge;
+
+__END__;
+*/
+
+/* Note: binary data consists of one byte for each row of each character top
+   to bottom, character 0 to character 255, six bytes per character. Each
+   byte contains the same four character bits in both nybbles.
+   MSBit to LSBit = left to right.
+ */
+
+#include "font.h"
+
+#define FONTDATAMAX 1536
+
+static unsigned char fontdata_mini_4x6[FONTDATAMAX] = {
+
+	/*{*/
+	  	/*   Char 0: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 1: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 2: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 3: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 4: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 5: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 6: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 7: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 8: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 9: ' '  */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 10: '' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 11: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 12: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 13: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 14: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 15: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 16: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 17: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 18: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 19: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 20: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 21: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 22: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 23: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 24: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 25: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 26: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 27: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 28: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 29: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 30: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 31: ' ' */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 32: ' ' */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 33: '!' */
+	0x44,	/*=  [ *  ]       */
+	0x44,	/*=  [ *  ]       */
+	0x44,	/*=  [ *  ]       */
+	0x00,	/*=  [    ]       */
+	0x44,	/*=  [ *  ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 34: '"' */
+	0xaa,	/*=  [* * ]       */
+	0xaa,	/*=  [* * ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 35: '#' */
+	0xaa,	/*=  [* * ]       */
+	0xff,	/*=  [****]       */
+	0xff,	/*=  [****]       */
+	0xaa,	/*=  [* * ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 36: '$' */
+	0x44,	/*=  [ *  ]       */
+	0x66,	/*=  [ ** ]       */
+	0xee,	/*=  [*** ]       */
+	0xcc,	/*=  [**  ]       */
+	0x44,	/*=  [ *  ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 37: '%' */
+	0xaa,	/*=  [* * ]       */
+	0x22,	/*=  [  * ]       */
+	0x44,	/*=  [ *  ]       */
+	0x88,	/*=  [*   ]       */
+	0xaa,	/*=  [* * ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 38: '&' */
+	0x66,	/*=  [ ** ]       */
+	0x99,	/*=  [*  *]       */
+	0x66,	/*=  [ ** ]       */
+	0xaa,	/*=  [* * ]       */
+	0xdd,	/*=  [** *]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 39: ''' */
+	0x22,	/*=  [  * ]       */
+	0x44,	/*=  [ *  ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 40: '(' */
+	0x22,	/*=  [  * ]       */
+	0x44,	/*=  [ *  ]       */
+	0x44,	/*=  [ *  ]       */
+	0x44,	/*=  [ *  ]       */
+	0x22,	/*=  [  * ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 41: ')' */
+	0x44,	/*=  [ *  ]       */
+	0x22,	/*=  [  * ]       */
+	0x22,	/*=  [  * ]       */
+	0x22,	/*=  [  * ]       */
+	0x44,	/*=  [ *  ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 42: '*' */
+	0x00,	/*=  [    ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 43: '+' */
+	0x00,	/*=  [    ]       */
+	0x44,	/*=  [ *  ]       */
+	0xee,	/*=  [*** ]       */
+	0x44,	/*=  [ *  ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 44: ',' */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x44,	/*=  [ *  ]       */
+	0x88,	/*=  [*   ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 45: '-' */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0xee,	/*=  [*** ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 46: '.' */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	0x44,	/*=  [ *  ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 47: '/' */
+	0x00,	/*=  [    ]       */
+	0x22,	/*=  [  * ]       */
+	0x44,	/*=  [ *  ]       */
+	0x88,	/*=  [*   ]       */
+	0x00,	/*=  [    ]       */
+	0x00,	/*=  [    ]       */
+	/*}*/
+	/*{*/
+	  	/*   Char 48: '0'   */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/
+	  	/*   Char 49: '1'   */
+	0x44,	/*=   [ *  ]        */
+	0xcc,	/*=   [**  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/
+	  	/*   Char 50: '2'   */
+	0xcc,	/*=   [**  ]        */
+	0x22,	/*=   [  * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/
+	  	/*   Char 51: '3'   */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x22,	/*=   [  * ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 52: '4'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 53: '5'   */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 54: '6'   */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 55: '7'   */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 56: '8'   */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 57: '9'   */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 58: ':'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 59: ';'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x88,	/*=   [*   ]        */
+	/*}*/
+	/*{*/ 	/*   Char 60: '<'   */
+	0x22,	/*=   [  * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x88,	/*=   [*   ]        */
+	0x44,	/*=   [ *  ]        */
+	0x22,	/*=   [  * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 61: '='   */
+	0x00,	/*=   [    ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 62: '>'   */
+	0x88,	/*=   [*   ]        */
+	0x44,	/*=   [ *  ]        */
+	0x22,	/*=   [  * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x88,	/*=   [*   ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 63: '?'   */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 64: '@'   */
+	0x44,	/*=   [ *  ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 65: 'A'   */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 66: 'B'   */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 67: 'C'   */
+	0x66,	/*=   [ ** ]        */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 68: 'D'   */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 69: 'E'   */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 70: 'F'   */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 71: 'G'   */
+	0x66,	/*=   [ ** ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 72: 'H'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 73: 'I'   */
+	0xee,	/*=   [*** ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 74: 'J'   */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 75: 'K'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 76: 'L'   */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 77: 'M'   */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 78: 'N'   */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 79: 'O'   */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 80: 'P'   */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 81: 'Q'   */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 82: 'R'   */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 83: 'S'   */
+	0x66,	/*=   [ ** ]        */
+	0x88,	/*=   [*   ]        */
+	0x44,	/*=   [ *  ]        */
+	0x22,	/*=   [  * ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 84: 'T'   */
+	0xee,	/*=   [*** ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 85: 'U'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 86: 'V'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 87: 'W'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 88: 'X'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 89: 'Y'   */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 90: 'Z'   */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x88,	/*=   [*   ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 91: '['   */
+	0x66,	/*=   [ ** ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 92: '\'   */
+	0x00,	/*=   [    ]        */
+	0x88,	/*=   [*   ]        */
+	0x44,	/*=   [ *  ]        */
+	0x22,	/*=   [  * ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 93: ']'   */
+	0x66,	/*=   [ ** ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 94: '^'   */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 95: '_'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	/*}*/
+	/*{*/ 	/*   Char 96: '`'   */
+	0x88,	/*=   [*   ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 97: 'a'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x66,	/*=   [ ** ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 98: 'b'   */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 99: 'c'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x66,	/*=   [ ** ]        */
+	0x88,	/*=   [*   ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 100: 'd'   */
+	0x22,	/*=   [  * ]        */
+	0x22,	/*=   [  * ]        */
+	0x66,	/*=   [ ** ]        */
+	0xaa,	/*=   [* * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 101: 'e'   */
+	0x00,	/*=   [    ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x88,	/*=   [*   ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 102: 'f'   */
+	0x22,	/*=   [  * ]        */
+	0x44,	/*=   [ *  ]        */
+	0xee,	/*=   [*** ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 103: 'g'   */
+	0x00,	/*=   [    ]        */
+	0x66,	/*=   [ ** ]        */
+	0xaa,	/*=   [* * ]        */
+	0x66,	/*=   [ ** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 104: 'h'   */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 105: 'i'   */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 106: 'j'   */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x88,	/*=   [*   ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 107: 'k'   */
+	0x00,	/*=   [    ]        */
+	0x88,	/*=   [*   ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 108: 'l'   */
+	0x00,	/*=   [    ]        */
+	0xcc,	/*=   [**  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 109: 'm'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 110: 'n'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 111: 'o'   */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 112: 'p'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xcc,	/*=   [**  ]        */
+	0x88,	/*=   [*   ]        */
+	/*}*/
+	/*{*/ 	/*   Char 113: 'q'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x66,	/*=   [ ** ]        */
+	0xaa,	/*=   [* * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x22,	/*=   [  * ]        */
+	/*}*/
+	/*{*/ 	/*   Char 114: 'r'   */
+	0x00,	/*=   [    ]        */
+	0xcc,	/*=   [**  ]        */
+	0xaa,	/*=   [* * ]        */
+	0x88,	/*=   [*   ]        */
+	0x88,	/*=   [*   ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 115: 's'   */
+	0x00,	/*=   [    ]        */
+	0x66,	/*=   [ ** ]        */
+	0xcc,	/*=   [**  ]        */
+	0x22,	/*=   [  * ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 116: 't'   */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0xee,	/*=   [*** ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 117: 'u'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 118: 'v'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 119: 'w'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 120: 'x'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xaa,	/*=   [* * ]        */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 121: 'y'   */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x22,	/*=   [  * ]        */
+	0xcc,	/*=   [**  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 122: 'z' */
+	0x00,	/*=   [    ]        */
+	0xee,	/*=   [*** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xcc,	/*=   [**  ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 123: '{' */
+	0x22,	/*=   [  * ]        */
+	0x44,	/*=   [ *  ]        */
+	0xcc,	/*=   [**  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x22,	/*=   [  * ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 124: '|' */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 125: '}' */
+	0x88,	/*=   [*   ]        */
+	0x44,	/*=   [ *  ]        */
+	0x66,	/*=   [ ** ]        */
+	0x44,	/*=   [ *  ]        */
+	0x88,	/*=   [*   ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 126: '~' */
+	0x55,	/*=   [ * *]        */
+	0xaa,	/*=   [* * ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 127: '' */
+	0x44,	/*=   [ *  ]        */
+	0xaa,	/*=   [* * ]        */
+	0xaa,	/*=   [* * ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 128:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 129:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 130:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 131:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 132:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 133:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 134:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 135:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 136:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 137:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 138:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 139:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 140:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 141:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 142:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 143:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 144:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 145:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 146:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 147:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 148:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 149:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 150:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 151:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 152:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 153:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 154:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 155:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 156:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 157:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 158:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 159:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 160:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 161:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 162:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 163:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 164:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 165:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 166:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 167:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 168:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 169:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 170:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 171:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 172:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 173:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 174:  */
+	0x00,	/*=   [    ]        */
+	0x66,	/*=   [ ** ]        */
+	0xcc,	/*=   [**  ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 175:  */
+	0x00,	/*=   [    ]        */
+	0xcc,	/*=   [**  ]        */
+	0x66,	/*=   [ ** ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 176:  */
+	0x88,	/*=   [*   ]        */
+	0x22,	/*=   [  * ]        */
+	0x88,	/*=   [*   ]        */
+	0x22,	/*=   [  * ]        */
+	0x88,	/*=   [*   ]        */
+	0x22,	/*=   [  * ]        */
+	/*}*/
+	/*{*/ 	/*   Char 177:  */
+	0xaa,	/*=   [* * ]        */
+	0x55,	/*=   [ * *]        */
+	0xaa,	/*=   [* * ]        */
+	0x55,	/*=   [ * *]        */
+	0xaa,	/*=   [* * ]        */
+	0x55,	/*=   [ * *]        */
+	/*}*/
+	/*{*/ 	/*   Char 178:  */
+	0xdd,	/*=   [** *]        */
+	0xbb,	/*=   [* **]        */
+	0xdd,	/*=   [** *]        */
+	0xbb,	/*=   [* **]        */
+	0xdd,	/*=   [** *]        */
+	0xbb,	/*=   [* **]        */
+	/*}*/
+	/*{*/ 	/*   Char 179:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 180:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xcc,	/*=   [**  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 181:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 182:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xee,	/*=   [*** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 183:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xee,	/*=   [*** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 184:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 185:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 186:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 187:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 188:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 189:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 190:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 191:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xcc,	/*=   [**  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 192:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x77,	/*=   [ ***]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 193:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xff,	/*=   [****]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 194:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 195:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x77,	/*=   [ ***]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 196:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 197:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xff,	/*=   [****]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 198:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x77,	/*=   [ ***]        */
+	0x77,	/*=   [ ***]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 199:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x77,	/*=   [ ***]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 200:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x77,	/*=   [ ***]        */
+	0x77,	/*=   [ ***]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 201:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x77,	/*=   [ ***]        */
+	0x77,	/*=   [ ***]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 202:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 203:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 204:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x77,	/*=   [ ***]        */
+	0x77,	/*=   [ ***]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 205:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 206:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 207:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 208:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xff,	/*=   [****]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 209:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 210:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 211:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x77,	/*=   [ ***]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 212:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x77,	/*=   [ ***]        */
+	0x77,	/*=   [ ***]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 213:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x77,	/*=   [ ***]        */
+	0x77,	/*=   [ ***]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 214:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x77,	/*=   [ ***]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 215:  */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0xff,	/*=   [****]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	/*}*/
+	/*{*/ 	/*   Char 216:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 217:  */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0xcc,	/*=   [**  ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 218:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x77,	/*=   [ ***]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	0x44,	/*=   [ *  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 219:  */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	/*}*/
+	/*{*/ 	/*   Char 220:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	/*}*/
+	/*{*/ 	/*   Char 221:  */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	0xcc,	/*=   [**  ]        */
+	/*}*/
+	/*{*/ 	/*   Char 222:  */
+	0x33,	/*=   [  **]        */
+	0x33,	/*=   [  **]        */
+	0x33,	/*=   [  **]        */
+	0x33,	/*=   [  **]        */
+	0x33,	/*=   [  **]        */
+	0x33,	/*=   [  **]        */
+	/*}*/
+	/*{*/ 	/*   Char 223:  */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0xff,	/*=   [****]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 224:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 225:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 226:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 227:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 228:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 229:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 230:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 231:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 232:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 233:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 234:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 235:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 236:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 237:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 238:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 239:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 240:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 241:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 242:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 243:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 244:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 245:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 246:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 247:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 248:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 249:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 250:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 251:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 252:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 253:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 254:  */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	0x66,	/*=   [ ** ]        */
+	0x66,	/*=   [ ** ]        */
+	0x00,	/*=   [    ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+	/*{*/ 	/*   Char 255:  */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0xee,	/*=   [*** ]        */
+	0x00,	/*=   [    ]        */
+	/*}*/
+};
+
+struct font_desc font_mini_4x6 = {
+	MINI4x6_IDX,
+	"MINI4x6",
+	4,
+	6,
+	fontdata_mini_4x6,
+	3
+};
+
diff -Nru a/drivers/video/console/font_pearl_8x8.c b/drivers/video/console/font_pearl_8x8.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/font_pearl_8x8.c	Mon Dec  9 18:46:34 2002
@@ -0,0 +1,2587 @@
+/**********************************************/
+/*                                            */
+/*       Font file generated by cpi2fnt       */
+/*       ------------------------------       */
+/*       Combined with the alpha-numeric      */
+/*       portion of Greg Harp's old PEARL     */
+/*       font (from earlier versions of       */
+/*       linux-m86k) by John Shifflett        */
+/*                                            */
+/**********************************************/
+
+#include "font.h"
+
+#define FONTDATAMAX 2048
+
+static unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
+
+   /* 0 0x00 '^@' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 1 0x01 '^A' */
+   0x7e, /* 01111110 */
+   0x81, /* 10000001 */
+   0xa5, /* 10100101 */
+   0x81, /* 10000001 */
+   0xbd, /* 10111101 */
+   0x99, /* 10011001 */
+   0x81, /* 10000001 */
+   0x7e, /* 01111110 */
+
+   /* 2 0x02 '^B' */
+   0x7e, /* 01111110 */
+   0xff, /* 11111111 */
+   0xdb, /* 11011011 */
+   0xff, /* 11111111 */
+   0xc3, /* 11000011 */
+   0xe7, /* 11100111 */
+   0xff, /* 11111111 */
+   0x7e, /* 01111110 */
+
+   /* 3 0x03 '^C' */
+   0x6c, /* 01101100 */
+   0xfe, /* 11111110 */
+   0xfe, /* 11111110 */
+   0xfe, /* 11111110 */
+   0x7c, /* 01111100 */
+   0x38, /* 00111000 */
+   0x10, /* 00010000 */
+   0x00, /* 00000000 */
+
+   /* 4 0x04 '^D' */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+   0x7c, /* 01111100 */
+   0xfe, /* 11111110 */
+   0x7c, /* 01111100 */
+   0x38, /* 00111000 */
+   0x10, /* 00010000 */
+   0x00, /* 00000000 */
+
+   /* 5 0x05 '^E' */
+   0x38, /* 00111000 */
+   0x7c, /* 01111100 */
+   0x38, /* 00111000 */
+   0xfe, /* 11111110 */
+   0xfe, /* 11111110 */
+   0xd6, /* 11010110 */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+
+   /* 6 0x06 '^F' */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+   0x7c, /* 01111100 */
+   0xfe, /* 11111110 */
+   0xfe, /* 11111110 */
+   0x7c, /* 01111100 */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+
+   /* 7 0x07 '^G' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 8 0x08 '^H' */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xe7, /* 11100111 */
+   0xc3, /* 11000011 */
+   0xc3, /* 11000011 */
+   0xe7, /* 11100111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+
+   /* 9 0x09 '^I' */
+   0x00, /* 00000000 */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x42, /* 01000010 */
+   0x42, /* 01000010 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 10 0x0a '^J' */
+   0xff, /* 11111111 */
+   0xc3, /* 11000011 */
+   0x99, /* 10011001 */
+   0xbd, /* 10111101 */
+   0xbd, /* 10111101 */
+   0x99, /* 10011001 */
+   0xc3, /* 11000011 */
+   0xff, /* 11111111 */
+
+   /* 11 0x0b '^K' */
+   0x0f, /* 00001111 */
+   0x07, /* 00000111 */
+   0x0f, /* 00001111 */
+   0x7d, /* 01111101 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0x78, /* 01111000 */
+
+   /* 12 0x0c '^L' */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+
+   /* 13 0x0d '^M' */
+   0x3f, /* 00111111 */
+   0x33, /* 00110011 */
+   0x3f, /* 00111111 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x70, /* 01110000 */
+   0xf0, /* 11110000 */
+   0xe0, /* 11100000 */
+
+   /* 14 0x0e '^N' */
+   0x7f, /* 01111111 */
+   0x63, /* 01100011 */
+   0x7f, /* 01111111 */
+   0x63, /* 01100011 */
+   0x63, /* 01100011 */
+   0x67, /* 01100111 */
+   0xe6, /* 11100110 */
+   0xc0, /* 11000000 */
+
+   /* 15 0x0f '^O' */
+   0x18, /* 00011000 */
+   0xdb, /* 11011011 */
+   0x3c, /* 00111100 */
+   0xe7, /* 11100111 */
+   0xe7, /* 11100111 */
+   0x3c, /* 00111100 */
+   0xdb, /* 11011011 */
+   0x18, /* 00011000 */
+
+   /* 16 0x10 '^P' */
+   0x80, /* 10000000 */
+   0xe0, /* 11100000 */
+   0xf8, /* 11111000 */
+   0xfe, /* 11111110 */
+   0xf8, /* 11111000 */
+   0xe0, /* 11100000 */
+   0x80, /* 10000000 */
+   0x00, /* 00000000 */
+
+   /* 17 0x11 '^Q' */
+   0x02, /* 00000010 */
+   0x0e, /* 00001110 */
+   0x3e, /* 00111110 */
+   0xfe, /* 11111110 */
+   0x3e, /* 00111110 */
+   0x0e, /* 00001110 */
+   0x02, /* 00000010 */
+   0x00, /* 00000000 */
+
+   /* 18 0x12 '^R' */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+
+   /* 19 0x13 '^S' */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x00, /* 00000000 */
+   0x66, /* 01100110 */
+   0x00, /* 00000000 */
+
+   /* 20 0x14 '^T' */
+   0x7f, /* 01111111 */
+   0xdb, /* 11011011 */
+   0xdb, /* 11011011 */
+   0x7b, /* 01111011 */
+   0x1b, /* 00011011 */
+   0x1b, /* 00011011 */
+   0x1b, /* 00011011 */
+   0x00, /* 00000000 */
+
+   /* 21 0x15 '^U' */
+   0x3e, /* 00111110 */
+   0x61, /* 01100001 */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x86, /* 10000110 */
+   0x7c, /* 01111100 */
+
+   /* 22 0x16 '^V' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x7e, /* 01111110 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 23 0x17 '^W' */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+
+   /* 24 0x18 '^X' */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 25 0x19 '^Y' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 26 0x1a '^Z' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0xfe, /* 11111110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 27 0x1b '^[' */
+   0x00, /* 00000000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0xfe, /* 11111110 */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 28 0x1c '^\' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 29 0x1d '^]' */
+   0x00, /* 00000000 */
+   0x24, /* 00100100 */
+   0x66, /* 01100110 */
+   0xff, /* 11111111 */
+   0x66, /* 01100110 */
+   0x24, /* 00100100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 30 0x1e '^^' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x7e, /* 01111110 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 31 0x1f '^_' */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0x7e, /* 01111110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 32 0x20 ' ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 33 0x21 '!' */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 34 0x22 '"' */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 35 0x23 '#' */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0xfe, /* 11111110 */
+   0x6c, /* 01101100 */
+   0xfe, /* 11111110 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x00, /* 00000000 */
+
+   /* 36 0x24 '$' */
+   0x18, /* 00011000 */
+   0x3e, /* 00111110 */
+   0x60, /* 01100000 */
+   0x3c, /* 00111100 */
+   0x06, /* 00000110 */
+   0x7c, /* 01111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 37 0x25 '%' */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xcc, /* 11001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x66, /* 01100110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 38 0x26 '&' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0x68, /* 01101000 */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 39 0x27 ''' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 40 0x28 '(' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x00, /* 00000000 */
+
+   /* 41 0x29 ')' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x00, /* 00000000 */
+
+   /* 42 0x2a '*' */
+   0x00, /* 00000000 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0xff, /* 11111111 */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 43 0x2b '+' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 44 0x2c ',' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+
+   /* 45 0x2d '-' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 46 0x2e '.' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 47 0x2f '/' */
+   0x03, /* 00000011 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+
+   /* 48 0x30 '0' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xde, /* 11011110 */
+   0xfe, /* 11111110 */
+   0xf6, /* 11110110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 49 0x31 '1' */
+   0x18, /* 00011000 */
+   0x78, /* 01111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 50 0x32 '2' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 51 0x33 '3' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0x06, /* 00000110 */
+   0x1c, /* 00011100 */
+   0x06, /* 00000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 52 0x34 '4' */
+   0x1c, /* 00011100 */
+   0x3c, /* 00111100 */
+   0x6c, /* 01101100 */
+   0xcc, /* 11001100 */
+   0xfe, /* 11111110 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x00, /* 00000000 */
+
+   /* 53 0x35 '5' */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0xfc, /* 11111100 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 54 0x36 '6' */
+   0x38, /* 00111000 */
+   0x60, /* 01100000 */
+   0xc0, /* 11000000 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 55 0x37 '7' */
+   0xfe, /* 11111110 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0x60, /* 01100000 */
+   0x00, /* 00000000 */
+
+   /* 56 0x38 '8' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 57 0x39 '9' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+
+   /* 58 0x3a ':' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 59 0x3b ';' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+
+   /* 60 0x3c '<' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x00, /* 00000000 */
+
+   /* 61 0x3d '=' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 62 0x3e '>' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x00, /* 00000000 */
+
+   /* 63 0x3f '?' */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 64 0x40 '@' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xde, /* 11011110 */
+   0xde, /* 11011110 */
+   0xde, /* 11011110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 65 0x41 'A' */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 66 0x42 'B' */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0x00, /* 00000000 */
+
+   /* 67 0x43 'C' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 68 0x44 'D' */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0x00, /* 00000000 */
+
+   /* 69 0x45 'E' */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xf8, /* 11111000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 70 0x46 'F' */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xf8, /* 11111000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+
+   /* 71 0x47 'G' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc0, /* 11000000 */
+   0xce, /* 11001110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 72 0x48 'H' */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 73 0x49 'I' */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 74 0x4a 'J' */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 75 0x4b 'K' */
+   0xc6, /* 11000110 */
+   0xcc, /* 11001100 */
+   0xd8, /* 11011000 */
+   0xf0, /* 11110000 */
+   0xd8, /* 11011000 */
+   0xcc, /* 11001100 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 76 0x4c 'L' */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 77 0x4d 'M' */
+   0x82, /* 10000010 */
+   0xc6, /* 11000110 */
+   0xee, /* 11101110 */
+   0xfe, /* 11111110 */
+   0xd6, /* 11010110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 78 0x4e 'N' */
+   0xc6, /* 11000110 */
+   0xe6, /* 11100110 */
+   0xf6, /* 11110110 */
+   0xde, /* 11011110 */
+   0xce, /* 11001110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 79 0x4f 'O' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 80 0x50 'P' */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+
+   /* 81 0x51 'Q' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xf6, /* 11110110 */
+   0xde, /* 11011110 */
+   0x7c, /* 01111100 */
+   0x06, /* 00000110 */
+
+   /* 82 0x52 'R' */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0xd8, /* 11011000 */
+   0xcc, /* 11001100 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 83 0x53 'S' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0x60, /* 01100000 */
+   0x38, /* 00111000 */
+   0x0c, /* 00001100 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 84 0x54 'T' */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 85 0x55 'U' */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 86 0x56 'V' */
+   0xc3, /* 11000011 */
+   0xc3, /* 11000011 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 87 0x57 'W' */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xd6, /* 11010110 */
+   0xfe, /* 11111110 */
+   0xee, /* 11101110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 88 0x58 'X' */
+   0xc3, /* 11000011 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0xc3, /* 11000011 */
+   0x00, /* 00000000 */
+
+   /* 89 0x59 'Y' */
+   0xc3, /* 11000011 */
+   0xc3, /* 11000011 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 90 0x5a 'Z' */
+   0xfe, /* 11111110 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 91 0x5b '[' */
+   0x3c, /* 00111100 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 92 0x5c '\' */
+   0xc0, /* 11000000 */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x06, /* 00000110 */
+   0x03, /* 00000011 */
+   0x00, /* 00000000 */
+
+   /* 93 0x5d ']' */
+   0x3c, /* 00111100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 94 0x5e '^' */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 95 0x5f '_' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+
+   /* 96 0x60 '`' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 97 0x61 'a' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0x06, /* 00000110 */
+   0x7e, /* 01111110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 98 0x62 'b' */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0x00, /* 00000000 */
+
+   /* 99 0x63 'c' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc0, /* 11000000 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 100 0x64 'd' */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x7e, /* 01111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 101 0x65 'e' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 102 0x66 'f' */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x60, /* 01100000 */
+   0xf0, /* 11110000 */
+   0x60, /* 01100000 */
+   0x60, /* 01100000 */
+   0x60, /* 01100000 */
+   0x00, /* 00000000 */
+
+   /* 103 0x67 'g' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x06, /* 00000110 */
+   0x7c, /* 01111100 */
+
+   /* 104 0x68 'h' */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 105 0x69 'i' */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 106 0x6a 'j' */
+   0x06, /* 00000110 */
+   0x00, /* 00000000 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+
+   /* 107 0x6b 'k' */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xcc, /* 11001100 */
+   0xd8, /* 11011000 */
+   0xf0, /* 11110000 */
+   0xd8, /* 11011000 */
+   0xcc, /* 11001100 */
+   0x00, /* 00000000 */
+
+   /* 108 0x6c 'l' */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 109 0x6d 'm' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xec, /* 11101100 */
+   0xfe, /* 11111110 */
+   0xd6, /* 11010110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 110 0x6e 'n' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 111 0x6f 'o' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 112 0x70 'p' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+
+   /* 113 0x71 'q' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+
+   /* 114 0x72 'r' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xdc, /* 11011100 */
+   0xe6, /* 11100110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+
+   /* 115 0x73 's' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x06, /* 00000110 */
+   0xfc, /* 11111100 */
+   0x00, /* 00000000 */
+
+   /* 116 0x74 't' */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x7c, /* 01111100 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x36, /* 00110110 */
+   0x1c, /* 00011100 */
+   0x00, /* 00000000 */
+
+   /* 117 0x75 'u' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 118 0x76 'v' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+
+   /* 119 0x77 'w' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xd6, /* 11010110 */
+   0xfe, /* 11111110 */
+   0x6c, /* 01101100 */
+   0x00, /* 00000000 */
+
+   /* 120 0x78 'x' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 121 0x79 'y' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc3, /* 11000011 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+
+   /* 122 0x7a 'z' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x0c, /* 00001100 */
+   0x38, /* 00111000 */
+   0x60, /* 01100000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 123 0x7b '{' */
+   0x0e, /* 00001110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x70, /* 01110000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x0e, /* 00001110 */
+   0x00, /* 00000000 */
+
+   /* 124 0x7c '|' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 125 0x7d '}' */
+   0x70, /* 01110000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x0e, /* 00001110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x70, /* 01110000 */
+   0x00, /* 00000000 */
+
+   /* 126 0x7e '~' */
+   0x72, /* 01110010 */
+   0x9c, /* 10011100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 127 0x7f '' */
+   0x00, /* 00000000 */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 128 0x80 '€' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x0c, /* 00001100 */
+   0x78, /* 01111000 */
+
+   /* 129 0x81 '�' */
+   0xcc, /* 11001100 */
+   0x00, /* 00000000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 130 0x82 '‚' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 131 0x83 'ƒ' */
+   0x7c, /* 01111100 */
+   0x82, /* 10000010 */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x7c, /* 01111100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 132 0x84 '„' */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x7c, /* 01111100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 133 0x85 '…' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x7c, /* 01111100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 134 0x86 '†' */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x7c, /* 01111100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 135 0x87 '‡' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x7e, /* 01111110 */
+   0x0c, /* 00001100 */
+   0x38, /* 00111000 */
+
+   /* 136 0x88 'ˆ' */
+   0x7c, /* 01111100 */
+   0x82, /* 10000010 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 137 0x89 '‰' */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 138 0x8a 'Š' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 139 0x8b '‹' */
+   0x66, /* 01100110 */
+   0x00, /* 00000000 */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 140 0x8c 'Œ' */
+   0x7c, /* 01111100 */
+   0x82, /* 10000010 */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 141 0x8d '�' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 142 0x8e 'Ž' */
+   0xc6, /* 11000110 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 143 0x8f '�' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 144 0x90 '�' */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0xf8, /* 11111000 */
+   0xc0, /* 11000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 145 0x91 '‘' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0xd8, /* 11011000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 146 0x92 '’' */
+   0x3e, /* 00111110 */
+   0x6c, /* 01101100 */
+   0xcc, /* 11001100 */
+   0xfe, /* 11111110 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xce, /* 11001110 */
+   0x00, /* 00000000 */
+
+   /* 147 0x93 '“' */
+   0x7c, /* 01111100 */
+   0x82, /* 10000010 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 148 0x94 '”' */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 149 0x95 '•' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 150 0x96 '–' */
+   0x78, /* 01111000 */
+   0x84, /* 10000100 */
+   0x00, /* 00000000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 151 0x97 '—' */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 152 0x98 '˜' */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x06, /* 00000110 */
+   0xfc, /* 11111100 */
+
+   /* 153 0x99 '™' */
+   0xc6, /* 11000110 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+
+   /* 154 0x9a 'š' */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 155 0x9b '›' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 156 0x9c 'œ' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0x64, /* 01100100 */
+   0xf0, /* 11110000 */
+   0x60, /* 01100000 */
+   0x66, /* 01100110 */
+   0xfc, /* 11111100 */
+   0x00, /* 00000000 */
+
+   /* 157 0x9d '�' */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 158 0x9e 'ž' */
+   0xf8, /* 11111000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xfa, /* 11111010 */
+   0xc6, /* 11000110 */
+   0xcf, /* 11001111 */
+   0xc6, /* 11000110 */
+   0xc7, /* 11000111 */
+
+   /* 159 0x9f 'Ÿ' */
+   0x0e, /* 00001110 */
+   0x1b, /* 00011011 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0xd8, /* 11011000 */
+   0x70, /* 01110000 */
+   0x00, /* 00000000 */
+
+   /* 160 0xa0 ' ' */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x7c, /* 01111100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 161 0xa1 '¡' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 162 0xa2 '¢' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 163 0xa3 '£' */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 164 0xa4 '¤' */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0x00, /* 00000000 */
+   0xdc, /* 11011100 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x00, /* 00000000 */
+
+   /* 165 0xa5 '¥' */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0x00, /* 00000000 */
+   0xe6, /* 11100110 */
+   0xf6, /* 11110110 */
+   0xde, /* 11011110 */
+   0xce, /* 11001110 */
+   0x00, /* 00000000 */
+
+   /* 166 0xa6 '¦' */
+   0x3c, /* 00111100 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x3e, /* 00111110 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 167 0xa7 '§' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 168 0xa8 '¨' */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x63, /* 01100011 */
+   0x3e, /* 00111110 */
+   0x00, /* 00000000 */
+
+   /* 169 0xa9 '©' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 170 0xaa 'ª' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 171 0xab '«' */
+   0x63, /* 01100011 */
+   0xe6, /* 11100110 */
+   0x6c, /* 01101100 */
+   0x7e, /* 01111110 */
+   0x33, /* 00110011 */
+   0x66, /* 01100110 */
+   0xcc, /* 11001100 */
+   0x0f, /* 00001111 */
+
+   /* 172 0xac '¬' */
+   0x63, /* 01100011 */
+   0xe6, /* 11100110 */
+   0x6c, /* 01101100 */
+   0x7a, /* 01111010 */
+   0x36, /* 00110110 */
+   0x6a, /* 01101010 */
+   0xdf, /* 11011111 */
+   0x06, /* 00000110 */
+
+   /* 173 0xad '­' */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 174 0xae '®' */
+   0x00, /* 00000000 */
+   0x33, /* 00110011 */
+   0x66, /* 01100110 */
+   0xcc, /* 11001100 */
+   0x66, /* 01100110 */
+   0x33, /* 00110011 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 175 0xaf '¯' */
+   0x00, /* 00000000 */
+   0xcc, /* 11001100 */
+   0x66, /* 01100110 */
+   0x33, /* 00110011 */
+   0x66, /* 01100110 */
+   0xcc, /* 11001100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 176 0xb0 '°' */
+   0x22, /* 00100010 */
+   0x88, /* 10001000 */
+   0x22, /* 00100010 */
+   0x88, /* 10001000 */
+   0x22, /* 00100010 */
+   0x88, /* 10001000 */
+   0x22, /* 00100010 */
+   0x88, /* 10001000 */
+
+   /* 177 0xb1 '±' */
+   0x55, /* 01010101 */
+   0xaa, /* 10101010 */
+   0x55, /* 01010101 */
+   0xaa, /* 10101010 */
+   0x55, /* 01010101 */
+   0xaa, /* 10101010 */
+   0x55, /* 01010101 */
+   0xaa, /* 10101010 */
+
+   /* 178 0xb2 '²' */
+   0x77, /* 01110111 */
+   0xdd, /* 11011101 */
+   0x77, /* 01110111 */
+   0xdd, /* 11011101 */
+   0x77, /* 01110111 */
+   0xdd, /* 11011101 */
+   0x77, /* 01110111 */
+   0xdd, /* 11011101 */
+
+   /* 179 0xb3 '³' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 180 0xb4 '´' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 181 0xb5 'µ' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 182 0xb6 '¶' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xf6, /* 11110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 183 0xb7 '·' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 184 0xb8 '¸' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 185 0xb9 '¹' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xf6, /* 11110110 */
+   0x06, /* 00000110 */
+   0xf6, /* 11110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 186 0xba 'º' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 187 0xbb '»' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x06, /* 00000110 */
+   0xf6, /* 11110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 188 0xbc '¼' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xf6, /* 11110110 */
+   0x06, /* 00000110 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 189 0xbd '½' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 190 0xbe '¾' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 191 0xbf '¿' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 192 0xc0 'À' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 193 0xc1 'Á' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 194 0xc2 'Â' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 195 0xc3 'Ã' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 196 0xc4 'Ä' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 197 0xc5 'Å' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 198 0xc6 'Æ' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 199 0xc7 'Ç' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x37, /* 00110111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 200 0xc8 'È' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x37, /* 00110111 */
+   0x30, /* 00110000 */
+   0x3f, /* 00111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 201 0xc9 'É' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x3f, /* 00111111 */
+   0x30, /* 00110000 */
+   0x37, /* 00110111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 202 0xca 'Ê' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xf7, /* 11110111 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 203 0xcb 'Ë' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0xf7, /* 11110111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 204 0xcc 'Ì' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x37, /* 00110111 */
+   0x30, /* 00110000 */
+   0x37, /* 00110111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 205 0xcd 'Í' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 206 0xce 'Î' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xf7, /* 11110111 */
+   0x00, /* 00000000 */
+   0xf7, /* 11110111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 207 0xcf 'Ï' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 208 0xd0 'Ð' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 209 0xd1 'Ñ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 210 0xd2 'Ò' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 211 0xd3 'Ó' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x3f, /* 00111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 212 0xd4 'Ô' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 213 0xd5 'Õ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 214 0xd6 'Ö' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x3f, /* 00111111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 215 0xd7 '×' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xff, /* 11111111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 216 0xd8 'Ø' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 217 0xd9 'Ù' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 218 0xda 'Ú' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 219 0xdb 'Û' */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+
+   /* 220 0xdc 'Ü' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+
+   /* 221 0xdd 'Ý' */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+
+   /* 222 0xde 'Þ' */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+
+   /* 223 0xdf 'ß' */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 224 0xe0 'à' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0xc8, /* 11001000 */
+   0xdc, /* 11011100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 225 0xe1 'á' */
+   0x78, /* 01111000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xd8, /* 11011000 */
+   0xcc, /* 11001100 */
+   0xc6, /* 11000110 */
+   0xcc, /* 11001100 */
+   0x00, /* 00000000 */
+
+   /* 226 0xe2 'â' */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+
+   /* 227 0xe3 'ã' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x00, /* 00000000 */
+
+   /* 228 0xe4 'ä' */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 229 0xe5 'å' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xd8, /* 11011000 */
+   0xd8, /* 11011000 */
+   0xd8, /* 11011000 */
+   0x70, /* 01110000 */
+   0x00, /* 00000000 */
+
+   /* 230 0xe6 'æ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x7c, /* 01111100 */
+   0xc0, /* 11000000 */
+
+   /* 231 0xe7 'ç' */
+   0x00, /* 00000000 */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 232 0xe8 'è' */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+
+   /* 233 0xe9 'é' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+
+   /* 234 0xea 'ê' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0xee, /* 11101110 */
+   0x00, /* 00000000 */
+
+   /* 235 0xeb 'ë' */
+   0x0e, /* 00001110 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x3e, /* 00111110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 236 0xec 'ì' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xdb, /* 11011011 */
+   0xdb, /* 11011011 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 237 0xed 'í' */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x7e, /* 01111110 */
+   0xdb, /* 11011011 */
+   0xdb, /* 11011011 */
+   0x7e, /* 01111110 */
+   0x60, /* 01100000 */
+   0xc0, /* 11000000 */
+
+   /* 238 0xee 'î' */
+   0x1e, /* 00011110 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0x7e, /* 01111110 */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0x1e, /* 00011110 */
+   0x00, /* 00000000 */
+
+   /* 239 0xef 'ï' */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 240 0xf0 'ð' */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 241 0xf1 'ñ' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 242 0xf2 'ò' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 243 0xf3 'ó' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 244 0xf4 'ô' */
+   0x0e, /* 00001110 */
+   0x1b, /* 00011011 */
+   0x1b, /* 00011011 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 245 0xf5 'õ' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xd8, /* 11011000 */
+   0xd8, /* 11011000 */
+   0x70, /* 01110000 */
+
+   /* 246 0xf6 'ö' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 247 0xf7 '÷' */
+   0x00, /* 00000000 */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0x00, /* 00000000 */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 248 0xf8 'ø' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 249 0xf9 'ù' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 250 0xfa 'ú' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 251 0xfb 'û' */
+   0x0f, /* 00001111 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0xec, /* 11101100 */
+   0x6c, /* 01101100 */
+   0x3c, /* 00111100 */
+   0x1c, /* 00011100 */
+
+   /* 252 0xfc 'ü' */
+   0x6c, /* 01101100 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 253 0xfd 'ý' */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 254 0xfe 'þ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 255 0xff 'ÿ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+};
+
+struct font_desc font_pearl_8x8 = {
+	PEARL8x8_IDX,
+	"PEARL8x8",
+	8,
+	8,
+	fontdata_pearl8x8,
+	2
+};
diff -Nru a/drivers/video/console/font_sun12x22.c b/drivers/video/console/font_sun12x22.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/font_sun12x22.c	Mon Dec  9 18:46:37 2002
@@ -0,0 +1,6220 @@
+#include "font.h"
+
+#define FONTDATAMAX 11264
+
+static unsigned char fontdata_sun12x22[FONTDATAMAX] = {
+
+	/* 0 0x00 '^@' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 1 0x01 '^A' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 2 0x02 '^B' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 3 0x03 '^C' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 4 0x04 '^D' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 5 0x05 '^E' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 6 0x06 '^F' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 7 0x07 '^G' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 8 0x08 '^H' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 9 0x09 '^I' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 10 0x0a '^J' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 11 0x0b '^K' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 12 0x0c '^L' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 13 0x0d '^M' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 14 0x0e '^N' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 15 0x0f '^O' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 16 0x10 '^P' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 17 0x11 '^Q' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 18 0x12 '^R' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 19 0x13 '^S' */
+	0x00, 0x00, /* 000000000000 */
+	0x31, 0x80, /* 001100011000 */
+	0x31, 0x80, /* 001100011000 */
+	0x31, 0x80, /* 001100011000 */
+	0x31, 0x80, /* 001100011000 */
+	0x31, 0x80, /* 001100011000 */
+	0x31, 0x80, /* 001100011000 */
+	0x31, 0x80, /* 001100011000 */
+	0x31, 0x80, /* 001100011000 */
+	0x31, 0x80, /* 001100011000 */
+	0x31, 0x80, /* 001100011000 */
+	0x31, 0x80, /* 001100011000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x31, 0x80, /* 001100011000 */
+	0x31, 0x80, /* 001100011000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 20 0x14 '^T' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x1f, 0xf0, /* 000111111111 */
+	0x3c, 0xc0, /* 001111001100 */
+	0x7c, 0xc0, /* 011111001100 */
+	0x7c, 0xc0, /* 011111001100 */
+	0x7c, 0xc0, /* 011111001100 */
+	0x3c, 0xc0, /* 001111001100 */
+	0x1c, 0xc0, /* 000111001100 */
+	0x0c, 0xc0, /* 000011001100 */
+	0x0c, 0xc0, /* 000011001100 */
+	0x0c, 0xc0, /* 000011001100 */
+	0x0c, 0xc0, /* 000011001100 */
+	0x0c, 0xc0, /* 000011001100 */
+	0x0c, 0xc0, /* 000011001100 */
+	0x1c, 0xe0, /* 000111001110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 21 0x15 '^U' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x31, 0x80, /* 001100011000 */
+	0x31, 0x80, /* 001100011000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x31, 0x80, /* 001100011000 */
+	0x31, 0x80, /* 001100011000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x01, 0x80, /* 000000011000 */
+	0x01, 0x80, /* 000000011000 */
+	0x31, 0x80, /* 001100011000 */
+	0x31, 0x80, /* 001100011000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 22 0x16 '^V' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 23 0x17 '^W' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 24 0x18 '^X' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 25 0x19 '^Y' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 26 0x1a '^Z' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 27 0x1b '^[' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 28 0x1c '^\' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 29 0x1d '^]' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 30 0x1e '^^' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 31 0x1f '^_' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 32 0x20 ' ' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 33 0x21 '!' */
+	0x00, 0x00, /* 000000000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 34 0x22 '"' */
+	0x00, 0x00, /* 000000000000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 35 0x23 '#' */
+	0x00, 0x00, /* 000000000000 */
+	0x03, 0x30, /* 000000110011 */
+	0x03, 0x30, /* 000000110011 */
+	0x03, 0x30, /* 000000110011 */
+	0x06, 0x60, /* 000001100110 */
+	0x1f, 0xf0, /* 000111111111 */
+	0x1f, 0xf0, /* 000111111111 */
+	0x0c, 0xc0, /* 000011001100 */
+	0x0c, 0xc0, /* 000011001100 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x7f, 0xc0, /* 011111111100 */
+	0x7f, 0xc0, /* 011111111100 */
+	0x33, 0x00, /* 001100110000 */
+	0x66, 0x00, /* 011001100000 */
+	0x66, 0x00, /* 011001100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 36 0x24 '$' */
+	0x00, 0x00, /* 000000000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x66, 0xe0, /* 011001101110 */
+	0x66, 0x60, /* 011001100110 */
+	0x66, 0x00, /* 011001100000 */
+	0x3e, 0x00, /* 001111100000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x07, 0xc0, /* 000001111100 */
+	0x06, 0x60, /* 000001100110 */
+	0x06, 0x60, /* 000001100110 */
+	0x66, 0x60, /* 011001100110 */
+	0x7f, 0xc0, /* 011111111100 */
+	0x3f, 0x80, /* 001111111000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 37 0x25 '%' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x38, 0xc0, /* 001110001100 */
+	0x4c, 0xc0, /* 010011001100 */
+	0x45, 0x80, /* 010001011000 */
+	0x65, 0x80, /* 011001011000 */
+	0x3b, 0x00, /* 001110110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0d, 0xc0, /* 000011011100 */
+	0x1a, 0x60, /* 000110100110 */
+	0x1a, 0x20, /* 000110100010 */
+	0x33, 0x20, /* 001100110010 */
+	0x31, 0xc0, /* 001100011100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 38 0x26 '&' */
+	0x00, 0x00, /* 000000000000 */
+	0x07, 0x00, /* 000001110000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x18, 0xc0, /* 000110001100 */
+	0x18, 0xc0, /* 000110001100 */
+	0x18, 0xc0, /* 000110001100 */
+	0x0f, 0x80, /* 000011111000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x3e, 0x00, /* 001111100000 */
+	0x77, 0x00, /* 011101110000 */
+	0x63, 0x60, /* 011000110110 */
+	0x61, 0xe0, /* 011000011110 */
+	0x61, 0xc0, /* 011000011100 */
+	0x61, 0x80, /* 011000011000 */
+	0x3f, 0xe0, /* 001111111110 */
+	0x1e, 0x60, /* 000111100110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 39 0x27 ''' */
+	0x00, 0x00, /* 000000000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x10, 0x00, /* 000100000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 40 0x28 '(' */
+	0x00, 0x00, /* 000000000000 */
+	0x01, 0x80, /* 000000011000 */
+	0x03, 0x00, /* 000000110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x03, 0x00, /* 000000110000 */
+	0x01, 0x80, /* 000000011000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 41 0x29 ')' */
+	0x00, 0x00, /* 000000000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 42 0x2a '*' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x66, 0x60, /* 011001100110 */
+	0x76, 0xe0, /* 011101101110 */
+	0x19, 0x80, /* 000110011000 */
+	0x00, 0x00, /* 000000000000 */
+	0x19, 0x80, /* 000110011000 */
+	0x76, 0xe0, /* 011101101110 */
+	0x66, 0x60, /* 011001100110 */
+	0x06, 0x00, /* 000001100000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 43 0x2b '+' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 44 0x2c ',' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x10, 0x00, /* 000100000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 45 0x2d '-' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 46 0x2e '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 47 0x2f '/' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x60, /* 000000000110 */
+	0x00, 0xc0, /* 000000001100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x01, 0x80, /* 000000011000 */
+	0x01, 0x80, /* 000000011000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 48 0x30 '0' */
+	0x00, 0x00, /* 000000000000 */
+	0x07, 0x00, /* 000001110000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x11, 0x80, /* 000100011000 */
+	0x10, 0xc0, /* 000100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0x80, /* 001100001000 */
+	0x18, 0x80, /* 000110001000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 49 0x31 '1' */
+	0x00, 0x00, /* 000000000000 */
+	0x02, 0x00, /* 000000100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x36, 0x00, /* 001101100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 50 0x32 '2' */
+	0x00, 0x00, /* 000000000000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x3f, 0x80, /* 001111111000 */
+	0x61, 0xc0, /* 011000011100 */
+	0x40, 0xc0, /* 010000001100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x01, 0x80, /* 000000011000 */
+	0x03, 0x00, /* 000000110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x30, 0x20, /* 001100000010 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 51 0x33 '3' */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x1f, 0xc0, /* 000111111100 */
+	0x20, 0xe0, /* 001000001110 */
+	0x40, 0x60, /* 010000000110 */
+	0x00, 0x60, /* 000000000110 */
+	0x00, 0xe0, /* 000000001110 */
+	0x07, 0xc0, /* 000001111100 */
+	0x0f, 0xc0, /* 000011111100 */
+	0x00, 0xe0, /* 000000001110 */
+	0x00, 0x60, /* 000000000110 */
+	0x00, 0x60, /* 000000000110 */
+	0x40, 0x60, /* 010000000110 */
+	0x60, 0x40, /* 011000000100 */
+	0x3f, 0x80, /* 001111111000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 52 0x34 '4' */
+	0x00, 0x00, /* 000000000000 */
+	0x01, 0x80, /* 000000011000 */
+	0x03, 0x80, /* 000000111000 */
+	0x03, 0x80, /* 000000111000 */
+	0x05, 0x80, /* 000001011000 */
+	0x05, 0x80, /* 000001011000 */
+	0x09, 0x80, /* 000010011000 */
+	0x09, 0x80, /* 000010011000 */
+	0x11, 0x80, /* 000100011000 */
+	0x11, 0x80, /* 000100011000 */
+	0x21, 0x80, /* 001000011000 */
+	0x3f, 0xe0, /* 001111111110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x01, 0x80, /* 000000011000 */
+	0x01, 0x80, /* 000000011000 */
+	0x01, 0x80, /* 000000011000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 53 0x35 '5' */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0xc0, /* 000011111100 */
+	0x0f, 0xc0, /* 000011111100 */
+	0x10, 0x00, /* 000100000000 */
+	0x10, 0x00, /* 000100000000 */
+	0x20, 0x00, /* 001000000000 */
+	0x3f, 0x80, /* 001111111000 */
+	0x31, 0xc0, /* 001100011100 */
+	0x00, 0xe0, /* 000000001110 */
+	0x00, 0x60, /* 000000000110 */
+	0x00, 0x60, /* 000000000110 */
+	0x00, 0x60, /* 000000000110 */
+	0x40, 0x60, /* 010000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x30, 0xc0, /* 001100001100 */
+	0x1f, 0x80, /* 000111111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 54 0x36 '6' */
+	0x00, 0x00, /* 000000000000 */
+	0x07, 0x00, /* 000001110000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x67, 0x80, /* 011001111000 */
+	0x6f, 0xc0, /* 011011111100 */
+	0x70, 0xe0, /* 011100001110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x70, 0x40, /* 011100000100 */
+	0x3f, 0x80, /* 001111111000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 55 0x37 '7' */
+	0x00, 0x00, /* 000000000000 */
+	0x1f, 0xe0, /* 000111111110 */
+	0x3f, 0xe0, /* 001111111110 */
+	0x60, 0x40, /* 011000000100 */
+	0x00, 0x40, /* 000000000100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x00, 0x80, /* 000000001000 */
+	0x00, 0x80, /* 000000001000 */
+	0x01, 0x80, /* 000000011000 */
+	0x01, 0x00, /* 000000010000 */
+	0x01, 0x00, /* 000000010000 */
+	0x03, 0x00, /* 000000110000 */
+	0x02, 0x00, /* 000000100000 */
+	0x02, 0x00, /* 000000100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x04, 0x00, /* 000001000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 56 0x38 '8' */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x11, 0x80, /* 000100011000 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x18, 0x80, /* 000110001000 */
+	0x0d, 0x00, /* 000011010000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0b, 0x00, /* 000010110000 */
+	0x11, 0x80, /* 000100011000 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x18, 0x80, /* 000110001000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 57 0x39 '9' */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x11, 0xc0, /* 000100011100 */
+	0x20, 0xe0, /* 001000001110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x70, 0xe0, /* 011100001110 */
+	0x3f, 0x60, /* 001111110110 */
+	0x1e, 0x60, /* 000111100110 */
+	0x00, 0x60, /* 000000000110 */
+	0x00, 0xc0, /* 000000001100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x01, 0x80, /* 000000011000 */
+	0x07, 0x00, /* 000001110000 */
+	0x3c, 0x00, /* 001111000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 58 0x3a ':' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 59 0x3b ';' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x10, 0x00, /* 000100000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 60 0x3c '<' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x60, /* 000000000110 */
+	0x01, 0xc0, /* 000000011100 */
+	0x07, 0x00, /* 000001110000 */
+	0x1c, 0x00, /* 000111000000 */
+	0x70, 0x00, /* 011100000000 */
+	0x70, 0x00, /* 011100000000 */
+	0x1c, 0x00, /* 000111000000 */
+	0x07, 0x00, /* 000001110000 */
+	0x01, 0xc0, /* 000000011100 */
+	0x00, 0x60, /* 000000000110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 61 0x3d '=' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 62 0x3e '>' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x38, 0x00, /* 001110000000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x03, 0x80, /* 000000111000 */
+	0x00, 0xe0, /* 000000001110 */
+	0x00, 0xe0, /* 000000001110 */
+	0x03, 0x80, /* 000000111000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x38, 0x00, /* 001110000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 63 0x3f '?' */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x39, 0xc0, /* 001110011100 */
+	0x20, 0xc0, /* 001000001100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x01, 0x80, /* 000000011000 */
+	0x03, 0x00, /* 000000110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 64 0x40 '@' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x30, 0x60, /* 001100000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x67, 0x20, /* 011001110010 */
+	0x6f, 0xa0, /* 011011111010 */
+	0x6c, 0xa0, /* 011011001010 */
+	0x6c, 0xa0, /* 011011001010 */
+	0x67, 0xe0, /* 011001111110 */
+	0x60, 0x00, /* 011000000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x3f, 0xe0, /* 001111111110 */
+	0x0f, 0xe0, /* 000011111110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 65 0x41 'A' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0b, 0x00, /* 000010110000 */
+	0x0b, 0x00, /* 000010110000 */
+	0x09, 0x00, /* 000010010000 */
+	0x11, 0x80, /* 000100011000 */
+	0x11, 0x80, /* 000100011000 */
+	0x10, 0x80, /* 000100001000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x20, 0xc0, /* 001000001100 */
+	0x20, 0x40, /* 001000000100 */
+	0x40, 0x60, /* 010000000110 */
+	0x40, 0x60, /* 010000000110 */
+	0xe0, 0xf0, /* 111000001111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 66 0x42 'B' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xff, 0x00, /* 111111110000 */
+	0x60, 0x80, /* 011000001000 */
+	0x60, 0xc0, /* 011000001100 */
+	0x60, 0xc0, /* 011000001100 */
+	0x60, 0xc0, /* 011000001100 */
+	0x61, 0x80, /* 011000011000 */
+	0x7f, 0x80, /* 011111111000 */
+	0x60, 0xc0, /* 011000001100 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0xc0, /* 011000001100 */
+	0xff, 0x80, /* 111111111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 67 0x43 'C' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0xc0, /* 000011111100 */
+	0x10, 0x60, /* 000100000110 */
+	0x20, 0x20, /* 001000000010 */
+	0x20, 0x00, /* 001000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x20, 0x00, /* 001000000000 */
+	0x30, 0x20, /* 001100000010 */
+	0x18, 0x40, /* 000110000100 */
+	0x0f, 0x80, /* 000011111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 68 0x44 'D' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xff, 0x00, /* 111111110000 */
+	0x61, 0xc0, /* 011000011100 */
+	0x60, 0xc0, /* 011000001100 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x40, /* 011000000100 */
+	0x61, 0x80, /* 011000011000 */
+	0xfe, 0x00, /* 111111100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 69 0x45 'E' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x7f, 0xc0, /* 011111111100 */
+	0x30, 0x40, /* 001100000100 */
+	0x30, 0x40, /* 001100000100 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x80, /* 001100001000 */
+	0x3f, 0x80, /* 001111111000 */
+	0x30, 0x80, /* 001100001000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x20, /* 001100000010 */
+	0x30, 0x20, /* 001100000010 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 70 0x46 'F' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x7f, 0xc0, /* 011111111100 */
+	0x30, 0x40, /* 001100000100 */
+	0x30, 0x40, /* 001100000100 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x80, /* 001100001000 */
+	0x3f, 0x80, /* 001111111000 */
+	0x30, 0x80, /* 001100001000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x78, 0x00, /* 011110000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 71 0x47 'G' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0xc0, /* 000011111100 */
+	0x10, 0x60, /* 000100000110 */
+	0x20, 0x20, /* 001000000010 */
+	0x20, 0x00, /* 001000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x61, 0xf0, /* 011000011111 */
+	0x60, 0x60, /* 011000000110 */
+	0x20, 0x60, /* 001000000110 */
+	0x30, 0x60, /* 001100000110 */
+	0x18, 0x60, /* 000110000110 */
+	0x0f, 0x80, /* 000011111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 72 0x48 'H' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xf0, 0xf0, /* 111100001111 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0xf0, 0xf0, /* 111100001111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 73 0x49 'I' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 74 0x4a 'J' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x04, 0x00, /* 000001000000 */
+	0x38, 0x00, /* 001110000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 75 0x4b 'K' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xf0, 0xe0, /* 111100001110 */
+	0x61, 0x80, /* 011000011000 */
+	0x63, 0x00, /* 011000110000 */
+	0x66, 0x00, /* 011001100000 */
+	0x6c, 0x00, /* 011011000000 */
+	0x78, 0x00, /* 011110000000 */
+	0x78, 0x00, /* 011110000000 */
+	0x7c, 0x00, /* 011111000000 */
+	0x6e, 0x00, /* 011011100000 */
+	0x67, 0x00, /* 011001110000 */
+	0x63, 0x80, /* 011000111000 */
+	0x61, 0xc0, /* 011000011100 */
+	0x60, 0xe0, /* 011000001110 */
+	0xf0, 0x70, /* 111100000111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 76 0x4c 'L' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x78, 0x00, /* 011110000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x20, /* 001100000010 */
+	0x30, 0x20, /* 001100000010 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 77 0x4d 'M' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xe0, 0x70, /* 111000000111 */
+	0x60, 0xe0, /* 011000001110 */
+	0x70, 0xe0, /* 011100001110 */
+	0x70, 0xe0, /* 011100001110 */
+	0x70, 0xe0, /* 011100001110 */
+	0x59, 0x60, /* 010110010110 */
+	0x59, 0x60, /* 010110010110 */
+	0x59, 0x60, /* 010110010110 */
+	0x4d, 0x60, /* 010011010110 */
+	0x4e, 0x60, /* 010011100110 */
+	0x4e, 0x60, /* 010011100110 */
+	0x44, 0x60, /* 010001000110 */
+	0x44, 0x60, /* 010001000110 */
+	0xe4, 0xf0, /* 111001001111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 78 0x4e 'N' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xc0, 0x70, /* 110000000111 */
+	0x60, 0x20, /* 011000000010 */
+	0x70, 0x20, /* 011100000010 */
+	0x78, 0x20, /* 011110000010 */
+	0x58, 0x20, /* 010110000010 */
+	0x4c, 0x20, /* 010011000010 */
+	0x46, 0x20, /* 010001100010 */
+	0x47, 0x20, /* 010001110010 */
+	0x43, 0x20, /* 010000110010 */
+	0x41, 0xa0, /* 010000011010 */
+	0x40, 0xe0, /* 010000001110 */
+	0x40, 0xe0, /* 010000001110 */
+	0x40, 0x60, /* 010000000110 */
+	0xe0, 0x30, /* 111000000011 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 79 0x4f 'O' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x11, 0xc0, /* 000100011100 */
+	0x20, 0xc0, /* 001000001100 */
+	0x20, 0x60, /* 001000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x20, 0x40, /* 001000000100 */
+	0x30, 0x40, /* 001100000100 */
+	0x18, 0x80, /* 000110001000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 80 0x50 'P' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x7f, 0x80, /* 011111111000 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0x60, /* 001100000110 */
+	0x30, 0x60, /* 001100000110 */
+	0x30, 0x60, /* 001100000110 */
+	0x30, 0xc0, /* 001100001100 */
+	0x37, 0x80, /* 001101111000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x78, 0x00, /* 011110000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 81 0x51 'Q' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x11, 0xc0, /* 000100011100 */
+	0x20, 0xc0, /* 001000001100 */
+	0x20, 0x60, /* 001000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x30, 0x40, /* 001100000100 */
+	0x38, 0x40, /* 001110000100 */
+	0x1f, 0x80, /* 000111111000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x23, 0x90, /* 001000111001 */
+	0x01, 0xe0, /* 000000011110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 82 0x52 'R' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xff, 0x00, /* 111111110000 */
+	0x61, 0x80, /* 011000011000 */
+	0x60, 0xc0, /* 011000001100 */
+	0x60, 0xc0, /* 011000001100 */
+	0x60, 0xc0, /* 011000001100 */
+	0x60, 0x80, /* 011000001000 */
+	0x7f, 0x00, /* 011111110000 */
+	0x7c, 0x00, /* 011111000000 */
+	0x6e, 0x00, /* 011011100000 */
+	0x67, 0x00, /* 011001110000 */
+	0x63, 0x80, /* 011000111000 */
+	0x61, 0xc0, /* 011000011100 */
+	0x60, 0xe0, /* 011000001110 */
+	0xf0, 0x70, /* 111100000111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 83 0x53 'S' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x1f, 0xe0, /* 000111111110 */
+	0x30, 0x60, /* 001100000110 */
+	0x60, 0x20, /* 011000000010 */
+	0x60, 0x20, /* 011000000010 */
+	0x70, 0x00, /* 011100000000 */
+	0x3c, 0x00, /* 001111000000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x07, 0x80, /* 000001111000 */
+	0x01, 0xc0, /* 000000011100 */
+	0x00, 0xe0, /* 000000001110 */
+	0x40, 0x60, /* 010000000110 */
+	0x40, 0x60, /* 010000000110 */
+	0x60, 0xc0, /* 011000001100 */
+	0x7f, 0x80, /* 011111111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 84 0x54 'T' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x46, 0x20, /* 010001100010 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 85 0x55 'U' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xf0, 0x70, /* 111100000111 */
+	0x60, 0x20, /* 011000000010 */
+	0x60, 0x20, /* 011000000010 */
+	0x60, 0x20, /* 011000000010 */
+	0x60, 0x20, /* 011000000010 */
+	0x60, 0x20, /* 011000000010 */
+	0x60, 0x20, /* 011000000010 */
+	0x60, 0x20, /* 011000000010 */
+	0x60, 0x20, /* 011000000010 */
+	0x60, 0x20, /* 011000000010 */
+	0x60, 0x20, /* 011000000010 */
+	0x70, 0x40, /* 011100000100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x1f, 0x80, /* 000111111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 86 0x56 'V' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xe0, 0xe0, /* 111000001110 */
+	0x60, 0x40, /* 011000000100 */
+	0x30, 0x80, /* 001100001000 */
+	0x30, 0x80, /* 001100001000 */
+	0x30, 0x80, /* 001100001000 */
+	0x19, 0x00, /* 000110010000 */
+	0x19, 0x00, /* 000110010000 */
+	0x19, 0x00, /* 000110010000 */
+	0x0a, 0x00, /* 000010100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x04, 0x00, /* 000001000000 */
+	0x04, 0x00, /* 000001000000 */
+	0x04, 0x00, /* 000001000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 87 0x57 'W' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xfe, 0xf0, /* 111111101111 */
+	0x66, 0x20, /* 011001100010 */
+	0x66, 0x20, /* 011001100010 */
+	0x66, 0x20, /* 011001100010 */
+	0x76, 0x20, /* 011101100010 */
+	0x77, 0x40, /* 011101110100 */
+	0x33, 0x40, /* 001100110100 */
+	0x37, 0x40, /* 001101110100 */
+	0x3b, 0xc0, /* 001110111100 */
+	0x3b, 0x80, /* 001110111000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 88 0x58 'X' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xf0, 0x70, /* 111100000111 */
+	0x60, 0x20, /* 011000000010 */
+	0x30, 0x40, /* 001100000100 */
+	0x38, 0x80, /* 001110001000 */
+	0x18, 0x80, /* 000110001000 */
+	0x0d, 0x00, /* 000011010000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0b, 0x00, /* 000010110000 */
+	0x11, 0x80, /* 000100011000 */
+	0x11, 0xc0, /* 000100011100 */
+	0x20, 0xc0, /* 001000001100 */
+	0x40, 0x60, /* 010000000110 */
+	0xe0, 0xf0, /* 111000001111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 89 0x59 'Y' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xf0, 0x70, /* 111100000111 */
+	0x60, 0x20, /* 011000000010 */
+	0x30, 0x40, /* 001100000100 */
+	0x18, 0x80, /* 000110001000 */
+	0x18, 0x80, /* 000110001000 */
+	0x0d, 0x00, /* 000011010000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 90 0x5a 'Z' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xe0, /* 001111111110 */
+	0x20, 0xc0, /* 001000001100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x01, 0x80, /* 000000011000 */
+	0x01, 0x80, /* 000000011000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x18, 0x20, /* 000110000010 */
+	0x3f, 0xe0, /* 001111111110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 91 0x5b '[' */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 92 0x5c '\' */
+	0x00, 0x00, /* 000000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x01, 0x80, /* 000000011000 */
+	0x01, 0x80, /* 000000011000 */
+	0x00, 0xc0, /* 000000001100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x00, 0x60, /* 000000000110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 93 0x5d ']' */
+	0x00, 0x00, /* 000000000000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 94 0x5e '^' */
+	0x00, 0x00, /* 000000000000 */
+	0x04, 0x00, /* 000001000000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x1b, 0x00, /* 000110110000 */
+	0x31, 0x80, /* 001100011000 */
+	0x60, 0xc0, /* 011000001100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 95 0x5f '_' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 96 0x60 '`' */
+	0x00, 0x00, /* 000000000000 */
+	0x01, 0x00, /* 000000010000 */
+	0x03, 0x00, /* 000000110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x07, 0x80, /* 000001111000 */
+	0x07, 0x80, /* 000001111000 */
+	0x03, 0x00, /* 000000110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 97 0x61 'a' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x18, 0xc0, /* 000110001100 */
+	0x10, 0xc0, /* 000100001100 */
+	0x03, 0xc0, /* 000000111100 */
+	0x1c, 0xc0, /* 000111001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x39, 0xc0, /* 001110011100 */
+	0x1e, 0xe0, /* 000111101110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 98 0x62 'b' */
+	0x00, 0x00, /* 000000000000 */
+	0x20, 0x00, /* 001000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0xe0, 0x00, /* 111000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x67, 0x80, /* 011001111000 */
+	0x6f, 0xc0, /* 011011111100 */
+	0x70, 0xe0, /* 011100001110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x70, 0x60, /* 011100000110 */
+	0x78, 0xc0, /* 011110001100 */
+	0x4f, 0x80, /* 010011111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 99 0x63 'c' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x31, 0xc0, /* 001100011100 */
+	0x20, 0xc0, /* 001000001100 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x70, 0x40, /* 011100000100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x1f, 0x80, /* 000111111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 100 0x64 'd' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x60, /* 000000000110 */
+	0x00, 0xe0, /* 000000001110 */
+	0x00, 0x60, /* 000000000110 */
+	0x00, 0x60, /* 000000000110 */
+	0x00, 0x60, /* 000000000110 */
+	0x0f, 0x60, /* 000011110110 */
+	0x31, 0xe0, /* 001100011110 */
+	0x20, 0xe0, /* 001000001110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x70, 0xe0, /* 011100001110 */
+	0x39, 0x60, /* 001110010110 */
+	0x1e, 0x70, /* 000111100111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 101 0x65 'e' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x30, 0xc0, /* 001100001100 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x18, 0x60, /* 000110000110 */
+	0x0f, 0x80, /* 000011111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 102 0x66 'f' */
+	0x00, 0x00, /* 000000000000 */
+	0x03, 0x80, /* 000000111000 */
+	0x04, 0xc0, /* 000001001100 */
+	0x04, 0xc0, /* 000001001100 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x3f, 0x80, /* 001111111000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 103 0x67 'g' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x1f, 0x20, /* 000111110010 */
+	0x31, 0xe0, /* 001100011110 */
+	0x60, 0xc0, /* 011000001100 */
+	0x60, 0xc0, /* 011000001100 */
+	0x60, 0xc0, /* 011000001100 */
+	0x31, 0x80, /* 001100011000 */
+	0x3f, 0x00, /* 001111110000 */
+	0x60, 0x00, /* 011000000000 */
+	0x7f, 0xc0, /* 011111111100 */
+	0x3f, 0xe0, /* 001111111110 */
+	0x20, 0x60, /* 001000000110 */
+	0x40, 0x20, /* 010000000010 */
+	0x40, 0x20, /* 010000000010 */
+	0x7f, 0xc0, /* 011111111100 */
+	0x3f, 0x80, /* 001111111000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 104 0x68 'h' */
+	0x00, 0x00, /* 000000000000 */
+	0x10, 0x00, /* 000100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x70, 0x00, /* 011100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x37, 0x80, /* 001101111000 */
+	0x39, 0xc0, /* 001110011100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x79, 0xe0, /* 011110011110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 105 0x69 'i' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 106 0x6a 'j' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0xc0, /* 000000001100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x03, 0xc0, /* 000000111100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x20, 0xc0, /* 001000001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x38, 0x80, /* 001110001000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 107 0x6b 'k' */
+	0x00, 0x00, /* 000000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0xe0, 0x00, /* 111000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x61, 0xc0, /* 011000011100 */
+	0x63, 0x00, /* 011000110000 */
+	0x66, 0x00, /* 011001100000 */
+	0x7c, 0x00, /* 011111000000 */
+	0x78, 0x00, /* 011110000000 */
+	0x7c, 0x00, /* 011111000000 */
+	0x6e, 0x00, /* 011011100000 */
+	0x67, 0x00, /* 011001110000 */
+	0x63, 0x80, /* 011000111000 */
+	0xf1, 0xe0, /* 111100011110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 108 0x6c 'l' */
+	0x00, 0x00, /* 000000000000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 109 0x6d 'm' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xdd, 0xc0, /* 110111011100 */
+	0x6e, 0xe0, /* 011011101110 */
+	0x66, 0x60, /* 011001100110 */
+	0x66, 0x60, /* 011001100110 */
+	0x66, 0x60, /* 011001100110 */
+	0x66, 0x60, /* 011001100110 */
+	0x66, 0x60, /* 011001100110 */
+	0x66, 0x60, /* 011001100110 */
+	0x66, 0x60, /* 011001100110 */
+	0xef, 0x70, /* 111011110111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 110 0x6e 'n' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x27, 0x80, /* 001001111000 */
+	0x79, 0xc0, /* 011110011100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x79, 0xe0, /* 011110011110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 111 0x6f 'o' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x11, 0xc0, /* 000100011100 */
+	0x20, 0xe0, /* 001000001110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x70, 0x40, /* 011100000100 */
+	0x38, 0x80, /* 001110001000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 112 0x70 'p' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xef, 0x80, /* 111011111000 */
+	0x71, 0xc0, /* 011100011100 */
+	0x60, 0xe0, /* 011000001110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x40, /* 011000000100 */
+	0x70, 0x80, /* 011100001000 */
+	0x7f, 0x00, /* 011111110000 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0xf0, 0x00, /* 111100000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 113 0x71 'q' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x20, /* 000011110010 */
+	0x11, 0xe0, /* 000100011110 */
+	0x20, 0xe0, /* 001000001110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x70, 0x60, /* 011100000110 */
+	0x38, 0xe0, /* 001110001110 */
+	0x1f, 0xe0, /* 000111111110 */
+	0x00, 0x60, /* 000000000110 */
+	0x00, 0x60, /* 000000000110 */
+	0x00, 0x60, /* 000000000110 */
+	0x00, 0x60, /* 000000000110 */
+	0x00, 0xf0, /* 000000001111 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 114 0x72 'r' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x73, 0x80, /* 011100111000 */
+	0x34, 0xc0, /* 001101001100 */
+	0x38, 0xc0, /* 001110001100 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x78, 0x00, /* 011110000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 115 0x73 's' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x1f, 0xc0, /* 000111111100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0x40, /* 001100000100 */
+	0x38, 0x00, /* 001110000000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x07, 0x80, /* 000001111000 */
+	0x01, 0xc0, /* 000000011100 */
+	0x20, 0xc0, /* 001000001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x3f, 0x80, /* 001111111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 116 0x74 't' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x04, 0x00, /* 000001000000 */
+	0x04, 0x00, /* 000001000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x7f, 0xc0, /* 011111111100 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x20, /* 000011000010 */
+	0x0e, 0x40, /* 000011100100 */
+	0x07, 0x80, /* 000001111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 117 0x75 'u' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x79, 0xe0, /* 011110011110 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x39, 0xc0, /* 001110011100 */
+	0x1e, 0x60, /* 000111100110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 118 0x76 'v' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xf0, 0x70, /* 111100000111 */
+	0x60, 0x20, /* 011000000010 */
+	0x30, 0x40, /* 001100000100 */
+	0x30, 0x40, /* 001100000100 */
+	0x18, 0x80, /* 000110001000 */
+	0x18, 0x80, /* 000110001000 */
+	0x0d, 0x00, /* 000011010000 */
+	0x0d, 0x00, /* 000011010000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 119 0x77 'w' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xff, 0x70, /* 111111110111 */
+	0x66, 0x20, /* 011001100010 */
+	0x66, 0x20, /* 011001100010 */
+	0x66, 0x20, /* 011001100010 */
+	0x37, 0x40, /* 001101110100 */
+	0x3b, 0x40, /* 001110110100 */
+	0x3b, 0x40, /* 001110110100 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 120 0x78 'x' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xf8, 0xf0, /* 111110001111 */
+	0x70, 0x40, /* 011100000100 */
+	0x38, 0x80, /* 001110001000 */
+	0x1d, 0x00, /* 000111010000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x07, 0x00, /* 000001110000 */
+	0x0b, 0x80, /* 000010111000 */
+	0x11, 0xc0, /* 000100011100 */
+	0x20, 0xe0, /* 001000001110 */
+	0xf1, 0xf0, /* 111100011111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 121 0x79 'y' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xf0, 0xf0, /* 111100001111 */
+	0x60, 0x20, /* 011000000010 */
+	0x30, 0x40, /* 001100000100 */
+	0x30, 0x40, /* 001100000100 */
+	0x18, 0x80, /* 000110001000 */
+	0x18, 0x80, /* 000110001000 */
+	0x0d, 0x00, /* 000011010000 */
+	0x0d, 0x00, /* 000011010000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x04, 0x00, /* 000001000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x08, 0x00, /* 000010000000 */
+	0x78, 0x00, /* 011110000000 */
+	0x70, 0x00, /* 011100000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 122 0x7a 'z' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x60, 0xe0, /* 011000001110 */
+	0x41, 0xc0, /* 010000011100 */
+	0x03, 0x80, /* 000000111000 */
+	0x07, 0x00, /* 000001110000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x1c, 0x00, /* 000111000000 */
+	0x38, 0x20, /* 001110000010 */
+	0x70, 0x60, /* 011100000110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 123 0x7b '{' */
+	0x00, 0x00, /* 000000000000 */
+	0x03, 0x80, /* 000000111000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x38, 0x00, /* 001110000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x03, 0x80, /* 000000111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 124 0x7c '|' */
+	0x00, 0x00, /* 000000000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 125 0x7d '}' */
+	0x00, 0x00, /* 000000000000 */
+	0x1c, 0x00, /* 000111000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x03, 0x00, /* 000000110000 */
+	0x01, 0xc0, /* 000000011100 */
+	0x03, 0x00, /* 000000110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x1c, 0x00, /* 000111000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 126 0x7e '~' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x1c, 0x20, /* 000111000010 */
+	0x3e, 0x60, /* 001111100110 */
+	0x67, 0xc0, /* 011001111100 */
+	0x43, 0x80, /* 010000111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 127 0x7f '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 128 0x80 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0xc0, /* 000011111100 */
+	0x10, 0x60, /* 000100000110 */
+	0x20, 0x20, /* 001000000010 */
+	0x20, 0x00, /* 001000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x20, 0x00, /* 001000000000 */
+	0x30, 0x20, /* 001100000010 */
+	0x18, 0x40, /* 000110000100 */
+	0x0f, 0x80, /* 000011111000 */
+	0x06, 0x00, /* 000001100000 */
+	0x03, 0x00, /* 000000110000 */
+	0x01, 0x80, /* 000000011000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 129 0x81 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x79, 0xe0, /* 011110011110 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x39, 0xc0, /* 001110011100 */
+	0x1e, 0x60, /* 000111100110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 130 0x82 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x01, 0x80, /* 000000011000 */
+	0x03, 0x00, /* 000000110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x30, 0xc0, /* 001100001100 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x18, 0x60, /* 000110000110 */
+	0x0f, 0x80, /* 000011111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 131 0x83 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x02, 0x00, /* 000000100000 */
+	0x07, 0x00, /* 000001110000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x18, 0xc0, /* 000110001100 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x18, 0xc0, /* 000110001100 */
+	0x10, 0xc0, /* 000100001100 */
+	0x03, 0xc0, /* 000000111100 */
+	0x1c, 0xc0, /* 000111001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x39, 0xc0, /* 001110011100 */
+	0x1e, 0xe0, /* 000111101110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 132 0x84 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x18, 0xc0, /* 000110001100 */
+	0x10, 0xc0, /* 000100001100 */
+	0x03, 0xc0, /* 000000111100 */
+	0x1c, 0xc0, /* 000111001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x39, 0xc0, /* 001110011100 */
+	0x1e, 0xe0, /* 000111101110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 133 0x85 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x03, 0x00, /* 000000110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x18, 0xc0, /* 000110001100 */
+	0x10, 0xc0, /* 000100001100 */
+	0x03, 0xc0, /* 000000111100 */
+	0x1c, 0xc0, /* 000111001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x39, 0xc0, /* 001110011100 */
+	0x1e, 0xe0, /* 000111101110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 134 0x86 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x07, 0x00, /* 000001110000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x07, 0x00, /* 000001110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x18, 0xc0, /* 000110001100 */
+	0x10, 0xc0, /* 000100001100 */
+	0x03, 0xc0, /* 000000111100 */
+	0x1c, 0xc0, /* 000111001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x39, 0xc0, /* 001110011100 */
+	0x1e, 0xe0, /* 000111101110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 135 0x87 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x31, 0xc0, /* 001100011100 */
+	0x20, 0xc0, /* 001000001100 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x70, 0x40, /* 011100000100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x1f, 0x80, /* 000111111000 */
+	0x06, 0x00, /* 000001100000 */
+	0x03, 0x00, /* 000000110000 */
+	0x01, 0x80, /* 000000011000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 136 0x88 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x02, 0x00, /* 000000100000 */
+	0x07, 0x00, /* 000001110000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x18, 0xc0, /* 000110001100 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x30, 0xc0, /* 001100001100 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x18, 0x60, /* 000110000110 */
+	0x0f, 0x80, /* 000011111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 137 0x89 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x30, 0xc0, /* 001100001100 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x18, 0x60, /* 000110000110 */
+	0x0f, 0x80, /* 000011111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 138 0x8a '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x03, 0x00, /* 000000110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x30, 0xc0, /* 001100001100 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x60, 0x00, /* 011000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x18, 0x60, /* 000110000110 */
+	0x0f, 0x80, /* 000011111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 139 0x8b '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 140 0x8c '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x04, 0x00, /* 000001000000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x1b, 0x00, /* 000110110000 */
+	0x31, 0x80, /* 001100011000 */
+	0x00, 0x00, /* 000000000000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 141 0x8d '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 142 0x8e '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x00, 0x00, /* 000000000000 */
+	0x04, 0x00, /* 000001000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0b, 0x00, /* 000010110000 */
+	0x0b, 0x00, /* 000010110000 */
+	0x19, 0x80, /* 000110011000 */
+	0x11, 0x80, /* 000100011000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x20, 0xc0, /* 001000001100 */
+	0x60, 0x60, /* 011000000110 */
+	0x40, 0x60, /* 010000000110 */
+	0xe0, 0xf0, /* 111000001111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 143 0x8f '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x19, 0x80, /* 000110011000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x04, 0x00, /* 000001000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0b, 0x00, /* 000010110000 */
+	0x0b, 0x00, /* 000010110000 */
+	0x19, 0x80, /* 000110011000 */
+	0x11, 0x80, /* 000100011000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x20, 0xc0, /* 001000001100 */
+	0x60, 0x60, /* 011000000110 */
+	0x40, 0x60, /* 010000000110 */
+	0xe0, 0xf0, /* 111000001111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 144 0x90 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x03, 0x00, /* 000000110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x08, 0x00, /* 000010000000 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x30, 0x20, /* 001100000010 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x80, /* 001100001000 */
+	0x3f, 0x80, /* 001111111000 */
+	0x30, 0x80, /* 001100001000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x20, /* 001100000010 */
+	0x30, 0x20, /* 001100000010 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 145 0x91 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3d, 0xe0, /* 001111011110 */
+	0x66, 0x30, /* 011001100011 */
+	0x46, 0x30, /* 010001100011 */
+	0x06, 0x30, /* 000001100011 */
+	0x3f, 0xf0, /* 001111111111 */
+	0x66, 0x00, /* 011001100000 */
+	0xc6, 0x00, /* 110001100000 */
+	0xc6, 0x00, /* 110001100000 */
+	0xe7, 0x30, /* 111001110011 */
+	0x7d, 0xe0, /* 011111011110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 146 0x92 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x03, 0xf0, /* 000000111111 */
+	0x07, 0x10, /* 000001110001 */
+	0x07, 0x10, /* 000001110001 */
+	0x0b, 0x00, /* 000010110000 */
+	0x0b, 0x00, /* 000010110000 */
+	0x0b, 0x20, /* 000010110010 */
+	0x13, 0xe0, /* 000100111110 */
+	0x13, 0x20, /* 000100110010 */
+	0x3f, 0x00, /* 001111110000 */
+	0x23, 0x00, /* 001000110000 */
+	0x23, 0x00, /* 001000110000 */
+	0x43, 0x10, /* 010000110001 */
+	0x43, 0x10, /* 010000110001 */
+	0xe7, 0xf0, /* 111001111111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 147 0x93 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x02, 0x00, /* 000000100000 */
+	0x07, 0x00, /* 000001110000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x18, 0xc0, /* 000110001100 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x11, 0xc0, /* 000100011100 */
+	0x20, 0xe0, /* 001000001110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x70, 0x40, /* 011100000100 */
+	0x38, 0x80, /* 001110001000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 148 0x94 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x11, 0xc0, /* 000100011100 */
+	0x20, 0xe0, /* 001000001110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x70, 0x40, /* 011100000100 */
+	0x38, 0x80, /* 001110001000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 149 0x95 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x03, 0x00, /* 000000110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x11, 0xc0, /* 000100011100 */
+	0x20, 0xe0, /* 001000001110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x70, 0x40, /* 011100000100 */
+	0x38, 0x80, /* 001110001000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 150 0x96 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x02, 0x00, /* 000000100000 */
+	0x07, 0x00, /* 000001110000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x18, 0xc0, /* 000110001100 */
+	0x00, 0x00, /* 000000000000 */
+	0x79, 0xe0, /* 011110011110 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x39, 0xc0, /* 001110011100 */
+	0x1e, 0x60, /* 000111100110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 151 0x97 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x79, 0xe0, /* 011110011110 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x39, 0xc0, /* 001110011100 */
+	0x1e, 0x60, /* 000111100110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 152 0x98 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xf0, 0xf0, /* 111100001111 */
+	0x60, 0x20, /* 011000000010 */
+	0x30, 0x40, /* 001100000100 */
+	0x30, 0x40, /* 001100000100 */
+	0x18, 0x80, /* 000110001000 */
+	0x18, 0x80, /* 000110001000 */
+	0x0d, 0x00, /* 000011010000 */
+	0x0d, 0x00, /* 000011010000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x04, 0x00, /* 000001000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x08, 0x00, /* 000010000000 */
+	0x78, 0x00, /* 011110000000 */
+	0x70, 0x00, /* 011100000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 153 0x99 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x11, 0xc0, /* 000100011100 */
+	0x20, 0xc0, /* 001000001100 */
+	0x20, 0x60, /* 001000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x20, 0x40, /* 001000000100 */
+	0x30, 0x40, /* 001100000100 */
+	0x18, 0x80, /* 000110001000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 154 0x9a '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0xe0, 0x30, /* 111000000011 */
+	0x60, 0x20, /* 011000000010 */
+	0x60, 0x20, /* 011000000010 */
+	0x60, 0x20, /* 011000000010 */
+	0x60, 0x20, /* 011000000010 */
+	0x60, 0x20, /* 011000000010 */
+	0x60, 0x20, /* 011000000010 */
+	0x60, 0x20, /* 011000000010 */
+	0x60, 0x20, /* 011000000010 */
+	0x60, 0x20, /* 011000000010 */
+	0x70, 0x40, /* 011100000100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x1f, 0x80, /* 000111111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 155 0x9b '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x36, 0xc0, /* 001101101100 */
+	0x26, 0xc0, /* 001001101100 */
+	0x66, 0x00, /* 011001100000 */
+	0x66, 0x00, /* 011001100000 */
+	0x66, 0x00, /* 011001100000 */
+	0x66, 0x00, /* 011001100000 */
+	0x76, 0x40, /* 011101100100 */
+	0x36, 0xc0, /* 001101101100 */
+	0x1f, 0x80, /* 000111111000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 156 0x9c '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x1c, 0xc0, /* 000111001100 */
+	0x18, 0xc0, /* 000110001100 */
+	0x18, 0x00, /* 000110000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x7e, 0x00, /* 011111100000 */
+	0x7e, 0x00, /* 011111100000 */
+	0x18, 0x00, /* 000110000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x3e, 0x20, /* 001111100010 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x61, 0xc0, /* 011000011100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 157 0x9d '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x30, 0xc0, /* 001100001100 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x06, 0x00, /* 000001100000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 158 0x9e '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 159 0x9f '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 160 0xa0 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x01, 0x80, /* 000000011000 */
+	0x03, 0x00, /* 000000110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x18, 0xc0, /* 000110001100 */
+	0x10, 0xc0, /* 000100001100 */
+	0x03, 0xc0, /* 000000111100 */
+	0x1c, 0xc0, /* 000111001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x39, 0xc0, /* 001110011100 */
+	0x1e, 0xe0, /* 000111101110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 161 0xa1 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x01, 0x80, /* 000000011000 */
+	0x03, 0x00, /* 000000110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 162 0xa2 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x01, 0x80, /* 000000011000 */
+	0x03, 0x00, /* 000000110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x11, 0xc0, /* 000100011100 */
+	0x20, 0xe0, /* 001000001110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x70, 0x40, /* 011100000100 */
+	0x38, 0x80, /* 001110001000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 163 0xa3 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x01, 0x80, /* 000000011000 */
+	0x03, 0x00, /* 000000110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x79, 0xe0, /* 011110011110 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x39, 0xc0, /* 001110011100 */
+	0x1e, 0x60, /* 000111100110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 164 0xa4 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x1c, 0x40, /* 000111000100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x23, 0x80, /* 001000111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x27, 0x80, /* 001001111000 */
+	0x79, 0xc0, /* 011110011100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x79, 0xe0, /* 011110011110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 165 0xa5 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x1c, 0x40, /* 000111000100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x23, 0x80, /* 001000111000 */
+	0xc0, 0x70, /* 110000000111 */
+	0x60, 0x20, /* 011000000010 */
+	0x70, 0x20, /* 011100000010 */
+	0x78, 0x20, /* 011110000010 */
+	0x5c, 0x20, /* 010111000010 */
+	0x4e, 0x20, /* 010011100010 */
+	0x47, 0x20, /* 010001110010 */
+	0x43, 0xa0, /* 010000111010 */
+	0x41, 0xe0, /* 010000011110 */
+	0x40, 0xe0, /* 010000001110 */
+	0x40, 0x60, /* 010000000110 */
+	0xe0, 0x30, /* 111000000011 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 166 0xa6 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x31, 0x80, /* 001100011000 */
+	0x01, 0x80, /* 000000011000 */
+	0x07, 0x80, /* 000001111000 */
+	0x19, 0x80, /* 000110011000 */
+	0x31, 0x80, /* 001100011000 */
+	0x31, 0x80, /* 001100011000 */
+	0x33, 0x80, /* 001100111000 */
+	0x1d, 0xc0, /* 000111011100 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 167 0xa7 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x07, 0x00, /* 000001110000 */
+	0x19, 0x80, /* 000110011000 */
+	0x10, 0xc0, /* 000100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0x80, /* 001100001000 */
+	0x19, 0x80, /* 000110011000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 168 0xa8 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x40, /* 001100000100 */
+	0x39, 0xc0, /* 001110011100 */
+	0x1f, 0x80, /* 000111111000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 169 0xa9 '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 170 0xaa '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 171 0xab '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x10, 0x00, /* 000100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x10, 0x00, /* 000100000000 */
+	0x10, 0x40, /* 000100000100 */
+	0x10, 0x80, /* 000100001000 */
+	0x11, 0x00, /* 000100010000 */
+	0x3a, 0x00, /* 001110100000 */
+	0x05, 0xc0, /* 000001011100 */
+	0x0a, 0x20, /* 000010100010 */
+	0x10, 0x20, /* 000100000010 */
+	0x20, 0xc0, /* 001000001100 */
+	0x41, 0x00, /* 010000010000 */
+	0x02, 0x00, /* 000000100000 */
+	0x03, 0xe0, /* 000000111110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 172 0xac '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x10, 0x00, /* 000100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x10, 0x00, /* 000100000000 */
+	0x10, 0x40, /* 000100000100 */
+	0x10, 0x80, /* 000100001000 */
+	0x11, 0x00, /* 000100010000 */
+	0x3a, 0x40, /* 001110100100 */
+	0x04, 0xc0, /* 000001001100 */
+	0x09, 0x40, /* 000010010100 */
+	0x12, 0x40, /* 000100100100 */
+	0x24, 0x40, /* 001001000100 */
+	0x47, 0xe0, /* 010001111110 */
+	0x00, 0x40, /* 000000000100 */
+	0x00, 0x40, /* 000000000100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 173 0xad '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 174 0xae '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x06, 0x60, /* 000001100110 */
+	0x0c, 0xc0, /* 000011001100 */
+	0x19, 0x80, /* 000110011000 */
+	0x33, 0x00, /* 001100110000 */
+	0x66, 0x00, /* 011001100000 */
+	0x33, 0x00, /* 001100110000 */
+	0x19, 0x80, /* 000110011000 */
+	0x0c, 0xc0, /* 000011001100 */
+	0x06, 0x60, /* 000001100110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 175 0xaf '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x66, 0x00, /* 011001100000 */
+	0x33, 0x00, /* 001100110000 */
+	0x19, 0x80, /* 000110011000 */
+	0x0c, 0xc0, /* 000011001100 */
+	0x06, 0x60, /* 000001100110 */
+	0x0c, 0xc0, /* 000011001100 */
+	0x19, 0x80, /* 000110011000 */
+	0x33, 0x00, /* 001100110000 */
+	0x66, 0x00, /* 011001100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 176 0xb0 '.' */
+	0x0c, 0x30, /* 000011000011 */
+	0x08, 0x20, /* 000010000010 */
+	0x61, 0x80, /* 011000011000 */
+	0x20, 0x80, /* 001000001000 */
+	0x0c, 0x30, /* 000011000011 */
+	0x08, 0x20, /* 000010000010 */
+	0x61, 0x80, /* 011000011000 */
+	0x20, 0x80, /* 001000001000 */
+	0x0c, 0x30, /* 000011000011 */
+	0x08, 0x20, /* 000010000010 */
+	0x61, 0x80, /* 011000011000 */
+	0x20, 0x80, /* 001000001000 */
+	0x0c, 0x30, /* 000011000011 */
+	0x08, 0x20, /* 000010000010 */
+	0x61, 0x80, /* 011000011000 */
+	0x20, 0x80, /* 001000001000 */
+	0x0c, 0x30, /* 000011000011 */
+	0x08, 0x20, /* 000010000010 */
+	0x61, 0x80, /* 011000011000 */
+	0x20, 0x80, /* 001000001000 */
+	0x0c, 0x30, /* 000011000011 */
+	0x08, 0x20, /* 000010000010 */
+
+	/* 177 0xb1 '.' */
+	0x77, 0x70, /* 011101110111 */
+	0x22, 0x20, /* 001000100010 */
+	0x88, 0x80, /* 100010001000 */
+	0xdd, 0xd0, /* 110111011101 */
+	0x88, 0x80, /* 100010001000 */
+	0x22, 0x20, /* 001000100010 */
+	0x77, 0x70, /* 011101110111 */
+	0x22, 0x20, /* 001000100010 */
+	0x88, 0x80, /* 100010001000 */
+	0xdd, 0xd0, /* 110111011101 */
+	0x88, 0x80, /* 100010001000 */
+	0x22, 0x20, /* 001000100010 */
+	0x77, 0x70, /* 011101110111 */
+	0x22, 0x20, /* 001000100010 */
+	0x88, 0x80, /* 100010001000 */
+	0xdd, 0xd0, /* 110111011101 */
+	0x88, 0x80, /* 100010001000 */
+	0x22, 0x20, /* 001000100010 */
+	0x77, 0x70, /* 011101110111 */
+	0x22, 0x20, /* 001000100010 */
+	0x88, 0x80, /* 100010001000 */
+	0xdd, 0xd0, /* 110111011101 */
+
+	/* 178 0xb2 '.' */
+	0xf3, 0xc0, /* 111100111100 */
+	0xf7, 0xd0, /* 111101111101 */
+	0x9e, 0x70, /* 100111100111 */
+	0xdf, 0x70, /* 110111110111 */
+	0xf3, 0xc0, /* 111100111100 */
+	0xf7, 0xd0, /* 111101111101 */
+	0x9e, 0x70, /* 100111100111 */
+	0xdf, 0x70, /* 110111110111 */
+	0xf3, 0xc0, /* 111100111100 */
+	0xf7, 0xd0, /* 111101111101 */
+	0x9e, 0x70, /* 100111100111 */
+	0xdf, 0x70, /* 110111110111 */
+	0xf3, 0xc0, /* 111100111100 */
+	0xf7, 0xd0, /* 111101111101 */
+	0x9e, 0x70, /* 100111100111 */
+	0xdf, 0x70, /* 110111110111 */
+	0xf3, 0xc0, /* 111100111100 */
+	0xf7, 0xd0, /* 111101111101 */
+	0x9e, 0x70, /* 100111100111 */
+	0xdf, 0x70, /* 110111110111 */
+	0xf3, 0xc0, /* 111100111100 */
+	0xf7, 0xd0, /* 111101111101 */
+
+	/* 179 0xb3 '.' */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+
+	/* 180 0xb4 '.' */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0xfe, 0x00, /* 111111100000 */
+	0xfe, 0x00, /* 111111100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+
+	/* 181 0xb5 '.' */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0xfe, 0x00, /* 111111100000 */
+	0xfe, 0x00, /* 111111100000 */
+	0x06, 0x00, /* 000001100000 */
+	0xfe, 0x00, /* 111111100000 */
+	0xfe, 0x00, /* 111111100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+
+	/* 182 0xb6 '.' */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0xfd, 0x80, /* 111111011000 */
+	0xfd, 0x80, /* 111111011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+
+	/* 183 0xb7 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xff, 0x80, /* 111111111000 */
+	0xff, 0x80, /* 111111111000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+
+	/* 184 0xb8 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xfe, 0x00, /* 111111100000 */
+	0xfe, 0x00, /* 111111100000 */
+	0x06, 0x00, /* 000001100000 */
+	0xfe, 0x00, /* 111111100000 */
+	0xfe, 0x00, /* 111111100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+
+	/* 185 0xb9 '.' */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0xfd, 0x80, /* 111111011000 */
+	0xfd, 0x80, /* 111111011000 */
+	0x01, 0x80, /* 000000011000 */
+	0xfd, 0x80, /* 111111011000 */
+	0xfd, 0x80, /* 111111011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+
+	/* 186 0xba '.' */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+
+	/* 187 0xbb '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xff, 0x80, /* 111111111000 */
+	0xff, 0x80, /* 111111111000 */
+	0x01, 0x80, /* 000000011000 */
+	0xfd, 0x80, /* 111111011000 */
+	0xfd, 0x80, /* 111111011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+
+	/* 188 0xbc '.' */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0xfd, 0x80, /* 111111011000 */
+	0xfd, 0x80, /* 111111011000 */
+	0x01, 0x80, /* 000000011000 */
+	0xff, 0x80, /* 111111111000 */
+	0xff, 0x80, /* 111111111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 189 0xbd '.' */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0xff, 0x80, /* 111111111000 */
+	0xff, 0x80, /* 111111111000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 190 0xbe '.' */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0xfe, 0x00, /* 111111100000 */
+	0xfe, 0x00, /* 111111100000 */
+	0x06, 0x00, /* 000001100000 */
+	0xfe, 0x00, /* 111111100000 */
+	0xfe, 0x00, /* 111111100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 191 0xbf '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xfe, 0x00, /* 111111100000 */
+	0xfe, 0x00, /* 111111100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+
+	/* 192 0xc0 '.' */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x07, 0xf0, /* 000001111111 */
+	0x07, 0xf0, /* 000001111111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 193 0xc1 '.' */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 194 0xc2 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+
+	/* 195 0xc3 '.' */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x07, 0xf0, /* 000001111111 */
+	0x07, 0xf0, /* 000001111111 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+
+	/* 196 0xc4 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 197 0xc5 '.' */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+
+	/* 198 0xc6 '.' */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x07, 0xf0, /* 000001111111 */
+	0x07, 0xf0, /* 000001111111 */
+	0x06, 0x00, /* 000001100000 */
+	0x07, 0xf0, /* 000001111111 */
+	0x07, 0xf0, /* 000001111111 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+
+	/* 199 0xc7 '.' */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0xf0, /* 000011011111 */
+	0x0d, 0xf0, /* 000011011111 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+
+	/* 200 0xc8 '.' */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0xf0, /* 000011011111 */
+	0x0d, 0xf0, /* 000011011111 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0f, 0xf0, /* 000011111111 */
+	0x0f, 0xf0, /* 000011111111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 201 0xc9 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0xf0, /* 000011111111 */
+	0x0f, 0xf0, /* 000011111111 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0d, 0xf0, /* 000011011111 */
+	0x0d, 0xf0, /* 000011011111 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+
+	/* 202 0xca '.' */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0xfd, 0xf0, /* 111111011111 */
+	0xfd, 0xf0, /* 111111011111 */
+	0x00, 0x00, /* 000000000000 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 203 0xcb '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0x00, 0x00, /* 000000000000 */
+	0xfd, 0xf0, /* 111111011111 */
+	0xfd, 0xf0, /* 111111011111 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+
+	/* 204 0xcc '.' */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0xf0, /* 000011011111 */
+	0x0d, 0xf0, /* 000011011111 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0d, 0xf0, /* 000011011111 */
+	0x0d, 0xf0, /* 000011011111 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+
+	/* 205 0xcd '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0x00, 0x00, /* 000000000000 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 206 0xce '.' */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0xfd, 0xf0, /* 111111011111 */
+	0xfd, 0xf0, /* 111111011111 */
+	0x00, 0x00, /* 000000000000 */
+	0xfd, 0xf0, /* 111111011111 */
+	0xfd, 0xf0, /* 111111011111 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+
+	/* 207 0xcf '.' */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0x00, 0x00, /* 000000000000 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 208 0xd0 '.' */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 209 0xd1 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0x00, 0x00, /* 000000000000 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+
+	/* 210 0xd2 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+
+	/* 211 0xd3 '.' */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0f, 0xf0, /* 000011111111 */
+	0x0f, 0xf0, /* 000011111111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 212 0xd4 '.' */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x07, 0xf0, /* 000001111111 */
+	0x07, 0xf0, /* 000001111111 */
+	0x06, 0x00, /* 000001100000 */
+	0x07, 0xf0, /* 000001111111 */
+	0x07, 0xf0, /* 000001111111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 213 0xd5 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x07, 0xf0, /* 000001111111 */
+	0x07, 0xf0, /* 000001111111 */
+	0x06, 0x00, /* 000001100000 */
+	0x07, 0xf0, /* 000001111111 */
+	0x07, 0xf0, /* 000001111111 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+
+	/* 214 0xd6 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0xf0, /* 000011111111 */
+	0x0f, 0xf0, /* 000011111111 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+
+	/* 215 0xd7 '.' */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+	0x0d, 0x80, /* 000011011000 */
+
+	/* 216 0xd8 '.' */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0x06, 0x00, /* 000001100000 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+
+	/* 217 0xd9 '.' */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0xfe, 0x00, /* 111111100000 */
+	0xfe, 0x00, /* 111111100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 218 0xda '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x07, 0xf0, /* 000001111111 */
+	0x07, 0xf0, /* 000001111111 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+
+	/* 219 0xdb '.' */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+
+	/* 220 0xdc '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+
+	/* 221 0xdd '.' */
+	0xfc, 0x00, /* 111111000000 */
+	0xfc, 0x00, /* 111111000000 */
+	0xfc, 0x00, /* 111111000000 */
+	0xfc, 0x00, /* 111111000000 */
+	0xfc, 0x00, /* 111111000000 */
+	0xfc, 0x00, /* 111111000000 */
+	0xfc, 0x00, /* 111111000000 */
+	0xfc, 0x00, /* 111111000000 */
+	0xfc, 0x00, /* 111111000000 */
+	0xfc, 0x00, /* 111111000000 */
+	0xfc, 0x00, /* 111111000000 */
+	0xfc, 0x00, /* 111111000000 */
+	0xfc, 0x00, /* 111111000000 */
+	0xfc, 0x00, /* 111111000000 */
+	0xfc, 0x00, /* 111111000000 */
+	0xfc, 0x00, /* 111111000000 */
+	0xfc, 0x00, /* 111111000000 */
+	0xfc, 0x00, /* 111111000000 */
+	0xfc, 0x00, /* 111111000000 */
+	0xfc, 0x00, /* 111111000000 */
+	0xfc, 0x00, /* 111111000000 */
+	0xfc, 0x00, /* 111111000000 */
+
+	/* 222 0xde '.' */
+	0x03, 0xf0, /* 000000111111 */
+	0x03, 0xf0, /* 000000111111 */
+	0x03, 0xf0, /* 000000111111 */
+	0x03, 0xf0, /* 000000111111 */
+	0x03, 0xf0, /* 000000111111 */
+	0x03, 0xf0, /* 000000111111 */
+	0x03, 0xf0, /* 000000111111 */
+	0x03, 0xf0, /* 000000111111 */
+	0x03, 0xf0, /* 000000111111 */
+	0x03, 0xf0, /* 000000111111 */
+	0x03, 0xf0, /* 000000111111 */
+	0x03, 0xf0, /* 000000111111 */
+	0x03, 0xf0, /* 000000111111 */
+	0x03, 0xf0, /* 000000111111 */
+	0x03, 0xf0, /* 000000111111 */
+	0x03, 0xf0, /* 000000111111 */
+	0x03, 0xf0, /* 000000111111 */
+	0x03, 0xf0, /* 000000111111 */
+	0x03, 0xf0, /* 000000111111 */
+	0x03, 0xf0, /* 000000111111 */
+	0x03, 0xf0, /* 000000111111 */
+	0x03, 0xf0, /* 000000111111 */
+
+	/* 223 0xdf '.' */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 224 0xe0 '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 225 0xe1 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x19, 0x80, /* 000110011000 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x31, 0x80, /* 001100011000 */
+	0x37, 0x80, /* 001101111000 */
+	0x31, 0x80, /* 001100011000 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x31, 0x80, /* 001100011000 */
+	0x77, 0x00, /* 011101110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 226 0xe2 '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 227 0xe3 '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 228 0xe4 '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 229 0xe5 '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 230 0xe6 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x39, 0xc0, /* 001110011100 */
+	0x36, 0xe0, /* 001101101110 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 231 0xe7 '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 232 0xe8 '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 233 0xe9 '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 234 0xea '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 235 0xeb '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 236 0xec '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 237 0xed '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 238 0xee '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 239 0xef '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 240 0xf0 '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 241 0xf1 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 242 0xf2 '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 243 0xf3 '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 244 0xf4 '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 245 0xf5 '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 246 0xf6 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 247 0xf7 '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 248 0xf8 '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 249 0xf9 '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 250 0xfa '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 251 0xfb '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 252 0xfc '.' */
+	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 253 0xfd '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x31, 0x80, /* 001100011000 */
+	0x21, 0x80, /* 001000011000 */
+	0x03, 0x00, /* 000000110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x18, 0x40, /* 000110000100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 254 0xfe '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 255 0xff '.' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+
+};
+
+
+struct font_desc font_sun_12x22 = {
+	SUN12x22_IDX,
+	"SUN12x22",
+	12,
+	22,
+	fontdata_sun12x22,
+#ifdef __sparc__
+	5
+#else
+	-1
+#endif
+};
diff -Nru a/drivers/video/console/font_sun8x16.c b/drivers/video/console/font_sun8x16.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/font_sun8x16.c	Mon Dec  9 18:46:50 2002
@@ -0,0 +1,275 @@
+#include "font.h"
+
+#define FONTDATAMAX 4096
+
+static unsigned char fontdata_sun8x16[FONTDATAMAX] = {
+/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x7e,0x81,0xa5,0x81,0x81,0xbd,0x99,0x81,0x81,0x7e,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x7e,0xff,0xdb,0xff,0xff,0xc3,0xe7,0xff,0xff,0x7e,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x6c,0xfe,0xfe,0xfe,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x10,0x38,0x7c,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x18,0x3c,0x3c,0xe7,0xe7,0xe7,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x18,0x3c,0x7e,0xff,0xff,0x7e,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0xff,0xff,0xff,0xff,0xff,0xff,0xe7,0xc3,0xc3,0xe7,0xff,0xff,0xff,0xff,0xff,0xff,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x3c,0x66,0x42,0x42,0x66,0x3c,0x00,0x00,0x00,0x00,0x00,
+/* */ 0xff,0xff,0xff,0xff,0xff,0xc3,0x99,0xbd,0xbd,0x99,0xc3,0xff,0xff,0xff,0xff,0xff,
+/* */ 0x00,0x00,0x1e,0x0e,0x1a,0x32,0x78,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x3c,0x66,0x66,0x66,0x66,0x3c,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x3f,0x33,0x3f,0x30,0x30,0x30,0x30,0x70,0xf0,0xe0,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x7f,0x63,0x7f,0x63,0x63,0x63,0x63,0x67,0xe7,0xe6,0xc0,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x18,0x18,0xdb,0x3c,0xe7,0x3c,0xdb,0x18,0x18,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfe,0xf8,0xf0,0xe0,0xc0,0x80,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x02,0x06,0x0e,0x1e,0x3e,0xfe,0x3e,0x1e,0x0e,0x06,0x02,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x66,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x7f,0xdb,0xdb,0xdb,0x7b,0x1b,0x1b,0x1b,0x1b,0x1b,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x7c,0xc6,0x60,0x38,0x6c,0xc6,0xc6,0x6c,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xfe,0xfe,0xfe,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x18,0x0c,0xfe,0x0c,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xfe,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xc0,0xc0,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x24,0x66,0xff,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7c,0x7c,0xfe,0xfe,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0xfe,0xfe,0x7c,0x7c,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/*!*/ 0x00,0x00,0x18,0x3c,0x3c,0x3c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
+/*"*/ 0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/*#*/ 0x00,0x00,0x00,0x6c,0x6c,0xfe,0x6c,0x6c,0x6c,0xfe,0x6c,0x6c,0x00,0x00,0x00,0x00,
+/*$*/ 0x18,0x18,0x7c,0xc6,0xc2,0xc0,0x7c,0x06,0x06,0x86,0xc6,0x7c,0x18,0x18,0x00,0x00,
+/*%*/ 0x00,0x00,0x00,0x00,0xc2,0xc6,0x0c,0x18,0x30,0x60,0xc6,0x86,0x00,0x00,0x00,0x00,
+/*&*/ 0x00,0x00,0x38,0x6c,0x6c,0x38,0x76,0xdc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
+/*'*/ 0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/*(*/ 0x00,0x00,0x0c,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0c,0x00,0x00,0x00,0x00,
+/*)*/ 0x00,0x00,0x30,0x18,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x18,0x30,0x00,0x00,0x00,0x00,
+/***/ 0x00,0x00,0x00,0x00,0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00,0x00,0x00,0x00,0x00,
+/*+*/ 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
+/*,*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00,
+/*-*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/*.*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x02,0x06,0x0c,0x18,0x30,0x60,0xc0,0x80,0x00,0x00,0x00,0x00,
+/*0*/ 0x00,0x00,0x7c,0xc6,0xc6,0xce,0xde,0xf6,0xe6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*1*/ 0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x00,0x00,0x00,0x00,
+/*2*/ 0x00,0x00,0x7c,0xc6,0x06,0x0c,0x18,0x30,0x60,0xc0,0xc6,0xfe,0x00,0x00,0x00,0x00,
+/*3*/ 0x00,0x00,0x7c,0xc6,0x06,0x06,0x3c,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*4*/ 0x00,0x00,0x0c,0x1c,0x3c,0x6c,0xcc,0xfe,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00,
+/*5*/ 0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xfc,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*6*/ 0x00,0x00,0x38,0x60,0xc0,0xc0,0xfc,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*7*/ 0x00,0x00,0xfe,0xc6,0x06,0x06,0x0c,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00,
+/*8*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7c,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*9*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7e,0x06,0x06,0x06,0x0c,0x78,0x00,0x00,0x00,0x00,
+/*:*/ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
+/*;*/ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00,
+/*<*/ 0x00,0x00,0x00,0x06,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x06,0x00,0x00,0x00,0x00,
+/*=*/ 0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/*>*/ 0x00,0x00,0x00,0x60,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x60,0x00,0x00,0x00,0x00,
+/*?*/ 0x00,0x00,0x7c,0xc6,0xc6,0x0c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
+/*@*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xde,0xde,0xde,0xdc,0xc0,0x7c,0x00,0x00,0x00,0x00,
+/*A*/ 0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
+/*B*/ 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x66,0x66,0x66,0x66,0xfc,0x00,0x00,0x00,0x00,
+/*C*/ 0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x00,0x00,0x00,0x00,
+/*D*/ 0x00,0x00,0xf8,0x6c,0x66,0x66,0x66,0x66,0x66,0x66,0x6c,0xf8,0x00,0x00,0x00,0x00,
+/*E*/ 0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00,
+/*F*/ 0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
+/*G*/ 0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xde,0xc6,0xc6,0x66,0x3a,0x00,0x00,0x00,0x00,
+/*H*/ 0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
+/*I*/ 0x00,0x00,0x3c,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
+/*J*/ 0x00,0x00,0x1e,0x0c,0x0c,0x0c,0x0c,0x0c,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00,
+/*K*/ 0x00,0x00,0xe6,0x66,0x66,0x6c,0x78,0x78,0x6c,0x66,0x66,0xe6,0x00,0x00,0x00,0x00,
+/*L*/ 0x00,0x00,0xf0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00,
+/*M*/ 0x00,0x00,0xc3,0xe7,0xff,0xff,0xdb,0xc3,0xc3,0xc3,0xc3,0xc3,0x00,0x00,0x00,0x00,
+/*N*/ 0x00,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
+/*O*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*P*/ 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
+/*Q*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xd6,0xde,0x7c,0x0c,0x0e,0x00,0x00,
+/*R*/ 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x6c,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00,
+/*S*/ 0x00,0x00,0x7c,0xc6,0xc6,0x60,0x38,0x0c,0x06,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*T*/ 0x00,0x00,0xff,0xdb,0x99,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
+/*U*/ 0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*V*/ 0x00,0x00,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x00,0x00,0x00,0x00,
+/*W*/ 0x00,0x00,0xc3,0xc3,0xc3,0xc3,0xc3,0xdb,0xdb,0xff,0x66,0x66,0x00,0x00,0x00,0x00,
+/*X*/ 0x00,0x00,0xc3,0xc3,0x66,0x3c,0x18,0x18,0x3c,0x66,0xc3,0xc3,0x00,0x00,0x00,0x00,
+/*Y*/ 0x00,0x00,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
+/*Z*/ 0x00,0x00,0xff,0xc3,0x86,0x0c,0x18,0x30,0x60,0xc1,0xc3,0xff,0x00,0x00,0x00,0x00,
+/*[*/ 0x00,0x00,0x3c,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3c,0x00,0x00,0x00,0x00,
+/*\*/ 0x00,0x00,0x00,0x80,0xc0,0xe0,0x70,0x38,0x1c,0x0e,0x06,0x02,0x00,0x00,0x00,0x00,
+/*]*/ 0x00,0x00,0x3c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3c,0x00,0x00,0x00,0x00,
+/*^*/ 0x10,0x38,0x6c,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/*_*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,
+/*`*/ 0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/*a*/ 0x00,0x00,0x00,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
+/*b*/ 0x00,0x00,0xe0,0x60,0x60,0x78,0x6c,0x66,0x66,0x66,0x66,0x7c,0x00,0x00,0x00,0x00,
+/*c*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc0,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*d*/ 0x00,0x00,0x1c,0x0c,0x0c,0x3c,0x6c,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
+/*e*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*f*/ 0x00,0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
+/*g*/ 0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0xcc,0x78,0x00,
+/*h*/ 0x00,0x00,0xe0,0x60,0x60,0x6c,0x76,0x66,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00,
+/*i*/ 0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
+/*j*/ 0x00,0x00,0x06,0x06,0x00,0x0e,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3c,0x00,
+/*k*/ 0x00,0x00,0xe0,0x60,0x60,0x66,0x6c,0x78,0x78,0x6c,0x66,0xe6,0x00,0x00,0x00,0x00,
+/*l*/ 0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
+/*m*/ 0x00,0x00,0x00,0x00,0x00,0xe6,0xff,0xdb,0xdb,0xdb,0xdb,0xdb,0x00,0x00,0x00,0x00,
+/*n*/ 0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
+/*o*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*p*/ 0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xf0,0x00,
+/*q*/ 0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x0c,0x1e,0x00,
+/*r*/ 0x00,0x00,0x00,0x00,0x00,0xdc,0x76,0x66,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
+/*s*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0x60,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*t*/ 0x00,0x00,0x10,0x30,0x30,0xfc,0x30,0x30,0x30,0x30,0x36,0x1c,0x00,0x00,0x00,0x00,
+/*u*/ 0x00,0x00,0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
+/*v*/ 0x00,0x00,0x00,0x00,0x00,0xc3,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x00,0x00,0x00,0x00,
+/*w*/ 0x00,0x00,0x00,0x00,0x00,0xc3,0xc3,0xc3,0xdb,0xdb,0xff,0x66,0x00,0x00,0x00,0x00,
+/*x*/ 0x00,0x00,0x00,0x00,0x00,0xc3,0x66,0x3c,0x18,0x3c,0x66,0xc3,0x00,0x00,0x00,0x00,
+/*y*/ 0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0xf8,0x00,
+/*z*/ 0x00,0x00,0x00,0x00,0x00,0xfe,0xcc,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00,
+/*{*/ 0x00,0x00,0x0e,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0e,0x00,0x00,0x00,0x00,
+/*|*/ 0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
+/*}*/ 0x00,0x00,0x70,0x18,0x18,0x18,0x0e,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00,
+/*~*/ 0x00,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xc6,0xfe,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x0c,0x06,0x7c,0x00,0x00,
+/* */ 0x00,0x00,0xcc,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x0c,0x18,0x30,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x10,0x38,0x6c,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0xcc,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x60,0x30,0x18,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x38,0x6c,0x38,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x3c,0x66,0x60,0x60,0x66,0x3c,0x0c,0x06,0x3c,0x00,0x00,0x00,
+/* */ 0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x66,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x18,0x3c,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
+/* */ 0x00,0xc6,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
+/* */ 0x38,0x6c,0x38,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
+/* */ 0x18,0x30,0x60,0x00,0xfe,0x66,0x60,0x7c,0x60,0x60,0x66,0xfe,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x6e,0x3b,0x1b,0x7e,0xd8,0xdc,0x77,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x3e,0x6c,0xcc,0xcc,0xfe,0xcc,0xcc,0xcc,0xcc,0xce,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x30,0x78,0xcc,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x60,0x30,0x18,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0xc6,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0x78,0x00,
+/* */ 0x00,0xc6,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/* */ 0x00,0xc6,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x18,0x18,0x7e,0xc3,0xc0,0xc0,0xc0,0xc3,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xe6,0xfc,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0xc3,0x66,0x3c,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
+/* */ 0x00,0xfc,0x66,0x66,0x7c,0x62,0x66,0x6f,0x66,0x66,0x66,0xf3,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x0e,0x1b,0x18,0x18,0x18,0x7e,0x18,0x18,0x18,0x18,0x18,0xd8,0x70,0x00,0x00,
+/* */ 0x00,0x18,0x30,0x60,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x0c,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x18,0x30,0x60,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x18,0x30,0x60,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x76,0xdc,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
+/* */ 0x76,0xdc,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x3c,0x6c,0x6c,0x3e,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x38,0x6c,0x6c,0x38,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0xc0,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x60,0xce,0x9b,0x06,0x0c,0x1f,0x00,0x00,
+/* */ 0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x66,0xce,0x96,0x3e,0x06,0x06,0x00,0x00,
+/* */ 0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x3c,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x36,0x6c,0xd8,0x6c,0x36,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0xd8,0x6c,0x36,0x6c,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,
+/* */ 0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,
+/* */ 0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,
+/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* */ 0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* */ 0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* */ 0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* */ 0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* */ 0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* */ 0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* */ 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x3f,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* */ 0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* */ 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* */ 0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* */ 0x18,0x18,0x18,0x18,0x18,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* */ 0x18,0x18,0x18,0x18,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* */ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+/* */ 0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,
+/* */ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
+/* */ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0xd8,0xd8,0xd8,0xdc,0x76,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x78,0xcc,0xcc,0xcc,0xd8,0xcc,0xc6,0xc6,0xc6,0xcc,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0xfe,0xc6,0xc6,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0xfe,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0xfe,0xc6,0x60,0x30,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x7e,0xd8,0xd8,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xc0,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x76,0xdc,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x7e,0x18,0x3c,0x66,0x66,0x66,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0x6c,0x38,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x38,0x6c,0xc6,0xc6,0xc6,0x6c,0x6c,0x6c,0x6c,0xee,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x1e,0x30,0x18,0x0c,0x3e,0x66,0x66,0x66,0x66,0x3c,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x7e,0xdb,0xdb,0xdb,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x03,0x06,0x7e,0xdb,0xdb,0xf3,0x7e,0x60,0xc0,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x1c,0x30,0x60,0x60,0x7c,0x60,0x60,0x60,0x30,0x1c,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0xff,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x00,0x7e,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x00,0x7e,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x0e,0x1b,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x7e,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x38,0x6c,0x6c,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x0f,0x0c,0x0c,0x0c,0x0c,0x0c,0xec,0x6c,0x6c,0x3c,0x1c,0x00,0x00,0x00,0x00,
+/* */ 0x00,0xd8,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x70,0xd8,0x30,0x60,0xc8,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x00,0x00,0x00,0x00,0x00,
+/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+struct font_desc font_sun_8x16 = {
+	SUN8x16_IDX,
+	"SUN8x16",
+	8,
+	16,
+	fontdata_sun8x16,
+#ifdef __sparc__
+	10
+#else
+	-1
+#endif
+};
diff -Nru a/drivers/video/console/fonts.c b/drivers/video/console/fonts.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/fonts.c	Mon Dec  9 18:46:50 2002
@@ -0,0 +1,142 @@
+/*
+ * linux/drivers/video/fonts.c -- `Soft' font definitions
+ *
+ *    Created 1995 by Geert Uytterhoeven
+ *    Rewritten 1998 by Martin Mares <mj@ucw.cz>
+ *
+ *	2001 - Documented with DocBook
+ *	- Brad Douglas <brad@neruo.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#if defined(__mc68000__) || defined(CONFIG_APUS)
+#include <asm/setup.h>
+#endif
+#include "font.h"
+
+#define NO_FONTS
+
+static struct font_desc *fonts[] = {
+#ifdef CONFIG_FONT_8x8
+#undef NO_FONTS
+    &font_vga_8x8,
+#endif
+#ifdef CONFIG_FONT_8x16
+#undef NO_FONTS
+    &font_vga_8x16,
+#endif
+#ifdef CONFIG_FONT_6x11
+#undef NO_FONTS
+    &font_vga_6x11,
+#endif
+#ifdef CONFIG_FONT_SUN8x16
+#undef NO_FONTS
+    &font_sun_8x16,
+#endif
+#ifdef CONFIG_FONT_SUN12x22
+#undef NO_FONTS
+    &font_sun_12x22,
+#endif
+#ifdef CONFIG_FONT_ACORN_8x8
+#undef NO_FONTS
+    &font_acorn_8x8,
+#endif
+#ifdef CONFIG_FONT_PEARL_8x8
+#undef NO_FONTS
+    &font_pearl_8x8,
+#endif
+#ifdef CONFIG_FONT_MINI_4x6
+#undef NO_FONTS
+    &font_mini_4x6,
+#endif
+};
+
+#define num_fonts (sizeof(fonts)/sizeof(*fonts))
+
+#ifdef NO_FONTS
+#error No fonts configured.
+#endif
+
+
+/**
+ *	find_font - find a font
+ *	@name: string name of a font
+ *
+ *	Find a specified font with string name @name.
+ *
+ *	Returns %NULL if no font found, or a pointer to the
+ *	specified font.
+ *
+ */
+
+struct font_desc *find_font(char *name)
+{
+   unsigned int i;
+
+   for (i = 0; i < num_fonts; i++)
+      if (!strcmp(fonts[i]->name, name))
+	  return fonts[i];
+   return NULL;
+}
+
+
+/**
+ *	get_default_font - get default font
+ *	@xres: screen size of X
+ *	@yres: screen size of Y
+ *
+ *	Get the default font for a specified screen size.
+ *	Dimensions are in pixels.
+ *
+ *	Returns %NULL if no font is found, or a pointer to the
+ *	chosen font.
+ *
+ */
+
+struct font_desc *get_default_font(int xres, int yres)
+{
+    int i, c, cc;
+    struct font_desc *f, *g;
+
+    g = NULL;
+    cc = -10000;
+    for(i=0; i<num_fonts; i++) {
+	f = fonts[i];
+	c = f->pref;
+#if defined(__mc68000__) || defined(CONFIG_APUS)
+#ifdef CONFIG_FONT_PEARL_8x8
+	if (MACH_IS_AMIGA && f->idx == PEARL8x8_IDX)
+	    c = 100;
+#endif
+#ifdef CONFIG_FONT_6x11
+	if (MACH_IS_MAC && xres < 640 && f->idx == VGA6x11_IDX)
+	    c = 100;
+#endif
+#endif
+	if ((yres < 400) == (f->height <= 8))
+	    c += 1000;
+	if (c > cc) {
+	    cc = c;
+	    g = f;
+	}
+    }
+    return g;
+}
+
+int init_module(void) { return 0; };
+void cleanup_module(void) {};
+
+EXPORT_SYMBOL(fonts);
+EXPORT_SYMBOL(find_font);
+EXPORT_SYMBOL(get_default_font);
+
+MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
+MODULE_DESCRIPTION("Console Fonts");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/mdacon.c	Mon Dec  9 18:46:38 2002
@@ -0,0 +1,631 @@
+/*
+ *  linux/drivers/video/mdacon.c -- Low level MDA based console driver
+ *
+ *	(c) 1998 Andrew Apted <ajapted@netspace.net.au>
+ *
+ *      including portions (c) 1995-1998 Patrick Caulfield.
+ *
+ *      slight improvements (c) 2000 Edward Betts <edward@debian.org>
+ *
+ *  This file is based on the VGA console driver (vgacon.c):
+ *	
+ *	Created 28 Sep 1997 by Geert Uytterhoeven
+ *
+ *	Rewritten by Martin Mares <mj@ucw.cz>, July 1998
+ *
+ *  and on the old console.c, vga.c and vesa_blank.c drivers:
+ *
+ *	Copyright (C) 1991, 1992  Linus Torvalds
+ *			    1995  Jay Estabrook
+ *
+ *  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.
+ *
+ *  Changelog:
+ *  Paul G. (03/2001) Fix mdacon= boot prompt to use __setup().
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/string.h>
+#include <linux/kd.h>
+#include <linux/slab.h>
+#include <linux/vt_kern.h>
+#include <linux/vt_buffer.h>
+#include <linux/selection.h>
+#include <linux/spinlock.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/vga.h>
+
+static spinlock_t mda_lock = SPIN_LOCK_UNLOCKED;
+
+/* description of the hardware layout */
+
+static unsigned long	mda_vram_base;		/* Base of video memory */
+static unsigned long	mda_vram_len;		/* Size of video memory */
+static unsigned int	mda_num_columns;	/* Number of text columns */
+static unsigned int	mda_num_lines;		/* Number of text lines */
+
+static unsigned int	mda_index_port;		/* Register select port */
+static unsigned int	mda_value_port;		/* Register value port */
+static unsigned int	mda_mode_port;		/* Mode control port */
+static unsigned int	mda_status_port;	/* Status and Config port */
+static unsigned int	mda_gfx_port;		/* Graphics control port */
+
+/* current hardware state */
+
+static int	mda_origin_loc=-1;
+static int	mda_cursor_loc=-1;
+static int	mda_cursor_size_from=-1;
+static int	mda_cursor_size_to=-1;
+
+static enum { TYPE_MDA, TYPE_HERC, TYPE_HERCPLUS, TYPE_HERCCOLOR } mda_type;
+static char *mda_type_name;
+
+/* console information */
+
+static int	mda_first_vc = 13;
+static int	mda_last_vc  = 16;
+
+static struct vc_data	*mda_display_fg = NULL;
+
+MODULE_PARM(mda_first_vc, "1-255i");
+MODULE_PARM(mda_last_vc,  "1-255i");
+
+/* MDA register values
+ */
+
+#define MDA_CURSOR_BLINKING	0x00
+#define MDA_CURSOR_OFF		0x20
+#define MDA_CURSOR_SLOWBLINK	0x60
+
+#define MDA_MODE_GRAPHICS	0x02
+#define MDA_MODE_VIDEO_EN	0x08
+#define MDA_MODE_BLINK_EN	0x20
+#define MDA_MODE_GFX_PAGE1	0x80
+
+#define MDA_STATUS_HSYNC	0x01
+#define MDA_STATUS_VSYNC	0x80
+#define MDA_STATUS_VIDEO	0x08
+
+#define MDA_CONFIG_COL132	0x08
+#define MDA_GFX_MODE_EN		0x01
+#define MDA_GFX_PAGE_EN		0x02
+
+
+/*
+ * MDA could easily be classified as "pre-dinosaur hardware".
+ */
+
+static void write_mda_b(unsigned int val, unsigned char reg)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&mda_lock, flags);	
+
+	outb_p(reg, mda_index_port); 
+	outb_p(val, mda_value_port);
+
+	spin_unlock_irqrestore(&mda_lock, flags);
+}
+
+static void write_mda_w(unsigned int val, unsigned char reg)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&mda_lock, flags);
+
+	outb_p(reg,   mda_index_port); outb_p(val >> 8,   mda_value_port);
+	outb_p(reg+1, mda_index_port); outb_p(val & 0xff, mda_value_port);
+
+	spin_unlock_irqrestore(&mda_lock, flags);
+}
+
+#ifdef TEST_MDA_B
+static int test_mda_b(unsigned char val, unsigned char reg)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&mda_lock, flags);
+
+	outb_p(reg, mda_index_port); 
+	outb  (val, mda_value_port);
+
+	udelay(20); val = (inb_p(mda_value_port) == val);
+
+	spin_unlock_irqrestore(&mda_lock, flags);
+	return val;
+}
+#endif
+
+static inline void mda_set_origin(unsigned int location)
+{
+	if (mda_origin_loc == location)
+		return;
+
+	write_mda_w(location >> 1, 0x0c);
+
+	mda_origin_loc = location;
+}
+
+static inline void mda_set_cursor(unsigned int location) 
+{
+	if (mda_cursor_loc == location)
+		return;
+
+	write_mda_w(location >> 1, 0x0e);
+
+	mda_cursor_loc = location;
+}
+
+static inline void mda_set_cursor_size(int from, int to)
+{
+	if (mda_cursor_size_from==from && mda_cursor_size_to==to)
+		return;
+	
+	if (from > to) {
+		write_mda_b(MDA_CURSOR_OFF, 0x0a);	/* disable cursor */
+	} else {
+		write_mda_b(from, 0x0a);	/* cursor start */
+		write_mda_b(to,   0x0b);	/* cursor end */
+	}
+
+	mda_cursor_size_from = from;
+	mda_cursor_size_to   = to;
+}
+
+
+#ifndef MODULE
+static int __init mdacon_setup(char *str)
+{
+	/* command line format: mdacon=<first>,<last> */
+
+	int ints[3];
+
+	str = get_options(str, ARRAY_SIZE(ints), ints);
+
+	if (ints[0] < 2)
+		return 0;
+
+	if (ints[1] < 1 || ints[1] > MAX_NR_CONSOLES || 
+	    ints[2] < 1 || ints[2] > MAX_NR_CONSOLES)
+		return 0;
+
+	mda_first_vc = ints[1];
+	mda_last_vc  = ints[2];
+	return 1;
+}
+
+__setup("mdacon=", mdacon_setup);
+#endif
+
+static int __init mda_detect(void)
+{
+	int count=0;
+	u16 *p, p_save;
+	u16 *q, q_save;
+
+	/* do a memory check */
+
+	p = (u16 *) mda_vram_base;
+	q = (u16 *) (mda_vram_base + 0x01000);
+
+	p_save = scr_readw(p); q_save = scr_readw(q);
+
+	scr_writew(0xAA55, p); if (scr_readw(p) == 0xAA55) count++;
+	scr_writew(0x55AA, p); if (scr_readw(p) == 0x55AA) count++;
+	scr_writew(p_save, p);
+
+	if (count != 2) {
+		return 0;
+	}
+
+	/* check if we have 4K or 8K */
+
+	scr_writew(0xA55A, q); scr_writew(0x0000, p);
+	if (scr_readw(q) == 0xA55A) count++;
+	
+	scr_writew(0x5AA5, q); scr_writew(0x0000, p);
+	if (scr_readw(q) == 0x5AA5) count++;
+
+	scr_writew(p_save, p); scr_writew(q_save, q);
+	
+	if (count == 4) {
+		mda_vram_len = 0x02000;
+	}
+	
+	/* Ok, there is definitely a card registering at the correct
+	 * memory location, so now we do an I/O port test.
+	 */
+
+#ifdef TEST_MDA_B
+	/* Edward: These two mess `tests' mess up my cursor on bootup */
+
+	/* cursor low register */
+	if (! test_mda_b(0x66, 0x0f)) {
+		return 0;
+	}
+
+	/* cursor low register */
+	if (! test_mda_b(0x99, 0x0f)) {
+		return 0;
+	}
+#endif
+
+	/* See if the card is a Hercules, by checking whether the vsync
+	 * bit of the status register is changing.  This test lasts for
+	 * approximately 1/10th of a second.
+	 */
+	
+	p_save = q_save = inb_p(mda_status_port) & MDA_STATUS_VSYNC;
+
+	for (count=0; count < 50000 && p_save == q_save; count++) {
+		q_save = inb(mda_status_port) & MDA_STATUS_VSYNC;
+		udelay(2);
+	}
+
+	if (p_save != q_save) {
+		switch (inb_p(mda_status_port) & 0x70) {
+			case 0x10:
+				mda_type = TYPE_HERCPLUS;
+				mda_type_name = "HerculesPlus";
+				break;
+			case 0x50:
+				mda_type = TYPE_HERCCOLOR;
+				mda_type_name = "HerculesColor";
+				break;
+			default:
+				mda_type = TYPE_HERC;
+				mda_type_name = "Hercules";
+				break;
+		}
+	}
+
+	return 1;
+}
+
+static void __init mda_initialize(void)
+{
+	write_mda_b(97, 0x00);		/* horizontal total */
+	write_mda_b(80, 0x01);		/* horizontal displayed */
+	write_mda_b(82, 0x02);		/* horizontal sync pos */
+	write_mda_b(15, 0x03);		/* horizontal sync width */
+
+	write_mda_b(25, 0x04);		/* vertical total */
+	write_mda_b(6,  0x05);		/* vertical total adjust */
+	write_mda_b(25, 0x06);		/* vertical displayed */
+	write_mda_b(25, 0x07);		/* vertical sync pos */
+
+	write_mda_b(2,  0x08);		/* interlace mode */
+	write_mda_b(13, 0x09);		/* maximum scanline */
+	write_mda_b(12, 0x0a);		/* cursor start */
+	write_mda_b(13, 0x0b);		/* cursor end */
+
+	write_mda_w(0x0000, 0x0c);	/* start address */
+	write_mda_w(0x0000, 0x0e);	/* cursor location */
+
+	outb_p(MDA_MODE_VIDEO_EN | MDA_MODE_BLINK_EN, mda_mode_port);
+	outb_p(0x00, mda_status_port);
+	outb_p(0x00, mda_gfx_port);
+}
+
+static const char __init *mdacon_startup(void)
+{
+	mda_num_columns = 80;
+	mda_num_lines   = 25;
+
+	mda_vram_base = VGA_MAP_MEM(0xb0000);
+	mda_vram_len  = 0x01000;
+
+	mda_index_port  = 0x3b4;
+	mda_value_port  = 0x3b5;
+	mda_mode_port   = 0x3b8;
+	mda_status_port = 0x3ba;
+	mda_gfx_port    = 0x3bf;
+
+	mda_type = TYPE_MDA;
+	mda_type_name = "MDA";
+
+	if (! mda_detect()) {
+		printk("mdacon: MDA card not detected.\n");
+		return NULL;
+	}
+
+	if (mda_type != TYPE_MDA) {
+		mda_initialize();
+	}
+
+	/* cursor looks ugly during boot-up, so turn it off */
+	mda_set_cursor(mda_vram_len - 1);
+
+	printk("mdacon: %s with %ldK of memory detected.\n",
+		mda_type_name, mda_vram_len/1024);
+
+	return "MDA-2";
+}
+
+static void mdacon_init(struct vc_data *c, int init)
+{
+	c->vc_complement_mask = 0x0800;	 /* reverse video */
+	c->vc_display_fg = &mda_display_fg;
+
+	if (init) {
+		c->vc_cols = mda_num_columns;
+		c->vc_rows = mda_num_lines;
+	} else {
+		vc_resize(c->vc_num, mda_num_columns, mda_num_lines);
+        }
+	
+	/* make the first MDA console visible */
+
+	if (mda_display_fg == NULL)
+		mda_display_fg = c;
+
+	MOD_INC_USE_COUNT;
+}
+
+static void mdacon_deinit(struct vc_data *c)
+{
+	/* con_set_default_unimap(c->vc_num); */
+
+	if (mda_display_fg == c)
+		mda_display_fg = NULL;
+
+	MOD_DEC_USE_COUNT;
+}
+
+static inline u16 mda_convert_attr(u16 ch)
+{
+	u16 attr = 0x0700;
+
+	/* Underline and reverse-video are mutually exclusive on MDA.
+	 * Since reverse-video is used for cursors and selected areas,
+	 * it takes precedence. 
+	 */
+
+	if (ch & 0x0800)	attr = 0x7000;	/* reverse */
+	else if (ch & 0x0400)	attr = 0x0100;	/* underline */
+
+	return ((ch & 0x0200) << 2) | 		/* intensity */ 
+		(ch & 0x8000) |			/* blink */ 
+		(ch & 0x00ff) | attr;
+}
+
+static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity, 
+			    u8 blink, u8 underline, u8 reverse)
+{
+	/* The attribute is just a bit vector:
+	 *
+	 *	Bit 0..1 : intensity (0..2)
+	 *	Bit 2    : underline
+	 *	Bit 3    : reverse
+	 *	Bit 7    : blink
+	 */
+
+	return (intensity & 3) |
+		((underline & 1) << 2) |
+		((reverse   & 1) << 3) |
+		((blink     & 1) << 7);
+}
+
+static void mdacon_invert_region(struct vc_data *c, u16 *p, int count)
+{
+	for (; count > 0; count--) {
+		scr_writew(scr_readw(p) ^ 0x0800, p);
+		p++;
+	}
+}
+
+#define MDA_ADDR(x,y)  ((u16 *) mda_vram_base + (y)*mda_num_columns + (x))
+
+static void mdacon_putc(struct vc_data *c, int ch, int y, int x)
+{
+	scr_writew(mda_convert_attr(ch), MDA_ADDR(x, y));
+}
+
+static void mdacon_putcs(struct vc_data *c, const unsigned short *s,
+		         int count, int y, int x)
+{
+	u16 *dest = MDA_ADDR(x, y);
+
+	for (; count > 0; count--) {
+		scr_writew(mda_convert_attr(scr_readw(s++)), dest++);
+	}
+}
+
+static void mdacon_clear(struct vc_data *c, int y, int x, 
+			  int height, int width)
+{
+	u16 *dest = MDA_ADDR(x, y);
+	u16 eattr = mda_convert_attr(c->vc_video_erase_char);
+
+	if (width <= 0 || height <= 0)
+		return;
+
+	if (x==0 && width==mda_num_columns) {
+		scr_memsetw(dest, eattr, height*width*2);
+	} else {
+		for (; height > 0; height--, dest+=mda_num_columns)
+			scr_memsetw(dest, eattr, width*2);
+	}
+}
+                        
+static void mdacon_bmove(struct vc_data *c, int sy, int sx, 
+			 int dy, int dx, int height, int width)
+{
+	u16 *src, *dest;
+
+	if (width <= 0 || height <= 0)
+		return;
+		
+	if (sx==0 && dx==0 && width==mda_num_columns) {
+		scr_memmovew(MDA_ADDR(0,dy), MDA_ADDR(0,sy), height*width*2);
+
+	} else if (dy < sy || (dy == sy && dx < sx)) {
+		src  = MDA_ADDR(sx, sy);
+		dest = MDA_ADDR(dx, dy);
+
+		for (; height > 0; height--) {
+			scr_memmovew(dest, src, width*2);
+			src  += mda_num_columns;
+			dest += mda_num_columns;
+		}
+	} else {
+		src  = MDA_ADDR(sx, sy+height-1);
+		dest = MDA_ADDR(dx, dy+height-1);
+
+		for (; height > 0; height--) {
+			scr_memmovew(dest, src, width*2);
+			src  -= mda_num_columns;
+			dest -= mda_num_columns;
+		}
+	}
+}
+
+static int mdacon_switch(struct vc_data *c)
+{
+	return 1;	/* redrawing needed */
+}
+
+static int mdacon_set_palette(struct vc_data *c, unsigned char *table)
+{
+	return -EINVAL;
+}
+
+static int mdacon_blank(struct vc_data *c, int blank)
+{
+	if (mda_type == TYPE_MDA) {
+		if (blank) 
+			scr_memsetw((void *)mda_vram_base, 
+				mda_convert_attr(c->vc_video_erase_char),
+				c->vc_screenbuf_size);
+		/* Tell console.c that it has to restore the screen itself */
+		return 1;
+	} else {
+		if (blank)
+			outb_p(0x00, mda_mode_port);	/* disable video */
+		else
+			outb_p(MDA_MODE_VIDEO_EN | MDA_MODE_BLINK_EN, 
+				mda_mode_port);
+		return 0;
+	}
+}
+
+static int mdacon_font_op(struct vc_data *c, struct console_font_op *op)
+{
+	return -ENOSYS;
+}
+
+static int mdacon_scrolldelta(struct vc_data *c, int lines)
+{
+	return 0;
+}
+
+static void mdacon_cursor(struct vc_data *c, int mode)
+{
+	if (mode == CM_ERASE) {
+		mda_set_cursor(mda_vram_len - 1);
+		return;
+	}
+
+	mda_set_cursor(c->vc_y*mda_num_columns*2 + c->vc_x*2);
+
+	switch (c->vc_cursor_type & 0x0f) {
+
+		case CUR_LOWER_THIRD:	mda_set_cursor_size(10, 13); break;
+		case CUR_LOWER_HALF:	mda_set_cursor_size(7,  13); break;
+		case CUR_TWO_THIRDS:	mda_set_cursor_size(4,  13); break;
+		case CUR_BLOCK:		mda_set_cursor_size(1,  13); break;
+		case CUR_NONE:		mda_set_cursor_size(14, 13); break;
+		default:		mda_set_cursor_size(12, 13); break;
+	}
+}
+
+static int mdacon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
+{
+	u16 eattr = mda_convert_attr(c->vc_video_erase_char);
+
+	if (!lines)
+		return 0;
+
+	if (lines > c->vc_rows)   /* maximum realistic size */
+		lines = c->vc_rows;
+
+	switch (dir) {
+
+	case SM_UP:
+		scr_memmovew(MDA_ADDR(0,t), MDA_ADDR(0,t+lines),
+				(b-t-lines)*mda_num_columns*2);
+		scr_memsetw(MDA_ADDR(0,b-lines), eattr,
+				lines*mda_num_columns*2);
+		break;
+
+	case SM_DOWN:
+		scr_memmovew(MDA_ADDR(0,t+lines), MDA_ADDR(0,t),
+				(b-t-lines)*mda_num_columns*2);
+		scr_memsetw(MDA_ADDR(0,t), eattr, lines*mda_num_columns*2);
+		break;
+	}
+
+	return 0;
+}
+
+
+/*
+ *  The console `switch' structure for the MDA based console
+ */
+
+const struct consw mda_con = {
+	.con_startup =		mdacon_startup,
+	.con_init =		mdacon_init,
+	.con_deinit =		mdacon_deinit,
+	.con_clear =		mdacon_clear,
+	.con_putc =		mdacon_putc,
+	.con_putcs =		mdacon_putcs,
+	.con_cursor =		mdacon_cursor,
+	.con_scroll =		mdacon_scroll,
+	.con_bmove =		mdacon_bmove,
+	.con_switch =		mdacon_switch,
+	.con_blank =		mdacon_blank,
+	.con_font_op =		mdacon_font_op,
+	.con_set_palette =	mdacon_set_palette,
+	.con_scrolldelta =	mdacon_scrolldelta,
+	.con_build_attr =	mdacon_build_attr,
+	.con_invert_region =	mdacon_invert_region,
+};
+
+void __init mda_console_init(void)
+{
+	if (mda_first_vc > mda_last_vc)
+		return;
+
+	take_over_console(&mda_con, mda_first_vc-1, mda_last_vc-1, 0);
+}
+
+#ifdef MODULE
+
+MODULE_LICENSE("GPL");
+
+int init_module(void)
+{
+	mda_console_init();
+
+	return 0;
+}
+
+void cleanup_module(void)
+{
+	give_up_console(&mda_con);
+}
+
+#endif
diff -Nru a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/newport_con.c	Mon Dec  9 18:46:50 2002
@@ -0,0 +1,745 @@
+/*
+ * newport_con.c: Abscon for newport hardware
+ * 
+ * (C) 1998 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
+ * (C) 1999 Ulf Carlsson (ulfc@thepuffingruop.com)
+ * 
+ * This driver is based on sgicons.c and cons_newport.
+ * 
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/tty.h>
+#include <linux/kd.h>
+#include <linux/selection.h>
+#include <linux/console.h>
+#include <linux/vt_kern.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <video/newport.h>
+#define INCLUDE_LINUX_LOGO_DATA
+#include <asm/linux_logo.h>
+
+#include "font.h"
+
+#define LOGO_W		80
+#define LOGO_H		80
+
+extern struct font_desc font_vga_8x16;
+
+#define FONT_DATA ((unsigned char *)font_vga_8x16.data)
+
+/* borrowed from fbcon.c */
+#define REFCOUNT(fd)	(((int *)(fd))[-1])
+#define FNTSIZE(fd)	(((int *)(fd))[-2])
+#define FNTCHARCNT(fd)	(((int *)(fd))[-3])
+#define FONT_EXTRA_WORDS 3
+
+static unsigned char *font_data[MAX_NR_CONSOLES];
+
+extern struct newport_regs *npregs;
+
+static int logo_active;
+static int topscan;
+static int xcurs_correction = 29;
+static int newport_xsize;
+static int newport_ysize;
+
+#define BMASK(c) (c << 24)
+
+#define RENDER(regs, cp) do { \
+(regs)->go.zpattern = BMASK((cp)[0x0]); (regs)->go.zpattern = BMASK((cp)[0x1]); \
+(regs)->go.zpattern = BMASK((cp)[0x2]); (regs)->go.zpattern = BMASK((cp)[0x3]); \
+(regs)->go.zpattern = BMASK((cp)[0x4]); (regs)->go.zpattern = BMASK((cp)[0x5]); \
+(regs)->go.zpattern = BMASK((cp)[0x6]); (regs)->go.zpattern = BMASK((cp)[0x7]); \
+(regs)->go.zpattern = BMASK((cp)[0x8]); (regs)->go.zpattern = BMASK((cp)[0x9]); \
+(regs)->go.zpattern = BMASK((cp)[0xa]); (regs)->go.zpattern = BMASK((cp)[0xb]); \
+(regs)->go.zpattern = BMASK((cp)[0xc]); (regs)->go.zpattern = BMASK((cp)[0xd]); \
+(regs)->go.zpattern = BMASK((cp)[0xe]); (regs)->go.zpattern = BMASK((cp)[0xf]); \
+} while(0)
+
+#define TESTVAL 0xdeadbeef
+#define XSTI_TO_FXSTART(val) (((val) & 0xffff) << 11)
+
+static inline void newport_render_background(int xstart, int ystart,
+					     int xend, int yend, int ci)
+{
+	newport_wait();
+	npregs->set.wrmask = 0xffffffff;
+	npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
+				 NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
+				 | NPORT_DMODE0_STOPY);
+	npregs->set.colori = ci;
+	npregs->set.xystarti =
+	    (xstart << 16) | ((ystart + topscan) & 0x3ff);
+	npregs->go.xyendi =
+	    ((xend + 7) << 16) | ((yend + topscan + 15) & 0x3ff);
+}
+
+static inline void newport_init_cmap(void)
+{
+	unsigned short i;
+
+	for (i = 0; i < 16; i++) {
+		newport_bfwait();
+		newport_cmap_setaddr(npregs, color_table[i]);
+		newport_cmap_setrgb(npregs,
+				    default_red[i],
+				    default_grn[i], default_blu[i]);
+	}
+}
+
+static inline void newport_show_logo(void)
+{
+	unsigned long i;
+
+	for (i = 0; i < LINUX_LOGO_COLORS; i++) {
+		newport_bfwait();
+		newport_cmap_setaddr(npregs, i + 0x20);
+		newport_cmap_setrgb(npregs,
+				    linux_logo_red[i],
+				    linux_logo_green[i],
+				    linux_logo_blue[i]);
+	}
+
+	newport_wait();
+	npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
+				 NPORT_DMODE0_CHOST);
+
+	npregs->set.xystarti = ((newport_xsize - LOGO_W) << 16) | (0);
+	npregs->set.xyendi = ((newport_xsize - 1) << 16);
+	newport_wait();
+
+	for (i = 0; i < LOGO_W * LOGO_H; i++)
+		npregs->go.hostrw0 = linux_logo[i] << 24;
+}
+
+static inline void newport_clear_screen(int xstart, int ystart, int xend,
+					int yend, int ci)
+{
+	if (logo_active)
+		return;
+
+	newport_wait();
+	npregs->set.wrmask = 0xffffffff;
+	npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
+				 NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
+				 | NPORT_DMODE0_STOPY);
+	npregs->set.colori = ci;
+	npregs->set.xystarti = (xstart << 16) | ystart;
+	npregs->go.xyendi = (xend << 16) | yend;
+}
+
+static inline void newport_clear_lines(int ystart, int yend, int ci)
+{
+	ystart = ((ystart << 4) + topscan) & 0x3ff;
+	yend = ((yend << 4) + topscan + 15) & 0x3ff;
+	newport_clear_screen(0, ystart, 1280 + 63, yend, ci);
+}
+
+void newport_reset(void)
+{
+	unsigned short treg;
+	int i;
+
+	newport_wait();
+	treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
+	newport_vc2_set(npregs, VC2_IREG_CONTROL,
+			(treg | VC2_CTRL_EVIDEO));
+
+	treg = newport_vc2_get(npregs, VC2_IREG_CENTRY);
+	newport_vc2_set(npregs, VC2_IREG_RADDR, treg);
+	npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
+			       NPORT_DMODE_W2 | VC2_PROTOCOL);
+	for (i = 0; i < 128; i++) {
+		newport_bfwait();
+		if (i == 92 || i == 94)
+			npregs->set.dcbdata0.byshort.s1 = 0xff00;
+		else
+			npregs->set.dcbdata0.byshort.s1 = 0x0000;
+	}
+
+	newport_init_cmap();
+
+	/* turn off popup plane */
+	npregs->set.dcbmode = (DCB_XMAP0 | R_DCB_XMAP9_PROTOCOL |
+			       XM9_CRS_CONFIG | NPORT_DMODE_W1);
+	npregs->set.dcbdata0.bybytes.b3 &= ~XM9_PUPMODE;
+	npregs->set.dcbmode = (DCB_XMAP1 | R_DCB_XMAP9_PROTOCOL |
+			       XM9_CRS_CONFIG | NPORT_DMODE_W1);
+	npregs->set.dcbdata0.bybytes.b3 &= ~XM9_PUPMODE;
+
+	topscan = 0;
+	npregs->cset.topscan = 0x3ff;
+	npregs->cset.xywin = (4096 << 16) | 4096;
+
+	/* Clear the screen. */
+	newport_clear_screen(0, 0, 1280 + 63, 1024, 0);
+}
+
+/*
+ * calculate the actual screen size by reading
+ * the video timing out of the VC2
+ */
+void newport_get_screensize(void)
+{
+	int i, cols;
+	unsigned short ventry, treg;
+	unsigned short linetable[128];	/* should be enough */
+
+	ventry = newport_vc2_get(npregs, VC2_IREG_VENTRY);
+	newport_vc2_set(npregs, VC2_IREG_RADDR, ventry);
+	npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
+			       NPORT_DMODE_W2 | VC2_PROTOCOL);
+	for (i = 0; i < 128; i++) {
+		newport_bfwait();
+		linetable[i] = npregs->set.dcbdata0.byshort.s1;
+	}
+
+	newport_xsize = newport_ysize = 0;
+	for (i = 0; linetable[i + 1] && (i < sizeof(linetable)); i += 2) {
+		cols = 0;
+		newport_vc2_set(npregs, VC2_IREG_RADDR, linetable[i]);
+		npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
+				       NPORT_DMODE_W2 | VC2_PROTOCOL);
+		do {
+			newport_bfwait();
+			treg = npregs->set.dcbdata0.byshort.s1;
+			if ((treg & 1) == 0)
+				cols += (treg >> 7) & 0xfe;
+			if ((treg & 0x80) == 0) {
+				newport_bfwait();
+				treg = npregs->set.dcbdata0.byshort.s1;
+			}
+		} while ((treg & 0x8000) == 0);
+		if (cols) {
+			if (cols > newport_xsize)
+				newport_xsize = cols;
+			newport_ysize += linetable[i + 1];
+		}
+	}
+	printk("NG1: Screensize %dx%d\n", newport_xsize, newport_ysize);
+}
+
+static void newport_get_revisions(void)
+{
+	unsigned int tmp;
+	unsigned int board_rev;
+	unsigned int rex3_rev;
+	unsigned int vc2_rev;
+	unsigned int cmap_rev;
+	unsigned int xmap9_rev;
+	unsigned int bt445_rev;
+	unsigned int bitplanes;
+
+	rex3_rev = npregs->cset.status & NPORT_STAT_VERS;
+
+	npregs->set.dcbmode = (DCB_CMAP0 | NCMAP_PROTOCOL |
+			       NCMAP_REGADDR_RREG | NPORT_DMODE_W1);
+	tmp = npregs->set.dcbdata0.bybytes.b3;
+	cmap_rev = tmp & 7;
+	board_rev = (tmp >> 4) & 7;
+	bitplanes = ((board_rev > 1) && (tmp & 0x80)) ? 8 : 24;
+
+	npregs->set.dcbmode = (DCB_CMAP1 | NCMAP_PROTOCOL |
+			       NCMAP_REGADDR_RREG | NPORT_DMODE_W1);
+	tmp = npregs->set.dcbdata0.bybytes.b3;
+	if ((tmp & 7) < cmap_rev)
+		cmap_rev = (tmp & 7);
+
+	vc2_rev = (newport_vc2_get(npregs, VC2_IREG_CONFIG) >> 5) & 7;
+
+	npregs->set.dcbmode = (DCB_XMAP0 | R_DCB_XMAP9_PROTOCOL |
+			       XM9_CRS_REVISION | NPORT_DMODE_W1);
+	xmap9_rev = npregs->set.dcbdata0.bybytes.b3 & 7;
+
+	npregs->set.dcbmode = (DCB_BT445 | BT445_PROTOCOL |
+			       BT445_CSR_ADDR_REG | NPORT_DMODE_W1);
+	npregs->set.dcbdata0.bybytes.b3 = BT445_REVISION_REG;
+	npregs->set.dcbmode = (DCB_BT445 | BT445_PROTOCOL |
+			       BT445_CSR_REVISION | NPORT_DMODE_W1);
+	bt445_rev = (npregs->set.dcbdata0.bybytes.b3 >> 4) - 0x0a;
+
+#define L(a)     (char)('A'+(a))
+	printk
+	    ("NG1: Revision %d, %d bitplanes, REX3 revision %c, VC2 revision %c, xmap9 revision %c, cmap revision %c, bt445 revision %c\n",
+	     board_rev, bitplanes, L(rex3_rev), L(vc2_rev), L(xmap9_rev),
+	     L(cmap_rev ? (cmap_rev + 1) : 0), L(bt445_rev));
+#undef L
+
+	if (board_rev == 3)	/* I don't know all affected revisions */
+		xcurs_correction = 21;
+}
+
+#ifdef MODULE
+static const char *newport_startup(void)
+#else
+static const char *__init newport_startup(void)
+#endif
+{
+	int i;
+	struct newport_regs *p;
+
+	npregs = (struct newport_regs *) (KSEG1 + 0x1f0f0000);
+
+	p = npregs;
+	p->cset.config = NPORT_CFG_GD0;
+
+	if (newport_wait()) {
+		return NULL;
+	}
+
+	p->set.xstarti = TESTVAL;
+	if (p->set._xstart.word != XSTI_TO_FXSTART(TESTVAL))
+		return NULL;
+
+	for (i = 0; i < MAX_NR_CONSOLES; i++)
+		font_data[i] = FONT_DATA;
+
+	newport_reset();
+	newport_get_revisions();
+	newport_get_screensize();
+
+	/* gfx_init (display_desc); */
+
+	return "SGI Newport";
+}
+
+static void newport_init(struct vc_data *vc, int init)
+{
+	vc->vc_cols = newport_xsize / 8;
+	vc->vc_rows = newport_ysize / 16;
+	vc->vc_can_do_color = 1;
+}
+
+static void newport_clear(struct vc_data *vc, int sy, int sx, int height,
+			  int width)
+{
+	int xend = ((sx + width) << 3) - 1;
+	int ystart = ((sy << 4) + topscan) & 0x3ff;
+	int yend = (((sy + height) << 4) + topscan - 1) & 0x3ff;
+
+	if (logo_active)
+		return;
+
+	if (ystart < yend) {
+		newport_clear_screen(sx << 3, ystart, xend, yend,
+				     (vc->vc_color & 0xf0) >> 4);
+	} else {
+		newport_clear_screen(sx << 3, ystart, xend, 1023,
+				     (vc->vc_color & 0xf0) >> 4);
+		newport_clear_screen(sx << 3, 0, xend, yend,
+				     (vc->vc_color & 0xf0) >> 4);
+	}
+}
+
+static void newport_putc(struct vc_data *vc, int charattr, int ypos,
+			 int xpos)
+{
+	unsigned char *p;
+
+	p = &font_data[vc->vc_num][(charattr & 0xff) << 4];
+	charattr = (charattr >> 8) & 0xff;
+	xpos <<= 3;
+	ypos <<= 4;
+
+	newport_render_background(xpos, ypos, xpos, ypos,
+				  (charattr & 0xf0) >> 4);
+
+	/* Set the color and drawing mode. */
+	newport_wait();
+	npregs->set.colori = charattr & 0xf;
+	npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
+				 NPORT_DMODE0_STOPX | NPORT_DMODE0_ZPENAB |
+				 NPORT_DMODE0_L32);
+
+	/* Set coordinates for bitmap operation. */
+	npregs->set.xystarti = (xpos << 16) | ((ypos + topscan) & 0x3ff);
+	npregs->set.xyendi = ((xpos + 7) << 16);
+	newport_wait();
+
+	/* Go, baby, go... */
+	RENDER(npregs, p);
+}
+
+static void newport_putcs(struct vc_data *vc, const unsigned short *s,
+			  int count, int ypos, int xpos)
+{
+	int i;
+	int charattr;
+	unsigned char *p;
+
+	charattr = (scr_readw(s) >> 8) & 0xff;
+
+	xpos <<= 3;
+	ypos <<= 4;
+
+	if (!logo_active)
+		/* Clear the area behing the string */
+		newport_render_background(xpos, ypos,
+					  xpos + ((count - 1) << 3), ypos,
+					  (charattr & 0xf0) >> 4);
+
+	newport_wait();
+
+	/* Set the color and drawing mode. */
+	npregs->set.colori = charattr & 0xf;
+	npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
+				 NPORT_DMODE0_STOPX | NPORT_DMODE0_ZPENAB |
+				 NPORT_DMODE0_L32);
+
+	for (i = 0; i < count; i++, xpos += 8) {
+		p = &font_data[vc->vc_num][(scr_readw(s++) & 0xff) << 4];
+
+		newport_wait();
+
+		/* Set coordinates for bitmap operation. */
+		npregs->set.xystarti =
+		    (xpos << 16) | ((ypos + topscan) & 0x3ff);
+		npregs->set.xyendi = ((xpos + 7) << 16);
+
+		/* Go, baby, go... */
+		RENDER(npregs, p);
+	}
+}
+
+static void newport_cursor(struct vc_data *vc, int mode)
+{
+	unsigned short treg;
+	int xcurs, ycurs;
+
+	switch (mode) {
+	case CM_ERASE:
+		treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
+		newport_vc2_set(npregs, VC2_IREG_CONTROL,
+				(treg & ~(VC2_CTRL_ECDISP)));
+		break;
+
+	case CM_MOVE:
+	case CM_DRAW:
+		treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
+		newport_vc2_set(npregs, VC2_IREG_CONTROL,
+				(treg | VC2_CTRL_ECDISP));
+		xcurs = (vc->vc_pos - vc->vc_visible_origin) / 2;
+		ycurs = ((xcurs / vc->vc_cols) << 4) + 31;
+		xcurs = ((xcurs % vc->vc_cols) << 3) + xcurs_correction;
+		newport_vc2_set(npregs, VC2_IREG_CURSX, xcurs);
+		newport_vc2_set(npregs, VC2_IREG_CURSY, ycurs);
+	}
+}
+
+static int newport_switch(struct vc_data *vc)
+{
+	static int logo_drawn = 0;
+
+	topscan = 0;
+	npregs->cset.topscan = 0x3ff;
+
+	if (!logo_drawn) {
+		newport_show_logo();
+		logo_drawn = 1;
+		logo_active = 1;
+	}
+
+	return 1;
+}
+
+static int newport_blank(struct vc_data *c, int blank)
+{
+	unsigned short treg;
+
+	if (blank == 0) {
+		/* unblank console */
+		treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
+		newport_vc2_set(npregs, VC2_IREG_CONTROL,
+				(treg | VC2_CTRL_EDISP));
+	} else {
+		/* blank console */
+		treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
+		newport_vc2_set(npregs, VC2_IREG_CONTROL,
+				(treg & ~(VC2_CTRL_EDISP)));
+	}
+	return 1;
+}
+
+static int newport_set_font(int unit, struct console_font_op *op)
+{
+	int w = op->width;
+	int h = op->height;
+	int size = h * op->charcount;
+	int i;
+	unsigned char *new_data, *data = op->data, *p;
+
+	/* ladis: when I grow up, there will be a day... and more sizes will
+	 * be supported ;-) */
+	if ((w != 8) || (h != 16)
+	    || (op->charcount != 256 && op->charcount != 512))
+		return -EINVAL;
+
+	if (!(new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size,
+	     GFP_USER))) return -ENOMEM;
+
+	new_data += FONT_EXTRA_WORDS * sizeof(int);
+	FNTSIZE(new_data) = size;
+	FNTCHARCNT(new_data) = op->charcount;
+	REFCOUNT(new_data) = 0;	/* usage counter */
+
+	p = new_data;
+	for (i = 0; i < op->charcount; i++) {
+		memcpy(p, data, h);
+		data += 32;
+		p += h;
+	}
+
+	/* check if font is already used by other console */
+	for (i = 0; i < MAX_NR_CONSOLES; i++) {
+		if (font_data[i] != FONT_DATA
+		    && FNTSIZE(font_data[i]) == size
+		    && !memcmp(font_data[i], new_data, size)) {
+			kfree(new_data - FONT_EXTRA_WORDS * sizeof(int));
+			/* current font is the same as the new one */
+			if (i == unit)
+				return 0;
+			new_data = font_data[i];
+			break;
+		}
+	}
+	/* old font is user font */
+	if (font_data[unit] != FONT_DATA) {
+		if (--REFCOUNT(font_data[unit]) == 0)
+			kfree(font_data[unit] -
+			      FONT_EXTRA_WORDS * sizeof(int));
+	}
+	REFCOUNT(new_data)++;
+	font_data[unit] = new_data;
+
+	return 0;
+}
+
+static int newport_set_def_font(int unit, struct console_font_op *op)
+{
+	if (font_data[unit] != FONT_DATA) {
+		if (--REFCOUNT(font_data[unit]) == 0)
+			kfree(font_data[unit] -
+			      FONT_EXTRA_WORDS * sizeof(int));
+		font_data[unit] = FONT_DATA;
+	}
+
+	return 0;
+}
+
+static int newport_font_op(struct vc_data *vc, struct console_font_op *op)
+{
+	int unit = vc->vc_num;
+
+	switch (op->op) {
+	case KD_FONT_OP_SET:
+		return newport_set_font(unit, op);
+	case KD_FONT_OP_SET_DEFAULT:
+		return newport_set_def_font(unit, op);
+	default:
+		return -ENOSYS;
+	}
+}
+
+static int newport_set_palette(struct vc_data *vc, unsigned char *table)
+{
+	return -EINVAL;
+}
+
+static int newport_scrolldelta(struct vc_data *vc, int lines)
+{
+	/* there is (nearly) no off-screen memory, so we can't scroll back */
+	return 0;
+}
+
+static int newport_scroll(struct vc_data *vc, int t, int b, int dir,
+			  int lines)
+{
+	int count, x, y;
+	unsigned short *s, *d;
+	unsigned short chattr;
+
+	logo_active = 0;	/* it's time to disable the logo now.. */
+
+	if (t == 0 && b == vc->vc_rows) {
+		if (dir == SM_UP) {
+			topscan = (topscan + (lines << 4)) & 0x3ff;
+			newport_clear_lines(vc->vc_rows - lines,
+					    vc->vc_rows - 1,
+					    (vc->vc_color & 0xf0) >> 4);
+		} else {
+			topscan = (topscan + (-lines << 4)) & 0x3ff;
+			newport_clear_lines(0, lines - 1,
+					    (vc->vc_color & 0xf0) >> 4);
+		}
+		npregs->cset.topscan = (topscan - 1) & 0x3ff;
+		return 0;
+	}
+
+	count = (b - t - lines) * vc->vc_cols;
+	if (dir == SM_UP) {
+		x = 0;
+		y = t;
+		s = (unsigned short *) (vc->vc_origin +
+					vc->vc_size_row * (t + lines));
+		d = (unsigned short *) (vc->vc_origin +
+					vc->vc_size_row * t);
+		while (count--) {
+			chattr = scr_readw(s++);
+			if (chattr != scr_readw(d)) {
+				newport_putc(vc, chattr, y, x);
+				scr_writew(chattr, d);
+			}
+			d++;
+			if (++x == vc->vc_cols) {
+				x = 0;
+				y++;
+			}
+		}
+		d = (unsigned short *) (vc->vc_origin +
+					vc->vc_size_row * (b - lines));
+		x = 0;
+		y = b - lines;
+		for (count = 0; count < (lines * vc->vc_cols); count++) {
+			if (scr_readw(d) != vc->vc_video_erase_char) {
+				newport_putc(vc, vc->vc_video_erase_char,
+					     y, x);
+				scr_writew(vc->vc_video_erase_char, d);
+			}
+			d++;
+			if (++x == vc->vc_cols) {
+				x = 0;
+				y++;
+			}
+		}
+	} else {
+		x = vc->vc_cols - 1;
+		y = b - 1;
+		s = (unsigned short *) (vc->vc_origin +
+					vc->vc_size_row * (b - lines) - 2);
+		d = (unsigned short *) (vc->vc_origin +
+					vc->vc_size_row * b - 2);
+		while (count--) {
+			chattr = scr_readw(s--);
+			if (chattr != scr_readw(d)) {
+				newport_putc(vc, chattr, y, x);
+				scr_writew(chattr, d);
+			}
+			d--;
+			if (x-- == 0) {
+				x = vc->vc_cols - 1;
+				y--;
+			}
+		}
+		d = (unsigned short *) (vc->vc_origin +
+					vc->vc_size_row * t);
+		x = 0;
+		y = t;
+		for (count = 0; count < (lines * vc->vc_cols); count++) {
+			if (scr_readw(d) != vc->vc_video_erase_char) {
+				newport_putc(vc, vc->vc_video_erase_char,
+					     y, x);
+				scr_writew(vc->vc_video_erase_char, d);
+			}
+			d++;
+			if (++x == vc->vc_cols) {
+				x = 0;
+				y++;
+			}
+		}
+	}
+	return 1;
+}
+
+static void newport_bmove(struct vc_data *vc, int sy, int sx, int dy,
+			  int dx, int h, int w)
+{
+	short xs, ys, xe, ye, xoffs, yoffs, tmp;
+
+	xs = sx << 3;
+	xe = ((sx + w) << 3) - 1;
+	/*
+	 * as bmove is only used to move stuff around in the same line
+	 * (h == 1), we don't care about wrap arounds caused by topscan != 0
+	 */
+	ys = ((sy << 4) + topscan) & 0x3ff;
+	ye = (((sy + h) << 4) - 1 + topscan) & 0x3ff;
+	xoffs = (dx - sx) << 3;
+	yoffs = (dy - sy) << 4;
+	if (xoffs > 0) {
+		/* move to the right, exchange starting points */
+		tmp = xe;
+		xe = xs;
+		xs = tmp;
+	}
+	newport_wait();
+	npregs->set.drawmode0 = (NPORT_DMODE0_S2S | NPORT_DMODE0_BLOCK |
+				 NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
+				 | NPORT_DMODE0_STOPY);
+	npregs->set.xystarti = (xs << 16) | ys;
+	npregs->set.xyendi = (xe << 16) | ye;
+	npregs->go.xymove = (xoffs << 16) | yoffs;
+}
+
+static int newport_dummy(struct vc_data *c)
+{
+	return 0;
+}
+
+#define DUMMY (void *) newport_dummy
+
+const struct consw newport_con = {
+    .con_startup =	newport_startup,
+    .con_init =		newport_init,
+    .con_deinit =	DUMMY,
+    .con_clear =	newport_clear,
+    .con_putc =		newport_putc,
+    .con_putcs =	newport_putcs,
+    .con_cursor =	newport_cursor,
+    .con_scroll =	newport_scroll,
+    .con_bmove =	newport_bmove,
+    .con_switch =	newport_switch,
+    .con_blank =	newport_blank,
+    .con_font_op =	newport_font_op,
+    .con_set_palette =	newport_set_palette,
+    .con_scrolldelta =	newport_scrolldelta,
+    .con_set_origin =	DUMMY,
+    .con_save_screen =	DUMMY
+};
+
+#ifdef MODULE
+MODULE_LICENSE("GPL");
+
+int init_module(void)
+{
+	if (!newport_startup())
+		printk("Error loading SGI Newport Console driver\n");
+	else
+		printk("Loading SGI Newport Console Driver\n");
+	take_over_console(&newport_con, 0, MAX_NR_CONSOLES - 1, 1);
+
+	return 0;
+}
+
+int cleanup_module(void)
+{
+	int i;
+
+	printk("Unloading SGI Newport Console Driver\n");
+	/* free memory used by user font */
+	for (i = 0; i < MAX_NR_CONSOLES; i++)
+		newport_set_def_font(i, NULL);
+
+	return 0;
+}
+#endif
diff -Nru a/drivers/video/console/prom.uni b/drivers/video/console/prom.uni
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/prom.uni	Mon Dec  9 18:46:49 2002
@@ -0,0 +1,11 @@
+#
+# Unicode mapping table for font in Sun PROM
+# 
+#
+0x20-0x7e	idem
+0xa0-0xff	idem
+#
+0x7c		U+2502
+0x2d		U+2500
+0x2b		U+250c U+2510 U+2514 U+2518 U+251c U+2524 U+252c U+2534 U+253c
+0xa4		U+fffd
diff -Nru a/drivers/video/console/promcon.c b/drivers/video/console/promcon.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/promcon.c	Mon Dec  9 18:46:38 2002
@@ -0,0 +1,605 @@
+/* $Id: promcon.c,v 1.17 2000/07/26 23:02:52 davem Exp $
+ * Console driver utilizing PROM sun terminal emulation
+ *
+ * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
+ * Copyright (C) 1998  Jakub Jelinek  (jj@ultra.linux.cz)
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/console.h>
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/kd.h>
+
+#include <asm/oplib.h>
+#include <asm/uaccess.h>
+
+static short pw = 80 - 1, ph = 34 - 1;
+static short px, py;
+static unsigned long promcon_uni_pagedir[2];
+
+extern u8 promfont_unicount[];
+extern u16 promfont_unitable[];
+
+#define PROMCON_COLOR 0
+
+#if PROMCON_COLOR
+#define inverted(s)	((((s) & 0x7700) == 0x0700) ? 0 : 1)
+#else
+#define inverted(s)	(((s) & 0x0800) ? 1 : 0)
+#endif
+
+static __inline__ void
+promcon_puts(char *buf, int cnt)
+{
+	prom_printf("%*.*s", cnt, cnt, buf);
+}
+
+static int
+promcon_start(struct vc_data *conp, char *b)
+{
+	unsigned short *s = (unsigned short *)
+			(conp->vc_origin + py * conp->vc_size_row + (px << 1));
+	u16 cs;
+
+	cs = scr_readw(s);
+	if (px == pw) {
+		unsigned short *t = s - 1;
+		u16 ct = scr_readw(t);
+
+		if (inverted(cs) && inverted(ct))
+			return sprintf(b, "\b\033[7m%c\b\033[@%c\033[m", cs,
+				       ct);
+		else if (inverted(cs))
+			return sprintf(b, "\b\033[7m%c\033[m\b\033[@%c", cs,
+				       ct);
+		else if (inverted(ct))
+			return sprintf(b, "\b%c\b\033[@\033[7m%c\033[m", cs,
+				       ct);
+		else
+			return sprintf(b, "\b%c\b\033[@%c", cs, ct);
+	}
+
+	if (inverted(cs))
+		return sprintf(b, "\033[7m%c\033[m\b", cs);
+	else
+		return sprintf(b, "%c\b", cs);
+}
+
+static int
+promcon_end(struct vc_data *conp, char *b)
+{
+	unsigned short *s = (unsigned short *)
+			(conp->vc_origin + py * conp->vc_size_row + (px << 1));
+	char *p = b;
+	u16 cs;
+
+	b += sprintf(b, "\033[%d;%dH", py + 1, px + 1);
+
+	cs = scr_readw(s);
+	if (px == pw) {
+		unsigned short *t = s - 1;
+		u16 ct = scr_readw(t);
+
+		if (inverted(cs) && inverted(ct))
+			b += sprintf(b, "\b%c\b\033[@\033[7m%c\033[m", cs, ct);
+		else if (inverted(cs))
+			b += sprintf(b, "\b%c\b\033[@%c", cs, ct);
+		else if (inverted(ct))
+			b += sprintf(b, "\b\033[7m%c\b\033[@%c\033[m", cs, ct);
+		else
+			b += sprintf(b, "\b\033[7m%c\033[m\b\033[@%c", cs, ct);
+		return b - p;
+	}
+
+	if (inverted(cs))
+		b += sprintf(b, "%c\b", cs);
+	else
+		b += sprintf(b, "\033[7m%c\033[m\b", cs);
+	return b - p;
+}
+
+const char __init *promcon_startup(void)
+{
+	const char *display_desc = "PROM";
+	int node;
+	char buf[40];
+	
+	node = prom_getchild(prom_root_node);
+	node = prom_searchsiblings(node, "options");
+	if (prom_getproperty(node,  "screen-#columns", buf, 40) != -1) {
+		pw = simple_strtoul(buf, NULL, 0);
+		if (pw < 10 || pw > 256)
+			pw = 80;
+		pw--;
+	}
+	if (prom_getproperty(node,  "screen-#rows", buf, 40) != -1) {
+		ph = simple_strtoul(buf, NULL, 0);
+		if (ph < 10 || ph > 256)
+			ph = 34;
+		ph--;
+	}
+	promcon_puts("\033[H\033[J", 6);
+	return display_desc;
+}
+
+static void __init 
+promcon_init_unimap(struct vc_data *conp)
+{
+	mm_segment_t old_fs = get_fs();
+	struct unipair *p, *p1;
+	u16 *q;
+	int i, j, k;
+	
+	p = kmalloc(256*sizeof(struct unipair), GFP_KERNEL);
+	if (!p) return;
+	
+	q = promfont_unitable;
+	p1 = p;
+	k = 0;
+	for (i = 0; i < 256; i++)
+		for (j = promfont_unicount[i]; j; j--) {
+			p1->unicode = *q++;
+			p1->fontpos = i;
+			p1++;
+			k++;
+		}
+	set_fs(KERNEL_DS);
+	con_clear_unimap(conp->vc_num, NULL);
+	con_set_unimap(conp->vc_num, k, p);
+	con_protect_unimap(conp->vc_num, 1);
+	set_fs(old_fs);
+	kfree(p);
+}
+
+static void
+promcon_init(struct vc_data *conp, int init)
+{
+	unsigned long p;
+	
+	conp->vc_can_do_color = PROMCON_COLOR;
+	if (init) {
+		conp->vc_cols = pw + 1;
+		conp->vc_rows = ph + 1;
+	}
+	p = *conp->vc_uni_pagedir_loc;
+	if (conp->vc_uni_pagedir_loc == &conp->vc_uni_pagedir ||
+	    !--conp->vc_uni_pagedir_loc[1])
+		con_free_unimap(conp->vc_num);
+	conp->vc_uni_pagedir_loc = promcon_uni_pagedir;
+	promcon_uni_pagedir[1]++;
+	if (!promcon_uni_pagedir[0] && p) {
+		promcon_init_unimap(conp);
+	}
+	if (!init) {
+		if (conp->vc_cols != pw + 1 || conp->vc_rows != ph + 1)
+			vc_resize(conp->unit, pw + 1, ph + 1);
+	}
+}
+
+static void
+promcon_deinit(struct vc_data *conp)
+{
+	/* When closing the last console, reset video origin */
+	if (!--promcon_uni_pagedir[1])
+		con_free_unimap(conp->vc_num);
+	conp->vc_uni_pagedir_loc = &conp->vc_uni_pagedir;
+	con_set_default_unimap(conp->vc_num);
+}
+
+static int
+promcon_switch(struct vc_data *conp)
+{
+	return 1;
+}
+
+static unsigned short *
+promcon_repaint_line(unsigned short *s, unsigned char *buf, unsigned char **bp)
+{
+	int cnt = pw + 1;
+	int attr = -1;
+	unsigned char *b = *bp;
+
+	while (cnt--) {
+		u16 c = scr_readw(s);
+		if (attr != inverted(c)) {
+			attr = inverted(c);
+			if (attr) {
+				strcpy (b, "\033[7m");
+				b += 4;
+			} else {
+				strcpy (b, "\033[m");
+				b += 3;
+			}
+		}
+		*b++ = c;
+		s++;
+		if (b - buf >= 224) {
+			promcon_puts(buf, b - buf);
+			b = buf;
+		}
+	}
+	*bp = b;
+	return s;
+}
+
+static void
+promcon_putcs(struct vc_data *conp, const unsigned short *s,
+	      int count, int y, int x)
+{
+	unsigned char buf[256], *b = buf;
+	unsigned short attr = scr_readw(s);
+	unsigned char save;
+	int i, last = 0;
+
+	if (console_blanked)
+		return;
+	
+	if (count <= 0)
+		return;
+
+	b += promcon_start(conp, b);
+
+	if (x + count >= pw + 1) {
+		if (count == 1) {
+			x -= 1;
+			save = scr_readw((unsigned short *)(conp->vc_origin
+						   + y * conp->vc_size_row
+						   + (x << 1)));
+
+			if (px != x || py != y) {
+				b += sprintf(b, "\033[%d;%dH", y + 1, x + 1);
+				px = x;
+				py = y;
+			}
+
+			if (inverted(attr))
+				b += sprintf(b, "\033[7m%c\033[m", scr_readw(s++));
+			else
+				b += sprintf(b, "%c", scr_readw(s++));
+
+			strcpy(b, "\b\033[@");
+			b += 4;
+
+			if (inverted(save))
+				b += sprintf(b, "\033[7m%c\033[m", save);
+			else
+				b += sprintf(b, "%c", save);
+
+			px++;
+
+			b += promcon_end(conp, b);
+			promcon_puts(buf, b - buf);
+			return;
+		} else {
+			last = 1;
+			count = pw - x - 1;
+		}
+	}
+
+	if (inverted(attr)) {
+		strcpy(b, "\033[7m");
+		b += 4;
+	}
+
+	if (px != x || py != y) {
+		b += sprintf(b, "\033[%d;%dH", y + 1, x + 1);
+		px = x;
+		py = y;
+	}
+
+	for (i = 0; i < count; i++) {
+		if (b - buf >= 224) {
+			promcon_puts(buf, b - buf);
+			b = buf;
+		}
+		*b++ = scr_readw(s++);
+	}
+
+	px += count;
+
+	if (last) {
+		save = scr_readw(s++);
+		b += sprintf(b, "%c\b\033[@%c", scr_readw(s++), save);
+		px++;
+	}
+
+	if (inverted(attr)) {
+		strcpy(b, "\033[m");
+		b += 3;
+	}
+
+	b += promcon_end(conp, b);
+	promcon_puts(buf, b - buf);
+}
+
+static void
+promcon_putc(struct vc_data *conp, int c, int y, int x)
+{
+	unsigned short s;
+
+	if (console_blanked)
+		return;
+	
+	scr_writew(c, &s);
+	promcon_putcs(conp, &s, 1, y, x);
+}
+
+static void
+promcon_clear(struct vc_data *conp, int sy, int sx, int height, int width)
+{
+	unsigned char buf[256], *b = buf;
+	int i, j;
+
+	if (console_blanked)
+		return;
+	
+	b += promcon_start(conp, b);
+
+	if (!sx && width == pw + 1) {
+
+		if (!sy && height == ph + 1) {
+			strcpy(b, "\033[H\033[J");
+			b += 6;
+			b += promcon_end(conp, b);
+			promcon_puts(buf, b - buf);
+			return;
+		} else if (sy + height == ph + 1) {
+			b += sprintf(b, "\033[%dH\033[J", sy + 1);
+			b += promcon_end(conp, b);
+			promcon_puts(buf, b - buf);
+			return;
+		}
+
+		b += sprintf(b, "\033[%dH", sy + 1);
+		for (i = 1; i < height; i++) {
+			strcpy(b, "\033[K\n");
+			b += 4;
+		}
+
+		strcpy(b, "\033[K");
+		b += 3;
+
+		b += promcon_end(conp, b);
+		promcon_puts(buf, b - buf);
+		return;
+
+	} else if (sx + width == pw + 1) {
+
+		b += sprintf(b, "\033[%d;%dH", sy + 1, sx + 1);
+		for (i = 1; i < height; i++) {
+			strcpy(b, "\033[K\n");
+			b += 4;
+		}
+
+		strcpy(b, "\033[K");
+		b += 3;
+
+		b += promcon_end(conp, b);
+		promcon_puts(buf, b - buf);
+		return;
+	}
+
+	for (i = sy + 1; i <= sy + height; i++) {
+		b += sprintf(b, "\033[%d;%dH", i, sx + 1);
+		for (j = 0; j < width; j++)
+			*b++ = ' ';
+		if (b - buf + width >= 224) {
+			promcon_puts(buf, b - buf);
+			b = buf;
+		}
+	}
+
+	b += promcon_end(conp, b);
+	promcon_puts(buf, b - buf);
+}
+                        
+static void
+promcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
+	      int height, int width)
+{
+	char buf[256], *b = buf;
+
+	if (console_blanked)
+		return;
+	
+	b += promcon_start(conp, b);
+	if (sy == dy && height == 1) {
+		if (dx > sx && dx + width == conp->vc_cols)
+			b += sprintf(b, "\033[%d;%dH\033[%d@\033[%d;%dH",
+				     sy + 1, sx + 1, dx - sx, py + 1, px + 1);
+		else if (dx < sx && sx + width == conp->vc_cols)
+			b += sprintf(b, "\033[%d;%dH\033[%dP\033[%d;%dH",
+				     dy + 1, dx + 1, sx - dx, py + 1, px + 1);
+
+		b += promcon_end(conp, b);
+		promcon_puts(buf, b - buf);
+		return;
+	}
+
+	/*
+	 * FIXME: What to do here???
+	 * Current console.c should not call it like that ever.
+	 */
+	prom_printf("\033[7mFIXME: bmove not handled\033[m\n");
+}
+
+static void
+promcon_cursor(struct vc_data *conp, int mode)
+{
+	char buf[32], *b = buf;
+
+	switch (mode) {
+	case CM_ERASE:
+		break;
+
+	case CM_MOVE:
+	case CM_DRAW:
+		b += promcon_start(conp, b);
+		if (px != conp->vc_x || py != conp->vc_y) {
+			px = conp->vc_x;
+			py = conp->vc_y;
+			b += sprintf(b, "\033[%d;%dH", py + 1, px + 1);
+		}
+		promcon_puts(buf, b - buf);
+		break;
+	}
+}
+
+static int
+promcon_font_op(struct vc_data *conp, struct console_font_op *op)
+{
+	return -ENOSYS;
+}
+        
+static int
+promcon_blank(struct vc_data *conp, int blank)
+{
+	if (blank) {
+		promcon_puts("\033[H\033[J\033[7m \033[m\b", 15);
+		return 0;
+	} else {
+		/* Let console.c redraw */
+		return 1;
+	}
+}
+
+static int
+promcon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
+{
+	unsigned char buf[256], *p = buf;
+	unsigned short *s;
+	int i;
+
+	if (console_blanked)
+		return 0;
+	
+	p += promcon_start(conp, p);
+
+	switch (dir) {
+	case SM_UP:
+		if (b == ph + 1) {
+			p += sprintf(p, "\033[%dH\033[%dM", t + 1, count);
+			px = 0;
+			py = t;
+			p += promcon_end(conp, p);
+			promcon_puts(buf, p - buf);
+			break;
+		}
+
+		s = (unsigned short *)(conp->vc_origin
+				       + (t + count) * conp->vc_size_row);
+
+		p += sprintf(p, "\033[%dH", t + 1);
+
+		for (i = t; i < b - count; i++)
+			s = promcon_repaint_line(s, buf, &p);
+
+		for (; i < b - 1; i++) {
+			strcpy(p, "\033[K\n");
+			p += 4;
+			if (p - buf >= 224) {
+				promcon_puts(buf, p - buf);
+				p = buf;
+			}
+		}
+
+		strcpy(p, "\033[K");
+		p += 3;
+
+		p += promcon_end(conp, p);
+		promcon_puts(buf, p - buf);
+		break;
+
+	case SM_DOWN:
+		if (b == ph + 1) {
+			p += sprintf(p, "\033[%dH\033[%dL", t + 1, count);
+			px = 0;
+			py = t;
+			p += promcon_end(conp, p);
+			promcon_puts(buf, p - buf);
+			break;
+		}
+
+		s = (unsigned short *)(conp->vc_origin + t * conp->vc_size_row);
+
+		p += sprintf(p, "\033[%dH", t + 1);
+
+		for (i = t; i < t + count; i++) {
+			strcpy(p, "\033[K\n");
+			p += 4;
+			if (p - buf >= 224) {
+				promcon_puts(buf, p - buf);
+				p = buf;
+			}
+		}
+
+		for (; i < b; i++)
+			s = promcon_repaint_line(s, buf, &p);
+
+		p += promcon_end(conp, p);
+		promcon_puts(buf, p - buf);
+		break;
+	}
+
+	return 0;
+}
+
+#if !(PROMCON_COLOR)
+static u8 promcon_build_attr(struct vc_data *conp, u8 _color, u8 _intensity, u8 _blink, u8 _underline, u8 _reverse)
+{
+	return (_reverse) ? 0xf : 0x7;
+}
+#endif
+
+/*
+ *  The console 'switch' structure for the VGA based console
+ */
+
+static int promcon_dummy(void)
+{
+        return 0;
+}
+
+#define DUMMY (void *) promcon_dummy
+
+const struct consw prom_con = {
+	.con_startup =		promcon_startup,
+	.con_init =		promcon_init,
+	.con_deinit =		promcon_deinit,
+	.con_clear =		promcon_clear,
+	.con_putc =		promcon_putc,
+	.con_putcs =		promcon_putcs,
+	.con_cursor =		promcon_cursor,
+	.con_scroll =		promcon_scroll,
+	.con_bmove =		promcon_bmove,
+	.con_switch =		promcon_switch,
+	.con_blank =		promcon_blank,
+	.con_font_op =		promcon_font_op,
+	.con_set_palette =	DUMMY,
+	.con_scrolldelta =	DUMMY,
+#if !(PROMCON_COLOR)
+	.con_build_attr =	promcon_build_attr,
+#endif
+};
+
+void __init prom_con_init(void)
+{
+#ifdef CONFIG_DUMMY_CONSOLE
+	if (conswitchp == &dummy_con)
+		take_over_console(&prom_con, 0, MAX_NR_CONSOLES-1, 1);
+	else
+#endif
+	if (conswitchp == &prom_con)
+		promcon_init_unimap(vc_cons[fg_console].d);
+}
diff -Nru a/drivers/video/console/sti.h b/drivers/video/console/sti.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/sti.h	Mon Dec  9 18:46:50 2002
@@ -0,0 +1,289 @@
+#define STI_REGION_MAX 8
+#define STI_DEV_NAME_LENGTH 32
+
+struct sti_rom_font {
+	u16 first_char;
+	u16 last_char;
+	 u8 width;
+	 u8 height;
+	 u8 font_type;
+	 u8 bytes_per_char;
+	u32 next_font;
+	 u8 underline_height;
+	 u8 underline_pos;
+	 u8 res008[2];
+};
+
+struct sti_rom {
+	 u8 type[4];
+	 u8 res004;
+	 u8 num_mons;
+	 u8 revno[2];
+	 u8 graphics_id[8];
+
+	u32 font_start;
+	u32 statesize;
+	u32 last_addr;
+	u32 region_list;
+
+	u16 reentsize;
+	u16 maxtime;
+	u32 mon_tbl_addr;
+	u32 user_data_addr;
+	u32 sti_mem_req;
+
+	u32 user_data_size;
+	u16 power;
+	 u8 bus_support;
+	 u8 ext_bus_support;
+	 u8 alt_code_type;
+	 u8 ext_dd_struct[3];
+	u32 cfb_addr;
+	
+	u32 init_graph;
+	u32 state_mgmt;
+	u32 font_unpmv;
+	u32 block_move;
+	u32 self_test;
+	u32 excep_hdlr;
+	u32 inq_conf;
+	u32 set_cm_entry;
+	u32 dma_ctrl;
+	 u8 res040[7 * 4];
+	
+	u32 init_graph_m68k;
+	u32 flow_ctrl;
+	u32 user_timing;
+	u32 process_mgr;
+	u32 sti_util;
+	u32 end_addr;
+	u32 res0b8;
+	u32 res0bc;
+};
+	
+struct sti_cooked_font {
+	struct sti_rom_font *raw;
+	struct sti_cooked_font *next_font;
+};
+
+struct sti_cooked_rom {
+	struct sti_rom *raw;
+	struct sti_cooked_font *font_start;
+	u32 *region_list;
+};
+
+struct sti_glob_cfg_ext {
+	u8  curr_mon;
+	u8  friendly_boot;
+	s16 power;
+	s32 freq_ref;
+	s32 *sti_mem_addr;
+	s32 *future_ptr;
+};
+
+struct sti_glob_cfg {
+	s32 text_planes;
+	s16 onscreen_x;
+	s16 onscreen_y;
+	s16 offscreen_x;
+	s16 offscreen_y;
+	s16 total_x;
+	s16 total_y;
+	u32 region_ptrs[STI_REGION_MAX];
+	s32 reent_lvl;
+	s32 *save_addr;
+	struct sti_glob_cfg_ext *ext_ptr;
+};
+
+struct sti_init_flags {
+	u32 wait : 1;
+	u32 reset : 1;
+	u32 text : 1;
+	u32 nontext : 1;
+	u32 clear : 1;
+	u32 cmap_blk : 1;
+	u32 enable_be_timer : 1;
+	u32 enable_be_int : 1;
+	u32 no_chg_tx : 1;
+	u32 no_chg_ntx : 1;
+	u32 no_chg_bet : 1;
+	u32 no_chg_bei : 1;
+	u32 init_cmap_tx : 1;
+	u32 cmt_chg : 1;
+	u32 retain_ie : 1;
+	u32 pad : 17;
+
+	s32 *future_ptr;
+};
+
+struct sti_init_inptr_ext {
+	u8  config_mon_type;
+	u8  pad[1];
+	u16 inflight_data;
+	s32 *future_ptr;
+};
+
+struct sti_init_inptr {
+	s32 text_planes;
+	struct sti_init_inptr_ext *ext_ptr;
+};
+
+struct sti_init_outptr {
+	s32 errno;
+	s32 text_planes;
+	s32 *future_ptr;
+};
+
+struct sti_conf_flags {
+	u32 wait : 1;
+	u32 pad : 31;
+	s32 *future_ptr;
+};
+
+struct sti_conf_inptr {
+	s32 *future_ptr;
+};
+
+struct sti_conf_outptr_ext {
+	u32 crt_config[3];
+	u32 crt_hdw[3];
+	s32 *future_ptr;
+};
+
+struct sti_conf_outptr {
+	s32 errno;
+	s16 onscreen_x;
+	s16 onscreen_y;
+	s16 offscreen_x;
+	s16 offscreen_y;
+	s16 total_x;
+	s16 total_y;
+	s32 bits_per_pixel;
+	s32 bits_used;
+	s32 planes;
+	 u8 dev_name[STI_DEV_NAME_LENGTH];
+	u32 attributes;
+	struct sti_conf_outptr_ext *ext_ptr;
+};
+
+
+struct sti_font_inptr {
+	u32 font_start_addr;
+	s16 index;
+	u8 fg_color;
+	u8 bg_color;
+	s16 dest_x;
+	s16 dest_y;
+	s32 *future_ptr;
+};
+
+struct sti_font_flags {
+	u32 wait : 1;
+	u32 non_text : 1;
+	u32 pad : 30;
+
+	s32 *future_ptr;
+};
+	
+struct sti_font_outptr {
+	s32 errno;
+	s32 *future_ptr;
+};
+
+struct sti_blkmv_flags {
+	u32 wait : 1;
+	u32 color : 1;
+	u32 clear : 1;
+	u32 non_text : 1;
+	u32 pad : 28;
+	s32 *future_ptr;
+};
+
+struct sti_blkmv_inptr {
+	u8 fg_color;
+	u8 bg_color;
+	s16 src_x;
+	s16 src_y;
+	s16 dest_x;
+	s16 dest_y;
+	s16 width;
+	s16 height;
+	s32 *future_ptr;
+};
+
+struct sti_blkmv_outptr {
+	s32 errno;
+	s32 *future_ptr;
+};
+
+struct sti_struct {
+	spinlock_t lock;
+
+	struct sti_cooked_rom *rom;
+
+	unsigned long font_unpmv;
+	unsigned long block_move;
+	unsigned long init_graph;
+	unsigned long inq_conf;
+
+	struct sti_glob_cfg *glob_cfg;
+	struct sti_rom_font *font;
+
+	s32 text_planes;
+
+	char **mon_strings;
+	u32 *regions;
+	 u8 *pci_regions;
+};
+
+#define STI_CALL(func, flags, inptr, outptr, glob_cfg) \
+	({							\
+		real32_call( func, (unsigned long)STI_PTR(flags), \
+				    STI_PTR(inptr), STI_PTR(outptr), \
+				    glob_cfg); \
+	})
+
+/* The latency of the STI functions cannot really be reduced by setting
+ * this to 0;  STI doesn't seem to be designed to allow calling a different
+ * function (or the same function with different arguments) after a
+ * function exited with 1 as return value.
+ *
+ * As all of the functions below could be called from interrupt context,
+ * we have to spin_lock_irqsave around the do { ret = bla(); } while(ret==1)
+ * block.  Really bad latency there.
+ *
+ * Probably the best solution to all this is have the generic code manage
+ * the screen buffer and a kernel thread to call STI occasionally.
+ * 
+ * Luckily, the frame buffer guys have the same problem so we can just wait
+ * for them to fix it and steal their solution.   prumpf
+ *
+ * Actually, another long-term viable solution is to completely do STI
+ * support in userspace - that way we avoid the potential license issues
+ * of using proprietary fonts, too. */
+ 
+#define STI_WAIT 1
+#define STI_PTR(p) ( (typeof(p)) virt_to_phys(p))
+#define PTR_STI(p) ( (typeof(p)) phys_to_virt((unsigned long)p) )
+
+#define sti_onscreen_x(sti) (PTR_STI(sti->glob_cfg)->onscreen_x)
+#define sti_onscreen_y(sti) (PTR_STI(sti->glob_cfg)->onscreen_y)
+#define sti_font_x(sti) (PTR_STI(sti->font)->width)
+#define sti_font_y(sti) (PTR_STI(sti->font)->height)
+
+extern struct sti_struct * sti_init_roms(void);
+
+void sti_init_graph(struct sti_struct *sti);
+void sti_inq_conf(struct sti_struct *sti);
+void sti_putc(struct sti_struct *sti, int c, int y, int x);
+void sti_set(struct sti_struct *sti, int src_y, int src_x,
+	     int height, int width, u8 color);
+void sti_clear(struct sti_struct *sti, int src_y, int src_x,
+	       int height, int width);
+void sti_bmove(struct sti_struct *sti, int src_y, int src_x,
+	       int dst_y, int dst_x, int height, int width);
+
+/* XXX: this probably should not be here, but we rely on STI being
+   initialized early and independently of stifb at the moment, so
+   there's no other way for stifb to find it. */
+extern struct sti_struct default_sti;
diff -Nru a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/sticon.c	Mon Dec  9 18:46:50 2002
@@ -0,0 +1,214 @@
+/*
+ *  linux/drivers/video/sticon.c  - console driver using HP's STI firmware
+ *
+ *	Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
+ *
+ *  Based on linux/drivers/video/vgacon.c and linux/drivers/video/fbcon.c,
+ *  which were
+ *
+ *	Created 28 Sep 1997 by Geert Uytterhoeven
+ *	Rewritten by Martin Mares <mj@ucw.cz>, July 1998
+ *	Copyright (C) 1991, 1992  Linus Torvalds
+ *			    1995  Jay Estabrook
+ *	Copyright (C) 1995 Geert Uytterhoeven
+ *	Copyright (C) 1993 Bjoern Brauel
+ *			   Roman Hodek
+ *	Copyright (C) 1993 Hamish Macdonald
+ *			   Greg Harp
+ *	Copyright (C) 1994 David Carter [carter@compsci.bristol.ac.uk]
+ *
+ *	      with work by William Rucklidge (wjr@cs.cornell.edu)
+ *			   Geert Uytterhoeven
+ *			   Jes Sorensen (jds@kom.auc.dk)
+ *			   Martin Apel
+ *	      with work by Guenther Kelleter
+ *			   Martin Schaller
+ *			   Andreas Schwab
+ *			   Emmanuel Marty (core@ggi-project.org)
+ *			   Jakub Jelinek (jj@ultra.linux.cz)
+ *			   Martin Mares <mj@ucw.cz>
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+/*
+ *  TODO:
+ *   - call STI in virtual mode rather than in real mode
+ *   - support for PCI-only STI ROMs (which don't have a traditional region
+ *     list)
+ *   - safe detection (i.e. verify there is a graphics device at a given
+ *     address first, not just read a random device's io space)
+ *   - support for multiple STI devices in one machine
+ *   - support for byte-mode STI ROMs
+ *   - support for just using STI to switch to a colour fb (stifb ?)
+ *   - try to make it work on m68k hp workstations ;)
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/errno.h>
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+
+#include <asm/io.h>
+
+#include "sti.h"
+
+/* STICON */
+
+static const char * __init
+sticon_startup(void)
+{
+	return "STI console";
+}
+
+static int
+sticon_set_palette(struct vc_data *c, unsigned char *table)
+{
+	return -EINVAL;
+}
+static int
+sticon_font_op(struct vc_data *c, struct console_font_op *op)
+{
+	return -ENOSYS;
+}
+
+static void sticon_putc(struct vc_data *conp, int c, int ypos, int xpos)
+{
+	sti_putc(&default_sti, c, ypos, xpos);
+}
+
+static void sticon_putcs(struct vc_data *conp, const unsigned short *s,
+	int count, int ypos, int xpos)
+{
+	while(count--) {
+		sti_putc(&default_sti, scr_readw(s++), ypos, xpos++);
+	}
+}
+
+static void sticon_cursor(struct vc_data *conp, int mode)
+{
+}
+
+static int sticon_scroll(struct vc_data *conp, int t, int b, int dir,
+			int count)
+{
+	struct sti_struct *sti = &default_sti;
+
+	if(console_blanked)
+		return 0;
+
+	sticon_cursor(conp, CM_ERASE);
+
+	switch(dir) {
+	case SM_UP:
+		sti_bmove(sti, t+count, 0, t, 0, b-t-count, conp->vc_cols);
+		sti_clear(sti, b-count, 0, count, conp->vc_cols);
+
+		break;
+
+	case SM_DOWN:
+		sti_bmove(sti, t, 0, t+count, 0, b-t-count, conp->vc_cols);
+		sti_clear(sti, t, 0, count, conp->vc_cols);
+
+		break;
+	}
+
+	return 0;
+}
+	
+static void sticon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
+			 int height, int width)
+{
+	sti_bmove(&default_sti, sy, sx, dy, dx, height, width);
+}
+
+static void sticon_init(struct vc_data *c, int init)
+{
+	struct sti_struct *sti = &default_sti;
+	int vc_cols, vc_rows;
+
+	sti_set(sti, 0, 0, sti_onscreen_y(sti), sti_onscreen_x(sti), 0);
+	c->vc_can_do_color = 1;
+	vc_cols = PTR_STI(sti->glob_cfg)->onscreen_x / sti_font_x(sti);
+	vc_rows = PTR_STI(sti->glob_cfg)->onscreen_y / sti_font_y(sti);
+
+	vc_resize(c->vc_num, vc_cols, vc_rows);
+}
+
+static void sticon_deinit(struct vc_data *c)
+{
+}
+
+static void sticon_clear(struct vc_data *conp, int sy, int sx, int height,
+			int width)
+{
+	sti_clear(&default_sti, sy, sx, height, width);
+}
+
+static int sticon_switch(struct vc_data *conp)
+{
+	return 0;
+}
+
+static int sticon_blank(struct vc_data *conp, int blank)
+{
+	return 0;
+}
+
+static int sticon_scrolldelta(struct vc_data *conp, int lines)
+{
+	return 0;
+}
+
+static int sticon_set_origin(struct vc_data *conp)
+{
+	return 0;
+}
+
+static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens, u8 blink, u8 underline, u8 reverse)
+{
+	u8 attr = ((color & 0x70) >> 1) | ((color & 7));
+
+	if(reverse) {
+		color = ((color>>3)&0x7) | ((color &0x7)<<3);
+	}
+
+
+	return attr;
+}
+
+struct consw sti_con = {
+	.con_startup = 		sticon_startup, 
+	.con_init = 		sticon_init,
+	.con_deinit = 		sticon_deinit,
+	.con_clear = 		sticon_clear,
+	.con_putc = 		sticon_putc,
+	.con_putcs = 		sticon_putcs,
+	.con_cursor = 		sticon_cursor,
+	.con_scroll = 		sticon_scroll,
+	.con_bmove = 		sticon_bmove,
+	.con_switch = 		sticon_switch,
+	.con_blank = 		sticon_blank,
+	.con_font_op =		sticon_font_op,
+	.con_set_palette =	sticon_set_palette,
+	.con_scrolldelta =	sticon_scrolldelta,
+	.con_set_origin = 	sticon_set_origin,
+	.con_build_attr =	sticon_build_attr,
+};
+
+static int __init sti_init(void)
+{
+	printk("searching for word mode STI ROMs\n");
+	if (sti_init_roms()) {
+		pdc_console_die();
+		take_over_console(&sti_con, 0, MAX_NR_CONSOLES-1, 1);
+		return 0;
+	} else
+		return -ENODEV;
+}
+
+module_init(sti_init)
diff -Nru a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/sticore.c	Mon Dec  9 18:46:35 2002
@@ -0,0 +1,601 @@
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
+#include <asm/io.h>
+
+#include "sti.h"
+
+struct sti_struct default_sti = {
+	SPIN_LOCK_UNLOCKED,
+};
+
+static struct sti_font_flags default_font_flags = {
+	STI_WAIT, 0, 0, NULL
+};
+
+/* The colour indices used by STI are
+ *   0 - Black
+ *   1 - White
+ *   2 - Red
+ *   3 - Yellow/Brown
+ *   4 - Green
+ *   5 - Cyan
+ *   6 - Blue
+ *   7 - Magenta
+ *
+ * So we have the same colours as VGA (basically one bit each for R, G, B),
+ * but have to translate them, anyway. */
+
+static u8 col_trans[8] = {
+        0, 6, 4, 5,
+        2, 7, 3, 1
+};
+
+#define c_fg(sti, c) col_trans[((c>> 8) & 7)]
+#define c_bg(sti, c) col_trans[((c>>11) & 7)]
+#define c_index(sti, c) (c&0xff)
+
+static struct sti_init_flags default_init_flags = {
+	STI_WAIT, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, NULL
+};
+
+void
+sti_init_graph(struct sti_struct *sti) 
+{
+	struct sti_init_inptr_ext inptr_ext = {
+		0, { 0 }, 0, NULL
+	};
+	struct sti_init_inptr inptr = {
+		3, STI_PTR(&inptr_ext)
+	};
+	struct sti_init_outptr outptr = { 0 };
+	unsigned long flags;
+	s32 ret;
+
+	spin_lock_irqsave(&sti->lock, flags);
+
+	ret = STI_CALL(sti->init_graph, &default_init_flags, &inptr,
+		&outptr, sti->glob_cfg);
+
+	spin_unlock_irqrestore(&sti->lock, flags);
+
+	sti->text_planes = outptr.text_planes;
+}
+
+static struct sti_conf_flags default_conf_flags = {
+	STI_WAIT, 0, NULL
+};
+
+void
+sti_inq_conf(struct sti_struct *sti)
+{
+	struct sti_conf_inptr inptr = { NULL };
+	struct sti_conf_outptr_ext outptr_ext = { .future_ptr = NULL };
+	struct sti_conf_outptr outptr = {
+		.ext_ptr = STI_PTR(&outptr_ext)
+	};
+	unsigned long flags;
+	s32 ret;
+	
+	do {
+		spin_lock_irqsave(&sti->lock, flags);
+		ret = STI_CALL(sti->inq_conf, &default_conf_flags,
+			&inptr, &outptr, sti->glob_cfg);
+		spin_unlock_irqrestore(&sti->lock, flags);
+	} while(ret == 1);
+}
+
+void
+sti_putc(struct sti_struct *sti, int c, int y, int x)
+{
+	struct sti_font_inptr inptr = {
+		(u32) sti->font, c_index(sti, c), c_fg(sti, c), c_bg(sti, c),
+		x * sti_font_x(sti), y * sti_font_y(sti), NULL
+	};
+	struct sti_font_outptr outptr = {
+		0, NULL
+	};
+	s32 ret;
+	unsigned long flags;
+
+	do {
+		spin_lock_irqsave(&sti->lock, flags);
+		ret = STI_CALL(sti->font_unpmv, &default_font_flags,
+			&inptr, &outptr, sti->glob_cfg);
+		spin_unlock_irqrestore(&sti->lock, flags);
+	} while(ret == 1);
+}
+
+static struct sti_blkmv_flags clear_blkmv_flags = {
+	STI_WAIT, 1, 1, 0, 0, NULL
+};
+
+void
+sti_set(struct sti_struct *sti, int src_y, int src_x,
+	int height, int width, u8 color)
+{
+	struct sti_blkmv_inptr inptr = {
+		color, color,
+		src_x, src_y ,
+		src_x, src_y ,
+		width, height,
+		NULL
+	};
+	struct sti_blkmv_outptr outptr = { 0, NULL };
+	s32 ret = 0;
+	unsigned long flags;
+	
+	do {
+		spin_lock_irqsave(&sti->lock, flags);
+		ret = STI_CALL(sti->block_move, &clear_blkmv_flags,
+			&inptr, &outptr, sti->glob_cfg);
+		spin_unlock_irqrestore(&sti->lock, flags);
+	} while(ret == 1);
+}
+
+void
+sti_clear(struct sti_struct *sti, int src_y, int src_x,
+	  int height, int width)
+{
+	struct sti_blkmv_inptr inptr = {
+		0, 0,
+		src_x * sti_font_x(sti), src_y * sti_font_y(sti),
+		src_x * sti_font_x(sti), src_y * sti_font_y(sti),
+		width * sti_font_x(sti), height* sti_font_y(sti),
+		NULL
+	};
+	struct sti_blkmv_outptr outptr = { 0, NULL };
+	s32 ret = 0;
+	unsigned long flags;
+
+	do {
+		spin_lock_irqsave(&sti->lock, flags);
+		ret = STI_CALL(sti->block_move, &clear_blkmv_flags,
+			&inptr, &outptr, sti->glob_cfg);
+		spin_unlock_irqrestore(&sti->lock, flags);
+	} while(ret == 1);
+}
+
+static struct sti_blkmv_flags default_blkmv_flags = {
+	STI_WAIT, 0, 0, 0, 0, NULL
+};
+
+void
+sti_bmove(struct sti_struct *sti, int src_y, int src_x,
+	  int dst_y, int dst_x, int height, int width)
+{
+	struct sti_blkmv_inptr inptr = {
+		0, 0,
+		src_x * sti_font_x(sti), src_y * sti_font_y(sti),
+		dst_x * sti_font_x(sti), dst_y * sti_font_y(sti),
+		width * sti_font_x(sti), height* sti_font_y(sti),
+		NULL
+	};
+	struct sti_blkmv_outptr outptr = { 0, NULL };
+	s32 ret = 0;
+	unsigned long flags;
+
+	do {
+		spin_lock_irqsave(&sti->lock, flags);
+		ret = STI_CALL(sti->block_move, &default_blkmv_flags,
+			&inptr, &outptr, sti->glob_cfg);
+		spin_unlock_irqrestore(&sti->lock, flags);
+	} while(ret == 1);
+}
+
+
+static void __init
+sti_rom_copy(unsigned long base, unsigned long offset,
+	     unsigned long count, void *dest)
+{
+	void *savedest = dest;
+	int savecount = count;
+
+	while(count >= 4) {
+		count -= 4;
+		*(u32 *)dest = gsc_readl(base + offset);
+		offset += 4;
+		dest += 4;
+	}
+	while(count) {
+		count--;
+		*(u8 *)dest = gsc_readb(base + offset);
+		offset++;
+		dest++;
+	}
+
+	flush_kernel_dcache_range((unsigned long)dest, count);
+	flush_icache_range((unsigned long)dest, dest + count);
+}
+
+static void dump_sti_rom(struct sti_rom *rom)
+{
+	printk("STI word mode ROM type %d\n", rom->type[3]);
+	printk(" supports %d monitors\n", rom->num_mons);
+	printk(" conforms to STI ROM spec revision %d.%02x\n",
+		rom->revno[0] >> 4, rom->revno[0] & 0x0f);
+	printk(" graphics id %02x%02x%02x%02x%02x%02x%02x%02x\n",
+		rom->graphics_id[0], 
+		rom->graphics_id[1], 
+		rom->graphics_id[2], 
+		rom->graphics_id[3], 
+		rom->graphics_id[4], 
+		rom->graphics_id[5], 
+		rom->graphics_id[6], 
+		rom->graphics_id[7]);
+	printk(" font start %08x\n", rom->font_start);
+	printk(" region list %08x\n", rom->region_list);
+	printk(" init_graph %08x\n", rom->init_graph);
+	printk(" alternate code type %d\n", rom->alt_code_type);
+}
+
+static void __init sti_cook_fonts(struct sti_cooked_rom *cooked_rom,
+				  struct sti_rom *raw_rom)
+{
+	struct sti_rom_font *raw_font;
+	struct sti_cooked_font *cooked_font;
+	struct sti_rom_font *font_start;
+	
+	cooked_font =
+		kmalloc(sizeof *cooked_font, GFP_KERNEL);
+	if(!cooked_font)
+		return;
+
+	cooked_rom->font_start = cooked_font;
+
+	raw_font = ((void *)raw_rom) + (raw_rom->font_start);
+
+	font_start = raw_font;
+	cooked_font->raw = raw_font;
+
+	while(raw_font->next_font) {
+		raw_font = ((void *)font_start) + (raw_font->next_font);
+		
+		cooked_font->next_font =
+			kmalloc(sizeof *cooked_font, GFP_KERNEL);
+		if(!cooked_font->next_font)
+			return;
+
+		cooked_font = cooked_font->next_font;
+
+		cooked_font->raw = raw_font;
+	}
+
+	cooked_font->next_font = NULL;
+}
+
+static int font_index, font_height, font_width;
+
+static int __init sti_font_setup(char *str)
+{
+	char *x;
+
+	/* we accept sti_font=10x20, sti_font=10*20 or sti_font=7 style
+	 * command lines. */
+
+	if((x = strchr(str, 'x')) || (x = strchr(str, '*'))) {
+		font_height = simple_strtoul(str, NULL, 0);
+		font_width = simple_strtoul(x+1, NULL, 0);
+	} else {
+		font_index = simple_strtoul(str, NULL, 0);
+	}
+
+	return 0;
+}
+
+__setup("sti_font=", sti_font_setup);
+
+static int __init sti_search_font(struct sti_cooked_rom *rom,
+				  int height, int width)
+{
+	struct sti_cooked_font *font;
+	int i = 0;
+	
+	for(font = rom->font_start; font; font = font->next_font, i++) {
+		if((font->raw->width == width) && (font->raw->height == height))
+			return i;
+	}
+
+	return 0;
+}
+
+static struct sti_cooked_font * __init
+sti_select_font(struct sti_cooked_rom *rom)
+{
+	struct sti_cooked_font *font;
+	int i;
+
+	if(font_width && font_height)
+		font_index = sti_search_font(rom, font_height, font_width);
+
+	for(font = rom->font_start, i = font_index;
+	    font && (i > 0);
+	    font = font->next_font, i--);
+
+	if(font)
+		return font;
+	else
+		return rom->font_start;
+}
+	
+static void __init
+sti_dump_globcfg_ext(struct sti_glob_cfg_ext *cfg)
+{
+	printk(	"monitor %d\n"
+		"in friendly mode: %d\n"
+		"power consumption %d watts\n"
+		"freq ref %d\n"
+		"sti_mem_addr %p\n",
+		cfg->curr_mon,
+		cfg->friendly_boot,
+		cfg->power,
+		cfg->freq_ref,
+		cfg->sti_mem_addr);
+}
+
+void __init
+sti_dump_globcfg(struct sti_glob_cfg *glob_cfg)
+{
+	printk(	"%d text planes\n"
+		"%4d x %4d screen resolution\n"
+		"%4d x %4d offscreen\n"
+		"%4d x %4d layout\n"
+		"regions at %08x %08x %08x %08x\n"
+		"regions at %08x %08x %08x %08x\n"
+		"reent_lvl %d\n"
+		"save_addr %p\n",
+		glob_cfg->text_planes,
+		glob_cfg->onscreen_x, glob_cfg->onscreen_y,
+		glob_cfg->offscreen_x, glob_cfg->offscreen_y,
+		glob_cfg->total_x, glob_cfg->total_y,
+		glob_cfg->region_ptrs[0], glob_cfg->region_ptrs[1],
+		glob_cfg->region_ptrs[2], glob_cfg->region_ptrs[3],
+		glob_cfg->region_ptrs[4], glob_cfg->region_ptrs[5],
+		glob_cfg->region_ptrs[6], glob_cfg->region_ptrs[7],
+		glob_cfg->reent_lvl,
+		glob_cfg->save_addr);
+	sti_dump_globcfg_ext(PTR_STI(glob_cfg->ext_ptr));
+}
+		
+static void __init
+sti_init_glob_cfg(struct sti_struct *sti, unsigned long hpa,
+		  unsigned long rom_address)
+{
+	struct sti_glob_cfg *glob_cfg;
+	struct sti_glob_cfg_ext *glob_cfg_ext;
+	void *save_addr;
+	void *sti_mem_addr;
+
+	glob_cfg = kmalloc(sizeof *sti->glob_cfg, GFP_KERNEL);
+	glob_cfg_ext = kmalloc(sizeof *glob_cfg_ext, GFP_KERNEL);
+	save_addr = kmalloc(1024 /*XXX*/, GFP_KERNEL);
+	sti_mem_addr = kmalloc(1024, GFP_KERNEL);
+
+	if((!glob_cfg) || (!glob_cfg_ext) || (!save_addr) || (!sti_mem_addr))
+		return;
+
+	memset(glob_cfg, 0, sizeof *glob_cfg);
+	memset(glob_cfg_ext, 0, sizeof *glob_cfg_ext);
+	memset(save_addr, 0, 1024);
+	memset(sti_mem_addr, 0, 1024);
+
+	glob_cfg->ext_ptr = STI_PTR(glob_cfg_ext);
+	glob_cfg->save_addr = STI_PTR(save_addr);
+	glob_cfg->region_ptrs[0] = ((sti->regions[0]>>18)<<12) + rom_address;
+	glob_cfg->region_ptrs[1] = ((sti->regions[1]>>18)<<12) + hpa;
+	glob_cfg->region_ptrs[2] = ((sti->regions[2]>>18)<<12) + hpa;
+	glob_cfg->region_ptrs[3] = ((sti->regions[3]>>18)<<12) + hpa;
+	glob_cfg->region_ptrs[4] = ((sti->regions[4]>>18)<<12) + hpa;
+	glob_cfg->region_ptrs[5] = ((sti->regions[5]>>18)<<12) + hpa;
+	glob_cfg->region_ptrs[6] = ((sti->regions[6]>>18)<<12) + hpa;
+	glob_cfg->region_ptrs[7] = ((sti->regions[7]>>18)<<12) + hpa;
+	
+	glob_cfg_ext->sti_mem_addr = STI_PTR(sti_mem_addr);
+
+	sti->glob_cfg = STI_PTR(glob_cfg);
+}
+
+/* address is a pointer to a word mode or pci rom */
+static struct sti_struct * __init
+sti_read_rom(unsigned long address)
+{
+	struct sti_struct *ret = NULL;
+	struct sti_cooked_rom *cooked = NULL;
+	struct sti_rom *raw = NULL;
+	unsigned long size;
+
+	ret = &default_sti;
+
+	if(!ret)
+		goto out_err;
+
+	cooked = kmalloc(sizeof *cooked, GFP_KERNEL);
+	raw = kmalloc(sizeof *raw, GFP_KERNEL);
+	
+	if(!(raw && cooked))
+		goto out_err;
+
+	/* reallocate raw */
+	sti_rom_copy(address, 0, sizeof *raw, raw);
+
+	dump_sti_rom(raw);
+
+	size = raw->last_addr;
+	/* kfree(raw); */
+	raw = kmalloc(size, GFP_KERNEL);
+	if(!raw)
+		goto out_err;
+	sti_rom_copy(address, 0, size, raw);
+
+	sti_cook_fonts(cooked, raw);
+#if 0
+	sti_cook_regions(cooked, raw);
+	sti_cook_functions(cooked, raw);
+#endif
+
+	if(raw->region_list) {
+		ret->regions = kmalloc(32, GFP_KERNEL);	/* FIXME */
+
+		memcpy(ret->regions, ((void *)raw)+raw->region_list, 32);
+	}
+
+	address = virt_to_phys(raw);
+
+	ret->font_unpmv = address+(raw->font_unpmv & 0x03ffffff);
+	ret->block_move = address+(raw->block_move & 0x03ffffff);
+	ret->init_graph = address+(raw->init_graph & 0x03ffffff);
+	ret->inq_conf = address+(raw->inq_conf     & 0x03ffffff);
+
+	ret->rom = cooked;
+	ret->rom->raw = raw;
+
+	ret->font = (struct sti_rom_font *) virt_to_phys(sti_select_font(ret->rom)->raw);
+
+	return ret;
+
+out_err:
+	if(raw)
+		kfree(raw);
+	if(cooked)
+		kfree(cooked);
+
+	return NULL;
+}
+
+static struct sti_struct * __init
+sti_try_rom(unsigned long address, unsigned long hpa)
+{
+	struct sti_struct *sti = NULL;
+	u16 sig;
+	
+test_rom:
+	/* if we can't read the ROM, bail out early.  Not being able
+	 * to read the hpa is okay, for romless sti */
+	if(pdc_add_valid((void*)address))
+		return NULL;
+
+	printk("found potential STI ROM at %08lx\n", address);
+
+	sig = le16_to_cpu(gsc_readw(address));
+
+	if((sig==0x55aa) || (sig==0xaa55)) {
+		address += le32_to_cpu(gsc_readl(address+8));
+		printk("sig %04x, PCI STI ROM at %08lx\n",
+		       sig, address);
+
+		goto test_rom;
+	}
+
+	if((sig&0xff) == 0x01) {
+		printk("STI byte mode ROM at %08lx, ignored\n",
+		       address);
+
+		sti = NULL;
+	}
+
+	if(sig == 0x0303) {
+		printk("STI word mode ROM at %08lx\n",
+		       address);
+
+		sti = sti_read_rom(address);
+	}
+
+	if (!sti)
+		return NULL;
+
+	/* this is hacked.  We need a better way to find out the HPA for
+	 * romless STI (eg search for the graphics devices we know about
+	 * by sversion) */
+	if (!pdc_add_valid((void *)0xf5000000)) printk("f4000000 g\n");
+	if (!pdc_add_valid((void *)0xf7000000)) printk("f6000000 g\n");
+	if (!pdc_add_valid((void *)0xf9000000)) printk("f8000000 g\n");
+	if (!pdc_add_valid((void *)0xfb000000)) printk("fa000000 g\n");
+	sti_init_glob_cfg(sti, hpa, address);
+
+	sti_init_graph(sti);
+
+	sti_inq_conf(sti);
+	sti_dump_globcfg(PTR_STI(sti->glob_cfg));
+
+	return sti;
+}
+
+static unsigned long sti_address;
+static unsigned long sti_hpa;
+
+/* XXX: should build a list of STI ROMs */
+struct sti_struct * __init
+sti_init_roms(void)
+{
+	struct sti_struct *tmp = NULL, *sti = NULL;
+
+	/* handle the command line */
+	if (sti_address && sti_hpa) {
+		return sti_try_rom(sti_address, sti_hpa);
+	}
+
+	/* 712, 715, some other boxes don't have a separate STI ROM,
+	 * but use part of the regular flash */
+	if (PAGE0->proc_sti) {
+		printk("STI ROM from PDC at %08x\n", PAGE0->proc_sti);
+		if (!pdc_add_valid((void *)0xf9000000))
+			sti = sti_try_rom(PAGE0->proc_sti, 0xf8000000);
+		else if (!pdc_add_valid((void *)0xf5000000))
+			sti = sti_try_rom(PAGE0->proc_sti, 0xf4000000);
+		else if (!pdc_add_valid((void *)0xf7000000))
+			sti = sti_try_rom(PAGE0->proc_sti, 0xf6000000);
+		else if (!pdc_add_valid((void *)0xfb000000))
+			sti = sti_try_rom(PAGE0->proc_sti, 0xfa000000);
+
+	}
+
+	/* standard locations for GSC graphic devices */
+	if (!pdc_add_valid((void *)0xf4000000))
+		tmp = sti_try_rom(0xf4000000, 0xf4000000);
+	sti = tmp ? tmp : sti;
+	if (!pdc_add_valid((void *)0xf6000000))
+		tmp = sti_try_rom(0xf6000000, 0xf6000000);
+	sti = tmp ? tmp : sti;
+	if (!pdc_add_valid((void *)0xf8000000))
+		tmp = sti_try_rom(0xf8000000, 0xf8000000);
+	sti = tmp ? tmp : sti;
+	if (!pdc_add_valid((void *)0xfa000000))
+		tmp = sti_try_rom(0xfa000000, 0xfa000000);
+	sti = tmp ? tmp : sti;
+
+	return sti;
+}
+
+static int __init
+sti_setup(char *str)
+{
+	char *end;
+
+	if(strcmp(str, "pdc") == 0) {
+		sti_address = PAGE0->proc_sti;
+
+		return 1;
+	} else {
+		sti_address = simple_strtoul(str, &end, 16);
+
+		if((end == str) || (sti_address < 0xf0000000)) {
+			sti_address = 0;
+			return 0;
+		}
+
+		sti_hpa = sti_address;
+
+		return 1;
+	}
+
+	return 0;
+}
+
+__setup("sti=", sti_setup);
+
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/console/vgacon.c	Mon Dec  9 18:46:36 2002
@@ -0,0 +1,1066 @@
+/*
+ *  linux/drivers/video/vgacon.c -- Low level VGA based console driver
+ *
+ *	Created 28 Sep 1997 by Geert Uytterhoeven
+ *
+ *	Rewritten by Martin Mares <mj@ucw.cz>, July 1998
+ *
+ *  This file is based on the old console.c, vga.c and vesa_blank.c drivers.
+ *
+ *	Copyright (C) 1991, 1992  Linus Torvalds
+ *			    1995  Jay Estabrook
+ *
+ *	User definable mapping table and font loading by Eugene G. Crosser,
+ *	<crosser@average.org>
+ *
+ *	Improved loadable font/UTF-8 support by H. Peter Anvin
+ *	Feb-Sep 1995 <peter.anvin@linux.org>
+ *
+ *	Colour palette handling, by Simon Tatham
+ *	17-Jun-95 <sgt20@cam.ac.uk>
+ *
+ *	if 512 char mode is already enabled don't re-enable it,
+ *	because it causes screen to flicker, by Mitja Horvat
+ *	5-May-96 <mitja.horvat@guest.arnes.si>
+ *
+ *	Use 2 outw instead of 4 outb_p to reduce erroneous text
+ *	flashing on RHS of screen during heavy console scrolling .
+ *	Oct 1996, Paul Gortmaker.
+ *
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/string.h>
+#include <linux/kd.h>
+#include <linux/slab.h>
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+#include <linux/spinlock.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+
+static spinlock_t vga_lock = SPIN_LOCK_UNLOCKED;
+
+#define BLANK 0x0020
+
+#define CAN_LOAD_EGA_FONTS	/* undefine if the user must not do this */
+#define CAN_LOAD_PALETTE	/* undefine if the user must not do this */
+
+/* You really do _NOT_ want to define this, unless you have buggy
+ * Trident VGA which will resize cursor when moving it between column
+ * 15 & 16. If you define this and your VGA is OK, inverse bug will
+ * appear.
+ */
+#undef TRIDENT_GLITCH
+
+#define dac_reg		0x3c8
+#define dac_val		0x3c9
+#define attrib_port	0x3c0
+#define seq_port_reg	0x3c4
+#define seq_port_val	0x3c5
+#define gr_port_reg	0x3ce
+#define gr_port_val	0x3cf
+#define video_misc_rd	0x3cc
+#define video_misc_wr	0x3c2
+
+/*
+ *  Interface used by the world
+ */
+
+static const char *vgacon_startup(void);
+static void vgacon_init(struct vc_data *c, int init);
+static void vgacon_deinit(struct vc_data *c);
+static void vgacon_cursor(struct vc_data *c, int mode);
+static int vgacon_switch(struct vc_data *c);
+static int vgacon_blank(struct vc_data *c, int blank);
+static int vgacon_font_op(struct vc_data *c, struct console_font_op *op);
+static int vgacon_set_palette(struct vc_data *c, unsigned char *table);
+static int vgacon_scrolldelta(struct vc_data *c, int lines);
+static int vgacon_set_origin(struct vc_data *c);
+static void vgacon_save_screen(struct vc_data *c);
+static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, int lines);
+static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity, u8 blink, u8 underline, u8 reverse);
+static void vgacon_invert_region(struct vc_data *c, u16 *p, int count);
+static unsigned long vgacon_uni_pagedir[2];
+
+
+/* Description of the hardware situation */
+static unsigned long   vga_vram_base;		/* Base of video memory */
+static unsigned long   vga_vram_end;		/* End of video memory */
+static u16             vga_video_port_reg;	/* Video register select port */
+static u16             vga_video_port_val;	/* Video register value port */
+static unsigned int    vga_video_num_columns;	/* Number of text columns */
+static unsigned int    vga_video_num_lines;	/* Number of text lines */
+static int	       vga_can_do_color = 0;	/* Do we support colors? */
+static unsigned int    vga_default_font_height;	/* Height of default screen font */
+static unsigned char   vga_video_type;		/* Card type */
+static unsigned char   vga_hardscroll_enabled;
+static unsigned char   vga_hardscroll_user_enable = 1;
+static unsigned char   vga_font_is_default = 1;
+static int	       vga_vesa_blanked;
+static int	       vga_palette_blanked;
+static int	       vga_is_gfx;
+static int	       vga_512_chars;
+static int	       vga_video_font_height;
+static unsigned int    vga_rolled_over = 0;
+
+
+static int __init no_scroll(char *str)
+{
+	/*
+	 * Disabling scrollback is required for the Braillex ib80-piezo
+	 * Braille reader made by F.H. Papenmeier (Germany).
+	 * Use the "no-scroll" bootflag.
+	 */
+	vga_hardscroll_user_enable = vga_hardscroll_enabled = 0;
+	return 1;
+}
+
+__setup("no-scroll", no_scroll);
+
+/*
+ * By replacing the four outb_p with two back to back outw, we can reduce
+ * the window of opportunity to see text mislocated to the RHS of the
+ * console during heavy scrolling activity. However there is the remote
+ * possibility that some pre-dinosaur hardware won't like the back to back
+ * I/O. Since the Xservers get away with it, we should be able to as well.
+ */
+static inline void write_vga(unsigned char reg, unsigned int val)
+{
+	unsigned int v1, v2;
+	unsigned long flags;
+
+	/*
+	 * ddprintk might set the console position from interrupt
+	 * handlers, thus the write has to be IRQ-atomic.
+	 */
+	spin_lock_irqsave(&vga_lock, flags);	
+
+#ifndef SLOW_VGA
+	v1 = reg + (val & 0xff00);
+	v2 = reg + 1 + ((val << 8) & 0xff00);
+	outw(v1, vga_video_port_reg);
+	outw(v2, vga_video_port_reg);
+#else
+	outb_p(reg, vga_video_port_reg);
+	outb_p(val >> 8, vga_video_port_val);
+	outb_p(reg+1, vga_video_port_reg);
+	outb_p(val & 0xff, vga_video_port_val);
+#endif
+	spin_unlock_irqrestore(&vga_lock, flags);
+}
+
+static const char __init *vgacon_startup(void)
+{
+	const char *display_desc = NULL;
+	u16 saved1, saved2;
+	volatile u16 *p;
+
+	if (ORIG_VIDEO_ISVGA == VIDEO_TYPE_VLFB) {
+	no_vga:
+#ifdef CONFIG_DUMMY_CONSOLE
+		conswitchp = &dummy_con;
+		return conswitchp->con_startup();
+#else
+		return NULL;
+#endif
+	}
+
+	/* VGA16 modes are not handled by VGACON */
+	if ((ORIG_VIDEO_MODE == 0x0D) || /* 320x200/4 */
+	    (ORIG_VIDEO_MODE == 0x0E) || /* 640x200/4 */
+	    (ORIG_VIDEO_MODE == 0x10) || /* 640x350/4 */
+	    (ORIG_VIDEO_MODE == 0x12) || /* 640x480/4 */
+	    (ORIG_VIDEO_MODE == 0x6A))   /* 800x600/4, 0x6A is very common */
+		goto no_vga;
+
+	vga_video_num_lines = ORIG_VIDEO_LINES;
+	vga_video_num_columns = ORIG_VIDEO_COLS;
+
+	if (ORIG_VIDEO_MODE == 7)	/* Is this a monochrome display? */
+	{
+		vga_vram_base = 0xb0000;
+		vga_video_port_reg = 0x3b4;
+		vga_video_port_val = 0x3b5;
+		if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
+		{
+			static struct resource ega_console_resource = { "ega", 0x3B0, 0x3BF };
+			vga_video_type = VIDEO_TYPE_EGAM;
+			vga_vram_end = 0xb8000;
+			display_desc = "EGA+";
+			request_resource(&ioport_resource, &ega_console_resource);
+		}
+		else
+		{
+			static struct resource mda1_console_resource = { "mda", 0x3B0, 0x3BB };
+			static struct resource mda2_console_resource = { "mda", 0x3BF, 0x3BF };
+			vga_video_type = VIDEO_TYPE_MDA;
+			vga_vram_end = 0xb2000;
+			display_desc = "*MDA";
+			request_resource(&ioport_resource, &mda1_console_resource);
+			request_resource(&ioport_resource, &mda2_console_resource);
+			vga_video_font_height = 14;
+		}
+	}
+	else				/* If not, it is color. */
+	{
+		vga_can_do_color = 1;
+		vga_vram_base = 0xb8000;
+		vga_video_port_reg = 0x3d4;
+		vga_video_port_val = 0x3d5;
+		if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
+		{
+			int i;
+
+			vga_vram_end = 0xc0000;
+
+			if (!ORIG_VIDEO_ISVGA) {
+				static struct resource ega_console_resource = { "ega", 0x3C0, 0x3DF };
+				vga_video_type = VIDEO_TYPE_EGAC;
+				display_desc = "EGA";
+				request_resource(&ioport_resource, &ega_console_resource);
+			} else {
+				static struct resource vga_console_resource = { "vga+", 0x3C0, 0x3DF };
+				vga_video_type = VIDEO_TYPE_VGAC;
+				display_desc = "VGA+";
+				request_resource(&ioport_resource, &vga_console_resource);
+
+#ifdef VGA_CAN_DO_64KB
+				/*
+				 * get 64K rather than 32K of video RAM.
+				 * This doesn't actually work on all "VGA"
+				 * controllers (it seems like setting MM=01
+				 * and COE=1 isn't necessarily a good idea)
+				 */
+				vga_vram_base = 0xa0000;
+				vga_vram_end = 0xb0000;
+				outb_p (6, 0x3ce) ;
+				outb_p (6, 0x3cf) ;
+#endif
+
+				/*
+				 * Normalise the palette registers, to point
+				 * the 16 screen colours to the first 16
+				 * DAC entries.
+				 */
+
+				for (i=0; i<16; i++) {
+					inb_p (0x3da) ;
+					outb_p (i, 0x3c0) ;
+					outb_p (i, 0x3c0) ;
+				}
+				outb_p (0x20, 0x3c0) ;
+
+				/* now set the DAC registers back to their
+				 * default values */
+
+				for (i=0; i<16; i++) {
+					outb_p (color_table[i], 0x3c8) ;
+					outb_p (default_red[i], 0x3c9) ;
+					outb_p (default_grn[i], 0x3c9) ;
+					outb_p (default_blu[i], 0x3c9) ;
+				}
+			}
+		}
+		else
+		{
+			static struct resource cga_console_resource = { "cga", 0x3D4, 0x3D5 };
+			vga_video_type = VIDEO_TYPE_CGA;
+			vga_vram_end = 0xba000;
+			display_desc = "*CGA";
+			request_resource(&ioport_resource, &cga_console_resource);
+			vga_video_font_height = 8;
+		}
+	}
+
+	vga_vram_base = VGA_MAP_MEM(vga_vram_base);
+	vga_vram_end = VGA_MAP_MEM(vga_vram_end);
+
+	/*
+	 *	Find out if there is a graphics card present.
+	 *	Are there smarter methods around?
+	 */
+	p = (volatile u16 *)vga_vram_base;
+	saved1 = scr_readw(p);
+	saved2 = scr_readw(p + 1);
+	scr_writew(0xAA55, p);
+	scr_writew(0x55AA, p + 1);
+	if (scr_readw(p) != 0xAA55 || scr_readw(p + 1) != 0x55AA) {
+		scr_writew(saved1, p);
+		scr_writew(saved2, p + 1);
+		goto no_vga;
+	}
+	scr_writew(0x55AA, p);
+	scr_writew(0xAA55, p + 1);
+	if (scr_readw(p) != 0x55AA || scr_readw(p + 1) != 0xAA55) {
+		scr_writew(saved1, p);
+		scr_writew(saved2, p + 1);
+		goto no_vga;
+	}
+	scr_writew(saved1, p);
+	scr_writew(saved2, p + 1);
+
+	if (vga_video_type == VIDEO_TYPE_EGAC
+	    || vga_video_type == VIDEO_TYPE_VGAC
+	    || vga_video_type == VIDEO_TYPE_EGAM) {
+		vga_hardscroll_enabled = vga_hardscroll_user_enable;
+		vga_default_font_height = ORIG_VIDEO_POINTS;
+		vga_video_font_height = ORIG_VIDEO_POINTS;
+		/* This may be suboptimal but is a safe bet - go with it */
+		video_scan_lines =
+			vga_video_font_height * vga_video_num_lines;
+	}
+	video_font_height = vga_video_font_height;
+
+	return display_desc;
+}
+
+static void vgacon_init(struct vc_data *c, int init)
+{
+	unsigned long p;
+	
+	/* We cannot be loaded as a module, therefore init is always 1 */
+	c->vc_can_do_color = vga_can_do_color;
+	c->vc_cols = vga_video_num_columns;
+	c->vc_rows = vga_video_num_lines;
+	c->vc_complement_mask = 0x7700;
+	p = *c->vc_uni_pagedir_loc;
+	if (c->vc_uni_pagedir_loc == &c->vc_uni_pagedir ||
+	    !--c->vc_uni_pagedir_loc[1])
+		con_free_unimap(c->vc_num);
+	c->vc_uni_pagedir_loc = vgacon_uni_pagedir;
+	vgacon_uni_pagedir[1]++;
+	if (!vgacon_uni_pagedir[0] && p)
+		con_set_default_unimap(c->vc_num);
+}
+
+static inline void vga_set_mem_top(struct vc_data *c)
+{
+	write_vga(12, (c->vc_visible_origin-vga_vram_base)/2);
+}
+
+static void vgacon_deinit(struct vc_data *c)
+{
+	/* When closing the last console, reset video origin */
+	if (!--vgacon_uni_pagedir[1]) {
+		c->vc_visible_origin = vga_vram_base;
+		vga_set_mem_top(c);
+		con_free_unimap(c->vc_num);
+	}
+	c->vc_uni_pagedir_loc = &c->vc_uni_pagedir;
+	con_set_default_unimap(c->vc_num);
+}
+
+static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity, u8 blink, u8 underline, u8 reverse)
+{
+	u8 attr = color;
+
+	if (vga_can_do_color) {
+		if (underline)
+			attr = (attr & 0xf0) | c->vc_ulcolor;
+		else if (intensity == 0)
+			attr = (attr & 0xf0) | c->vc_halfcolor;
+	}
+	if (reverse)
+		attr = ((attr) & 0x88) | ((((attr) >> 4) | ((attr) << 4)) & 0x77);
+	if (blink)
+		attr ^= 0x80;
+	if (intensity == 2)
+		attr ^= 0x08;
+	if (!vga_can_do_color) {
+		if (underline)
+			attr = (attr & 0xf8) | 0x01;
+		else if (intensity == 0)
+			attr = (attr & 0xf0) | 0x08;
+	}
+	return attr;
+}
+
+static void vgacon_invert_region(struct vc_data *c, u16 *p, int count)
+{
+	int col = vga_can_do_color;
+
+	while (count--) {
+		u16 a = scr_readw(p);
+		if (col)
+			a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4);
+		else
+			a ^= ((a & 0x0700) == 0x0100) ? 0x7000 : 0x7700;
+		scr_writew(a, p++);
+	}
+}
+
+static void vgacon_set_cursor_size(int xpos, int from, int to)
+{
+	unsigned long flags;
+	int curs, cure;
+	static int lastfrom, lastto;
+
+#ifdef TRIDENT_GLITCH
+	if (xpos<16) from--, to--;
+#endif
+
+	if ((from == lastfrom) && (to == lastto)) return;
+	lastfrom = from; lastto = to;
+
+	spin_lock_irqsave(&vga_lock, flags);
+	outb_p(0x0a, vga_video_port_reg);		/* Cursor start */
+	curs = inb_p(vga_video_port_val);
+	outb_p(0x0b, vga_video_port_reg);		/* Cursor end */
+	cure = inb_p(vga_video_port_val);
+
+	curs = (curs & 0xc0) | from;
+	cure = (cure & 0xe0) | to;
+
+	outb_p(0x0a, vga_video_port_reg);		/* Cursor start */
+	outb_p(curs, vga_video_port_val);
+	outb_p(0x0b, vga_video_port_reg);		/* Cursor end */
+	outb_p(cure, vga_video_port_val);
+	spin_unlock_irqrestore(&vga_lock, flags);
+}
+
+static void vgacon_cursor(struct vc_data *c, int mode)
+{
+    if (c->vc_origin != c->vc_visible_origin)
+	vgacon_scrolldelta(c, 0);
+    switch (mode) {
+	case CM_ERASE:
+	    write_vga(14, (vga_vram_end - vga_vram_base - 1)/2);
+	    break;
+
+	case CM_MOVE:
+	case CM_DRAW:
+	    write_vga(14, (c->vc_pos-vga_vram_base)/2);
+	    switch (c->vc_cursor_type & 0x0f) {
+		case CUR_UNDERLINE:
+			vgacon_set_cursor_size(c->vc_x, 
+					video_font_height - (video_font_height < 10 ? 2 : 3),
+					video_font_height - (video_font_height < 10 ? 1 : 2));
+			break;
+		case CUR_TWO_THIRDS:
+			vgacon_set_cursor_size(c->vc_x, 
+					 video_font_height / 3,
+					 video_font_height - (video_font_height < 10 ? 1 : 2));
+			break;
+		case CUR_LOWER_THIRD:
+			vgacon_set_cursor_size(c->vc_x, 
+					 (video_font_height*2) / 3,
+					 video_font_height - (video_font_height < 10 ? 1 : 2));
+			break;
+		case CUR_LOWER_HALF:
+			vgacon_set_cursor_size(c->vc_x, 
+					 video_font_height / 2,
+					 video_font_height - (video_font_height < 10 ? 1 : 2));
+			break;
+		case CUR_NONE:
+			vgacon_set_cursor_size(c->vc_x, 31, 30);
+			break;
+          	default:
+			vgacon_set_cursor_size(c->vc_x, 1, video_font_height);
+			break;
+		}
+	    break;
+    }
+}
+
+static int vgacon_switch(struct vc_data *c)
+{
+	/*
+	 * We need to save screen size here as it's the only way
+	 * we can spot the screen has been resized and we need to
+	 * set size of freshly allocated screens ourselves.
+	 */
+	vga_video_num_columns = c->vc_cols;
+	vga_video_num_lines = c->vc_rows;
+	if (!vga_is_gfx)
+		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size);
+	return 0;	/* Redrawing not needed */
+}
+
+static void vga_set_palette(struct vc_data *c, unsigned char *table)
+{
+	int i, j ;
+
+	for (i=j=0; i<16; i++) {
+		outb_p (table[i], dac_reg) ;
+		outb_p (c->vc_palette[j++]>>2, dac_val) ;
+		outb_p (c->vc_palette[j++]>>2, dac_val) ;
+		outb_p (c->vc_palette[j++]>>2, dac_val) ;
+	}
+}
+
+static int vgacon_set_palette(struct vc_data *c, unsigned char *table)
+{
+#ifdef CAN_LOAD_PALETTE
+	if (vga_video_type != VIDEO_TYPE_VGAC || vga_palette_blanked || !CON_IS_VISIBLE(c))
+		return -EINVAL;
+	vga_set_palette(c, table);
+	return 0;
+#else
+	return -EINVAL;
+#endif
+}
+
+/* structure holding original VGA register settings */
+static struct {
+	unsigned char	SeqCtrlIndex;		/* Sequencer Index reg.   */
+	unsigned char	CrtCtrlIndex;		/* CRT-Contr. Index reg.  */
+	unsigned char	CrtMiscIO;		/* Miscellaneous register */
+	unsigned char	HorizontalTotal;	/* CRT-Controller:00h */
+	unsigned char	HorizDisplayEnd;	/* CRT-Controller:01h */
+	unsigned char	StartHorizRetrace;	/* CRT-Controller:04h */
+	unsigned char	EndHorizRetrace;	/* CRT-Controller:05h */
+	unsigned char	Overflow;		/* CRT-Controller:07h */
+	unsigned char	StartVertRetrace;	/* CRT-Controller:10h */
+	unsigned char	EndVertRetrace;		/* CRT-Controller:11h */
+	unsigned char	ModeControl;		/* CRT-Controller:17h */
+	unsigned char	ClockingMode;		/* Seq-Controller:01h */
+} vga_state;
+
+static void vga_vesa_blank(int mode)
+{
+	/* save original values of VGA controller registers */
+	if(!vga_vesa_blanked) {
+		spin_lock_irq(&vga_lock);
+		vga_state.SeqCtrlIndex = inb_p(seq_port_reg);
+		vga_state.CrtCtrlIndex = inb_p(vga_video_port_reg);
+		vga_state.CrtMiscIO = inb_p(video_misc_rd);
+		spin_unlock_irq(&vga_lock);
+
+		outb_p(0x00,vga_video_port_reg);	/* HorizontalTotal */
+		vga_state.HorizontalTotal = inb_p(vga_video_port_val);
+		outb_p(0x01,vga_video_port_reg);	/* HorizDisplayEnd */
+		vga_state.HorizDisplayEnd = inb_p(vga_video_port_val);
+		outb_p(0x04,vga_video_port_reg);	/* StartHorizRetrace */
+		vga_state.StartHorizRetrace = inb_p(vga_video_port_val);
+		outb_p(0x05,vga_video_port_reg);	/* EndHorizRetrace */
+		vga_state.EndHorizRetrace = inb_p(vga_video_port_val);
+		outb_p(0x07,vga_video_port_reg);	/* Overflow */
+		vga_state.Overflow = inb_p(vga_video_port_val);
+		outb_p(0x10,vga_video_port_reg);	/* StartVertRetrace */
+		vga_state.StartVertRetrace = inb_p(vga_video_port_val);
+		outb_p(0x11,vga_video_port_reg);	/* EndVertRetrace */
+		vga_state.EndVertRetrace = inb_p(vga_video_port_val);
+		outb_p(0x17,vga_video_port_reg);	/* ModeControl */
+		vga_state.ModeControl = inb_p(vga_video_port_val);
+		outb_p(0x01,seq_port_reg);		/* ClockingMode */
+		vga_state.ClockingMode = inb_p(seq_port_val);
+	}
+
+	/* assure that video is enabled */
+	/* "0x20" is VIDEO_ENABLE_bit in register 01 of sequencer */
+	spin_lock_irq(&vga_lock);
+	outb_p(0x01,seq_port_reg);
+	outb_p(vga_state.ClockingMode | 0x20,seq_port_val);
+
+	/* test for vertical retrace in process.... */
+	if ((vga_state.CrtMiscIO & 0x80) == 0x80)
+		outb_p(vga_state.CrtMiscIO & 0xef,video_misc_wr);
+
+	/*
+	 * Set <End of vertical retrace> to minimum (0) and
+	 * <Start of vertical Retrace> to maximum (incl. overflow)
+	 * Result: turn off vertical sync (VSync) pulse.
+	 */
+	if (mode & VESA_VSYNC_SUSPEND) {
+		outb_p(0x10,vga_video_port_reg);	/* StartVertRetrace */
+		outb_p(0xff,vga_video_port_val); 	/* maximum value */
+		outb_p(0x11,vga_video_port_reg);	/* EndVertRetrace */
+		outb_p(0x40,vga_video_port_val);	/* minimum (bits 0..3)  */
+		outb_p(0x07,vga_video_port_reg);	/* Overflow */
+		outb_p(vga_state.Overflow | 0x84,vga_video_port_val); /* bits 9,10 of vert. retrace */
+	}
+
+	if (mode & VESA_HSYNC_SUSPEND) {
+		/*
+		 * Set <End of horizontal retrace> to minimum (0) and
+		 *  <Start of horizontal Retrace> to maximum
+		 * Result: turn off horizontal sync (HSync) pulse.
+		 */
+		outb_p(0x04,vga_video_port_reg);	/* StartHorizRetrace */
+		outb_p(0xff,vga_video_port_val);	/* maximum */
+		outb_p(0x05,vga_video_port_reg);	/* EndHorizRetrace */
+		outb_p(0x00,vga_video_port_val);	/* minimum (0) */
+	}
+
+	/* restore both index registers */
+	outb_p(vga_state.SeqCtrlIndex,seq_port_reg);
+	outb_p(vga_state.CrtCtrlIndex,vga_video_port_reg);
+	spin_unlock_irq(&vga_lock);
+}
+
+static void vga_vesa_unblank(void)
+{
+	/* restore original values of VGA controller registers */
+	spin_lock_irq(&vga_lock);
+	outb_p(vga_state.CrtMiscIO,video_misc_wr);
+
+	outb_p(0x00,vga_video_port_reg);		/* HorizontalTotal */
+	outb_p(vga_state.HorizontalTotal,vga_video_port_val);
+	outb_p(0x01,vga_video_port_reg);		/* HorizDisplayEnd */
+	outb_p(vga_state.HorizDisplayEnd,vga_video_port_val);
+	outb_p(0x04,vga_video_port_reg);		/* StartHorizRetrace */
+	outb_p(vga_state.StartHorizRetrace,vga_video_port_val);
+	outb_p(0x05,vga_video_port_reg);		/* EndHorizRetrace */
+	outb_p(vga_state.EndHorizRetrace,vga_video_port_val);
+	outb_p(0x07,vga_video_port_reg);		/* Overflow */
+	outb_p(vga_state.Overflow,vga_video_port_val);
+	outb_p(0x10,vga_video_port_reg);		/* StartVertRetrace */
+	outb_p(vga_state.StartVertRetrace,vga_video_port_val);
+	outb_p(0x11,vga_video_port_reg);		/* EndVertRetrace */
+	outb_p(vga_state.EndVertRetrace,vga_video_port_val);
+	outb_p(0x17,vga_video_port_reg);		/* ModeControl */
+	outb_p(vga_state.ModeControl,vga_video_port_val);
+	outb_p(0x01,seq_port_reg);		/* ClockingMode */
+	outb_p(vga_state.ClockingMode,seq_port_val);
+
+	/* restore index/control registers */
+	outb_p(vga_state.SeqCtrlIndex,seq_port_reg);
+	outb_p(vga_state.CrtCtrlIndex,vga_video_port_reg);
+	spin_unlock_irq(&vga_lock);
+}
+
+static void vga_pal_blank(void)
+{
+	int i;
+
+	for (i=0; i<16; i++) {
+		outb_p (i, dac_reg) ;
+		outb_p (0, dac_val) ;
+		outb_p (0, dac_val) ;
+		outb_p (0, dac_val) ;
+	}
+}
+
+static int vgacon_blank(struct vc_data *c, int blank)
+{
+	switch (blank) {
+	case 0:				/* Unblank */
+		if (vga_vesa_blanked) {
+			vga_vesa_unblank();
+			vga_vesa_blanked = 0;
+		}
+		if (vga_palette_blanked) {
+			vga_set_palette(c, color_table);
+			vga_palette_blanked = 0;
+			return 0;
+		}
+		vga_is_gfx = 0;
+		/* Tell console.c that it has to restore the screen itself */
+		return 1;
+	case 1:				/* Normal blanking */
+		if (vga_video_type == VIDEO_TYPE_VGAC) {
+			vga_pal_blank();
+			vga_palette_blanked = 1;
+			return 0;
+		}
+		vgacon_set_origin(c);
+		scr_memsetw((void *)vga_vram_base, BLANK, c->vc_screenbuf_size);
+		return 1;
+	case -1:			/* Entering graphic mode */
+		scr_memsetw((void *)vga_vram_base, BLANK, c->vc_screenbuf_size);
+		vga_is_gfx = 1;
+		return 1;
+	default:			/* VESA blanking */
+		if (vga_video_type == VIDEO_TYPE_VGAC) {
+			vga_vesa_blank(blank-1);
+			vga_vesa_blanked = blank;
+		}
+		return 0;
+	}
+}
+
+/*
+ * PIO_FONT support.
+ *
+ * The font loading code goes back to the codepage package by
+ * Joel Hoffman (joel@wam.umd.edu). (He reports that the original
+ * reference is: "From: p. 307 of _Programmer's Guide to PC & PS/2
+ * Video Systems_ by Richard Wilton. 1987.  Microsoft Press".)
+ *
+ * Change for certain monochrome monitors by Yury Shevchuck
+ * (sizif@botik.yaroslavl.su).
+ */
+
+#ifdef CAN_LOAD_EGA_FONTS
+
+#define colourmap 0xa0000
+/* Pauline Middelink <middelin@polyware.iaf.nl> reports that we
+   should use 0xA0000 for the bwmap as well.. */
+#define blackwmap 0xa0000
+#define cmapsz 8192
+
+static int
+vgacon_do_font_op(char *arg, int set, int ch512)
+{
+	int i;
+	char *charmap;
+	int beg;
+	unsigned short video_port_status = vga_video_port_reg + 6;
+	int font_select = 0x00;
+
+	if (vga_video_type != VIDEO_TYPE_EGAM) {
+		charmap = (char *)VGA_MAP_MEM(colourmap);
+		beg = 0x0e;
+#ifdef VGA_CAN_DO_64KB
+		if (vga_video_type == VIDEO_TYPE_VGAC)
+			beg = 0x06;
+#endif
+	} else {
+		charmap = (char *)VGA_MAP_MEM(blackwmap);
+		beg = 0x0a;
+	}
+	
+#ifdef BROKEN_GRAPHICS_PROGRAMS
+	/*
+	 * All fonts are loaded in slot 0 (0:1 for 512 ch)
+	 */
+
+	if (!arg)
+		return -EINVAL;		/* Return to default font not supported */
+
+	vga_font_is_default = 0;
+	font_select = ch512 ? 0x04 : 0x00;
+#else	
+	/*
+	 * The default font is kept in slot 0 and is never touched.
+	 * A custom font is loaded in slot 2 (256 ch) or 2:3 (512 ch)
+	 */
+
+	if (set) {
+		vga_font_is_default = !arg;
+		if (!arg)
+			ch512 = 0;		/* Default font is always 256 */
+		font_select = arg ? (ch512 ? 0x0e : 0x0a) : 0x00;
+	}
+
+	if ( !vga_font_is_default )
+		charmap += 4*cmapsz;
+#endif
+
+	spin_lock_irq(&vga_lock);
+	outb_p( 0x00, seq_port_reg );   /* First, the sequencer */
+	outb_p( 0x01, seq_port_val );   /* Synchronous reset */
+	outb_p( 0x02, seq_port_reg );
+	outb_p( 0x04, seq_port_val );   /* CPU writes only to map 2 */
+	outb_p( 0x04, seq_port_reg );
+	outb_p( 0x07, seq_port_val );   /* Sequential addressing */
+	outb_p( 0x00, seq_port_reg );
+	outb_p( 0x03, seq_port_val );   /* Clear synchronous reset */
+
+	outb_p( 0x04, gr_port_reg );    /* Now, the graphics controller */
+	outb_p( 0x02, gr_port_val );    /* select map 2 */
+	outb_p( 0x05, gr_port_reg );
+	outb_p( 0x00, gr_port_val );    /* disable odd-even addressing */
+	outb_p( 0x06, gr_port_reg );
+	outb_p( 0x00, gr_port_val );    /* map start at A000:0000 */
+	spin_unlock_irq(&vga_lock);
+	
+	if (arg) {
+		if (set)
+			for (i=0; i<cmapsz ; i++)
+				vga_writeb(arg[i], charmap + i);
+		else
+			for (i=0; i<cmapsz ; i++)
+				arg[i] = vga_readb(charmap + i);
+
+		/*
+		 * In 512-character mode, the character map is not contiguous if
+		 * we want to remain EGA compatible -- which we do
+		 */
+
+		if (ch512) {
+			charmap += 2*cmapsz;
+			arg += cmapsz;
+			if (set)
+				for (i=0; i<cmapsz ; i++)
+					vga_writeb(arg[i], charmap+i);
+			else
+				for (i=0; i<cmapsz ; i++)
+					arg[i] = vga_readb(charmap+i);
+		}
+	}
+	
+	spin_lock_irq(&vga_lock);
+	outb_p( 0x00, seq_port_reg );   /* First, the sequencer */
+	outb_p( 0x01, seq_port_val );   /* Synchronous reset */
+	outb_p( 0x02, seq_port_reg );
+	outb_p( 0x03, seq_port_val );   /* CPU writes to maps 0 and 1 */
+	outb_p( 0x04, seq_port_reg );
+	outb_p( 0x03, seq_port_val );   /* odd-even addressing */
+	if (set) {
+		outb_p( 0x03, seq_port_reg ); /* Character Map Select */
+		outb_p( font_select, seq_port_val );
+	}
+	outb_p( 0x00, seq_port_reg );
+	outb_p( 0x03, seq_port_val );   /* clear synchronous reset */
+
+	outb_p( 0x04, gr_port_reg );    /* Now, the graphics controller */
+	outb_p( 0x00, gr_port_val );    /* select map 0 for CPU */
+	outb_p( 0x05, gr_port_reg );
+	outb_p( 0x10, gr_port_val );    /* enable even-odd addressing */
+	outb_p( 0x06, gr_port_reg );
+	outb_p( beg, gr_port_val );     /* map starts at b800:0 or b000:0 */
+
+	/* if 512 char mode is already enabled don't re-enable it. */
+	if ((set)&&(ch512!=vga_512_chars)) {	/* attribute controller */
+		int i;
+		for(i=0; i<MAX_NR_CONSOLES; i++) {
+			struct vc_data *c = vc_cons[i].d;
+			if (c && c->vc_sw == &vga_con)
+				c->vc_hi_font_mask = ch512 ? 0x0800 : 0;
+		}
+		vga_512_chars=ch512;
+		/* 256-char: enable intensity bit
+		   512-char: disable intensity bit */
+		inb_p( video_port_status );	/* clear address flip-flop */
+		outb_p ( 0x12, attrib_port ); /* color plane enable register */
+		outb_p ( ch512 ? 0x07 : 0x0f, attrib_port );
+		/* Wilton (1987) mentions the following; I don't know what
+		   it means, but it works, and it appears necessary */
+		inb_p( video_port_status );
+		outb_p ( 0x20, attrib_port );
+	}
+	spin_unlock_irq(&vga_lock);
+	return 0;
+}
+
+/*
+ * Adjust the screen to fit a font of a certain height
+ */
+static int
+vgacon_adjust_height(unsigned fontheight)
+{
+	unsigned char ovr, vde, fsr;
+	int rows, maxscan, i;
+
+	if (fontheight == vga_video_font_height)
+		return 0;
+
+	vga_video_font_height = video_font_height = fontheight;
+
+	rows = video_scan_lines/fontheight;	/* Number of video rows we end up with */
+	maxscan = rows*fontheight - 1;		/* Scan lines to actually display-1 */
+
+	/* Reprogram the CRTC for the new font size
+	   Note: the attempt to read the overflow register will fail
+	   on an EGA, but using 0xff for the previous value appears to
+	   be OK for EGA text modes in the range 257-512 scan lines, so I
+	   guess we don't need to worry about it.
+
+	   The same applies for the spill bits in the font size and cursor
+	   registers; they are write-only on EGA, but it appears that they
+	   are all don't care bits on EGA, so I guess it doesn't matter. */
+
+	spin_lock_irq(&vga_lock);
+	outb_p( 0x07, vga_video_port_reg );		/* CRTC overflow register */
+	ovr = inb_p(vga_video_port_val);
+	outb_p( 0x09, vga_video_port_reg );		/* Font size register */
+	fsr = inb_p(vga_video_port_val);
+	spin_unlock_irq(&vga_lock);
+
+	vde = maxscan & 0xff;			/* Vertical display end reg */
+	ovr = (ovr & 0xbd) +			/* Overflow register */
+	      ((maxscan & 0x100) >> 7) +
+	      ((maxscan & 0x200) >> 3);
+	fsr = (fsr & 0xe0) + (fontheight-1);    /*  Font size register */
+
+	spin_lock_irq(&vga_lock);
+	outb_p( 0x07, vga_video_port_reg );		/* CRTC overflow register */
+	outb_p( ovr, vga_video_port_val );
+	outb_p( 0x09, vga_video_port_reg );		/* Font size */
+	outb_p( fsr, vga_video_port_val );
+	outb_p( 0x12, vga_video_port_reg );		/* Vertical display limit */
+	outb_p( vde, vga_video_port_val );
+	spin_unlock_irq(&vga_lock);	
+
+	for (i = 0; i < MAX_NR_CONSOLES; i++) {
+		struct vc_data *c = vc_cons[i].d;
+
+		if (c && c->vc_sw == &vga_con)
+			vc_resize(c->vc_num, 0, rows);	/* Adjust console size */
+	}
+	return 0;
+}
+
+static int vgacon_font_op(struct vc_data *c, struct console_font_op *op)
+{
+	int rc;
+
+	if (vga_video_type < VIDEO_TYPE_EGAM)
+		return -EINVAL;
+
+	if (op->op == KD_FONT_OP_SET) {
+		if (op->width != 8 || (op->charcount != 256 && op->charcount != 512))
+			return -EINVAL;
+		rc = vgacon_do_font_op(op->data, 1, op->charcount == 512);
+		if (!rc && !(op->flags & KD_FONT_FLAG_DONT_RECALC))
+			rc = vgacon_adjust_height(op->height);
+	} else if (op->op == KD_FONT_OP_GET) {
+		op->width = 8;
+		op->height = vga_video_font_height;
+		op->charcount = vga_512_chars ? 512 : 256;
+		if (!op->data) return 0;
+		rc = vgacon_do_font_op(op->data, 0, 0);
+	} else
+		rc = -ENOSYS;
+	return rc;
+}
+
+#else
+
+static int vgacon_font_op(struct vc_data *c, struct console_font_op *op)
+{
+	return -ENOSYS;
+}
+
+#endif
+
+static int vgacon_scrolldelta(struct vc_data *c, int lines)
+{
+	if (!lines)			/* Turn scrollback off */
+		c->vc_visible_origin = c->vc_origin;
+	else {
+		int vram_size = vga_vram_end - vga_vram_base;
+		int margin = c->vc_size_row * 4;
+		int ul, we, p, st;
+
+		if (vga_rolled_over > (c->vc_scr_end - vga_vram_base) + margin) {
+			ul = c->vc_scr_end - vga_vram_base;
+			we = vga_rolled_over + c->vc_size_row;
+		} else {
+			ul = 0;
+			we = vram_size;
+		}
+		p = (c->vc_visible_origin - vga_vram_base - ul + we) % we + lines * c->vc_size_row;
+		st = (c->vc_origin - vga_vram_base - ul + we) % we;
+		if (p < margin)
+			p = 0;
+		if (p > st - margin)
+			p = st;
+		c->vc_visible_origin = vga_vram_base + (p + ul) % we;
+	}
+	vga_set_mem_top(c);
+	return 1;
+}
+
+static int vgacon_set_origin(struct vc_data *c)
+{
+	if (vga_is_gfx ||	/* We don't play origin tricks in graphic modes */
+	    (console_blanked && !vga_palette_blanked))	/* Nor we write to blanked screens */
+		return 0;
+	c->vc_origin = c->vc_visible_origin = vga_vram_base;
+	vga_set_mem_top(c);
+	vga_rolled_over = 0;
+	return 1;
+}
+
+static void vgacon_save_screen(struct vc_data *c)
+{
+	static int vga_bootup_console = 0;
+
+	if (!vga_bootup_console) {
+		/* This is a gross hack, but here is the only place we can
+		 * set bootup console parameters without messing up generic
+		 * console initialization routines.
+		 */
+		vga_bootup_console = 1;
+		c->vc_x = ORIG_X;
+		c->vc_y = ORIG_Y;
+	}
+	if (!vga_is_gfx)
+		scr_memcpyw((u16 *) c->vc_screenbuf, (u16 *) c->vc_origin, c->vc_screenbuf_size);
+}
+
+static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
+{
+	unsigned long oldo;
+	unsigned int delta;
+	
+	if (t || b != c->vc_rows || vga_is_gfx)
+		return 0;
+
+	if (c->vc_origin != c->vc_visible_origin)
+		vgacon_scrolldelta(c, 0);
+
+	if (!vga_hardscroll_enabled || lines >= c->vc_rows/2)
+		return 0;
+
+	oldo = c->vc_origin;
+	delta = lines * c->vc_size_row;
+	if (dir == SM_UP) {
+		if (c->vc_scr_end + delta >= vga_vram_end) {
+			scr_memcpyw((u16 *)vga_vram_base,
+				    (u16 *)(oldo + delta),
+				    c->vc_screenbuf_size - delta);
+			c->vc_origin = vga_vram_base;
+			vga_rolled_over = oldo - vga_vram_base;
+		} else
+			c->vc_origin += delta;
+		scr_memsetw((u16 *)(c->vc_origin + c->vc_screenbuf_size - delta), c->vc_video_erase_char, delta);
+	} else {
+		if (oldo - delta < vga_vram_base) {
+			scr_memmovew((u16 *)(vga_vram_end - c->vc_screenbuf_size + delta),
+				     (u16 *)oldo,
+				     c->vc_screenbuf_size - delta);
+			c->vc_origin = vga_vram_end - c->vc_screenbuf_size;
+			vga_rolled_over = 0;
+		} else
+			c->vc_origin -= delta;
+		c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;
+		scr_memsetw((u16 *)(c->vc_origin), c->vc_video_erase_char, delta);
+	}
+	c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;
+	c->vc_visible_origin = c->vc_origin;
+	vga_set_mem_top(c);
+	c->vc_pos = (c->vc_pos - oldo) + c->vc_origin;
+	return 1;
+}
+
+
+/*
+ *  The console `switch' structure for the VGA based console
+ */
+
+static int vgacon_dummy(struct vc_data *c)
+{
+	return 0;
+}
+
+#define DUMMY (void *) vgacon_dummy
+
+const struct consw vga_con = {
+	.con_startup =		vgacon_startup,
+	.con_init =		vgacon_init,
+	.con_deinit =		vgacon_deinit,
+	.con_clear =		DUMMY,
+	.con_putc =		DUMMY,
+	.con_putcs =		DUMMY,
+	.con_cursor =		vgacon_cursor,
+	.con_scroll =		vgacon_scroll,
+	.con_bmove =		DUMMY,
+	.con_switch =		vgacon_switch,
+	.con_blank =		vgacon_blank,
+	.con_font_op =		vgacon_font_op,
+	.con_set_palette =	vgacon_set_palette,
+	.con_scrolldelta =	vgacon_scrolldelta,
+	.con_set_origin =	vgacon_set_origin,
+	.con_save_screen =	vgacon_save_screen,
+	.con_build_attr =	vgacon_build_attr,
+	.con_invert_region =	vgacon_invert_region,
+};
+
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/controlfb.c b/drivers/video/controlfb.c
--- a/drivers/video/controlfb.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/video/controlfb.c	Mon Dec  9 18:46:35 2002
@@ -96,13 +96,11 @@
 }
 
 struct fb_info_control {
-	struct fb_info			info;
-	struct display			display;
-	struct fb_par_control		par;
-	struct {
-		__u8 red, green, blue;
-	}			palette[256];
-	
+	struct fb_info		info;
+	struct display		display; /* Will disappear */
+	struct fb_par_control	par;
+	u32			pseudo_palette[17];
+		
 	struct cmap_regs	*cmap_regs;
 	unsigned long		cmap_regs_phys;
 	
@@ -118,14 +116,6 @@
 	int			control_use_bank2;
 	unsigned long		total_vram;
 	unsigned char		vram_attr;
-	union {
-#ifdef FBCON_HAS_CFB16
-		u16 cfb16[16];
-#endif
-#ifdef FBCON_HAS_CFB32
-		u32 cfb32[16];
-#endif
-	} fbcon_cmap;
 };
 
 /* control register access macro */
@@ -136,33 +126,15 @@
 /*
  * struct fb_ops
  */
-static int control_get_fix(struct fb_fix_screeninfo *fix, int con,
-	struct fb_info *info);
-static int control_get_var(struct fb_var_screeninfo *var, int con,
-	struct fb_info *info);
-static int control_set_var(struct fb_var_screeninfo *var, int con,
-	struct fb_info *info);
-static int control_pan_display(struct fb_var_screeninfo *var, int con,
-	struct fb_info *info);
-static int control_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+static int controlfb_pan_display(struct fb_var_screeninfo *var, int con,
 	struct fb_info *info);
 static int controlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 	u_int transp, struct fb_info *info);
 static int controlfb_blank(int blank_mode, struct fb_info *info);
-static int control_mmap(struct fb_info *info, struct file *file,
+static int controlfb_mmap(struct fb_info *info, struct file *file,
 	struct vm_area_struct *vma);
-
-/*
- * low level fbcon ops
- */
-static int controlfb_switch(int con, struct fb_info *info);
-static int controlfb_updatevar(int con, struct fb_info *info);
-
-/*
- * low level cmap set/get ops
- */
-static int controlfb_getcolreg(u_int regno, u_int *red, u_int *green,
-	u_int *blue, u_int *transp, struct fb_info *info);
+static int controlfb_set_par (struct fb_info *info);
+static int controlfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info);
 
 /*
  * inititialization
@@ -170,13 +142,6 @@
 int control_init(void);
 void control_setup(char *);
 
-/*
- * low level fbcon revc ops
- */
-static void control_cfb16_revc(struct display *p, int xx, int yy);
-static void control_cfb32_revc(struct display *p, int xx, int yy);
-
-
 /******************** Prototypes for internal functions **********************/
 
 static void set_control_clock(unsigned char *params);
@@ -184,10 +149,6 @@
 static void control_set_hardware(struct fb_info_control *p,
 	struct fb_par_control *par);
 static int control_of_init(struct device_node *dp);
-static void control_par_to_fix(struct fb_par_control *par,
-	struct fb_fix_screeninfo *fix, struct fb_info_control *p);
-static void control_set_dispsw(struct display *disp, int cmode,
-	struct fb_info_control *p);
 static void find_vram_size(struct fb_info_control *p);
 static int read_control_sense(struct fb_info_control *p);
 static int calc_clock_params(unsigned long clk, unsigned char *param);
@@ -195,13 +156,6 @@
 	struct fb_par_control *par, const struct fb_info *fb_info);
 static inline void control_par_to_var(struct fb_par_control *par,
 	struct fb_var_screeninfo *var);
-static void control_par_to_fix(struct fb_par_control *par,
-	struct fb_fix_screeninfo *fix, struct fb_info_control *p);
-static void control_par_to_display(struct fb_par_control *par,
-	struct display *disp, struct fb_fix_screeninfo *fix,
-	struct fb_info_control *p);
-static void control_set_dispsw(struct display *disp, int cmode,
-	struct fb_info_control *p);
 static void control_init_info(struct fb_info *info, struct fb_info_control *p);
 static void control_cleanup(void);
 
@@ -216,16 +170,19 @@
 
 
 static struct fb_ops controlfb_ops = {
-	.owner =	THIS_MODULE,
-	.fb_get_fix =	control_get_fix,
-	.fb_get_var =	control_get_var,
-	.fb_set_var =	control_set_var,
-	.fb_get_cmap =	control_get_cmap,
-	.fb_set_cmap =	gen_set_cmap,
-	.fb_setcolreg =	controlfb_setcolreg,
-	.fb_pan_display =control_pan_display,
-	.fb_blank =	controlfb_blank,
-	.fb_mmap =	control_mmap,
+	.owner		= THIS_MODULE,
+	.fb_set_var	= gen_set_var,
+	.fb_check_var	= controlfb_check_var,
+	.fb_set_par	= controlfb_set_par,
+	.fb_get_cmap	= gen_get_cmap,
+	.fb_set_cmap	= gen_set_cmap,
+	.fb_setcolreg	= controlfb_setcolreg,
+	.fb_pan_display = controlfb_pan_display,
+	.fb_blank	= controlfb_blank,
+	.fb_mmap	= controlfb_mmap,
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit,
 };
 
 
@@ -251,87 +208,48 @@
 }
 #endif
 
-/*********** Providing our information to the user ************/
-
-static int control_get_fix(struct fb_fix_screeninfo *fix, int con,
-			 struct fb_info *info)
+/*
+ * Checks a var structure
+ */
+static int controlfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info)
 {
-	struct fb_info_control *p = (struct fb_info_control *) info;
-
-	if(con == -1) {
-		control_par_to_fix(&p->par, fix, p);
-	} else {
-		struct fb_par_control par;
-		
-		control_var_to_par(&fb_display[con].var, &par, info);
-		control_par_to_fix(&par, fix, p);
-	}
-	return 0;
-}
+	struct fb_par_control par;
+	int err;
 
-static int control_get_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *info)
-{
-	struct fb_info_control *p = (struct fb_info_control *) info;
+	err = control_var_to_par(var, &par, info);
+	if (err)
+		return err;	
+	control_par_to_var(&par, var);
 
-	if(con == -1) {
-		control_par_to_var(&p->par, var);
-	} else {
-		*var = fb_display[con].var;
-	}
 	return 0;
 }
 
-
 /*
- * Sets everything according to var
+ * Applies current var to display
  */
-static int control_set_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *info)
+static int controlfb_set_par (struct fb_info *info)
 {
 	struct fb_info_control *p = (struct fb_info_control *) info;
-	struct display *disp;
 	struct fb_par_control par;
-	int depthchange, err;
-	int activate = var->activate;
+	int err;
 
-	if((err = control_var_to_par(var, &par, info))) {
-		if (con < 0)
-			printk (KERN_ERR "control_set_var: error calling"
-					 " control_var_to_par: %d.\n", err);
+	if((err = control_var_to_par(&info->var, &par, info))) {
+		printk (KERN_ERR "controlfb_set_par: error calling"
+				 " control_var_to_par: %d.\n", err);
 		return err;
 	}
 	
-	control_par_to_var(&par, var);
-	
-	if ((activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW)
-		return 0;
-
-	disp = (con >= 0) ? &fb_display[con] : info->disp;
-
-	depthchange = (disp->var.bits_per_pixel != var->bits_per_pixel);
-	if(!VAR_MATCH(&disp->var, var)) {
-		struct fb_fix_screeninfo	fix;
-		control_par_to_fix(&par, &fix, p);
-		control_par_to_display(&par, disp, &fix, p);
-		if(info->changevar)
-			(*info->changevar)(con);
-	} else
-		disp->var = *var;
+	control_set_hardware(p, &par);
 
-	if (con == info->currcon) {
-		control_set_hardware(p, &par);
-		if(depthchange) {
-			if((err = fb_alloc_cmap(&disp->cmap, 0, 0)))
-				return err;
-			do_install_cmap(con, info);
-		}
-	}
+	info->fix.visual = (p->par.cmode == CMODE_8) ?
+		FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
+	info->fix.line_length = p->par.pitch;
+	info->fix.xpanstep = 32 >> p->par.cmode;
+	info->fix.ypanstep = 1;
 
 	return 0;
 }
 
-
 /*
  * Set screen start address according to var offset values
  */
@@ -347,7 +265,7 @@
 }
 
 
-static int control_pan_display(struct fb_var_screeninfo *var, int con,
+static int controlfb_pan_display(struct fb_var_screeninfo *var, int con,
 			     struct fb_info *info)
 {
 	unsigned int xoffset, hstep;
@@ -369,48 +287,30 @@
 	return 0;
 }
 
-static int control_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, controlfb_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;
-}
 
 /*
  * Private mmap since we want to have a different caching on the framebuffer
  * for controlfb.
  * Note there's no locking in here; it's done in fb_mmap() in fbmem.c.
  */
-static int control_mmap(struct fb_info *info, struct file *file,
+static int controlfb_mmap(struct fb_info *info, struct file *file,
                        struct vm_area_struct *vma)
 {
-       struct fb_ops *fb = info->fbops;
-       struct fb_fix_screeninfo fix;
-       struct fb_var_screeninfo var;
        unsigned long off, start;
        u32 len;
 
-       fb->fb_get_fix(&fix, PROC_CONSOLE(info), info);
        off = vma->vm_pgoff << PAGE_SHIFT;
 
        /* frame buffer memory */
-       start = fix.smem_start;
-       len = PAGE_ALIGN((start & ~PAGE_MASK)+fix.smem_len);
+       start = info->fix.smem_start;
+       len = PAGE_ALIGN((start & ~PAGE_MASK)+info->fix.smem_len);
        if (off >= len) {
                /* memory mapped io */
                off -= len;
-               fb->fb_get_var(&var, PROC_CONSOLE(info), info);
-               if (var.accel_flags)
+               if (info->var.accel_flags)
                        return -EINVAL;
-               start = fix.mmio_start;
-               len = PAGE_ALIGN((start & ~PAGE_MASK)+fix.mmio_len);
+               start = info->fix.mmio_start;
+               len = PAGE_ALIGN((start & ~PAGE_MASK)+info->fix.mmio_len);
                pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE|_PAGE_GUARDED;
        } else {
                /* framebuffer */
@@ -428,44 +328,6 @@
        return 0;
 }
 
-
-/********************  End of controlfb_ops implementation  ******************/
-
-/*
- * low level fbcon ops
- */
-
-static int controlfb_switch(int con, struct fb_info *info)
-{
-	struct fb_info_control	*p = (struct fb_info_control *)info;
-	struct fb_par_control	par;
-
-	if (info->currcon >= 0 && fb_display[info->currcon].cmap.len)
-		fb_get_cmap(&fb_display[info->currcon].cmap, 1, controlfb_getcolreg,
-			    info);
-	info->currcon = con;
-
-	fb_display[con].var.activate = FB_ACTIVATE_NOW;
-	control_var_to_par(&fb_display[con].var, &par, info);
-	control_set_hardware(p, &par);
-	control_set_dispsw(&fb_display[con], par.cmode, p);
-	do_install_cmap(con, info);
-
-	return 1;
-}
-
-
-static int controlfb_updatevar(int con, struct fb_info *info)
-{
-	struct fb_var_screeninfo *var = &fb_display[con].var;
-	struct fb_info_control *p = (struct fb_info_control *) info;
-
-	set_screen_start(var->xoffset, var->yoffset, p);
-
-	return 0;
-}
-
-
 static int controlfb_blank(int blank_mode, struct fb_info *info)
 {
 	struct fb_info_control *p = (struct fb_info_control *) info;
@@ -498,30 +360,10 @@
 	return 0;
 }
 
-
-/*
- * low level cmap set/get ops
- */
-
-static int controlfb_getcolreg(u_int regno, u_int *red, u_int *green,
-			     u_int *blue, u_int *transp, struct fb_info *info)
-{
-	struct fb_info_control *p = (struct fb_info_control *) info;
-
-	if (regno > 255)
-		return 1;
-	*red = (p->palette[regno].red<<8) | p->palette[regno].red;
-	*green = (p->palette[regno].green<<8) | p->palette[regno].green;
-	*blue = (p->palette[regno].blue<<8) | p->palette[regno].blue;
-	*transp = 0;
-	return 0;
-}
-
 static int controlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 			     u_int transp, struct fb_info *info)
 {
 	struct fb_info_control *p = (struct fb_info_control *) info;
-	u_int i;
 	__u8 r, g, b;
 
 	if (regno > 255)
@@ -531,32 +373,34 @@
 	g = green >> 8;
 	b = blue >> 8;
 
-	p->palette[regno].red = r;
-	p->palette[regno].green = g;
-	p->palette[regno].blue = b;
-
 	out_8(&p->cmap_regs->addr, regno);	/* tell clut what addr to fill	*/
 	out_8(&p->cmap_regs->lut, r);		/* send one color channel at	*/
 	out_8(&p->cmap_regs->lut, g);		/* a time...			*/
 	out_8(&p->cmap_regs->lut, b);
 
-	if (regno < 16)
+	if (regno < 16) {
+		int i;
 		switch (p->par.cmode) {
-#ifdef FBCON_HAS_CFB16
-			case CMODE_16:
-				p->fbcon_cmap.cfb16[regno] = (regno << 10) | (regno << 5) | regno;
-				break;
-#endif
-#ifdef FBCON_HAS_CFB32
-			case CMODE_32:
-				i = (regno << 8) | regno;
-				p->fbcon_cmap.cfb32[regno] = (i << 16) | i;
-				break;
-#endif
+		case CMODE_16:
+			((u16 *) (info->pseudo_palette))[regno] =
+			    (regno << 10) | (regno << 5) | regno;
+			break;
+		case CMODE_32:
+			i = (regno << 8) | regno;
+			((u32 *) (info->pseudo_palette))[regno] =
+			    (i << 16) | i;
+			break;
 		}
+	}
+
 	return 0;
 }
 
+
+/********************  End of controlfb_ops implementation  ******************/
+
+
+
 static void set_control_clock(unsigned char *params)
 {
 #ifdef CONFIG_ADB_CUDA
@@ -580,7 +424,8 @@
 {
 	int full, sense, vmode, cmode, vyres;
 	struct fb_var_screeninfo var;
-
+	int rc;
+	
 	printk(KERN_INFO "controlfb: ");
 
 	full = p->total_vram == 0x400000;
@@ -613,6 +458,10 @@
 		}
 	}
 
+	/* Initialize info structure */
+	control_init_info(&p->info, p);
+
+	/* Setup default var */
 	if (mac_vmode_to_var(vmode, cmode, &var) < 0) {
 		/* This shouldn't happen! */
 		printk("mac_vmode_to_var(%d, %d,) failed\n", vmode, cmode);
@@ -631,18 +480,14 @@
 	if (vyres > var.yres)
 		var.yres_virtual = vyres;
 
-	control_init_info(&p->info, p);
-	p->info.currcon = -1;
+	/* Apply default var */
+	p->info.var = var;
 	var.activate = FB_ACTIVATE_NOW;
+	rc = gen_set_var(&var, -1, &p->info);
+	if (rc && (vmode != VMODE_640_480_60 || cmode != CMODE_8))
+		goto try_again;
 
-	if (control_set_var(&var, -1, &p->info) < 0) {
-		if (vmode != VMODE_640_480_60 || cmode != CMODE_8)
-			goto try_again;
-		printk(KERN_ERR "controlfb: initilization failed\n");
-		return -ENXIO;
-	}
-
-	p->info.flags = FBINFO_FLAG_DEFAULT;
+	/* Register with fbdev layer */
 	if (register_framebuffer(&p->info) < 0)
 		return -ENXIO;
 	
@@ -820,7 +665,7 @@
 		printk(KERN_ERR "expecting 2 address for control (got %d)", dp->n_addrs);
 		return -ENXIO;
 	}
-	p = kmalloc(sizeof(*p), GFP_ATOMIC);
+	p = kmalloc(sizeof(*p), GFP_KERNEL);
 	if (p == 0)
 		return -ENXIO;
 	control_fb = p;	/* save it for cleanups */
@@ -1164,171 +1009,41 @@
 	var->pixclock >>= par->regvals.clock_params[2];
 }
 
-
-/*
- * init fix according to given par
- */
-static void control_par_to_fix(struct fb_par_control *par, struct fb_fix_screeninfo *fix,
-	struct fb_info_control *p)
-{
-	memset(fix, 0, sizeof(*fix));
-	strcpy(fix->id, "control");
-	fix->mmio_start = p->control_regs_phys;
-	fix->mmio_len = sizeof(struct control_regs);
-	fix->type = FB_TYPE_PACKED_PIXELS;
-	
-	fix->xpanstep = 32 >> par->cmode;
-	fix->ypanstep = 1;
-
-	fix->smem_start = p->frame_buffer_phys + CTRLFB_OFF;
-	fix->smem_len = p->total_vram - CTRLFB_OFF;
-	fix->visual = (par->cmode == CMODE_8) ?
-		FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
-	fix->line_length = par->pitch;
-}
-
-/*
- * initialize a portion of struct display which low level driver is responsible
- * for.
- */
-static void control_par_to_display(struct fb_par_control *par,
-  struct display *disp, struct fb_fix_screeninfo *fix, struct fb_info_control *p)
-{
-	disp->type = fix->type;
-	disp->can_soft_blank = 1;
-	disp->scrollmode = SCROLL_YNOMOVE | SCROLL_YNOPARTIAL;
-	disp->ypanstep = fix->ypanstep;
-	disp->ywrapstep = fix->ywrapstep;
-
-	control_par_to_var(par, &disp->var);
-	p->info.screen_base = (char *) p->frame_buffer + CTRLFB_OFF;
-	disp->visual = fix->visual;
-	disp->line_length = fix->line_length;
-	control_set_dispsw(disp, par->cmode, p);
-}
-
-
-/*
- * our own _revc() routines since generic routines don't work for DIRECT Color
- * devices like control
- */
-static void control_cfb16_revc(struct display *p, int xx, int yy)
-{
-    u8 *dest;
-    int bytes = p->next_line, rows;
-
-    dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p)*2;
-    for (rows = fontheight(p); rows--; dest += bytes) {
-       switch (fontwidth(p)) {
-       case 16:
-           ((u32 *)dest)[6] ^= 0x3def3def; ((u32 *)dest)[7] ^= 0x3def3def;
-           /* FALL THROUGH */
-       case 12:
-           ((u32 *)dest)[4] ^= 0x3def3def; ((u32 *)dest)[5] ^= 0x3def3def;
-           /* FALL THROUGH */
-       case 8:
-           ((u32 *)dest)[2] ^= 0x3def3def; ((u32 *)dest)[3] ^= 0x3def3def;
-           /* FALL THROUGH */
-       case 4:
-           ((u32 *)dest)[0] ^= 0x3def3def; ((u32 *)dest)[1] ^= 0x3def3def;
-       }
-    }
-}
-
-static void control_cfb32_revc(struct display *p, int xx, int yy)
-{
-    u8 *dest;
-    int bytes = p->next_line, rows;
-
-    dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 4;
-    for (rows = fontheight(p); rows--; dest += bytes) {
-       switch (fontwidth(p)) {
-       case 16:
-           ((u32 *)dest)[12] ^= 0x0f0f0f0f; ((u32 *)dest)[13] ^= 0x0f0f0f0f;
-           ((u32 *)dest)[14] ^= 0x0f0f0f0f; ((u32 *)dest)[15] ^= 0x0f0f0f0f;
-           /* FALL THROUGH */
-       case 12:
-           ((u32 *)dest)[8] ^= 0x0f0f0f0f; ((u32 *)dest)[9] ^= 0x0f0f0f0f;
-           ((u32 *)dest)[10] ^= 0x0f0f0f0f; ((u32 *)dest)[11] ^= 0x0f0f0f0f;
-           /* FALL THROUGH */
-       case 8:
-           ((u32 *)dest)[4] ^= 0x0f0f0f0f; ((u32 *)dest)[5] ^= 0x0f0f0f0f;
-           ((u32 *)dest)[6] ^= 0x0f0f0f0f; ((u32 *)dest)[7] ^= 0x0f0f0f0f;
-           /* FALL THROUGH */
-       case 4:
-           ((u32 *)dest)[0] ^= 0x0f0f0f0f; ((u32 *)dest)[1] ^= 0x0f0f0f0f;
-           ((u32 *)dest)[2] ^= 0x0f0f0f0f; ((u32 *)dest)[3] ^= 0x0f0f0f0f;
-           /* FALL THROUGH */
-       }
-    }
-}
-
-static struct display_switch control_cfb16 = {
-    setup:		fbcon_cfb16_setup,
-    bmove:		fbcon_cfb16_bmove,
-    clear:		fbcon_cfb16_clear,
-    putc:		fbcon_cfb16_putc,
-    putcs:		fbcon_cfb16_putcs,
-    revc:		control_cfb16_revc,
-    clear_margins:	fbcon_cfb16_clear_margins,
-    fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-
-static struct display_switch control_cfb32 = {
-    setup:		fbcon_cfb32_setup,
-    bmove:		fbcon_cfb32_bmove,
-    clear:		fbcon_cfb32_clear,
-    putc:		fbcon_cfb32_putc,
-    putcs:		fbcon_cfb32_putcs,
-    revc:		control_cfb32_revc,
-    clear_margins:	fbcon_cfb32_clear_margins,
-    fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-
-
-/*
- * Set struct dispsw according to given cmode
- */
-static void control_set_dispsw(struct display *disp, int cmode, struct fb_info_control *p)
-{
-	switch (cmode) {
-#ifdef FBCON_HAS_CFB8
-		case CMODE_8:
-			disp->dispsw = &fbcon_cfb8;
-			break;
-#endif
-#ifdef FBCON_HAS_CFB16
-		case CMODE_16:
-			disp->dispsw = &control_cfb16;
-			disp->dispsw_data = p->fbcon_cmap.cfb16;
-			break;
-#endif
-#ifdef FBCON_HAS_CFB32
-		case CMODE_32:
-			disp->dispsw = &control_cfb32;
-			disp->dispsw_data = p->fbcon_cmap.cfb32;
-			break;
-#endif
-		default:
-			disp->dispsw = &fbcon_dummy;
-			break;
-	}
-}
-
-
 /*
  * Set misc info vars for this driver
  */
 static void __init control_init_info(struct fb_info *info, struct fb_info_control *p)
 {
+	/* Fill fb_info */
 	strcpy(info->modename, "control");
+	info->currcon = -1;
+	info->par = &p->par;
 	info->node = NODEV;
 	info->fbops = &controlfb_ops;
 	info->disp = &p->display;
-	strcpy(info->fontname, fontname);
+	info->pseudo_palette = p->pseudo_palette;
+        info->flags = FBINFO_FLAG_DEFAULT;
+        strncpy (info->fontname, fontname, sizeof (info->fontname));
+        info->fontname[sizeof (info->fontname) - 1] = 0;
 	info->changevar = NULL;
-	info->switch_con = &controlfb_switch;
-	info->updatevar = &controlfb_updatevar;
+        info->display_fg = NULL;
+	info->screen_base = (char *) p->frame_buffer + CTRLFB_OFF;
+	info->changevar  = NULL;
+	info->switch_con = gen_switch;
+	info->updatevar  = gen_update_var;
+
+	fb_alloc_cmap(&info->cmap, 256, 0);
+
+	/* Fill fix common fields */
+	strcpy(info->fix.id, "control");
+	info->fix.mmio_start = p->control_regs_phys;
+	info->fix.mmio_len = sizeof(struct control_regs);
+	info->fix.type = FB_TYPE_PACKED_PIXELS;
+	info->fix.smem_start = p->frame_buffer_phys + CTRLFB_OFF;
+	info->fix.smem_len = p->total_vram - CTRLFB_OFF;
+        info->fix.ywrapstep = 0;
+        info->fix.type_aux = 0;
+        info->fix.accel = FB_ACCEL_NONE;
 }
 
 
diff -Nru a/drivers/video/cyberfb.c b/drivers/video/cyberfb.c
--- a/drivers/video/cyberfb.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/video/cyberfb.c	Mon Dec  9 18:46:34 2002
@@ -1063,7 +1063,7 @@
 	    }
 
 	    printk("fb%d: %s frame buffer device, using %ldK of video memory\n",
-		   GET_FB_IDX(fb_info.node), fb_info.modename, CyberSize>>10);
+		   minor(fb_info.node), fb_info.modename, CyberSize>>10);
 
 	    /* TODO: This driver cannot be unloaded yet */
 	    MOD_INC_USE_COUNT;
diff -Nru a/drivers/video/dnfb.c b/drivers/video/dnfb.c
--- a/drivers/video/dnfb.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/video/dnfb.c	Mon Dec  9 18:46:35 2002
@@ -15,8 +15,6 @@
 #include <linux/fb.h>
 #include <linux/module.h>
 
-#include <video/fbcon.h>
-
 /* apollo video HW definitions */
 
 /*
@@ -111,7 +109,6 @@
 #endif
 
 static struct fb_info fb_info;
-static struct display disp;
 
 /* frame buffer operations */
 
@@ -120,13 +117,11 @@
 
 static struct fb_ops dn_fb_ops = {
 	.owner		= THIS_MODULE,
-	.fb_set_var	= gen_set_var,
-	.fb_get_cmap	= gen_get_cmap,
-	.fb_set_cmap	= gen_set_cmap,
 	.fb_blank	= dnfb_blank,
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= dnfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
+	.fb_cursor	= soft_cursor,
 };
 
 struct fb_var_screeninfo dnfb_var __initdata = {
@@ -239,22 +234,13 @@
 {
 	int err;
 
-	strcpy(fb_info.modename, dnfb_fix.id);
-	fb_info.changevar = NULL;
-	fb_info.fontname[0] = 0;
-	fb_info.disp = &disp;
-	fb_info.switch_con = gen_switch;
-	fb_info.updatevar = gen_update_var;
 	fb_info.node = NODEV;
 	fb_info.fbops = &dn_fb_ops;
-	fb_info.currcon = -1;
 	fb_info.fix = dnfb_fix;
 	fb_info.var = dnfb_var;
+	fb_info.screen_base = (u_char *) fb_info.fix.smem_start;
 
 	fb_alloc_cmap(&fb_info.cmap, 2, 0);
-	gen_set_disp(-1, &fb_info);
-
-	fb_info.screen_base = (u_char *) fb_info.fix.smem_start;
 
 	err = register_framebuffer(&fb_info);
 	if (err < 0)
diff -Nru a/drivers/video/dummycon.c b/drivers/video/dummycon.c
--- a/drivers/video/dummycon.c	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,74 +0,0 @@
-/*
- *  linux/drivers/video/dummycon.c -- A dummy console driver
- *
- *  To be used if there's no other console driver (e.g. for plain VGA text)
- *  available, usually until fbcon takes console over.
- */
-
-#include <linux/types.h>
-#include <linux/kdev_t.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/console_struct.h>
-#include <linux/vt_kern.h>
-#include <linux/init.h>
-
-/*
- *  Dummy console driver
- */
-
-#if defined(__arm__)
-#define DUMMY_COLUMNS	ORIG_VIDEO_COLS
-#define DUMMY_ROWS	ORIG_VIDEO_LINES
-#elif defined(__hppa__)
-#define DUMMY_COLUMNS	80	/* fixme ! (mine uses 160x64 at 1280x1024) */
-#define DUMMY_ROWS	25
-#else
-#define DUMMY_COLUMNS	80
-#define DUMMY_ROWS	25
-#endif
-
-static const char *dummycon_startup(void)
-{
-    return "dummy device";
-}
-
-static void dummycon_init(struct vc_data *conp, int init)
-{
-    conp->vc_can_do_color = 1;
-    if (init) {
-	conp->vc_cols = DUMMY_COLUMNS;
-	conp->vc_rows = DUMMY_ROWS;
-    } else
-	vc_resize_con(DUMMY_ROWS, DUMMY_COLUMNS, conp->vc_num);
-}
-
-static int dummycon_dummy(void)
-{
-    return 0;
-}
-
-#define DUMMY	(void *)dummycon_dummy
-
-/*
- *  The console `switch' structure for the dummy console
- *
- *  Most of the operations are dummies.
- */
-
-const struct consw dummy_con = {
-    .con_startup =	dummycon_startup,
-    .con_init =		dummycon_init,
-    .con_deinit =	DUMMY,
-    .con_clear =	DUMMY,
-    .con_putc =		DUMMY,
-    .con_putcs =	DUMMY,
-    .con_cursor =	DUMMY,
-    .con_scroll =	DUMMY,
-    .con_bmove =	DUMMY,
-    .con_switch =	DUMMY,
-    .con_blank =	DUMMY,
-    .con_font_op =	DUMMY,
-    .con_set_palette =	DUMMY,
-    .con_scrolldelta =	DUMMY,
-};
diff -Nru a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
--- a/drivers/video/epson1355fb.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/video/epson1355fb.c	Mon Dec  9 18:46:34 2002
@@ -517,7 +517,7 @@
 		do_install_cmap(0, &fb_info.gen);
 	if (register_framebuffer(&fb_info.gen.info) < 0)
 		return -EINVAL;
-	printk(KERN_INFO "fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.gen.info.node),
+	printk(KERN_INFO "fb%d: %s frame buffer device\n", minor(fb_info.gen.info.node),
 	       fb_info.gen.info.modename);
 
 	return 0;
diff -Nru a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
--- a/drivers/video/fbcmap.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/video/fbcmap.c	Mon Dec  9 18:46:50 2002
@@ -94,16 +94,7 @@
     int size = len*sizeof(u16);
 
     if (cmap->len != len) {
-	if (cmap->red)
-	    kfree(cmap->red);
-	if (cmap->green)
-	    kfree(cmap->green);
-	if (cmap->blue)
-	    kfree(cmap->blue);
-	if (cmap->transp)
-	    kfree(cmap->transp);
-	cmap->red = cmap->green = cmap->blue = cmap->transp = NULL;
-	cmap->len = 0;
+	fb_dealloc_cmap(cmap);
 	if (!len)
 	    return 0;
 	if (!(cmap->red = kmalloc(size, GFP_ATOMIC)))
@@ -124,6 +115,29 @@
     return 0;
 }
 
+/**
+ *      fb_dealloc_cmap - deallocate a colormap
+ *      @cmap: frame buffer colormap structure
+ *
+ *      Deallocates a colormap that was previously allocated with
+ *      fb_alloc_cmap().
+ *
+ */
+
+void fb_dealloc_cmap(struct fb_cmap *cmap)
+{
+	if (cmap->red)
+		kfree(cmap->red);
+	if (cmap->green)
+		kfree(cmap->green);
+	if (cmap->blue)
+		kfree(cmap->blue);
+	if (cmap->transp)
+		kfree(cmap->transp);
+
+	cmap->red = cmap->green = cmap->blue = cmap->transp = NULL;
+	cmap->len = 0;
+}
 
 /**
  *	fb_copy_cmap - copy a colormap
@@ -181,62 +195,6 @@
     }
 }
 
-
-/**
- *	fb_get_cmap - get a colormap
- *	@cmap: frame buffer colormap
- *	@kspc: boolean, 0 copy local, 1 put_user() function
- *	@getcolreg: pointer to a function to get a color register
- *	@info: frame buffer info structure
- *
- *	Get a colormap @cmap for a screen of device @info.
- *
- *	Returns negative errno on error, or zero on success.
- *
- */
-
-int fb_get_cmap(struct fb_cmap *cmap, int kspc,
-    	    	int (*getcolreg)(u_int, u_int *, u_int *, u_int *, u_int *,
-				 struct fb_info *),
-		struct fb_info *info)
-{
-    int i, start;
-    u16 *red, *green, *blue, *transp;
-    u_int hred, hgreen, hblue, htransp;
-
-    red = cmap->red;
-    green = cmap->green;
-    blue = cmap->blue;
-    transp = cmap->transp;
-    start = cmap->start;
-    if (start < 0)
-	return -EINVAL;
-    for (i = 0; i < cmap->len; i++) {
-	if (getcolreg(start++, &hred, &hgreen, &hblue, &htransp, info))
-	    return 0;
-	if (kspc) {
-	    *red = hred;
-	    *green = hgreen;
-	    *blue = hblue;
-	    if (transp)
-		*transp = htransp;
-	} else {
-	    put_user(hred, red);
-	    put_user(hgreen, green);
-	    put_user(hblue, blue);
-	    if (transp)
-		put_user(htransp, transp);
-	}
-	red++;
-	green++;
-	blue++;
-	if (transp)
-	    transp++;
-    }
-    return 0;
-}
-
-
 /**
  *	fb_set_cmap - set the colormap
  *	@cmap: frame buffer colormap structure
@@ -352,8 +310,8 @@
      */
 
 EXPORT_SYMBOL(fb_alloc_cmap);
+EXPORT_SYMBOL(fb_dealloc_cmap);
 EXPORT_SYMBOL(fb_copy_cmap);
-EXPORT_SYMBOL(fb_get_cmap);
 EXPORT_SYMBOL(fb_set_cmap);
 EXPORT_SYMBOL(fb_default_cmap);
 EXPORT_SYMBOL(fb_invert_cmaps);
diff -Nru a/drivers/video/fbcon-accel.c b/drivers/video/fbcon-accel.c
--- a/drivers/video/fbcon-accel.c	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,188 +0,0 @@
-/*
- *  linux/drivers/video/fbcon-accel.c -- Framebuffer accel console wrapper
- *
- *      Created 20 Feb 2001 by James Simmons <jsimmons@users.sf.net>
- *
- *  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 <video/fbcon.h>
-#include "fbcon-accel.h"
-
-void fbcon_accel_setup(struct display *p)
-{
-	p->next_line = p->fb_info->fix.line_length;
-	p->next_plane = 0;
-}
-
-void fbcon_accel_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;
-
-	area.sx = sx * fontwidth(p);
-	area.sy = sy * fontheight(p);
-	area.dx = dx * fontwidth(p);
-	area.dy = dy * fontheight(p);
-	area.height = height * fontheight(p);
-	area.width  = width * fontwidth(p);
-
-	info->fbops->fb_copyarea(info, &area);
-}
-
-void fbcon_accel_clear(struct vc_data *vc, struct display *p, int sy, int sx,
-		       int height, int width)
-{
-	struct fb_info *info = p->fb_info;
-	struct fb_fillrect region;
-
-	region.color = attr_bgcol_ec(p,vc);
-	region.dx = sx * fontwidth(p);
-	region.dy = sy * fontheight(p);
-	region.width = width * fontwidth(p);
-	region.height = height * fontheight(p);
-	region.rop = ROP_COPY;
-
-	info->fbops->fb_fillrect(info, &region);
-}
-
-void fbcon_accel_putc(struct vc_data *vc, struct display *p, int c, int yy,
-		      int xx)
-{
-	struct fb_info *info = p->fb_info;
-	unsigned short charmask = p->charmask;
-	unsigned int width = ((fontwidth(p)+7)>>3);
-	struct fb_image image;
-
-	image.fg_color = attr_fgcol(p, c);
-	image.bg_color = attr_bgcol(p, c);
-	image.dx = xx * fontwidth(p);
-	image.dy = yy * fontheight(p);
-	image.width = fontwidth(p);
-	image.height = fontheight(p);
-	image.depth = 1;
-	image.data = p->fontdata + (c & charmask)*fontheight(p)*width;
-
-	info->fbops->fb_imageblit(info, &image);
-}
-
-void fbcon_accel_putcs(struct vc_data *vc, struct display *p,
-		       const unsigned short *s, int count, int yy, int xx)
-{
-	struct fb_info *info = p->fb_info;
-	unsigned short charmask = p->charmask;
-	unsigned int width = ((fontwidth(p)+7)>>3);
-	struct fb_image image;
-
-	image.fg_color = attr_fgcol(p, *s);
-	image.bg_color = attr_bgcol(p, *s);
-	image.dx = xx * fontwidth(p);
-	image.dy = yy * fontheight(p);
-	image.width = fontwidth(p);
-	image.height = fontheight(p);
-	image.depth = 1;
-
-	while (count--) {
-		image.data = p->fontdata +
-			(scr_readw(s++) & charmask) * fontheight(p) * width;
-		info->fbops->fb_imageblit(info, &image);
-		image.dx += fontwidth(p);
-	}
-}
-
-void fbcon_accel_revc(struct display *p, int xx, int yy)
-{
-	struct fb_info *info = p->fb_info;
-	struct fb_fillrect region;
-
-	region.color = attr_fgcol_ec(p, p->conp);
-	region.dx = xx * fontwidth(p);
-	region.dy = yy * fontheight(p);
-	region.width  = fontwidth(p);
-	region.height = fontheight(p); 
-	region.rop = ROP_XOR;
-	
-	info->fbops->fb_fillrect(info, &region);
-}
-
-void fbcon_accel_clear_margins(struct vc_data *vc, struct display *p,
-			       int bottom_only)
-{
-	struct fb_info *info = p->fb_info;
-	unsigned int cw = fontwidth(p);
-	unsigned int ch = fontheight(p);
-	unsigned int rw = info->var.xres % cw;
-	unsigned int bh = info->var.yres % ch;
-	unsigned int rs = info->var.xres - rw;
-	unsigned int bs = info->var.yres - bh;
-	struct fb_fillrect region;
-
-	region.color = attr_bgcol_ec(p,vc);
-	region.rop = ROP_COPY;
-
-	if (rw && !bottom_only) {
-		region.dx = info->var.xoffset + rs;
-		region.dy = 0;
-		region.width  = rw;
-		region.height = info->var.yres_virtual;
-		info->fbops->fb_fillrect(info, &region); 
-	}
-
-	if (bh) {
-		region.dx = info->var.xoffset;
-                region.dy = info->var.yoffset + bs;
-                region.width  = rs;
-                region.height = bh;
-		info->fbops->fb_fillrect(info, &region);
-	}
-}
-
-    /*
-     *  `switch' for the low level operations
-     */
-
-struct display_switch fbcon_accel = {
-	.setup =	fbcon_accel_setup,
-	.bmove =	fbcon_accel_bmove,
-	.clear =	fbcon_accel_clear,
-	.putc =		fbcon_accel_putc,
-	.putcs =	fbcon_accel_putcs,
-	.revc =		fbcon_accel_revc,
-	.clear_margins =fbcon_accel_clear_margins,
-	.fontwidthmask =FONTWIDTHRANGE(1, 16)	
-};
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
-    return 0;
-}
-
-void cleanup_module(void)
-{}
-#endif /* MODULE */
-
-
-    /*
-     *  Visible symbols for modules
-     */
-
-EXPORT_SYMBOL(fbcon_accel);
-EXPORT_SYMBOL(fbcon_accel_setup);
-EXPORT_SYMBOL(fbcon_accel_bmove);
-EXPORT_SYMBOL(fbcon_accel_clear);
-EXPORT_SYMBOL(fbcon_accel_putc);
-EXPORT_SYMBOL(fbcon_accel_putcs);
-EXPORT_SYMBOL(fbcon_accel_revc);
-EXPORT_SYMBOL(fbcon_accel_clear_margins);
diff -Nru a/drivers/video/fbcon-accel.h b/drivers/video/fbcon-accel.h
--- a/drivers/video/fbcon-accel.h	Mon Dec  9 18:46:51 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,34 +0,0 @@
-/*
- *  FBcon low-level driver that is a wrapper for the accel engine. 
- */
-
-#ifndef _VIDEO_FBCON_ACCEL_H
-#define _VIDEO_FBCON_ACCEL_H
-
-#include <linux/config.h>
-
-#ifdef MODULE
-#if defined(CONFIG_FBCON_ACCEL) || defined(CONFIG_FBCON_ACCEL_MODULE)
-#define FBCON_HAS_ACCEL
-#endif
-#else
-#if defined(CONFIG_FBCON_ACCEL)
-#define FBCON_HAS_ACCEL
-#endif
-#endif
-
-extern struct display_switch fbcon_accel;
-extern void fbcon_accel_setup(struct display *p);
-extern void fbcon_accel_bmove(struct display *p, int sy, int sx, int dy,
-			      int dx, int height, int width);
-extern void fbcon_accel_clear(struct vc_data *vc, struct display *p, int sy,
-			      int sx, int height, int width);
-extern void fbcon_accel_putc(struct vc_data *vc, struct display *p, int c,
-			     int yy, int xx);
-extern void fbcon_accel_putcs(struct vc_data *vc, struct display *p,
-			      const unsigned short *s, int count, int yy, int xx);
-extern void fbcon_accel_revc(struct display *p, int xx, int yy);
-extern void fbcon_accel_clear_margins(struct vc_data *vc, struct display *p,
-				      int bottom_only);
-
-#endif /* _VIDEO_FBCON_ACCEL_H */
diff -Nru a/drivers/video/fbcon-afb.c b/drivers/video/fbcon-afb.c
--- a/drivers/video/fbcon-afb.c	Mon Dec  9 18:46:34 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,448 +0,0 @@
-/*
- *  linux/drivers/video/afb.c -- Low level frame buffer operations for
- *				 bitplanes à la Amiga
- *
- *	Created 5 Apr 1997 by Geert Uytterhoeven
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-#include <linux/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-afb.h>
-
-
-    /*
-     *  Bitplanes à la Amiga
-     */
-
-static u8 expand_table[1024] = {
-    /*  bg = fg = 0 */
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    /* bg = 0, fg = 1 */
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
-    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-    0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
-    0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
-    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
-    0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
-    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
-    0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
-    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
-    0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
-    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
-    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
-    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
-    0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
-    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
-    0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
-    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
-    0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
-    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
-    0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
-    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
-    0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
-    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
-    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
-    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
-    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
-    /* bg = 1, fg = 0 */
-    0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
-    0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
-    0xef, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xe9, 0xe8,
-    0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0,
-    0xdf, 0xde, 0xdd, 0xdc, 0xdb, 0xda, 0xd9, 0xd8,
-    0xd7, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xd0,
-    0xcf, 0xce, 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc8,
-    0xc7, 0xc6, 0xc5, 0xc4, 0xc3, 0xc2, 0xc1, 0xc0,
-    0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8,
-    0xb7, 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1, 0xb0,
-    0xaf, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9, 0xa8,
-    0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0,
-    0x9f, 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98,
-    0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
-    0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88,
-    0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
-    0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78,
-    0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70,
-    0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68,
-    0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x60,
-    0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a, 0x59, 0x58,
-    0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50,
-    0x4f, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48,
-    0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40,
-    0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38,
-    0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30,
-    0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28,
-    0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20,
-    0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18,
-    0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
-    0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
-    0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
-    /* bg = fg = 1 */
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
-};
-
-void fbcon_afb_setup(struct display *p)
-{
-    if (p->fb_info->fix.line_length)
-	p->next_line = p->fb_info->fix.line_length;
-    else
-	p->next_line = p->var.xres_virtual>>3;
-    p->next_plane = p->var.yres_virtual*p->next_line;
-}
-
-void fbcon_afb_bmove(struct display *p, int sy, int sx, int dy, int dx,
-		     int height, int width)
-{
-    u8 *src, *dest, *src0, *dest0;
-    u_short i, j;
-
-    if (sx == 0 && dx == 0 && width == p->next_line) {
-	src = p->fb_info->screen_base+sy*fontheight(p)*width;
-	dest = p->fb_info->screen_base+dy*fontheight(p)*width;
-	i = p->var.bits_per_pixel;
-	do {
-	    fb_memmove(dest, src, height*fontheight(p)*width);
-	    src += p->next_plane;
-	    dest += p->next_plane;
-	} while (--i);
-    } else if (dy <= sy) {
-	src0 = p->fb_info->screen_base+sy*fontheight(p)*p->next_line+sx;
-	dest0 = p->fb_info->screen_base+dy*fontheight(p)*p->next_line+dx;
-	i = p->var.bits_per_pixel;
-	do {
-	    src = src0;
-	    dest = dest0;
-	    j = height*fontheight(p);
-	    do {
-	        fb_memmove(dest, src, width);
-	        src += p->next_line;
-	        dest += p->next_line;
-	    } while (--j);
-	    src0 += p->next_plane;
-	    dest0 += p->next_plane;
-	} while (--i);
-    } else {
-	src0 = p->fb_info->screen_base+(sy+height)*fontheight(p)*p->next_line+sx;
-	dest0 = p->fb_info->screen_base+(dy+height)*fontheight(p)*p->next_line+dx;
-	i = p->var.bits_per_pixel;
-	do {
-	    src = src0;
-	    dest = dest0;
-	    j = height*fontheight(p);
-	    do {
-	        src -= p->next_line;
-	        dest -= p->next_line;
-	        fb_memmove(dest, src, width);
-	    } while (--j);
-	    src0 += p->next_plane;
-	    dest0 += p->next_plane;
-	} while (--i);
-    }
-}
-
-void fbcon_afb_clear(struct vc_data *conp, struct display *p, int sy, int sx,
-		     int height, int width)
-{
-    u8 *dest, *dest0;
-    u_short i, j;
-    int bg;
-
-    dest0 = p->fb_info->screen_base+sy*fontheight(p)*p->next_line+sx;
-
-    bg = attr_bgcol_ec(p,conp);
-    i = p->var.bits_per_pixel;
-    do {
-	dest = dest0;
-	j = height*fontheight(p);
-	do {
-	    if (bg & 1)
-	        fb_memset255(dest, width);
-	    else
-	        fb_memclear(dest, width);
-	    dest += p->next_line;
-	} while (--j);
-	bg >>= 1;
-	dest0 += p->next_plane;
-    } while (--i);
-}
-
-void fbcon_afb_putc(struct vc_data *conp, struct display *p, int c, int yy,
-		    int xx)
-{
-    u8 *dest, *dest0, *cdat, *cdat0, *expand;
-    u_short i, j;
-    int fg, bg;
-
-    dest0 = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
-    cdat0 = p->fontdata+(c&p->charmask)*fontheight(p);
-    fg = attr_fgcol(p,c);
-    bg = attr_bgcol(p,c);
-
-    i = p->var.bits_per_pixel;
-    do {
-	dest = dest0;
-	cdat = cdat0;
-	expand = expand_table;
-	if (bg & 1)
-	    expand += 512;
-	if (fg & 1)
-	    expand += 256;
-	j = fontheight(p);
-	do {
-	    *dest = expand[*cdat++];
-	    dest += p->next_line;
-	} while (--j);
-	bg >>= 1;
-	fg >>= 1;
-	dest0 += p->next_plane;
-    } while (--i);
-}
-
-    /*
-     *  I've split the console character loop in two parts
-     *  (cfr. fbcon_putcs_ilbm())
-     */
-
-void fbcon_afb_putcs(struct vc_data *conp, struct display *p, 
-		     const unsigned short *s, int count, int yy, int xx)
-{
-    u8 *dest, *dest0, *dest1, *expand;
-    u8 *cdat1, *cdat2, *cdat3, *cdat4, *cdat10, *cdat20, *cdat30, *cdat40;
-    u_short i, j;
-    u16 c1, c2, c3, c4;
-    int fg0, bg0, fg, bg;
-
-    dest0 = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
-    c1 = scr_readw(s);
-    fg0 = attr_fgcol(p, c1);
-    bg0 = attr_bgcol(p, c1);
-
-    while (count--)
-	if (xx&3 || count < 3) {	/* Slow version */
-	    c1 = scr_readw(s++) & p->charmask;
-	    dest1 = dest0++;
-	    xx++;
-
-	    cdat10 = p->fontdata+c1*fontheight(p);
-	    fg = fg0;
-	    bg = bg0;
-
-	    i = p->var.bits_per_pixel;
-	    do {
-	        dest = dest1;
-	        cdat1 = cdat10;
-		expand = expand_table;
-		if (bg & 1)
-		    expand += 512;
-		if (fg & 1)
-		    expand += 256;
-		j = fontheight(p);
-		do {
-		    *dest = expand[*cdat1++];
-		    dest += p->next_line;
-	        } while (--j);
-	        bg >>= 1;
-	        fg >>= 1;
-		dest1 += p->next_plane;
-	    } while (--i);
-	} else {			/* Fast version */
-	    c1 = scr_readw(&s[0]) & p->charmask;
-	    c2 = scr_readw(&s[1]) & p->charmask;
-	    c3 = scr_readw(&s[2]) & p->charmask;
-	    c4 = scr_readw(&s[3]) & p->charmask;
-
-	    dest1 = dest0;
-	    cdat10 = p->fontdata+c1*fontheight(p);
-	    cdat20 = p->fontdata+c2*fontheight(p);
-	    cdat30 = p->fontdata+c3*fontheight(p);
-	    cdat40 = p->fontdata+c4*fontheight(p);
-	    fg = fg0;
-	    bg = bg0;
-
-	    i = p->var.bits_per_pixel;
-	    do {
-	        dest = dest1;
-	        cdat1 = cdat10;
-	        cdat2 = cdat20;
-	        cdat3 = cdat30;
-	        cdat4 = cdat40;
-		expand = expand_table;
-		if (bg & 1)
-		    expand += 512;
-		if (fg & 1)
-		    expand += 256;
-		j = fontheight(p);
-	        do {
-#if defined(__BIG_ENDIAN)
-		    *(u32 *)dest = expand[*cdat1++]<<24 |
-				   expand[*cdat2++]<<16 |
-				   expand[*cdat3++]<<8 |
-				   expand[*cdat4++];
-#elif defined(__LITTLE_ENDIAN)
-		    *(u32 *)dest = expand[*cdat1++] |
-				   expand[*cdat2++]<<8 |
-				   expand[*cdat3++]<<16 |
-				   expand[*cdat4++]<<24;
-#else
-#error FIXME: No endianness??
-#endif
-		    dest += p->next_line;
-	        } while (--j);
-	        bg >>= 1;
-	        fg >>= 1;
-		dest1 += p->next_plane;
-	    } while (--i);
-	    s += 4;
-	    dest0 += 4;
-	    xx += 4;
-	    count -= 3;
-	}
-}
-
-void fbcon_afb_revc(struct display *p, int xx, int yy)
-{
-    u8 *dest, *dest0;
-    u_short i, j;
-    int mask;
-
-    dest0 = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
-    mask = p->fgcol ^ p->bgcol;
-
-    /*
-     *  This should really obey the individual character's
-     *  background and foreground colors instead of simply
-     *  inverting.
-     */
-
-    i = p->var.bits_per_pixel;
-    do {
-	if (mask & 1) {
-	    dest = dest0;
-	    j = fontheight(p);
-	    do {
-	        *dest = ~*dest;
-		dest += p->next_line;
-	    } while (--j);
-	}
-	mask >>= 1;
-	dest0 += p->next_plane;
-    } while (--i);
-}
-
-
-    /*
-     *  `switch' for the low level operations
-     */
-
-struct display_switch fbcon_afb = {
-    setup:		fbcon_afb_setup,
-    bmove:		fbcon_afb_bmove,
-    clear:		fbcon_afb_clear,
-    putc:		fbcon_afb_putc,
-    putcs:		fbcon_afb_putcs,
-    revc:		fbcon_afb_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_afb);
-EXPORT_SYMBOL(fbcon_afb_setup);
-EXPORT_SYMBOL(fbcon_afb_bmove);
-EXPORT_SYMBOL(fbcon_afb_clear);
-EXPORT_SYMBOL(fbcon_afb_putc);
-EXPORT_SYMBOL(fbcon_afb_putcs);
-EXPORT_SYMBOL(fbcon_afb_revc);
diff -Nru a/drivers/video/fbcon-cfb16.c b/drivers/video/fbcon-cfb16.c
--- a/drivers/video/fbcon-cfb16.c	Mon Dec  9 18:46:37 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,319 +0,0 @@
-/*
- *  linux/drivers/video/cfb16.c -- Low level frame buffer operations for 16 bpp
- *				   truecolor packed pixels
- *
- *	Created 5 Apr 1997 by Geert Uytterhoeven
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-#include <linux/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-cfb16.h>
-
-
-    /*
-     *  16 bpp packed pixels
-     */
-
-static u32 tab_cfb16[] = {
-#if defined(__BIG_ENDIAN)
-    0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
-#elif defined(__LITTLE_ENDIAN)
-    0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff
-#else
-#error FIXME: No endianness??
-#endif
-};
-
-void fbcon_cfb16_setup(struct display *p)
-{
-    p->next_line = p->fb_info->fix.line_length ? p->fb_info->fix.line_length : p->var.xres_virtual<<1;
-    p->next_plane = 0;
-}
-
-void fbcon_cfb16_bmove(struct display *p, int sy, int sx, int dy, int dx,
-		       int height, int width)
-{
-    int bytes = p->next_line, linesize = bytes * fontheight(p), rows;
-    u8 *src, *dst;
-
-    if (sx == 0 && dx == 0 && width * fontwidth(p) * 2 == bytes) {
-	fb_memmove(p->fb_info->screen_base + dy * linesize,
-		  p->fb_info->screen_base + sy * linesize,
-		  height * linesize);
-	return;
-    }
-    if (fontwidthlog(p)) {
-	sx <<= fontwidthlog(p)+1;
-	dx <<= fontwidthlog(p)+1;
-	width <<= fontwidthlog(p)+1;
-    } else {
-	sx *= fontwidth(p)*2;
-	dx *= fontwidth(p)*2;
-	width *= fontwidth(p)*2;
-    }
-    if (dy < sy || (dy == sy && dx < sx)) {
-	src = p->fb_info->screen_base + sy * linesize + sx;
-	dst = p->fb_info->screen_base + dy * linesize + dx;
-	for (rows = height * fontheight(p); rows--;) {
-	    fb_memmove(dst, src, width);
-	    src += bytes;
-	    dst += bytes;
-	}
-    } else {
-	src = p->fb_info->screen_base + (sy+height) * linesize + sx - bytes;
-	dst = p->fb_info->screen_base + (dy+height) * linesize + dx - bytes;
-	for (rows = height * fontheight(p); rows--;) {
-	    fb_memmove(dst, src, width);
-	    src -= bytes;
-	    dst -= bytes;
-	}
-    }
-}
-
-static inline void rectfill(u8 *dest, int width, int height, u32 data,
-			    int linesize)
-{
-    int i;
-
-    data |= data<<16;
-
-    while (height-- > 0) {
-	u32 *p = (u32 *)dest;
-	for (i = 0; i < width/4; i++) {
-	    fb_writel(data, p++);
-	    fb_writel(data, p++);
-	}
-	if (width & 2)
-	    fb_writel(data, p++);
-	if (width & 1)
-	    fb_writew(data, (u16*)p);
-	dest += linesize;
-    }
-}
-
-void fbcon_cfb16_clear(struct vc_data *conp, struct display *p, int sy, int sx,
-		       int height, int width)
-{
-    u8 *dest;
-    int bytes = p->next_line, lines = height * fontheight(p);
-    u32 bgx;
-
-    dest = p->fb_info->screen_base + sy * fontheight(p) * bytes + sx * fontwidth(p) * 2;
-
-    bgx = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-
-    width *= fontwidth(p)/4;
-    if (width * 8 == bytes)
-	rectfill(dest, lines * width * 4, 1, bgx, bytes);
-    else
-	rectfill(dest, width * 4, lines, bgx, bytes);
-}
-
-void fbcon_cfb16_putc(struct vc_data *conp, struct display *p, int c, int yy,
-		      int xx)
-{
-    u8 *dest, *cdat, bits;
-    int bytes = p->next_line, rows;
-    u32 eorx, fgx, bgx;
-
-    dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 2;
-
-    fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)];
-    bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)];
-    fgx |= (fgx << 16);
-    bgx |= (bgx << 16);
-    eorx = fgx ^ bgx;
-
-    switch (fontwidth(p)) {
-    case 4:
-    case 8:
-	cdat = p->fontdata + (c & p->charmask) * fontheight(p);
-	for (rows = fontheight(p); rows--; dest += bytes) {
-	    bits = *cdat++;
-	    fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
-	    fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
-	    if (fontwidth(p) == 8) {
-		fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
-		fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
-	    }
-	}
-	break;
-    case 12:
-    case 16:
-	cdat = p->fontdata + ((c & p->charmask) * fontheight(p) << 1);
-	for (rows = fontheight(p); rows--; dest += bytes) {
-	    bits = *cdat++;
-	    fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
-	    fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
-	    fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
-	    fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
-	    bits = *cdat++;
-	    fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest+16);
-	    fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+20);
-	    if (fontwidth(p) == 16) {
-		fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+24);
-		fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+28);
-	    }
-	}
-	break;
-    }
-}
-
-void fbcon_cfb16_putcs(struct vc_data *conp, struct display *p,
-		       const unsigned short *s, int count, int yy, int xx)
-{
-    u8 *cdat, *dest, *dest0;
-    u16 c;
-    int rows, bytes = p->next_line;
-    u32 eorx, fgx, bgx;
-
-    dest0 = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 2;
-    c = scr_readw(s);
-    fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)];
-    bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)];
-    fgx |= (fgx << 16);
-    bgx |= (bgx << 16);
-    eorx = fgx ^ bgx;
-
-    switch (fontwidth(p)) {
-    case 4:
-    case 8:
-	while (count--) {
-	    c = scr_readw(s++) & p->charmask;
-	    cdat = p->fontdata + c * fontheight(p);
-	    for (rows = fontheight(p), dest = dest0; rows--; dest += bytes) {
-		u8 bits = *cdat++;
-	        fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
-	        fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
-		if (fontwidth(p) == 8) {
-		    fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
-		    fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
-		}
-	    }
-	    dest0 += fontwidth(p)*2;;
-	}
-	break;
-    case 12:
-    case 16:
-	while (count--) {
-	    c = scr_readw(s++) & p->charmask;
-	    cdat = p->fontdata + (c * fontheight(p) << 1);
-	    for (rows = fontheight(p), dest = dest0; rows--; dest += bytes) {
-		u8 bits = *cdat++;
-	        fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
-	        fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
-	        fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
-	        fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
-		bits = *cdat++;
-	        fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest+16);
-	        fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+20);
-		if (fontwidth(p) == 16) {
-		    fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+24);
-		    fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+28);
-		}
-	    }
-	    dest0 += fontwidth(p)*2;
-	}
-	break;
-    }
-}
-
-void fbcon_cfb16_revc(struct display *p, int xx, int yy)
-{
-    u8 *dest;
-    int bytes = p->next_line, rows;
-
-    dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p)*2;
-    for (rows = fontheight(p); rows--; dest += bytes) {
-	switch (fontwidth(p)) {
-	case 16:
-	    fb_writel(fb_readl(dest+24) ^ 0xffffffff, dest+24);
-	    fb_writel(fb_readl(dest+28) ^ 0xffffffff, dest+28);
-	    /* FALL THROUGH */
-	case 12:
-	    fb_writel(fb_readl(dest+16) ^ 0xffffffff, dest+16);
-	    fb_writel(fb_readl(dest+20) ^ 0xffffffff, dest+20);
-	    /* FALL THROUGH */
-	case 8:
-	    fb_writel(fb_readl(dest+8) ^ 0xffffffff, dest+8);
-	    fb_writel(fb_readl(dest+12) ^ 0xffffffff, dest+12);
-	    /* FALL THROUGH */
-	case 4:
-	    fb_writel(fb_readl(dest+0) ^ 0xffffffff, dest+0);
-	    fb_writel(fb_readl(dest+4) ^ 0xffffffff, dest+4);
-	}
-    }
-}
-
-void fbcon_cfb16_clear_margins(struct vc_data *conp, struct display *p,
-			       int bottom_only)
-{
-    int bytes = p->next_line;
-    u32 bgx;
-
-    unsigned int right_start = conp->vc_cols*fontwidth(p);
-    unsigned int bottom_start = conp->vc_rows*fontheight(p);
-    unsigned int right_width, bottom_width;
-
-    bgx = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-
-    if (!bottom_only && (right_width = p->var.xres-right_start))
-	rectfill(p->fb_info->screen_base+right_start*2, right_width,
-		 p->var.yres_virtual, bgx, bytes);
-    if ((bottom_width = p->var.yres-bottom_start))
-	rectfill(p->fb_info->screen_base+(p->var.yoffset+bottom_start)*bytes,
-		 right_start, bottom_width, bgx, bytes);
-}
-
-
-    /*
-     *  `switch' for the low level operations
-     */
-
-struct display_switch fbcon_cfb16 = {
-    setup:		fbcon_cfb16_setup,
-    bmove:		fbcon_cfb16_bmove,
-    clear:		fbcon_cfb16_clear,
-    putc:		fbcon_cfb16_putc,
-    putcs:		fbcon_cfb16_putcs,
-    revc:		fbcon_cfb16_revc,
-    clear_margins:	fbcon_cfb16_clear_margins,
-    fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
-    return 0;
-}
-
-void cleanup_module(void)
-{}
-#endif /* MODULE */
-
-
-    /*
-     *  Visible symbols for modules
-     */
-
-EXPORT_SYMBOL(fbcon_cfb16);
-EXPORT_SYMBOL(fbcon_cfb16_setup);
-EXPORT_SYMBOL(fbcon_cfb16_bmove);
-EXPORT_SYMBOL(fbcon_cfb16_clear);
-EXPORT_SYMBOL(fbcon_cfb16_putc);
-EXPORT_SYMBOL(fbcon_cfb16_putcs);
-EXPORT_SYMBOL(fbcon_cfb16_revc);
-EXPORT_SYMBOL(fbcon_cfb16_clear_margins);
diff -Nru a/drivers/video/fbcon-cfb2.c b/drivers/video/fbcon-cfb2.c
--- a/drivers/video/fbcon-cfb2.c	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,225 +0,0 @@
-/*
- *  linux/drivers/video/cfb2.c -- Low level frame buffer operations for 2 bpp
- *				  packed pixels
- *
- *	Created 26 Dec 1997 by Michael Schmitz
- *	Based on cfb4.c
- *
- *  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 <video/fbcon.h>
-#include <video/fbcon-cfb2.h>
-
-
-    /*
-     *  2 bpp packed pixels
-     */
-
-    /*
-     *  IFF the font is even pixel aligned (that is to say each
-     *  character start is a byte start in the pixel pairs). That
-     *  avoids us having to mask bytes and means we won't be here
-     *  all week. On a MacII that matters _lots_
-     */
-
-static u_char nibbletab_cfb2[]={
-#if defined(__BIG_ENDIAN)
-	0x00,0x03,0x0c,0x0f,
-	0x30,0x33,0x3c,0x3f,
-	0xc0,0xc3,0xcc,0xcf,
-	0xf0,0xf3,0xfc,0xff
-#elif defined(__LITTLE_ENDIAN)
-	0x00,0xc0,0x30,0xf0,
-	0x0c,0xcc,0x3c,0xfc,
-	0x03,0xc3,0x33,0xf3,
-	0x0f,0xcf,0x3f,0xff
-#else
-#error FIXME: No endianness??
-#endif
-};
- 
-
-void fbcon_cfb2_setup(struct display *p)
-{
-    p->next_line = p->fb_info->fix.line_length ? p->fb_info->fix.line_length : p->var.xres_virtual>>2;
-    p->next_plane = 0;
-}
-
-void fbcon_cfb2_bmove(struct display *p, int sy, int sx, int dy, int dx,
-		      int height, int width)
-{
-	int bytes = p->next_line, linesize = bytes * fontheight(p), rows;
-	u8 *src,*dst;
-
-	if (sx == 0 && dx == 0 && width * 2 == bytes) {
-		fb_memmove(p->fb_info->screen_base + dy * linesize,
-			  p->fb_info->screen_base + sy * linesize,
-			  height * linesize);
-	}
-	else {
-		if (dy < sy || (dy == sy && dx < sx)) {
-			src = p->fb_info->screen_base + sy * linesize + sx * 2;
-			dst = p->fb_info->screen_base + dy * linesize + dx * 2;
-			for (rows = height * fontheight(p) ; rows-- ;) {
-				fb_memmove(dst, src, width * 2);
-				src += bytes;
-				dst += bytes;
-			}
-		}
-		else {
-			src = p->fb_info->screen_base + (sy+height) * linesize + sx * 2 - bytes;
-			dst = p->fb_info->screen_base + (dy+height) * linesize + dx * 2 - bytes;
-			for (rows = height * fontheight(p) ; rows-- ;) {
-				fb_memmove(dst, src, width * 2);
-				src -= bytes;
-				dst -= bytes;
-			}
-		}
-	}
-}
-
-void fbcon_cfb2_clear(struct vc_data *conp, struct display *p, int sy, int sx,
-		      int height, int width)
-{
-	u8 *dest0,*dest;
-	int bytes=p->next_line,lines=height * fontheight(p), rows, i;
-	u32 bgx;
-
-	dest = p->fb_info->screen_base + sy * fontheight(p) * bytes + sx * 2;
-
-	bgx=attr_bgcol_ec(p,conp);
-	bgx |= (bgx << 2);	/* expand the colour to 16 bits */
-	bgx |= (bgx << 4);
-	bgx |= (bgx << 8);
-
-	if (sx == 0 && width * 2 == bytes) {
-		for (i = 0 ; i < lines * width ; i++) {
-			fb_writew (bgx, dest);
-			dest+=2;
-		}
-	} else {
-		dest0=dest;
-		for (rows = lines; rows-- ; dest0 += bytes) {
-			dest=dest0;
-			for (i = 0 ; i < width ; i++) {
-				/* memset ?? */
-				fb_writew (bgx, dest);
-				dest+=2;
-			}
-		}
-	}
-}
-
-void fbcon_cfb2_putc(struct vc_data *conp, struct display *p, int c, int yy,
-		     int xx)
-{
-	u8 *dest,*cdat;
-	int bytes=p->next_line,rows;
-	u32 eorx,fgx,bgx;
-
-	dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * 2;
-	cdat = p->fontdata + (c & p->charmask) * fontheight(p);
-
-	fgx=3;/*attr_fgcol(p,c);*/
-	bgx=attr_bgcol(p,c);
-	fgx |= (fgx << 2);	/* expand color to 8 bits */
-	fgx |= (fgx << 4);
-	bgx |= (bgx << 2);
-	bgx |= (bgx << 4);
-	eorx = fgx ^ bgx;
-
-	for (rows = fontheight(p) ; rows-- ; dest += bytes) {
-		fb_writeb((nibbletab_cfb2[*cdat >> 4] & eorx) ^ bgx, dest+0);
-		fb_writeb((nibbletab_cfb2[*cdat++ & 0xf] & eorx) ^ bgx, dest+1);
-	}
-}
-
-void fbcon_cfb2_putcs(struct vc_data *conp, struct display *p, const unsigned short *s,
-		      int count, int yy, int xx)
-{
-	u8 *cdat, *dest, *dest0;
-	u16 c;
-	int rows,bytes=p->next_line;
-	u32 eorx, fgx, bgx;
-
-	dest0 = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * 2;
-	c = scr_readw(s);
-	fgx = 3/*attr_fgcol(p, c)*/;
-	bgx = attr_bgcol(p, c);
-	fgx |= (fgx << 2);
-	fgx |= (fgx << 4);
-	bgx |= (bgx << 2);
-	bgx |= (bgx << 4);
-	eorx = fgx ^ bgx;
-	while (count--) {
-		c = scr_readw(s++) & p->charmask;
-		cdat = p->fontdata + c * fontheight(p);
-
-		for (rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
-			fb_writeb((nibbletab_cfb2[*cdat >> 4] & eorx) ^ bgx, dest+0);
-			fb_writeb((nibbletab_cfb2[*cdat++ & 0xf] & eorx) ^ bgx, dest+1);
-		}
-		dest0+=2;
-	}
-}
-
-void fbcon_cfb2_revc(struct display *p, int xx, int yy)
-{
-	u8 *dest;
-	int bytes=p->next_line, rows;
-
-	dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * 2;
-	for (rows = fontheight(p) ; rows-- ; dest += bytes) {
-		fb_writew(fb_readw(dest) ^ 0xffff, dest);
-	}
-}
-
-
-    /*
-     *  `switch' for the low level operations
-     */
-
-struct display_switch fbcon_cfb2 = {
-    setup:		fbcon_cfb2_setup,
-    bmove:		fbcon_cfb2_bmove,
-    clear:		fbcon_cfb2_clear,
-    putc:		fbcon_cfb2_putc,
-    putcs:		fbcon_cfb2_putcs,
-    revc:		fbcon_cfb2_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_cfb2);
-EXPORT_SYMBOL(fbcon_cfb2_setup);
-EXPORT_SYMBOL(fbcon_cfb2_bmove);
-EXPORT_SYMBOL(fbcon_cfb2_clear);
-EXPORT_SYMBOL(fbcon_cfb2_putc);
-EXPORT_SYMBOL(fbcon_cfb2_putcs);
-EXPORT_SYMBOL(fbcon_cfb2_revc);
diff -Nru a/drivers/video/fbcon-cfb24.c b/drivers/video/fbcon-cfb24.c
--- a/drivers/video/fbcon-cfb24.c	Mon Dec  9 18:46:35 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,333 +0,0 @@
-/*
- *  linux/drivers/video/cfb24.c -- Low level frame buffer operations for 24 bpp
- *				   truecolor packed pixels
- *
- *	Created 7 Mar 1998 by Geert Uytterhoeven
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-#include <linux/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-cfb24.h>
-
-
-    /*
-     *  24 bpp packed pixels
-     */
-
-void fbcon_cfb24_setup(struct display *p)
-{
-    struct fb_info *info = p->fb_info;	
-
-    p->next_line = info->fix.line_length ? info->fix.line_length : p->var.xres_virtual*3;
-    p->next_plane = 0;
-}
-
-void fbcon_cfb24_bmove(struct display *p, int sy, int sx, int dy, int dx,
-		       int height, int width)
-{
-    int bytes = p->next_line, linesize = bytes * fontheight(p), rows;
-    u8 *src, *dst;
-
-    if (sx == 0 && dx == 0 && width * fontwidth(p) * 3 == bytes) {
-	fb_memmove(p->fb_info->screen_base + dy * linesize,
-		  p->fb_info->screen_base + sy * linesize,
-		  height * linesize);
-	return;
-    }
-    if (fontwidthlog(p)) {
-	sx <<= fontwidthlog(p);
-	dx <<= fontwidthlog(p);
-	width <<= fontwidthlog(p);
-    } else {
-	sx *= fontwidth(p);
-	dx *= fontwidth(p);
-	width *= fontwidth(p);
-    }
-    sx *= 3; dx *= 3; width *= 3;
-    if (dy < sy || (dy == sy && dx < sx)) {
-	src = p->fb_info->screen_base + sy * linesize + sx;
-	dst = p->fb_info->screen_base + dy * linesize + dx;
-	for (rows = height * fontheight(p); rows--;) {
-	    fb_memmove(dst, src, width);
-	    src += bytes;
-	    dst += bytes;
-	}
-    } else {
-	src = p->fb_info->screen_base + (sy+height) * linesize + sx - bytes;
-	dst = p->fb_info->screen_base + (dy+height) * linesize + dx - bytes;
-	for (rows = height * fontheight(p); rows--;) {
-	    fb_memmove(dst, src, width);
-	    src -= bytes;
-	    dst -= bytes;
-	}
-    }
-}
-
-#if defined(__BIG_ENDIAN)
-#define convert4to3(in1, in2, in3, in4, out1, out2, out3) \
-    do { \
-	out1 = (in1<<8)  | (in2>>16); \
-	out2 = (in2<<16) | (in3>>8); \
-	out3 = (in3<<24) | in4; \
-    } while (0);
-#elif defined(__LITTLE_ENDIAN)
-#define convert4to3(in1, in2, in3, in4, out1, out2, out3) \
-    do { \
-	out1 = in1       | (in2<<24); \
-	out2 = (in2>> 8) | (in3<<16); \
-	out3 = (in3>>16) | (in4<< 8); \
-    } while (0);
-#else
-#error FIXME: No endianness??
-#endif
-
-static inline void store4pixels(u32 d1, u32 d2, u32 d3, u32 d4, u32 *dest)
-{
-    u32 o1, o2, o3;
-    convert4to3(d1, d2, d3, d4, o1, o2, o3);
-    fb_writel (o1, dest++);
-    fb_writel (o2, dest++);
-    fb_writel (o3, dest);
-}
-
-static inline void rectfill(u8 *dest, int width, int height, u32 data,
-			    int linesize)
-{
-    u32 d1, d2, d3;
-    int i;
-
-    convert4to3(data, data, data, data, d1, d2, d3);
-    while (height-- > 0) {
-	u32 *p = (u32 *)dest;
-	for (i = 0; i < width/4; i++) {
-	    fb_writel(d1, p++);
-	    fb_writel(d2, p++);
-	    fb_writel(d3, p++);
-	}
-	dest += linesize;
-    }
-}
-
-void fbcon_cfb24_clear(struct vc_data *conp, struct display *p, int sy, int sx,
-		       int height, int width)
-{
-    u8 *dest;
-    int bytes = p->next_line, lines = height * fontheight(p);
-    u32 bgx;
-
-    dest = p->fb_info->screen_base + sy * fontheight(p) * bytes + sx * fontwidth(p) * 3;
-
-    bgx = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-
-    width *= fontwidth(p)/4;
-    if (width * 12 == bytes)
-	rectfill(dest, lines * width * 4, 1, bgx, bytes);
-    else
-	rectfill(dest, width * 4, lines, bgx, bytes);
-}
-
-void fbcon_cfb24_putc(struct vc_data *conp, struct display *p, int c, int yy,
-		      int xx)
-{
-    u8 *dest, *cdat, bits;
-    int bytes = p->next_line, rows;
-    u32 eorx, fgx, bgx, d1, d2, d3, d4;
-
-    dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 3;
-    if (fontwidth(p) <= 8)
-	cdat = p->fontdata + (c & p->charmask) * fontheight(p);
-    else
-	cdat = p->fontdata + ((c & p->charmask) * fontheight(p) << 1);
-
-    fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p, c)];
-    bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p, c)];
-    eorx = fgx ^ bgx;
-
-    for (rows = fontheight(p); rows--; dest += bytes) {
-	bits = *cdat++;
-	d1 = (-(bits >> 7) & eorx) ^ bgx;
-	d2 = (-(bits >> 6 & 1) & eorx) ^ bgx;
-	d3 = (-(bits >> 5 & 1) & eorx) ^ bgx;
-	d4 = (-(bits >> 4 & 1) & eorx) ^ bgx;
-	store4pixels(d1, d2, d3, d4, (u32 *)dest);
-	if (fontwidth(p) < 8)
-	    continue;
-	d1 = (-(bits >> 3 & 1) & eorx) ^ bgx;
-	d2 = (-(bits >> 2 & 1) & eorx) ^ bgx;
-	d3 = (-(bits >> 1 & 1) & eorx) ^ bgx;
-	d4 = (-(bits & 1) & eorx) ^ bgx;
-	store4pixels(d1, d2, d3, d4, (u32 *)(dest+12));
-	if (fontwidth(p) < 12)
-	    continue;
-	bits = *cdat++;
-	d1 = (-(bits >> 7) & eorx) ^ bgx;
-	d2 = (-(bits >> 6 & 1) & eorx) ^ bgx;
-	d3 = (-(bits >> 5 & 1) & eorx) ^ bgx;
-	d4 = (-(bits >> 4 & 1) & eorx) ^ bgx;
-	store4pixels(d1, d2, d3, d4, (u32 *)(dest+24));
-	if (fontwidth(p) < 16)
-	    continue;
-	d1 = (-(bits >> 3 & 1) & eorx) ^ bgx;
-	d2 = (-(bits >> 2 & 1) & eorx) ^ bgx;
-	d3 = (-(bits >> 1 & 1) & eorx) ^ bgx;
-	d4 = (-(bits & 1) & eorx) ^ bgx;
-	store4pixels(d1, d2, d3, d4, (u32 *)(dest+36));
-    }
-}
-
-void fbcon_cfb24_putcs(struct vc_data *conp, struct display *p,
-		       const unsigned short *s, int count, int yy, int xx)
-{
-    u8 *cdat, *dest, *dest0, bits;
-    u16 c;
-    int rows, bytes = p->next_line;
-    u32 eorx, fgx, bgx, d1, d2, d3, d4;
-
-    dest0 = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 3;
-    c = scr_readw(s);
-    fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p, c)];
-    bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p, c)];
-    eorx = fgx ^ bgx;
-    while (count--) {
-	c = scr_readw(s++) & p->charmask;
-	if (fontwidth(p) <= 8)
-	    cdat = p->fontdata + c * fontheight(p);
-	  
-	else
-	    cdat = p->fontdata + (c * fontheight(p) << 1);
-	for (rows = fontheight(p), dest = dest0; rows--; dest += bytes) {
-	    bits = *cdat++;
-	    d1 = (-(bits >> 7) & eorx) ^ bgx;
-	    d2 = (-(bits >> 6 & 1) & eorx) ^ bgx;
-	    d3 = (-(bits >> 5 & 1) & eorx) ^ bgx;
-	    d4 = (-(bits >> 4 & 1) & eorx) ^ bgx;
-	    store4pixels(d1, d2, d3, d4, (u32 *)dest);
-	    if (fontwidth(p) < 8)
-		continue;
-	    d1 = (-(bits >> 3 & 1) & eorx) ^ bgx;
-	    d2 = (-(bits >> 2 & 1) & eorx) ^ bgx;
-	    d3 = (-(bits >> 1 & 1) & eorx) ^ bgx;
-	    d4 = (-(bits & 1) & eorx) ^ bgx;
-	    store4pixels(d1, d2, d3, d4, (u32 *)(dest+12));
-	    if (fontwidth(p) < 12)
-		continue;
-	    bits = *cdat++;
-	    d1 = (-(bits >> 7) & eorx) ^ bgx;
-	    d2 = (-(bits >> 6 & 1) & eorx) ^ bgx;
-	    d3 = (-(bits >> 5 & 1) & eorx) ^ bgx;
-	    d4 = (-(bits >> 4 & 1) & eorx) ^ bgx;
-	    store4pixels(d1, d2, d3, d4, (u32 *)(dest+24));
-	    if (fontwidth(p) < 16)
-		continue;
-	    d1 = (-(bits >> 3 & 1) & eorx) ^ bgx;
-	    d2 = (-(bits >> 2 & 1) & eorx) ^ bgx;
-	    d3 = (-(bits >> 1 & 1) & eorx) ^ bgx;
-	    d4 = (-(bits & 1) & eorx) ^ bgx;
-	    store4pixels(d1, d2, d3, d4, (u32 *)(dest+36));
-	}
-	dest0 += fontwidth(p)*3;
-    }
-}
-
-void fbcon_cfb24_revc(struct display *p, int xx, int yy)
-{
-    u8 *dest;
-    int bytes = p->next_line, rows;
-
-    dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 3;
-    for (rows = fontheight(p); rows--; dest += bytes) {
-	switch (fontwidth(p)) {
-	case 16:
-	    fb_writel(fb_readl(dest+36) ^ 0xffffffff, dest+36);
-	    fb_writel(fb_readl(dest+40) ^ 0xffffffff, dest+40);
-	    fb_writel(fb_readl(dest+44) ^ 0xffffffff, dest+44);
-	    /* FALL THROUGH */
-	case 12:
-	    fb_writel(fb_readl(dest+24) ^ 0xffffffff, dest+24);
-	    fb_writel(fb_readl(dest+28) ^ 0xffffffff, dest+28);
-	    fb_writel(fb_readl(dest+32) ^ 0xffffffff, dest+32);
-	    /* FALL THROUGH */
-	case 8:
-	    fb_writel(fb_readl(dest+12) ^ 0xffffffff, dest+12);
-	    fb_writel(fb_readl(dest+16) ^ 0xffffffff, dest+16);
-	    fb_writel(fb_readl(dest+20) ^ 0xffffffff, dest+20);
-	    /* FALL THROUGH */
-	case 4:
-	    fb_writel(fb_readl(dest+0) ^ 0xffffffff, dest+0);
-	    fb_writel(fb_readl(dest+4) ^ 0xffffffff, dest+4);
-	    fb_writel(fb_readl(dest+8) ^ 0xffffffff, dest+8);
-	}
-    }
-}
-
-void fbcon_cfb24_clear_margins(struct vc_data *conp, struct display *p,
-			       int bottom_only)
-{
-    int bytes = p->next_line;
-    u32 bgx;
-
-    unsigned int right_start = conp->vc_cols*fontwidth(p);
-    unsigned int bottom_start = conp->vc_rows*fontheight(p);
-    unsigned int right_width, bottom_width;
-
-    bgx = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-
-    if (!bottom_only && (right_width = p->var.xres-right_start))
-	rectfill(p->fb_info->screen_base+right_start*3, right_width,
-		 p->var.yres_virtual, bgx, bytes);
-    if ((bottom_width = p->var.yres-bottom_start))
-	rectfill(p->fb_info->screen_base+(p->var.yoffset+bottom_start)*bytes,
-		 right_start, bottom_width, bgx, bytes);
-}
-
-
-    /*
-     *  `switch' for the low level operations
-     */
-
-struct display_switch fbcon_cfb24 = {
-    setup:		fbcon_cfb24_setup,
-    bmove:		fbcon_cfb24_bmove,
-    clear:		fbcon_cfb24_clear,
-    putc:		fbcon_cfb24_putc,
-    putcs:		fbcon_cfb24_putcs,
-    revc:		fbcon_cfb24_revc,
-    clear_margins:	fbcon_cfb24_clear_margins,
-    fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
-    return 0;
-}
-
-void cleanup_module(void)
-{}
-#endif /* MODULE */
-
-
-    /*
-     *  Visible symbols for modules
-     */
-
-EXPORT_SYMBOL(fbcon_cfb24);
-EXPORT_SYMBOL(fbcon_cfb24_setup);
-EXPORT_SYMBOL(fbcon_cfb24_bmove);
-EXPORT_SYMBOL(fbcon_cfb24_clear);
-EXPORT_SYMBOL(fbcon_cfb24_putc);
-EXPORT_SYMBOL(fbcon_cfb24_putcs);
-EXPORT_SYMBOL(fbcon_cfb24_revc);
-EXPORT_SYMBOL(fbcon_cfb24_clear_margins);
diff -Nru a/drivers/video/fbcon-cfb32.c b/drivers/video/fbcon-cfb32.c
--- a/drivers/video/fbcon-cfb32.c	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,305 +0,0 @@
-/*
- *  linux/drivers/video/cfb32.c -- Low level frame buffer operations for 32 bpp
- *				   truecolor packed pixels
- *
- *	Created 28 Dec 1997 by Geert Uytterhoeven
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-#include <linux/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-cfb32.h>
-
-
-    /*
-     *  32 bpp packed pixels
-     */
-
-void fbcon_cfb32_setup(struct display *p)
-{
-    p->next_line = p->fb_info->fix.line_length ? p->fb_info->fix.line_length : p->var.xres_virtual<<2;
-    p->next_plane = 0;
-}
-
-void fbcon_cfb32_bmove(struct display *p, int sy, int sx, int dy, int dx,
-		       int height, int width)
-{
-    int bytes = p->next_line, linesize = bytes * fontheight(p), rows;
-    u8 *src, *dst;
-
-    if (sx == 0 && dx == 0 && width * fontwidth(p) * 4 == bytes) {
-	fb_memmove(p->fb_info->screen_base + dy * linesize,
-		  p->fb_info->screen_base + sy * linesize,
-		  height * linesize);
-	return;
-    }
-    if (fontwidthlog(p)) {
-	sx <<= fontwidthlog(p)+2;
-	dx <<= fontwidthlog(p)+2;
-	width <<= fontwidthlog(p)+2;
-    } else {
-	sx *= fontwidth(p)*4;
-	dx *= fontwidth(p)*4;
-	width *= fontwidth(p)*4;
-    }
-    if (dy < sy || (dy == sy && dx < sx)) {
-	src = p->fb_info->screen_base + sy * linesize + sx;
-	dst = p->fb_info->screen_base + dy * linesize + dx;
-	for (rows = height * fontheight(p); rows--;) {
-	    fb_memmove(dst, src, width);
-	    src += bytes;
-	    dst += bytes;
-	}
-    } else {
-	src = p->fb_info->screen_base + (sy+height) * linesize + sx - bytes;
-	dst = p->fb_info->screen_base + (dy+height) * linesize + dx - bytes;
-	for (rows = height * fontheight(p); rows--;) {
-	    fb_memmove(dst, src, width);
-	    src -= bytes;
-	    dst -= bytes;
-	}
-    }
-}
-
-static inline void rectfill(u8 *dest, int width, int height, u32 data,
-			    int linesize)
-{
-    int i;
-
-    while (height-- > 0) {
-	u32 *p = (u32 *)dest;
-	for (i = 0; i < width/4; i++) {
-	    fb_writel(data, p++);
-	    fb_writel(data, p++);
-	    fb_writel(data, p++);
-	    fb_writel(data, p++);
-	}
-	if (width & 2) {
-	    fb_writel(data, p++);
-	    fb_writel(data, p++);
-	}
-	if (width & 1)
-	    fb_writel(data, p++);
-	dest += linesize;
-    }
-}
-
-void fbcon_cfb32_clear(struct vc_data *conp, struct display *p, int sy, int sx,
-		       int height, int width)
-{
-    u8 *dest;
-    int bytes = p->next_line, lines = height * fontheight(p);
-    u32 bgx;
-
-    dest = p->fb_info->screen_base + sy * fontheight(p) * bytes + sx * fontwidth(p) * 4;
-
-    bgx = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-
-    width *= fontwidth(p)/4;
-    if (width * 16 == bytes)
-	rectfill(dest, lines * width * 4, 1, bgx, bytes);
-    else
-	rectfill(dest, width * 4, lines, bgx, bytes);
-}
-
-void fbcon_cfb32_putc(struct vc_data *conp, struct display *p, int c, int yy,
-		      int xx)
-{
-    u8 *dest, *cdat, bits;
-    int bytes = p->next_line, rows;
-    u32 eorx, fgx, bgx, *pt;
-
-    dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 4;
-    if (fontwidth(p) <= 8)
-	cdat = p->fontdata + (c & p->charmask) * fontheight(p);
-    else
-	cdat = p->fontdata + ((c & p->charmask) * fontheight(p) << 1);
-    fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p, c)];
-    bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p, c)];
-    eorx = fgx ^ bgx;
-
-    for (rows = fontheight(p); rows--; dest += bytes) {
-	bits = *cdat++;
-	pt = (u32 *) dest;
-	fb_writel((-(bits >> 7) & eorx) ^ bgx, pt++);
-	fb_writel((-(bits >> 6 & 1) & eorx) ^ bgx, pt++);
-	fb_writel((-(bits >> 5 & 1) & eorx) ^ bgx, pt++);
-	fb_writel((-(bits >> 4 & 1) & eorx) ^ bgx, pt++);
-	if (fontwidth(p) < 8)
-	    continue;
-	fb_writel((-(bits >> 3 & 1) & eorx) ^ bgx, pt++);
-	fb_writel((-(bits >> 2 & 1) & eorx) ^ bgx, pt++);
-	fb_writel((-(bits >> 1 & 1) & eorx) ^ bgx, pt++);
-	fb_writel((-(bits & 1) & eorx) ^ bgx, pt++);
-	if (fontwidth(p) < 12)
-	    continue;
-	bits = *cdat++;
-	fb_writel((-(bits >> 7) & eorx) ^ bgx, pt++);
-	fb_writel((-(bits >> 6 & 1) & eorx) ^ bgx, pt++);
-	fb_writel((-(bits >> 5 & 1) & eorx) ^ bgx, pt++);
-	fb_writel((-(bits >> 4 & 1) & eorx) ^ bgx, pt++);
-	if (fontwidth(p) < 16)
-	    continue;
-	fb_writel((-(bits >> 3 & 1) & eorx) ^ bgx, pt++);
-	fb_writel((-(bits >> 2 & 1) & eorx) ^ bgx, pt++);
-	fb_writel((-(bits >> 1 & 1) & eorx) ^ bgx, pt++);
-	fb_writel((-(bits & 1) & eorx) ^ bgx, pt++);
-    }
-}
-
-void fbcon_cfb32_putcs(struct vc_data *conp, struct display *p,
-		       const unsigned short *s, int count, int yy, int xx)
-{
-    u8 *cdat, *dest, *dest0, bits;
-    u16 c;
-    int rows, bytes = p->next_line;
-    u32 eorx, fgx, bgx, *pt;
-
-    dest0 = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 4;
-    c = scr_readw(s);
-    fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p, c)];
-    bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p, c)];
-    eorx = fgx ^ bgx;
-    while (count--) {
-	c = scr_readw(s++) & p->charmask;
-	if (fontwidth(p) <= 8)
-	    cdat = p->fontdata + c * fontheight(p);
-	else
-	    cdat = p->fontdata + (c * fontheight(p) << 1);
-	for (rows = fontheight(p), dest = dest0; rows--; dest += bytes) {
-	    bits = *cdat++;
-	    pt = (u32 *) dest;
-	    fb_writel((-(bits >> 7) & eorx) ^ bgx, pt++);
-	    fb_writel((-(bits >> 6 & 1) & eorx) ^ bgx, pt++);
-	    fb_writel((-(bits >> 5 & 1) & eorx) ^ bgx, pt++);
-	    fb_writel((-(bits >> 4 & 1) & eorx) ^ bgx, pt++);
-	    if (fontwidth(p) < 8)
-		continue;
-	    fb_writel((-(bits >> 3 & 1) & eorx) ^ bgx, pt++);
-	    fb_writel((-(bits >> 2 & 1) & eorx) ^ bgx, pt++);
-	    fb_writel((-(bits >> 1 & 1) & eorx) ^ bgx, pt++);
-	    fb_writel((-(bits & 1) & eorx) ^ bgx, pt++);
-	    if (fontwidth(p) < 12)
-		continue;
-	    bits = *cdat++;
-	    fb_writel((-(bits >> 7) & eorx) ^ bgx, pt++);
-	    fb_writel((-(bits >> 6 & 1) & eorx) ^ bgx, pt++);
-	    fb_writel((-(bits >> 5 & 1) & eorx) ^ bgx, pt++);
-	    fb_writel((-(bits >> 4 & 1) & eorx) ^ bgx, pt++);
-	    if (fontwidth(p) < 16)
-		continue;
-	    fb_writel((-(bits >> 3 & 1) & eorx) ^ bgx, pt++);
-	    fb_writel((-(bits >> 2 & 1) & eorx) ^ bgx, pt++);
-	    fb_writel((-(bits >> 1 & 1) & eorx) ^ bgx, pt++);
-	    fb_writel((-(bits & 1) & eorx) ^ bgx, pt++);
-	}
-	dest0 += fontwidth(p)*4;
-    }
-}
-
-void fbcon_cfb32_revc(struct display *p, int xx, int yy)
-{
-    u8 *dest;
-    int bytes = p->next_line, rows;
-
-    dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 4;
-    for (rows = fontheight(p); rows--; dest += bytes) {
-	switch (fontwidth(p)) {
-	case 16:
-	    fb_writel(fb_readl(dest+(4*12)) ^ 0xffffffff, dest+(4*12));
-	    fb_writel(fb_readl(dest+(4*13)) ^ 0xffffffff, dest+(4*13));
-	    fb_writel(fb_readl(dest+(4*14)) ^ 0xffffffff, dest+(4*14));
-	    fb_writel(fb_readl(dest+(4*15)) ^ 0xffffffff, dest+(4*15));
-	    /* FALL THROUGH */
-	case 12:
-	    fb_writel(fb_readl(dest+(4*8)) ^ 0xffffffff, dest+(4*8));
-	    fb_writel(fb_readl(dest+(4*9)) ^ 0xffffffff, dest+(4*9));
-	    fb_writel(fb_readl(dest+(4*10)) ^ 0xffffffff, dest+(4*10));
-	    fb_writel(fb_readl(dest+(4*11)) ^ 0xffffffff, dest+(4*11));
-	    /* FALL THROUGH */
-	case 8:
-	    fb_writel(fb_readl(dest+(4*4)) ^ 0xffffffff, dest+(4*4));
-	    fb_writel(fb_readl(dest+(4*5)) ^ 0xffffffff, dest+(4*5));
-	    fb_writel(fb_readl(dest+(4*6)) ^ 0xffffffff, dest+(4*6));
-	    fb_writel(fb_readl(dest+(4*7)) ^ 0xffffffff, dest+(4*7));
-	    /* FALL THROUGH */
-	case 4:
-	    fb_writel(fb_readl(dest+(4*0)) ^ 0xffffffff, dest+(4*0));
-	    fb_writel(fb_readl(dest+(4*1)) ^ 0xffffffff, dest+(4*1));
-	    fb_writel(fb_readl(dest+(4*2)) ^ 0xffffffff, dest+(4*2));
-	    fb_writel(fb_readl(dest+(4*3)) ^ 0xffffffff, dest+(4*3));
-	    /* FALL THROUGH */
-	}
-    }
-}
-
-void fbcon_cfb32_clear_margins(struct vc_data *conp, struct display *p,
-			       int bottom_only)
-{
-    int bytes = p->next_line;
-    u32 bgx;
-
-    unsigned int right_start = conp->vc_cols*fontwidth(p);
-    unsigned int bottom_start = conp->vc_rows*fontheight(p);
-    unsigned int right_width, bottom_width;
-
-    bgx = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-
-    if (!bottom_only && (right_width = p->var.xres-right_start))
-	rectfill(p->fb_info->screen_base+right_start*4, right_width,
-		 p->var.yres_virtual, bgx, bytes);
-    if ((bottom_width = p->var.yres-bottom_start))
-	rectfill(p->fb_info->screen_base+(p->var.yoffset+bottom_start)*bytes,
-		 right_start, bottom_width, bgx, bytes);
-}
-
-
-    /*
-     *  `switch' for the low level operations
-     */
-
-struct display_switch fbcon_cfb32 = {
-    setup:		fbcon_cfb32_setup,
-    bmove:		fbcon_cfb32_bmove,
-    clear:		fbcon_cfb32_clear,
-    putc:		fbcon_cfb32_putc,
-    putcs:		fbcon_cfb32_putcs,
-    revc:		fbcon_cfb32_revc,
-    clear_margins:	fbcon_cfb32_clear_margins,
-    fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
-    return 0;
-}
-
-void cleanup_module(void)
-{}
-#endif /* MODULE */
-
-
-    /*
-     *  Visible symbols for modules
-     */
-
-EXPORT_SYMBOL(fbcon_cfb32);
-EXPORT_SYMBOL(fbcon_cfb32_setup);
-EXPORT_SYMBOL(fbcon_cfb32_bmove);
-EXPORT_SYMBOL(fbcon_cfb32_clear);
-EXPORT_SYMBOL(fbcon_cfb32_putc);
-EXPORT_SYMBOL(fbcon_cfb32_putcs);
-EXPORT_SYMBOL(fbcon_cfb32_revc);
-EXPORT_SYMBOL(fbcon_cfb32_clear_margins);
diff -Nru a/drivers/video/fbcon-cfb4.c b/drivers/video/fbcon-cfb4.c
--- a/drivers/video/fbcon-cfb4.c	Mon Dec  9 18:46:36 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,229 +0,0 @@
-/*
- *  linux/drivers/video/cfb4.c -- Low level frame buffer operations for 4 bpp
- *				  packed pixels
- *
- *	Created 26 Dec 1997 by Michael Schmitz
- *	Based on the old macfb.c 4bpp code by Alan Cox
- *
- *  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 <video/fbcon.h>
-#include <video/fbcon-cfb4.h>
-
-
-    /*
-     *  4 bpp packed pixels
-     */
-
-    /*
-     *  IFF the font is even pixel aligned (that is to say each
-     *  character start is a byte start in the pixel pairs). That
-     *  avoids us having to mask bytes and means we won't be here
-     *  all week. On a MacII that matters _lots_
-     */
-
-static u16 nibbletab_cfb4[] = {
-#if defined(__BIG_ENDIAN)
-    0x0000,0x000f,0x00f0,0x00ff,
-    0x0f00,0x0f0f,0x0ff0,0x0fff,
-    0xf000,0xf00f,0xf0f0,0xf0ff,
-    0xff00,0xff0f,0xfff0,0xffff
-#elif defined(__LITTLE_ENDIAN)
-    0x0000,0xf000,0x0f00,0xff00,
-    0x00f0,0xf0f0,0x0ff0,0xfff0,
-    0x000f,0xf00f,0x0f0f,0xff0f,
-    0x00ff,0xf0ff,0x0fff,0xffff
-#else
-#error FIXME: No endianness??
-#endif
-
-};
-
-void fbcon_cfb4_setup(struct display *p)
-{
-    p->next_line = p->fb_info->fix.line_length ? p->fb_info->fix.line_length : p->var.xres_virtual>>1;
-    p->next_plane = 0;
-}
-
-void fbcon_cfb4_bmove(struct display *p, int sy, int sx, int dy, int dx,
-		      int height, int width)
-{
-	int bytes = p->next_line, linesize = bytes * fontheight(p), rows;
-	u8 *src,*dst;
-
-	if (sx == 0 && dx == 0 && width * 4 == bytes) {
-		fb_memmove(p->fb_info->screen_base + dy * linesize,
-			  p->fb_info->screen_base + sy * linesize,
-			  height * linesize);
-	}
-	else {
-		if (dy < sy || (dy == sy && dx < sx)) {
-			src = p->fb_info->screen_base + sy * linesize + sx * 4;
-			dst = p->fb_info->screen_base + dy * linesize + dx * 4;
-			for (rows = height * fontheight(p) ; rows-- ;) {
-				fb_memmove(dst, src, width * 4);
-				src += bytes;
-				dst += bytes;
-			}
-		}
-		else {
-			src = p->fb_info->screen_base + (sy+height) * linesize + sx * 4 - bytes;
-			dst = p->fb_info->screen_base + (dy+height) * linesize + dx * 4 - bytes;
-			for (rows = height * fontheight(p) ; rows-- ;) {
-				fb_memmove(dst, src, width * 4);
-				src -= bytes;
-				dst -= bytes;
-			}
-		}
-	}
-}
-
-void fbcon_cfb4_clear(struct vc_data *conp, struct display *p, int sy, int sx,
-		      int height, int width)
-{
-	u8 *dest0,*dest;
-	int bytes=p->next_line,lines=height * fontheight(p), rows, i;
-	u32 bgx;
-
-/*	if(p->fb_info->screen_base!=0xFDD00020)
-		mac_boom(1);*/
-	dest = p->fb_info->screen_base + sy * fontheight(p) * bytes + sx * 4;
-
-	bgx=attr_bgcol_ec(p,conp);
-	bgx |= (bgx << 4);	/* expand the colour to 32bits */
-	bgx |= (bgx << 8);
-	bgx |= (bgx << 16);
-
-	if (sx == 0 && width * 4 == bytes) {
-		for (i = 0 ; i < lines * width ; i++) {
-			fb_writel (bgx, dest);
-			dest+=4;
-		}
-	} else {
-		dest0=dest;
-		for (rows = lines; rows-- ; dest0 += bytes) {
-			dest=dest0;
-			for (i = 0 ; i < width ; i++) {
-				/* memset ?? */
-				fb_writel (bgx, dest);
-				dest+=4;
-			}
-		}
-	}
-}
-
-void fbcon_cfb4_putc(struct vc_data *conp, struct display *p, int c, int yy,
-		     int xx)
-{
-	u8 *dest,*cdat;
-	int bytes=p->next_line,rows;
-	u32 eorx,fgx,bgx;
-
-	dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * 4;
-	cdat = p->fontdata + (c & p->charmask) * fontheight(p);
-
-	fgx=attr_fgcol(p,c);
-	bgx=attr_bgcol(p,c);
-	fgx |= (fgx << 4);
-	fgx |= (fgx << 8);
-	bgx |= (bgx << 4);
-	bgx |= (bgx << 8);
-	eorx = fgx ^ bgx;
-
-	for (rows = fontheight(p) ; rows-- ; dest += bytes) {
-		fb_writew((nibbletab_cfb4[*cdat >> 4] & eorx) ^ bgx, dest+0);
-		fb_writew((nibbletab_cfb4[*cdat++ & 0xf] & eorx) ^ bgx, dest+2);
-	}
-}
-
-void fbcon_cfb4_putcs(struct vc_data *conp, struct display *p, 
-		      const unsigned short *s, int count, int yy, int xx)
-{
-	u8 *cdat, *dest, *dest0;
-	u16 c;
-	int rows,bytes=p->next_line;
-	u32 eorx, fgx, bgx;
-
-	dest0 = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * 4;
-	c = scr_readw(s);
-	fgx = attr_fgcol(p, c);
-	bgx = attr_bgcol(p, c);
-	fgx |= (fgx << 4);
-	fgx |= (fgx << 8);
-	fgx |= (fgx << 16);
-	bgx |= (bgx << 4);
-	bgx |= (bgx << 8);
-	bgx |= (bgx << 16);
-	eorx = fgx ^ bgx;
-	while (count--) {
-		c = scr_readw(s++) & p->charmask;
-		cdat = p->fontdata + c * fontheight(p);
-
-		for (rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
-			fb_writew((nibbletab_cfb4[*cdat >> 4] & eorx) ^ bgx, dest+0);
-			fb_writew((nibbletab_cfb4[*cdat++ & 0xf] & eorx) ^ bgx, dest+2);
-		}
-		dest0+=4;
-	}
-}
-
-void fbcon_cfb4_revc(struct display *p, int xx, int yy)
-{
-	u8 *dest;
-	int bytes=p->next_line, rows;
-
-	dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * 4;
-	for (rows = fontheight(p) ; rows-- ; dest += bytes) {
-		fb_writel(fb_readl(dest+0) ^ 0xffffffff, dest+0);
-	}
-}
-
-
-    /*
-     *  `switch' for the low level operations
-     */
-
-struct display_switch fbcon_cfb4 = {
-    setup:		fbcon_cfb4_setup,
-    bmove:		fbcon_cfb4_bmove,
-    clear:		fbcon_cfb4_clear,
-    putc:		fbcon_cfb4_putc,
-    putcs:		fbcon_cfb4_putcs,
-    revc:		fbcon_cfb4_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_cfb4);
-EXPORT_SYMBOL(fbcon_cfb4_setup);
-EXPORT_SYMBOL(fbcon_cfb4_bmove);
-EXPORT_SYMBOL(fbcon_cfb4_clear);
-EXPORT_SYMBOL(fbcon_cfb4_putc);
-EXPORT_SYMBOL(fbcon_cfb4_putcs);
-EXPORT_SYMBOL(fbcon_cfb4_revc);
diff -Nru a/drivers/video/fbcon-cfb8.c b/drivers/video/fbcon-cfb8.c
--- a/drivers/video/fbcon-cfb8.c	Mon Dec  9 18:46:52 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,294 +0,0 @@
-/*
- *  linux/drivers/video/cfb8.c -- Low level frame buffer operations for 8 bpp
- *				  packed pixels
- *
- *	Created 5 Apr 1997 by Geert Uytterhoeven
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-#include <linux/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-
-
-    /*
-     *  8 bpp packed pixels
-     */
-
-static u32 nibbletab_cfb8[] = {
-#if defined(__BIG_ENDIAN)
-    0x00000000,0x000000ff,0x0000ff00,0x0000ffff,
-    0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff,
-    0xff000000,0xff0000ff,0xff00ff00,0xff00ffff,
-    0xffff0000,0xffff00ff,0xffffff00,0xffffffff
-#elif defined(__LITTLE_ENDIAN)
-    0x00000000,0xff000000,0x00ff0000,0xffff0000,
-    0x0000ff00,0xff00ff00,0x00ffff00,0xffffff00,
-    0x000000ff,0xff0000ff,0x00ff00ff,0xffff00ff,
-    0x0000ffff,0xff00ffff,0x00ffffff,0xffffffff
-#else
-#error FIXME: No endianness??
-#endif
-};
-
-void fbcon_cfb8_setup(struct display *p)
-{
-    p->next_line = p->fb_info->fix.line_length ? p->fb_info->fix.line_length : p->var.xres_virtual;
-    p->next_plane = 0;
-}
-
-void fbcon_cfb8_bmove(struct display *p, int sy, int sx, int dy, int dx,
-		      int height, int width)
-{
-    int bytes = p->next_line, linesize = bytes * fontheight(p), rows;
-    u8 *src,*dst;
-
-    if (sx == 0 && dx == 0 && width * fontwidth(p) == bytes) {
-	fb_memmove(p->fb_info->screen_base + dy * linesize,
-		  p->fb_info->screen_base + sy * linesize,
-		  height * linesize);
-	return;
-    }
-    if (fontwidthlog(p)) {
-    	sx <<= fontwidthlog(p); dx <<= fontwidthlog(p); width <<= fontwidthlog(p);
-    } else {
-    	sx *= fontwidth(p); dx *= fontwidth(p); width *= fontwidth(p);
-    }
-    if (dy < sy || (dy == sy && dx < sx)) {
-	src = p->fb_info->screen_base + sy * linesize + sx;
-	dst = p->fb_info->screen_base + dy * linesize + dx;
-	for (rows = height * fontheight(p) ; rows-- ;) {
-	    fb_memmove(dst, src, width);
-	    src += bytes;
-	    dst += bytes;
-	}
-    } else {
-	src = p->fb_info->screen_base + (sy+height) * linesize + sx - bytes;
-	dst = p->fb_info->screen_base + (dy+height) * linesize + dx - bytes;
-	for (rows = height * fontheight(p) ; rows-- ;) {
-	    fb_memmove(dst, src, width);
-	    src -= bytes;
-	    dst -= bytes;
-	}
-    }
-}
-
-static inline void rectfill(u8 *dest, int width, int height, u8 data,
-			    int linesize)
-{
-    while (height-- > 0) {
-	fb_memset(dest, data, width);
-	dest += linesize;
-    }
-}
-
-void fbcon_cfb8_clear(struct vc_data *conp, struct display *p, int sy, int sx,
-		      int height, int width)
-{
-    u8 *dest;
-    int bytes=p->next_line,lines=height * fontheight(p);
-    u8 bgx;
-
-    dest = p->fb_info->screen_base + sy * fontheight(p) * bytes + sx * fontwidth(p);
-
-    bgx=attr_bgcol_ec(p,conp);
-
-    width *= fontwidth(p);
-    if (width == bytes)
-	rectfill(dest, lines * width, 1, bgx, bytes);
-    else
-	rectfill(dest, width, lines, bgx, bytes);
-}
-
-void fbcon_cfb8_putc(struct vc_data *conp, struct display *p, int c, int yy,
-		     int xx)
-{
-    u8 *dest,*cdat;
-    int bytes=p->next_line,rows;
-    u32 eorx,fgx,bgx;
-
-    dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p);
-    if (fontwidth(p) <= 8)
-	cdat = p->fontdata + (c & p->charmask) * fontheight(p);
-    else
-	cdat = p->fontdata + ((c & p->charmask) * fontheight(p) << 1);
-
-    fgx=attr_fgcol(p,c);
-    bgx=attr_bgcol(p,c);
-    fgx |= (fgx << 8);
-    fgx |= (fgx << 16);
-    bgx |= (bgx << 8);
-    bgx |= (bgx << 16);
-    eorx = fgx ^ bgx;
-
-    switch (fontwidth(p)) {
-    case 4:
-	for (rows = fontheight(p) ; rows-- ; dest += bytes)
-	    fb_writel((nibbletab_cfb8[*cdat++ >> 4] & eorx) ^ bgx, dest);
-        break;
-    case 8:
-	for (rows = fontheight(p) ; rows-- ; dest += bytes) {
-	    fb_writel((nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx, dest);
-	    fb_writel((nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx, dest+4);
-        }
-        break;
-    case 12:
-    case 16:
-	for (rows = fontheight(p) ; rows-- ; dest += bytes) {
-	    fb_writel((nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx, dest);
-	    fb_writel((nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx, dest+4);
-	    fb_writel((nibbletab_cfb8[(*cdat >> 4) & 0xf] & eorx) ^ bgx, dest+8);
-	    if (fontwidth(p) == 16)
-		fb_writel((nibbletab_cfb8[*cdat & 0xf] & eorx) ^ bgx, dest+12);
-	    cdat++;
-        }
-        break;
-    }
-}
-
-void fbcon_cfb8_putcs(struct vc_data *conp, struct display *p, 
-		      const unsigned short *s, int count, int yy, int xx)
-{
-    u8 *cdat, *dest, *dest0;
-    u16 c;
-    int rows,bytes=p->next_line;
-    u32 eorx, fgx, bgx;
-
-    dest0 = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p);
-    c = scr_readw(s);
-    fgx = attr_fgcol(p, c);
-    bgx = attr_bgcol(p, c);
-    fgx |= (fgx << 8);
-    fgx |= (fgx << 16);
-    bgx |= (bgx << 8);
-    bgx |= (bgx << 16);
-    eorx = fgx ^ bgx;
-    switch (fontwidth(p)) {
-    case 4:
-	while (count--) {
-	    c = scr_readw(s++) & p->charmask;
-	    cdat = p->fontdata + c * fontheight(p);
-
-	    for (rows = fontheight(p), dest = dest0; rows-- ; dest += bytes)
-		fb_writel((nibbletab_cfb8[*cdat++ >> 4] & eorx) ^ bgx, dest);
-	    dest0+=4;
-        }
-        break;
-    case 8:
-	while (count--) {
-	    c = scr_readw(s++) & p->charmask;
-	    cdat = p->fontdata + c * fontheight(p);
-
-	    for (rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
-		fb_writel((nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx, dest);
-		fb_writel((nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx, dest+4);
-	    }
-	    dest0+=8;
-        }
-        break;
-    case 12:
-    case 16:
-	while (count--) {
-	    c = scr_readw(s++) & p->charmask;
-	    cdat = p->fontdata + (c * fontheight(p) << 1);
-
-	    for (rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
-		fb_writel((nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx, dest);
-		fb_writel((nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx, dest+4);
-		fb_writel((nibbletab_cfb8[(*cdat >> 4) & 0xf] & eorx) ^ bgx, dest+8);
-		if (fontwidth(p) == 16)
-		   fb_writel((nibbletab_cfb8[*cdat & 0xf] & eorx) ^ bgx, dest+12);
-		cdat++;
-	    }
-	    dest0+=fontwidth(p);
-        }
-        break;
-    }
-}
-
-void fbcon_cfb8_revc(struct display *p, int xx, int yy)
-{
-    u8 *dest;
-    int bytes=p->next_line, rows;
-
-    dest = p->fb_info->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p);
-    for (rows = fontheight(p) ; rows-- ; dest += bytes) {
-    	switch (fontwidth(p)) {
-    	case 16: fb_writel(fb_readl(dest+12) ^ 0x0f0f0f0f, dest+12); /* fall thru */
-    	case 12: fb_writel(fb_readl(dest+8) ^ 0x0f0f0f0f, dest+8); /* fall thru */
-    	case 8: fb_writel(fb_readl(dest+4) ^ 0x0f0f0f0f, dest+4); /* fall thru */
-    	case 4: fb_writel(fb_readl(dest) ^ 0x0f0f0f0f, dest); /* fall thru */
-    	default: break;
-    	}
-    }
-}
-
-void fbcon_cfb8_clear_margins(struct vc_data *conp, struct display *p,
-			      int bottom_only)
-{
-    int bytes=p->next_line;
-    u8 bgx;
-
-    unsigned int right_start = conp->vc_cols*fontwidth(p);
-    unsigned int bottom_start = conp->vc_rows*fontheight(p);
-    unsigned int right_width, bottom_width;
-
-    bgx=attr_bgcol_ec(p,conp);
-
-    if (!bottom_only && (right_width = p->var.xres-right_start))
-	rectfill(p->fb_info->screen_base+right_start, right_width, p->var.yres_virtual, bgx, bytes);
-    if ((bottom_width = p->var.yres-bottom_start))
-	rectfill(p->fb_info->screen_base+(p->var.yoffset+bottom_start)*bytes,
-		 right_start, bottom_width, bgx, bytes);
-}
-
-
-    /*
-     *  `switch' for the low level operations
-     */
-
-struct display_switch fbcon_cfb8 = {
-    setup:		fbcon_cfb8_setup,
-    bmove:		fbcon_cfb8_bmove,
-    clear:		fbcon_cfb8_clear,
-    putc:		fbcon_cfb8_putc,
-    putcs:		fbcon_cfb8_putcs,
-    revc:		fbcon_cfb8_revc,
-    clear_margins:	fbcon_cfb8_clear_margins,
-    fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
-    return 0;
-}
-
-void cleanup_module(void)
-{}
-#endif /* MODULE */
-
-
-    /*
-     *  Visible symbols for modules
-     */
-
-EXPORT_SYMBOL(fbcon_cfb8);
-EXPORT_SYMBOL(fbcon_cfb8_setup);
-EXPORT_SYMBOL(fbcon_cfb8_bmove);
-EXPORT_SYMBOL(fbcon_cfb8_clear);
-EXPORT_SYMBOL(fbcon_cfb8_putc);
-EXPORT_SYMBOL(fbcon_cfb8_putcs);
-EXPORT_SYMBOL(fbcon_cfb8_revc);
-EXPORT_SYMBOL(fbcon_cfb8_clear_margins);
diff -Nru a/drivers/video/fbcon-hga.c b/drivers/video/fbcon-hga.c
--- a/drivers/video/fbcon-hga.c	Mon Dec  9 18:46:35 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,253 +0,0 @@
-/*
- *  linux/drivers/video/fbcon-hga.c -- Low level frame buffer operations for
- *				       the Hercules graphics adaptor
- *
- *	Created 25 Nov 1999 by Ferenc Bakonyi (fero@drama.obuda.kando.hu)
- *	Based on fbcon-mfb.c by Geert Uytterhoeven
- *
- * History:
- *
- * - Revision 0.1.0 (6 Dec 1999): comment changes
- * - First release (25 Nov 1999)
- * 
- *  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 <video/fbcon.h>
-#include <video/fbcon-hga.h>
-
-#if 0
-#define DPRINTK(args...) printk(KERN_DEBUG __FILE__": " ##args)
-#else
-#define DPRINTK(args...)
-#endif
-
-#define HGA_ROWADDR(row) ((row%4)*8192 + (row>>2)*90)
-
-    /*
-     *  Hercules monochrome
-     */
-
-static inline u8* rowaddr(struct display *p, u_int row)
-{
-	return p->fb_info->screen_base + HGA_ROWADDR(row);
-}
-	
-void fbcon_hga_setup(struct display *p)
-{
-	DPRINTK("fbcon_hga_setup: ll:%d\n", (int)p->line_length);
-
-	p->next_line = p->fb_info->fix.line_length;
-	p->next_plane = 0;
-}
-
-void fbcon_hga_bmove(struct display *p, int sy, int sx, int dy, int dx,
-		     int height, int width)
-{
-	u8 *src, *dest;
-	u_int rows, y1, y2;
-	
-#if 0
-	if (sx == 0 && dx == 0 && width == p->next_line) {
-		src = p->fb_info->screen_base+sy*fontheight(p)*width;
-		dest = p->fb_info->screen_base+dy*fontheight(p)*width;
-		fb_memmove(dest, src, height*fontheight(p)*width);
-	} else 
-#endif
-	if (dy <= sy) {
-		y1 = sy*fontheight(p);
-		y2 = dy*fontheight(p);
-		for (rows = height*fontheight(p); rows--; ) {
-			src = rowaddr(p, y1)+sx;
-			dest = rowaddr(p, y2)+dx;
-			fb_memmove(dest, src, width);
-			y1++;
-			y2++;
-		}
-	} else {
-		y1 = (sy+height)*fontheight(p)-1;
-		y2 = (dy+height)*fontheight(p)-1;
-		for (rows = height*fontheight(p); rows--;) {
-			src = rowaddr(p, y1)+sx;
-			dest = rowaddr(p, y2)+dx;
-			fb_memmove(dest, src, width);
-			y1--;
-			y2--;
-		}
-	}
-}
-
-void fbcon_hga_clear(struct vc_data *conp, struct display *p, int sy, int sx,
-		     int height, int width)
-{
-	u8 *dest;
-	u_int rows, y;
-	int inverse = conp ? attr_reverse(p,conp->vc_video_erase_char) : 0;
-
-	DPRINTK("fbcon_hga_clear: sx:%d, sy:%d, height:%d, width:%d\n", sx, sy, height, width);
-	
-	y = sy*fontheight(p);
-#if 0
-	if (sx == 0 && width == p->next_line) {
-		if (inverse) {
-			fb_memset255(dest, height*fontheight(p)*width);
-		} else {
-			fb_memclear(dest, height*fontheight(p)*width);
-		}
-	} else
-#endif	    
-	for (rows = height*fontheight(p); rows--; y++) {
-		dest = rowaddr(p, y)+sx;
-		if (inverse) {
-			fb_memset255(dest, width);
-		} else {
-			fb_memclear(dest, width);
-		}
-	}
-}
-
-void fbcon_hga_putc(struct vc_data *conp, struct display *p, int c, int yy,
-		    int xx)
-{
-	u8 *dest, *cdat;
-	u_int rows, y, bold, revs, underl;
-	u8 d;
-
-	cdat = p->fontdata+(c&p->charmask)*fontheight(p);
-	bold = attr_bold(p, c);
-	revs = attr_reverse(p, c);
-	underl = attr_underline(p, c);
-	y = yy*fontheight(p);
-
-	for (rows = fontheight(p); rows--; y++) {
-		d = *cdat++;
-		if (underl && !rows)
-			d = 0xff;
-		else if (bold)
-			d |= d>>1;
-		if (revs)
-			d = ~d;
-		dest = rowaddr(p, y)+xx;
-		*dest = d;
-	}
-}
-
-void fbcon_hga_putcs(struct vc_data *conp, struct display *p, 
-		     const unsigned short *s, int count, int yy, int xx)
-{
-	u8 *dest, *cdat;
-	u_int rows, y, y0, bold, revs, underl;
-	u8 d;
-	u16 c;
-	
-	c = scr_readw(s);
-	bold = attr_bold(p, c);
-	revs = attr_reverse(p, c);
-	underl = attr_underline(p, c);
-	y0 = yy*fontheight(p);
-
-	while (count--) {
-		c = scr_readw(s++) & p->charmask;
-		cdat = p->fontdata+c*fontheight(p);
-		y = y0;
-		for (rows = fontheight(p); rows--; y++) {
-			d = *cdat++;
-	    		if (underl && !rows)
-				d = 0xff;
-	    		else if (bold)
-				d |= d>>1;
-	    		if (revs)
-				d = ~d;
-			dest = rowaddr(p, y)+xx;
-	    		*dest = d;
-		}
-		xx++;
-	}
-}
-
-void fbcon_hga_revc(struct display *p, int xx, int yy)
-{
-	u8 *dest;
-	u_int rows, y;
-
-	y = yy*fontheight(p);
-	for (rows = fontheight(p); rows--; y++) {
-		dest = rowaddr(p, y)+xx;
-		*dest = ~*dest;
-	}
-}
-
-void fbcon_hga_clear_margins(struct vc_data *conp, struct display *p,
-			     int bottom_only)
-{
-	u8 *dest;
-	u_int height, y;
-	int inverse = conp ? attr_reverse(p,conp->vc_video_erase_char) : 0;
-
-	DPRINTK("fbcon_hga_clear_margins: enter\n");
-
-	/* No need to handle right margin. */
-
-	y = conp->vc_rows * fontheight(p);
-	for (height = p->var.yres - y; height-- > 0; y++) {
-		DPRINTK("fbcon_hga_clear_margins: y:%d, height:%d\n", y, height);
-		dest = rowaddr(p, y);
-		if (inverse) {
-			fb_memset255(dest, p->next_line);
-		} else {
-			fb_memclear(dest, p->next_line);
-		}
-	}
-}
-
-
-	/*
-	 *  `switch' for the low level operations
-	 */
-
-struct display_switch fbcon_hga = {
-	.setup =	fbcon_hga_setup,
-	.bmove =	fbcon_hga_bmove,
-	.clear =	fbcon_hga_clear,
-	.putc =		fbcon_hga_putc,
-	.putcs =	fbcon_hga_putcs,
-	.revc =		fbcon_hga_revc,
-	.clear_margins =fbcon_hga_clear_margins,
-	.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_hga);
-EXPORT_SYMBOL(fbcon_hga_setup);
-EXPORT_SYMBOL(fbcon_hga_bmove);
-EXPORT_SYMBOL(fbcon_hga_clear);
-EXPORT_SYMBOL(fbcon_hga_putc);
-EXPORT_SYMBOL(fbcon_hga_putcs);
-EXPORT_SYMBOL(fbcon_hga_revc);
-EXPORT_SYMBOL(fbcon_hga_clear_margins);
diff -Nru a/drivers/video/fbcon-ilbm.c b/drivers/video/fbcon-ilbm.c
--- a/drivers/video/fbcon-ilbm.c	Mon Dec  9 18:46:35 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,296 +0,0 @@
-/*
- *  linux/drivers/video/ilbm.c -- Low level frame buffer operations for
- *				  interleaved bitplanes à la Amiga
- *
- *	Created 5 Apr 1997 by Geert Uytterhoeven
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-#include <linux/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-ilbm.h>
-
-
-    /*
-     *  Interleaved bitplanes à la Amiga
-     *
-     *  This code heavily relies on the fact that
-     *
-     *      next_line == interleave == next_plane*bits_per_pixel
-     *
-     *  But maybe it can be merged with the code for normal bitplanes without
-     *  much performance loss?
-     */
-
-void fbcon_ilbm_setup(struct display *p)
-{
-    if (p->fb_info->fix.line_length) {
-	p->next_line = p->fb_info->fix.line_length*p->var.bits_per_pixel;
-	p->next_plane = p->fb_info->fix.line_length;
-    } else {
-	p->next_line = p->fb_info->fix.type_aux;
-	p->next_plane = p->fb_info->fix.type_aux/p->var.bits_per_pixel;
-    }
-}
-
-void fbcon_ilbm_bmove(struct display *p, int sy, int sx, int dy, int dx,
-		      int height, int width)
-{
-    if (sx == 0 && dx == 0 && width == p->next_plane)
-	fb_memmove(p->fb_info->screen_base+dy*fontheight(p)*p->next_line,
-		  p->fb_info->screen_base+sy*fontheight(p)*p->next_line,
-		  height*fontheight(p)*p->next_line);
-    else {
-	u8 *src, *dest;
-	u_int i;
-
-	if (dy <= sy) {
-	    src = p->fb_info->screen_base+sy*fontheight(p)*p->next_line+sx;
-	    dest = p->fb_info->screen_base+dy*fontheight(p)*p->next_line+dx;
-	    for (i = p->var.bits_per_pixel*height*fontheight(p); i--;) {
-		fb_memmove(dest, src, width);
-		src += p->next_plane;
-		dest += p->next_plane;
-	    }
-	} else {
-	    src = p->fb_info->screen_base+(sy+height)*fontheight(p)*p->next_line+sx;
-	    dest = p->fb_info->screen_base+(dy+height)*fontheight(p)*p->next_line+dx;
-	    for (i = p->var.bits_per_pixel*height*fontheight(p); i--;) {
-		src -= p->next_plane;
-		dest -= p->next_plane;
-		fb_memmove(dest, src, width);
-	    }
-	}
-    }
-}
-
-void fbcon_ilbm_clear(struct vc_data *conp, struct display *p, int sy, int sx,
-		      int height, int width)
-{
-    u8 *dest;
-    u_int i, rows;
-    int bg, bg0;
-
-    dest = p->fb_info->screen_base+sy*fontheight(p)*p->next_line+sx;
-
-    bg0 = attr_bgcol_ec(p,conp);
-    for (rows = height*fontheight(p); rows--;) {
-	bg = bg0;
-	for (i = p->var.bits_per_pixel; i--; dest += p->next_plane) {
-	    if (bg & 1)
-		fb_memset255(dest, width);
-	    else
-		fb_memclear(dest, width);
-	    bg >>= 1;
-	}
-    }
-}
-
-void fbcon_ilbm_putc(struct vc_data *conp, struct display *p, int c, int yy,
-		     int xx)
-{
-    u8 *dest, *cdat;
-    u_int rows, i;
-    u8 d;
-    int fg0, bg0, fg, bg;
-
-    dest = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
-    cdat = p->fontdata+(c&p->charmask)*fontheight(p);
-    fg0 = attr_fgcol(p,c);
-    bg0 = attr_bgcol(p,c);
-
-    for (rows = fontheight(p); rows--;) {
-	d = *cdat++;
-	fg = fg0;
-	bg = bg0;
-	for (i = p->var.bits_per_pixel; i--; dest += p->next_plane) {
-	    if (bg & 1){
-		if (fg & 1)
-		    *dest = 0xff;
-		else
-		    *dest = ~d;
-	    }else{
-		if (fg & 1)
-		    *dest = d;
-		else
-		    *dest = 0x00;
-	    }
-	    bg >>= 1;
-	    fg >>= 1;
-	}
-    }
-}
-
-    /*
-     *  I've split the console character loop in two parts:
-     *
-     *      - slow version: this blits one character at a time
-     *
-     *      - fast version: this blits 4 characters at a time at a longword
-     *			    aligned address, to reduce the number of expensive
-     *			    Chip RAM accesses.
-     *
-     *  Experiments on my A4000/040 revealed that this makes a console switch
-     *  on a 640x400 screen with 256 colors about 3 times faster.
-     *
-     *  -- Geert
-     */
-
-void fbcon_ilbm_putcs(struct vc_data *conp, struct display *p, 
-		      const unsigned short *s, int count, int yy, int xx)
-{
-    u8 *dest0, *dest, *cdat1, *cdat2, *cdat3, *cdat4;
-    u_int rows, i;
-    u16 c1, c2, c3, c4;
-    u32 d;
-    int fg0, bg0, fg, bg;
-
-    dest0 = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
-    c1 = scr_readw(s);
-    fg0 = attr_fgcol(p, c1);
-    bg0 = attr_bgcol(p, c1);
-
-    while (count--)
-	if (xx&3 || count < 3) {	/* Slow version */
-	    c1 = scr_readw(s++) & p->charmask;
-	    dest = dest0++;
-	    xx++;
-
-	    cdat1 = p->fontdata+c1*fontheight(p);
-	    for (rows = fontheight(p); rows--;) {
-		d = *cdat1++;
-		fg = fg0;
-		bg = bg0;
-		for (i = p->var.bits_per_pixel; i--; dest += p->next_plane) {
-		    if (bg & 1){
-			if (fg & 1)
-			    *dest = 0xff;
-			else
-			    *dest = ~d;
-		    }else{
-			if (fg & 1)
-			    *dest = d;
-			else
-			    *dest = 0x00;
-		    }
-		    bg >>= 1;
-		    fg >>= 1;
-		}
-	    }
-	} else {		/* Fast version */
-	    c1 = scr_readw(&s[0]) & p->charmask;
-	    c2 = scr_readw(&s[1]) & p->charmask;
-	    c3 = scr_readw(&s[2]) & p->charmask;
-	    c4 = scr_readw(&s[3]) & p->charmask;
-
-	    dest = dest0;
-	    cdat1 = p->fontdata+c1*fontheight(p);
-	    cdat2 = p->fontdata+c2*fontheight(p);
-	    cdat3 = p->fontdata+c3*fontheight(p);
-	    cdat4 = p->fontdata+c4*fontheight(p);
-	    for (rows = fontheight(p); rows--;) {
-#if defined(__BIG_ENDIAN)
-		d = *cdat1++<<24 | *cdat2++<<16 | *cdat3++<<8 | *cdat4++;
-#elif defined(__LITTLE_ENDIAN)
-		d = *cdat1++ | *cdat2++<<8 | *cdat3++<<16 | *cdat4++<<24;
-#else
-#error FIXME: No endianness??
-#endif
-		fg = fg0;
-		bg = bg0;
-		for (i = p->var.bits_per_pixel; i--; dest += p->next_plane) {
-		    if (bg & 1){
-			if (fg & 1)
-			    *(u32 *)dest = 0xffffffff;
-			else
-			    *(u32 *)dest = ~d;
-		    }else{
-			if (fg & 1)
-			    *(u32 *)dest = d;
-			else
-			    *(u32 *)dest = 0x00000000;
-		    }
-		    bg >>= 1;
-		    fg >>= 1;
-		}
-	    }
-	    s += 4;
-	    dest0 += 4;
-	    xx += 4;
-	    count -= 3;
-	}
-}
-
-void fbcon_ilbm_revc(struct display *p, int xx, int yy)
-{
-    u8 *dest, *dest0;
-    u_int rows, i;
-    int mask;
-
-    dest0 = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
-    mask = p->fgcol ^ p->bgcol;
-
-    /*
-     *  This should really obey the individual character's
-     *  background and foreground colors instead of simply
-     *  inverting.
-     */
-
-    for (i = p->var.bits_per_pixel; i--; dest0 += p->next_plane) {
-	if (mask & 1) {
-	    dest = dest0;
-	    for (rows = fontheight(p); rows--; dest += p->next_line)
-		*dest = ~*dest;
-	}
-	mask >>= 1;
-    }
-}
-
-
-    /*
-     *  `switch' for the low level operations
-     */
-
-struct display_switch fbcon_ilbm = {
-    setup:		fbcon_ilbm_setup,
-    bmove:		fbcon_ilbm_bmove,
-    clear:		fbcon_ilbm_clear,
-    putc:		fbcon_ilbm_putc,
-    putcs:		fbcon_ilbm_putcs,
-    revc:		fbcon_ilbm_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_ilbm);
-EXPORT_SYMBOL(fbcon_ilbm_setup);
-EXPORT_SYMBOL(fbcon_ilbm_bmove);
-EXPORT_SYMBOL(fbcon_ilbm_clear);
-EXPORT_SYMBOL(fbcon_ilbm_putc);
-EXPORT_SYMBOL(fbcon_ilbm_putcs);
-EXPORT_SYMBOL(fbcon_ilbm_revc);
diff -Nru a/drivers/video/fbcon-iplan2p2.c b/drivers/video/fbcon-iplan2p2.c
--- a/drivers/video/fbcon-iplan2p2.c	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,476 +0,0 @@
-/*
- *  linux/drivers/video/fbcon-iplan2p2.c -- Low level frame buffer operations
- *				  for interleaved bitplanes à la Atari (2
- *				  planes, 2 bytes interleave)
- *
- *	Created 5 Apr 1997 by Geert Uytterhoeven
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-#include <linux/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-
-#include <asm/byteorder.h>
-
-#ifdef __mc68000__
-#include <asm/setup.h>
-#endif
-
-#include <video/fbcon.h>
-#include <video/fbcon-iplan2p2.h>
-
-
-    /*
-     *  Interleaved bitplanes à la Atari (2 planes, 2 bytes interleave)
-     */
-
-/* Increment/decrement 2 plane addresses */
-
-#define	INC_2P(p)	do { if (!((long)(++(p)) & 1)) (p) += 2; } while(0)
-#define	DEC_2P(p)	do { if ((long)(--(p)) & 1) (p) -= 2; } while(0)
-
-    /*  Convert a standard 4 bit color to our 2 bit color assignment:
-     *  If at least two RGB channels are active, the low bit is turned on;
-     *  The intensity bit (b3) is shifted into b1.
-     */
-
-static const u8 color_2p[] = { 0, 0, 0, 1, 0, 1, 1, 1, 2, 2, 2, 3, 2, 3, 3, 3 };
-#define	COLOR_2P(c)	color_2p[c]
-
-/* Perform the m68k movepw operation.  */
-static inline void movepw(u8 *d, u16 val)
-{
-#if defined __mc68000__ && !defined CPU_M68060_ONLY
-    asm volatile ("movepw %1,%0@(0)" : : "a" (d), "d" (val));
-#else
-    d[0] = (val >> 16) & 0xff;
-    d[2] = val & 0xff;
-#endif
-}
-
-/* Sets the bytes in the visible column at d, height h, to the value
- * val for a 2 plane screen. The bits of the color in 'color' are
- * moved (8 times) to the respective bytes. This means:
- *
- * for(h times; d += bpr)
- *   *d     = (color & 1) ? 0xff : 0;
- *   *(d+2) = (color & 2) ? 0xff : 0;
- */
-
-static __inline__ void memclear_2p_col(void *d, size_t h, u16 val, int bpr)
-{
-    u8 *dd = d;
-    do {
-	movepw(dd, val);
-	dd += bpr;
-    } while (--h);
-}
-
-/* Sets a 2 plane region from 'd', length 'count' bytes, to the color
- * in val1. 'd' has to be an even address and count must be divisible
- * by 8, because only whole words and all planes are accessed. I.e.:
- *
- * for(count/4 times)
- *   *d     = *(d+1) = (color & 1) ? 0xff : 0;
- *   *(d+2) = *(d+3) = (color & 2) ? 0xff : 0;
- */
-
-static __inline__ void memset_even_2p(void *d, size_t count, u32 val)
-{
-    u32 *dd = d;
-
-    count /= 4;
-    while (count--)
-	*dd++ = val;
-}
-
-/* Copies a 2 plane column from 's', height 'h', to 'd'. */
-
-static __inline__ void memmove_2p_col (void *d, void *s, int h, int bpr)
-{
-    u8 *dd = d, *ss = s;
-
-    while (h--) {
-	dd[0] = ss[0];
-	dd[2] = ss[2];
-	dd += bpr;
-	ss += bpr;
-    }
-}
-
-
-/* This expands a 2 bit color into a short for movepw (2 plane) operations. */
-
-static const u16 two2byte[] = {
-    0x0000, 0xff00, 0x00ff, 0xffff
-};
-
-static __inline__ u16 expand2w(u8 c)
-{
-    return two2byte[c];
-}
-
-
-/* This expands a 2 bit color into one long for a movel operation
- * (2 planes).
- */
-
-static const u32 two2word[] = {
-#ifndef __LITTLE_ENDIAN
-    0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff
-#else
-    0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
-#endif
-};
-
-static __inline__ u32 expand2l(u8 c)
-{
-    return two2word[c];
-}
-
-
-/* This duplicates a byte 2 times into a short. */
-
-static __inline__ u16 dup2w(u8 c)
-{
-    u16 rv;
-
-    rv = c;
-    rv |= c << 8;
-    return rv;
-}
-
-
-void fbcon_iplan2p2_setup(struct display *p)
-{
-    p->next_line = p->var.xres_virtual>>2;
-    p->next_plane = 2;
-}
-
-void fbcon_iplan2p2_bmove(struct display *p, int sy, int sx, int dy, int dx,
-			  int height, int width)
-{
-    /*  bmove() has to distinguish two major cases: If both, source and
-     *  destination, start at even addresses or both are at odd
-     *  addresses, just the first odd and last even column (if present)
-     *  require special treatment (memmove_col()). The rest between
-     *  then can be copied by normal operations, because all adjacent
-     *  bytes are affected and are to be stored in the same order.
-     *    The pathological case is when the move should go from an odd
-     *  address to an even or vice versa. Since the bytes in the plane
-     *  words must be assembled in new order, it seems wisest to make
-     *  all movements by memmove_col().
-     */
-
-    if (sx == 0 && dx == 0 && width * 2 == p->next_line) {
-	/*  Special (but often used) case: Moving whole lines can be
-	 *  done with memmove()
-	 */
-	fb_memmove(p->fb_info->screen_base + dy * p->next_line * fontheight(p),
-		  p->fb_info->screen_base + sy * p->next_line * fontheight(p),
-		  p->next_line * height * fontheight(p));
-    } else {
-	int rows, cols;
-	u8 *src;
-	u8 *dst;
-	int bytes = p->next_line;
-	int linesize;
-	u_int colsize;
-	u_int upwards  = (dy < sy) || (dy == sy && dx < sx);
-
-	if (fontheightlog(p)) {
-	    linesize = bytes << fontheightlog(p);
-	    colsize = height << fontheightlog(p);
-	} else {
-	    linesize = bytes * fontheight(p);
-	    colsize = height * fontheight(p);
-	}
-	if ((sx & 1) == (dx & 1)) {
-	    /* odd->odd or even->even */
-	    if (upwards) {
-		src = p->fb_info->screen_base + sy * linesize + (sx>>1)*4 + (sx & 1);
-		dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*4 + (dx & 1);
-		if (sx & 1) {
-		    memmove_2p_col(dst, src, colsize, bytes);
-		    src += 3;
-		    dst += 3;
-		    --width;
-		}
-		if (width > 1) {
-		    for (rows = colsize; rows > 0; --rows) {
-			fb_memmove(dst, src, (width>>1)*4);
-			src += bytes;
-			dst += bytes;
-		    }
-		}
-		if (width & 1) {
-		    src -= colsize * bytes;
-		    dst -= colsize * bytes;
-		    memmove_2p_col(dst + (width>>1)*4, src + (width>>1)*4,
-				   colsize, bytes);
-		}
-	    } else {
-		if (!((sx+width-1) & 1)) {
-		    src = p->fb_info->screen_base + sy * linesize + ((sx+width-1)>>1)*4;
-		    dst = p->fb_info->screen_base + dy * linesize + ((dx+width-1)>>1)*4;
-		    memmove_2p_col(dst, src, colsize, bytes);
-		    --width;
-		}
-		src = p->fb_info->screen_base + sy * linesize + (sx>>1)*4 + (sx & 1);
-		dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*4 + (dx & 1);
-		if (width > 1) {
-		    src += colsize * bytes + (sx & 1)*3;
-		    dst += colsize * bytes + (sx & 1)*3;
-		    for(rows = colsize; rows > 0; --rows) {
-			src -= bytes;
-			dst -= bytes;
-			fb_memmove(dst, src, (width>>1)*4);
-		    }
-		}
-		if (width & 1)
-		    memmove_2p_col(dst-3, src-3, colsize, bytes);
-	    }
-	} else {
-	    /* odd->even or even->odd */
-	    if (upwards) {
-		src = p->fb_info->screen_base + sy * linesize + (sx>>1)*4 + (sx & 1);
-		dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*4 + (dx & 1);
-		for (cols = width; cols > 0; --cols) {
-		    memmove_2p_col(dst, src, colsize, bytes);
-		    INC_2P(src);
-		    INC_2P(dst);
-		}
-	    } else {
-		sx += width-1;
-		dx += width-1;
-		src = p->fb_info->screen_base + sy * linesize + (sx>>1)*4 + (sx & 1);
-		dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*4 + (dx & 1);
-		for(cols = width; cols > 0; --cols) {
-		    memmove_2p_col(dst, src, colsize, bytes);
-		    DEC_2P(src);
-		    DEC_2P(dst);
-		}
-	    }
-	}
-    }
-}
-
-void fbcon_iplan2p2_clear(struct vc_data *conp, struct display *p, int sy,
-			  int sx, int height, int width)
-{
-    u32 offset;
-    u8 *start;
-    int rows;
-    int bytes = p->next_line;
-    int lines;
-    u32 size;
-    u32 cval;
-    u16 pcval;
-
-    cval = expand2l (COLOR_2P (attr_bgcol_ec(p,conp)));
-
-    if (fontheightlog(p))
-	lines = height << fontheightlog(p);
-    else
-	lines = height * fontheight(p);
-
-    if (sx == 0 && width * 2 == bytes) {
-	if (fontheightlog(p))
-	    offset = (sy * bytes) << fontheightlog(p);
-	else
-	    offset = sy * bytes * fontheight(p);
-	size = lines * bytes;
-	memset_even_2p(p->fb_info->screen_base+offset, size, cval);
-    } else {
-	if (fontheightlog(p))
-	    offset = ((sy * bytes) << fontheightlog(p)) + (sx>>1)*4 + (sx & 1);
-	else
-	    offset = sy * bytes * fontheight(p) + (sx>>1)*4 + (sx & 1);
-	start = p->fb_info->screen_base + offset;
-	pcval = expand2w(COLOR_2P(attr_bgcol_ec(p,conp)));
-
-	/*  Clears are split if the region starts at an odd column or
-	 *  end at an even column. These extra columns are spread
-	 *  across the interleaved planes. All in between can be
-	 *  cleared by normal fb_memclear_small(), because both bytes of
-	 *  the single plane words are affected.
-	 */
-
-	if (sx & 1) {
-	    memclear_2p_col(start, lines, pcval, bytes);
-	    start += 3;
-	    width--;
-	}
-	if (width & 1) {
-	    memclear_2p_col(start + (width>>1)*4, lines, pcval, bytes);
-	    width--;
-	}
-	if (width) {
-	    for (rows = lines; rows-- ; start += bytes)
-	    memset_even_2p(start, width*2, cval);
-	}
-    }
-}
-
-void fbcon_iplan2p2_putc(struct vc_data *conp, struct display *p, int c,
-			 int yy, int xx)
-{
-    u8 *dest;
-    u8 *cdat;
-    int rows;
-    int bytes = p->next_line;
-    u16 eorx, fgx, bgx, fdx;
-
-    if (fontheightlog(p)) {
-	dest = (p->fb_info->screen_base + ((yy * bytes) << fontheightlog(p)) +
-		(xx>>1)*4 + (xx & 1));
-	cdat = p->fontdata + ((c & p->charmask) << fontheightlog(p));
-    } else {
-	dest = (p->fb_info->screen_base + yy * bytes * fontheight(p) +
-		(xx>>1)*4 + (xx & 1));
-	cdat = p->fontdata + (c & p->charmask) * fontheight(p);
-    }
-
-    fgx = expand2w(COLOR_2P(attr_fgcol(p,c)));
-    bgx = expand2w(COLOR_2P(attr_bgcol(p,c)));
-    eorx = fgx ^ bgx;
-
-    for (rows = fontheight(p) ; rows-- ; dest += bytes) {
-	fdx = dup2w(*cdat++);
-	movepw(dest, (fdx & eorx) ^ bgx);
-    }
-}
-
-void fbcon_iplan2p2_putcs(struct vc_data *conp, struct display *p,
-			  const unsigned short *s, int count, int yy, int xx)
-{
-    u8 *dest, *dest0;
-    u8 *cdat;
-    u16 c;
-    int rows;
-    int bytes;
-    u16 eorx, fgx, bgx, fdx;
-
-    bytes = p->next_line;
-    if (fontheightlog(p))
-	dest0 = (p->fb_info->screen_base + ((yy * bytes) << fontheightlog(p)) +
-		 (xx>>1)*4 + (xx & 1));
-    else
-	dest0 = (p->fb_info->screen_base + yy * bytes * fontheight(p) +
-		 (xx>>1)*4 + (xx & 1));
-    c = scr_readw(s);
-    fgx = expand2w(COLOR_2P(attr_fgcol(p, c)));
-    bgx = expand2w(COLOR_2P(attr_bgcol(p, c)));
-    eorx = fgx ^ bgx;
-
-    while (count--) {
-	c = scr_readw(s++) & p->charmask;
-	if (fontheightlog(p))
-	    cdat = p->fontdata + (c << fontheightlog(p));
-	else
-	    cdat = p->fontdata + c * fontheight(p);
-
-	for (rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
-	    fdx = dup2w(*cdat++);
-	    movepw(dest, (fdx & eorx) ^ bgx);
-	}
-	INC_2P(dest0);
-    }
-}
-
-void fbcon_iplan2p2_revc(struct display *p, int xx, int yy)
-{
-    u8 *dest;
-    int j;
-    int bytes;
-
-    if (fontheightlog(p))
-	dest = (p->fb_info->screen_base + ((yy * p->next_line) << fontheightlog(p)) + (xx>>1)*4 + (xx & 1));
-    else
-	dest = (p->fb_info->screen_base + yy * p->next_line * fontheight(p) +
-		(xx>>1)*4 + (xx & 1));
-    j = fontheight(p);
-    bytes = p->next_line;
-    while (j--) {
-	/*  This should really obey the individual character's
-	 *  background and foreground colors instead of simply
-	 *  inverting.
-	 */
-	dest[0] = ~dest[0];
-	dest[2] = ~dest[2];
-	dest += bytes;
-    }
-}
-
-void fbcon_iplan2p2_clear_margins(struct vc_data *conp, struct display *p,
-				  int bottom_only)
-{
-    u32 offset;
-    int bytes;
-    int lines;
-    u32 cval;
-
-/* No need to handle right margin, cannot occur with fontwidth == 8 */
-
-    bytes = p->next_line;
-    if (fontheightlog(p)) {
-	lines = p->var.yres - (conp->vc_rows << fontheightlog(p));
-	offset = ((p->yscroll + conp->vc_rows) * bytes) << fontheightlog(p);
-    } else {
-	lines = p->var.yres - conp->vc_rows * fontheight(p);
-	offset = (p->yscroll + conp->vc_rows) * bytes * fontheight(p);
-    }
-    if (lines) {
-	cval = expand2l(COLOR_2P(attr_bgcol_ec(p,conp)));
-	memset_even_2p(p->fb_info->screen_base+offset, lines * bytes, cval);
-    }
-}
-
-
-    /*
-     *  `switch' for the low level operations
-     */
-
-struct display_switch fbcon_iplan2p2 = {
-    setup:		fbcon_iplan2p2_setup,
-    bmove:		fbcon_iplan2p2_bmove,
-    clear:		fbcon_iplan2p2_clear,
-    putc:		fbcon_iplan2p2_putc,
-    putcs:		fbcon_iplan2p2_putcs,
-    revc:		fbcon_iplan2p2_revc,
-    clear_margins:	fbcon_iplan2p2_clear_margins,
-    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_iplan2p2);
-EXPORT_SYMBOL(fbcon_iplan2p2_setup);
-EXPORT_SYMBOL(fbcon_iplan2p2_bmove);
-EXPORT_SYMBOL(fbcon_iplan2p2_clear);
-EXPORT_SYMBOL(fbcon_iplan2p2_putc);
-EXPORT_SYMBOL(fbcon_iplan2p2_putcs);
-EXPORT_SYMBOL(fbcon_iplan2p2_revc);
-EXPORT_SYMBOL(fbcon_iplan2p2_clear_margins);
diff -Nru a/drivers/video/fbcon-iplan2p4.c b/drivers/video/fbcon-iplan2p4.c
--- a/drivers/video/fbcon-iplan2p4.c	Mon Dec  9 18:46:35 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,497 +0,0 @@
-/*
- *  linux/drivers/video/fbcon-iplan2p4.c -- Low level frame buffer operations
- *				   for interleaved bitplanes à la Atari (4
- *				   planes, 2 bytes interleave)
- *
- *	Created 5 Apr 1997 by Geert Uytterhoeven
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-#include <linux/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-
-#include <asm/byteorder.h>
-
-#ifdef __mc68000__
-#include <asm/setup.h>
-#endif
-
-#include <video/fbcon.h>
-#include <video/fbcon-iplan2p4.h>
-
-
-    /*
-     *  Interleaved bitplanes à la Atari (4 planes, 2 bytes interleave)
-     */
-
-/* Increment/decrement 4 plane addresses */
-
-#define	INC_4P(p)	do { if (!((long)(++(p)) & 1)) (p) += 6; } while(0)
-#define	DEC_4P(p)	do { if ((long)(--(p)) & 1) (p) -= 6; } while(0)
-
-/* Perform the m68k movepl operation.  */
-static inline void movepl(u8 *d, u32 val)
-{
-#if defined __mc68000__ && !defined CPU_M68060_ONLY
-    asm volatile ("movepl %1,%0@(0)" : : "a" (d), "d" (val));
-#else
-    d[0] = (val >> 24) & 0xff;
-    d[2] = (val >> 16) & 0xff;
-    d[4] = (val >> 8) & 0xff;
-    d[6] = val & 0xff;
-#endif
-}
-
-/* Sets the bytes in the visible column at d, height h, to the value
- * val for a 4 plane screen. The bits of the color in 'color' are
- * moved (8 times) to the respective bytes. This means:
- *
- * for(h times; d += bpr)
- *   *d     = (color & 1) ? 0xff : 0;
- *   *(d+2) = (color & 2) ? 0xff : 0;
- *   *(d+4) = (color & 4) ? 0xff : 0;
- *   *(d+6) = (color & 8) ? 0xff : 0;
- */
-
-static __inline__ void memclear_4p_col(void *d, size_t h, u32 val, int bpr)
-{
-    u8 *dd = d;
-    do {
-	movepl(dd, val);
-	dd += bpr;
-    } while (--h);
-}
-
-/* Sets a 4 plane region from 'd', length 'count' bytes, to the color
- * in val1/val2. 'd' has to be an even address and count must be divisible
- * by 8, because only whole words and all planes are accessed. I.e.:
- *
- * for(count/8 times)
- *   *d     = *(d+1) = (color & 1) ? 0xff : 0;
- *   *(d+2) = *(d+3) = (color & 2) ? 0xff : 0;
- *   *(d+4) = *(d+5) = (color & 4) ? 0xff : 0;
- *   *(d+6) = *(d+7) = (color & 8) ? 0xff : 0;
- */
-
-static __inline__ void memset_even_4p(void *d, size_t count, u32 val1,
-                                      u32 val2)
-{
-    u32 *dd = d;
-
-    count /= 8;
-    while (count--) {
-	*dd++ = val1;
-	*dd++ = val2;
-    }
-}
-
-/* Copies a 4 plane column from 's', height 'h', to 'd'. */
-
-static __inline__ void memmove_4p_col (void *d, void *s, int h, int bpr)
-{
-    u8 *dd = d, *ss = s;
-
-    while (h--) {
-	dd[0] = ss[0];
-	dd[2] = ss[2];
-	dd[4] = ss[4];
-	dd[6] = ss[6];
-	dd += bpr;
-	ss += bpr;
-    }
-}
-
-
-/* This expands a 4 bit color into a long for movepl (4 plane) operations. */
-
-static const u32 four2byte[] = {
-    0x00000000, 0xff000000, 0x00ff0000, 0xffff0000,
-    0x0000ff00, 0xff00ff00, 0x00ffff00, 0xffffff00,
-    0x000000ff, 0xff0000ff, 0x00ff00ff, 0xffff00ff,
-    0x0000ffff, 0xff00ffff, 0x00ffffff, 0xffffffff
-};
-
-static __inline__ u32 expand4l(u8 c)
-{
-    return four2byte[c];
-}
-
-
-/* This expands a 4 bit color into two longs for two movel operations
- * (4 planes).
- */
-
-static const u32 two2word[] = {
-#ifndef __LITTLE_ENDIAN
-    0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff,
-#else
-    0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff,
-#endif
-};
-
-static __inline__ void expand4dl(u8 c, u32 *ret1, u32 *ret2)
-{
-    *ret1 = two2word[c & 3];
-    *ret2 = two2word[c >> 2];
-}
-
-
-/* This duplicates a byte 4 times into a long. */
-
-static __inline__ u32 dup4l(u8 c)
-{
-    u32 rv;
-
-    rv = c;
-    rv |= rv << 8;
-    rv |= rv << 16;
-    return rv;
-}
-
-
-void fbcon_iplan2p4_setup(struct display *p)
-{
-    p->next_line = p->var.xres_virtual>>1;
-    p->next_plane = 2;
-}
-
-void fbcon_iplan2p4_bmove(struct display *p, int sy, int sx, int dy, int dx,
-			  int height, int width)
-{
-    /*  bmove() has to distinguish two major cases: If both, source and
-     *  destination, start at even addresses or both are at odd
-     *  addresses, just the first odd and last even column (if present)
-     *  require special treatment (memmove_col()). The rest between
-     *  then can be copied by normal operations, because all adjacent
-     *  bytes are affected and are to be stored in the same order.
-     *    The pathological case is when the move should go from an odd
-     *  address to an even or vice versa. Since the bytes in the plane
-     *  words must be assembled in new order, it seems wisest to make
-     *  all movements by memmove_col().
-     */
-
-    if (sx == 0 && dx == 0 && width * 4 == p->next_line) {
-	/*  Special (but often used) case: Moving whole lines can be
-	 *done with memmove()
-	 */
-	fb_memmove(p->fb_info->screen_base + dy * p->next_line * fontheight(p),
-		  p->fb_info->screen_base + sy * p->next_line * fontheight(p),
-		  p->next_line * height * fontheight(p));
-    } else {
-	int rows, cols;
-	u8 *src;
-	u8 *dst;
-	int bytes = p->next_line;
-	int linesize;
-	u_int colsize;
-	u_int upwards  = (dy < sy) || (dy == sy && dx < sx);
-
-	if (fontheightlog(p)) {
-	    linesize = bytes << fontheightlog(p);
-	    colsize = height << fontheightlog(p);
-	} else {
-	    linesize = bytes * fontheight(p);
-	    colsize = height * fontheight(p);
-	}
-	if ((sx & 1) == (dx & 1)) {
-	    /* odd->odd or even->even */
-
-	    if (upwards) {
-		src = p->fb_info->screen_base + sy * linesize + (sx>>1)*8 + (sx & 1);
-		dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*8 + (dx & 1);
-		if (sx & 1) {
-		    memmove_4p_col(dst, src, colsize, bytes);
-		    src += 7;
-		    dst += 7;
-		    --width;
-		}
-		if (width > 1) {
-		    for(rows = colsize; rows > 0; --rows) {
-			fb_memmove(dst, src, (width>>1)*8);
-			src += bytes;
-			dst += bytes;
-		    }
-		}
-		if (width & 1) {
-		    src -= colsize * bytes;
-		    dst -= colsize * bytes;
-		    memmove_4p_col(dst + (width>>1)*8, src + (width>>1)*8,
-		    colsize, bytes);
-		}
-	    } else {
-		if (!((sx+width-1) & 1)) {
-		    src = p->fb_info->screen_base + sy * linesize + ((sx+width-1)>>1)*8;
-		    dst = p->fb_info->screen_base + dy * linesize + ((dx+width-1)>>1)*8;
-		    memmove_4p_col(dst, src, colsize, bytes);
-		    --width;
-		}
-		src = p->fb_info->screen_base + sy * linesize + (sx>>1)*8 + (sx & 1);
-		dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*8 + (dx & 1);
-		if (width > 1) {
-		    src += colsize * bytes + (sx & 1)*7;
-		    dst += colsize * bytes + (sx & 1)*7;
-		    for(rows = colsize; rows > 0; --rows) {
-			src -= bytes;
-			dst -= bytes;
-			fb_memmove(dst, src, (width>>1)*8);
-		    }
-		}
-		if (width & 1) {
-		memmove_4p_col(dst-7, src-7, colsize, bytes);
-		}
-	    }
-	} else {
-	/* odd->even or even->odd */
-
-	    if (upwards) {
-		src = p->fb_info->screen_base + sy * linesize + (sx>>1)*8 + (sx & 1);
-		dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*8 + (dx & 1);
-		for(cols = width; cols > 0; --cols) {
-		    memmove_4p_col(dst, src, colsize, bytes);
-		    INC_4P(src);
-		    INC_4P(dst);
-		}
-	    } else {
-		sx += width-1;
-		dx += width-1;
-		src = p->fb_info->screen_base + sy * linesize + (sx>>1)*8 + (sx & 1);
-		dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*8 + (dx & 1);
-		for(cols = width; cols > 0; --cols) {
-		    memmove_4p_col(dst, src, colsize, bytes);
-		    DEC_4P(src);
-		    DEC_4P(dst);
-		}
-	    }
-	}
-    }
-}
-
-void fbcon_iplan2p4_clear(struct vc_data *conp, struct display *p, int sy,
-			  int sx, int height, int width)
-{
-    u32 offset;
-    u8 *start;
-    int rows;
-    int bytes = p->next_line;
-    int lines;
-    u32 size;
-    u32 cval1, cval2, pcval;
-
-    expand4dl(attr_bgcol_ec(p,conp), &cval1, &cval2);
-
-    if (fontheightlog(p))
-	lines = height << fontheightlog(p);
-    else
-	lines = height * fontheight(p);
-
-    if (sx == 0 && width * 4 == bytes) {
-	if (fontheightlog(p))
-	    offset = (sy * bytes) << fontheightlog(p);
-	else
-	    offset = sy * bytes * fontheight(p);
-	size = lines * bytes;
-	memset_even_4p(p->fb_info->screen_base+offset, size, cval1, cval2);
-    } else {
-	if (fontheightlog(p))
-	    offset = ((sy * bytes) << fontheightlog(p)) + (sx>>1)*8 + (sx & 1);
-	else
-	    offset = sy * bytes * fontheight(p) + (sx>>1)*8 + (sx & 1);
-	start = p->fb_info->screen_base + offset;
-	pcval = expand4l(attr_bgcol_ec(p,conp));
-
-	/*  Clears are split if the region starts at an odd column or
-	 *  end at an even column. These extra columns are spread
-	 *  across the interleaved planes. All in between can be
-	 *  cleared by normal fb_memclear_small(), because both bytes of
-	 *  the single plane words are affected.
-	 */
-
-	if (sx & 1) {
-	    memclear_4p_col(start, lines, pcval, bytes);
-	    start += 7;
-	    width--;
-	}
-	if (width & 1) {
-	    memclear_4p_col(start + (width>>1)*8, lines, pcval, bytes);
-	    width--;
-	}
-	if (width) {
-	    for(rows = lines; rows-- ; start += bytes)
-		memset_even_4p(start, width*4, cval1, cval2);
-	}
-    }
-}
-
-void fbcon_iplan2p4_putc(struct vc_data *conp, struct display *p, int c,
-			 int yy, int xx)
-{
-    u8 *dest;
-    u8 *cdat;
-    int rows;
-    int bytes = p->next_line;
-    u32 eorx, fgx, bgx, fdx;
-
-    if (fontheightlog(p)) {
-	dest = (p->fb_info->screen_base + ((yy * bytes) << fontheightlog(p)) +
-		(xx>>1)*8 + (xx & 1));
-	cdat = p->fontdata + ((c & p->charmask) << fontheightlog(p));
-    } else {
-	dest = (p->fb_info->screen_base + yy * bytes * fontheight(p) +
-		(xx>>1)*8 + (xx & 1));
-	cdat = p->fontdata + (c & p->charmask) * fontheight(p);
-    }
-
-    fgx = expand4l(attr_fgcol(p,c));
-    bgx = expand4l(attr_bgcol(p,c));
-    eorx = fgx ^ bgx;
-
-    for(rows = fontheight(p) ; rows-- ; dest += bytes) {
-	fdx = dup4l(*cdat++);
-	movepl(dest, (fdx & eorx) ^ bgx);
-    }
-}
-
-void fbcon_iplan2p4_putcs(struct vc_data *conp, struct display *p,
-			  const unsigned short *s, int count, int yy, int xx)
-{
-    u8 *dest, *dest0;
-    u8 *cdat;
-    u16 c;
-    int rows;
-    int bytes;
-    u32 eorx, fgx, bgx, fdx;
-
-    bytes = p->next_line;
-    if (fontheightlog(p))
-	dest0 = (p->fb_info->screen_base + ((yy * bytes) << fontheightlog(p)) +
-		 (xx>>1)*8 + (xx & 1));
-    else
-	dest0 = (p->fb_info->screen_base + yy * bytes * fontheight(p) +
-		 (xx>>1)*8 + (xx & 1));
-    c = scr_readw(s);
-    fgx = expand4l(attr_fgcol(p, c));
-    bgx = expand4l(attr_bgcol(p, c));
-    eorx = fgx ^ bgx;
-
-    while (count--) {
-	/* I think, unrolling the loops like in the 1 plane case isn't
-	* practicable here, because the body is much longer for 4
-	* planes (mostly the dup4l()). I guess, unrolling this would
-	* need more than 256 bytes and so exceed the instruction
-	* cache :-(
-	*/
-
-	c = scr_readw(s++) & p->charmask;
-	if (fontheightlog(p))
-	    cdat = p->fontdata + (c << fontheightlog(p));
-	else
-	    cdat = p->fontdata + c * fontheight(p);
-
-	for(rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
-	    fdx = dup4l(*cdat++);
-	    movepl(dest, (fdx & eorx) ^ bgx);
-	}
-	INC_4P(dest0);
-    }
-}
-
-void fbcon_iplan2p4_revc(struct display *p, int xx, int yy)
-{
-    u8 *dest;
-    int j;
-    int bytes;
-
-    if (fontheightlog(p))
-	dest = (p->fb_info->screen_base + ((yy * p->next_line) << fontheightlog(p)) +
-		(xx>>1)*8 + (xx & 1));
-    else
-	dest = (p->fb_info->screen_base + yy * p->next_line * fontheight(p) +
-		(xx>>1)*8 + (xx & 1));
-    j = fontheight(p);
-    bytes = p->next_line;
-
-    while (j--) {
-	/*  This should really obey the individual character's
-	 *  background and foreground colors instead of simply
-	 *  inverting.
-	 */
-	dest[0] = ~dest[0];
-	dest[2] = ~dest[2];
-	dest[4] = ~dest[4];
-	dest[6] = ~dest[6];
-	dest += bytes;
-    }
-}
-
-void fbcon_iplan2p4_clear_margins(struct vc_data *conp, struct display *p,
-				  int bottom_only)
-{
-    u32 offset;
-    int bytes;
-    int lines;
-    u32 cval1, cval2;
-
-/* No need to handle right margin, cannot occur with fontwidth == 8 */
-
-    bytes = p->next_line;
-    if (fontheightlog(p)) {
-	lines = p->var.yres - (conp->vc_rows << fontheightlog(p));
-	offset = ((p->yscroll + conp->vc_rows) * bytes) << fontheightlog(p);
-    } else {
-	lines = p->var.yres - conp->vc_rows * fontheight(p);
-	offset = (p->yscroll + conp->vc_rows) * bytes * fontheight(p);
-    }
-    if (lines) {
-	expand4dl(attr_bgcol_ec(p,conp), &cval1, &cval2);
-	memset_even_4p(p->fb_info->screen_base+offset, lines * bytes, cval1, cval2);
-    }
-}
-
-
-    /*
-     *  `switch' for the low level operations
-     */
-
-struct display_switch fbcon_iplan2p4 = {
-    setup:		fbcon_iplan2p4_setup,
-    bmove:		fbcon_iplan2p4_bmove,
-    clear:		fbcon_iplan2p4_clear,
-    putc:		fbcon_iplan2p4_putc,
-    putcs:		fbcon_iplan2p4_putcs,
-    revc:		fbcon_iplan2p4_revc,
-    clear_margins:	fbcon_iplan2p4_clear_margins,
-    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_iplan2p4);
-EXPORT_SYMBOL(fbcon_iplan2p4_setup);
-EXPORT_SYMBOL(fbcon_iplan2p4_bmove);
-EXPORT_SYMBOL(fbcon_iplan2p4_clear);
-EXPORT_SYMBOL(fbcon_iplan2p4_putc);
-EXPORT_SYMBOL(fbcon_iplan2p4_putcs);
-EXPORT_SYMBOL(fbcon_iplan2p4_revc);
-EXPORT_SYMBOL(fbcon_iplan2p4_clear_margins);
diff -Nru a/drivers/video/fbcon-iplan2p8.c b/drivers/video/fbcon-iplan2p8.c
--- a/drivers/video/fbcon-iplan2p8.c	Mon Dec  9 18:46:51 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,534 +0,0 @@
-/*
- *  linux/drivers/video/iplan2p8.c -- Low level frame buffer operations for
- *				      interleaved bitplanes à la Atari (8
- *				      planes, 2 bytes interleave)
- *
- *	Created 5 Apr 1997 by Geert Uytterhoeven
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-#include <linux/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-
-#include <asm/byteorder.h>
-
-#ifdef __mc68000__
-#include <asm/setup.h>
-#endif
-
-#include <video/fbcon.h>
-#include <video/fbcon-iplan2p8.h>
-
-
-    /*
-     *  Interleaved bitplanes à la Atari (8 planes, 2 bytes interleave)
-     *
-     *  In 8 plane mode, 256 colors would be possible, but only the first
-     *  16 are used by the console code (the upper 4 bits are
-     *  background/unused). For that, the following functions mask off the
-     *  higher 4 bits of each color.
-     */
-
-/* Increment/decrement 8 plane addresses */
-
-#define	INC_8P(p)	do { if (!((long)(++(p)) & 1)) (p) += 14; } while(0)
-#define	DEC_8P(p)	do { if ((long)(--(p)) & 1) (p) -= 14; } while(0)
-
-/* Perform the m68k movepl operation extended to 64 bits.  */
-static inline void movepl2(u8 *d, u32 val1, u32 val2)
-{
-#if defined __mc68000__ && !defined CPU_M68060_ONLY
-    asm volatile ("movepl %1,%0@(0); movepl %2,%0@(8)"
-		  : : "a" (d), "d" (val1), "d" (val2));
-#else
-    d[0] = (val1 >> 24) & 0xff;
-    d[2] = (val1 >> 16) & 0xff;
-    d[4] = (val1 >> 8) & 0xff;
-    d[6] = val1 & 0xff;
-    d[8] = (val2 >> 24) & 0xff;
-    d[10] = (val2 >> 16) & 0xff;
-    d[12] = (val2 >> 8) & 0xff;
-    d[14] = val2 & 0xff;
-#endif
-}
-
-/* Sets the bytes in the visible column at d, height h, to the value
- * val1,val2 for a 8 plane screen. The bits of the color in 'color' are
- * moved (8 times) to the respective bytes. This means:
- *
- * for(h times; d += bpr)
- *   *d      = (color & 1) ? 0xff : 0;
- *   *(d+2)  = (color & 2) ? 0xff : 0;
- *   *(d+4)  = (color & 4) ? 0xff : 0;
- *   *(d+6)  = (color & 8) ? 0xff : 0;
- *   *(d+8)  = (color & 16) ? 0xff : 0;
- *   *(d+10) = (color & 32) ? 0xff : 0;
- *   *(d+12) = (color & 64) ? 0xff : 0;
- *   *(d+14) = (color & 128) ? 0xff : 0;
- */
-
-static __inline__ void memclear_8p_col(void *d, size_t h, u32 val1,
-                                       u32 val2, int bpr)
-{
-    u8 *dd = d;
-    do {
-	movepl2(dd, val1, val2);
-	dd += bpr;
-    } while (--h);
-}
-
-/* Sets a 8 plane region from 'd', length 'count' bytes, to the color
- * val1..val4. 'd' has to be an even address and count must be divisible
- * by 16, because only whole words and all planes are accessed. I.e.:
- *
- * for(count/16 times)
- *   *d      = *(d+1)  = (color & 1) ? 0xff : 0;
- *   *(d+2)  = *(d+3)  = (color & 2) ? 0xff : 0;
- *   *(d+4)  = *(d+5)  = (color & 4) ? 0xff : 0;
- *   *(d+6)  = *(d+7)  = (color & 8) ? 0xff : 0;
- *   *(d+8)  = *(d+9)  = (color & 16) ? 0xff : 0;
- *   *(d+10) = *(d+11) = (color & 32) ? 0xff : 0;
- *   *(d+12) = *(d+13) = (color & 64) ? 0xff : 0;
- *   *(d+14) = *(d+15) = (color & 128) ? 0xff : 0;
- */
-
-static __inline__ void memset_even_8p(void *d, size_t count, u32 val1,
-                                      u32 val2, u32 val3, u32 val4)
-{
-    u32 *dd = d;
-
-    count /= 16;
-    while (count--) {
-	*dd++ = val1;
-	*dd++ = val2;
-	*dd++ = val3;
-	*dd++ = val4;
-    }
-}
-
-/* Copies a 8 plane column from 's', height 'h', to 'd'. */
-
-static __inline__ void memmove_8p_col (void *d, void *s, int h, int bpr)
-{
-    u8 *dd = d, *ss = s;
-
-    while (h--) {
-	dd[0] = ss[0];
-	dd[2] = ss[2];
-	dd[4] = ss[4];
-	dd[6] = ss[6];
-	dd[8] = ss[8];
-	dd[10] = ss[10];
-	dd[12] = ss[12];
-	dd[14] = ss[14];
-	dd += bpr;
-	ss += bpr;
-    }
-}
-
-
-/* This expands a 8 bit color into two longs for two movepl (8 plane)
- * operations.
- */
-
-static const u32 four2long[] =
-{
-    0x00000000, 0xff000000, 0x00ff0000, 0xffff0000,
-    0x0000ff00, 0xff00ff00, 0x00ffff00, 0xffffff00,
-    0x000000ff, 0xff0000ff, 0x00ff00ff, 0xffff00ff,
-    0x0000ffff, 0xff00ffff, 0x00ffffff, 0xffffffff,
-};
-
-static __inline__ void expand8dl(u8 c, u32 *ret1, u32 *ret2)
-{
-    *ret1 = four2long[c & 15];
-    *ret2 = four2long[c >> 4];
-}
-
-
-/* This expands a 8 bit color into four longs for four movel operations
- * (8 planes).
- */
-
-static const u32 two2word[] =
-{
-#ifndef __LITTLE_ENDIAN
-    0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff
-#else
-    0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
-#endif
-};
-
-static inline void expand8ql(u8 c, u32 *rv1, u32 *rv2, u32 *rv3, u32 *rv4)
-{
-    *rv1 = two2word[c & 4];
-    *rv2 = two2word[(c >> 2) & 4];
-    *rv3 = two2word[(c >> 4) & 4];
-    *rv4 = two2word[c >> 6];
-}
-
-
-/* This duplicates a byte 4 times into a long. */
-
-static __inline__ u32 dup4l(u8 c)
-{
-    u32 rv;
-
-    rv = c;
-    rv |= rv << 8;
-    rv |= rv << 16;
-    return rv;
-}
-
-
-void fbcon_iplan2p8_setup(struct display *p)
-{
-    p->next_line = p->var.xres_virtual;
-    p->next_plane = 2;
-}
-
-void fbcon_iplan2p8_bmove(struct display *p, int sy, int sx, int dy, int dx,
-			  int height, int width)
-{
-    /*  bmove() has to distinguish two major cases: If both, source and
-     *  destination, start at even addresses or both are at odd
-     *  addresses, just the first odd and last even column (if present)
-     *  require special treatment (memmove_col()). The rest between
-     *  then can be copied by normal operations, because all adjacent
-     *  bytes are affected and are to be stored in the same order.
-     *    The pathological case is when the move should go from an odd
-     *  address to an even or vice versa. Since the bytes in the plane
-     *  words must be assembled in new order, it seems wisest to make
-     *  all movements by memmove_col().
-     */
-
-     if (sx == 0 && dx == 0 && width * 8 == p->next_line) {
-	/*  Special (but often used) case: Moving whole lines can be
-	 *  done with memmove()
-	 */
-	fast_memmove(p->fb_info->screen_base + dy * p->next_line * fontheight(p),
-		     p->fb_info->screen_base + sy * p->next_line * fontheight(p),
-		     p->next_line * height * fontheight(p));
-     } else {
-	int rows, cols;
-	u8 *src;
-	u8 *dst;
-	int bytes = p->next_line;
-	int linesize;
-	u_int colsize;
-	u_int upwards = (dy < sy) || (dy == sy && dx < sx);
-
-	if (fontheightlog(p)) {
-	    linesize = bytes << fontheightlog(p);
-	    colsize = height << fontheightlog(p);
-	} else {
-	    linesize = bytes * fontheight(p);
-	    colsize = height * fontheight(p);
-	}
-	if ((sx & 1) == (dx & 1)) {
-	    /* odd->odd or even->even */
-
-	    if (upwards) {
-		src = p->fb_info->screen_base + sy * linesize + (sx>>1)*16 + (sx & 1);
-		dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*16 + (dx & 1);
-		if (sx & 1) {
-		    memmove_8p_col(dst, src, colsize, bytes);
-		    src += 15;
-		    dst += 15;
-		    --width;
-		}
-		if (width > 1) {
-		    for(rows = colsize; rows > 0; --rows) {
-			fast_memmove (dst, src, (width >> 1) * 16);
-			src += bytes;
-			dst += bytes;
-		    }
-		}
-
-		if (width & 1) {
-		    src -= colsize * bytes;
-		    dst -= colsize * bytes;
-		    memmove_8p_col(dst + (width>>1)*16, src + (width>>1)*16,
-		    colsize, bytes);
-		}
-	    } else {
-		if (!((sx+width-1) & 1)) {
-		    src = p->fb_info->screen_base + sy * linesize + ((sx+width-1)>>1)*16;
-		    dst = p->fb_info->screen_base + dy * linesize + ((dx+width-1)>>1)*16;
-		    memmove_8p_col(dst, src, colsize, bytes);
-		    --width;
-		}
-		src = p->fb_info->screen_base + sy * linesize + (sx>>1)*16 + (sx & 1);
-		dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*16 + (dx & 1);
-		if (width > 1) {
-		    src += colsize * bytes + (sx & 1)*15;
-		    dst += colsize * bytes + (sx & 1)*15;
-		    for(rows = colsize; rows > 0; --rows) {
-			src -= bytes;
-			dst -= bytes;
-			fast_memmove (dst, src, (width>>1)*16);
-		    }
-		}
-		if (width & 1)
-		    memmove_8p_col(dst-15, src-15, colsize, bytes);
-	    }
-	} else {
-	/* odd->even or even->odd */
-
-	    if (upwards) {
-		src = p->fb_info->screen_base + sy * linesize + (sx>>1)*16 + (sx & 1);
-		dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*16 + (dx & 1);
-		for(cols = width; cols > 0; --cols) {
-		    memmove_8p_col(dst, src, colsize, bytes);
-		    INC_8P(src);
-		    INC_8P(dst);
-		}
-	    } else {
-		sx += width-1;
-		dx += width-1;
-		src = p->fb_info->screen_base + sy * linesize + (sx>>1)*16 + (sx & 1);
-		dst = p->fb_info->screen_base + dy * linesize + (dx>>1)*16 + (dx & 1);
-		for(cols = width; cols > 0; --cols) {
-		    memmove_8p_col(dst, src, colsize, bytes);
-		    DEC_8P(src);
-		    DEC_8P(dst);
-		}
-	    }
-	}
-    }
-}
-
-void fbcon_iplan2p8_clear(struct vc_data *conp, struct display *p, int sy,
-			  int sx, int height, int width)
-{
-    u32 offset;
-    u8 *start;
-    int rows;
-    int bytes = p->next_line;
-    int lines;
-    u32 size;
-    u32 cval1, cval2, cval3, cval4, pcval1, pcval2;
-
-    expand8ql(attr_bgcol_ec(p,conp), &cval1, &cval2, &cval3, &cval4);
-
-    if (fontheightlog(p))
-	lines = height << fontheightlog(p);
-    else
-	lines = height * fontheight(p);
-
-    if (sx == 0 && width * 8 == bytes) {
-	if (fontheightlog(p))
-	    offset = (sy * bytes) << fontheightlog(p);
-	else
-	    offset = sy * bytes * fontheight(p);
-	size    = lines * bytes;
-	memset_even_8p(p->fb_info->screen_base+offset, size, cval1, cval2, cval3, cval4);
-    } else {
-	if (fontheightlog(p))
-	    offset = ((sy * bytes) << fontheightlog(p)) + (sx>>1)*16 + (sx & 1);
-	else
-	    offset = sy * bytes * fontheight(p) + (sx>>1)*16 + (sx & 1);
-	start = p->fb_info->screen_base + offset;
-	expand8dl(attr_bgcol_ec(p,conp), &pcval1, &pcval2);
-
-	/* Clears are split if the region starts at an odd column or
-	* end at an even column. These extra columns are spread
-	* across the interleaved planes. All in between can be
-	* cleared by normal fb_memclear_small(), because both bytes of
-	* the single plane words are affected.
-	*/
-
-	if (sx & 1) {
-	    memclear_8p_col(start, lines, pcval1, pcval2, bytes);
-	    start += 7;
-	    width--;
-	}
-	if (width & 1) {
-	    memclear_8p_col(start + (width>>1)*16, lines, pcval1,
-	    pcval2, bytes);
-	    width--;
-	}
-	if (width)
-	    for(rows = lines; rows-- ; start += bytes)
-		memset_even_8p(start, width*8, cval1, cval2, cval3, cval4);
-	}
-}
-
-void fbcon_iplan2p8_putc(struct vc_data *conp, struct display *p, int c,
-			 int yy, int xx)
-{
-    u8 *dest;
-    u8 *cdat;
-    int rows;
-    int bytes = p->next_line;
-    u32 eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx;
-
-    if (fontheightlog(p)) {
-	dest = (p->fb_info->screen_base + ((yy * bytes) << fontheightlog(p)) +
-		(xx>>1)*16 + (xx & 1));
-	cdat = p->fontdata + ((c & p->charmask) << fontheightlog(p));
-    } else {
-	dest = (p->fb_info->screen_base + yy * bytes * fontheight(p) +
-		(xx>>1)*16 + (xx & 1));
-	cdat = p->fontdata + (c & p->charmask) * fontheight(p);
-    }
-
-    expand8dl(attr_fgcol(p,c), &fgx1, &fgx2);
-    expand8dl(attr_bgcol(p,c), &bgx1, &bgx2);
-    eorx1 = fgx1 ^ bgx1; eorx2  = fgx2 ^ bgx2;
-
-    for(rows = fontheight(p) ; rows-- ; dest += bytes) {
-	fdx = dup4l(*cdat++);
-	movepl2(dest, (fdx & eorx1) ^ bgx1, (fdx & eorx2) ^ bgx2);
-    }
-}
-
-void fbcon_iplan2p8_putcs(struct vc_data *conp, struct display *p,
-			  const unsigned short *s, int count, int yy, int xx)
-{
-    u8 *dest, *dest0;
-    u8 *cdat;
-    u16 c;
-    int rows;
-    int bytes;
-    u32 eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx;
-
-    bytes = p->next_line;
-    if (fontheightlog(p))
-	dest0 = (p->fb_info->screen_base + ((yy * bytes) << fontheightlog(p)) +
-		 (xx>>1)*16 + (xx & 1));
-    else
-	dest0 = (p->fb_info->screen_base + yy * bytes * fontheight(p) +
-		 (xx>>1)*16 + (xx & 1));
-
-    c = scr_readw(s);
-    expand8dl(attr_fgcol(p, c), &fgx1, &fgx2);
-    expand8dl(attr_bgcol(p, c), &bgx1, &bgx2);
-    eorx1 = fgx1 ^ bgx1; eorx2  = fgx2 ^ bgx2;
-
-    while (count--) {
-
-	/* I think, unrolling the loops like in the 1 plane case isn't
-	* practicable here, because the body is much longer for 4
-	* planes (mostly the dup4l()). I guess, unrolling this would
-	* need more than 256 bytes and so exceed the instruction
-	* cache :-(
-	*/
-
-	c = scr_readw(s++) & p->charmask;
-	if (fontheightlog(p))
-	    cdat = p->fontdata + (c << fontheightlog(p));
-	else
-	    cdat = p->fontdata + c * fontheight(p);
-
-	for(rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
-	    fdx = dup4l(*cdat++);
-	    movepl2(dest, (fdx & eorx1) ^ bgx1, (fdx & eorx2) ^ bgx2);
-	}
-	INC_8P(dest0);
-    }
-}
-
-void fbcon_iplan2p8_revc(struct display *p, int xx, int yy)
-{
-    u8 *dest;
-    int j;
-    int bytes;
-
-    if (fontheightlog(p))
-	dest = (p->fb_info->screen_base + ((yy * p->next_line) << fontheightlog(p)) +
-		(xx>>1)*16 + (xx & 1));
-    else
-	dest = (p->fb_info->screen_base + yy * p->next_line * fontheight(p) +
-		(xx>>1)*16 + (xx & 1));
-    j = fontheight(p);
-    bytes = p->next_line;
-
-    while (j--) {
-	/*  This should really obey the individual character's
-	 *  background and foreground colors instead of simply
-	 *  inverting. For 8 plane mode, only the lower 4 bits of the
-	 *  color are inverted, because only these color registers have
-	 *  been set up.
-	 */
-	dest[0] = ~dest[0];
-	dest[2] = ~dest[2];
-	dest[4] = ~dest[4];
-	dest[6] = ~dest[6];
-	dest += bytes;
-    }
-}
-
-void fbcon_iplan2p8_clear_margins(struct vc_data *conp, struct display *p,
-				  int bottom_only)
-{
-    u32 offset;
-    int bytes;
-    int lines;
-    u32 cval1, cval2, cval3, cval4;
-
-/* No need to handle right margin, cannot occur with fontwidth == 8 */
-
-    bytes = p->next_line;
-    if (fontheightlog(p)) {
-	lines = p->var.yres - (conp->vc_rows << fontheightlog(p));
-	offset = ((p->yscroll + conp->vc_rows) * bytes) << fontheightlog(p);
-    } else {
-	lines = p->var.yres - conp->vc_rows * fontheight(p);
-	offset = (p->yscroll + conp->vc_rows) * bytes * fontheight(p);
-    }
-    if (lines) {
-	expand8ql(attr_bgcol_ec(p,conp), &cval1, &cval2, &cval3, &cval4);
-	memset_even_8p(p->fb_info->screen_base+offset, lines * bytes,
-		       cval1, cval2, cval3, cval4);
-    }
-}
-
-
-    /*
-     *  `switch' for the low level operations
-     */
-
-struct display_switch fbcon_iplan2p8 = {
-    setup:		fbcon_iplan2p8_setup,
-    bmove:		fbcon_iplan2p8_bmove,
-    clear:		fbcon_iplan2p8_clear,
-    putc:		fbcon_iplan2p8_putc,
-    putcs:		fbcon_iplan2p8_putcs,
-    revc:		fbcon_iplan2p8_revc,
-    clear_margins:	fbcon_iplan2p8_clear_margins,
-    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_iplan2p8);
-EXPORT_SYMBOL(fbcon_iplan2p8_setup);
-EXPORT_SYMBOL(fbcon_iplan2p8_bmove);
-EXPORT_SYMBOL(fbcon_iplan2p8_clear);
-EXPORT_SYMBOL(fbcon_iplan2p8_putc);
-EXPORT_SYMBOL(fbcon_iplan2p8_putcs);
-EXPORT_SYMBOL(fbcon_iplan2p8_revc);
-EXPORT_SYMBOL(fbcon_iplan2p8_clear_margins);
diff -Nru a/drivers/video/fbcon-mfb.c b/drivers/video/fbcon-mfb.c
--- a/drivers/video/fbcon-mfb.c	Mon Dec  9 18:46:38 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,217 +0,0 @@
-/*
- *  linux/drivers/video/mfb.c -- Low level frame buffer operations for
- *				 monochrome
- *
- *	Created 5 Apr 1997 by Geert Uytterhoeven
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-#include <linux/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-mfb.h>
-
-
-    /*
-     *  Monochrome
-     */
-
-void fbcon_mfb_setup(struct display *p)
-{
-    if (p->fb_info->fix.line_length)
-	p->next_line = p->fb_info->fix.line_length;
-    else
-	p->next_line = p->var.xres_virtual>>3;
-    p->next_plane = 0;
-}
-
-void fbcon_mfb_bmove(struct display *p, int sy, int sx, int dy, int dx,
-		     int height, int width)
-{
-    u8 *src, *dest;
-    u_int rows;
-
-    if (sx == 0 && dx == 0 && width == p->next_line) {
-	src = p->fb_info->screen_base+sy*fontheight(p)*width;
-	dest = p->fb_info->screen_base+dy*fontheight(p)*width;
-	fb_memmove(dest, src, height*fontheight(p)*width);
-    } else if (dy <= sy) {
-	src = p->fb_info->screen_base+sy*fontheight(p)*p->next_line+sx;
-	dest = p->fb_info->screen_base+dy*fontheight(p)*p->next_line+dx;
-	for (rows = height*fontheight(p); rows--;) {
-	    fb_memmove(dest, src, width);
-	    src += p->next_line;
-	    dest += p->next_line;
-	}
-    } else {
-	src = p->fb_info->screen_base+((sy+height)*fontheight(p)-1)*p->next_line+sx;
-	dest = p->fb_info->screen_base+((dy+height)*fontheight(p)-1)*p->next_line+dx;
-	for (rows = height*fontheight(p); rows--;) {
-	    fb_memmove(dest, src, width);
-	    src -= p->next_line;
-	    dest -= p->next_line;
-	}
-    }
-}
-
-void fbcon_mfb_clear(struct vc_data *conp, struct display *p, int sy, int sx,
-		     int height, int width)
-{
-    u8 *dest;
-    u_int rows;
-    int inverse = conp ? attr_reverse(p,conp->vc_video_erase_char) : 0;
-
-    dest = p->fb_info->screen_base+sy*fontheight(p)*p->next_line+sx;
-
-    if (sx == 0 && width == p->next_line) {
-	if (inverse)
-	    fb_memset255(dest, height*fontheight(p)*width);
-	else
-	    fb_memclear(dest, height*fontheight(p)*width);
-    } else
-	for (rows = height*fontheight(p); rows--; dest += p->next_line)
-	    if (inverse)
-		fb_memset255(dest, width);
-	    else
-		fb_memclear_small(dest, width);
-}
-
-void fbcon_mfb_putc(struct vc_data *conp, struct display *p, int c, int yy,
-		    int xx)
-{
-    u8 *dest, *cdat;
-    u_int rows, bold, revs, underl;
-    u8 d;
-
-    dest = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
-    cdat = p->fontdata+(c&p->charmask)*fontheight(p);
-    bold = attr_bold(p,c);
-    revs = attr_reverse(p,c);
-    underl = attr_underline(p,c);
-
-    for (rows = fontheight(p); rows--; dest += p->next_line) {
-	d = *cdat++;
-	if (underl && !rows)
-	    d = 0xff;
-	else if (bold)
-	    d |= d>>1;
-	if (revs)
-	    d = ~d;
-    	fb_writeb (d, dest);
-    }
-}
-
-void fbcon_mfb_putcs(struct vc_data *conp, struct display *p, 
-		     const unsigned short *s, int count, int yy, int xx)
-{
-    u8 *dest, *dest0, *cdat;
-    u_int rows, bold, revs, underl;
-    u8 d;
-    u16 c;
-
-    dest0 = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
-    c = scr_readw(s);
-    bold = attr_bold(p, c);
-    revs = attr_reverse(p, c);
-    underl = attr_underline(p, c);
-
-    while (count--) {
-	c = scr_readw(s++) & p->charmask;
-	dest = dest0++;
-	cdat = p->fontdata+c*fontheight(p);
-	for (rows = fontheight(p); rows--; dest += p->next_line) {
-	    d = *cdat++;
-	    if (underl && !rows)
-		d = 0xff;
-	    else if (bold)
-		d |= d>>1;
-	    if (revs)
-		d = ~d;
-    	    fb_writeb (d, dest);
-	}
-    }
-}
-
-void fbcon_mfb_revc(struct display *p, int xx, int yy)
-{
-    u8 *dest, d;
-    u_int rows;
-
-    dest = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
-    for (rows = fontheight(p); rows--; dest += p->next_line) {
-    	d = fb_readb(dest);
-	fb_writeb (~d, dest);
-    }
-}
-
-void fbcon_mfb_clear_margins(struct vc_data *conp, struct display *p,
-			     int bottom_only)
-{
-    u8 *dest;
-    int height, bottom;
-    int inverse = conp ? attr_reverse(p,conp->vc_video_erase_char) : 0;
-
-    /* XXX Need to handle right margin? */
-
-    height = p->var.yres - conp->vc_rows * fontheight(p);
-    if (!height)
-	return;
-    bottom = conp->vc_rows + p->yscroll;
-    if (bottom >= p->vrows)
-	bottom -= p->vrows;
-    dest = p->fb_info->screen_base + bottom * fontheight(p) * p->next_line;
-    if (inverse)
-	fb_memset255(dest, height * p->next_line);
-    else
-	fb_memclear(dest, height * p->next_line);
-}
-
-
-    /*
-     *  `switch' for the low level operations
-     */
-
-struct display_switch fbcon_mfb = {
-    setup:		fbcon_mfb_setup,
-    bmove:		fbcon_mfb_bmove,
-    clear:		fbcon_mfb_clear,
-    putc:		fbcon_mfb_putc,
-    putcs:		fbcon_mfb_putcs,
-    revc:		fbcon_mfb_revc,
-    clear_margins:	fbcon_mfb_clear_margins,
-    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_mfb);
-EXPORT_SYMBOL(fbcon_mfb_setup);
-EXPORT_SYMBOL(fbcon_mfb_bmove);
-EXPORT_SYMBOL(fbcon_mfb_clear);
-EXPORT_SYMBOL(fbcon_mfb_putc);
-EXPORT_SYMBOL(fbcon_mfb_putcs);
-EXPORT_SYMBOL(fbcon_mfb_revc);
-EXPORT_SYMBOL(fbcon_mfb_clear_margins);
diff -Nru a/drivers/video/fbcon-sti.c b/drivers/video/fbcon-sti.c
--- a/drivers/video/fbcon-sti.c	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,337 +0,0 @@
-/*
- * linux/drivers/video/fbcon-sti.c -- Low level frame buffer
- *  	operations for generic HP video boards using STI (standard
- *  	text interface) firmware
- *
- *  Based on linux/drivers/video/fbcon-artist.c
- *	Created 5 Apr 1997 by Geert Uytterhoeven
- *	Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file COPYING in the main directory of this archive for
- * more details.  */
-
-#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 <asm/types.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-mfb.h>
-
-#include "sti.h"
-
-/* Translate an address as it would be found in a 2048x2048x1 bit frame
- * buffer into a logical address Artist actually expects.  Addresses fed
- * into Artist look like this:
- *  fixed          Y               X
- * FFFF FFFF LLLL LLLL LLLC CCCC CCCC CC00
- *
- * our "RAM" addresses look like this:
- * 
- * FFFF FFFF 0000 0LLL LLLL LLLL CCCC CCCC [CCC]
- *
- * */
-
-static inline u32
-ram2log(void * addr)
-{
-	u32 a = (unsigned long) addr;
-	u32 r;
-
-#if 0
-	r  =   a & 0xff000000;		/* fixed part */
-	r += ((a & 0x000000ff) << 5);
-	r += ((a & 0x00ffff00) << 3);
-#else
-	r  =   a & 0xff000000;		/* fixed part */
-	r += ((a & 0x000000ff) << 5);
-	r += ((a & 0x0007ff00) << 5);
-#endif
-
-	return r;
-}
-
-/* All those functions need better names. */
-
-static void
-memcpy_fromhp_tohp(void *dest, void *src, int count)
-{
-	unsigned long d = ram2log(dest);
-	unsigned long s = ram2log(src);
-
-	count += 3;
-	count &= ~3; /* XXX */
-
-	while(count) {
-		count --;
-		gsc_writel(~gsc_readl(s), d);
-		d += 32*4;
-		s += 32*4;
-	}
-}
-
-static void
-memcpy_tohp(void *dest, void *src, int count)
-{
-	unsigned long d = (unsigned long) dest;
-	u32 *s = (u32 *)src;
-
-	count += 3;
-	count &= ~3; /* XXX */
-
-	d = ram2log(dest);
-
-	while(count) {
-		count--;
-		gsc_writel(*s++, d);
-		d += 32*4;
-	}
-}
-
-static void
-memcopy_fromhp(void *dest, void *src, int count)
-{
-	/* FIXME */
-	printk("uhm ...\n");
-}
-
-static void
-memset_tohp(void *dest, u32 word, int count)
-{
-	unsigned long d = ram2log(dest);
-
-	count += 3;
-	count &= ~3;
-
-	while(count) {
-		count--;
-		gsc_writel(word, d);
-		d += 32;
-	}
-}
-
-static u8
-readb_hp(void *src)
-{
-	unsigned long s = ram2log(src);
-
-	return ~gsc_readb(s);
-}
-
-static void
-writeb_hp(u8 b, void *dst)
-{
-	unsigned long d = ram2log(dst);
-
-	if((d&0xf0000000) != 0xf0000000) {
-		printk("writeb_hp %02x %p (%08lx) (%p)\n",
-			b, dst, d, __builtin_return_address(0));
-		return;
-	}
-
-	gsc_writeb(b, d);
-}
-
-static void
-fbcon_sti_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;
-}
-
-static void
-fbcon_sti_bmove(struct display *p, int sy, int sx,
-		int dy, int dx,
-		int height, int width)
-{
-#if 0 /* Unfortunately, still broken */
-	sti_bmove(&default_sti /* FIXME */, sy, sx, dy, dx, height, width);
-#else
-	u8 *src, *dest;
-	u_int rows;
-
-	if (sx == 0 && dx == 0 && width == p->next_line) {
-		src = p->fb_info->screen_base+sy*fontheight(p)*width;
-		dest = p->fb_info->screen_base+dy*fontheight(p)*width;
-		memcpy_fromhp_tohp(dest, src, height*fontheight(p)*width);
-	} else if (dy <= sy) {
-		src = p->fb_info->screen_base+sy*fontheight(p)*p->next_line+sx;
-		dest = p->fb_info->screen_base+dy*fontheight(p)*p->next_line+dx;
-		for (rows = height*fontheight(p); rows--;) {
-			memcpy_fromhp_tohp(dest, src, width);
-			src += p->next_line;
-			dest += p->next_line;
-		}
-	} else {
-		src = p->fb_info->screen_base+((sy+height)*fontheight(p)-1)*p->next_line+sx;
-		dest = p->fb_info->screen_base+((dy+height)*fontheight(p)-1)*p->next_line+dx;
-		for (rows = height*fontheight(p); rows--;) {
-			memcpy_fromhp_tohp(dest, src, width);
-			src -= p->next_line;
-			dest -= p->next_line;
-		}
-	}
-#endif
-}
-
-static void
-fbcon_sti_clear(struct vc_data *conp,
-		struct display *p, int sy, int sx,
-		int height, int width)
-{
-	u8 *dest;
-	u_int rows;
-	int inverse = conp ? attr_reverse(p,conp->vc_video_erase_char) : 0;
-
-	dest = p->fb_info->screen_base+sy*fontheight(p)*p->next_line+sx;
-
-	if (sx == 0 && width == p->next_line) {
-		if (inverse)
-			memset_tohp(dest, ~0, height*fontheight(p)*width);
-		else
-			memset_tohp(dest,  0, height*fontheight(p)*width);
-	} else
-		for (rows = height*fontheight(p); rows--; dest += p->next_line)
-			if (inverse)
-				memset_tohp(dest, 0xffffffff, width);
-			else
-				memset_tohp(dest, 0x00000000, width);
-}
-
-static void fbcon_sti_putc(struct vc_data *conp,
-			   struct display *p, int c,
-			   int yy, int xx)
-{
-	u8 *dest, *cdat;
-	u_int rows, bold, revs, underl;
-	u8 d;
-
-	dest = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
-	cdat = p->fontdata+(c&p->charmask)*fontheight(p);
-	bold = attr_bold(p,c);
-	revs = attr_reverse(p,c);
-	underl = attr_underline(p,c);
-
-	for (rows = fontheight(p); rows--; dest += p->next_line) {
-		d = *cdat++;
-		if (underl && !rows)
-			d = 0xff;
-		else if (bold)
-			d |= d>>1;
-		if (revs)
-			d = ~d;
-		writeb_hp (d, dest);
-	}
-}
-
-static void fbcon_sti_putcs(struct vc_data *conp,
-			    struct display *p, 
-			    const unsigned short *s,
-			    int count, int yy, int xx)
-{
-	u8 *dest, *dest0, *cdat;
-	u_int rows, bold, revs, underl;
-	u8 d;
-	u16 c;
-
-	if(((unsigned)xx > 200) || ((unsigned) yy > 200)) {
-		printk("refusing to putcs %p %p %p %d %d %d (%p)\n",
-			conp, p, s, count, yy, xx, __builtin_return_address(0));
-		return;
-	}	
-
-
-	dest0 = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
-	if(((u32)dest0&0xf0000000)!=0xf0000000) {
-		printk("refusing to putcs %p %p %p %d %d %d (%p) %p = %p + %d * %d * %ld + %d\n",
-			conp, p, s, count, yy, xx, __builtin_return_address(0),
-			dest0, p->fb_info->screen_base, yy, fontheight(p), p->next_line,
-			xx);
-		return;
-	}	
-
-	c = scr_readw(s);
-	bold = attr_bold(p, c);
-	revs = attr_reverse(p, c);
-	underl = attr_underline(p, c);
-
-	while (count--) {
-		c = scr_readw(s++) & p->charmask;
-		dest = dest0++;
-		cdat = p->fontdata+c*fontheight(p);
-		for (rows = fontheight(p); rows--; dest += p->next_line) {
-			d = *cdat++;
-			if (0 && underl && !rows)
-				d = 0xff;
-			else if (0 && bold)
-				d |= d>>1;
-			if (revs)
-				d = ~d;
-			writeb_hp (d, dest);
-		}
-	}
-}
-
-static void fbcon_sti_revc(struct display *p,
-			   int xx, int yy)
-{
-	u8 *dest, d;
-	u_int rows;
-
-
-	dest = p->fb_info->screen_base+yy*fontheight(p)*p->next_line+xx;
-	for (rows = fontheight(p); rows--; dest += p->next_line) {
-		d = readb_hp(dest);
-		writeb_hp (~d, dest);
-	}
-}
-
-static void
-fbcon_sti_clear_margins(struct vc_data *conp,
-			struct display *p,
-			int bottom_only)
-{
-	u8 *dest;
-	int height, bottom;
-	int inverse = conp ? attr_reverse(p,conp->vc_video_erase_char) : 0;
-
-
-	/* XXX Need to handle right margin? */
-
-	height = p->var.yres - conp->vc_rows * fontheight(p);
-	if (!height)
-		return;
-	bottom = conp->vc_rows + p->yscroll;
-	if (bottom >= p->vrows)
-		bottom -= p->vrows;
-	dest = p->fb_info->screen_base + bottom * fontheight(p) * p->next_line;
-	if (inverse)
-		memset_tohp(dest, 0xffffffff, height * p->next_line);
-	else
-		memset_tohp(dest, 0x00000000, height * p->next_line);
-}
-
-
-    /*
-     *  `switch' for the low level operations
-     */
-
-struct display_switch fbcon_sti = {
-	.setup =	fbcon_sti_setup, 
-	.bmove =	fbcon_sti_bmove, 
-	.clear =	fbcon_sti_clear,
-	.putc =		fbcon_sti_putc, 
-	.putcs =	fbcon_sti_putcs, 
-	.revc =		fbcon_sti_revc,
-	.clear_margins =fbcon_sti_clear_margins,
-	.fontwidthmask =FONTWIDTH(8)
-};
-
-MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/fbcon-vga-planes.c b/drivers/video/fbcon-vga-planes.c
--- a/drivers/video/fbcon-vga-planes.c	Mon Dec  9 18:46:37 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,387 +0,0 @@
-/*
- *  linux/drivers/video/fbcon-vga-planes.c -- Low level frame buffer operations
- *				  for VGA 4-plane modes
- *
- * Copyright 1999 Ben Pfaff <pfaffben@debian.org> and Petr Vandrovec <VANDROVE@vc.cvut.cz>
- * Based on code by Michael Schmitz
- * Based on the old macfb.c 4bpp code by Alan Cox
- *
- * 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 <linux/vt_buffer.h>
-
-#include <asm/io.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-vga-planes.h>
-
-#define GRAPHICS_ADDR_REG 0x3ce		/* Graphics address register. */
-#define GRAPHICS_DATA_REG 0x3cf		/* Graphics data register. */
-
-#define SET_RESET_INDEX 0		/* Set/Reset Register index. */
-#define ENABLE_SET_RESET_INDEX 1	/* Enable Set/Reset Register index. */
-#define DATA_ROTATE_INDEX 3		/* Data Rotate Register index. */
-#define GRAPHICS_MODE_INDEX 5		/* Graphics Mode Register index. */
-#define BIT_MASK_INDEX 8		/* Bit Mask Register index. */
-
-/* The VGA's weird architecture often requires that we read a byte and
-   write a byte to the same location.  It doesn't matter *what* byte
-   we write, however.  This is because all the action goes on behind
-   the scenes in the VGA's 32-bit latch register, and reading and writing
-   video memory just invokes latch behavior.
-
-   To avoid race conditions (is this necessary?), reading and writing
-   the memory byte should be done with a single instruction.  One
-   suitable instruction is the x86 bitwise OR.  The following
-   read-modify-write routine should optimize to one such bitwise
-   OR. */
-static inline void rmw(volatile char *p)
-{
-	readb(p);
-	writeb(1, p);
-}
-
-/* Set the Graphics Mode Register.  Bits 0-1 are write mode, bit 3 is
-   read mode. */
-static inline void setmode(int mode)
-{
-	outb(GRAPHICS_MODE_INDEX, GRAPHICS_ADDR_REG);
-	outb(mode, GRAPHICS_DATA_REG);
-}
-
-/* Select the Bit Mask Register. */
-static inline void selectmask(void)
-{
-	outb(BIT_MASK_INDEX, GRAPHICS_ADDR_REG);
-}
-
-/* Set the value of the Bit Mask Register.  It must already have been
-   selected with selectmask(). */
-static inline void setmask(int mask)
-{
-	outb(mask, GRAPHICS_DATA_REG);
-}
-
-/* Set the Data Rotate Register.  Bits 0-2 are rotate count, bits 3-4
-   are logical operation (0=NOP, 1=AND, 2=OR, 3=XOR). */
-static inline void setop(int op)
-{
-	outb(DATA_ROTATE_INDEX, GRAPHICS_ADDR_REG);
-	outb(op, GRAPHICS_DATA_REG);
-}
-
-/* Set the Enable Set/Reset Register.  The code here always uses value
-   0xf for this register.  */
-static inline void setsr(int sr)
-{
-	outb(ENABLE_SET_RESET_INDEX, GRAPHICS_ADDR_REG);
-	outb(sr, GRAPHICS_DATA_REG);
-}
-
-/* Set the Set/Reset Register. */
-static inline void setcolor(int color)
-{
-	outb(SET_RESET_INDEX, GRAPHICS_ADDR_REG);
-	outb(color, GRAPHICS_DATA_REG);
-}
-
-/* Set the value in the Graphics Address Register. */
-static inline void setindex(int index)
-{
-	outb(index, GRAPHICS_ADDR_REG);
-}
-
-void fbcon_vga_planes_setup(struct display *p)
-{
-}
-
-void fbcon_vga_planes_bmove(struct display *p, int sy, int sx, int dy, int dx,
-		   int height, int width)
-{
-	char *src;
-	char *dest;
-	int line_ofs;
-	int x;
-
-	setmode(1);
-	setop(0);
-	setsr(0xf);
-
-	sy *= fontheight(p);
-	dy *= fontheight(p);
-	height *= fontheight(p);
-
-	if (dy < sy || (dy == sy && dx < sx)) {
-		line_ofs = p->fb_info->fix.line_length - width;
-		dest = p->fb_info->screen_base + dx + dy * p->fb_info->fix.line_length;
-		src = p->fb_info->screen_base + sx + sy * p->fb_info->fix.line_length;
-		while (height--) {
-			for (x = 0; x < width; x++) {
-				readb(src);
-				writeb(0, dest);
-				dest++;
-				src++;
-			}
-			src += line_ofs;
-			dest += line_ofs;
-		}
-	} else {
-		line_ofs = p->fb_info->fix.line_length - width;
-		dest = p->fb_info->screen_base + dx + width + (dy + height - 1) * p->fb_info->fix.line_length;
-		src = p->fb_info->screen_base + sx + width + (sy + height - 1) * p->fb_info->fix.line_length;
-		while (height--) {
-			for (x = 0; x < width; x++) {
-				dest--;
-				src--;
-				readb(src);
-				writeb(0, dest);
-			}
-			src -= line_ofs;
-			dest -= line_ofs;
-		}
-	}
-}
-
-void fbcon_vga_planes_clear(struct vc_data *conp, struct display *p, int sy, int sx,
-		   int height, int width)
-{
-	int line_ofs = p->fb_info->fix.line_length - width;
-	char *where;
-	int x;
-	
-	setmode(0);
-	setop(0);
-	setsr(0xf);
-	setcolor(attr_bgcol_ec(p, conp));
-	selectmask();
-
-	setmask(0xff);
-
-	sy *= fontheight(p);
-	height *= fontheight(p);
-
-	where = p->fb_info->screen_base + sx + sy * p->fb_info->fix.line_length;
-	while (height--) {
-		for (x = 0; x < width; x++) {
-			writeb(0, where);
-			where++;
-		}
-		where += line_ofs;
-	}
-}
-
-void fbcon_ega_planes_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx)
-{
-	int fg = attr_fgcol(p,c);
-	int bg = attr_bgcol(p,c);
-
-	int y;
-	u8 *cdat = p->fontdata + (c & p->charmask) * fontheight(p);
-	char *where = p->fb_info->screen_base + xx + yy * p->fb_info->fix.line_length * fontheight(p);
-
-	setmode(0);
-	setop(0);
-	setsr(0xf);
-	setcolor(bg);
-	selectmask();
-
-	setmask(0xff);
-	for (y = 0; y < fontheight(p); y++, where += p->fb_info->fix.line_length) 
-		rmw(where);
-
-	where -= p->fb_info->fix.line_length * y;
-	setcolor(fg);
-	selectmask();
-	for (y = 0; y < fontheight(p); y++, where += p->fb_info->fix.line_length) 
-		if (cdat[y]) {
-			setmask(cdat[y]);
-			rmw(where);
-		}
-}
-
-void fbcon_vga_planes_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx)
-{
-	int fg = attr_fgcol(p,c);
-	int bg = attr_bgcol(p,c);
-
-	int y;
-	u8 *cdat = p->fontdata + (c & p->charmask) * fontheight(p);
-	char *where = p->fb_info->screen_base + xx + yy * p->fb_info->fix.line_length * fontheight(p);
-
-	setmode(2);
-	setop(0);
-	setsr(0xf);
-	setcolor(fg);
-	selectmask();
-
-	setmask(0xff);
-	writeb(bg, where);
-	rmb();
-	readb(where); /* fill latches */
-	setmode(3);
-	wmb();
-	for (y = 0; y < fontheight(p); y++, where += p->fb_info->fix.line_length) 
-		writeb(cdat[y], where);
-	wmb();
-}
-
-/* 28.50 in my test */
-void fbcon_ega_planes_putcs(struct vc_data *conp, struct display *p, const unsigned short *s,
-		   int count, int yy, int xx)
-{
-	u16 c = scr_readw(s);
-	int fg = attr_fgcol(p, c);
-	int bg = attr_bgcol(p, c);
-
-	char *where;
-	int n;
-
-	setmode(2);
-	setop(0);
-	selectmask();
-
-	setmask(0xff);
-	where = p->fb_info->screen_base + xx + yy * p->fb_info->fix.line_length * fontheight(p);
-	writeb(bg, where);
-	rmb();
-	readb(where); /* fill latches */
-	wmb();
-	selectmask();
-	for (n = 0; n < count; n++) {
-		int c = scr_readw(s++) & p->charmask;
-		u8 *cdat = p->fontdata + c * fontheight(p);
-		u8 *end = cdat + fontheight(p);
-
-		while (cdat < end) {
-			outb(*cdat++, GRAPHICS_DATA_REG);	
-			wmb();
-			writeb(fg, where);
-			where += p->fb_info->fix.line_length;
-		}
-		where += 1 - p->fb_info->fix.line_length * fontheight(p);
-	}
-	
-	wmb();
-}
-
-/* 6.96 in my test */
-void fbcon_vga_planes_putcs(struct vc_data *conp, struct display *p, const unsigned short *s,
-		   int count, int yy, int xx)
-{
-	u16 c = scr_readw(s);
-	int fg = attr_fgcol(p, c);
-	int bg = attr_bgcol(p, c);
-
-	char *where;
-	int n;
-
-	setmode(2);
-	setop(0);
-	setsr(0xf);
-	setcolor(fg);
-	selectmask();
-
-	setmask(0xff);
-	where = p->fb_info->screen_base + xx + yy * p->fb_info->fix.line_length * fontheight(p);
-	writeb(bg, where);
-	rmb();
-	readb(where); /* fill latches */
-	setmode(3);	
-	wmb();
-	for (n = 0; n < count; n++) {
-		int y;
-		int c = scr_readw(s++) & p->charmask;
-		u8 *cdat = p->fontdata + (c & p->charmask) * fontheight(p);
-
-		for (y = 0; y < fontheight(p); y++, cdat++) {
-			writeb (*cdat, where);
-			where += p->fb_info->fix.line_length;
-		}
-		where += 1 - p->fb_info->fix.line_length * fontheight(p);
-	}
-	
-	wmb();
-}
-
-void fbcon_vga_planes_revc(struct display *p, int xx, int yy)
-{
-	char *where = p->fb_info->screen_base + xx + yy * p->fb_info->fix.line_length * fontheight(p);
-	int y;
-	
-	setmode(0);
-	setop(0x18);
-	setsr(0xf);
-	setcolor(0xf);
-	selectmask();
-
-	setmask(0xff);
-	for (y = 0; y < fontheight(p); y++) {
-		rmw(where);
-		where += p->fb_info->fix.line_length;
-	}
-}
-
-struct display_switch fbcon_vga_planes = {
-    setup:		fbcon_vga_planes_setup,
-    bmove:		fbcon_vga_planes_bmove,
-    clear:		fbcon_vga_planes_clear,
-    putc:		fbcon_vga_planes_putc,
-    putcs:		fbcon_vga_planes_putcs,
-    revc:		fbcon_vga_planes_revc,
-    fontwidthmask:	FONTWIDTH(8)
-};
-
-struct display_switch fbcon_ega_planes = {
-    setup:		fbcon_vga_planes_setup,
-    bmove:		fbcon_vga_planes_bmove,
-    clear:		fbcon_vga_planes_clear,
-    putc:		fbcon_ega_planes_putc,
-    putcs:		fbcon_ega_planes_putcs,
-    revc:		fbcon_vga_planes_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_planes);
-EXPORT_SYMBOL(fbcon_vga_planes_setup);
-EXPORT_SYMBOL(fbcon_vga_planes_bmove);
-EXPORT_SYMBOL(fbcon_vga_planes_clear);
-EXPORT_SYMBOL(fbcon_vga_planes_putc);
-EXPORT_SYMBOL(fbcon_vga_planes_putcs);
-EXPORT_SYMBOL(fbcon_vga_planes_revc);
-
-EXPORT_SYMBOL(fbcon_ega_planes);
-EXPORT_SYMBOL(fbcon_ega_planes_putc);
-EXPORT_SYMBOL(fbcon_ega_planes_putcs);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
-
diff -Nru a/drivers/video/fbcon.c b/drivers/video/fbcon.c
--- a/drivers/video/fbcon.c	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,2509 +0,0 @@
-/*
- *  linux/drivers/video/fbcon.c -- Low level frame buffer based console driver
- *
- *	Copyright (C) 1995 Geert Uytterhoeven
- *
- *
- *  This file is based on the original Amiga console driver (amicon.c):
- *
- *	Copyright (C) 1993 Hamish Macdonald
- *			   Greg Harp
- *	Copyright (C) 1994 David Carter [carter@compsci.bristol.ac.uk]
- *
- *	      with work by William Rucklidge (wjr@cs.cornell.edu)
- *			   Geert Uytterhoeven
- *			   Jes Sorensen (jds@kom.auc.dk)
- *			   Martin Apel
- *
- *  and on the original Atari console driver (atacon.c):
- *
- *	Copyright (C) 1993 Bjoern Brauel
- *			   Roman Hodek
- *
- *	      with work by Guenther Kelleter
- *			   Martin Schaller
- *			   Andreas Schwab
- *
- *  Hardware cursor support added by Emmanuel Marty (core@ggi-project.org)
- *  Smart redraw scrolling, arbitrary font width support, 512char font support
- *  and software scrollback added by 
- *                         Jakub Jelinek (jj@ultra.linux.cz)
- *
- *  Random hacking by Martin Mares <mj@ucw.cz>
- *
- *	2001 - Documented with DocBook
- *	- Brad Douglas <brad@neruo.com>
- *
- *  The low level operations for the various display memory organizations are
- *  now in separate source files.
- *
- *  Currently the following organizations are supported:
- *
- *    o afb			Amiga bitplanes
- *    o cfb{2,4,8,16,24,32}	Packed pixels
- *    o ilbm			Amiga interleaved bitplanes
- *    o iplan2p[248]		Atari interleaved bitplanes
- *    o mfb			Monochrome
- *    o vga			VGA characters/attributes
- *
- *  To do:
- *
- *    - Implement 16 plane mode (iplan2p16)
- *
- *
- *  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 FBCONDEBUG
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>	/* MSch: for IRQ probe */
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/kd.h>
-#include <linux/slab.h>
-#include <linux/fb.h>
-#include <linux/vt_kern.h>
-#include <linux/selection.h>
-#include <linux/smp.h>
-#include <linux/init.h>
-
-#include <asm/irq.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#ifdef CONFIG_AMIGA
-#include <asm/amigahw.h>
-#include <asm/amigaints.h>
-#endif /* CONFIG_AMIGA */
-#ifdef CONFIG_ATARI
-#include <asm/atariints.h>
-#endif
-#ifdef CONFIG_MAC
-#include <asm/macints.h>
-#endif
-#if defined(__mc68000__) || defined(CONFIG_APUS)
-#include <asm/machdep.h>
-#include <asm/setup.h>
-#endif
-#ifdef CONFIG_FBCON_VGA_PLANES
-#include <asm/io.h>
-#endif
-#define INCLUDE_LINUX_LOGO_DATA
-#include <asm/linux_logo.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-mac.h>	/* for 6x11 font on mac */
-#include <video/font.h>
-
-#ifdef FBCONDEBUG
-#  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
-#else
-#  define DPRINTK(fmt, args...)
-#endif
-
-#define LOGO_H			80
-#define LOGO_W			80
-#define LOGO_LINE	(LOGO_W/8)
-
-struct display fb_display[MAX_NR_CONSOLES];
-char con2fb_map[MAX_NR_CONSOLES];
-static int logo_lines;
-static int logo_shown = -1;
-/* Software scrollback */
-int fbcon_softback_size = 32768;
-static unsigned long softback_buf, softback_curr;
-static unsigned long softback_in;
-static unsigned long softback_top, softback_end;
-static int softback_lines;
-
-#define REFCOUNT(fd)	(((int *)(fd))[-1])
-#define FNTSIZE(fd)	(((int *)(fd))[-2])
-#define FNTCHARCNT(fd)	(((int *)(fd))[-3])
-#define FNTSUM(fd)	(((int *)(fd))[-4])
-#define FONT_EXTRA_WORDS 4
-
-#define CM_SOFTBACK	(8)
-
-#define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * conp->vc_size_row)
-
-static void fbcon_free_font(struct display *);
-static int fbcon_set_origin(struct vc_data *);
-
-/*
- * Emmanuel: fbcon will now use a hardware cursor if the
- * low-level driver provides a non-NULL dispsw->cursor pointer,
- * in which case the hardware should do blinking, etc.
- *
- * if dispsw->cursor is NULL, use Atari alike software cursor
- */
-
-static int cursor_drawn;
-
-#define CURSOR_DRAW_DELAY		(1)
-
-/* # VBL ints between cursor state changes */
-#define ARM_CURSOR_BLINK_RATE		(10)
-#define AMIGA_CURSOR_BLINK_RATE		(20)
-#define ATARI_CURSOR_BLINK_RATE		(42)
-#define MAC_CURSOR_BLINK_RATE		(32)
-#define DEFAULT_CURSOR_BLINK_RATE	(20)
-
-static int vbl_cursor_cnt;
-static int cursor_on;
-static int cursor_blink_rate;
-
-static inline void cursor_undrawn(void)
-{
-    vbl_cursor_cnt = 0;
-    cursor_drawn = 0;
-}
-
-
-#define divides(a, b)	((!(a) || (b)%(a)) ? 0 : 1)
-
-
-/*
- *  Interface used by the world
- */
-
-static const char *fbcon_startup(void);
-static void fbcon_init(struct vc_data *conp, int init);
-static void fbcon_deinit(struct vc_data *conp);
-static int fbcon_changevar(int con);
-static void fbcon_clear(struct vc_data *conp, int sy, int sx, int height,
-		       int width);
-static void fbcon_putc(struct vc_data *conp, int c, int ypos, int xpos);
-static void fbcon_putcs(struct vc_data *conp, const unsigned short *s, int count,
-			int ypos, int xpos);
-static void fbcon_cursor(struct vc_data *conp, int mode);
-static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir,
-			 int count);
-static void fbcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
-			int height, int width);
-static int fbcon_switch(struct vc_data *conp);
-static int fbcon_blank(struct vc_data *conp, int blank);
-static int fbcon_font_op(struct vc_data *conp, struct console_font_op *op);
-static int fbcon_set_palette(struct vc_data *conp, unsigned char *table);
-static int fbcon_scrolldelta(struct vc_data *conp, int lines);
-
-
-/*
- *  Internal routines
- */
-
-static void fbcon_setup(int con, int init, int logo);
-static __inline__ int real_y(struct display *p, int ypos);
-static void fbcon_vbl_handler(int irq, void *dummy, struct pt_regs *fp);
-static __inline__ void updatescrollmode(struct display *p);
-static __inline__ void ywrap_up(int unit, struct vc_data *conp,
-				struct display *p, int count);
-static __inline__ void ywrap_down(int unit, struct vc_data *conp,
-				  struct display *p, int count);
-static __inline__ void ypan_up(int unit, struct vc_data *conp,
-			       struct display *p, int count);
-static __inline__ void ypan_down(int unit, struct vc_data *conp,
-				 struct display *p, int count);
-static void fbcon_bmove_rec(struct display *p, int sy, int sx, int dy, int dx,
-			    int height, int width, u_int y_break);
-
-static int fbcon_show_logo(void);
-
-#ifdef CONFIG_MAC
-/*
- * On the Macintoy, there may or may not be a working VBL int. We need to probe
- */
-static int vbl_detected;
-
-static void fbcon_vbl_detect(int irq, void *dummy, struct pt_regs *fp)
-{
-      vbl_detected++;
-}
-#endif
-
-static void cursor_timer_handler(unsigned long dev_addr);
-
-static struct timer_list cursor_timer = {
-    function: cursor_timer_handler
-};
-
-static void cursor_timer_handler(unsigned long dev_addr)
-{
-      fbcon_vbl_handler(0, NULL, NULL);
-      cursor_timer.expires = jiffies+HZ/50;
-      add_timer(&cursor_timer);
-}
-
-
-/**
- *	PROC_CONSOLE - find the attached tty or visible console
- *	@info: frame buffer info structure
- *
- *	Finds the tty attached to the process or visible console if
- *	the process is not directly attached to a tty (e.g. remote
- *	user) for device @info.
- *
- *	Returns -1 errno on error, or tty/visible console number
- *	on success.
- *
- */
-
-int PROC_CONSOLE(const struct fb_info *info)
-{
-        int fgc;
-        
-        if (info->display_fg != NULL)
-                fgc = info->display_fg->vc_num;
-        else
-                return -1;
-                
-        if (!current->tty)
-                return fgc;
-
-        if (current->tty->driver.type != TTY_DRIVER_TYPE_CONSOLE)
-                /* XXX Should report error here? */
-                return fgc;
-
-        if (minor(current->tty->device) < 1)
-                return fgc;
-
-        return minor(current->tty->device) - 1;
-}
-
-
-/**
- *	set_all_vcs - set all virtual consoles to match
- *	@fbidx: frame buffer index (e.g. fb0, fb1, ...)
- *	@fb: frame buffer ops structure
- *	@var: frame buffer screen structure to set
- *	@info: frame buffer info structure
- *
- *	Set all virtual consoles to match screen info set in @var
- *	for device @info.
- *
- *	Returns negative errno on error, or zero on success.
- *
- */
-
-int set_all_vcs(int fbidx, struct fb_ops *fb, struct fb_var_screeninfo *var,
-                struct fb_info *info)
-{
-    int unit, err;
-
-    var->activate |= FB_ACTIVATE_TEST;
-    err = fb->fb_set_var(var, PROC_CONSOLE(info), info);
-    var->activate &= ~FB_ACTIVATE_TEST;
-    if (err)
-            return err;
-    for (unit = 0; unit < MAX_NR_CONSOLES; unit++)
-            if (fb_display[unit].conp && con2fb_map[unit] == fbidx)
-                    fb->fb_set_var(var, unit, info);
-    return 0;
-}
-
-
-/**
- *	set_con2fb_map - map console to frame buffer device
- *	@unit: virtual console number to map
- *	@newidx: frame buffer index to map virtual console to
- *
- *	Maps a virtual console @unit to a frame buffer device
- *	@newidx.
- *
- */
-
-void set_con2fb_map(int unit, int newidx)
-{
-    int oldidx = con2fb_map[unit];
-    struct fb_info *oldfb, *newfb;
-    struct vc_data *conp;
-    char *fontdata;
-    unsigned short fontwidth, fontheight, fontwidthlog, fontheightlog;
-    int userfont;
-
-    if (newidx != con2fb_map[unit]) {
-       oldfb = registered_fb[oldidx];
-       newfb = registered_fb[newidx];
-	if (newfb->fbops->owner)
-		__MOD_INC_USE_COUNT(newfb->fbops->owner);
-	if (newfb->fbops->fb_open && newfb->fbops->fb_open(newfb,0)) {
-		if (newfb->fbops->owner)
-			__MOD_DEC_USE_COUNT(newfb->fbops->owner);
-		return;
-	}
-	if (oldfb->fbops->fb_release)
-		oldfb->fbops->fb_release(oldfb,0);
-	if (oldfb->fbops->owner)
-		__MOD_DEC_USE_COUNT(oldfb->fbops->owner);
-       conp = fb_display[unit].conp;
-       fontdata = fb_display[unit].fontdata;
-       fontwidth = fb_display[unit]._fontwidth;
-       fontheight = fb_display[unit]._fontheight;
-       fontwidthlog = fb_display[unit]._fontwidthlog;
-       fontheightlog = fb_display[unit]._fontheightlog;
-       userfont = fb_display[unit].userfont;
-       con2fb_map[unit] = newidx;
-       fb_display[unit] = *(newfb->disp);
-       fb_display[unit].conp = conp;
-       fb_display[unit].fontdata = fontdata;
-       fb_display[unit]._fontwidth = fontwidth;
-       fb_display[unit]._fontheight = fontheight;
-       fb_display[unit]._fontwidthlog = fontwidthlog;
-       fb_display[unit]._fontheightlog = fontheightlog;
-       fb_display[unit].userfont = userfont;
-       fb_display[unit].fb_info = newfb;
-       if (conp)
-	   conp->vc_display_fg = &newfb->display_fg;
-       if (!newfb->display_fg)
-	   newfb->display_fg = conp;
-       if (!newfb->changevar)
-           newfb->changevar = oldfb->changevar;
-       /* tell console var has changed */
-       if (newfb->changevar)
-           newfb->changevar(unit);
-   }
-}
-
-/*
- *  Low Level Operations
- */
-
-struct display_switch fbcon_dummy;
-
-/* NOTE: fbcon cannot be __init: it may be called from take_over_console later */
-
-static const char *fbcon_startup(void)
-{
-    const char *display_desc = "frame buffer device";
-    int irqres = 1;
-    static int done = 0;
-
-    /*
-     *  If num_registered_fb is zero, this is a call for the dummy part.
-     *  The frame buffer devices weren't initialized yet.
-     */
-    if (!num_registered_fb || done)
-	return display_desc;
-    done = 1;
-
-#ifdef CONFIG_AMIGA
-    if (MACH_IS_AMIGA) {
-	cursor_blink_rate = AMIGA_CURSOR_BLINK_RATE;
-	irqres = request_irq(IRQ_AMIGA_VERTB, fbcon_vbl_handler, 0,
-			     "console/cursor", fbcon_vbl_handler);
-    }
-#endif /* CONFIG_AMIGA */
-#ifdef CONFIG_ATARI
-    if (MACH_IS_ATARI) {
-	cursor_blink_rate = ATARI_CURSOR_BLINK_RATE;
-	irqres = request_irq(IRQ_AUTO_4, fbcon_vbl_handler, IRQ_TYPE_PRIO,
-			     "console/cursor", fbcon_vbl_handler);
-    }
-#endif /* CONFIG_ATARI */
-
-#ifdef CONFIG_MAC
-    /*
-     * On a Macintoy, the VBL interrupt may or may not be active. 
-     * As interrupt based cursor is more reliable and race free, we 
-     * probe for VBL interrupts.
-     */
-    if (MACH_IS_MAC) {
-	int ct = 0;
-	/*
-	 * Probe for VBL: set temp. handler ...
-	 */
-	irqres = request_irq(IRQ_MAC_VBL, fbcon_vbl_detect, 0,
-			     "console/cursor", fbcon_vbl_detect);
-	vbl_detected = 0;
-
-	/*
-	 * ... and spin for 20 ms ...
-	 */
-	while (!vbl_detected && ++ct<1000)
-	    udelay(20);
- 
-	if(ct==1000)
-	    printk("fbcon_startup: No VBL detected, using timer based cursor.\n");
- 
-	free_irq(IRQ_MAC_VBL, fbcon_vbl_detect);
-
-	if (vbl_detected) {
-	    /*
-	     * interrupt based cursor ok
-	     */
-	    cursor_blink_rate = MAC_CURSOR_BLINK_RATE;
-	    irqres = request_irq(IRQ_MAC_VBL, fbcon_vbl_handler, 0,
-				 "console/cursor", fbcon_vbl_handler);
-	} else {
-	    /*
-	     * VBL not detected: fall through, use timer based cursor
-	     */
-	    irqres = 1;
-	}
-    }
-#endif /* CONFIG_MAC */
-
-#if defined(__arm__) && defined(IRQ_VSYNCPULSE)
-    cursor_blink_rate = ARM_CURSOR_BLINK_RATE;
-    irqres = request_irq(IRQ_VSYNCPULSE, fbcon_vbl_handler, SA_SHIRQ,
-			 "console/cursor", fbcon_vbl_handler);
-#endif
-
-    if (irqres) {
-	cursor_blink_rate = DEFAULT_CURSOR_BLINK_RATE;
-	cursor_timer.expires = jiffies+HZ/50;
-	add_timer(&cursor_timer);
-    }
-
-    return display_desc;
-}
-
-
-static void fbcon_init(struct vc_data *conp, int init)
-{
-    int unit = conp->vc_num;
-    struct fb_info *info;
-
-    /* on which frame buffer will we open this console? */
-    info = registered_fb[(int)con2fb_map[unit]];
-
-    info->changevar = &fbcon_changevar;
-    fb_display[unit] = *(info->disp);	/* copy from default */
-    DPRINTK("mode:   %s\n",info->modename);
-    DPRINTK("visual: %d\n",fb_display[unit].visual);
-    DPRINTK("res:    %dx%d-%d\n",fb_display[unit].var.xres,
-	                     fb_display[unit].var.yres,
-	                     fb_display[unit].var.bits_per_pixel);
-    fb_display[unit].conp = conp;
-    fb_display[unit].fb_info = info;
-    /* clear out the cmap so we don't have dangling pointers */
-    fb_display[unit].cmap.len = 0;
-    fb_display[unit].cmap.red = 0;
-    fb_display[unit].cmap.green = 0;
-    fb_display[unit].cmap.blue = 0;
-    fb_display[unit].cmap.transp = 0;
-    fbcon_setup(unit, init, !init);
-    /* Must be done after fbcon_setup to prevent excess updates */
-    conp->vc_display_fg = &info->display_fg;
-    if (!info->display_fg)
-        info->display_fg = conp;
-}
-
-
-static void fbcon_deinit(struct vc_data *conp)
-{
-    int unit = conp->vc_num;
-    struct display *p = &fb_display[unit];
-
-    fbcon_free_font(p);
-    p->dispsw = &fbcon_dummy;
-    p->conp = 0;
-}
-
-
-static int fbcon_changevar(int con)
-{
-    if (fb_display[con].conp)
-	    fbcon_setup(con, 0, 0);
-    return 0;
-}
-
-
-static __inline__ void updatescrollmode(struct display *p)
-{
-    struct fb_info *info = p->fb_info;	
-
-    int m;
-    if (p->scrollmode & __SCROLL_YFIXED)
-    	return;
-    if (divides(info->fix.ywrapstep, fontheight(p)) &&
-	divides(fontheight(p), info->var.yres_virtual))
-	m = __SCROLL_YWRAP;
-    else if (divides(info->fix.ypanstep, fontheight(p)) &&
-	     p->var.yres_virtual >= p->var.yres+fontheight(p))
-	m = __SCROLL_YPAN;
-    else if (p->scrollmode & __SCROLL_YNOMOVE)
-    	m = __SCROLL_YREDRAW;
-    else
-	m = __SCROLL_YMOVE;
-    p->scrollmode = (p->scrollmode & ~__SCROLL_YMASK) | m;
-}
-
-static void fbcon_font_widths(struct display *p)
-{
-    int i;
-    
-    p->_fontwidthlog = 0;
-    for (i = 2; i <= 6; i++)
-    	if (fontwidth(p) == (1 << i))
-	    p->_fontwidthlog = i;
-    p->_fontheightlog = 0;
-    for (i = 2; i <= 6; i++)
-    	if (fontheight(p) == (1 << i))
-	    p->_fontheightlog = i;
-}
-
-#define fontwidthvalid(p,w) ((p)->dispsw->fontwidthmask & FONTWIDTH(w))
-
-static void fbcon_setup(int con, int init, int logo)
-{
-    struct display *p = &fb_display[con];
-    struct fb_info *info = p->fb_info;
-    struct vc_data *conp = p->conp;
-    int nr_rows, nr_cols;
-    int old_rows, old_cols;
-    unsigned short *save = NULL, *r, *q;
-    int i, charcnt = 256;
-    struct fbcon_font_desc *font;
-    
-    if (con != fg_console || (info->flags & FBINFO_FLAG_MODULE) ||
-        info->fix.type == FB_TYPE_TEXT)
-    	logo = 0;
-
-    p->var.xoffset = p->var.yoffset = p->yscroll = 0;  /* reset wrap/pan */
-
-    if (con == fg_console && info->fix.type != FB_TYPE_TEXT) {   
-	if (fbcon_softback_size) {
-	    if (!softback_buf) {
-		softback_buf = (unsigned long)kmalloc(fbcon_softback_size, GFP_KERNEL);
-		if (!softback_buf) {
-    	            fbcon_softback_size = 0;
-    	            softback_top = 0;
-    		}
-    	    }
-	} else {
-	    if (softback_buf) {
-		kfree((void *)softback_buf);
-		softback_buf = 0;
-		softback_top = 0;
-	    }
-	}
-	if (softback_buf)
-	    softback_in = softback_top = softback_curr = softback_buf;
-	softback_lines = 0;
-    }
-    
-    for (i = 0; i < MAX_NR_CONSOLES; i++)
-    	if (i != con && fb_display[i].fb_info == p->fb_info &&
-    	    fb_display[i].conp && fb_display[i].fontdata)
-    		break;
-
-    fbcon_free_font(p);    
-    if (i < MAX_NR_CONSOLES) {
-    	struct display *q = &fb_display[i];
-
-        if (fontwidthvalid(p,fontwidth(q))) {
-            /* If we are not the first console on this
-               fb, copy the font from that console */
-	    p->_fontwidth = q->_fontwidth;
-	    p->_fontheight = q->_fontheight;
-    	    p->_fontwidthlog = q->_fontwidthlog;
-    	    p->_fontheightlog = q->_fontheightlog;
-    	    p->fontdata = q->fontdata;
-    	    p->userfont = q->userfont; 
-    	    if (p->userfont) {
-    		REFCOUNT(p->fontdata)++;
-    		charcnt = FNTCHARCNT(p->fontdata);
-    	    }
-    	    con_copy_unimap(con, i);
-    	}
-    }
-
-    if (!p->fontdata) {
-        if (!p->fb_info->fontname[0] ||
-	    !(font = fbcon_find_font(p->fb_info->fontname)))
-	        font = fbcon_get_default_font(p->var.xres, p->var.yres);
-        p->_fontwidth = font->width;
-        p->_fontheight = font->height;
-        p->fontdata = font->data;
-        fbcon_font_widths(p);
-    }
-    
-    if (!fontwidthvalid(p,fontwidth(p))) {
-#if defined(CONFIG_FBCON_MAC) && defined(CONFIG_MAC)
-	if (MACH_IS_MAC)
-	    /* ++Geert: hack to make 6x11 fonts work on mac */
-	    p->dispsw = &fbcon_mac;
-	else
-#endif
-	{
-	    /* ++Geert: changed from panic() to `correct and continue' */
-	    printk(KERN_ERR "fbcon_setup: No support for fontwidth %d\n", fontwidth(p));
-	    p->dispsw = &fbcon_dummy;
-	}
-    }
-    if (p->dispsw->set_font)
-    	p->dispsw->set_font(p, fontwidth(p), fontheight(p));
-    updatescrollmode(p);
-    
-    old_cols = conp->vc_cols;
-    old_rows = conp->vc_rows;
-    
-    nr_cols = p->var.xres/fontwidth(p);
-    nr_rows = p->var.yres/fontheight(p);
-    
-    if (logo) {
-    	/* Need to make room for the logo */
-	int cnt;
-	int step;
-    
-    	logo_lines = (LOGO_H + fontheight(p) - 1) / fontheight(p);
-    	q = (unsigned short *)(conp->vc_origin + conp->vc_size_row * old_rows);
-    	step = logo_lines * old_cols;
-    	for (r = q - logo_lines * old_cols; r < q; r++)
-    	    if (scr_readw(r) != conp->vc_video_erase_char)
-    	    	break;
-	if (r != q && nr_rows >= old_rows + logo_lines) {
-    	    save = kmalloc(logo_lines * nr_cols * 2, GFP_KERNEL);
-    	    if (save) {
-    	        int i = old_cols < nr_cols ? old_cols : nr_cols;
-    	    	scr_memsetw(save, conp->vc_video_erase_char, logo_lines * nr_cols * 2);
-    	    	r = q - step;
-    	    	for (cnt = 0; cnt < logo_lines; cnt++, r += i)
-    	    		scr_memcpyw(save + cnt * nr_cols, r, 2 * i);
-    	    	r = q;
-    	    }
-    	}
-    	if (r == q) {
-    	    /* We can scroll screen down */
-	    r = q - step - old_cols;
-    	    for (cnt = old_rows - logo_lines; cnt > 0; cnt--) {
-    	    	scr_memcpyw(r + step, r, conp->vc_size_row);
-    	    	r -= old_cols;
-    	    }
-    	    if (!save) {
-	    	conp->vc_y += logo_lines;
-    		conp->vc_pos += logo_lines * conp->vc_size_row;
-    	    }
-    	}
-    	scr_memsetw((unsigned short *)conp->vc_origin,
-		    conp->vc_video_erase_char, 
-		    conp->vc_size_row * logo_lines);
-    }
-    
-    /*
-     *  ++guenther: console.c:vc_allocate() relies on initializing
-     *  vc_{cols,rows}, but we must not set those if we are only
-     *  resizing the console.
-     */
-    if (init) {
-	conp->vc_cols = nr_cols;
-	conp->vc_rows = nr_rows;
-    }
-    p->vrows = p->var.yres_virtual/fontheight(p);
-    if ((p->var.yres % fontheight(p)) &&
-	(p->var.yres_virtual % fontheight(p) < p->var.yres % fontheight(p)))
-	p->vrows--;
-    conp->vc_can_do_color = p->var.bits_per_pixel != 1;
-    conp->vc_complement_mask = conp->vc_can_do_color ? 0x7700 : 0x0800;
-    if (charcnt == 256) {
-    	conp->vc_hi_font_mask = 0;
-    	p->fgshift = 8;
-    	p->bgshift = 12;
-    	p->charmask = 0xff;
-    } else {
-    	conp->vc_hi_font_mask = 0x100;
-    	if (conp->vc_can_do_color)
-	    conp->vc_complement_mask <<= 1;
-    	p->fgshift = 9;
-    	p->bgshift = 13;
-    	p->charmask = 0x1ff;
-    }
-
-    if (p->dispsw == &fbcon_dummy)
-	printk(KERN_WARNING "fbcon_setup: type %d (aux %d, depth %d) not "
-	       "supported\n", info->fix.type, info->fix.type_aux, 
-		p->var.bits_per_pixel);
-    p->dispsw->setup(p);
-
-    p->fgcol = p->var.bits_per_pixel > 2 ? 7 : (1<<p->var.bits_per_pixel)-1;
-    p->bgcol = 0;
-
-    if (!init) {
-	if (conp->vc_cols != nr_cols || conp->vc_rows != nr_rows)
-	    vc_resize_con(nr_rows, nr_cols, con);
-	else if (CON_IS_VISIBLE(conp) &&
-		 vt_cons[conp->vc_num]->vc_mode == KD_TEXT) {
-	    if (p->dispsw->clear_margins)
-		p->dispsw->clear_margins(conp, p, 0);
-	    update_screen(con);
-	}
-	if (save) {
-    	    q = (unsigned short *)(conp->vc_origin + conp->vc_size_row * old_rows);
-	    scr_memcpyw(q, save, logo_lines * nr_cols * 2);
-	    conp->vc_y += logo_lines;
-    	    conp->vc_pos += logo_lines * conp->vc_size_row;
-    	    kfree(save);
-	}
-    }
-	
-    if (logo) {
-	logo_shown = -2;
-    	conp->vc_top = logo_lines;
-    }
-    
-    if (con == fg_console && softback_buf) {
-    	int l = fbcon_softback_size / conp->vc_size_row;
-    	if (l > 5)
-    	    softback_end = softback_buf + l * conp->vc_size_row;
-    	else {
-    	    /* Smaller scrollback makes no sense, and 0 would screw
-    	       the operation totally */
-    	    softback_top = 0;
-    	}
-    }
-}
-
-
-/* ====================================================================== */
-
-/*  fbcon_XXX routines - interface used by the world
- *
- *  This system is now divided into two levels because of complications
- *  caused by hardware scrolling. Top level functions:
- *
- *	fbcon_bmove(), fbcon_clear(), fbcon_putc()
- *
- *  handles y values in range [0, scr_height-1] that correspond to real
- *  screen positions. y_wrap shift means that first line of bitmap may be
- *  anywhere on this display. These functions convert lineoffsets to
- *  bitmap offsets and deal with the wrap-around case by splitting blits.
- *
- *	fbcon_bmove_physical_8()    -- These functions fast implementations
- *	fbcon_clear_physical_8()    -- of original fbcon_XXX fns.
- *	fbcon_putc_physical_8()	    -- (fontwidth != 8) may be added later
- *
- *  WARNING:
- *
- *  At the moment fbcon_putc() cannot blit across vertical wrap boundary
- *  Implies should only really hardware scroll in rows. Only reason for
- *  restriction is simplicity & efficiency at the moment.
- */
-
-static __inline__ int real_y(struct display *p, int ypos)
-{
-    int rows = p->vrows;
-
-    ypos += p->yscroll;
-    return ypos < rows ? ypos : ypos-rows;
-}
-
-
-static void fbcon_clear(struct vc_data *conp, int sy, int sx, int height,
-			int width)
-{
-    int unit = conp->vc_num;
-    struct display *p = &fb_display[unit];
-    u_int y_break;
-    int redraw_cursor = 0;
-
-    if (!p->can_soft_blank && console_blanked)
-	return;
-
-    if (!height || !width)
-	return;
-
-    if ((sy <= p->cursor_y) && (p->cursor_y < sy+height) &&
-	(sx <= p->cursor_x) && (p->cursor_x < sx+width)) {
-	cursor_undrawn();
-	redraw_cursor = 1;
-    }
-
-    /* Split blits that cross physical y_wrap boundary */
-
-    y_break = p->vrows-p->yscroll;
-    if (sy < y_break && sy+height-1 >= y_break) {
-	u_int b = y_break-sy;
-	p->dispsw->clear(conp, p, real_y(p, sy), sx, b, width);
-	p->dispsw->clear(conp, p, real_y(p, sy+b), sx, height-b, width);
-    } else
-	p->dispsw->clear(conp, p, real_y(p, sy), sx, height, width);
-
-    if (redraw_cursor)
-	vbl_cursor_cnt = CURSOR_DRAW_DELAY;
-}
-
-
-static void fbcon_putc(struct vc_data *conp, int c, int ypos, int xpos)
-{
-    int unit = conp->vc_num;
-    struct display *p = &fb_display[unit];
-    int redraw_cursor = 0;
-
-    if (!p->can_soft_blank && console_blanked)
-	    return;
-	    
-    if (vt_cons[unit]->vc_mode != KD_TEXT)
-    	    return;
-
-    if ((p->cursor_x == xpos) && (p->cursor_y == ypos)) {
-	    cursor_undrawn();
-	    redraw_cursor = 1;
-    }
-
-    p->dispsw->putc(conp, p, c, real_y(p, ypos), xpos);
-
-    if (redraw_cursor)
-	    vbl_cursor_cnt = CURSOR_DRAW_DELAY;
-}
-
-
-static void fbcon_putcs(struct vc_data *conp, const unsigned short *s, int count,
-		       int ypos, int xpos)
-{
-    int unit = conp->vc_num;
-    struct display *p = &fb_display[unit];
-    int redraw_cursor = 0;
-
-    if (!p->can_soft_blank && console_blanked)
-	    return;
-
-    if (vt_cons[unit]->vc_mode != KD_TEXT)
-    	    return;
-
-    if ((p->cursor_y == ypos) && (xpos <= p->cursor_x) &&
-	(p->cursor_x < (xpos + count))) {
-	    cursor_undrawn();
-	    redraw_cursor = 1;
-    }
-    p->dispsw->putcs(conp, p, s, count, real_y(p, ypos), xpos);
-    if (redraw_cursor)
-	    vbl_cursor_cnt = CURSOR_DRAW_DELAY;
-}
-
-
-static void fbcon_cursor(struct vc_data *conp, int mode)
-{
-    int unit = conp->vc_num;
-    struct display *p = &fb_display[unit];
-    int y = conp->vc_y;
-    
-    if (mode & CM_SOFTBACK) {
-    	mode &= ~CM_SOFTBACK;
-    	if (softback_lines) {
-    	    if (y + softback_lines >= conp->vc_rows)
-    		mode = CM_ERASE;
-    	    else
-    	        y += softback_lines;
-    	}
-    } else if (softback_lines)
-        fbcon_set_origin(conp);
-
-    /* do we have a hardware cursor ? */
-    if (p->dispsw->cursor) {
-	p->cursor_x = conp->vc_x;
-	p->cursor_y = y;
-	p->dispsw->cursor(p, mode, p->cursor_x, real_y(p, p->cursor_y));
-	return;
-    }
-
-    /* Avoid flickering if there's no real change. */
-    if (p->cursor_x == conp->vc_x && p->cursor_y == y &&
-	(mode == CM_ERASE) == !cursor_on)
-	return;
-
-    cursor_on = 0;
-    if (cursor_drawn)
-        p->dispsw->revc(p, p->cursor_x, real_y(p, p->cursor_y));
-
-    p->cursor_x = conp->vc_x;
-    p->cursor_y = y;
-
-    switch (mode) {
-        case CM_ERASE:
-            cursor_drawn = 0;
-            break;
-        case CM_MOVE:
-        case CM_DRAW:
-            if (cursor_drawn)
-	        p->dispsw->revc(p, p->cursor_x, real_y(p, p->cursor_y));
-            vbl_cursor_cnt = CURSOR_DRAW_DELAY;
-            cursor_on = 1;
-            break;
-        }
-}
-
-
-static void fbcon_vbl_handler(int irq, void *dummy, struct pt_regs *fp)
-{
-    struct display *p;
-
-    if (!cursor_on)
-	return;
-
-    if (vbl_cursor_cnt && --vbl_cursor_cnt == 0) {
-	p = &fb_display[fg_console];
-	if (p->dispsw->revc)
-		p->dispsw->revc(p, p->cursor_x, real_y(p, p->cursor_y));
-	cursor_drawn ^= 1;
-	vbl_cursor_cnt = cursor_blink_rate;
-    }
-}
-
-static int scrollback_phys_max = 0;
-static int scrollback_max = 0;
-static int scrollback_current = 0;
-
-static __inline__ void ywrap_up(int unit, struct vc_data *conp,
-				struct display *p, int count)
-{
-    p->yscroll += count;
-    if (p->yscroll >= p->vrows)	/* Deal with wrap */
-	p->yscroll -= p->vrows;
-    p->var.xoffset = 0;
-    p->var.yoffset = p->yscroll*fontheight(p);
-    p->var.vmode |= FB_VMODE_YWRAP;
-    p->fb_info->updatevar(unit, p->fb_info);
-    scrollback_max += count;
-    if (scrollback_max > scrollback_phys_max)
-	scrollback_max = scrollback_phys_max;
-    scrollback_current = 0;
-}
-
-
-static __inline__ void ywrap_down(int unit, struct vc_data *conp,
-				  struct display *p, int count)
-{
-    p->yscroll -= count;
-    if (p->yscroll < 0)		/* Deal with wrap */
-	p->yscroll += p->vrows;
-    p->var.xoffset = 0;
-    p->var.yoffset = p->yscroll*fontheight(p);
-    p->var.vmode |= FB_VMODE_YWRAP;
-    p->fb_info->updatevar(unit, p->fb_info);
-    scrollback_max -= count;
-    if (scrollback_max < 0)
-	scrollback_max = 0;
-    scrollback_current = 0;
-}
-
-
-static __inline__ void ypan_up(int unit, struct vc_data *conp,
-			       struct display *p, int count)
-{
-    p->yscroll += count;
-    if (p->yscroll > p->vrows-conp->vc_rows) {
-	p->dispsw->bmove(p, p->vrows-conp->vc_rows, 0, 0, 0,
-			 conp->vc_rows, conp->vc_cols);
-	p->yscroll -= p->vrows-conp->vc_rows;
-    }
-    p->var.xoffset = 0;
-    p->var.yoffset = p->yscroll*fontheight(p);
-    p->var.vmode &= ~FB_VMODE_YWRAP;
-    p->fb_info->updatevar(unit, p->fb_info);
-    if (p->dispsw->clear_margins)
-	p->dispsw->clear_margins(conp, p, 1);
-    scrollback_max += count;
-    if (scrollback_max > scrollback_phys_max)
-	scrollback_max = scrollback_phys_max;
-    scrollback_current = 0;
-}
-
-
-static __inline__ void ypan_down(int unit, struct vc_data *conp,
-				 struct display *p, int count)
-{
-    p->yscroll -= count;
-    if (p->yscroll < 0) {
-	p->dispsw->bmove(p, 0, 0, p->vrows-conp->vc_rows, 0,
-			 conp->vc_rows, conp->vc_cols);
-	p->yscroll += p->vrows-conp->vc_rows;
-    }
-    p->var.xoffset = 0;
-    p->var.yoffset = p->yscroll*fontheight(p);
-    p->var.vmode &= ~FB_VMODE_YWRAP;
-    p->fb_info->updatevar(unit, p->fb_info);
-    if (p->dispsw->clear_margins)
-	p->dispsw->clear_margins(conp, p, 1);
-    scrollback_max -= count;
-    if (scrollback_max < 0)
-	scrollback_max = 0;
-    scrollback_current = 0;
-}
-
-static void fbcon_redraw_softback(struct vc_data *conp, struct display *p, long delta)
-{
-    unsigned short *d, *s;
-    unsigned long n;
-    int line = 0;
-    int count = conp->vc_rows;
-    
-    d = (u16 *)softback_curr;
-    if (d == (u16 *)softback_in)
-	d = (u16 *)conp->vc_origin;
-    n = softback_curr + delta * conp->vc_size_row;
-    softback_lines -= delta;
-    if (delta < 0) {
-        if (softback_curr < softback_top && n < softback_buf) {
-            n += softback_end - softback_buf;
-	    if (n < softback_top) {
-		softback_lines -= (softback_top - n) / conp->vc_size_row;
-		n = softback_top;
-	    }
-        } else if (softback_curr >= softback_top && n < softback_top) {
-	    softback_lines -= (softback_top - n) / conp->vc_size_row;
-	    n = softback_top;
-        }
-    } else {
-    	if (softback_curr > softback_in && n >= softback_end) {
-    	    n += softback_buf - softback_end;
-	    if (n > softback_in) {
-		n = softback_in;
-		softback_lines = 0;
-	    }
-	} else if (softback_curr <= softback_in && n > softback_in) {
-	    n = softback_in;
-	    softback_lines = 0;
-	}
-    }
-    if (n == softback_curr)
-    	return;
-    softback_curr = n;
-    s = (u16 *)softback_curr;
-    if (s == (u16 *)softback_in)
-	s = (u16 *)conp->vc_origin;
-    while (count--) {
-	unsigned short *start;
-	unsigned short *le;
-	unsigned short c;
-	int x = 0;
-	unsigned short attr = 1;
-
-	start = s;
-	le = advance_row(s, 1);
-	do {
-	    c = scr_readw(s);
-	    if (attr != (c & 0xff00)) {
-		attr = c & 0xff00;
-		if (s > start) {
-		    p->dispsw->putcs(conp, p, start, s - start,
-				     real_y(p, line), x);
-		    x += s - start;
-		    start = s;
-		}
-	    }
-	    if (c == scr_readw(d)) {
-	    	if (s > start) {
-	    	    p->dispsw->putcs(conp, p, start, s - start,
-				     real_y(p, line), x);
-		    x += s - start + 1;
-		    start = s + 1;
-	    	} else {
-	    	    x++;
-	    	    start++;
-	    	}
-	    }
-	    s++;
-	    d++;
-	} while (s < le);
-	if (s > start)
-	    p->dispsw->putcs(conp, p, start, s - start, real_y(p, line), x);
-	line++;
-	if (d == (u16 *)softback_end)
-	    d = (u16 *)softback_buf;
-	if (d == (u16 *)softback_in)
-	    d = (u16 *)conp->vc_origin;
-	if (s == (u16 *)softback_end)
-	    s = (u16 *)softback_buf;
-	if (s == (u16 *)softback_in)
-	    s = (u16 *)conp->vc_origin;
-    }
-}
-
-static void fbcon_redraw(struct vc_data *conp, struct display *p, 
-			 int line, int count, int offset)
-{
-    unsigned short *d = (unsigned short *)
-	(conp->vc_origin + conp->vc_size_row * line);
-    unsigned short *s = d + offset;
-
-    while (count--) {
-	unsigned short *start = s;
-	unsigned short *le = advance_row(s, 1);
-	unsigned short c;
-	int x = 0;
-	unsigned short attr = 1;
-
-	do {
-	    c = scr_readw(s);
-	    if (attr != (c & 0xff00)) {
-		attr = c & 0xff00;
-		if (s > start) {
-		    p->dispsw->putcs(conp, p, start, s - start,
-				     real_y(p, line), x);
-		    x += s - start;
-		    start = s;
-		}
-	    }
-	    if (c == scr_readw(d)) {
-	    	if (s > start) {
-	    	    p->dispsw->putcs(conp, p, start, s - start,
-				     real_y(p, line), x);
-		    x += s - start + 1;
-		    start = s + 1;
-	    	} else {
-	    	    x++;
-	    	    start++;
-	    	}
-	    }
-	    scr_writew(c, d);
-	    console_conditional_schedule();
-	    s++;
-	    d++;
-	} while (s < le);
-	if (s > start)
-	    p->dispsw->putcs(conp, p, start, s - start, real_y(p, line), x);
-	console_conditional_schedule();
-	if (offset > 0)
-		line++;
-	else {
-		line--;
-		/* NOTE: We subtract two lines from these pointers */
-		s -= conp->vc_size_row;
-		d -= conp->vc_size_row;
-	}
-    }
-}
-
-/**
- *	fbcon_redraw_clear - clear area of the screen
- *	@conp: stucture pointing to current active virtual console
- *	@p: display structure
- *	@sy: starting Y coordinate
- *	@sx: starting X coordinate
- *	@height: height of area to clear
- *	@width: width of area to clear
- *
- *	Clears a specified area of the screen.  All dimensions are in
- *	pixels.
- *
- */
-
-void fbcon_redraw_clear(struct vc_data *conp, struct display *p, int sy, int sx,
-		     int height, int width)
-{
-    int x, y;
-    for (y=0; y<height; y++)
-	for (x=0; x<width; x++)
-	    fbcon_putc(conp, ' ', sy+y, sx+x);
-}
-
-
-/**
- *	fbcon_redraw_bmove - copy area of screen to another area
- *	@p: display structure
- *	@sy: origin Y coordinate
- *	@sx: origin X coordinate
- *	@dy: destination Y coordinate
- *	@dx: destination X coordinate
- *	@h: height of area to copy
- *	@w: width of area to copy
- *
- *	Copies an area of the screen to another area of the same screen.
- *	All dimensions are in pixels.
- *
- *	Note that this function cannot be used together with ypan or
- *	ywrap.
- *
- */
-
-void fbcon_redraw_bmove(struct display *p, int sy, int sx, int dy, int dx, int h, int w)
-{
-    if (sy != dy)
-    	panic("fbcon_redraw_bmove width sy != dy");
-    /* h will be always 1, but it does not matter if we are more generic */
-
-    while (h-- > 0) {
-	struct vc_data *conp = p->conp;
-	unsigned short *d = (unsigned short *)
-		(conp->vc_origin + conp->vc_size_row * dy + dx * 2);
-	unsigned short *s = d + (dx - sx);
-	unsigned short *start = d;
-	unsigned short *ls = d;
-	unsigned short *le = d + w;
-	unsigned short c;
-	int x = dx;
-	unsigned short attr = 1;
-
-	do {
-	    c = scr_readw(d);
-	    if (attr != (c & 0xff00)) {
-		attr = c & 0xff00;
-		if (d > start) {
-		    p->dispsw->putcs(conp, p, start, d - start, dy, x);
-		    x += d - start;
-		    start = d;
-		}
-	    }
-	    if (s >= ls && s < le && c == scr_readw(s)) {
-		if (d > start) {
-		    p->dispsw->putcs(conp, p, start, d - start, dy, x);
-		    x += d - start + 1;
-		    start = d + 1;
-		} else {
-		    x++;
-		    start++;
-		}
-	    }
-	    s++;
-	    d++;
-	} while (d < le);
-	if (d > start)
-	    p->dispsw->putcs(conp, p, start, d - start, dy, x);
-	sy++;
-	dy++;
-    }
-}
-
-static inline void fbcon_softback_note(struct vc_data *conp, int t, int count)
-{
-    unsigned short *p;
-
-    if (conp->vc_num != fg_console)
-	return;
-    p = (unsigned short *)(conp->vc_origin + t * conp->vc_size_row);
-
-    while (count) {
-    	scr_memcpyw((u16 *)softback_in, p, conp->vc_size_row);
-    	count--;
-    	p = advance_row(p, 1);
-    	softback_in += conp->vc_size_row;
-    	if (softback_in == softback_end)
-    	    softback_in = softback_buf;
-    	if (softback_in == softback_top) {
-    	    softback_top += conp->vc_size_row;
-    	    if (softback_top == softback_end)
-    	    	softback_top = softback_buf;
-    	}
-    }
-    softback_curr = softback_in;
-}
-
-static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir,
-			int count)
-{
-    int unit = conp->vc_num;
-    struct display *p = &fb_display[unit];
-    int scroll_partial = !(p->scrollmode & __SCROLL_YNOPARTIAL);
-
-    if (!p->can_soft_blank && console_blanked)
-	return 0;
-
-    if (!count || vt_cons[unit]->vc_mode != KD_TEXT)
-	return 0;
-
-    fbcon_cursor(conp, CM_ERASE);
-    
-    /*
-     * ++Geert: Only use ywrap/ypan if the console is in text mode
-     * ++Andrew: Only use ypan on hardware text mode when scrolling the
-     *           whole screen (prevents flicker).
-     */
-
-    switch (dir) {
-	case SM_UP:
-	    if (count > conp->vc_rows)	/* Maximum realistic size */
-		count = conp->vc_rows;
-	    if (softback_top)
-	        fbcon_softback_note(conp, t, count);
-	    if (logo_shown >= 0) goto redraw_up;
-	    switch (p->scrollmode & __SCROLL_YMASK) {
-	    case __SCROLL_YMOVE:
-		p->dispsw->bmove(p, t+count, 0, t, 0, b-t-count,
-				 conp->vc_cols);
-		p->dispsw->clear(conp, p, b-count, 0, count,
-				 conp->vc_cols);
-		break;
-
-	    case __SCROLL_YWRAP:
-		if (b-t-count > 3*conp->vc_rows>>2) {
-		    if (t > 0)
-			fbcon_bmove(conp, 0, 0, count, 0, t,
-				    conp->vc_cols);
-			ywrap_up(unit, conp, p, count);
-		    if (conp->vc_rows-b > 0)
-			fbcon_bmove(conp, b-count, 0, b, 0,
-				    conp->vc_rows-b, conp->vc_cols);
-		} else if (p->scrollmode & __SCROLL_YPANREDRAW)
-		    goto redraw_up;
-		else
-		    fbcon_bmove(conp, t+count, 0, t, 0, b-t-count,
-				conp->vc_cols);
-		fbcon_clear(conp, b-count, 0, count, conp->vc_cols);
-		break;
-
-	    case __SCROLL_YPAN:
-		if (( p->yscroll + count <= 2 * (p->vrows - conp->vc_rows)) &&
-		    (( !scroll_partial && (b-t == conp->vc_rows)) ||
-		     ( scroll_partial  && (b-t-count > 3*conp->vc_rows>>2)))) {
-		    if (t > 0)
-			fbcon_bmove(conp, 0, 0, count, 0, t,
-				    conp->vc_cols);
-		    ypan_up(unit, conp, p, count);
-		    if (conp->vc_rows-b > 0)
-			fbcon_bmove(conp, b-count, 0, b, 0,
-				    conp->vc_rows-b, conp->vc_cols);
-		} else if (p->scrollmode & __SCROLL_YPANREDRAW)
-		    goto redraw_up;
-		else
-		    fbcon_bmove(conp, t+count, 0, t, 0, b-t-count,
-				conp->vc_cols);
-		fbcon_clear(conp, b-count, 0, count, conp->vc_cols);
-		break;
-
-	    case __SCROLL_YREDRAW:
-	    redraw_up:
-		fbcon_redraw(conp, p, t, b-t-count, count*conp->vc_cols);
-		p->dispsw->clear(conp, p, real_y(p, b-count), 0,
-				 count, conp->vc_cols);
-		scr_memsetw((unsigned short *)(conp->vc_origin + 
-		    	    conp->vc_size_row * (b-count)), 
-		    	    conp->vc_video_erase_char,
-		    	    conp->vc_size_row * count);
-		return 1;
-	    }
-	    break;
-
-	case SM_DOWN:
-	    if (count > conp->vc_rows)	/* Maximum realistic size */
-		count = conp->vc_rows;
-	    switch (p->scrollmode & __SCROLL_YMASK) {
-	    case __SCROLL_YMOVE:
-		p->dispsw->bmove(p, t, 0, t+count, 0, b-t-count,
-				 conp->vc_cols);
-		p->dispsw->clear(conp, p, t, 0,
-				 count, conp->vc_cols);
-		break;
-
-	    case __SCROLL_YWRAP:
-		if (b-t-count > 3*conp->vc_rows>>2) {
-		    if (conp->vc_rows-b > 0)
-			fbcon_bmove(conp, b, 0, b-count, 0,
-				    conp->vc_rows-b, conp->vc_cols);
-		    ywrap_down(unit, conp, p, count);
-		    if (t > 0)
-			fbcon_bmove(conp, count, 0, 0, 0, t,
-				    conp->vc_cols);
-		} else if (p->scrollmode & __SCROLL_YPANREDRAW)
-		    goto redraw_down;
-		else
-		    fbcon_bmove(conp, t, 0, t+count, 0, b-t-count,
-				conp->vc_cols);
-		fbcon_clear(conp, t, 0, count, conp->vc_cols);
-		break;
-
-	    case __SCROLL_YPAN:
-		if (( count-p->yscroll <= p->vrows-conp->vc_rows) &&
-		    (( !scroll_partial && (b-t == conp->vc_rows)) ||
-		     ( scroll_partial  && (b-t-count > 3*conp->vc_rows>>2)))) {
-		    if (conp->vc_rows-b > 0)
-			fbcon_bmove(conp, b, 0, b-count, 0,
-				    conp->vc_rows-b, conp->vc_cols);
-		    ypan_down(unit, conp, p, count);
-		    if (t > 0)
-			fbcon_bmove(conp, count, 0, 0, 0, t,
-				    conp->vc_cols);
-		} else if (p->scrollmode & __SCROLL_YPANREDRAW)
-		    goto redraw_down;
-		else
-		    fbcon_bmove(conp, t, 0, t+count, 0, b-t-count,
-				conp->vc_cols);
-		fbcon_clear(conp, t, 0, count, conp->vc_cols);
-		break;
-
-	    case __SCROLL_YREDRAW:
-	    redraw_down:
-		fbcon_redraw(conp, p, b - 1, b-t-count, -count*conp->vc_cols);
-		p->dispsw->clear(conp, p, real_y(p, t), 0,
-				 count, conp->vc_cols);
-	    	scr_memsetw((unsigned short *)(conp->vc_origin + 
-	    		    conp->vc_size_row * t), 
-	    		    conp->vc_video_erase_char,
-	    		    conp->vc_size_row * count);
-	    	return 1;
-	    }
-    }
-    return 0;
-}
-
-
-static void fbcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
-			int height, int width)
-{
-    int unit = conp->vc_num;
-    struct display *p = &fb_display[unit];
-    
-    if (!p->can_soft_blank && console_blanked)
-	return;
-
-    if (!width || !height)
-	return;
-
-    if (((sy <= p->cursor_y) && (p->cursor_y < sy+height) &&
-	  (sx <= p->cursor_x) && (p->cursor_x < sx+width)) ||
-	 ((dy <= p->cursor_y) && (p->cursor_y < dy+height) &&
-	  (dx <= p->cursor_x) && (p->cursor_x < dx+width)))
-	fbcon_cursor(conp, CM_ERASE|CM_SOFTBACK);
-
-    /*  Split blits that cross physical y_wrap case.
-     *  Pathological case involves 4 blits, better to use recursive
-     *  code rather than unrolled case
-     *
-     *  Recursive invocations don't need to erase the cursor over and
-     *  over again, so we use fbcon_bmove_rec()
-     */
-    fbcon_bmove_rec(p, sy, sx, dy, dx, height, width, p->vrows-p->yscroll);
-}
-
-static void fbcon_bmove_rec(struct display *p, int sy, int sx, int dy, int dx,
-			    int height, int width, u_int y_break)
-{
-    u_int b;
-
-    if (sy < y_break && sy+height > y_break) {
-	b = y_break-sy;
-	if (dy < sy) {	/* Avoid trashing self */
-	    fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);
-	    fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);
-	} else {
-	    fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);
-	    fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);
-	}
-	return;
-    }
-
-    if (dy < y_break && dy+height > y_break) {
-	b = y_break-dy;
-	if (dy < sy) {	/* Avoid trashing self */
-	    fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);
-	    fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);
-	} else {
-	    fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);
-	    fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);
-	}
-	return;
-    }
-    p->dispsw->bmove(p, real_y(p, sy), sx, real_y(p, dy), dx, height, width);
-}
-
-
-static int fbcon_switch(struct vc_data *conp)
-{
-    int unit = conp->vc_num;
-    struct display *p = &fb_display[unit];
-    struct fb_info *info = p->fb_info;
-
-    if (softback_top) {
-    	int l = fbcon_softback_size / conp->vc_size_row;
-	if (softback_lines)
-	    fbcon_set_origin(conp);
-        softback_top = softback_curr = softback_in = softback_buf;
-        softback_lines = 0;
-
-	if (l > 5)
-	    softback_end = softback_buf + l * conp->vc_size_row;
-	else {
-	    /* Smaller scrollback makes no sense, and 0 would screw
-	       the operation totally */
-	    softback_top = 0;
-	}
-    }
-    if (logo_shown >= 0) {
-    	struct vc_data *conp2 = vc_cons[logo_shown].d;
-    	
-    	if (conp2->vc_top == logo_lines && conp2->vc_bottom == conp2->vc_rows)
-    		conp2->vc_top = 0;
-    	logo_shown = -1;
-    }
-    p->var.yoffset = p->yscroll = 0;
-    switch (p->scrollmode & __SCROLL_YMASK) {
-	case __SCROLL_YWRAP:
-	    scrollback_phys_max = p->vrows-conp->vc_rows;
-	    break;
-	case __SCROLL_YPAN:
-	    scrollback_phys_max = p->vrows-2*conp->vc_rows;
-	    if (scrollback_phys_max < 0)
-		scrollback_phys_max = 0;
-	    break;
-	default:
-	    scrollback_phys_max = 0;
-	    break;
-    }
-    scrollback_max = 0;
-    scrollback_current = 0;
-
-    if (info && info->switch_con)
-	(*info->switch_con)(unit, info);
-    if (p->dispsw->clear_margins && vt_cons[unit]->vc_mode == KD_TEXT)
-	p->dispsw->clear_margins(conp, p, 0);
-    if (logo_shown == -2) {
-	logo_shown = fg_console;
-	fbcon_show_logo(); /* This is protected above by initmem_freed */
-	update_region(fg_console,
-		      conp->vc_origin + conp->vc_size_row * conp->vc_top,
-		      conp->vc_size_row * (conp->vc_bottom - conp->vc_top) / 2);
-	return 0;
-    }
-    return 1;
-}
-
-
-static int fbcon_blank(struct vc_data *conp, int blank)
-{
-    struct display *p = &fb_display[conp->vc_num];
-    struct fb_info *info = p->fb_info;
-
-    if (blank < 0)	/* Entering graphics mode */
-	return 0;
-
-    fbcon_cursor(p->conp, blank ? CM_ERASE : CM_DRAW);
-
-    if (!p->can_soft_blank) {
-	if (blank) {
-	    if (info->fix.visual == FB_VISUAL_MONO01) {
-		if (info->screen_base)
-		    fb_memset255(info->screen_base,
-				 p->var.xres_virtual*p->var.yres_virtual*
-				 p->var.bits_per_pixel>>3);
-	    } else {
-	    	unsigned short oldc;
-	    	u_int height;
-	    	u_int y_break;
-
-	    	oldc = conp->vc_video_erase_char;
-	    	conp->vc_video_erase_char &= p->charmask;
-	    	height = conp->vc_rows;
-		y_break = p->vrows-p->yscroll;
-		if (height > y_break) {
-			p->dispsw->clear(conp, p, real_y(p, 0), 0, y_break, conp->vc_cols);
-			p->dispsw->clear(conp, p, real_y(p, y_break), 0, height-y_break, conp->vc_cols);
-		} else
-			p->dispsw->clear(conp, p, real_y(p, 0), 0, height, conp->vc_cols);
-		conp->vc_video_erase_char = oldc;
-	    }
-	    return 0;
-	} else {
-	    /* Tell console.c that it has to restore the screen itself */
-	    return 1;
-	}
-    }
-    if (info->fbops->fb_blank)	
-    	(*info->fbops->fb_blank)(blank, info);
-    return 0;
-}
-
-static void fbcon_free_font(struct display *p)
-{
-    if (p->userfont && p->fontdata &&
-        (--REFCOUNT(p->fontdata) == 0))
-	kfree(p->fontdata - FONT_EXTRA_WORDS*sizeof(int));
-    p->fontdata = NULL;
-    p->userfont = 0;
-}
-
-static inline int fbcon_get_font(int unit, struct console_font_op *op)
-{
-    struct display *p = &fb_display[unit];
-    u8 *data = op->data;
-    u8 *fontdata = p->fontdata;
-    int i, j;
-
-#ifdef CONFIG_FBCON_FONTWIDTH8_ONLY
-    if (fontwidth(p) != 8) return -EINVAL;
-#endif
-    op->width = fontwidth(p);
-    op->height = fontheight(p);
-    op->charcount = (p->charmask == 0x1ff) ? 512 : 256;
-    if (!op->data) return 0;
-    
-    if (op->width <= 8) {
-	j = fontheight(p);
-    	for (i = 0; i < op->charcount; i++) {
-	    memcpy(data, fontdata, j);
-	    memset(data+j, 0, 32-j);
-	    data += 32;
-	    fontdata += j;
-	}
-    }
-#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
-    else if (op->width <= 16) {
-	j = fontheight(p) * 2;
-	for (i = 0; i < op->charcount; i++) {
-	    memcpy(data, fontdata, j);
-	    memset(data+j, 0, 64-j);
-	    data += 64;
-	    fontdata += j;
-	}
-    } else if (op->width <= 24) {
-	for (i = 0; i < op->charcount; i++) {
-	    for (j = 0; j < fontheight(p); j++) {
-		*data++ = fontdata[0];
-		*data++ = fontdata[1];
-		*data++ = fontdata[2];
-		fontdata += sizeof(u32);
-	    }
-	    memset(data, 0, 3*(32-j));
-	    data += 3 * (32 - j);
-	}
-    } else {
-	j = fontheight(p) * 4;
-	for (i = 0; i < op->charcount; i++) {
-	    memcpy(data, fontdata, j);
-	    memset(data+j, 0, 128-j);
-	    data += 128;
-	    fontdata += j;
-	}
-    }
-#endif
-    return 0;
-}
-
-static int fbcon_do_set_font(int unit, struct console_font_op *op, u8 *data, int userfont)
-{
-    struct display *p = &fb_display[unit];
-    int resize;
-    int w = op->width;
-    int h = op->height;
-    int cnt;
-    char *old_data = NULL;
-
-    if (!fontwidthvalid(p,w)) {
-        if (userfont && op->op != KD_FONT_OP_COPY)
-	    kfree(data - FONT_EXTRA_WORDS*sizeof(int));
-	return -ENXIO;
-    }
-
-    if (CON_IS_VISIBLE(p->conp) && softback_lines)
-	fbcon_set_origin(p->conp);
-	
-    resize = (w != fontwidth(p)) || (h != fontheight(p));
-    if (p->userfont)
-        old_data = p->fontdata;
-    if (userfont)
-        cnt = FNTCHARCNT(data);
-    else
-    	cnt = 256;
-    p->fontdata = data;
-    if ((p->userfont = userfont))
-        REFCOUNT(data)++;
-    p->_fontwidth = w;
-    p->_fontheight = h;
-    if (p->conp->vc_hi_font_mask && cnt == 256) {
-    	p->conp->vc_hi_font_mask = 0;
-    	if (p->conp->vc_can_do_color)
-	    p->conp->vc_complement_mask >>= 1;
-    	p->fgshift--;
-    	p->bgshift--;
-    	p->charmask = 0xff;
-
-	/* ++Edmund: reorder the attribute bits */
-	if (p->conp->vc_can_do_color) {
-	    struct vc_data *conp = p->conp;
-	    unsigned short *cp = (unsigned short *) conp->vc_origin;
-	    int count = conp->vc_screenbuf_size/2;
-	    unsigned short c;
-	    for (; count > 0; count--, cp++) {
-	        c = scr_readw(cp);
-		scr_writew(((c & 0xfe00) >> 1) | (c & 0xff), cp);
-	    }
-	    c = conp->vc_video_erase_char;
-	    conp->vc_video_erase_char = ((c & 0xfe00) >> 1) | (c & 0xff);
-	    conp->vc_attr >>= 1;
-	}
-
-    } else if (!p->conp->vc_hi_font_mask && cnt == 512) {
-    	p->conp->vc_hi_font_mask = 0x100;
-    	if (p->conp->vc_can_do_color)
-	    p->conp->vc_complement_mask <<= 1;
-    	p->fgshift++;
-    	p->bgshift++;
-    	p->charmask = 0x1ff;
-
-	/* ++Edmund: reorder the attribute bits */
-	{
-	    struct vc_data *conp = p->conp;
-	    unsigned short *cp = (unsigned short *) conp->vc_origin;
-	    int count = conp->vc_screenbuf_size/2;
-	    unsigned short c;
-	    for (; count > 0; count--, cp++) {
-	        unsigned short newc;
-	        c = scr_readw(cp);
-		if (conp->vc_can_do_color)
-		    newc = ((c & 0xff00) << 1) | (c & 0xff);
-		else
-		    newc = c & ~0x100;
-		scr_writew(newc, cp);
-	    }
-	    c = conp->vc_video_erase_char;
-	    if (conp->vc_can_do_color) {
-		conp->vc_video_erase_char = ((c & 0xff00) << 1) | (c & 0xff);
-		conp->vc_attr <<= 1;
-	    } else
-	        conp->vc_video_erase_char = c & ~0x100;
-	}
-
-    }
-    fbcon_font_widths(p);
-
-    if (resize) {
-    	struct vc_data *conp = p->conp;
-	/* reset wrap/pan */
-	p->var.xoffset = p->var.yoffset = p->yscroll = 0;
-	p->vrows = p->var.yres_virtual/h;
-	if ((p->var.yres % h) && (p->var.yres_virtual % h < p->var.yres % h))
-	    p->vrows--;
-	updatescrollmode(p);
-	vc_resize_con( p->var.yres/h, p->var.xres/w, unit );
-        if (CON_IS_VISIBLE(conp) && softback_buf) {
-	    int l = fbcon_softback_size / conp->vc_size_row;
-	    if (l > 5)
-		softback_end = softback_buf + l * conp->vc_size_row;
-	    else {
-		/* Smaller scrollback makes no sense, and 0 would screw
-		   the operation totally */
-		softback_top = 0;
-    	    }
-    	}
-    } else if (CON_IS_VISIBLE(p->conp) && vt_cons[unit]->vc_mode == KD_TEXT) {
-	if (p->dispsw->clear_margins)
-	    p->dispsw->clear_margins(p->conp, p, 0);
-	update_screen(unit);
-    }
-
-    if (old_data && (--REFCOUNT(old_data) == 0))
-	kfree(old_data - FONT_EXTRA_WORDS*sizeof(int));
-
-    return 0;
-}
-
-static inline int fbcon_copy_font(int unit, struct console_font_op *op)
-{
-    struct display *od, *p = &fb_display[unit];
-    int h = op->height;
-
-    if (h < 0 || !vc_cons_allocated( h ))
-        return -ENOTTY;
-    if (h == unit)
-        return 0; /* nothing to do */
-    od = &fb_display[h];
-    if (od->fontdata == p->fontdata)
-        return 0; /* already the same font... */
-    op->width = fontwidth(od);
-    op->height = fontheight(od);
-    return fbcon_do_set_font(unit, op, od->fontdata, od->userfont);
-}
-
-static inline int fbcon_set_font(int unit, struct console_font_op *op)
-{
-    int w = op->width;
-    int h = op->height;
-    int size = h;
-    int i, k;
-    u8 *new_data, *data = op->data, *p;
-
-#ifdef CONFIG_FBCON_FONTWIDTH8_ONLY
-    if (w != 8)
-    	return -EINVAL;
-#endif
-    if ((w <= 0) || (w > 32) || (op->charcount != 256 && op->charcount != 512))
-        return -EINVAL;
-    
-    if (w > 8) { 
-    	if (w <= 16)
-    		size *= 2;
-    	else
-    		size *= 4;
-    }
-    size *= op->charcount;
-       
-    if (!(new_data = kmalloc(FONT_EXTRA_WORDS*sizeof(int)+size, GFP_USER)))
-        return -ENOMEM;
-    new_data += FONT_EXTRA_WORDS*sizeof(int);
-    FNTSIZE(new_data) = size;
-    FNTCHARCNT(new_data) = op->charcount;
-    REFCOUNT(new_data) = 0; /* usage counter */
-    p = new_data;
-    if (w <= 8) {
-	for (i = 0; i < op->charcount; i++) {
-	    memcpy(p, data, h);
-	    data += 32;
-	    p += h;
-	}
-    }
-#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
-    else if (w <= 16) {
-	h *= 2;
-	for (i = 0; i < op->charcount; i++) {
-	    memcpy(p, data, h);
-	    data += 64;
-	    p += h;
-	}
-    } else if (w <= 24) {
-	for (i = 0; i < op->charcount; i++) {
-	    int j;
-	    for (j = 0; j < h; j++) {
-	        memcpy(p, data, 3);
-		p[3] = 0;
-		data += 3;
-		p += sizeof(u32);
-	    }
-	    data += 3*(32 - h);
-	}
-    } else {
-	h *= 4;
-	for (i = 0; i < op->charcount; i++) {
-	    memcpy(p, data, h);
-	    data += 128;
-	    p += h;
-	}
-    }
-#endif
-    /* we can do it in u32 chunks because of charcount is 256 or 512, so
-       font length must be multiple of 256, at least. And 256 is multiple
-       of 4 */
-    k = 0;
-    while (p > new_data) k += *--(u32 *)p;
-    FNTSUM(new_data) = k;
-    /* Check if the same font is on some other console already */
-    for (i = 0; i < MAX_NR_CONSOLES; i++) {
-    	if (fb_display[i].userfont &&
-    	    fb_display[i].fontdata &&
-    	    FNTSUM(fb_display[i].fontdata) == k &&
-    	    FNTSIZE(fb_display[i].fontdata) == size &&
-    	    fontwidth(&fb_display[i]) == w &&
-	    !memcmp(fb_display[i].fontdata, new_data, size)) {
-	    kfree(new_data - FONT_EXTRA_WORDS*sizeof(int));
-	    new_data = fb_display[i].fontdata;
-	    break;
-    	}
-    }
-    return fbcon_do_set_font(unit, op, new_data, 1);
-}
-
-static inline int fbcon_set_def_font(int unit, struct console_font_op *op)
-{
-    char name[MAX_FONT_NAME];
-    struct fbcon_font_desc *f;
-    struct display *p = &fb_display[unit];
-
-    if (!op->data)
-	f = fbcon_get_default_font(p->var.xres, p->var.yres);
-    else if (strncpy_from_user(name, op->data, MAX_FONT_NAME-1) < 0)
-	return -EFAULT;
-    else {
-	name[MAX_FONT_NAME-1] = 0;
-	if (!(f = fbcon_find_font(name)))
-	    return -ENOENT;
-    }
-    op->width = f->width;
-    op->height = f->height;
-    return fbcon_do_set_font(unit, op, f->data, 0);
-}
-
-static int fbcon_font_op(struct vc_data *conp, struct console_font_op *op)
-{
-    int unit = conp->vc_num;
-
-    switch (op->op) {
-	case KD_FONT_OP_SET:
-	    return fbcon_set_font(unit, op);
-	case KD_FONT_OP_GET:
-	    return fbcon_get_font(unit, op);
-	case KD_FONT_OP_SET_DEFAULT:
-	    return fbcon_set_def_font(unit, op);
-	case KD_FONT_OP_COPY:
-	    return fbcon_copy_font(unit, op);
-	default:
-	    return -ENOSYS;
-    }
-}
-
-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
-};
-
-static int fbcon_set_palette(struct vc_data *conp, unsigned char *table)
-{
-    int unit = conp->vc_num;
-    struct display *p = &fb_display[unit];
-    int i, j, k;
-    u8 val;
-
-    if (!conp->vc_can_do_color || (!p->can_soft_blank && console_blanked))
-	return -EINVAL;
-    for (i = j = 0; i < 16; i++) {
-	k = table[i];
-	val = conp->vc_palette[j++];
-	palette_red[k] = (val<<8)|val;
-	val = conp->vc_palette[j++];
-	palette_green[k] = (val<<8)|val;
-	val = conp->vc_palette[j++];
-	palette_blue[k] = (val<<8)|val;
-    }
-    if (p->var.bits_per_pixel <= 4)
-	palette_cmap.len = 1<<p->var.bits_per_pixel;
-    else
-	palette_cmap.len = 16;
-    palette_cmap.start = 0;
-    return p->fb_info->fbops->fb_set_cmap(&palette_cmap, 1, unit, p->fb_info);
-}
-
-static u16 *fbcon_screen_pos(struct vc_data *conp, int offset)
-{
-    int line;
-    unsigned long p;
-
-    if (conp->vc_num != fg_console || !softback_lines)
-    	return (u16 *)(conp->vc_origin + offset);
-    line = offset / conp->vc_size_row;
-    if (line >= softback_lines)
-    	return (u16 *)(conp->vc_origin + offset - softback_lines * conp->vc_size_row);
-    p = softback_curr + offset;
-    if (p >= softback_end)
-    	p += softback_buf - softback_end;
-    return (u16 *)p;
-}
-
-static unsigned long fbcon_getxy(struct vc_data *conp, unsigned long pos, int *px, int *py)
-{
-    int x, y;
-    unsigned long ret;
-    if (pos >= conp->vc_origin && pos < conp->vc_scr_end) {
-    	unsigned long offset = (pos - conp->vc_origin) / 2;
-    	
-    	x = offset % conp->vc_cols;
-    	y = offset / conp->vc_cols;
-    	if (conp->vc_num == fg_console)
-    	    y += softback_lines;
-    	ret = pos + (conp->vc_cols - x) * 2;
-    } else if (conp->vc_num == fg_console && softback_lines) {
-    	unsigned long offset = pos - softback_curr;
-    	
-    	if (pos < softback_curr)
-    	    offset += softback_end - softback_buf;
-    	offset /= 2;
-    	x = offset % conp->vc_cols;
-    	y = offset / conp->vc_cols;
-	ret = pos + (conp->vc_cols - x) * 2;
-	if (ret == softback_end)
-	    ret = softback_buf;
-	if (ret == softback_in)
-	    ret = conp->vc_origin;
-    } else {
-    	/* Should not happen */
-    	x = y = 0;
-    	ret = conp->vc_origin;
-    }
-    if (px) *px = x;
-    if (py) *py = y;
-    return ret;
-}
-
-/* As we might be inside of softback, we may work with non-contiguous buffer,
-   that's why we have to use a separate routine. */
-static void fbcon_invert_region(struct vc_data *conp, u16 *p, int cnt)
-{
-    while (cnt--) {
-	u16 a = scr_readw(p);
-	if (!conp->vc_can_do_color)
-	    a ^= 0x0800;
-	else if (conp->vc_hi_font_mask == 0x100)
-	    a = ((a) & 0x11ff) | (((a) & 0xe000) >> 4) | (((a) & 0x0e00) << 4);
-	else
-	    a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4);
-	scr_writew(a, p++);
-	if (p == (u16 *)softback_end)
-	    p = (u16 *)softback_buf;
-	if (p == (u16 *)softback_in)
-	    p = (u16 *)conp->vc_origin;
-    }
-}
-
-static int fbcon_scrolldelta(struct vc_data *conp, int lines)
-{
-    int unit, offset, limit, scrollback_old;
-    struct display *p;
-    
-    unit = fg_console;
-    p = &fb_display[unit];
-    if (softback_top) {
-    	if (conp->vc_num != unit)
-    	    return 0;
-    	if (vt_cons[unit]->vc_mode != KD_TEXT || !lines)
-    	    return 0;
-    	if (logo_shown >= 0) {
-		struct vc_data *conp2 = vc_cons[logo_shown].d;
-    	
-		if (conp2->vc_top == logo_lines && conp2->vc_bottom == conp2->vc_rows)
-    		    conp2->vc_top = 0;
-    		if (logo_shown == unit) {
-    		    unsigned long p, q;
-    		    int i;
-    		    
-    		    p = softback_in;
-    		    q = conp->vc_origin + logo_lines * conp->vc_size_row;
-    		    for (i = 0; i < logo_lines; i++) {
-    		    	if (p == softback_top) break;
-    		    	if (p == softback_buf) p = softback_end;
-    		    	p -= conp->vc_size_row;
-    		    	q -= conp->vc_size_row;
-    		    	scr_memcpyw((u16 *)q, (u16 *)p, conp->vc_size_row);
-    		    }
-    		    softback_in = p;
-    		    update_region(unit, conp->vc_origin, logo_lines * conp->vc_cols);
-    		}
-		logo_shown = -1;
-	}
-    	fbcon_cursor(conp, CM_ERASE|CM_SOFTBACK);
-    	fbcon_redraw_softback(conp, p, lines);
-    	fbcon_cursor(conp, CM_DRAW|CM_SOFTBACK);
-    	return 0;
-    }
-
-    if (!scrollback_phys_max)
-	return -ENOSYS;
-
-    scrollback_old = scrollback_current;
-    scrollback_current -= lines;
-    if (scrollback_current < 0)
-	scrollback_current = 0;
-    else if (scrollback_current > scrollback_max)
-	scrollback_current = scrollback_max;
-    if (scrollback_current == scrollback_old)
-	return 0;
-
-    if (!p->can_soft_blank &&
-	(console_blanked || vt_cons[unit]->vc_mode != KD_TEXT || !lines))
-	return 0;
-    fbcon_cursor(conp, CM_ERASE);
-
-    offset = p->yscroll-scrollback_current;
-    limit = p->vrows;
-    switch (p->scrollmode && __SCROLL_YMASK) {
-	case __SCROLL_YWRAP:
-	    p->var.vmode |= FB_VMODE_YWRAP;
-	    break;
-	case __SCROLL_YPAN:
-	    limit -= conp->vc_rows;
-	    p->var.vmode &= ~FB_VMODE_YWRAP;
-	    break;
-    }
-    if (offset < 0)
-	offset += limit;
-    else if (offset >= limit)
-	offset -= limit;
-    p->var.xoffset = 0;
-    p->var.yoffset = offset*fontheight(p);
-    p->fb_info->updatevar(unit, p->fb_info);
-    if (!scrollback_current)
-	fbcon_cursor(conp, CM_DRAW);
-    return 0;
-}
-
-static int fbcon_set_origin(struct vc_data *conp)
-{
-    if (softback_lines && !console_blanked)
-        fbcon_scrolldelta(conp, softback_lines);
-    return 0;
-}
-
-static inline unsigned safe_shift(unsigned d,int n)
-{
-    return n<0 ? d>>-n : d<<n;
-}
-
-static int __init fbcon_show_logo( void )
-{
-    struct display *p = &fb_display[fg_console]; /* draw to vt in foreground */
-    struct fb_info *info = p->fb_info;
-    int depth = p->var.bits_per_pixel;
-    int line = p->next_line;
-    unsigned char *fb = info->screen_base;
-    unsigned char *logo;
-    unsigned char *dst, *src;
-    int i, j, n, x1, y1, x;
-    int logo_depth, done = 0;
-
-    /* Return if the frame buffer is not mapped */
-    if (!fb)
-	return 0;
-	
-    /*
-     * Set colors if visual is PSEUDOCOLOR and we have enough colors, or for
-     * DIRECTCOLOR
-     * We don't have to set the colors for the 16-color logo, since that logo
-     * uses the standard VGA text console palette
-     */
-    if ((info->fix.visual == FB_VISUAL_PSEUDOCOLOR && depth >= 8) ||
-	(info->fix.visual == FB_VISUAL_DIRECTCOLOR && depth >= 24))
-	for (i = 0; i < LINUX_LOGO_COLORS; i += n) {
-	    n = LINUX_LOGO_COLORS - i;
-	    if (n > 16)
-		/* palette_cmap provides space for only 16 colors at once */
-		n = 16;
-	    palette_cmap.start = 32 + i;
-	    palette_cmap.len   = n;
-	    for( j = 0; j < n; ++j ) {
-		palette_cmap.red[j]   = (linux_logo_red[i+j] << 8) |
-					linux_logo_red[i+j];
-		palette_cmap.green[j] = (linux_logo_green[i+j] << 8) |
-					linux_logo_green[i+j];
-		palette_cmap.blue[j]  = (linux_logo_blue[i+j] << 8) |
-					linux_logo_blue[i+j];
-	    }
-	    info->fbops->fb_set_cmap(&palette_cmap, 1, fg_console, info);
-	}
-	
-    if (depth >= 8) {
-	logo = linux_logo;
-	logo_depth = 8;
-    }
-    else if (depth >= 4) {
-	logo = linux_logo16;
-	logo_depth = 4;
-    }
-    else {
-	logo = linux_logo_bw;
-	logo_depth = 1;
-    }
-    
-    if (info->fbops->fb_rasterimg)
-    	info->fbops->fb_rasterimg(info, 1);
-
-    for (x = 0; x < num_online_cpus() * (LOGO_W + 8) &&
-    	 x < p->var.xres - (LOGO_W + 8); x += (LOGO_W + 8)) {
-    	 
-#if defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CFB24) || \
-    defined(CONFIG_FBCON_CFB32) || defined(CONFIG_FB_SBUS)
-        if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
-	    unsigned int val;		/* max. depth 32! */
-	    int bdepth;
-	    int redshift, greenshift, blueshift;
-		
-	    /* Bug: Doesn't obey msb_right ... (who needs that?) */
-	    redshift   = p->var.red.offset;
-	    greenshift = p->var.green.offset;
-	    blueshift  = p->var.blue.offset;
-
-	    if (depth >= 24 && (depth % 8) == 0) {
-		/* have at least 8 bits per color */
-		src = logo;
-		bdepth = depth/8;
-		for( y1 = 0; y1 < LOGO_H; y1++ ) {
-		    dst = fb + y1*line + x*bdepth;
-		    for( x1 = 0; x1 < LOGO_W; x1++, src++ ) {
-			val = (*src << redshift) |
-			      (*src << greenshift) |
-			      (*src << blueshift);
-			if (bdepth == 4 && !((long)dst & 3)) {
-			    /* Some cards require 32bit access */
-			    fb_writel (val, dst);
-			    dst += 4;
-			} else if (bdepth == 2 && !((long)dst & 1)) {
-			    /* others require 16bit access */
-			    fb_writew (val,dst);
-			    dst +=2;
-			} else {
-#ifdef __LITTLE_ENDIAN
-			    for( i = 0; i < bdepth; ++i )
-#else
-			    for( i = bdepth-1; i >= 0; --i )
-#endif
-			        fb_writeb (val >> (i*8), dst++);
-			}
-		    }
-		}
-	    }
-	    else if (depth >= 12 && depth <= 23) {
-	        /* have 4..7 bits per color, using 16 color image */
-		unsigned int pix;
-		src = linux_logo16;
-		bdepth = (depth+7)/8;
-		for( y1 = 0; y1 < LOGO_H; y1++ ) {
-		    dst = fb + y1*line + x*bdepth;
-		    for( x1 = 0; x1 < LOGO_W/2; x1++, src++ ) {
-			pix = *src >> 4; /* upper nibble */
-			val = (pix << redshift) |
-			      (pix << greenshift) |
-			      (pix << blueshift);
-#ifdef __LITTLE_ENDIAN
-			for( i = 0; i < bdepth; ++i )
-#else
-			for( i = bdepth-1; i >= 0; --i )
-#endif
-			    fb_writeb (val >> (i*8), dst++);
-			pix = *src & 0x0f; /* lower nibble */
-			val = (pix << redshift) |
-			      (pix << greenshift) |
-			      (pix << blueshift);
-#ifdef __LITTLE_ENDIAN
-			for( i = 0; i < bdepth; ++i )
-#else
-			for( i = bdepth-1; i >= 0; --i )
-#endif
-			    fb_writeb (val >> (i*8), dst++);
-		    }
-		}
-	    }
-	    done = 1;
-        }
-#endif
-#if defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CFB24) || \
-    defined(CONFIG_FBCON_CFB32) || defined(CONFIG_FB_SBUS)
-	if ((depth % 8 == 0) && (info->fix.visual == FB_VISUAL_TRUECOLOR)) {
-	    /* Modes without color mapping, needs special data transformation... */
-	    unsigned int val;		/* max. depth 32! */
-	    int bdepth = depth/8;
-	    unsigned char mask[9] = { 0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff };
-	    unsigned char redmask, greenmask, bluemask;
-	    int redshift, greenshift, blueshift;
-		
-	    /* Bug: Doesn't obey msb_right ... (who needs that?) */
-	    redmask   = mask[p->var.red.length   < 8 ? p->var.red.length   : 8];
-	    greenmask = mask[p->var.green.length < 8 ? p->var.green.length : 8];
-	    bluemask  = mask[p->var.blue.length  < 8 ? p->var.blue.length  : 8];
-	    redshift   = p->var.red.offset   - (8-p->var.red.length);
-	    greenshift = p->var.green.offset - (8-p->var.green.length);
-	    blueshift  = p->var.blue.offset  - (8-p->var.blue.length);
-
-	    src = logo;
-	    for( y1 = 0; y1 < LOGO_H; y1++ ) {
-		dst = fb + y1*line + x*bdepth;
-		for( x1 = 0; x1 < LOGO_W; x1++, src++ ) {
-		    val = safe_shift((linux_logo_red[*src-32]   & redmask), redshift) |
-		          safe_shift((linux_logo_green[*src-32] & greenmask), greenshift) |
-		          safe_shift((linux_logo_blue[*src-32]  & bluemask), blueshift);
-		    if (bdepth == 4 && !((long)dst & 3)) {
-			/* Some cards require 32bit access */
-			fb_writel (val, dst);
-			dst += 4;
-		    } else if (bdepth == 2 && !((long)dst & 1)) {
-			/* others require 16bit access */
-			fb_writew (val,dst);
-			dst +=2;
-		    } else {
-#ifdef __LITTLE_ENDIAN
-			for( i = 0; i < bdepth; ++i )
-#else
-			for( i = bdepth-1; i >= 0; --i )
-#endif
-			    fb_writeb (val >> (i*8), dst++);
-		    }
-		}
-	    }
-	    done = 1;
-	}
-#endif
-#if defined(CONFIG_FBCON_CFB4)
-	if (depth == 4 && info->fix.type == FB_TYPE_PACKED_PIXELS) {
-		src = logo;
-		for( y1 = 0; y1 < LOGO_H; y1++) {
-			dst = fb + y1*line + x/2;
-			for( x1 = 0; x1 < LOGO_W/2; x1++) {
-				u8 q = *src++;
-				q = (q << 4) | (q >> 4);
-				fb_writeb (q, dst++);
-			}
-		}
-		done = 1;
-	}
-#endif
-#if defined(CONFIG_FBCON_CFB8) || defined(CONFIG_FB_SBUS)
-	if (depth == 8 && info->fix.type == FB_TYPE_PACKED_PIXELS) {
-	    /* depth 8 or more, packed, with color registers */
-		
-	    src = logo;
-	    for( y1 = 0; y1 < LOGO_H; y1++ ) {
-		dst = fb + y1*line + x;
-		for( x1 = 0; x1 < LOGO_W; x1++ )
-		    fb_writeb (*src++, dst++);
-	    }
-	    done = 1;
-	}
-#endif
-#if defined(CONFIG_FBCON_AFB) || defined(CONFIG_FBCON_ILBM) || \
-    defined(CONFIG_FBCON_IPLAN2P2) || defined(CONFIG_FBCON_IPLAN2P4) || \
-    defined(CONFIG_FBCON_IPLAN2P8)
-	if (depth >= 2 && (info->fix.type == FB_TYPE_PLANES ||
-			   info->fix.type == FB_TYPE_INTERLEAVED_PLANES)) {
-	    /* planes (normal or interleaved), with color registers */
-	    int bit;
-	    unsigned char val, mask;
-	    int plane = p->next_plane;
-
-#if defined(CONFIG_FBCON_IPLAN2P2) || defined(CONFIG_FBCON_IPLAN2P4) || \
-    defined(CONFIG_FBCON_IPLAN2P8)
-	    int line_length = info->fix.line_length;
-
-	    /* for support of Atari interleaved planes */
-#define MAP_X(x)	(line_length ? (x) : ((x) & ~1)*depth + ((x) & 1))
-#else
-#define MAP_X(x)	(x)
-#endif
-	    /* extract a bit from the source image */
-#define	BIT(p,pix,bit)	(p[pix*logo_depth/8] & \
-			 (1 << ((8-((pix*logo_depth)&7)-logo_depth) + bit)))
-		
-	    src = logo;
-	    for( y1 = 0; y1 < LOGO_H; y1++ ) {
-		for( x1 = 0; x1 < LOGO_LINE; x1++, src += logo_depth ) {
-		    dst = fb + y1*line + MAP_X(x/8+x1);
-		    for( bit = 0; bit < logo_depth; bit++ ) {
-			val = 0;
-			for( mask = 0x80, i = 0; i < 8; mask >>= 1, i++ ) {
-			    if (BIT( src, i, bit ))
-				val |= mask;
-			}
-			*dst = val;
-			dst += plane;
-		    }
-		}
-	    }
-	
-	    /* fill remaining planes */
-	    if (depth > logo_depth) {
-		for( y1 = 0; y1 < LOGO_H; y1++ ) {
-		    for( x1 = 0; x1 < LOGO_LINE; x1++ ) {
-			dst = fb + y1*line + MAP_X(x/8+x1) + logo_depth*plane;
-			for( i = logo_depth; i < depth; i++, dst += plane )
-			    *dst = 0x00;
-		    }
-		}
-	    }
-	    done = 1;
-	    break;
-	}
-#endif
-#if defined(CONFIG_FBCON_MFB) || defined(CONFIG_FBCON_AFB) || \
-    defined(CONFIG_FBCON_ILBM) || defined(CONFIG_FBCON_HGA)
-
-	if (depth == 1 && (info->fix.type == FB_TYPE_PACKED_PIXELS ||
-			   info->fix.type == FB_TYPE_PLANES ||
-			   info->fix.type == FB_TYPE_INTERLEAVED_PLANES)) {
-
-	    /* monochrome */
-	    unsigned char inverse = p->inverse || info->fix.visual == FB_VISUAL_MONO01
-		? 0x00 : 0xff;
-
-	    int is_hga = !strncmp(p->fb_info->modename, "HGA", 3);
-	    /* can't use simply memcpy because need to apply inverse */
-	    for( y1 = 0; y1 < LOGO_H; y1++ ) {
-		src = logo + y1*LOGO_LINE;
-		if (is_hga)
-		    dst = fb + (y1%4)*8192 + (y1>>2)*line + x/8;
-		else
-		    dst = fb + y1*line + x/8;
-		for( x1 = 0; x1 < LOGO_LINE; ++x1 )
-		    fb_writeb(*src++ ^ inverse, dst++);
-	    }
-	    done = 1;
-	}
-#endif
-#if defined(CONFIG_FBCON_VGA_PLANES)
-	if (depth == 4 && info->fix.type == FB_TYPE_VGA_PLANES) {
-		outb_p(1,0x3ce); outb_p(0xf,0x3cf);
-		outb_p(3,0x3ce); outb_p(0,0x3cf);
-		outb_p(5,0x3ce); outb_p(0,0x3cf);
-
-		src = logo;
-		for (y1 = 0; y1 < LOGO_H; y1++) {
-			for (x1 = 0; x1 < LOGO_W / 2; x1++) {
-				dst = fb + y1*line + x1/4 + x/8;
-
-				outb_p(0,0x3ce);
-				outb_p(*src >> 4,0x3cf);
-				outb_p(8,0x3ce);
-				outb_p(1 << (7 - x1 % 4 * 2),0x3cf);
-				fb_readb (dst);
-				fb_writeb (0, dst);
-
-				outb_p(0,0x3ce);
-				outb_p(*src & 0xf,0x3cf);
-				outb_p(8,0x3ce);
-				outb_p(1 << (7 - (1 + x1 % 4 * 2)),0x3cf);
-				fb_readb (dst);
-				fb_writeb (0, dst);
-
-				src++;
-			}
-		}
-		done = 1;
-	}
-#endif			
-    }
-    
-    if (p->fb_info->fbops->fb_rasterimg)
-    	p->fb_info->fbops->fb_rasterimg(p->fb_info, 0);
-
-    /* Modes not yet supported: packed pixels with depth != 8 (does such a
-     * thing exist in reality?) */
-
-    return done ? (LOGO_H + fontheight(p) - 1) / fontheight(p) : 0 ;
-}
-
-/*
- *  The console `switch' structure for the frame buffer based console
- */
- 
-const struct consw fb_con = {
-    .con_startup = 	fbcon_startup, 
-    .con_init = 	fbcon_init,
-    .con_deinit = 	fbcon_deinit,
-    .con_clear = 	fbcon_clear,
-    .con_putc = 	fbcon_putc,
-    .con_putcs = 	fbcon_putcs,
-    .con_cursor = 	fbcon_cursor,
-    .con_scroll = 	fbcon_scroll,
-    .con_bmove = 	fbcon_bmove,
-    .con_switch = 	fbcon_switch,
-    .con_blank = 	fbcon_blank,
-    .con_font_op =	fbcon_font_op,
-    .con_set_palette = 	fbcon_set_palette,
-    .con_scrolldelta = 	fbcon_scrolldelta,
-    .con_set_origin = 	fbcon_set_origin,
-    .con_invert_region = fbcon_invert_region,
-    .con_screen_pos =	fbcon_screen_pos,
-    .con_getxy =	fbcon_getxy,
-};
-
-
-/*
- *  Dummy Low Level Operations
- */
-
-static void fbcon_dummy_op(void) {}
-
-#define DUMMY	(void *)fbcon_dummy_op
-
-struct display_switch fbcon_dummy = {
-    .setup =	DUMMY,
-    .bmove =	DUMMY,
-    .clear =	DUMMY,
-    .putc =	DUMMY,
-    .putcs =	DUMMY,
-    .revc =	DUMMY,
-};
-
-
-/*
- *  Visible symbols for modules
- */
-
-EXPORT_SYMBOL(fb_display);
-EXPORT_SYMBOL(fbcon_redraw_bmove);
-EXPORT_SYMBOL(fbcon_redraw_clear);
-EXPORT_SYMBOL(fbcon_dummy);
-EXPORT_SYMBOL(fb_con);
-
-MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/fbgen.c b/drivers/video/fbgen.c
--- a/drivers/video/fbgen.c	Mon Dec  9 18:46:37 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,286 +0,0 @@
-/*
- * linux/drivers/video/fbgen.c -- Generic routines for frame buffer devices
- *
- *  Created 3 Jan 1998 by Geert Uytterhoeven
- *
- *	2001 - Documented with DocBook
- *	- Brad Douglas <brad@neruo.com>
- *
- * 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/string.h>
-#include <linux/tty.h>
-#include <linux/fb.h>
-#include <linux/slab.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.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>
-#include "fbcon-accel.h"
-
-int gen_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
-{
-	int err;
-
-	if (con < 0 || (memcmp(&info->var, var, sizeof(struct fb_var_screeninfo)))) {
-		if (!info->fbops->fb_check_var) {
-			*var = info->var;
-			return 0;
-		}
-		
-		if ((err = info->fbops->fb_check_var(var, info)))
-			return err;
-
-		if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
-			info->var = *var;
-			
-			if (con == info->currcon) {
-				if (info->fbops->fb_set_par)
-					info->fbops->fb_set_par(info);
-
-				if (info->fbops->fb_pan_display)
-					info->fbops->fb_pan_display(&info->var, con, info);
-
-				gen_set_disp(con, info);
-				fb_set_cmap(&info->cmap, 1, info);
-			}
-		
-			if (info->changevar)
-				info->changevar(con);
-		}
-	}
-	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;
-}
-
-int gen_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-		 struct fb_info *info)
-{
-	struct display *disp = (con < 0) ? info->disp : (fb_display + con);
-	struct fb_cmap *dcmap = &disp->cmap;
-	int err = 0;
-
-	/* No colormap allocated ? */
-	if (!dcmap->len) {
-		int size = info->cmap.len;
-
-		err = fb_alloc_cmap(dcmap, size, 0);
-	}
- 	
-
-	if (!err && con == info->currcon) {
-		err = fb_set_cmap(cmap, kspc, info);
-		dcmap = &info->cmap;
-	}
-	
-	if (!err)
-		fb_copy_cmap(cmap, dcmap, kspc ? 0 : 1);
-	return err;
-}
-
-int fbgen_pan_display(struct fb_var_screeninfo *var, int con,
-		      struct fb_info *info)
-{
-    int xoffset = var->xoffset;
-    int yoffset = var->yoffset;
-    int err;
-
-    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 (info->fbops->fb_pan_display) {
-	    if ((err = info->fbops->fb_pan_display(var, con, info)))
-		return err;
-	} else
-	    return -EINVAL;
-    }
-    info->var.xoffset = var->xoffset;
-    info->var.yoffset = var->yoffset;
-    if (var->vmode & FB_VMODE_YWRAP)
-	info->var.vmode |= FB_VMODE_YWRAP;
-    else
-	info->var.vmode &= ~FB_VMODE_YWRAP;
-    return 0;
-}
-
-
-/* ---- Helper functions --------------------------------------------------- */
-
-void gen_set_disp(int con, struct fb_info *info)
-{
-	struct display *display = (con < 0) ? info->disp : (fb_display + con);
-
-	if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR ||
-	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
-		display->can_soft_blank = info->fbops->fb_blank ? 1 : 0;
-		display->dispsw_data = NULL;
-	} else {
-		display->can_soft_blank = 0;
-		display->dispsw_data = info->pseudo_palette;
-	}
-	display->var = info->var;
-
-	/*
-	 * If we are setting all the virtual consoles, also set
-	 * the defaults used to create new consoles.
-	 */
-	if (con < 0 || info->var.activate & FB_ACTIVATE_ALL)
-		info->disp->var = info->var;	
-
-	if (info->var.bits_per_pixel == 24) {
-#ifdef FBCON_HAS_CFB24
-		display->scrollmode = SCROLL_YREDRAW;		
-		display->dispsw = &fbcon_cfb24;
-		return;
-#endif
-	}
-
-#ifdef FBCON_HAS_ACCEL
-	display->scrollmode = SCROLL_YNOMOVE;
-	display->dispsw = &fbcon_accel;
-#else
-	display->dispsw = &fbcon_dummy;
-#endif
-	return;
-}
-
-/**
- *	do_install_cmap - install the current colormap
- *	@con: virtual console number
- *	@info: generic frame buffer info structure
- *
- *	Installs the current colormap for virtual console @con on
- *	device @info.
- *
- */
-
-void do_install_cmap(int con, struct fb_info *info)
-{
-    if (con != info->currcon)
-	return;
-    if (fb_display[con].cmap.len)
-	fb_set_cmap(&fb_display[con].cmap, 1, info);
-    else {
-	int size = fb_display[con].var.bits_per_pixel == 16 ? 64 : 256;
-	fb_set_cmap(fb_default_cmap(size), 1, info);
-    }
-}
-
-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;
-		}
-	}	
-	return 0;
-}
-
-int gen_switch(int con, struct fb_info *info)
-{
-	struct display *disp;
-	struct fb_cmap *cmap;
-	
-	if (info->currcon >= 0) {
-		disp = fb_display + info->currcon;
-	
-		/*
-		 * Save the old colormap and graphics mode.
-		 */
-		disp->var = info->var;
-		if (disp->cmap.len)
-			fb_copy_cmap(&info->cmap, &disp->cmap, 0);
-	}
-	
-	info->currcon = con;
-	disp = fb_display + con;
-	
-	/*
-	 * Install the new colormap and change the graphics mode. By default
-	 * fbcon sets all the colormaps and graphics modes to the default
-	 * values at bootup.
-	 *
-	 * Really, we want to set the colormap size depending on the
-	 * depth of the new grpahics mode. For now, we leave it as its
-	 * default 256 entry.
-	 */
-	if (disp->cmap.len)
-		cmap = &disp->cmap;
-	else
-		cmap = fb_default_cmap(1 << disp->var.bits_per_pixel);
-	
-	fb_copy_cmap(cmap, &info->cmap, 0);
-	
-	disp->var.activate = FB_ACTIVATE_NOW;
-	info->fbops->fb_set_var(&disp->var, con, info);
- 	return 0;	  	
-}
-
-/**
- *	fbgen_blank - blank the screen
- *	@blank: boolean, 0 unblank, 1 blank
- *	@info: frame buffer info structure
- *
- *	Blank the screen on device @info.
- *
- */
-
-int fbgen_blank(int blank, struct fb_info *info)
-{
-    struct fb_cmap cmap;
-    u16 black[16];
-    
-    if (info->fbops->fb_blank && !info->fbops->fb_blank(blank, info))
-	return 0;
-    if (blank) {
-	memset(black, 0, 16*sizeof(u16));
-	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;	
-}
-
-/* generic frame buffer operations */
-EXPORT_SYMBOL(gen_set_var);
-EXPORT_SYMBOL(gen_get_cmap);
-EXPORT_SYMBOL(gen_set_cmap);
-EXPORT_SYMBOL(fbgen_pan_display);
-/* helper functions */
-EXPORT_SYMBOL(do_install_cmap);
-EXPORT_SYMBOL(gen_update_var);
-EXPORT_SYMBOL(gen_switch);
-EXPORT_SYMBOL(fbgen_blank);
-
-MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/fbmem.c b/drivers/video/fbmem.c
--- a/drivers/video/fbmem.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/video/fbmem.c	Mon Dec  9 18:46:34 2002
@@ -24,7 +24,6 @@
 #include <linux/mm.h>
 #include <linux/mman.h>
 #include <linux/tty.h>
-#include <linux/console.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
 #ifdef CONFIG_KMOD
@@ -42,8 +41,9 @@
 #include <asm/pgtable.h>
 
 #include <linux/fb.h>
-#include <video/fbcon.h>
-
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE
+#include "console/fbcon.h"
+#endif
     /*
      *  Frame buffer device initialization and setup routines
      */
@@ -130,9 +130,9 @@
 extern int stifb_setup(char*);
 extern int pmagbafb_init(void);
 extern int pmagbbfb_init(void);
-extern void maxinefb_init(void);
+extern int maxinefb_init(void);
 extern int tx3912fb_init(void);
-extern void tx3912fb_setup(char*);
+extern int tx3912fb_setup(char*);
 extern int radeonfb_init(void);
 extern int radeonfb_setup(char*);
 extern int e1355fb_init(void);
@@ -356,11 +356,6 @@
 
 struct fb_info *registered_fb[FB_MAX];
 int num_registered_fb;
-extern int fbcon_softback_size; 
-
-static int first_fb_vc;
-static int last_fb_vc = MAX_NR_CONSOLES-1;
-static int fbcon_is_default = 1;
 
 #ifdef CONFIG_FB_OF
 static int ofonly __initdata = 0;
@@ -376,8 +371,8 @@
 	for (fi = registered_fb; fi < &registered_fb[FB_MAX] && len < 4000; fi++)
 		if (*fi)
 			clen += sprintf(buf + clen, "%d %s\n",
-				        GET_FB_IDX((*fi)->node),
-				        (*fi)->modename);
+				        minor((*fi)->node),
+				        (*fi)->fix.id);
 	*start = buf + offset;
 	if (clen > offset)
 		clen -= offset;
@@ -391,12 +386,15 @@
 {
 	unsigned long p = *ppos;
 	struct inode *inode = file->f_dentry->d_inode;
-	int fbidx = GET_FB_IDX(inode->i_rdev);
+	int fbidx = minor(inode->i_rdev);
 	struct fb_info *info = registered_fb[fbidx];
 
 	if (!info || ! info->screen_base)
 		return -ENODEV;
 
+	if (info->fbops->fb_read)
+		return info->fbops->fb_read(file, buf, count, ppos);
+	
 	if (p >= info->fix.smem_len)
 	    return 0;
 	if (count >= info->fix.smem_len)
@@ -420,13 +418,16 @@
 {
 	unsigned long p = *ppos;
 	struct inode *inode = file->f_dentry->d_inode;
-	int fbidx = GET_FB_IDX(inode->i_rdev);
+	int fbidx = minor(inode->i_rdev);
 	struct fb_info *info = registered_fb[fbidx];
 	int err;
 
 	if (!info || !info->screen_base)
 		return -ENODEV;
 
+	if (info->fbops->fb_write)
+		return info->fbops->fb_write(file, buf, count, ppos);
+	
 	if (p > info->fix.smem_len)
 	    return -ENOSPC;
 	if (count >= info->fix.smem_len)
@@ -459,17 +460,91 @@
 }
 #endif /* CONFIG_KMOD */
 
+int fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+        int xoffset = var->xoffset;
+        int yoffset = var->yoffset;
+        int err;
+
+        if (xoffset < 0 || yoffset < 0 ||
+            xoffset + info->var.xres > info->var.xres_virtual ||
+            yoffset + info->var.yres > info->var.yres_virtual)
+                return -EINVAL;
+        if (info->fbops->fb_pan_display) {
+                if ((err = info->fbops->fb_pan_display(var, info)))
+                        return err;
+                else
+                        return -EINVAL;
+        }
+        info->var.xoffset = var->xoffset;
+        info->var.yoffset = var->yoffset;
+        if (var->vmode & FB_VMODE_YWRAP)
+                info->var.vmode |= FB_VMODE_YWRAP;
+        else
+                info->var.vmode &= ~FB_VMODE_YWRAP;
+        return 0;
+}
+
+int fb_set_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	int err;
+
+	if (memcmp(&info->var, var, sizeof(struct fb_var_screeninfo))) {
+		if (!info->fbops->fb_check_var) {
+			*var = info->var;
+			return 0;
+		}
+
+		if ((err = info->fbops->fb_check_var(var, info)))
+			return err;
+
+		if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+			info->var = *var;
+
+			if (info->fbops->fb_set_par)
+				info->fbops->fb_set_par(info);
+
+			fb_pan_display(&info->var, info);
+
+			fb_set_cmap(&info->cmap, 1, info);
+		}
+	}
+	return 0;
+}
+
+int
+fb_blank(int blank, struct fb_info *info)
+{	
+	u16 black[info->cmap.len];
+	struct fb_cmap cmap;
+	
+	if (info->fbops->fb_blank && !info->fbops->fb_blank(blank, info))
+		return 0;
+	if (blank) { 
+		memset(black, 0, info->cmap.len * sizeof(u16));
+		cmap.red = cmap.green = cmap.blue = black;
+		if (info->cmap.transp)
+			cmap.transp = black;
+		cmap.start = info->cmap.start;
+		cmap.len = info->cmap.len;
+	} else
+		cmap = info->cmap;
+	return fb_set_cmap(&cmap, 1, info);
+}
+
 static int 
 fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 	 unsigned long arg)
 {
-	int fbidx = GET_FB_IDX(inode->i_rdev);
+	int fbidx = minor(inode->i_rdev);
 	struct fb_info *info = registered_fb[fbidx];
 	struct fb_ops *fb = info->fbops;
-	struct fb_cmap cmap;
 	struct fb_var_screeninfo var;
 	struct fb_fix_screeninfo fix;
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE
 	struct fb_con2fbmap con2fb;
+#endif
+	struct fb_cmap cmap;
 	int i;
 	
 	if (! fb)
@@ -481,11 +556,8 @@
 	case FBIOPUT_VSCREENINFO:
 		if (copy_from_user(&var, (void *) arg, sizeof(var)))
 			return -EFAULT;
-		i = var.activate & FB_ACTIVATE_ALL
-			    ? set_all_vcs(fbidx, fb, &var, info)
-			    : fb->fb_set_var(&var, PROC_CONSOLE(info), info);
-		if (i)
-			return i;
+		i = fb_set_var(&var, info);
+		if (i) return i;
 		if (copy_to_user((void *) arg, &var, sizeof(var)))
 			return -EFAULT;
 		return 0;
@@ -494,21 +566,20 @@
 	case FBIOPUTCMAP:
 		if (copy_from_user(&cmap, (void *) arg, sizeof(cmap)))
 			return -EFAULT;
-		return (fb->fb_set_cmap(&cmap, 0, PROC_CONSOLE(info), info));
+		return (fb_set_cmap(&cmap, 0, info));
 	case FBIOGETCMAP:
 		if (copy_from_user(&cmap, (void *) arg, sizeof(cmap)))
 			return -EFAULT;
-		return (fb->fb_get_cmap(&cmap, 0, PROC_CONSOLE(info), info));
+		fb_copy_cmap(&info->cmap, &cmap, 0);
 	case FBIOPAN_DISPLAY:
 		if (copy_from_user(&var, (void *) arg, sizeof(var)))
 			return -EFAULT;
-		if (fb->fb_pan_display == NULL)
-			return (var.xoffset || var.yoffset) ? -EINVAL : 0;
-		if ((i=fb->fb_pan_display(&var, PROC_CONSOLE(info), info)))
+		if ((i = fb_pan_display(&var, info)))
 			return i;
 		if (copy_to_user((void *) arg, &var, sizeof(var)))
 			return -EFAULT;
 		return i;
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE
 	case FBIOGET_CON2FBMAP:
 		if (copy_from_user(&con2fb, (void *)arg, sizeof(con2fb)))
 			return -EFAULT;
@@ -537,22 +608,20 @@
 		    for (i = 0; i < MAX_NR_CONSOLES; i++)
 			set_con2fb_map(i, con2fb.framebuffer);
 		return 0;
+#endif	/* CONFIG_FRAMEBUFFER_CONSOLE */
 	case FBIOBLANK:
-		if (fb->fb_blank == NULL)
-			return -EINVAL;
-		return fb->fb_blank(arg, info);
+		return fb_blank(arg, info);
 	default:
 		if (fb->fb_ioctl == NULL)
 			return -EINVAL;
-		return fb->fb_ioctl(inode, file, cmd, arg, PROC_CONSOLE(info),
-				    info);
+		return fb->fb_ioctl(inode, file, cmd, arg, info);
 	}
 }
 
 static int 
 fb_mmap(struct file *file, struct vm_area_struct * vma)
 {
-	int fbidx = GET_FB_IDX(file->f_dentry->d_inode->i_rdev);
+	int fbidx = minor(file->f_dentry->d_inode->i_rdev);
 	struct fb_info *info = registered_fb[fbidx];
 	struct fb_ops *fb = info->fbops;
 	unsigned long off;
@@ -648,28 +717,10 @@
 #endif /* !sparc32 */
 }
 
-#if 1 /* to go away in 2.5.0 */
-int GET_FB_IDX(kdev_t rdev)
-{
-    int fbidx = minor(rdev);
-    if (fbidx >= 32) {
-	int newfbidx = fbidx >> 5;
-	static int warned;
-	if (!(warned & (1<<newfbidx))) {
-	    warned |= 1<<newfbidx;
-	    printk("Warning: Remapping obsolete /dev/fb* minor %d to %d\n",
-		   fbidx, newfbidx);
-	}
-	fbidx = newfbidx;
-    }
-    return fbidx;
-}
-#endif
-
 static int
 fb_open(struct inode *inode, struct file *file)
 {
-	int fbidx = GET_FB_IDX(inode->i_rdev);
+	int fbidx = minor(inode->i_rdev);
 	struct fb_info *info;
 	int res = 0;
 
@@ -679,12 +730,12 @@
 #endif /* CONFIG_KMOD */
 	if (!(info = registered_fb[fbidx]))
 		return -ENODEV;
-	if (info->fbops->owner)
-		__MOD_INC_USE_COUNT(info->fbops->owner);
+	if (!try_module_get(info->fbops->owner))
+		return -ENODEV;
 	if (info->fbops->fb_open) {
 		res = info->fbops->fb_open(info,1);
-		if (res && info->fbops->owner)
-			__MOD_DEC_USE_COUNT(info->fbops->owner);
+		if (res)
+			module_put(info->fbops->owner);
 	}
 	return res;
 }
@@ -692,15 +743,14 @@
 static int 
 fb_release(struct inode *inode, struct file *file)
 {
-	int fbidx = GET_FB_IDX(inode->i_rdev);
+	int fbidx = minor(inode->i_rdev);
 	struct fb_info *info;
 
 	lock_kernel();
 	info = registered_fb[fbidx];
 	if (info->fbops->fb_release)
 		info->fbops->fb_release(info,1);
-	if (info->fbops->owner)
-		__MOD_DEC_USE_COUNT(info->fbops->owner);
+	module_put(info->fbops->owner);
 	unlock_kernel();
 	return 0;
 }
@@ -718,9 +768,6 @@
 #endif
 };
 
-static devfs_handle_t devfs_handle;
-
-
 /**
  *	register_framebuffer - registers a frame buffer device
  *	@fb_info: frame buffer info structure
@@ -734,10 +781,8 @@
 int
 register_framebuffer(struct fb_info *fb_info)
 {
-	int i, j;
-	char name_buf[8];
-	static int fb_ever_opened[FB_MAX];
-	static int first = 1;
+	char name_buf[12];
+	int i;
 
 	if (num_registered_fb == FB_MAX)
 		return -ENXIO;
@@ -747,36 +792,10 @@
 			break;
 	fb_info->node = mk_kdev(FB_MAJOR, i);
 	registered_fb[i] = fb_info;
-	if (!fb_ever_opened[i]) {
-		struct module *owner = fb_info->fbops->owner;
-		/*
-		 *  We assume initial frame buffer devices can be opened this
-		 *  many times
-		 */
-		for (j = 0; j < MAX_NR_CONSOLES; j++)
-			if (con2fb_map[j] == i) {
-				if (owner)
-					__MOD_INC_USE_COUNT(owner);
-				if (!fb_info->fbops->fb_open)
-					continue;
-				if (!fb_info->fbops->fb_open(fb_info,0))
-					continue;
-				if (owner)
-					__MOD_DEC_USE_COUNT(owner);
-			}
-		fb_ever_opened[i] = 1;
-	}
-
-	if (first) {
-		first = 0;
-		take_over_console(&fb_con, first_fb_vc, last_fb_vc, fbcon_is_default);
-	}
-	sprintf (name_buf, "%d", i);
-	fb_info->devfs_handle =
-	    devfs_register (devfs_handle, name_buf, DEVFS_FL_DEFAULT,
-			    FB_MAJOR, i, S_IFCHR | S_IRUGO | S_IWUGO,
-			    &fb_fops, NULL);
-
+	sprintf(name_buf, "fb/%d", i);
+	devfs_register(NULL, name_buf, DEVFS_FL_DEFAULT,
+			FB_MAJOR, i, S_IFCHR | S_IRUGO | S_IWUGO,
+			&fb_fops, NULL);
 	return 0;
 }
 
@@ -794,18 +813,12 @@
 int
 unregister_framebuffer(struct fb_info *fb_info)
 {
-	int i, j;
+	int i;
 
-	i = GET_FB_IDX(fb_info->node);
-	for (j = 0; j < MAX_NR_CONSOLES; j++)
-		if (con2fb_map[j] == i)
-			return -EBUSY;
+	i = minor(fb_info->node);
 	if (!registered_fb[i])
 		return -EINVAL;
-	devfs_unregister (fb_info->devfs_handle);
-	fb_info->devfs_handle = NULL;
-	devfs_unregister (fb_info->devfs_lhandle);
-	fb_info->devfs_lhandle = NULL;
+	devfs_remove("fb/%d", i);
 	registered_fb[i]=NULL;
 	num_registered_fb--;
 	return 0;
@@ -828,7 +841,7 @@
 
 	create_proc_read_entry("fb", 0, 0, fbmem_read_proc, NULL);
 
-	devfs_handle = devfs_mk_dir (NULL, "fb", NULL);
+	devfs_mk_dir(NULL, "fb", NULL);
 	if (register_chrdev(FB_MAJOR,"fb",&fb_fops))
 		printk("unable to get major %d for fb devs\n", FB_MAJOR);
 
@@ -869,44 +882,7 @@
 
     if (!options || !*options)
 	    return 0;
-	    
-    if (!strncmp(options, "scrollback:", 11)) {
-	    options += 11;
-	    if (*options) {
-		fbcon_softback_size = simple_strtoul(options, &options, 0);
-		if (*options == 'k' || *options == 'K') {
-			fbcon_softback_size *= 1024;
-			options++;
-		}
-		if (*options != ',')
-			return 0;
-		options++;
-	    } else
-	        return 0;
-    }
-
-    if (!strncmp(options, "map:", 4)) {
-	    options += 4;
-	    if (*options)
-		    for (i = 0, j = 0; i < MAX_NR_CONSOLES; i++) {
-			    if (!options[j])
-				    j = 0;
-			    con2fb_map[i] = (options[j++]-'0') % FB_MAX;
-		    }
-	    return 0;
-    }
-    
-    if (!strncmp(options, "vc:", 3)) {
-	    options += 3;
-	    if (*options)
-		first_fb_vc = simple_strtoul(options, &options, 10) - 1;
-	    if (first_fb_vc < 0)
-		first_fb_vc = 0;
-	    if (*options++ == '-')
-		last_fb_vc = simple_strtoul(options, &options, 10) - 1;
-	    fbcon_is_default = 0;
-    }
-
+	   
 #ifdef CONFIG_FB_OF
     if (!strcmp(options, "ofonly")) {
 	    ofonly = 1;
@@ -954,8 +930,5 @@
 EXPORT_SYMBOL(unregister_framebuffer);
 EXPORT_SYMBOL(registered_fb);
 EXPORT_SYMBOL(num_registered_fb);
-#if 1 /* to go away in 2.5.0 */
-EXPORT_SYMBOL(GET_FB_IDX);
-#endif
 
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/fm2fb.c b/drivers/video/fm2fb.c
--- a/drivers/video/fm2fb.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/video/fm2fb.c	Mon Dec  9 18:46:36 2002
@@ -21,8 +21,6 @@
 #include <linux/zorro.h>
 #include <asm/io.h>
 
-#include <video/fbcon.h>
-
 /*
  *	Some technical notes:
  *
@@ -133,7 +131,6 @@
 
 static struct fb_info fb_info;
 static u32 pseudo_palette[17];
-static struct display display;
 
 static struct fb_fix_screeninfo fb_fix __initdata = {
 	.smem_len =	FRAMEMASTER_REG,
@@ -176,14 +173,12 @@
 
 static struct fb_ops fm2fb_ops = {
 	.owner		= THIS_MODULE,
-	.fb_set_var	= gen_set_var,
-	.fb_get_cmap	= gen_get_cmap,
-	.fb_set_cmap	= gen_set_cmap,
 	.fb_setcolreg	= fm2fb_setcolreg,
 	.fb_blank	= fm2fb_blank,	
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
+	.fb_cursor	= soft_cursor,
 };
 
     /*
@@ -264,7 +259,6 @@
 		if (fm2fb_mode == -1)
 			fm2fb_mode = FM2FB_MODE_PAL;
 
-		strcpy(fb_info.modename, fb_fix.id);
 		fb_info.node = NODEV;
 		fb_info.fbops = &fm2fb_ops;
 		fb_info.var = fb_var_modes[fm2fb_mode];
@@ -274,19 +268,12 @@
 		fb_info.flags = FBINFO_FLAG_DEFAULT;
 
 		/* The below feilds will go away !!!! */
-		fb_info.currcon		= -1;
-		strcpy(fb_info.modename, fb_info.fix.id);
-		fb_info.disp		= &display;
-		fb_info.switch_con	= gen_switch;
-		fb_info.updatevar	= gen_update_var;
 		fb_alloc_cmap(&fb_info.cmap, 16, 0);
 
-		gen_set_disp(-1, &fb_info);
-
 		if (register_framebuffer(&fb_info) < 0)
 			return -EINVAL;
 
-		printk("fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.node), fb_fix.id);
+		printk("fb%d: %s frame buffer device\n", minor(fb_info.node), fb_fix.id);
 		return 0;
 	}
 	return -ENXIO;
diff -Nru a/drivers/video/font_6x11.c b/drivers/video/font_6x11.c
--- a/drivers/video/font_6x11.c	Mon Dec  9 18:46:34 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,3351 +0,0 @@
-/**********************************************/
-/*                                            */
-/*       Font file generated by rthelen       */
-/*                                            */
-/**********************************************/
-
-#include <video/font.h>
-
-#define FONTDATAMAX (11*256)
-
-static unsigned char fontdata_6x11[FONTDATAMAX] = {
-
-	/* 0 0x00 '^A' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 1 0x01 '^B' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 2 0x02 '^C' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 3 0x03 '^D' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 4 0x04 '^E' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 5 0x05 '^F' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 6 0x06 '^G' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 7 0x07 '^H' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 8 0x08 '^I' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 9 0x09 '^J' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 10 0x0a '^K' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 11 0x0b '^L' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 12 0x0c '^M' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 13 0x0d '^N' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 14 0x0e '^O' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 15 0x0f '^P' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 16 0x10 '^Q' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 17 0x11 '^R' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x28, /* 00 0 000 */
-	0x54, /* 0 0 0 00 */
-	0x38, /* 00   000 */
-	0x54, /* 0 0 0 00 */
-	0x28, /* 00 0 000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 18 0x12 '^S' */
-	0x04, /* 00000 00 */
-	0x04, /* 00000 00 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x50, /* 0 0 0000 */
-	0x50, /* 0 0 0000 */
-	0x20, /* 00 00000 */
-	0x20, /* 00 00000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 19 0x13 '^T' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x38, /* 00   000 */
-	0x7c, /* 0     00 */
-	0x38, /* 00   000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 20 0x14 '^U' */
-	0x18, /* 000  000 */
-	0x10, /* 000 0000 */
-	0x28, /* 00 0 000 */
-	0x7c, /* 0     00 */
-	0x78, /* 0    000 */
-	0x78, /* 0    000 */
-	0x7c, /* 0     00 */
-	0x28, /* 00 0 000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 21 0x15 '^V' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 22 0x16 '^W' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 23 0x17 '^X' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 24 0x18 '^Y' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 25 0x19 '^Z' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 26 0x1a '^[' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 27 0x1b '^\' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 28 0x1c '^]' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 29 0x1d '^^' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 30 0x1e '^_' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 31 0x1f '^`' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 32 0x20 ' ' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 33 0x21 '!' */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 34 0x22 '"' */
-	0x28, /* 00 0 000 */
-	0x28, /* 00 0 000 */
-	0x28, /* 00 0 000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 35 0x23 '#' */
-	0x00, /* 00000000 */
-	0x28, /* 00 0 000 */
-	0x7c, /* 0     00 */
-	0x28, /* 00 0 000 */
-	0x7c, /* 0     00 */
-	0x28, /* 00 0 000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 36 0x24 '$' */
-	0x10, /* 000 0000 */
-	0x38, /* 00   000 */
-	0x54, /* 0 0 0 00 */
-	0x50, /* 0 0 0000 */
-	0x38, /* 00   000 */
-	0x14, /* 000 0 00 */
-	0x54, /* 0 0 0 00 */
-	0x38, /* 00   000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 37 0x25 '%' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x54, /* 0 0 0 00 */
-	0x58, /* 0 0  000 */
-	0x28, /* 00 0 000 */
-	0x34, /* 00  0 00 */
-	0x54, /* 0 0 0 00 */
-	0x48, /* 0 00 000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 38 0x26 '&' */
-	0x00, /* 00000000 */
-	0x30, /* 00  0000 */
-	0x48, /* 0 00 000 */
-	0x50, /* 0 0 0000 */
-	0x20, /* 00 00000 */
-	0x54, /* 0 0 0 00 */
-	0x48, /* 0 00 000 */
-	0x34, /* 00  0 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 39 0x27 ''' */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 40 0x28 '(' */
-	0x04, /* 00000 00 */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x08, /* 0000 000 */
-	0x04, /* 00000 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 41 0x29 ')' */
-	0x20, /* 00 00000 */
-	0x10, /* 000 0000 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x20, /* 00 00000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 42 0x2a '*' */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x54, /* 0 0 0 00 */
-	0x38, /* 00   000 */
-	0x54, /* 0 0 0 00 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 43 0x2b '+' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x7c, /* 0     00 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 44 0x2c ',' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x30, /* 00  0000 */
-	0x30, /* 00  0000 */
-	0x10, /* 000 0000 */
-	0x20, /* 00 00000 */
-	0x00, /* 00000000 */
-
-	/* 45 0x2d '-' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 0     00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 46 0x2e '.' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 000  000 */
-	0x18, /* 000  000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 47 0x2f '/' */
-	0x04, /* 00000 00 */
-	0x04, /* 00000 00 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x20, /* 00 00000 */
-	0x20, /* 00 00000 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x00, /* 00000000 */
-
-	/* 48 0x30 '0' */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x4c, /* 0 00  00 */
-	0x54, /* 0 0 0 00 */
-	0x64, /* 0  00 00 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 49 0x31 '1' */
-	0x00, /* 00000000 */
-	0x08, /* 0000 000 */
-	0x18, /* 000  000 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x1c, /* 000   00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 50 0x32 '2' */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x04, /* 00000 00 */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x20, /* 00 00000 */
-	0x7c, /* 0     00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 51 0x33 '3' */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x04, /* 00000 00 */
-	0x18, /* 000  000 */
-	0x04, /* 00000 00 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 52 0x34 '4' */
-	0x00, /* 00000000 */
-	0x08, /* 0000 000 */
-	0x18, /* 000  000 */
-	0x28, /* 00 0 000 */
-	0x48, /* 0 00 000 */
-	0x7c, /* 0     00 */
-	0x08, /* 0000 000 */
-	0x1c, /* 000   00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 53 0x35 '5' */
-	0x00, /* 00000000 */
-	0x7c, /* 0     00 */
-	0x40, /* 0 000000 */
-	0x78, /* 0    000 */
-	0x04, /* 00000 00 */
-	0x04, /* 00000 00 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 54 0x36 '6' */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x40, /* 0 000000 */
-	0x78, /* 0    000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 55 0x37 '7' */
-	0x00, /* 00000000 */
-	0x7c, /* 0     00 */
-	0x04, /* 00000 00 */
-	0x04, /* 00000 00 */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 56 0x38 '8' */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 57 0x39 '9' */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x3c, /* 00    00 */
-	0x04, /* 00000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 58 0x3a ':' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 000  000 */
-	0x18, /* 000  000 */
-	0x00, /* 00000000 */
-	0x18, /* 000  000 */
-	0x18, /* 000  000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 59 0x3b ';' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x30, /* 00  0000 */
-	0x30, /* 00  0000 */
-	0x00, /* 00000000 */
-	0x30, /* 00  0000 */
-	0x30, /* 00  0000 */
-	0x10, /* 000 0000 */
-	0x20, /* 00 00000 */
-	0x00, /* 00000000 */
-
-	/* 60 0x3c '<' */
-	0x00, /* 00000000 */
-	0x04, /* 00000 00 */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x20, /* 00 00000 */
-	0x10, /* 000 0000 */
-	0x08, /* 0000 000 */
-	0x04, /* 00000 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 61 0x3d '=' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 0     00 */
-	0x00, /* 00000000 */
-	0x7c, /* 0     00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 62 0x3e '>' */
-	0x00, /* 00000000 */
-	0x20, /* 00 00000 */
-	0x10, /* 000 0000 */
-	0x08, /* 0000 000 */
-	0x04, /* 00000 00 */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x20, /* 00 00000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 63 0x3f '?' */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x04, /* 00000 00 */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 64 0x40 '@' */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x74, /* 0   0 00 */
-	0x54, /* 0 0 0 00 */
-	0x78, /* 0    000 */
-	0x40, /* 0 000000 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 65 0x41 'A' */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x7c, /* 0     00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 66 0x42 'B' */
-	0x00, /* 00000000 */
-	0x78, /* 0    000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x78, /* 0    000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x78, /* 0    000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 67 0x43 'C' */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 68 0x44 'D' */
-	0x00, /* 00000000 */
-	0x78, /* 0    000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x78, /* 0    000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 69 0x45 'E' */
-	0x00, /* 00000000 */
-	0x7c, /* 0     00 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x78, /* 0    000 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x7c, /* 0     00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 70 0x46 'F' */
-	0x00, /* 00000000 */
-	0x7c, /* 0     00 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x78, /* 0    000 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 71 0x47 'G' */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x40, /* 0 000000 */
-	0x4c, /* 0 00  00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 72 0x48 'H' */
-	0x00, /* 00000000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x7c, /* 0     00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 73 0x49 'I' */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 74 0x4a 'J' */
-	0x00, /* 00000000 */
-	0x04, /* 00000 00 */
-	0x04, /* 00000 00 */
-	0x04, /* 00000 00 */
-	0x04, /* 00000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 75 0x4b 'K' */
-	0x00, /* 00000000 */
-	0x44, /* 0 000 00 */
-	0x48, /* 0 00 000 */
-	0x50, /* 0 0 0000 */
-	0x60, /* 0  00000 */
-	0x50, /* 0 0 0000 */
-	0x48, /* 0 00 000 */
-	0x44, /* 0 000 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 76 0x4c 'L' */
-	0x00, /* 00000000 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x7c, /* 0     00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 77 0x4d 'M' */
-	0x00, /* 00000000 */
-	0x44, /* 0 000 00 */
-	0x6c, /* 0  0  00 */
-	0x54, /* 0 0 0 00 */
-	0x54, /* 0 0 0 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 78 0x4e 'N' */
-	0x00, /* 00000000 */
-	0x44, /* 0 000 00 */
-	0x64, /* 0  00 00 */
-	0x54, /* 0 0 0 00 */
-	0x4c, /* 0 00  00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 79 0x4f 'O' */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 80 0x50 'P' */
-	0x00, /* 00000000 */
-	0x78, /* 0    000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x78, /* 0    000 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 81 0x51 'Q' */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x54, /* 0 0 0 00 */
-	0x38, /* 00   000 */
-	0x04, /* 00000 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 82 0x52 'R' */
-	0x00, /* 00000000 */
-	0x78, /* 0    000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x78, /* 0    000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 83 0x53 'S' */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x40, /* 0 000000 */
-	0x38, /* 00   000 */
-	0x04, /* 00000 00 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 84 0x54 'T' */
-	0x00, /* 00000000 */
-	0x7c, /* 0     00 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 85 0x55 'U' */
-	0x00, /* 00000000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 86 0x56 'V' */
-	0x00, /* 00000000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x28, /* 00 0 000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 87 0x57 'W' */
-	0x00, /* 00000000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x54, /* 0 0 0 00 */
-	0x54, /* 0 0 0 00 */
-	0x6c, /* 0  0  00 */
-	0x44, /* 0 000 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 88 0x58 'X' */
-	0x00, /* 00000000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x28, /* 00 0 000 */
-	0x10, /* 000 0000 */
-	0x28, /* 00 0 000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 89 0x59 'Y' */
-	0x00, /* 00000000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x28, /* 00 0 000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 90 0x5a 'Z' */
-	0x00, /* 00000000 */
-	0x7c, /* 0     00 */
-	0x04, /* 00000 00 */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x20, /* 00 00000 */
-	0x40, /* 0 000000 */
-	0x7c, /* 0     00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 91 0x5b '[' */
-	0x0c, /* 0000  00 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x0c, /* 0000  00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 92 0x5c '\' */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x20, /* 00 00000 */
-	0x20, /* 00 00000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x04, /* 00000 00 */
-	0x04, /* 00000 00 */
-	0x00, /* 00000000 */
-
-	/* 93 0x5d ']' */
-	0x30, /* 00  0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x30, /* 00  0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 94 0x5e '^' */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x28, /* 00 0 000 */
-	0x44, /* 0 000 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 95 0x5f '_' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfc, /*       00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 96 0x60 '`' */
-	0x20, /* 00 00000 */
-	0x10, /* 000 0000 */
-	0x08, /* 0000 000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 97 0x61 'a' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x4c, /* 0 00  00 */
-	0x34, /* 00  0 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 98 0x62 'b' */
-	0x00, /* 00000000 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x78, /* 0    000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x78, /* 0    000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 99 0x63 'c' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x40, /* 0 000000 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 100 0x64 'd' */
-	0x00, /* 00000000 */
-	0x04, /* 00000 00 */
-	0x04, /* 00000 00 */
-	0x3c, /* 00    00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 101 0x65 'e' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x7c, /* 0     00 */
-	0x40, /* 0 000000 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 102 0x66 'f' */
-	0x00, /* 00000000 */
-	0x0c, /* 0000  00 */
-	0x10, /* 000 0000 */
-	0x38, /* 00   000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 103 0x67 'g' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x3c, /* 00    00 */
-	0x04, /* 00000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-
-	/* 104 0x68 'h' */
-	0x00, /* 00000000 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x78, /* 0    000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 105 0x69 'i' */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x30, /* 00  0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 106 0x6a 'j' */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x30, /* 00  0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x60, /* 0  00000 */
-	0x00, /* 00000000 */
-
-	/* 107 0x6b 'k' */
-	0x00, /* 00000000 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x48, /* 0 00 000 */
-	0x50, /* 0 0 0000 */
-	0x70, /* 0   0000 */
-	0x48, /* 0 00 000 */
-	0x44, /* 0 000 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 108 0x6c 'l' */
-	0x00, /* 00000000 */
-	0x30, /* 00  0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 109 0x6d 'm' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x78, /* 0    000 */
-	0x54, /* 0 0 0 00 */
-	0x54, /* 0 0 0 00 */
-	0x54, /* 0 0 0 00 */
-	0x54, /* 0 0 0 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 110 0x6e 'n' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x58, /* 0 0  000 */
-	0x64, /* 0  00 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 111 0x6f 'o' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 112 0x70 'p' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x78, /* 0    000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x78, /* 0    000 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x00, /* 00000000 */
-
-	/* 113 0x71 'q' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x3c, /* 00    00 */
-	0x04, /* 00000 00 */
-	0x04, /* 00000 00 */
-	0x00, /* 00000000 */
-
-	/* 114 0x72 'r' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x58, /* 0 0  000 */
-	0x64, /* 0  00 00 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 115 0x73 's' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x40, /* 0 000000 */
-	0x38, /* 00   000 */
-	0x04, /* 00000 00 */
-	0x78, /* 0    000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 116 0x74 't' */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x38, /* 00   000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x0c, /* 0000  00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 117 0x75 'u' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x4c, /* 0 00  00 */
-	0x34, /* 00  0 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 118 0x76 'v' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x28, /* 00 0 000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 119 0x77 'w' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x54, /* 0 0 0 00 */
-	0x54, /* 0 0 0 00 */
-	0x54, /* 0 0 0 00 */
-	0x54, /* 0 0 0 00 */
-	0x28, /* 00 0 000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 120 0x78 'x' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x44, /* 0 000 00 */
-	0x28, /* 00 0 000 */
-	0x10, /* 000 0000 */
-	0x28, /* 00 0 000 */
-	0x44, /* 0 000 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 121 0x79 'y' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x3c, /* 00    00 */
-	0x04, /* 00000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-
-	/* 122 0x7a 'z' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 0     00 */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x20, /* 00 00000 */
-	0x7c, /* 0     00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 123 0x7b '{' */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x04, /* 00000 00 */
-	0x00, /* 00000000 */
-
-	/* 124 0x7c '|' */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 125 0x7d '}' */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x20, /* 00 00000 */
-	0x00, /* 00000000 */
-
-	/* 126 0x7e '~' */
-	0x00, /* 00000000 */
-	0x34, /* 00  0 00 */
-	0x58, /* 0 0  000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 127 0x7f '^?' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 128 0x80 '\200' */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x7c, /* 0     00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 129 0x81 '\201' */
-	0x28, /* 00 0 000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x7c, /* 0     00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 130 0x82 '\202' */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 131 0x83 '\203' */
-	0x10, /* 000 0000 */
-	0x7c, /* 0     00 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x78, /* 0    000 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x7c, /* 0     00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 132 0x84 '\204' */
-	0x58, /* 0 0  000 */
-	0x44, /* 0 000 00 */
-	0x64, /* 0  00 00 */
-	0x54, /* 0 0 0 00 */
-	0x4c, /* 0 00  00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 133 0x85 '\205' */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 134 0x86 '\206' */
-	0x00, /* 00000000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 135 0x87 '\207' */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x4c, /* 0 00  00 */
-	0x34, /* 00  0 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 136 0x88 '\210' */
-	0x10, /* 000 0000 */
-	0x08, /* 0000 000 */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x4c, /* 0 00  00 */
-	0x34, /* 00  0 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 137 0x89 '\211' */
-	0x10, /* 000 0000 */
-	0x28, /* 00 0 000 */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x4c, /* 0 00  00 */
-	0x34, /* 00  0 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 138 0x8a '\212' */
-	0x00, /* 00000000 */
-	0x28, /* 00 0 000 */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x4c, /* 0 00  00 */
-	0x34, /* 00  0 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 139 0x8b '\213' */
-	0x34, /* 00  0 00 */
-	0x58, /* 0 0  000 */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x4c, /* 0 00  00 */
-	0x34, /* 00  0 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 140 0x8c '\214' */
-	0x18, /* 000  000 */
-	0x24, /* 00 00 00 */
-	0x18, /* 000  000 */
-	0x3c, /* 00    00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x4c, /* 0 00  00 */
-	0x34, /* 00  0 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 141 0x8d '\215' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x3c, /* 00    00 */
-	0x10, /* 000 0000 */
-	0x20, /* 00 00000 */
-	0x00, /* 00000000 */
-
-	/* 142 0x8e '\216' */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x7c, /* 0     00 */
-	0x40, /* 0 000000 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 143 0x8f '\217' */
-	0x20, /* 00 00000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x7c, /* 0     00 */
-	0x40, /* 0 000000 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 144 0x90 '\220' */
-	0x10, /* 000 0000 */
-	0x28, /* 00 0 000 */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x7c, /* 0     00 */
-	0x40, /* 0 000000 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 145 0x91 '\221' */
-	0x00, /* 00000000 */
-	0x28, /* 00 0 000 */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x7c, /* 0     00 */
-	0x40, /* 0 000000 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 146 0x92 '\222' */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 147 0x93 '\223' */
-	0x20, /* 00 00000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 148 0x94 '\224' */
-	0x10, /* 000 0000 */
-	0x28, /* 00 0 000 */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 149 0x95 '\225' */
-	0x00, /* 00000000 */
-	0x28, /* 00 0 000 */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 150 0x96 '\226' */
-	0x34, /* 00  0 00 */
-	0x58, /* 0 0  000 */
-	0x00, /* 00000000 */
-	0x58, /* 0 0  000 */
-	0x64, /* 0  00 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 151 0x97 '\227' */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 152 0x98 '\230' */
-	0x20, /* 00 00000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 153 0x99 '\231' */
-	0x10, /* 000 0000 */
-	0x28, /* 00 0 000 */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 154 0x9a '\232' */
-	0x00, /* 00000000 */
-	0x28, /* 00 0 000 */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 155 0x9b '\233' */
-	0x34, /* 00  0 00 */
-	0x58, /* 0 0  000 */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 156 0x9c '\234' */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x4c, /* 0 00  00 */
-	0x34, /* 00  0 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 157 0x9d '\235' */
-	0x20, /* 00 00000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x4c, /* 0 00  00 */
-	0x34, /* 00  0 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 158 0x9e '\236' */
-	0x10, /* 000 0000 */
-	0x28, /* 00 0 000 */
-	0x00, /* 00000000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x4c, /* 0 00  00 */
-	0x34, /* 00  0 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 159 0x9f '\237' */
-	0x00, /* 00000000 */
-	0x28, /* 00 0 000 */
-	0x00, /* 00000000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x4c, /* 0 00  00 */
-	0x34, /* 00  0 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 160 0xa0 '\240' */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x38, /* 00   000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 161 0xa1 '\241' */
-	0x18, /* 000  000 */
-	0x24, /* 00 00 00 */
-	0x24, /* 00 00 00 */
-	0x18, /* 000  000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 162 0xa2 '\242' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x38, /* 00   000 */
-	0x54, /* 0 0 0 00 */
-	0x50, /* 0 0 0000 */
-	0x54, /* 0 0 0 00 */
-	0x38, /* 00   000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 163 0xa3 '\243' */
-	0x30, /* 00  0000 */
-	0x48, /* 0 00 000 */
-	0x40, /* 0 000000 */
-	0x70, /* 0   0000 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x44, /* 0 000 00 */
-	0x78, /* 0    000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 164 0xa4 '\244' */
-	0x44, /* 0 000 00 */
-	0x24, /* 00 00 00 */
-	0x50, /* 0 0 0000 */
-	0x48, /* 0 00 000 */
-	0x24, /* 00 00 00 */
-	0x14, /* 000 0 00 */
-	0x48, /* 0 00 000 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 165 0xa5 '\245' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x7c, /* 0     00 */
-	0x7c, /* 0     00 */
-	0x7c, /* 0     00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 166 0xa6 '\246' */
-	0x3c, /* 00    00 */
-	0x54, /* 0 0 0 00 */
-	0x54, /* 0 0 0 00 */
-	0x54, /* 0 0 0 00 */
-	0x3c, /* 00    00 */
-	0x14, /* 000 0 00 */
-	0x14, /* 000 0 00 */
-	0x14, /* 000 0 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 167 0xa7 '\247' */
-	0x18, /* 000  000 */
-	0x24, /* 00 00 00 */
-	0x44, /* 0 000 00 */
-	0x48, /* 0 00 000 */
-	0x48, /* 0 00 000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x58, /* 0 0  000 */
-	0x40, /* 0 000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 168 0xa8 '\250' */
-	0x00, /* 00000000 */
-	0x70, /* 0   0000 */
-	0x08, /* 0000 000 */
-	0x64, /* 0  00 00 */
-	0x54, /* 0 0 0 00 */
-	0x64, /* 0  00 00 */
-	0x58, /* 0 0  000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 169 0xa9 '\251' */
-	0x00, /* 00000000 */
-	0x70, /* 0   0000 */
-	0x08, /* 0000 000 */
-	0x34, /* 00  0 00 */
-	0x44, /* 0 000 00 */
-	0x34, /* 00  0 00 */
-	0x08, /* 0000 000 */
-	0x70, /* 0   0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 170 0xaa '\252' */
-	0x00, /* 00000000 */
-	0xf4, /*     0 00 */
-	0x5c, /* 0 0   00 */
-	0x5c, /* 0 0   00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 171 0xab '\253' */
-	0x00, /* 00000000 */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 172 0xac '\254' */
-	0x00, /* 00000000 */
-	0x28, /* 00 0 000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 173 0xad '\255' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x08, /* 0000 000 */
-	0x7c, /* 0     00 */
-	0x10, /* 000 0000 */
-	0x7c, /* 0     00 */
-	0x20, /* 00 00000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 174 0xae '\256' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x50, /* 0 0 0000 */
-	0x50, /* 0 0 0000 */
-	0x78, /* 0    000 */
-	0x50, /* 0 0 0000 */
-	0x50, /* 0 0 0000 */
-	0x5c, /* 0 0   00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 175 0xaf '\257' */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x4c, /* 0 00  00 */
-	0x54, /* 0 0 0 00 */
-	0x64, /* 0  00 00 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 176 0xb0 '\260' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x6c, /* 0  0  00 */
-	0x54, /* 0 0 0 00 */
-	0x6c, /* 0  0  00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 177 0xb1 '\261' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x7c, /* 0     00 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x7c, /* 0     00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 178 0xb2 '\262' */
-	0x00, /* 00000000 */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x20, /* 00 00000 */
-	0x10, /* 000 0000 */
-	0x08, /* 0000 000 */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 179 0xb3 '\263' */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x08, /* 0000 000 */
-	0x04, /* 00000 00 */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x1c, /* 000   00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 180 0xb4 '\264' */
-	0x00, /* 00000000 */
-	0x44, /* 0 000 00 */
-	0x28, /* 00 0 000 */
-	0x7c, /* 0     00 */
-	0x10, /* 000 0000 */
-	0x7c, /* 0     00 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 181 0xb5 '\265' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x48, /* 0 00 000 */
-	0x48, /* 0 00 000 */
-	0x48, /* 0 00 000 */
-	0x48, /* 0 00 000 */
-	0x74, /* 0   0 00 */
-	0x40, /* 0 000000 */
-	0x40, /* 0 000000 */
-	0x00, /* 00000000 */
-
-	/* 182 0xb6 '\266' */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x08, /* 0000 000 */
-	0x0c, /* 0000  00 */
-	0x14, /* 000 0 00 */
-	0x24, /* 00 00 00 */
-	0x24, /* 00 00 00 */
-	0x18, /* 000  000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 183 0xb7 '\267' */
-	0x00, /* 00000000 */
-	0x7c, /* 0     00 */
-	0x24, /* 00 00 00 */
-	0x10, /* 000 0000 */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x24, /* 00 00 00 */
-	0x7c, /* 0     00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 184 0xb8 '\270' */
-	0x00, /* 00000000 */
-	0x7c, /* 0     00 */
-	0x28, /* 00 0 000 */
-	0x28, /* 00 0 000 */
-	0x28, /* 00 0 000 */
-	0x28, /* 00 0 000 */
-	0x28, /* 00 0 000 */
-	0x28, /* 00 0 000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 185 0xb9 '\271' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 0     00 */
-	0x28, /* 00 0 000 */
-	0x28, /* 00 0 000 */
-	0x28, /* 00 0 000 */
-	0x28, /* 00 0 000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 186 0xba '\272' */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x60, /* 0  00000 */
-	0x00, /* 00000000 */
-
-	/* 187 0xbb '\273' */
-	0x00, /* 00000000 */
-	0x1c, /* 000   00 */
-	0x24, /* 00 00 00 */
-	0x24, /* 00 00 00 */
-	0x1c, /* 000   00 */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 188 0xbc '\274' */
-	0x00, /* 00000000 */
-	0x18, /* 000  000 */
-	0x24, /* 00 00 00 */
-	0x24, /* 00 00 00 */
-	0x18, /* 000  000 */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 189 0xbd '\275' */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x28, /* 00 0 000 */
-	0x6c, /* 0  0  00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 190 0xbe '\276' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x54, /* 0 0 0 00 */
-	0x5c, /* 0 0   00 */
-	0x50, /* 0 0 0000 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 191 0xbf '\277' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x4c, /* 0 00  00 */
-	0x54, /* 0 0 0 00 */
-	0x64, /* 0  00 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 192 0xc0 '\300' */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x20, /* 00 00000 */
-	0x40, /* 0 000000 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 193 0xc1 '\301' */
-	0x00, /* 00000000 */
-	0x08, /* 0000 000 */
-	0x00, /* 00000000 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x08, /* 0000 000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 194 0xc2 '\302' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 0     00 */
-	0x04, /* 00000 00 */
-	0x04, /* 00000 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 195 0xc3 '\303' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x0c, /* 0000  00 */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x50, /* 0 0 0000 */
-	0x20, /* 00 00000 */
-	0x20, /* 00 00000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 196 0xc4 '\304' */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x38, /* 00   000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x60, /* 0  00000 */
-	0x00, /* 00000000 */
-
-	/* 197 0xc5 '\305' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x04, /* 00000 00 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x40, /* 0 000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 198 0xc6 '\306' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x10, /* 000 0000 */
-	0x28, /* 00 0 000 */
-	0x28, /* 00 0 000 */
-	0x44, /* 0 000 00 */
-	0x7c, /* 0     00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 199 0xc7 '\307' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x24, /* 00 00 00 */
-	0x48, /* 0 00 000 */
-	0x48, /* 0 00 000 */
-	0x24, /* 00 00 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 200 0xc8 '\310' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x48, /* 0 00 000 */
-	0x24, /* 00 00 00 */
-	0x24, /* 00 00 00 */
-	0x48, /* 0 00 000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 201 0xc9 '\311' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x54, /* 0 0 0 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 202 0xca '\312' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 203 0xcb '\313' */
-	0x10, /* 000 0000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x7c, /* 0     00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 204 0xcc '\314' */
-	0x58, /* 0 0  000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x7c, /* 0     00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 205 0xcd '\315' */
-	0x58, /* 0 0  000 */
-	0x38, /* 00   000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 206 0xce '\316' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x50, /* 0 0 0000 */
-	0x50, /* 0 0 0000 */
-	0x58, /* 0 0  000 */
-	0x50, /* 0 0 0000 */
-	0x50, /* 0 0 0000 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 207 0xcf '\317' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x28, /* 00 0 000 */
-	0x54, /* 0 0 0 00 */
-	0x5c, /* 0 0   00 */
-	0x50, /* 0 0 0000 */
-	0x2c, /* 00 0  00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 208 0xd0 '\320' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 209 0xd1 '\321' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfc, /*       00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 210 0xd2 '\322' */
-	0x00, /* 00000000 */
-	0x14, /* 000 0 00 */
-	0x28, /* 00 0 000 */
-	0x28, /* 00 0 000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 211 0xd3 '\323' */
-	0x00, /* 00000000 */
-	0x14, /* 000 0 00 */
-	0x14, /* 000 0 00 */
-	0x28, /* 00 0 000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 212 0xd4 '\324' */
-	0x00, /* 00000000 */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x18, /* 000  000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 213 0xd5 '\325' */
-	0x00, /* 00000000 */
-	0x18, /* 000  000 */
-	0x08, /* 0000 000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 214 0xd6 '\326' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x7c, /* 0     00 */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 215 0xd7 '\327' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x10, /* 000 0000 */
-	0x28, /* 00 0 000 */
-	0x44, /* 0 000 00 */
-	0x28, /* 00 0 000 */
-	0x10, /* 000 0000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 216 0xd8 '\330' */
-	0x00, /* 00000000 */
-	0x28, /* 00 0 000 */
-	0x00, /* 00000000 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x44, /* 0 000 00 */
-	0x3c, /* 00    00 */
-	0x04, /* 00000 00 */
-	0x38, /* 00   000 */
-	0x00, /* 00000000 */
-
-	/* 217 0xd9 '\331' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfc, /*       00 */
-	0x00, /* 00000000 */
-	0xfc, /*       00 */
-	0x00, /* 00000000 */
-	0xfc, /*       00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 218 0xda '\332' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 219 0xdb '\333' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 220 0xdc '\334' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 221 0xdd '\335' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 222 0xde '\336' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 223 0xdf '\337' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 224 0xe0 '\340' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 225 0xe1 '\341' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 226 0xe2 '\342' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 227 0xe3 '\343' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 228 0xe4 '\344' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 229 0xe5 '\345' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 230 0xe6 '\346' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 231 0xe7 '\347' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 232 0xe8 '\350' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 233 0xe9 '\351' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 234 0xea '\352' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 235 0xeb '\353' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 236 0xec '\354' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 237 0xed '\355' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 238 0xee '\356' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 239 0xef '\357' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 240 0xf0 '\360' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 241 0xf1 '\361' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 242 0xf2 '\362' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 243 0xf3 '\363' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 244 0xf4 '\364' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 245 0xf5 '\365' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 246 0xf6 '\366' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 247 0xf7 '\367' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 248 0xf8 '\370' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 249 0xf9 '\371' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 250 0xfa '\372' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 251 0xfb '\373' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 252 0xfc '\374' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 253 0xfd '\375' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 254 0xfe '\376' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 255 0xff '\377' */
-	0x00, /* 00000000 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x3c, /* 00    00 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-};
-
-
-struct fbcon_font_desc font_vga_6x11 = {
-	VGA6x11_IDX,
-	"ProFont6x11",
-	6,
-	11,
-	fontdata_6x11,
-	-2000	/* Try avoiding this font if possible unless on MAC */
-};
diff -Nru a/drivers/video/font_8x16.c b/drivers/video/font_8x16.c
--- a/drivers/video/font_8x16.c	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,4631 +0,0 @@
-/**********************************************/
-/*                                            */
-/*       Font file generated by cpi2fnt       */
-/*                                            */
-/**********************************************/
-
-#include <video/font.h>
-
-#define FONTDATAMAX 4096
-
-static unsigned char fontdata_8x16[FONTDATAMAX] = {
-
-	/* 0 0x00 '^@' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 1 0x01 '^A' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0x81, /* 10000001 */
-	0xa5, /* 10100101 */
-	0x81, /* 10000001 */
-	0x81, /* 10000001 */
-	0xbd, /* 10111101 */
-	0x99, /* 10011001 */
-	0x81, /* 10000001 */
-	0x81, /* 10000001 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 2 0x02 '^B' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0xff, /* 11111111 */
-	0xdb, /* 11011011 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xc3, /* 11000011 */
-	0xe7, /* 11100111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 3 0x03 '^C' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x6c, /* 01101100 */
-	0xfe, /* 11111110 */
-	0xfe, /* 11111110 */
-	0xfe, /* 11111110 */
-	0xfe, /* 11111110 */
-	0x7c, /* 01111100 */
-	0x38, /* 00111000 */
-	0x10, /* 00010000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 4 0x04 '^D' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x10, /* 00010000 */
-	0x38, /* 00111000 */
-	0x7c, /* 01111100 */
-	0xfe, /* 11111110 */
-	0x7c, /* 01111100 */
-	0x38, /* 00111000 */
-	0x10, /* 00010000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 5 0x05 '^E' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x3c, /* 00111100 */
-	0xe7, /* 11100111 */
-	0xe7, /* 11100111 */
-	0xe7, /* 11100111 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 6 0x06 '^F' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x7e, /* 01111110 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0x7e, /* 01111110 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 7 0x07 '^G' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 8 0x08 '^H' */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xe7, /* 11100111 */
-	0xc3, /* 11000011 */
-	0xc3, /* 11000011 */
-	0xe7, /* 11100111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-
-	/* 9 0x09 '^I' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x3c, /* 00111100 */
-	0x66, /* 01100110 */
-	0x42, /* 01000010 */
-	0x42, /* 01000010 */
-	0x66, /* 01100110 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 10 0x0a '^J' */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xc3, /* 11000011 */
-	0x99, /* 10011001 */
-	0xbd, /* 10111101 */
-	0xbd, /* 10111101 */
-	0x99, /* 10011001 */
-	0xc3, /* 11000011 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-
-	/* 11 0x0b '^K' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x1e, /* 00011110 */
-	0x0e, /* 00001110 */
-	0x1a, /* 00011010 */
-	0x32, /* 00110010 */
-	0x78, /* 01111000 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x78, /* 01111000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 12 0x0c '^L' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x3c, /* 00111100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-	0x7e, /* 01111110 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 13 0x0d '^M' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x3f, /* 00111111 */
-	0x33, /* 00110011 */
-	0x3f, /* 00111111 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x70, /* 01110000 */
-	0xf0, /* 11110000 */
-	0xe0, /* 11100000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 14 0x0e '^N' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7f, /* 01111111 */
-	0x63, /* 01100011 */
-	0x7f, /* 01111111 */
-	0x63, /* 01100011 */
-	0x63, /* 01100011 */
-	0x63, /* 01100011 */
-	0x63, /* 01100011 */
-	0x67, /* 01100111 */
-	0xe7, /* 11100111 */
-	0xe6, /* 11100110 */
-	0xc0, /* 11000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 15 0x0f '^O' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0xdb, /* 11011011 */
-	0x3c, /* 00111100 */
-	0xe7, /* 11100111 */
-	0x3c, /* 00111100 */
-	0xdb, /* 11011011 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 16 0x10 '^P' */
-	0x00, /* 00000000 */
-	0x80, /* 10000000 */
-	0xc0, /* 11000000 */
-	0xe0, /* 11100000 */
-	0xf0, /* 11110000 */
-	0xf8, /* 11111000 */
-	0xfe, /* 11111110 */
-	0xf8, /* 11111000 */
-	0xf0, /* 11110000 */
-	0xe0, /* 11100000 */
-	0xc0, /* 11000000 */
-	0x80, /* 10000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 17 0x11 '^Q' */
-	0x00, /* 00000000 */
-	0x02, /* 00000010 */
-	0x06, /* 00000110 */
-	0x0e, /* 00001110 */
-	0x1e, /* 00011110 */
-	0x3e, /* 00111110 */
-	0xfe, /* 11111110 */
-	0x3e, /* 00111110 */
-	0x1e, /* 00011110 */
-	0x0e, /* 00001110 */
-	0x06, /* 00000110 */
-	0x02, /* 00000010 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 18 0x12 '^R' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x7e, /* 01111110 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x7e, /* 01111110 */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 19 0x13 '^S' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x00, /* 00000000 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 20 0x14 '^T' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7f, /* 01111111 */
-	0xdb, /* 11011011 */
-	0xdb, /* 11011011 */
-	0xdb, /* 11011011 */
-	0x7b, /* 01111011 */
-	0x1b, /* 00011011 */
-	0x1b, /* 00011011 */
-	0x1b, /* 00011011 */
-	0x1b, /* 00011011 */
-	0x1b, /* 00011011 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 21 0x15 '^U' */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0x60, /* 01100000 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x6c, /* 01101100 */
-	0x38, /* 00111000 */
-	0x0c, /* 00001100 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 22 0x16 '^V' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0xfe, /* 11111110 */
-	0xfe, /* 11111110 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 23 0x17 '^W' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x7e, /* 01111110 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x7e, /* 01111110 */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 24 0x18 '^X' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x7e, /* 01111110 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 25 0x19 '^Y' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x7e, /* 01111110 */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 26 0x1a '^Z' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x0c, /* 00001100 */
-	0xfe, /* 11111110 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 27 0x1b '^[' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x30, /* 00110000 */
-	0x60, /* 01100000 */
-	0xfe, /* 11111110 */
-	0x60, /* 01100000 */
-	0x30, /* 00110000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 28 0x1c '^\' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 29 0x1d '^]' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x28, /* 00101000 */
-	0x6c, /* 01101100 */
-	0xfe, /* 11111110 */
-	0x6c, /* 01101100 */
-	0x28, /* 00101000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 30 0x1e '^^' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x10, /* 00010000 */
-	0x38, /* 00111000 */
-	0x38, /* 00111000 */
-	0x7c, /* 01111100 */
-	0x7c, /* 01111100 */
-	0xfe, /* 11111110 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 31 0x1f '^_' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0xfe, /* 11111110 */
-	0x7c, /* 01111100 */
-	0x7c, /* 01111100 */
-	0x38, /* 00111000 */
-	0x38, /* 00111000 */
-	0x10, /* 00010000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 32 0x20 ' ' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 33 0x21 '!' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x3c, /* 00111100 */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 34 0x22 '"' */
-	0x00, /* 00000000 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x24, /* 00100100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 35 0x23 '#' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0xfe, /* 11111110 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0xfe, /* 11111110 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 36 0x24 '$' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc2, /* 11000010 */
-	0xc0, /* 11000000 */
-	0x7c, /* 01111100 */
-	0x06, /* 00000110 */
-	0x06, /* 00000110 */
-	0x86, /* 10000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 37 0x25 '%' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xc2, /* 11000010 */
-	0xc6, /* 11000110 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x60, /* 01100000 */
-	0xc6, /* 11000110 */
-	0x86, /* 10000110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 38 0x26 '&' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0x38, /* 00111000 */
-	0x76, /* 01110110 */
-	0xdc, /* 11011100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 39 0x27 ''' */
-	0x00, /* 00000000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x60, /* 01100000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 40 0x28 '(' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x0c, /* 00001100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 41 0x29 ')' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 42 0x2a '*' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x66, /* 01100110 */
-	0x3c, /* 00111100 */
-	0xff, /* 11111111 */
-	0x3c, /* 00111100 */
-	0x66, /* 01100110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 43 0x2b '+' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x7e, /* 01111110 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 44 0x2c ',' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 45 0x2d '-' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 46 0x2e '.' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 47 0x2f '/' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x02, /* 00000010 */
-	0x06, /* 00000110 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x60, /* 01100000 */
-	0xc0, /* 11000000 */
-	0x80, /* 10000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 48 0x30 '0' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xd6, /* 11010110 */
-	0xd6, /* 11010110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x6c, /* 01101100 */
-	0x38, /* 00111000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 49 0x31 '1' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x38, /* 00111000 */
-	0x78, /* 01111000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 50 0x32 '2' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0x06, /* 00000110 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x60, /* 01100000 */
-	0xc0, /* 11000000 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 51 0x33 '3' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0x06, /* 00000110 */
-	0x06, /* 00000110 */
-	0x3c, /* 00111100 */
-	0x06, /* 00000110 */
-	0x06, /* 00000110 */
-	0x06, /* 00000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 52 0x34 '4' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x0c, /* 00001100 */
-	0x1c, /* 00011100 */
-	0x3c, /* 00111100 */
-	0x6c, /* 01101100 */
-	0xcc, /* 11001100 */
-	0xfe, /* 11111110 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x1e, /* 00011110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 53 0x35 '5' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xfc, /* 11111100 */
-	0x06, /* 00000110 */
-	0x06, /* 00000110 */
-	0x06, /* 00000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 54 0x36 '6' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x38, /* 00111000 */
-	0x60, /* 01100000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xfc, /* 11111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 55 0x37 '7' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0xc6, /* 11000110 */
-	0x06, /* 00000110 */
-	0x06, /* 00000110 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 56 0x38 '8' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 57 0x39 '9' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7e, /* 01111110 */
-	0x06, /* 00000110 */
-	0x06, /* 00000110 */
-	0x06, /* 00000110 */
-	0x0c, /* 00001100 */
-	0x78, /* 01111000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 58 0x3a ':' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 59 0x3b ';' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 60 0x3c '<' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x06, /* 00000110 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x60, /* 01100000 */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x0c, /* 00001100 */
-	0x06, /* 00000110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 61 0x3d '=' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 62 0x3e '>' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x60, /* 01100000 */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x0c, /* 00001100 */
-	0x06, /* 00000110 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x60, /* 01100000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 63 0x3f '?' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 64 0x40 '@' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xde, /* 11011110 */
-	0xde, /* 11011110 */
-	0xde, /* 11011110 */
-	0xdc, /* 11011100 */
-	0xc0, /* 11000000 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 65 0x41 'A' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x10, /* 00010000 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 66 0x42 'B' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfc, /* 11111100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x7c, /* 01111100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0xfc, /* 11111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 67 0x43 'C' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x3c, /* 00111100 */
-	0x66, /* 01100110 */
-	0xc2, /* 11000010 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc2, /* 11000010 */
-	0x66, /* 01100110 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 68 0x44 'D' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xf8, /* 11111000 */
-	0x6c, /* 01101100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x6c, /* 01101100 */
-	0xf8, /* 11111000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 69 0x45 'E' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0x66, /* 01100110 */
-	0x62, /* 01100010 */
-	0x68, /* 01101000 */
-	0x78, /* 01111000 */
-	0x68, /* 01101000 */
-	0x60, /* 01100000 */
-	0x62, /* 01100010 */
-	0x66, /* 01100110 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 70 0x46 'F' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0x66, /* 01100110 */
-	0x62, /* 01100010 */
-	0x68, /* 01101000 */
-	0x78, /* 01111000 */
-	0x68, /* 01101000 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0xf0, /* 11110000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 71 0x47 'G' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x3c, /* 00111100 */
-	0x66, /* 01100110 */
-	0xc2, /* 11000010 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xde, /* 11011110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x66, /* 01100110 */
-	0x3a, /* 00111010 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 72 0x48 'H' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 73 0x49 'I' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 74 0x4a 'J' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x1e, /* 00011110 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x78, /* 01111000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 75 0x4b 'K' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xe6, /* 11100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x6c, /* 01101100 */
-	0x78, /* 01111000 */
-	0x78, /* 01111000 */
-	0x6c, /* 01101100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0xe6, /* 11100110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 76 0x4c 'L' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xf0, /* 11110000 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0x62, /* 01100010 */
-	0x66, /* 01100110 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 77 0x4d 'M' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0xee, /* 11101110 */
-	0xfe, /* 11111110 */
-	0xfe, /* 11111110 */
-	0xd6, /* 11010110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 78 0x4e 'N' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0xe6, /* 11100110 */
-	0xf6, /* 11110110 */
-	0xfe, /* 11111110 */
-	0xde, /* 11011110 */
-	0xce, /* 11001110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 79 0x4f 'O' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 80 0x50 'P' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfc, /* 11111100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x7c, /* 01111100 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0xf0, /* 11110000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 81 0x51 'Q' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xd6, /* 11010110 */
-	0xde, /* 11011110 */
-	0x7c, /* 01111100 */
-	0x0c, /* 00001100 */
-	0x0e, /* 00001110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 82 0x52 'R' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfc, /* 11111100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x7c, /* 01111100 */
-	0x6c, /* 01101100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0xe6, /* 11100110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 83 0x53 'S' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x60, /* 01100000 */
-	0x38, /* 00111000 */
-	0x0c, /* 00001100 */
-	0x06, /* 00000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 84 0x54 'T' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0x7e, /* 01111110 */
-	0x5a, /* 01011010 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 85 0x55 'U' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 86 0x56 'V' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x6c, /* 01101100 */
-	0x38, /* 00111000 */
-	0x10, /* 00010000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 87 0x57 'W' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xd6, /* 11010110 */
-	0xd6, /* 11010110 */
-	0xd6, /* 11010110 */
-	0xfe, /* 11111110 */
-	0xee, /* 11101110 */
-	0x6c, /* 01101100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 88 0x58 'X' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x6c, /* 01101100 */
-	0x7c, /* 01111100 */
-	0x38, /* 00111000 */
-	0x38, /* 00111000 */
-	0x7c, /* 01111100 */
-	0x6c, /* 01101100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 89 0x59 'Y' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 90 0x5a 'Z' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0xc6, /* 11000110 */
-	0x86, /* 10000110 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x60, /* 01100000 */
-	0xc2, /* 11000010 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 91 0x5b '[' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x3c, /* 00111100 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 92 0x5c '\' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x80, /* 10000000 */
-	0xc0, /* 11000000 */
-	0xe0, /* 11100000 */
-	0x70, /* 01110000 */
-	0x38, /* 00111000 */
-	0x1c, /* 00011100 */
-	0x0e, /* 00001110 */
-	0x06, /* 00000110 */
-	0x02, /* 00000010 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 93 0x5d ']' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x3c, /* 00111100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 94 0x5e '^' */
-	0x10, /* 00010000 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 95 0x5f '_' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 96 0x60 '`' */
-	0x00, /* 00000000 */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x0c, /* 00001100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 97 0x61 'a' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x78, /* 01111000 */
-	0x0c, /* 00001100 */
-	0x7c, /* 01111100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 98 0x62 'b' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xe0, /* 11100000 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0x78, /* 01111000 */
-	0x6c, /* 01101100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 99 0x63 'c' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 100 0x64 'd' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x1c, /* 00011100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x3c, /* 00111100 */
-	0x6c, /* 01101100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 101 0x65 'e' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 102 0x66 'f' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x1c, /* 00011100 */
-	0x36, /* 00110110 */
-	0x32, /* 00110010 */
-	0x30, /* 00110000 */
-	0x78, /* 01111000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x78, /* 01111000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 103 0x67 'g' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x76, /* 01110110 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x7c, /* 01111100 */
-	0x0c, /* 00001100 */
-	0xcc, /* 11001100 */
-	0x78, /* 01111000 */
-	0x00, /* 00000000 */
-
-	/* 104 0x68 'h' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xe0, /* 11100000 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0x6c, /* 01101100 */
-	0x76, /* 01110110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0xe6, /* 11100110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 105 0x69 'i' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x38, /* 00111000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 106 0x6a 'j' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x06, /* 00000110 */
-	0x06, /* 00000110 */
-	0x00, /* 00000000 */
-	0x0e, /* 00001110 */
-	0x06, /* 00000110 */
-	0x06, /* 00000110 */
-	0x06, /* 00000110 */
-	0x06, /* 00000110 */
-	0x06, /* 00000110 */
-	0x06, /* 00000110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-
-	/* 107 0x6b 'k' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xe0, /* 11100000 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0x66, /* 01100110 */
-	0x6c, /* 01101100 */
-	0x78, /* 01111000 */
-	0x78, /* 01111000 */
-	0x6c, /* 01101100 */
-	0x66, /* 01100110 */
-	0xe6, /* 11100110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 108 0x6c 'l' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x38, /* 00111000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 109 0x6d 'm' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xec, /* 11101100 */
-	0xfe, /* 11111110 */
-	0xd6, /* 11010110 */
-	0xd6, /* 11010110 */
-	0xd6, /* 11010110 */
-	0xd6, /* 11010110 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 110 0x6e 'n' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xdc, /* 11011100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 111 0x6f 'o' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 112 0x70 'p' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xdc, /* 11011100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x7c, /* 01111100 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0xf0, /* 11110000 */
-	0x00, /* 00000000 */
-
-	/* 113 0x71 'q' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x76, /* 01110110 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x7c, /* 01111100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x1e, /* 00011110 */
-	0x00, /* 00000000 */
-
-	/* 114 0x72 'r' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xdc, /* 11011100 */
-	0x76, /* 01110110 */
-	0x66, /* 01100110 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0xf0, /* 11110000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 115 0x73 's' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0x60, /* 01100000 */
-	0x38, /* 00111000 */
-	0x0c, /* 00001100 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 116 0x74 't' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x10, /* 00010000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0xfc, /* 11111100 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x36, /* 00110110 */
-	0x1c, /* 00011100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 117 0x75 'u' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 118 0x76 'v' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x6c, /* 01101100 */
-	0x38, /* 00111000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 119 0x77 'w' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xd6, /* 11010110 */
-	0xd6, /* 11010110 */
-	0xd6, /* 11010110 */
-	0xfe, /* 11111110 */
-	0x6c, /* 01101100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 120 0x78 'x' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0x6c, /* 01101100 */
-	0x38, /* 00111000 */
-	0x38, /* 00111000 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 121 0x79 'y' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7e, /* 01111110 */
-	0x06, /* 00000110 */
-	0x0c, /* 00001100 */
-	0xf8, /* 11111000 */
-	0x00, /* 00000000 */
-
-	/* 122 0x7a 'z' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0xcc, /* 11001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x60, /* 01100000 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 123 0x7b '{' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x0e, /* 00001110 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x70, /* 01110000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x0e, /* 00001110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 124 0x7c '|' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 125 0x7d '}' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x70, /* 01110000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x0e, /* 00001110 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x70, /* 01110000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 126 0x7e '~' */
-	0x00, /* 00000000 */
-	0x76, /* 01110110 */
-	0xdc, /* 11011100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 127 0x7f '' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x10, /* 00010000 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 128 0x80 '€' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x3c, /* 00111100 */
-	0x66, /* 01100110 */
-	0xc2, /* 11000010 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc2, /* 11000010 */
-	0x66, /* 01100110 */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-	0x70, /* 01110000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 129 0x81 '�' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xcc, /* 11001100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 130 0x82 '‚' */
-	0x00, /* 00000000 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 131 0x83 'ƒ' */
-	0x00, /* 00000000 */
-	0x10, /* 00010000 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0x00, /* 00000000 */
-	0x78, /* 01111000 */
-	0x0c, /* 00001100 */
-	0x7c, /* 01111100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 132 0x84 '„' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xcc, /* 11001100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x78, /* 01111000 */
-	0x0c, /* 00001100 */
-	0x7c, /* 01111100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 133 0x85 '…' */
-	0x00, /* 00000000 */
-	0x60, /* 01100000 */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x78, /* 01111000 */
-	0x0c, /* 00001100 */
-	0x7c, /* 01111100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 134 0x86 '†' */
-	0x00, /* 00000000 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0x38, /* 00111000 */
-	0x00, /* 00000000 */
-	0x78, /* 01111000 */
-	0x0c, /* 00001100 */
-	0x7c, /* 01111100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 135 0x87 '‡' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x18, /* 00011000 */
-	0x70, /* 01110000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 136 0x88 'ˆ' */
-	0x00, /* 00000000 */
-	0x10, /* 00010000 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 137 0x89 '‰' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 138 0x8a 'Š' */
-	0x00, /* 00000000 */
-	0x60, /* 01100000 */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 139 0x8b '‹' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x66, /* 01100110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x38, /* 00111000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 140 0x8c 'Œ' */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x66, /* 01100110 */
-	0x00, /* 00000000 */
-	0x38, /* 00111000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 141 0x8d '�' */
-	0x00, /* 00000000 */
-	0x60, /* 01100000 */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x38, /* 00111000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 142 0x8e 'Ž' */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0x10, /* 00010000 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 143 0x8f '�' */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0x38, /* 00111000 */
-	0x10, /* 00010000 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 144 0x90 '�' */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0x66, /* 01100110 */
-	0x62, /* 01100010 */
-	0x68, /* 01101000 */
-	0x78, /* 01111000 */
-	0x68, /* 01101000 */
-	0x62, /* 01100010 */
-	0x66, /* 01100110 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 145 0x91 '‘' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xec, /* 11101100 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x7e, /* 01111110 */
-	0xd8, /* 11011000 */
-	0xd8, /* 11011000 */
-	0x6e, /* 01101110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 146 0x92 '’' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x3e, /* 00111110 */
-	0x6c, /* 01101100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xfe, /* 11111110 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xce, /* 11001110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 147 0x93 '“' */
-	0x00, /* 00000000 */
-	0x10, /* 00010000 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 148 0x94 '”' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 149 0x95 '•' */
-	0x00, /* 00000000 */
-	0x60, /* 01100000 */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 150 0x96 '–' */
-	0x00, /* 00000000 */
-	0x30, /* 00110000 */
-	0x78, /* 01111000 */
-	0xcc, /* 11001100 */
-	0x00, /* 00000000 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 151 0x97 '—' */
-	0x00, /* 00000000 */
-	0x60, /* 01100000 */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 152 0x98 '˜' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7e, /* 01111110 */
-	0x06, /* 00000110 */
-	0x0c, /* 00001100 */
-	0x78, /* 01111000 */
-	0x00, /* 00000000 */
-
-	/* 153 0x99 '™' */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 154 0x9a 'š' */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 155 0x9b '›' */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 156 0x9c 'œ' */
-	0x00, /* 00000000 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0x64, /* 01100100 */
-	0x60, /* 01100000 */
-	0xf0, /* 11110000 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0xe6, /* 11100110 */
-	0xfc, /* 11111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 157 0x9d '�' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-	0x7e, /* 01111110 */
-	0x18, /* 00011000 */
-	0x7e, /* 01111110 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 158 0x9e 'ž' */
-	0x00, /* 00000000 */
-	0xf8, /* 11111000 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xf8, /* 11111000 */
-	0xc4, /* 11000100 */
-	0xcc, /* 11001100 */
-	0xde, /* 11011110 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 159 0x9f 'Ÿ' */
-	0x00, /* 00000000 */
-	0x0e, /* 00001110 */
-	0x1b, /* 00011011 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x7e, /* 01111110 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0xd8, /* 11011000 */
-	0x70, /* 01110000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 160 0xa0 ' ' */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x60, /* 01100000 */
-	0x00, /* 00000000 */
-	0x78, /* 01111000 */
-	0x0c, /* 00001100 */
-	0x7c, /* 01111100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 161 0xa1 '¡' */
-	0x00, /* 00000000 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x00, /* 00000000 */
-	0x38, /* 00111000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 162 0xa2 '¢' */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x60, /* 01100000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 163 0xa3 '£' */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x60, /* 01100000 */
-	0x00, /* 00000000 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 164 0xa4 '¤' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x76, /* 01110110 */
-	0xdc, /* 11011100 */
-	0x00, /* 00000000 */
-	0xdc, /* 11011100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 165 0xa5 '¥' */
-	0x76, /* 01110110 */
-	0xdc, /* 11011100 */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0xe6, /* 11100110 */
-	0xf6, /* 11110110 */
-	0xfe, /* 11111110 */
-	0xde, /* 11011110 */
-	0xce, /* 11001110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 166 0xa6 '¦' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x3c, /* 00111100 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0x3e, /* 00111110 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 167 0xa7 '§' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0x38, /* 00111000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 168 0xa8 '¨' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x00, /* 00000000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x60, /* 01100000 */
-	0xc0, /* 11000000 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 169 0xa9 '©' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 170 0xaa 'ª' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0x06, /* 00000110 */
-	0x06, /* 00000110 */
-	0x06, /* 00000110 */
-	0x06, /* 00000110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 171 0xab '«' */
-	0x00, /* 00000000 */
-	0x60, /* 01100000 */
-	0xe0, /* 11100000 */
-	0x62, /* 01100010 */
-	0x66, /* 01100110 */
-	0x6c, /* 01101100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x60, /* 01100000 */
-	0xdc, /* 11011100 */
-	0x86, /* 10000110 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x3e, /* 00111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 172 0xac '¬' */
-	0x00, /* 00000000 */
-	0x60, /* 01100000 */
-	0xe0, /* 11100000 */
-	0x62, /* 01100010 */
-	0x66, /* 01100110 */
-	0x6c, /* 01101100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x66, /* 01100110 */
-	0xce, /* 11001110 */
-	0x9a, /* 10011010 */
-	0x3f, /* 00111111 */
-	0x06, /* 00000110 */
-	0x06, /* 00000110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 173 0xad '­' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x3c, /* 00111100 */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 174 0xae '®' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x36, /* 00110110 */
-	0x6c, /* 01101100 */
-	0xd8, /* 11011000 */
-	0x6c, /* 01101100 */
-	0x36, /* 00110110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 175 0xaf '¯' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xd8, /* 11011000 */
-	0x6c, /* 01101100 */
-	0x36, /* 00110110 */
-	0x6c, /* 01101100 */
-	0xd8, /* 11011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 176 0xb0 '°' */
-	0x11, /* 00010001 */
-	0x44, /* 01000100 */
-	0x11, /* 00010001 */
-	0x44, /* 01000100 */
-	0x11, /* 00010001 */
-	0x44, /* 01000100 */
-	0x11, /* 00010001 */
-	0x44, /* 01000100 */
-	0x11, /* 00010001 */
-	0x44, /* 01000100 */
-	0x11, /* 00010001 */
-	0x44, /* 01000100 */
-	0x11, /* 00010001 */
-	0x44, /* 01000100 */
-	0x11, /* 00010001 */
-	0x44, /* 01000100 */
-
-	/* 177 0xb1 '±' */
-	0x55, /* 01010101 */
-	0xaa, /* 10101010 */
-	0x55, /* 01010101 */
-	0xaa, /* 10101010 */
-	0x55, /* 01010101 */
-	0xaa, /* 10101010 */
-	0x55, /* 01010101 */
-	0xaa, /* 10101010 */
-	0x55, /* 01010101 */
-	0xaa, /* 10101010 */
-	0x55, /* 01010101 */
-	0xaa, /* 10101010 */
-	0x55, /* 01010101 */
-	0xaa, /* 10101010 */
-	0x55, /* 01010101 */
-	0xaa, /* 10101010 */
-
-	/* 178 0xb2 '²' */
-	0xdd, /* 11011101 */
-	0x77, /* 01110111 */
-	0xdd, /* 11011101 */
-	0x77, /* 01110111 */
-	0xdd, /* 11011101 */
-	0x77, /* 01110111 */
-	0xdd, /* 11011101 */
-	0x77, /* 01110111 */
-	0xdd, /* 11011101 */
-	0x77, /* 01110111 */
-	0xdd, /* 11011101 */
-	0x77, /* 01110111 */
-	0xdd, /* 11011101 */
-	0x77, /* 01110111 */
-	0xdd, /* 11011101 */
-	0x77, /* 01110111 */
-
-	/* 179 0xb3 '³' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 180 0xb4 '´' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0xf8, /* 11111000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 181 0xb5 'µ' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0xf8, /* 11111000 */
-	0x18, /* 00011000 */
-	0xf8, /* 11111000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 182 0xb6 '¶' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0xf6, /* 11110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 183 0xb7 '·' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 184 0xb8 '¸' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xf8, /* 11111000 */
-	0x18, /* 00011000 */
-	0xf8, /* 11111000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 185 0xb9 '¹' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0xf6, /* 11110110 */
-	0x06, /* 00000110 */
-	0xf6, /* 11110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 186 0xba 'º' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 187 0xbb '»' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0x06, /* 00000110 */
-	0xf6, /* 11110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 188 0xbc '¼' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0xf6, /* 11110110 */
-	0x06, /* 00000110 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 189 0xbd '½' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 190 0xbe '¾' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0xf8, /* 11111000 */
-	0x18, /* 00011000 */
-	0xf8, /* 11111000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 191 0xbf '¿' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xf8, /* 11111000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 192 0xc0 'À' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x1f, /* 00011111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 193 0xc1 'Á' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 194 0xc2 'Â' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 195 0xc3 'Ã' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x1f, /* 00011111 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 196 0xc4 'Ä' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 197 0xc5 'Å' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0xff, /* 11111111 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 198 0xc6 'Æ' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x1f, /* 00011111 */
-	0x18, /* 00011000 */
-	0x1f, /* 00011111 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 199 0xc7 'Ç' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x37, /* 00110111 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 200 0xc8 'È' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x37, /* 00110111 */
-	0x30, /* 00110000 */
-	0x3f, /* 00111111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 201 0xc9 'É' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x3f, /* 00111111 */
-	0x30, /* 00110000 */
-	0x37, /* 00110111 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 202 0xca 'Ê' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0xf7, /* 11110111 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 203 0xcb 'Ë' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0xf7, /* 11110111 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 204 0xcc 'Ì' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x37, /* 00110111 */
-	0x30, /* 00110000 */
-	0x37, /* 00110111 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 205 0xcd 'Í' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 206 0xce 'Î' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0xf7, /* 11110111 */
-	0x00, /* 00000000 */
-	0xf7, /* 11110111 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 207 0xcf 'Ï' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 208 0xd0 'Ð' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 209 0xd1 'Ñ' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 210 0xd2 'Ò' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 211 0xd3 'Ó' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x3f, /* 00111111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 212 0xd4 'Ô' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x1f, /* 00011111 */
-	0x18, /* 00011000 */
-	0x1f, /* 00011111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 213 0xd5 'Õ' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x1f, /* 00011111 */
-	0x18, /* 00011000 */
-	0x1f, /* 00011111 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 214 0xd6 'Ö' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x3f, /* 00111111 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 215 0xd7 '×' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0xff, /* 11111111 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 216 0xd8 'Ø' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0xff, /* 11111111 */
-	0x18, /* 00011000 */
-	0xff, /* 11111111 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 217 0xd9 'Ù' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0xf8, /* 11111000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 218 0xda 'Ú' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x1f, /* 00011111 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 219 0xdb 'Û' */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-
-	/* 220 0xdc 'Ü' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-
-	/* 221 0xdd 'Ý' */
-	0xf0, /* 11110000 */
-	0xf0, /* 11110000 */
-	0xf0, /* 11110000 */
-	0xf0, /* 11110000 */
-	0xf0, /* 11110000 */
-	0xf0, /* 11110000 */
-	0xf0, /* 11110000 */
-	0xf0, /* 11110000 */
-	0xf0, /* 11110000 */
-	0xf0, /* 11110000 */
-	0xf0, /* 11110000 */
-	0xf0, /* 11110000 */
-	0xf0, /* 11110000 */
-	0xf0, /* 11110000 */
-	0xf0, /* 11110000 */
-	0xf0, /* 11110000 */
-
-	/* 222 0xde 'Þ' */
-	0x0f, /* 00001111 */
-	0x0f, /* 00001111 */
-	0x0f, /* 00001111 */
-	0x0f, /* 00001111 */
-	0x0f, /* 00001111 */
-	0x0f, /* 00001111 */
-	0x0f, /* 00001111 */
-	0x0f, /* 00001111 */
-	0x0f, /* 00001111 */
-	0x0f, /* 00001111 */
-	0x0f, /* 00001111 */
-	0x0f, /* 00001111 */
-	0x0f, /* 00001111 */
-	0x0f, /* 00001111 */
-	0x0f, /* 00001111 */
-	0x0f, /* 00001111 */
-
-	/* 223 0xdf 'ß' */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 224 0xe0 'à' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x76, /* 01110110 */
-	0xdc, /* 11011100 */
-	0xd8, /* 11011000 */
-	0xd8, /* 11011000 */
-	0xd8, /* 11011000 */
-	0xdc, /* 11011100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 225 0xe1 'á' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x78, /* 01111000 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xd8, /* 11011000 */
-	0xcc, /* 11001100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xcc, /* 11001100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 226 0xe2 'â' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 227 0xe3 'ã' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 228 0xe4 'ä' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0xc6, /* 11000110 */
-	0x60, /* 01100000 */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x60, /* 01100000 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 229 0xe5 'å' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0xd8, /* 11011000 */
-	0xd8, /* 11011000 */
-	0xd8, /* 11011000 */
-	0xd8, /* 11011000 */
-	0xd8, /* 11011000 */
-	0x70, /* 01110000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 230 0xe6 'æ' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x7c, /* 01111100 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0xc0, /* 11000000 */
-	0x00, /* 00000000 */
-
-	/* 231 0xe7 'ç' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x76, /* 01110110 */
-	0xdc, /* 11011100 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 232 0xe8 'è' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 233 0xe9 'é' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x6c, /* 01101100 */
-	0x38, /* 00111000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 234 0xea 'ê' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0xee, /* 11101110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 235 0xeb 'ë' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x1e, /* 00011110 */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x0c, /* 00001100 */
-	0x3e, /* 00111110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 236 0xec 'ì' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0xdb, /* 11011011 */
-	0xdb, /* 11011011 */
-	0xdb, /* 11011011 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 237 0xed 'í' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x03, /* 00000011 */
-	0x06, /* 00000110 */
-	0x7e, /* 01111110 */
-	0xdb, /* 11011011 */
-	0xdb, /* 11011011 */
-	0xf3, /* 11110011 */
-	0x7e, /* 01111110 */
-	0x60, /* 01100000 */
-	0xc0, /* 11000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 238 0xee 'î' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x1c, /* 00011100 */
-	0x30, /* 00110000 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0x7c, /* 01111100 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0x30, /* 00110000 */
-	0x1c, /* 00011100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 239 0xef 'ï' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 240 0xf0 'ð' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 241 0xf1 'ñ' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x7e, /* 01111110 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 242 0xf2 'ò' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x0c, /* 00001100 */
-	0x06, /* 00000110 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 243 0xf3 'ó' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x60, /* 01100000 */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x0c, /* 00001100 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 244 0xf4 'ô' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x0e, /* 00001110 */
-	0x1b, /* 00011011 */
-	0x1b, /* 00011011 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 245 0xf5 'õ' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0xd8, /* 11011000 */
-	0xd8, /* 11011000 */
-	0xd8, /* 11011000 */
-	0x70, /* 01110000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 246 0xf6 'ö' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 247 0xf7 '÷' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x76, /* 01110110 */
-	0xdc, /* 11011100 */
-	0x00, /* 00000000 */
-	0x76, /* 01110110 */
-	0xdc, /* 11011100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 248 0xf8 'ø' */
-	0x00, /* 00000000 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0x38, /* 00111000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 249 0xf9 'ù' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 250 0xfa 'ú' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 251 0xfb 'û' */
-	0x00, /* 00000000 */
-	0x0f, /* 00001111 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0xec, /* 11101100 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0x3c, /* 00111100 */
-	0x1c, /* 00011100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 252 0xfc 'ü' */
-	0x00, /* 00000000 */
-	0x6c, /* 01101100 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 253 0xfd 'ý' */
-	0x00, /* 00000000 */
-	0x3c, /* 00111100 */
-	0x66, /* 01100110 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x32, /* 00110010 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 254 0xfe 'þ' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0x7e, /* 01111110 */
-	0x7e, /* 01111110 */
-	0x7e, /* 01111110 */
-	0x7e, /* 01111110 */
-	0x7e, /* 01111110 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 255 0xff 'ÿ' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-};
-
-
-struct fbcon_font_desc font_vga_8x16 = {
-	VGA8x16_IDX,
-	"VGA8x16",
-	8,
-	16,
-	fontdata_8x16,
-	0
-};
diff -Nru a/drivers/video/font_8x8.c b/drivers/video/font_8x8.c
--- a/drivers/video/font_8x8.c	Mon Dec  9 18:46:51 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,2583 +0,0 @@
-/**********************************************/
-/*                                            */
-/*       Font file generated by cpi2fnt       */
-/*                                            */
-/**********************************************/
-
-#include <video/font.h>
-
-#define FONTDATAMAX 2048
-
-static unsigned char fontdata_8x8[FONTDATAMAX] = {
-
-	/* 0 0x00 '^@' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 1 0x01 '^A' */
-	0x7e, /* 01111110 */
-	0x81, /* 10000001 */
-	0xa5, /* 10100101 */
-	0x81, /* 10000001 */
-	0xbd, /* 10111101 */
-	0x99, /* 10011001 */
-	0x81, /* 10000001 */
-	0x7e, /* 01111110 */
-
-	/* 2 0x02 '^B' */
-	0x7e, /* 01111110 */
-	0xff, /* 11111111 */
-	0xdb, /* 11011011 */
-	0xff, /* 11111111 */
-	0xc3, /* 11000011 */
-	0xe7, /* 11100111 */
-	0xff, /* 11111111 */
-	0x7e, /* 01111110 */
-
-	/* 3 0x03 '^C' */
-	0x6c, /* 01101100 */
-	0xfe, /* 11111110 */
-	0xfe, /* 11111110 */
-	0xfe, /* 11111110 */
-	0x7c, /* 01111100 */
-	0x38, /* 00111000 */
-	0x10, /* 00010000 */
-	0x00, /* 00000000 */
-
-	/* 4 0x04 '^D' */
-	0x10, /* 00010000 */
-	0x38, /* 00111000 */
-	0x7c, /* 01111100 */
-	0xfe, /* 11111110 */
-	0x7c, /* 01111100 */
-	0x38, /* 00111000 */
-	0x10, /* 00010000 */
-	0x00, /* 00000000 */
-
-	/* 5 0x05 '^E' */
-	0x38, /* 00111000 */
-	0x7c, /* 01111100 */
-	0x38, /* 00111000 */
-	0xfe, /* 11111110 */
-	0xfe, /* 11111110 */
-	0xd6, /* 11010110 */
-	0x10, /* 00010000 */
-	0x38, /* 00111000 */
-
-	/* 6 0x06 '^F' */
-	0x10, /* 00010000 */
-	0x38, /* 00111000 */
-	0x7c, /* 01111100 */
-	0xfe, /* 11111110 */
-	0xfe, /* 11111110 */
-	0x7c, /* 01111100 */
-	0x10, /* 00010000 */
-	0x38, /* 00111000 */
-
-	/* 7 0x07 '^G' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 8 0x08 '^H' */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xe7, /* 11100111 */
-	0xc3, /* 11000011 */
-	0xc3, /* 11000011 */
-	0xe7, /* 11100111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-
-	/* 9 0x09 '^I' */
-	0x00, /* 00000000 */
-	0x3c, /* 00111100 */
-	0x66, /* 01100110 */
-	0x42, /* 01000010 */
-	0x42, /* 01000010 */
-	0x66, /* 01100110 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-
-	/* 10 0x0a '^J' */
-	0xff, /* 11111111 */
-	0xc3, /* 11000011 */
-	0x99, /* 10011001 */
-	0xbd, /* 10111101 */
-	0xbd, /* 10111101 */
-	0x99, /* 10011001 */
-	0xc3, /* 11000011 */
-	0xff, /* 11111111 */
-
-	/* 11 0x0b '^K' */
-	0x0f, /* 00001111 */
-	0x07, /* 00000111 */
-	0x0f, /* 00001111 */
-	0x7d, /* 01111101 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x78, /* 01111000 */
-
-	/* 12 0x0c '^L' */
-	0x3c, /* 00111100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-	0x7e, /* 01111110 */
-	0x18, /* 00011000 */
-
-	/* 13 0x0d '^M' */
-	0x3f, /* 00111111 */
-	0x33, /* 00110011 */
-	0x3f, /* 00111111 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x70, /* 01110000 */
-	0xf0, /* 11110000 */
-	0xe0, /* 11100000 */
-
-	/* 14 0x0e '^N' */
-	0x7f, /* 01111111 */
-	0x63, /* 01100011 */
-	0x7f, /* 01111111 */
-	0x63, /* 01100011 */
-	0x63, /* 01100011 */
-	0x67, /* 01100111 */
-	0xe6, /* 11100110 */
-	0xc0, /* 11000000 */
-
-	/* 15 0x0f '^O' */
-	0x18, /* 00011000 */
-	0xdb, /* 11011011 */
-	0x3c, /* 00111100 */
-	0xe7, /* 11100111 */
-	0xe7, /* 11100111 */
-	0x3c, /* 00111100 */
-	0xdb, /* 11011011 */
-	0x18, /* 00011000 */
-
-	/* 16 0x10 '^P' */
-	0x80, /* 10000000 */
-	0xe0, /* 11100000 */
-	0xf8, /* 11111000 */
-	0xfe, /* 11111110 */
-	0xf8, /* 11111000 */
-	0xe0, /* 11100000 */
-	0x80, /* 10000000 */
-	0x00, /* 00000000 */
-
-	/* 17 0x11 '^Q' */
-	0x02, /* 00000010 */
-	0x0e, /* 00001110 */
-	0x3e, /* 00111110 */
-	0xfe, /* 11111110 */
-	0x3e, /* 00111110 */
-	0x0e, /* 00001110 */
-	0x02, /* 00000010 */
-	0x00, /* 00000000 */
-
-	/* 18 0x12 '^R' */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x7e, /* 01111110 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x7e, /* 01111110 */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-
-	/* 19 0x13 '^S' */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x00, /* 00000000 */
-	0x66, /* 01100110 */
-	0x00, /* 00000000 */
-
-	/* 20 0x14 '^T' */
-	0x7f, /* 01111111 */
-	0xdb, /* 11011011 */
-	0xdb, /* 11011011 */
-	0x7b, /* 01111011 */
-	0x1b, /* 00011011 */
-	0x1b, /* 00011011 */
-	0x1b, /* 00011011 */
-	0x00, /* 00000000 */
-
-	/* 21 0x15 '^U' */
-	0x3e, /* 00111110 */
-	0x61, /* 01100001 */
-	0x3c, /* 00111100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x3c, /* 00111100 */
-	0x86, /* 10000110 */
-	0x7c, /* 01111100 */
-
-	/* 22 0x16 '^V' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0x7e, /* 01111110 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-
-	/* 23 0x17 '^W' */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x7e, /* 01111110 */
-	0x18, /* 00011000 */
-	0x7e, /* 01111110 */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-	0xff, /* 11111111 */
-
-	/* 24 0x18 '^X' */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x7e, /* 01111110 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-
-	/* 25 0x19 '^Y' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x7e, /* 01111110 */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-
-	/* 26 0x1a '^Z' */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x0c, /* 00001100 */
-	0xfe, /* 11111110 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 27 0x1b '^[' */
-	0x00, /* 00000000 */
-	0x30, /* 00110000 */
-	0x60, /* 01100000 */
-	0xfe, /* 11111110 */
-	0x60, /* 01100000 */
-	0x30, /* 00110000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 28 0x1c '^\' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 29 0x1d '^]' */
-	0x00, /* 00000000 */
-	0x24, /* 00100100 */
-	0x66, /* 01100110 */
-	0xff, /* 11111111 */
-	0x66, /* 01100110 */
-	0x24, /* 00100100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 30 0x1e '^^' */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x7e, /* 01111110 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 31 0x1f '^_' */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0x7e, /* 01111110 */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 32 0x20 ' ' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 33 0x21 '!' */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-
-	/* 34 0x22 '"' */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x24, /* 00100100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 35 0x23 '#' */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0xfe, /* 11111110 */
-	0x6c, /* 01101100 */
-	0xfe, /* 11111110 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0x00, /* 00000000 */
-
-	/* 36 0x24 '$' */
-	0x18, /* 00011000 */
-	0x3e, /* 00111110 */
-	0x60, /* 01100000 */
-	0x3c, /* 00111100 */
-	0x06, /* 00000110 */
-	0x7c, /* 01111100 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-
-	/* 37 0x25 '%' */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0xcc, /* 11001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x66, /* 01100110 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-
-	/* 38 0x26 '&' */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0x38, /* 00111000 */
-	0x76, /* 01110110 */
-	0xdc, /* 11011100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-
-	/* 39 0x27 ''' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 40 0x28 '(' */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x0c, /* 00001100 */
-	0x00, /* 00000000 */
-
-	/* 41 0x29 ')' */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x00, /* 00000000 */
-
-	/* 42 0x2a '*' */
-	0x00, /* 00000000 */
-	0x66, /* 01100110 */
-	0x3c, /* 00111100 */
-	0xff, /* 11111111 */
-	0x3c, /* 00111100 */
-	0x66, /* 01100110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 43 0x2b '+' */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x7e, /* 01111110 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 44 0x2c ',' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-
-	/* 45 0x2d '-' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 46 0x2e '.' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-
-	/* 47 0x2f '/' */
-	0x06, /* 00000110 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x60, /* 01100000 */
-	0xc0, /* 11000000 */
-	0x80, /* 10000000 */
-	0x00, /* 00000000 */
-
-	/* 48 0x30 '0' */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0xc6, /* 11000110 */
-	0xd6, /* 11010110 */
-	0xc6, /* 11000110 */
-	0x6c, /* 01101100 */
-	0x38, /* 00111000 */
-	0x00, /* 00000000 */
-
-	/* 49 0x31 '1' */
-	0x18, /* 00011000 */
-	0x38, /* 00111000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-
-	/* 50 0x32 '2' */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0x06, /* 00000110 */
-	0x1c, /* 00011100 */
-	0x30, /* 00110000 */
-	0x66, /* 01100110 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-
-	/* 51 0x33 '3' */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0x06, /* 00000110 */
-	0x3c, /* 00111100 */
-	0x06, /* 00000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-
-	/* 52 0x34 '4' */
-	0x1c, /* 00011100 */
-	0x3c, /* 00111100 */
-	0x6c, /* 01101100 */
-	0xcc, /* 11001100 */
-	0xfe, /* 11111110 */
-	0x0c, /* 00001100 */
-	0x1e, /* 00011110 */
-	0x00, /* 00000000 */
-
-	/* 53 0x35 '5' */
-	0xfe, /* 11111110 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xfc, /* 11111100 */
-	0x06, /* 00000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-
-	/* 54 0x36 '6' */
-	0x38, /* 00111000 */
-	0x60, /* 01100000 */
-	0xc0, /* 11000000 */
-	0xfc, /* 11111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-
-	/* 55 0x37 '7' */
-	0xfe, /* 11111110 */
-	0xc6, /* 11000110 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x00, /* 00000000 */
-
-	/* 56 0x38 '8' */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-
-	/* 57 0x39 '9' */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7e, /* 01111110 */
-	0x06, /* 00000110 */
-	0x0c, /* 00001100 */
-	0x78, /* 01111000 */
-	0x00, /* 00000000 */
-
-	/* 58 0x3a ':' */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-
-	/* 59 0x3b ';' */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-
-	/* 60 0x3c '<' */
-	0x06, /* 00000110 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x0c, /* 00001100 */
-	0x06, /* 00000110 */
-	0x00, /* 00000000 */
-
-	/* 61 0x3d '=' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 62 0x3e '>' */
-	0x60, /* 01100000 */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x60, /* 01100000 */
-	0x00, /* 00000000 */
-
-	/* 63 0x3f '?' */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-
-	/* 64 0x40 '@' */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xde, /* 11011110 */
-	0xde, /* 11011110 */
-	0xde, /* 11011110 */
-	0xc0, /* 11000000 */
-	0x78, /* 01111000 */
-	0x00, /* 00000000 */
-
-	/* 65 0x41 'A' */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-
-	/* 66 0x42 'B' */
-	0xfc, /* 11111100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x7c, /* 01111100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0xfc, /* 11111100 */
-	0x00, /* 00000000 */
-
-	/* 67 0x43 'C' */
-	0x3c, /* 00111100 */
-	0x66, /* 01100110 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0x66, /* 01100110 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-
-	/* 68 0x44 'D' */
-	0xf8, /* 11111000 */
-	0x6c, /* 01101100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x6c, /* 01101100 */
-	0xf8, /* 11111000 */
-	0x00, /* 00000000 */
-
-	/* 69 0x45 'E' */
-	0xfe, /* 11111110 */
-	0x62, /* 01100010 */
-	0x68, /* 01101000 */
-	0x78, /* 01111000 */
-	0x68, /* 01101000 */
-	0x62, /* 01100010 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-
-	/* 70 0x46 'F' */
-	0xfe, /* 11111110 */
-	0x62, /* 01100010 */
-	0x68, /* 01101000 */
-	0x78, /* 01111000 */
-	0x68, /* 01101000 */
-	0x60, /* 01100000 */
-	0xf0, /* 11110000 */
-	0x00, /* 00000000 */
-
-	/* 71 0x47 'G' */
-	0x3c, /* 00111100 */
-	0x66, /* 01100110 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xce, /* 11001110 */
-	0x66, /* 01100110 */
-	0x3a, /* 00111010 */
-	0x00, /* 00000000 */
-
-	/* 72 0x48 'H' */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-
-	/* 73 0x49 'I' */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-
-	/* 74 0x4a 'J' */
-	0x1e, /* 00011110 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x78, /* 01111000 */
-	0x00, /* 00000000 */
-
-	/* 75 0x4b 'K' */
-	0xe6, /* 11100110 */
-	0x66, /* 01100110 */
-	0x6c, /* 01101100 */
-	0x78, /* 01111000 */
-	0x6c, /* 01101100 */
-	0x66, /* 01100110 */
-	0xe6, /* 11100110 */
-	0x00, /* 00000000 */
-
-	/* 76 0x4c 'L' */
-	0xf0, /* 11110000 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0x62, /* 01100010 */
-	0x66, /* 01100110 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-
-	/* 77 0x4d 'M' */
-	0xc6, /* 11000110 */
-	0xee, /* 11101110 */
-	0xfe, /* 11111110 */
-	0xfe, /* 11111110 */
-	0xd6, /* 11010110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-
-	/* 78 0x4e 'N' */
-	0xc6, /* 11000110 */
-	0xe6, /* 11100110 */
-	0xf6, /* 11110110 */
-	0xde, /* 11011110 */
-	0xce, /* 11001110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-
-	/* 79 0x4f 'O' */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-
-	/* 80 0x50 'P' */
-	0xfc, /* 11111100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x7c, /* 01111100 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0xf0, /* 11110000 */
-	0x00, /* 00000000 */
-
-	/* 81 0x51 'Q' */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xce, /* 11001110 */
-	0x7c, /* 01111100 */
-	0x0e, /* 00001110 */
-
-	/* 82 0x52 'R' */
-	0xfc, /* 11111100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x7c, /* 01111100 */
-	0x6c, /* 01101100 */
-	0x66, /* 01100110 */
-	0xe6, /* 11100110 */
-	0x00, /* 00000000 */
-
-	/* 83 0x53 'S' */
-	0x3c, /* 00111100 */
-	0x66, /* 01100110 */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x0c, /* 00001100 */
-	0x66, /* 01100110 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-
-	/* 84 0x54 'T' */
-	0x7e, /* 01111110 */
-	0x7e, /* 01111110 */
-	0x5a, /* 01011010 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-
-	/* 85 0x55 'U' */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-
-	/* 86 0x56 'V' */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x6c, /* 01101100 */
-	0x38, /* 00111000 */
-	0x00, /* 00000000 */
-
-	/* 87 0x57 'W' */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xd6, /* 11010110 */
-	0xd6, /* 11010110 */
-	0xfe, /* 11111110 */
-	0x6c, /* 01101100 */
-	0x00, /* 00000000 */
-
-	/* 88 0x58 'X' */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x6c, /* 01101100 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-
-	/* 89 0x59 'Y' */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-
-	/* 90 0x5a 'Z' */
-	0xfe, /* 11111110 */
-	0xc6, /* 11000110 */
-	0x8c, /* 10001100 */
-	0x18, /* 00011000 */
-	0x32, /* 00110010 */
-	0x66, /* 01100110 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-
-	/* 91 0x5b '[' */
-	0x3c, /* 00111100 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-
-	/* 92 0x5c '\' */
-	0xc0, /* 11000000 */
-	0x60, /* 01100000 */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x0c, /* 00001100 */
-	0x06, /* 00000110 */
-	0x02, /* 00000010 */
-	0x00, /* 00000000 */
-
-	/* 93 0x5d ']' */
-	0x3c, /* 00111100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-
-	/* 94 0x5e '^' */
-	0x10, /* 00010000 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 95 0x5f '_' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-
-	/* 96 0x60 '`' */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x0c, /* 00001100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 97 0x61 'a' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x78, /* 01111000 */
-	0x0c, /* 00001100 */
-	0x7c, /* 01111100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-
-	/* 98 0x62 'b' */
-	0xe0, /* 11100000 */
-	0x60, /* 01100000 */
-	0x7c, /* 01111100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0xdc, /* 11011100 */
-	0x00, /* 00000000 */
-
-	/* 99 0x63 'c' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc0, /* 11000000 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-
-	/* 100 0x64 'd' */
-	0x1c, /* 00011100 */
-	0x0c, /* 00001100 */
-	0x7c, /* 01111100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-
-	/* 101 0x65 'e' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0xc0, /* 11000000 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-
-	/* 102 0x66 'f' */
-	0x3c, /* 00111100 */
-	0x66, /* 01100110 */
-	0x60, /* 01100000 */
-	0xf8, /* 11111000 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0xf0, /* 11110000 */
-	0x00, /* 00000000 */
-
-	/* 103 0x67 'g' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x76, /* 01110110 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x7c, /* 01111100 */
-	0x0c, /* 00001100 */
-	0xf8, /* 11111000 */
-
-	/* 104 0x68 'h' */
-	0xe0, /* 11100000 */
-	0x60, /* 01100000 */
-	0x6c, /* 01101100 */
-	0x76, /* 01110110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0xe6, /* 11100110 */
-	0x00, /* 00000000 */
-
-	/* 105 0x69 'i' */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x38, /* 00111000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-
-	/* 106 0x6a 'j' */
-	0x06, /* 00000110 */
-	0x00, /* 00000000 */
-	0x06, /* 00000110 */
-	0x06, /* 00000110 */
-	0x06, /* 00000110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x3c, /* 00111100 */
-
-	/* 107 0x6b 'k' */
-	0xe0, /* 11100000 */
-	0x60, /* 01100000 */
-	0x66, /* 01100110 */
-	0x6c, /* 01101100 */
-	0x78, /* 01111000 */
-	0x6c, /* 01101100 */
-	0xe6, /* 11100110 */
-	0x00, /* 00000000 */
-
-	/* 108 0x6c 'l' */
-	0x38, /* 00111000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-
-	/* 109 0x6d 'm' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xec, /* 11101100 */
-	0xfe, /* 11111110 */
-	0xd6, /* 11010110 */
-	0xd6, /* 11010110 */
-	0xd6, /* 11010110 */
-	0x00, /* 00000000 */
-
-	/* 110 0x6e 'n' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xdc, /* 11011100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x00, /* 00000000 */
-
-	/* 111 0x6f 'o' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-
-	/* 112 0x70 'p' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xdc, /* 11011100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x7c, /* 01111100 */
-	0x60, /* 01100000 */
-	0xf0, /* 11110000 */
-
-	/* 113 0x71 'q' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x76, /* 01110110 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x7c, /* 01111100 */
-	0x0c, /* 00001100 */
-	0x1e, /* 00011110 */
-
-	/* 114 0x72 'r' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xdc, /* 11011100 */
-	0x76, /* 01110110 */
-	0x60, /* 01100000 */
-	0x60, /* 01100000 */
-	0xf0, /* 11110000 */
-	0x00, /* 00000000 */
-
-	/* 115 0x73 's' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0xc0, /* 11000000 */
-	0x7c, /* 01111100 */
-	0x06, /* 00000110 */
-	0xfc, /* 11111100 */
-	0x00, /* 00000000 */
-
-	/* 116 0x74 't' */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0xfc, /* 11111100 */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x36, /* 00110110 */
-	0x1c, /* 00011100 */
-	0x00, /* 00000000 */
-
-	/* 117 0x75 'u' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-
-	/* 118 0x76 'v' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x6c, /* 01101100 */
-	0x38, /* 00111000 */
-	0x00, /* 00000000 */
-
-	/* 119 0x77 'w' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0xd6, /* 11010110 */
-	0xd6, /* 11010110 */
-	0xfe, /* 11111110 */
-	0x6c, /* 01101100 */
-	0x00, /* 00000000 */
-
-	/* 120 0x78 'x' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0x6c, /* 01101100 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-
-	/* 121 0x79 'y' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7e, /* 01111110 */
-	0x06, /* 00000110 */
-	0xfc, /* 11111100 */
-
-	/* 122 0x7a 'z' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0x4c, /* 01001100 */
-	0x18, /* 00011000 */
-	0x32, /* 00110010 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-
-	/* 123 0x7b '{' */
-	0x0e, /* 00001110 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x70, /* 01110000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x0e, /* 00001110 */
-	0x00, /* 00000000 */
-
-	/* 124 0x7c '|' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-
-	/* 125 0x7d '}' */
-	0x70, /* 01110000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x0e, /* 00001110 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x70, /* 01110000 */
-	0x00, /* 00000000 */
-
-	/* 126 0x7e '~' */
-	0x76, /* 01110110 */
-	0xdc, /* 11011100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 127 0x7f '' */
-	0x00, /* 00000000 */
-	0x10, /* 00010000 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-
-	/* 128 0x80 '€' */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x0c, /* 00001100 */
-	0x78, /* 01111000 */
-
-	/* 129 0x81 '�' */
-	0xcc, /* 11001100 */
-	0x00, /* 00000000 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-
-	/* 130 0x82 '‚' */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0xc0, /* 11000000 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-
-	/* 131 0x83 'ƒ' */
-	0x7c, /* 01111100 */
-	0x82, /* 10000010 */
-	0x78, /* 01111000 */
-	0x0c, /* 00001100 */
-	0x7c, /* 01111100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-
-	/* 132 0x84 '„' */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0x78, /* 01111000 */
-	0x0c, /* 00001100 */
-	0x7c, /* 01111100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-
-	/* 133 0x85 '…' */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x78, /* 01111000 */
-	0x0c, /* 00001100 */
-	0x7c, /* 01111100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-
-	/* 134 0x86 '†' */
-	0x30, /* 00110000 */
-	0x30, /* 00110000 */
-	0x78, /* 01111000 */
-	0x0c, /* 00001100 */
-	0x7c, /* 01111100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-
-	/* 135 0x87 '‡' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0x7e, /* 01111110 */
-	0x0c, /* 00001100 */
-	0x38, /* 00111000 */
-
-	/* 136 0x88 'ˆ' */
-	0x7c, /* 01111100 */
-	0x82, /* 10000010 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0xc0, /* 11000000 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-
-	/* 137 0x89 '‰' */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0xc0, /* 11000000 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-
-	/* 138 0x8a 'Š' */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0xc0, /* 11000000 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-
-	/* 139 0x8b '‹' */
-	0x66, /* 01100110 */
-	0x00, /* 00000000 */
-	0x38, /* 00111000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-
-	/* 140 0x8c 'Œ' */
-	0x7c, /* 01111100 */
-	0x82, /* 10000010 */
-	0x38, /* 00111000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-
-	/* 141 0x8d '�' */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x38, /* 00111000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-
-	/* 142 0x8e 'Ž' */
-	0xc6, /* 11000110 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-
-	/* 143 0x8f '�' */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-
-	/* 144 0x90 '�' */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0xfe, /* 11111110 */
-	0xc0, /* 11000000 */
-	0xf8, /* 11111000 */
-	0xc0, /* 11000000 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-
-	/* 145 0x91 '‘' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0x18, /* 00011000 */
-	0x7e, /* 01111110 */
-	0xd8, /* 11011000 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-
-	/* 146 0x92 '’' */
-	0x3e, /* 00111110 */
-	0x6c, /* 01101100 */
-	0xcc, /* 11001100 */
-	0xfe, /* 11111110 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xce, /* 11001110 */
-	0x00, /* 00000000 */
-
-	/* 147 0x93 '“' */
-	0x7c, /* 01111100 */
-	0x82, /* 10000010 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-
-	/* 148 0x94 '”' */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-
-	/* 149 0x95 '•' */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-
-	/* 150 0x96 '–' */
-	0x78, /* 01111000 */
-	0x84, /* 10000100 */
-	0x00, /* 00000000 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-
-	/* 151 0x97 '—' */
-	0x60, /* 01100000 */
-	0x30, /* 00110000 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-
-	/* 152 0x98 '˜' */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7e, /* 01111110 */
-	0x06, /* 00000110 */
-	0xfc, /* 11111100 */
-
-	/* 153 0x99 '™' */
-	0xc6, /* 11000110 */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x6c, /* 01101100 */
-	0x38, /* 00111000 */
-	0x00, /* 00000000 */
-
-	/* 154 0x9a 'š' */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-
-	/* 155 0x9b '›' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x7e, /* 01111110 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0x7e, /* 01111110 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 156 0x9c 'œ' */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0x64, /* 01100100 */
-	0xf0, /* 11110000 */
-	0x60, /* 01100000 */
-	0x66, /* 01100110 */
-	0xfc, /* 11111100 */
-	0x00, /* 00000000 */
-
-	/* 157 0x9d '�' */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x3c, /* 00111100 */
-	0x7e, /* 01111110 */
-	0x18, /* 00011000 */
-	0x7e, /* 01111110 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 158 0x9e 'ž' */
-	0xf8, /* 11111000 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xfa, /* 11111010 */
-	0xc6, /* 11000110 */
-	0xcf, /* 11001111 */
-	0xc6, /* 11000110 */
-	0xc7, /* 11000111 */
-
-	/* 159 0x9f 'Ÿ' */
-	0x0e, /* 00001110 */
-	0x1b, /* 00011011 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-	0xd8, /* 11011000 */
-	0x70, /* 01110000 */
-	0x00, /* 00000000 */
-
-	/* 160 0xa0 ' ' */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x78, /* 01111000 */
-	0x0c, /* 00001100 */
-	0x7c, /* 01111100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-
-	/* 161 0xa1 '¡' */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x38, /* 00111000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-
-	/* 162 0xa2 '¢' */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-
-	/* 163 0xa3 '£' */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-
-	/* 164 0xa4 '¤' */
-	0x76, /* 01110110 */
-	0xdc, /* 11011100 */
-	0x00, /* 00000000 */
-	0xdc, /* 11011100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x00, /* 00000000 */
-
-	/* 165 0xa5 '¥' */
-	0x76, /* 01110110 */
-	0xdc, /* 11011100 */
-	0x00, /* 00000000 */
-	0xe6, /* 11100110 */
-	0xf6, /* 11110110 */
-	0xde, /* 11011110 */
-	0xce, /* 11001110 */
-	0x00, /* 00000000 */
-
-	/* 166 0xa6 '¦' */
-	0x3c, /* 00111100 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0x3e, /* 00111110 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 167 0xa7 '§' */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0x38, /* 00111000 */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 168 0xa8 '¨' */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x63, /* 01100011 */
-	0x3e, /* 00111110 */
-	0x00, /* 00000000 */
-
-	/* 169 0xa9 '©' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 170 0xaa 'ª' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0x06, /* 00000110 */
-	0x06, /* 00000110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 171 0xab '«' */
-	0x63, /* 01100011 */
-	0xe6, /* 11100110 */
-	0x6c, /* 01101100 */
-	0x7e, /* 01111110 */
-	0x33, /* 00110011 */
-	0x66, /* 01100110 */
-	0xcc, /* 11001100 */
-	0x0f, /* 00001111 */
-
-	/* 172 0xac '¬' */
-	0x63, /* 01100011 */
-	0xe6, /* 11100110 */
-	0x6c, /* 01101100 */
-	0x7a, /* 01111010 */
-	0x36, /* 00110110 */
-	0x6a, /* 01101010 */
-	0xdf, /* 11011111 */
-	0x06, /* 00000110 */
-
-	/* 173 0xad '­' */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-
-	/* 174 0xae '®' */
-	0x00, /* 00000000 */
-	0x33, /* 00110011 */
-	0x66, /* 01100110 */
-	0xcc, /* 11001100 */
-	0x66, /* 01100110 */
-	0x33, /* 00110011 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 175 0xaf '¯' */
-	0x00, /* 00000000 */
-	0xcc, /* 11001100 */
-	0x66, /* 01100110 */
-	0x33, /* 00110011 */
-	0x66, /* 01100110 */
-	0xcc, /* 11001100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 176 0xb0 '°' */
-	0x22, /* 00100010 */
-	0x88, /* 10001000 */
-	0x22, /* 00100010 */
-	0x88, /* 10001000 */
-	0x22, /* 00100010 */
-	0x88, /* 10001000 */
-	0x22, /* 00100010 */
-	0x88, /* 10001000 */
-
-	/* 177 0xb1 '±' */
-	0x55, /* 01010101 */
-	0xaa, /* 10101010 */
-	0x55, /* 01010101 */
-	0xaa, /* 10101010 */
-	0x55, /* 01010101 */
-	0xaa, /* 10101010 */
-	0x55, /* 01010101 */
-	0xaa, /* 10101010 */
-
-	/* 178 0xb2 '²' */
-	0x77, /* 01110111 */
-	0xdd, /* 11011101 */
-	0x77, /* 01110111 */
-	0xdd, /* 11011101 */
-	0x77, /* 01110111 */
-	0xdd, /* 11011101 */
-	0x77, /* 01110111 */
-	0xdd, /* 11011101 */
-
-	/* 179 0xb3 '³' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 180 0xb4 '´' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0xf8, /* 11111000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 181 0xb5 'µ' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0xf8, /* 11111000 */
-	0x18, /* 00011000 */
-	0xf8, /* 11111000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 182 0xb6 '¶' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0xf6, /* 11110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 183 0xb7 '·' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 184 0xb8 '¸' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xf8, /* 11111000 */
-	0x18, /* 00011000 */
-	0xf8, /* 11111000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 185 0xb9 '¹' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0xf6, /* 11110110 */
-	0x06, /* 00000110 */
-	0xf6, /* 11110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 186 0xba 'º' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 187 0xbb '»' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0x06, /* 00000110 */
-	0xf6, /* 11110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 188 0xbc '¼' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0xf6, /* 11110110 */
-	0x06, /* 00000110 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 189 0xbd '½' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 190 0xbe '¾' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0xf8, /* 11111000 */
-	0x18, /* 00011000 */
-	0xf8, /* 11111000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 191 0xbf '¿' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xf8, /* 11111000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 192 0xc0 'À' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x1f, /* 00011111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 193 0xc1 'Á' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 194 0xc2 'Â' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 195 0xc3 'Ã' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x1f, /* 00011111 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 196 0xc4 'Ä' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 197 0xc5 'Å' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0xff, /* 11111111 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 198 0xc6 'Æ' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x1f, /* 00011111 */
-	0x18, /* 00011000 */
-	0x1f, /* 00011111 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 199 0xc7 'Ç' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x37, /* 00110111 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 200 0xc8 'È' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x37, /* 00110111 */
-	0x30, /* 00110000 */
-	0x3f, /* 00111111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 201 0xc9 'É' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x3f, /* 00111111 */
-	0x30, /* 00110000 */
-	0x37, /* 00110111 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 202 0xca 'Ê' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0xf7, /* 11110111 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 203 0xcb 'Ë' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0xf7, /* 11110111 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 204 0xcc 'Ì' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x37, /* 00110111 */
-	0x30, /* 00110000 */
-	0x37, /* 00110111 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 205 0xcd 'Í' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 206 0xce 'Î' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0xf7, /* 11110111 */
-	0x00, /* 00000000 */
-	0xf7, /* 11110111 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 207 0xcf 'Ï' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 208 0xd0 'Ð' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 209 0xd1 'Ñ' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 210 0xd2 'Ò' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 211 0xd3 'Ó' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x3f, /* 00111111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 212 0xd4 'Ô' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x1f, /* 00011111 */
-	0x18, /* 00011000 */
-	0x1f, /* 00011111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 213 0xd5 'Õ' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x1f, /* 00011111 */
-	0x18, /* 00011000 */
-	0x1f, /* 00011111 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 214 0xd6 'Ö' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x3f, /* 00111111 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 215 0xd7 '×' */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0xff, /* 11111111 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-
-	/* 216 0xd8 'Ø' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0xff, /* 11111111 */
-	0x18, /* 00011000 */
-	0xff, /* 11111111 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 217 0xd9 'Ù' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0xf8, /* 11111000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 218 0xda 'Ú' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x1f, /* 00011111 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 219 0xdb 'Û' */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-
-	/* 220 0xdc 'Ü' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-
-	/* 221 0xdd 'Ý' */
-	0xf0, /* 11110000 */
-	0xf0, /* 11110000 */
-	0xf0, /* 11110000 */
-	0xf0, /* 11110000 */
-	0xf0, /* 11110000 */
-	0xf0, /* 11110000 */
-	0xf0, /* 11110000 */
-	0xf0, /* 11110000 */
-
-	/* 222 0xde 'Þ' */
-	0x0f, /* 00001111 */
-	0x0f, /* 00001111 */
-	0x0f, /* 00001111 */
-	0x0f, /* 00001111 */
-	0x0f, /* 00001111 */
-	0x0f, /* 00001111 */
-	0x0f, /* 00001111 */
-	0x0f, /* 00001111 */
-
-	/* 223 0xdf 'ß' */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0xff, /* 11111111 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 224 0xe0 'à' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x76, /* 01110110 */
-	0xdc, /* 11011100 */
-	0xc8, /* 11001000 */
-	0xdc, /* 11011100 */
-	0x76, /* 01110110 */
-	0x00, /* 00000000 */
-
-	/* 225 0xe1 'á' */
-	0x78, /* 01111000 */
-	0xcc, /* 11001100 */
-	0xcc, /* 11001100 */
-	0xd8, /* 11011000 */
-	0xcc, /* 11001100 */
-	0xc6, /* 11000110 */
-	0xcc, /* 11001100 */
-	0x00, /* 00000000 */
-
-	/* 226 0xe2 'â' */
-	0xfe, /* 11111110 */
-	0xc6, /* 11000110 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0xc0, /* 11000000 */
-	0x00, /* 00000000 */
-
-	/* 227 0xe3 'ã' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0x00, /* 00000000 */
-
-	/* 228 0xe4 'ä' */
-	0xfe, /* 11111110 */
-	0xc6, /* 11000110 */
-	0x60, /* 01100000 */
-	0x30, /* 00110000 */
-	0x60, /* 01100000 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-
-	/* 229 0xe5 'å' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0xd8, /* 11011000 */
-	0xd8, /* 11011000 */
-	0xd8, /* 11011000 */
-	0x70, /* 01110000 */
-	0x00, /* 00000000 */
-
-	/* 230 0xe6 'æ' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x7c, /* 01111100 */
-	0xc0, /* 11000000 */
-
-	/* 231 0xe7 'ç' */
-	0x00, /* 00000000 */
-	0x76, /* 01110110 */
-	0xdc, /* 11011100 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-
-	/* 232 0xe8 'è' */
-	0x7e, /* 01111110 */
-	0x18, /* 00011000 */
-	0x3c, /* 00111100 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x3c, /* 00111100 */
-	0x18, /* 00011000 */
-	0x7e, /* 01111110 */
-
-	/* 233 0xe9 'é' */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0xc6, /* 11000110 */
-	0xfe, /* 11111110 */
-	0xc6, /* 11000110 */
-	0x6c, /* 01101100 */
-	0x38, /* 00111000 */
-	0x00, /* 00000000 */
-
-	/* 234 0xea 'ê' */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0xee, /* 11101110 */
-	0x00, /* 00000000 */
-
-	/* 235 0xeb 'ë' */
-	0x0e, /* 00001110 */
-	0x18, /* 00011000 */
-	0x0c, /* 00001100 */
-	0x3e, /* 00111110 */
-	0x66, /* 01100110 */
-	0x66, /* 01100110 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-
-	/* 236 0xec 'ì' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0xdb, /* 11011011 */
-	0xdb, /* 11011011 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 237 0xed 'í' */
-	0x06, /* 00000110 */
-	0x0c, /* 00001100 */
-	0x7e, /* 01111110 */
-	0xdb, /* 11011011 */
-	0xdb, /* 11011011 */
-	0x7e, /* 01111110 */
-	0x60, /* 01100000 */
-	0xc0, /* 11000000 */
-
-	/* 238 0xee 'î' */
-	0x1e, /* 00011110 */
-	0x30, /* 00110000 */
-	0x60, /* 01100000 */
-	0x7e, /* 01111110 */
-	0x60, /* 01100000 */
-	0x30, /* 00110000 */
-	0x1e, /* 00011110 */
-	0x00, /* 00000000 */
-
-	/* 239 0xef 'ï' */
-	0x00, /* 00000000 */
-	0x7c, /* 01111100 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0xc6, /* 11000110 */
-	0x00, /* 00000000 */
-
-	/* 240 0xf0 'ð' */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-	0xfe, /* 11111110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 241 0xf1 'ñ' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x7e, /* 01111110 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-
-	/* 242 0xf2 'ò' */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-
-	/* 243 0xf3 'ó' */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x18, /* 00011000 */
-	0x0c, /* 00001100 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-
-	/* 244 0xf4 'ô' */
-	0x0e, /* 00001110 */
-	0x1b, /* 00011011 */
-	0x1b, /* 00011011 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-
-	/* 245 0xf5 'õ' */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0xd8, /* 11011000 */
-	0xd8, /* 11011000 */
-	0x70, /* 01110000 */
-
-	/* 246 0xf6 'ö' */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x7e, /* 01111110 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 247 0xf7 '÷' */
-	0x00, /* 00000000 */
-	0x76, /* 01110110 */
-	0xdc, /* 11011100 */
-	0x00, /* 00000000 */
-	0x76, /* 01110110 */
-	0xdc, /* 11011100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 248 0xf8 'ø' */
-	0x38, /* 00111000 */
-	0x6c, /* 01101100 */
-	0x6c, /* 01101100 */
-	0x38, /* 00111000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 249 0xf9 'ù' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 250 0xfa 'ú' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x18, /* 00011000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 251 0xfb 'û' */
-	0x0f, /* 00001111 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0x0c, /* 00001100 */
-	0xec, /* 11101100 */
-	0x6c, /* 01101100 */
-	0x3c, /* 00111100 */
-	0x1c, /* 00011100 */
-
-	/* 252 0xfc 'ü' */
-	0x6c, /* 01101100 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x36, /* 00110110 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 253 0xfd 'ý' */
-	0x78, /* 01111000 */
-	0x0c, /* 00001100 */
-	0x18, /* 00011000 */
-	0x30, /* 00110000 */
-	0x7c, /* 01111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 254 0xfe 'þ' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x3c, /* 00111100 */
-	0x3c, /* 00111100 */
-	0x3c, /* 00111100 */
-	0x3c, /* 00111100 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-	/* 255 0xff 'ÿ' */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-	0x00, /* 00000000 */
-
-};
-
-
-struct fbcon_font_desc font_vga_8x8 = {
-	VGA8x8_IDX,
-	"VGA8x8",
-	8,
-	8,
-	fontdata_8x8,
-	0
-};
diff -Nru a/drivers/video/font_acorn_8x8.c b/drivers/video/font_acorn_8x8.c
--- a/drivers/video/font_acorn_8x8.c	Mon Dec  9 18:46:36 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,277 +0,0 @@
-/* Acorn-like font definition, with PC graphics characters */
-
-#include <linux/config.h>
-
-#include <video/font.h>
-
-static unsigned char acorndata_8x8[] = {
-/* 00 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ^@ */
-/* 01 */  0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, /* ^A */
-/* 02 */  0x7e, 0xff, 0xbd, 0xff, 0xc3, 0xe7, 0xff, 0x7e, /* ^B */
-/* 03 */  0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, /* ^C */
-/* 04 */  0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, /* ^D */
-/* 05 */  0x00, 0x18, 0x3c, 0xe7, 0xe7, 0x3c, 0x18, 0x00, /* ^E */
-/* 06 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 07 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 08 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 09 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 0A */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 0B */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 0C */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 0D */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 0E */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 0F */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 10 */  0x00, 0x60, 0x78, 0x7e, 0x7e, 0x78, 0x60, 0x00, /* |> */
-/* 11 */  0x00, 0x06, 0x1e, 0x7e, 0x7e, 0x1e, 0x06, 0x00, /* <| */
-/* 12 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 13 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 14 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 15 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 16 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 17 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 18 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 19 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 1A */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 1B */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 1C */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 1D */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 1E */  0x00, 0x18, 0x18, 0x3c, 0x3c, 0x7e, 0x7e, 0x00, /* /\ */
-/* 1F */  0x00, 0x7e, 0x7e, 0x3c, 0x3c, 0x18, 0x18, 0x00, /* \/ */
-/* 20 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*	 */
-/* 21 */  0x18, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x00, /* ! */
-/* 22 */  0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, /* " */
-/* 23 */  0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00, /* # */
-/* 24 */  0x0C, 0x3F, 0x68, 0x3E, 0x0B, 0x7E, 0x18, 0x00, /* $ */
-/* 25 */  0x60, 0x66, 0x0C, 0x18, 0x30, 0x66, 0x06, 0x00, /* % */
-/* 26 */  0x38, 0x6C, 0x6C, 0x38, 0x6D, 0x66, 0x3B, 0x00, /* & */
-/* 27 */  0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, /* ' */
-/* 28 */  0x0C, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x00, /* ( */
-/* 29 */  0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00, /* ) */
-/* 2A */  0x00, 0x18, 0x7E, 0x3C, 0x7E, 0x18, 0x00, 0x00, /* * */
-/* 2B */  0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, /* + */
-/* 2C */  0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, /* , */
-/* 2D */  0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, /* - */
-/* 2E */  0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, /* . */
-/* 2F */  0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, /* / */
-/* 30 */  0x3C, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x3C, 0x00, /* 0 */
-/* 31 */  0x18, 0x38, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, /* 1 */
-/* 32 */  0x3C, 0x66, 0x06, 0x0C, 0x18, 0x30, 0x7E, 0x00, /* 2 */
-/* 33 */  0x3C, 0x66, 0x06, 0x1C, 0x06, 0x66, 0x3C, 0x00, /* 3 */
-/* 34 */  0x0C, 0x1C, 0x3C, 0x6C, 0x7E, 0x0C, 0x0C, 0x00, /* 4 */
-/* 35 */  0x7E, 0x60, 0x7C, 0x06, 0x06, 0x66, 0x3C, 0x00, /* 5 */
-/* 36 */  0x1C, 0x30, 0x60, 0x7C, 0x66, 0x66, 0x3C, 0x00, /* 6 */
-/* 37 */  0x7E, 0x06, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00, /* 7 */
-/* 38 */  0x3C, 0x66, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00, /* 8 */
-/* 39 */  0x3C, 0x66, 0x66, 0x3E, 0x06, 0x0C, 0x38, 0x00, /* 9 */
-/* 3A */  0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, /* : */
-/* 3B */  0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x30, /* ; */
-/* 3C */  0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x00, /* < */
-/* 3D */  0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00, /* = */ 
-/* 3E */  0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x00, /* > */
-/* 3F */  0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00, /* ? */
-/* 40 */  0x3C, 0x66, 0x6E, 0x6A, 0x6E, 0x60, 0x3C, 0x00, /* @ */
-/* 41 */  0x3C, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, /* A */
-/* 42 */  0x7C, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x7C, 0x00, /* B */
-/* 43 */  0x3C, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3C, 0x00, /* C */
-/* 44 */  0x78, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0x78, 0x00, /* D */
-/* 45 */  0x7E, 0x60, 0x60, 0x7C, 0x60, 0x60, 0x7E, 0x00, /* E */
-/* 46 */  0x7E, 0x60, 0x60, 0x7C, 0x60, 0x60, 0x60, 0x00, /* F */
-/* 47 */  0x3C, 0x66, 0x60, 0x6E, 0x66, 0x66, 0x3C, 0x00, /* G */
-/* 48 */  0x66, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, /* H */
-/* 49 */  0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, /* I */
-/* 4A */  0x3E, 0x0C, 0x0C, 0x0C, 0x0C, 0x6C, 0x38, 0x00, /* J */
-/* 4B */  0x66, 0x6C, 0x78, 0x70, 0x78, 0x6C, 0x66, 0x00, /* K */
-/* 4C */  0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7E, 0x00, /* L */
-/* 4D */  0x63, 0x77, 0x7F, 0x6B, 0x6B, 0x63, 0x63, 0x00, /* M */
-/* 4E */  0x66, 0x66, 0x76, 0x7E, 0x6E, 0x66, 0x66, 0x00, /* N */
-/* 4F */  0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, /* O */
-/* 50 */  0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0x00, /* P */
-/* 51 */  0x3C, 0x66, 0x66, 0x66, 0x6A, 0x6C, 0x36, 0x00, /* Q */
-/* 52 */  0x7C, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0x66, 0x00, /* R */
-/* 53 */  0x3C, 0x66, 0x60, 0x3C, 0x06, 0x66, 0x3C, 0x00, /* S */
-/* 54 */  0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, /* T */
-/* 55 */  0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, /* U */
-/* 56 */  0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, /* V */
-/* 57 */  0x63, 0x63, 0x6B, 0x6B, 0x7F, 0x77, 0x63, 0x00, /* W */
-/* 58 */  0x66, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00, /* X */
-/* 59 */  0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00, /* Y */
-/* 5A */  0x7E, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x7E, 0x00, /* Z */
-/* 5B */  0x7C, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7C, 0x00, /* [ */
-/* 5C */  0x00, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00, 0x00, /* \ */
-/* 5D */  0x3E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3E, 0x00, /* ] */
-/* 5E */  0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ^ */
-/* 5F */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, /* _ */
-/* 60 */  0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ` */
-/* 61 */  0x00, 0x00, 0x3C, 0x06, 0x3E, 0x66, 0x3E, 0x00, /* a */
-/* 62 */  0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x7C, 0x00, /* b */
-/* 63 */  0x00, 0x00, 0x3C, 0x66, 0x60, 0x66, 0x3C, 0x00, /* c */
-/* 64 */  0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x3E, 0x00, /* d */
-/* 65 */  0x00, 0x00, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00, /* e */
-/* 66 */  0x1C, 0x30, 0x30, 0x7C, 0x30, 0x30, 0x30, 0x00, /* f */
-/* 67 */  0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x3C, /* g */
-/* 68 */  0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x00, /* h */
-/* 69 */  0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00, /* i */
-/* 6A */  0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x70, /* j */
-/* 6B */  0x60, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0x00, /* k */
-/* 6C */  0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, /* l */
-/* 6D */  0x00, 0x00, 0x36, 0x7F, 0x6B, 0x6B, 0x63, 0x00, /* m */
-/* 6E */  0x00, 0x00, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x00, /* n */
-/* 6F */  0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00, /* o */
-/* 70 */  0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60, /* p */
-/* 71 */  0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x07, /* q */
-/* 72 */  0x00, 0x00, 0x6C, 0x76, 0x60, 0x60, 0x60, 0x00, /* r */
-/* 73 */  0x00, 0x00, 0x3E, 0x60, 0x3C, 0x06, 0x7C, 0x00, /* s */
-/* 74 */  0x30, 0x30, 0x7C, 0x30, 0x30, 0x30, 0x1C, 0x00, /* t */
-/* 75 */  0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x00, /* u */
-/* 76 */  0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, /* v */
-/* 77 */  0x00, 0x00, 0x63, 0x6B, 0x6B, 0x7F, 0x36, 0x00, /* w */
-/* 78 */  0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00, /* x */
-/* 79 */  0x00, 0x00, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x3C, /* y */
-/* 7A */  0x00, 0x00, 0x7E, 0x0C, 0x18, 0x30, 0x7E, 0x00, /* z */
-/* 7B */  0x0C, 0x18, 0x18, 0x70, 0x18, 0x18, 0x0C, 0x00, /* { */
-/* 7C */  0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, /* | */
-/* 7D */  0x30, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x30, 0x00, /* } */
-/* 7E */  0x31, 0x6B, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, /* ~ */
-/* 7F */  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  /*  */
-/* 80 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 81 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 82 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 83 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 84 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 85 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 86 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 87 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 88 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 89 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 8A */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 8B */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 8C */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 8D */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 8E */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 8F */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 90 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 91 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 92 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 93 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 94 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 95 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 96 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 97 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 98 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 99 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 9A */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 9B */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 9C */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 9D */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 9E */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* 9F */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* A0 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* A1 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* A2 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* A3 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* A4 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* A5 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* A6 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* A7 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* A8 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* A9 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* AA */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* AB */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* AC */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* AD */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* AE */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* AF */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* B0 */  0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88,
-/* B1 */  0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
-/* B2 */  0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
-/* B3 */  0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-/* B4 */  0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18,
-/* B5 */  0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18,
-/* B6 */  0x66, 0x66, 0x66, 0xe6, 0x66, 0x66, 0x66, 0x66,
-/* B7 */  0x00, 0x00, 0x00, 0xfe, 0x66, 0x66, 0x66, 0x66,
-/* B8 */  0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18,
-/* B9 */  0x66, 0x66, 0xe6, 0x06, 0xe6, 0x66, 0x66, 0x66,
-/* BA */  0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
-/* BB */  0x00, 0x00, 0xfe, 0x06, 0xe6, 0x66, 0x66, 0x66,
-/* BC */  0x66, 0x66, 0xe6, 0x06, 0xfe, 0x00, 0x00, 0x00,
-/* BD */  0x66, 0x66, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
-/* BE */  0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00,
-/* BF */  0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18,
-/* C0 */  0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00,
-/* C1 */  0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00,
-/* C2 */  0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18,
-/* C3 */  0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
-/* C4 */  0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
-/* C5 */  0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18,
-/* C6 */  0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18,
-/* C7 */  0x66, 0x66, 0x66, 0x67, 0x66, 0x66, 0x66, 0x66,
-/* C8 */  0x66, 0x66, 0x67, 0x60, 0x7f, 0x00, 0x00, 0x00,
-/* C9 */  0x00, 0x00, 0x7f, 0x60, 0x67, 0x66, 0x66, 0x66,
-/* CA */  0x66, 0x66, 0xe7, 0x00, 0xff, 0x00, 0x00, 0x00,
-/* CB */  0x00, 0x00, 0xff, 0x00, 0xe7, 0x66, 0x66, 0x66,
-/* CC */  0x66, 0x66, 0x67, 0x60, 0x67, 0x66, 0x66, 0x66,
-/* CD */  0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
-/* CE */  0x66, 0x66, 0xe7, 0x00, 0xe7, 0x66, 0x66, 0x66,
-/* CF */  0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
-/* D0 */  0x66, 0x66, 0x66, 0xff, 0x00, 0x00, 0x00, 0x00,
-/* D1 */  0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18,
-/* D2 */  0x00, 0x00, 0x00, 0xff, 0x66, 0x66, 0x66, 0x66,
-/* D3 */  0x66, 0x66, 0x66, 0x7f, 0x00, 0x00, 0x00, 0x00,
-/* D4 */  0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00,
-/* D5 */  0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18,
-/* D6 */  0x00, 0x00, 0x00, 0x7f, 0x66, 0x66, 0x66, 0x66,
-/* D7 */  0x66, 0x66, 0x66, 0xff, 0x66, 0x66, 0x66, 0x66,
-/* D8 */  0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18,
-/* D9 */  0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00,
-/* DA */  0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18,
-/* DB */  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-/* DC */  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
-/* DD */  0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
-/* DE */  0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-/* DF */  0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
-/* E0 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* E1 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* E2 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* E3 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* E4 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* E5 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* E6 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* E7 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* E8 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* E9 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* EA */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* EB */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* EC */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* ED */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* EE */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* EF */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* F0 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* F1 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* F2 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* F3 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* F4 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* F5 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* F6 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* F7 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* F8 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* F9 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* FA */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* FB */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* FC */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* FD */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* FE */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-/* FF */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-struct fbcon_font_desc font_acorn_8x8 = {
-	ACORN8x8_IDX,
-	"Acorn8x8",
-	8,
-	8,
-	acorndata_8x8,
-#ifdef CONFIG_ARCH_ACORN
-	20
-#else
-	0
-#endif
-};
diff -Nru a/drivers/video/font_mini_4x6.c b/drivers/video/font_mini_4x6.c
--- a/drivers/video/font_mini_4x6.c	Mon Dec  9 18:46:36 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,2158 +0,0 @@
-
-/* Hand composed "Miniscule" 4x6 font, with binary data generated using
- * Perl stub.
- *
- * Use 'perl -x mini_4x6.c < mini_4x6.c > new_version.c' to regenerate
- * binary data.
- *
- * Created by Kenneth Albanowski.
- * No rights reserved, released to the public domain.
- *
- * Version 1.0
- */
-
-/*
-
-#!/usr/bin/perl -pn
-
-s{((0x)?[0-9a-fA-F]+)(.*\[([\*\ ]{4})\])}{
-
-	($num,$pat,$bits) = ($1,$3,$4);
-	
-	$bits =~ s/([^\s0])|(.)/ defined($1) + 0 /ge;
-	
-	$num = ord(pack("B8", $bits));
-	$num |= $num >> 4;
-	$num = sprintf("0x%.2x", $num);
-	
-	#print "$num,$pat,$bits\n";
-	
-	$num . $pat;
-}ge;
-
-__END__;
-*/
-
-/* Note: binary data consists of one byte for each row of each character top
-   to bottom, character 0 to character 255, six bytes per character. Each
-   byte contains the same four character bits in both nybbles.
-   MSBit to LSBit = left to right.
- */
-
-#include <video/font.h>
-
-#define FONTDATAMAX 1536
-
-static unsigned char fontdata_mini_4x6[FONTDATAMAX] = {
-
-	/*{*/
-	  	/*   Char 0: ' '  */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 1: ' '  */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 2: ' '  */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 3: ' '  */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 4: ' '  */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 5: ' '  */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 6: ' '  */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 7: ' '  */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 8: ' '  */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 9: ' '  */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 10: '' */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 11: ' ' */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 12: ' ' */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 13: ' ' */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 14: ' ' */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 15: ' ' */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 16: ' ' */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 17: ' ' */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 18: ' ' */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 19: ' ' */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 20: ' ' */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 21: ' ' */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 22: ' ' */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 23: ' ' */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 24: ' ' */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 25: ' ' */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 26: ' ' */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 27: ' ' */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 28: ' ' */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 29: ' ' */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 30: ' ' */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 31: ' ' */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 32: ' ' */
-	0x00,	/*=  [    ]       */
-	0x00,	/*=  [    ]       */
-	0x00,	/*=  [    ]       */
-	0x00,	/*=  [    ]       */
-	0x00,	/*=  [    ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 33: '!' */
-	0x44,	/*=  [ *  ]       */
-	0x44,	/*=  [ *  ]       */
-	0x44,	/*=  [ *  ]       */
-	0x00,	/*=  [    ]       */
-	0x44,	/*=  [ *  ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 34: '"' */
-	0xaa,	/*=  [* * ]       */
-	0xaa,	/*=  [* * ]       */
-	0x00,	/*=  [    ]       */
-	0x00,	/*=  [    ]       */
-	0x00,	/*=  [    ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 35: '#' */
-	0xaa,	/*=  [* * ]       */
-	0xff,	/*=  [****]       */
-	0xff,	/*=  [****]       */
-	0xaa,	/*=  [* * ]       */
-	0x00,	/*=  [    ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 36: '$' */
-	0x44,	/*=  [ *  ]       */
-	0x66,	/*=  [ ** ]       */
-	0xee,	/*=  [*** ]       */
-	0xcc,	/*=  [**  ]       */
-	0x44,	/*=  [ *  ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 37: '%' */
-	0xaa,	/*=  [* * ]       */
-	0x22,	/*=  [  * ]       */
-	0x44,	/*=  [ *  ]       */
-	0x88,	/*=  [*   ]       */
-	0xaa,	/*=  [* * ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 38: '&' */
-	0x66,	/*=  [ ** ]       */
-	0x99,	/*=  [*  *]       */
-	0x66,	/*=  [ ** ]       */
-	0xaa,	/*=  [* * ]       */
-	0xdd,	/*=  [** *]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 39: ''' */
-	0x22,	/*=  [  * ]       */
-	0x44,	/*=  [ *  ]       */
-	0x00,	/*=  [    ]       */
-	0x00,	/*=  [    ]       */
-	0x00,	/*=  [    ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 40: '(' */
-	0x22,	/*=  [  * ]       */
-	0x44,	/*=  [ *  ]       */
-	0x44,	/*=  [ *  ]       */
-	0x44,	/*=  [ *  ]       */
-	0x22,	/*=  [  * ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 41: ')' */
-	0x44,	/*=  [ *  ]       */
-	0x22,	/*=  [  * ]       */
-	0x22,	/*=  [  * ]       */
-	0x22,	/*=  [  * ]       */
-	0x44,	/*=  [ *  ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 42: '*' */
-	0x00,	/*=  [    ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 43: '+' */
-	0x00,	/*=  [    ]       */
-	0x44,	/*=  [ *  ]       */
-	0xee,	/*=  [*** ]       */
-	0x44,	/*=  [ *  ]       */
-	0x00,	/*=  [    ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 44: ',' */
-	0x00,	/*=  [    ]       */
-	0x00,	/*=  [    ]       */
-	0x00,	/*=  [    ]       */
-	0x44,	/*=  [ *  ]       */
-	0x88,	/*=  [*   ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 45: '-' */
-	0x00,	/*=  [    ]       */
-	0x00,	/*=  [    ]       */
-	0xee,	/*=  [*** ]       */
-	0x00,	/*=  [    ]       */
-	0x00,	/*=  [    ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 46: '.' */
-	0x00,	/*=  [    ]       */
-	0x00,	/*=  [    ]       */
-	0x00,	/*=  [    ]       */
-	0x00,	/*=  [    ]       */
-	0x44,	/*=  [ *  ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 47: '/' */
-	0x00,	/*=  [    ]       */
-	0x22,	/*=  [  * ]       */
-	0x44,	/*=  [ *  ]       */
-	0x88,	/*=  [*   ]       */
-	0x00,	/*=  [    ]       */
-	0x00,	/*=  [    ]       */
-	/*}*/
-	/*{*/
-	  	/*   Char 48: '0'   */
-	0x44,	/*=   [ *  ]        */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0x44,	/*=   [ *  ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/
-	  	/*   Char 49: '1'   */
-	0x44,	/*=   [ *  ]        */
-	0xcc,	/*=   [**  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/
-	  	/*   Char 50: '2'   */
-	0xcc,	/*=   [**  ]        */
-	0x22,	/*=   [  * ]        */
-	0x44,	/*=   [ *  ]        */
-	0x88,	/*=   [*   ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/
-	  	/*   Char 51: '3'   */
-	0xee,	/*=   [*** ]        */
-	0x22,	/*=   [  * ]        */
-	0x66,	/*=   [ ** ]        */
-	0x22,	/*=   [  * ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 52: '4'   */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0xee,	/*=   [*** ]        */
-	0x22,	/*=   [  * ]        */
-	0x22,	/*=   [  * ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 53: '5'   */
-	0xee,	/*=   [*** ]        */
-	0x88,	/*=   [*   ]        */
-	0xee,	/*=   [*** ]        */
-	0x22,	/*=   [  * ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 54: '6'   */
-	0xee,	/*=   [*** ]        */
-	0x88,	/*=   [*   ]        */
-	0xee,	/*=   [*** ]        */
-	0xaa,	/*=   [* * ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 55: '7'   */
-	0xee,	/*=   [*** ]        */
-	0x22,	/*=   [  * ]        */
-	0x22,	/*=   [  * ]        */
-	0x22,	/*=   [  * ]        */
-	0x22,	/*=   [  * ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 56: '8'   */
-	0xee,	/*=   [*** ]        */
-	0xaa,	/*=   [* * ]        */
-	0xee,	/*=   [*** ]        */
-	0xaa,	/*=   [* * ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 57: '9'   */
-	0xee,	/*=   [*** ]        */
-	0xaa,	/*=   [* * ]        */
-	0xee,	/*=   [*** ]        */
-	0x22,	/*=   [  * ]        */
-	0x22,	/*=   [  * ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 58: ':'   */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x44,	/*=   [ *  ]        */
-	0x00,	/*=   [    ]        */
-	0x44,	/*=   [ *  ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 59: ';'   */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x44,	/*=   [ *  ]        */
-	0x00,	/*=   [    ]        */
-	0x44,	/*=   [ *  ]        */
-	0x88,	/*=   [*   ]        */
-	/*}*/
-	/*{*/ 	/*   Char 60: '<'   */
-	0x22,	/*=   [  * ]        */
-	0x44,	/*=   [ *  ]        */
-	0x88,	/*=   [*   ]        */
-	0x44,	/*=   [ *  ]        */
-	0x22,	/*=   [  * ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 61: '='   */
-	0x00,	/*=   [    ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 62: '>'   */
-	0x88,	/*=   [*   ]        */
-	0x44,	/*=   [ *  ]        */
-	0x22,	/*=   [  * ]        */
-	0x44,	/*=   [ *  ]        */
-	0x88,	/*=   [*   ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 63: '?'   */
-	0xee,	/*=   [*** ]        */
-	0x22,	/*=   [  * ]        */
-	0x66,	/*=   [ ** ]        */
-	0x00,	/*=   [    ]        */
-	0x44,	/*=   [ *  ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 64: '@'   */
-	0x44,	/*=   [ *  ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x88,	/*=   [*   ]        */
-	0x44,	/*=   [ *  ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 65: 'A'   */
-	0x44,	/*=   [ *  ]        */
-	0xaa,	/*=   [* * ]        */
-	0xee,	/*=   [*** ]        */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 66: 'B'   */
-	0xcc,	/*=   [**  ]        */
-	0xaa,	/*=   [* * ]        */
-	0xcc,	/*=   [**  ]        */
-	0xaa,	/*=   [* * ]        */
-	0xcc,	/*=   [**  ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 67: 'C'   */
-	0x66,	/*=   [ ** ]        */
-	0x88,	/*=   [*   ]        */
-	0x88,	/*=   [*   ]        */
-	0x88,	/*=   [*   ]        */
-	0x66,	/*=   [ ** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 68: 'D'   */
-	0xcc,	/*=   [**  ]        */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0xcc,	/*=   [**  ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 69: 'E'   */
-	0xee,	/*=   [*** ]        */
-	0x88,	/*=   [*   ]        */
-	0xee,	/*=   [*** ]        */
-	0x88,	/*=   [*   ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 70: 'F'   */
-	0xee,	/*=   [*** ]        */
-	0x88,	/*=   [*   ]        */
-	0xee,	/*=   [*** ]        */
-	0x88,	/*=   [*   ]        */
-	0x88,	/*=   [*   ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 71: 'G'   */
-	0x66,	/*=   [ ** ]        */
-	0x88,	/*=   [*   ]        */
-	0xee,	/*=   [*** ]        */
-	0xaa,	/*=   [* * ]        */
-	0x66,	/*=   [ ** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 72: 'H'   */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0xee,	/*=   [*** ]        */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 73: 'I'   */
-	0xee,	/*=   [*** ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 74: 'J'   */
-	0x22,	/*=   [  * ]        */
-	0x22,	/*=   [  * ]        */
-	0x22,	/*=   [  * ]        */
-	0xaa,	/*=   [* * ]        */
-	0x44,	/*=   [ *  ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 75: 'K'   */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0xcc,	/*=   [**  ]        */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 76: 'L'   */
-	0x88,	/*=   [*   ]        */
-	0x88,	/*=   [*   ]        */
-	0x88,	/*=   [*   ]        */
-	0x88,	/*=   [*   ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 77: 'M'   */
-	0xaa,	/*=   [* * ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 78: 'N'   */
-	0xaa,	/*=   [* * ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xaa,	/*=   [* * ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 79: 'O'   */
-	0x44,	/*=   [ *  ]        */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0x44,	/*=   [ *  ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 80: 'P'   */
-	0xcc,	/*=   [**  ]        */
-	0xaa,	/*=   [* * ]        */
-	0xcc,	/*=   [**  ]        */
-	0x88,	/*=   [*   ]        */
-	0x88,	/*=   [*   ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 81: 'Q'   */
-	0x44,	/*=   [ *  ]        */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0xee,	/*=   [*** ]        */
-	0x66,	/*=   [ ** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 82: 'R'   */
-	0xcc,	/*=   [**  ]        */
-	0xaa,	/*=   [* * ]        */
-	0xee,	/*=   [*** ]        */
-	0xcc,	/*=   [**  ]        */
-	0xaa,	/*=   [* * ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 83: 'S'   */
-	0x66,	/*=   [ ** ]        */
-	0x88,	/*=   [*   ]        */
-	0x44,	/*=   [ *  ]        */
-	0x22,	/*=   [  * ]        */
-	0xcc,	/*=   [**  ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 84: 'T'   */
-	0xee,	/*=   [*** ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 85: 'U'   */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0x66,	/*=   [ ** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 86: 'V'   */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 87: 'W'   */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xaa,	/*=   [* * ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 88: 'X'   */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0x44,	/*=   [ *  ]        */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 89: 'Y'   */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 90: 'Z'   */
-	0xee,	/*=   [*** ]        */
-	0x22,	/*=   [  * ]        */
-	0x44,	/*=   [ *  ]        */
-	0x88,	/*=   [*   ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 91: '['   */
-	0x66,	/*=   [ ** ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x66,	/*=   [ ** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 92: '\'   */
-	0x00,	/*=   [    ]        */
-	0x88,	/*=   [*   ]        */
-	0x44,	/*=   [ *  ]        */
-	0x22,	/*=   [  * ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 93: ']'   */
-	0x66,	/*=   [ ** ]        */
-	0x22,	/*=   [  * ]        */
-	0x22,	/*=   [  * ]        */
-	0x22,	/*=   [  * ]        */
-	0x66,	/*=   [ ** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 94: '^'   */
-	0x44,	/*=   [ *  ]        */
-	0xaa,	/*=   [* * ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 95: '_'   */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0xff,	/*=   [****]        */
-	/*}*/
-	/*{*/ 	/*   Char 96: '`'   */
-	0x88,	/*=   [*   ]        */
-	0x44,	/*=   [ *  ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 97: 'a'   */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x66,	/*=   [ ** ]        */
-	0xaa,	/*=   [* * ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 98: 'b'   */
-	0x88,	/*=   [*   ]        */
-	0x88,	/*=   [*   ]        */
-	0xcc,	/*=   [**  ]        */
-	0xaa,	/*=   [* * ]        */
-	0xcc,	/*=   [**  ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 99: 'c'   */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x66,	/*=   [ ** ]        */
-	0x88,	/*=   [*   ]        */
-	0x66,	/*=   [ ** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 100: 'd'   */
-	0x22,	/*=   [  * ]        */
-	0x22,	/*=   [  * ]        */
-	0x66,	/*=   [ ** ]        */
-	0xaa,	/*=   [* * ]        */
-	0x66,	/*=   [ ** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 101: 'e'   */
-	0x00,	/*=   [    ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x88,	/*=   [*   ]        */
-	0x66,	/*=   [ ** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 102: 'f'   */
-	0x22,	/*=   [  * ]        */
-	0x44,	/*=   [ *  ]        */
-	0xee,	/*=   [*** ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 103: 'g'   */
-	0x00,	/*=   [    ]        */
-	0x66,	/*=   [ ** ]        */
-	0xaa,	/*=   [* * ]        */
-	0x66,	/*=   [ ** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 104: 'h'   */
-	0x88,	/*=   [*   ]        */
-	0x88,	/*=   [*   ]        */
-	0xcc,	/*=   [**  ]        */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 105: 'i'   */
-	0x44,	/*=   [ *  ]        */
-	0x00,	/*=   [    ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 106: 'j'   */
-	0x44,	/*=   [ *  ]        */
-	0x00,	/*=   [    ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x88,	/*=   [*   ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 107: 'k'   */
-	0x00,	/*=   [    ]        */
-	0x88,	/*=   [*   ]        */
-	0xaa,	/*=   [* * ]        */
-	0xcc,	/*=   [**  ]        */
-	0xaa,	/*=   [* * ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 108: 'l'   */
-	0x00,	/*=   [    ]        */
-	0xcc,	/*=   [**  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 109: 'm'   */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xaa,	/*=   [* * ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 110: 'n'   */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0xcc,	/*=   [**  ]        */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 111: 'o'   */
-	0x00,	/*=   [    ]        */
-	0x44,	/*=   [ *  ]        */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0x44,	/*=   [ *  ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 112: 'p'   */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0xcc,	/*=   [**  ]        */
-	0xaa,	/*=   [* * ]        */
-	0xcc,	/*=   [**  ]        */
-	0x88,	/*=   [*   ]        */
-	/*}*/
-	/*{*/ 	/*   Char 113: 'q'   */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x66,	/*=   [ ** ]        */
-	0xaa,	/*=   [* * ]        */
-	0x66,	/*=   [ ** ]        */
-	0x22,	/*=   [  * ]        */
-	/*}*/
-	/*{*/ 	/*   Char 114: 'r'   */
-	0x00,	/*=   [    ]        */
-	0xcc,	/*=   [**  ]        */
-	0xaa,	/*=   [* * ]        */
-	0x88,	/*=   [*   ]        */
-	0x88,	/*=   [*   ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 115: 's'   */
-	0x00,	/*=   [    ]        */
-	0x66,	/*=   [ ** ]        */
-	0xcc,	/*=   [**  ]        */
-	0x22,	/*=   [  * ]        */
-	0xcc,	/*=   [**  ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 116: 't'   */
-	0x00,	/*=   [    ]        */
-	0x44,	/*=   [ *  ]        */
-	0xee,	/*=   [*** ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 117: 'u'   */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0x66,	/*=   [ ** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 118: 'v'   */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0xaa,	/*=   [* * ]        */
-	0xee,	/*=   [*** ]        */
-	0x44,	/*=   [ *  ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 119: 'w'   */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0xaa,	/*=   [* * ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 120: 'x'   */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0xaa,	/*=   [* * ]        */
-	0x44,	/*=   [ *  ]        */
-	0xaa,	/*=   [* * ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 121: 'y'   */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0xaa,	/*=   [* * ]        */
-	0xee,	/*=   [*** ]        */
-	0x22,	/*=   [  * ]        */
-	0xcc,	/*=   [**  ]        */
-	/*}*/
-	/*{*/ 	/*   Char 122: 'z' */
-	0x00,	/*=   [    ]        */
-	0xee,	/*=   [*** ]        */
-	0x66,	/*=   [ ** ]        */
-	0xcc,	/*=   [**  ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 123: '{' */
-	0x22,	/*=   [  * ]        */
-	0x44,	/*=   [ *  ]        */
-	0xcc,	/*=   [**  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x22,	/*=   [  * ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 124: '|' */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x00,	/*=   [    ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 125: '}' */
-	0x88,	/*=   [*   ]        */
-	0x44,	/*=   [ *  ]        */
-	0x66,	/*=   [ ** ]        */
-	0x44,	/*=   [ *  ]        */
-	0x88,	/*=   [*   ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 126: '~' */
-	0x55,	/*=   [ * *]        */
-	0xaa,	/*=   [* * ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 127: '' */
-	0x44,	/*=   [ *  ]        */
-	0xaa,	/*=   [* * ]        */
-	0xaa,	/*=   [* * ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 128:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 129:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 130:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 131:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 132:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 133:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 134:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 135:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 136:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 137:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 138:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 139:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 140:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 141:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 142:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 143:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 144:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 145:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 146:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 147:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 148:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 149:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 150:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 151:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 152:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 153:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 154:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 155:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 156:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 157:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 158:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 159:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 160:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 161:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 162:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 163:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 164:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 165:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 166:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 167:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 168:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 169:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 170:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 171:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 172:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 173:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 174:  */
-	0x00,	/*=   [    ]        */
-	0x66,	/*=   [ ** ]        */
-	0xcc,	/*=   [**  ]        */
-	0x66,	/*=   [ ** ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 175:  */
-	0x00,	/*=   [    ]        */
-	0xcc,	/*=   [**  ]        */
-	0x66,	/*=   [ ** ]        */
-	0xcc,	/*=   [**  ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 176:  */
-	0x88,	/*=   [*   ]        */
-	0x22,	/*=   [  * ]        */
-	0x88,	/*=   [*   ]        */
-	0x22,	/*=   [  * ]        */
-	0x88,	/*=   [*   ]        */
-	0x22,	/*=   [  * ]        */
-	/*}*/
-	/*{*/ 	/*   Char 177:  */
-	0xaa,	/*=   [* * ]        */
-	0x55,	/*=   [ * *]        */
-	0xaa,	/*=   [* * ]        */
-	0x55,	/*=   [ * *]        */
-	0xaa,	/*=   [* * ]        */
-	0x55,	/*=   [ * *]        */
-	/*}*/
-	/*{*/ 	/*   Char 178:  */
-	0xdd,	/*=   [** *]        */
-	0xbb,	/*=   [* **]        */
-	0xdd,	/*=   [** *]        */
-	0xbb,	/*=   [* **]        */
-	0xdd,	/*=   [** *]        */
-	0xbb,	/*=   [* **]        */
-	/*}*/
-	/*{*/ 	/*   Char 179:  */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	/*}*/
-	/*{*/ 	/*   Char 180:  */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0xcc,	/*=   [**  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	/*}*/
-	/*{*/ 	/*   Char 181:  */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0xcc,	/*=   [**  ]        */
-	0xcc,	/*=   [**  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	/*}*/
-	/*{*/ 	/*   Char 182:  */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	0xee,	/*=   [*** ]        */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	/*}*/
-	/*{*/ 	/*   Char 183:  */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0xee,	/*=   [*** ]        */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	/*}*/
-	/*{*/ 	/*   Char 184:  */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0xcc,	/*=   [**  ]        */
-	0xcc,	/*=   [**  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	/*}*/
-	/*{*/ 	/*   Char 185:  */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	/*}*/
-	/*{*/ 	/*   Char 186:  */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	/*}*/
-	/*{*/ 	/*   Char 187:  */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	/*}*/
-	/*{*/ 	/*   Char 188:  */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 189:  */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 190:  */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0xcc,	/*=   [**  ]        */
-	0xcc,	/*=   [**  ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 191:  */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0xcc,	/*=   [**  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	/*}*/
-	/*{*/ 	/*   Char 192:  */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x77,	/*=   [ ***]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 193:  */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0xff,	/*=   [****]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 194:  */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0xff,	/*=   [****]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	/*}*/
-	/*{*/ 	/*   Char 195:  */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x77,	/*=   [ ***]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	/*}*/
-	/*{*/ 	/*   Char 196:  */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0xff,	/*=   [****]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 197:  */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0xff,	/*=   [****]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	/*}*/
-	/*{*/ 	/*   Char 198:  */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x77,	/*=   [ ***]        */
-	0x77,	/*=   [ ***]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	/*}*/
-	/*{*/ 	/*   Char 199:  */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	0x77,	/*=   [ ***]        */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	/*}*/
-	/*{*/ 	/*   Char 200:  */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	0x77,	/*=   [ ***]        */
-	0x77,	/*=   [ ***]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 201:  */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x77,	/*=   [ ***]        */
-	0x77,	/*=   [ ***]        */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	/*}*/
-	/*{*/ 	/*   Char 202:  */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	0xff,	/*=   [****]        */
-	0xff,	/*=   [****]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 203:  */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0xff,	/*=   [****]        */
-	0xff,	/*=   [****]        */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	/*}*/
-	/*{*/ 	/*   Char 204:  */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	0x77,	/*=   [ ***]        */
-	0x77,	/*=   [ ***]        */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	/*}*/
-	/*{*/ 	/*   Char 205:  */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0xff,	/*=   [****]        */
-	0xff,	/*=   [****]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 206:  */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	0xff,	/*=   [****]        */
-	0xff,	/*=   [****]        */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	/*}*/
-	/*{*/ 	/*   Char 207:  */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0xff,	/*=   [****]        */
-	0xff,	/*=   [****]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 208:  */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	0xff,	/*=   [****]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 209:  */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0xff,	/*=   [****]        */
-	0xff,	/*=   [****]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	/*}*/
-	/*{*/ 	/*   Char 210:  */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0xff,	/*=   [****]        */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	/*}*/
-	/*{*/ 	/*   Char 211:  */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	0x77,	/*=   [ ***]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 212:  */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x77,	/*=   [ ***]        */
-	0x77,	/*=   [ ***]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 213:  */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x77,	/*=   [ ***]        */
-	0x77,	/*=   [ ***]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	/*}*/
-	/*{*/ 	/*   Char 214:  */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x77,	/*=   [ ***]        */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	/*}*/
-	/*{*/ 	/*   Char 215:  */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	0xff,	/*=   [****]        */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	/*}*/
-	/*{*/ 	/*   Char 216:  */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0xff,	/*=   [****]        */
-	0xff,	/*=   [****]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	/*}*/
-	/*{*/ 	/*   Char 217:  */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0xcc,	/*=   [**  ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 218:  */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x77,	/*=   [ ***]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	0x44,	/*=   [ *  ]        */
-	/*}*/
-	/*{*/ 	/*   Char 219:  */
-	0xff,	/*=   [****]        */
-	0xff,	/*=   [****]        */
-	0xff,	/*=   [****]        */
-	0xff,	/*=   [****]        */
-	0xff,	/*=   [****]        */
-	0xff,	/*=   [****]        */
-	/*}*/
-	/*{*/ 	/*   Char 220:  */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0xff,	/*=   [****]        */
-	0xff,	/*=   [****]        */
-	0xff,	/*=   [****]        */
-	/*}*/
-	/*{*/ 	/*   Char 221:  */
-	0xcc,	/*=   [**  ]        */
-	0xcc,	/*=   [**  ]        */
-	0xcc,	/*=   [**  ]        */
-	0xcc,	/*=   [**  ]        */
-	0xcc,	/*=   [**  ]        */
-	0xcc,	/*=   [**  ]        */
-	/*}*/
-	/*{*/ 	/*   Char 222:  */
-	0x33,	/*=   [  **]        */
-	0x33,	/*=   [  **]        */
-	0x33,	/*=   [  **]        */
-	0x33,	/*=   [  **]        */
-	0x33,	/*=   [  **]        */
-	0x33,	/*=   [  **]        */
-	/*}*/
-	/*{*/ 	/*   Char 223:  */
-	0xff,	/*=   [****]        */
-	0xff,	/*=   [****]        */
-	0xff,	/*=   [****]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 224:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 225:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 226:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 227:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 228:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 229:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 230:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 231:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 232:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 233:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 234:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 235:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 236:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 237:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 238:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 239:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 240:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 241:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 242:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 243:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 244:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 245:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 246:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 247:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 248:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 249:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 250:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 251:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 252:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 253:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 254:  */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	0x66,	/*=   [ ** ]        */
-	0x66,	/*=   [ ** ]        */
-	0x00,	/*=   [    ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-	/*{*/ 	/*   Char 255:  */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0xee,	/*=   [*** ]        */
-	0x00,	/*=   [    ]        */
-	/*}*/
-};
-
-struct fbcon_font_desc font_mini_4x6 = {
-	MINI4x6_IDX,
-	"MINI4x6",
-	4,
-	6,
-	fontdata_mini_4x6,
-	3
-};
-
diff -Nru a/drivers/video/font_pearl_8x8.c b/drivers/video/font_pearl_8x8.c
--- a/drivers/video/font_pearl_8x8.c	Mon Dec  9 18:46:34 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,2587 +0,0 @@
-/**********************************************/
-/*                                            */
-/*       Font file generated by cpi2fnt       */
-/*       ------------------------------       */
-/*       Combined with the alpha-numeric      */
-/*       portion of Greg Harp's old PEARL     */
-/*       font (from earlier versions of       */
-/*       linux-m86k) by John Shifflett        */
-/*                                            */
-/**********************************************/
-
-#include <video/font.h>
-
-#define FONTDATAMAX 2048
-
-static unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
-
-   /* 0 0x00 '^@' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 1 0x01 '^A' */
-   0x7e, /* 01111110 */
-   0x81, /* 10000001 */
-   0xa5, /* 10100101 */
-   0x81, /* 10000001 */
-   0xbd, /* 10111101 */
-   0x99, /* 10011001 */
-   0x81, /* 10000001 */
-   0x7e, /* 01111110 */
-
-   /* 2 0x02 '^B' */
-   0x7e, /* 01111110 */
-   0xff, /* 11111111 */
-   0xdb, /* 11011011 */
-   0xff, /* 11111111 */
-   0xc3, /* 11000011 */
-   0xe7, /* 11100111 */
-   0xff, /* 11111111 */
-   0x7e, /* 01111110 */
-
-   /* 3 0x03 '^C' */
-   0x6c, /* 01101100 */
-   0xfe, /* 11111110 */
-   0xfe, /* 11111110 */
-   0xfe, /* 11111110 */
-   0x7c, /* 01111100 */
-   0x38, /* 00111000 */
-   0x10, /* 00010000 */
-   0x00, /* 00000000 */
-
-   /* 4 0x04 '^D' */
-   0x10, /* 00010000 */
-   0x38, /* 00111000 */
-   0x7c, /* 01111100 */
-   0xfe, /* 11111110 */
-   0x7c, /* 01111100 */
-   0x38, /* 00111000 */
-   0x10, /* 00010000 */
-   0x00, /* 00000000 */
-
-   /* 5 0x05 '^E' */
-   0x38, /* 00111000 */
-   0x7c, /* 01111100 */
-   0x38, /* 00111000 */
-   0xfe, /* 11111110 */
-   0xfe, /* 11111110 */
-   0xd6, /* 11010110 */
-   0x10, /* 00010000 */
-   0x38, /* 00111000 */
-
-   /* 6 0x06 '^F' */
-   0x10, /* 00010000 */
-   0x38, /* 00111000 */
-   0x7c, /* 01111100 */
-   0xfe, /* 11111110 */
-   0xfe, /* 11111110 */
-   0x7c, /* 01111100 */
-   0x10, /* 00010000 */
-   0x38, /* 00111000 */
-
-   /* 7 0x07 '^G' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x18, /* 00011000 */
-   0x3c, /* 00111100 */
-   0x3c, /* 00111100 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 8 0x08 '^H' */
-   0xff, /* 11111111 */
-   0xff, /* 11111111 */
-   0xe7, /* 11100111 */
-   0xc3, /* 11000011 */
-   0xc3, /* 11000011 */
-   0xe7, /* 11100111 */
-   0xff, /* 11111111 */
-   0xff, /* 11111111 */
-
-   /* 9 0x09 '^I' */
-   0x00, /* 00000000 */
-   0x3c, /* 00111100 */
-   0x66, /* 01100110 */
-   0x42, /* 01000010 */
-   0x42, /* 01000010 */
-   0x66, /* 01100110 */
-   0x3c, /* 00111100 */
-   0x00, /* 00000000 */
-
-   /* 10 0x0a '^J' */
-   0xff, /* 11111111 */
-   0xc3, /* 11000011 */
-   0x99, /* 10011001 */
-   0xbd, /* 10111101 */
-   0xbd, /* 10111101 */
-   0x99, /* 10011001 */
-   0xc3, /* 11000011 */
-   0xff, /* 11111111 */
-
-   /* 11 0x0b '^K' */
-   0x0f, /* 00001111 */
-   0x07, /* 00000111 */
-   0x0f, /* 00001111 */
-   0x7d, /* 01111101 */
-   0xcc, /* 11001100 */
-   0xcc, /* 11001100 */
-   0xcc, /* 11001100 */
-   0x78, /* 01111000 */
-
-   /* 12 0x0c '^L' */
-   0x3c, /* 00111100 */
-   0x66, /* 01100110 */
-   0x66, /* 01100110 */
-   0x66, /* 01100110 */
-   0x3c, /* 00111100 */
-   0x18, /* 00011000 */
-   0x7e, /* 01111110 */
-   0x18, /* 00011000 */
-
-   /* 13 0x0d '^M' */
-   0x3f, /* 00111111 */
-   0x33, /* 00110011 */
-   0x3f, /* 00111111 */
-   0x30, /* 00110000 */
-   0x30, /* 00110000 */
-   0x70, /* 01110000 */
-   0xf0, /* 11110000 */
-   0xe0, /* 11100000 */
-
-   /* 14 0x0e '^N' */
-   0x7f, /* 01111111 */
-   0x63, /* 01100011 */
-   0x7f, /* 01111111 */
-   0x63, /* 01100011 */
-   0x63, /* 01100011 */
-   0x67, /* 01100111 */
-   0xe6, /* 11100110 */
-   0xc0, /* 11000000 */
-
-   /* 15 0x0f '^O' */
-   0x18, /* 00011000 */
-   0xdb, /* 11011011 */
-   0x3c, /* 00111100 */
-   0xe7, /* 11100111 */
-   0xe7, /* 11100111 */
-   0x3c, /* 00111100 */
-   0xdb, /* 11011011 */
-   0x18, /* 00011000 */
-
-   /* 16 0x10 '^P' */
-   0x80, /* 10000000 */
-   0xe0, /* 11100000 */
-   0xf8, /* 11111000 */
-   0xfe, /* 11111110 */
-   0xf8, /* 11111000 */
-   0xe0, /* 11100000 */
-   0x80, /* 10000000 */
-   0x00, /* 00000000 */
-
-   /* 17 0x11 '^Q' */
-   0x02, /* 00000010 */
-   0x0e, /* 00001110 */
-   0x3e, /* 00111110 */
-   0xfe, /* 11111110 */
-   0x3e, /* 00111110 */
-   0x0e, /* 00001110 */
-   0x02, /* 00000010 */
-   0x00, /* 00000000 */
-
-   /* 18 0x12 '^R' */
-   0x18, /* 00011000 */
-   0x3c, /* 00111100 */
-   0x7e, /* 01111110 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x7e, /* 01111110 */
-   0x3c, /* 00111100 */
-   0x18, /* 00011000 */
-
-   /* 19 0x13 '^S' */
-   0x66, /* 01100110 */
-   0x66, /* 01100110 */
-   0x66, /* 01100110 */
-   0x66, /* 01100110 */
-   0x66, /* 01100110 */
-   0x00, /* 00000000 */
-   0x66, /* 01100110 */
-   0x00, /* 00000000 */
-
-   /* 20 0x14 '^T' */
-   0x7f, /* 01111111 */
-   0xdb, /* 11011011 */
-   0xdb, /* 11011011 */
-   0x7b, /* 01111011 */
-   0x1b, /* 00011011 */
-   0x1b, /* 00011011 */
-   0x1b, /* 00011011 */
-   0x00, /* 00000000 */
-
-   /* 21 0x15 '^U' */
-   0x3e, /* 00111110 */
-   0x61, /* 01100001 */
-   0x3c, /* 00111100 */
-   0x66, /* 01100110 */
-   0x66, /* 01100110 */
-   0x3c, /* 00111100 */
-   0x86, /* 10000110 */
-   0x7c, /* 01111100 */
-
-   /* 22 0x16 '^V' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x7e, /* 01111110 */
-   0x7e, /* 01111110 */
-   0x7e, /* 01111110 */
-   0x00, /* 00000000 */
-
-   /* 23 0x17 '^W' */
-   0x18, /* 00011000 */
-   0x3c, /* 00111100 */
-   0x7e, /* 01111110 */
-   0x18, /* 00011000 */
-   0x7e, /* 01111110 */
-   0x3c, /* 00111100 */
-   0x18, /* 00011000 */
-   0xff, /* 11111111 */
-
-   /* 24 0x18 '^X' */
-   0x18, /* 00011000 */
-   0x3c, /* 00111100 */
-   0x7e, /* 01111110 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-
-   /* 25 0x19 '^Y' */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x7e, /* 01111110 */
-   0x3c, /* 00111100 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-
-   /* 26 0x1a '^Z' */
-   0x00, /* 00000000 */
-   0x18, /* 00011000 */
-   0x0c, /* 00001100 */
-   0xfe, /* 11111110 */
-   0x0c, /* 00001100 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 27 0x1b '^[' */
-   0x00, /* 00000000 */
-   0x30, /* 00110000 */
-   0x60, /* 01100000 */
-   0xfe, /* 11111110 */
-   0x60, /* 01100000 */
-   0x30, /* 00110000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 28 0x1c '^\' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0xfe, /* 11111110 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 29 0x1d '^]' */
-   0x00, /* 00000000 */
-   0x24, /* 00100100 */
-   0x66, /* 01100110 */
-   0xff, /* 11111111 */
-   0x66, /* 01100110 */
-   0x24, /* 00100100 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 30 0x1e '^^' */
-   0x00, /* 00000000 */
-   0x18, /* 00011000 */
-   0x3c, /* 00111100 */
-   0x7e, /* 01111110 */
-   0xff, /* 11111111 */
-   0xff, /* 11111111 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 31 0x1f '^_' */
-   0x00, /* 00000000 */
-   0xff, /* 11111111 */
-   0xff, /* 11111111 */
-   0x7e, /* 01111110 */
-   0x3c, /* 00111100 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 32 0x20 ' ' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 33 0x21 '!' */
-   0x18, /* 00011000 */
-   0x3c, /* 00111100 */
-   0x3c, /* 00111100 */
-   0x3c, /* 00111100 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-
-   /* 34 0x22 '"' */
-   0x6c, /* 01101100 */
-   0x6c, /* 01101100 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 35 0x23 '#' */
-   0x6c, /* 01101100 */
-   0x6c, /* 01101100 */
-   0xfe, /* 11111110 */
-   0x6c, /* 01101100 */
-   0xfe, /* 11111110 */
-   0x6c, /* 01101100 */
-   0x6c, /* 01101100 */
-   0x00, /* 00000000 */
-
-   /* 36 0x24 '$' */
-   0x18, /* 00011000 */
-   0x3e, /* 00111110 */
-   0x60, /* 01100000 */
-   0x3c, /* 00111100 */
-   0x06, /* 00000110 */
-   0x7c, /* 01111100 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-
-   /* 37 0x25 '%' */
-   0x00, /* 00000000 */
-   0xc6, /* 11000110 */
-   0xcc, /* 11001100 */
-   0x18, /* 00011000 */
-   0x30, /* 00110000 */
-   0x66, /* 01100110 */
-   0xc6, /* 11000110 */
-   0x00, /* 00000000 */
-
-   /* 38 0x26 '&' */
-   0x38, /* 00111000 */
-   0x6c, /* 01101100 */
-   0x68, /* 01101000 */
-   0x76, /* 01110110 */
-   0xdc, /* 11011100 */
-   0xcc, /* 11001100 */
-   0x76, /* 01110110 */
-   0x00, /* 00000000 */
-
-   /* 39 0x27 ''' */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x30, /* 00110000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 40 0x28 '(' */
-   0x0c, /* 00001100 */
-   0x18, /* 00011000 */
-   0x30, /* 00110000 */
-   0x30, /* 00110000 */
-   0x30, /* 00110000 */
-   0x18, /* 00011000 */
-   0x0c, /* 00001100 */
-   0x00, /* 00000000 */
-
-   /* 41 0x29 ')' */
-   0x30, /* 00110000 */
-   0x18, /* 00011000 */
-   0x0c, /* 00001100 */
-   0x0c, /* 00001100 */
-   0x0c, /* 00001100 */
-   0x18, /* 00011000 */
-   0x30, /* 00110000 */
-   0x00, /* 00000000 */
-
-   /* 42 0x2a '*' */
-   0x00, /* 00000000 */
-   0x66, /* 01100110 */
-   0x3c, /* 00111100 */
-   0xff, /* 11111111 */
-   0x3c, /* 00111100 */
-   0x66, /* 01100110 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 43 0x2b '+' */
-   0x00, /* 00000000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x7e, /* 01111110 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 44 0x2c ',' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x30, /* 00110000 */
-
-   /* 45 0x2d '-' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x7e, /* 01111110 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 46 0x2e '.' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-
-   /* 47 0x2f '/' */
-   0x03, /* 00000011 */
-   0x06, /* 00000110 */
-   0x0c, /* 00001100 */
-   0x18, /* 00011000 */
-   0x30, /* 00110000 */
-   0x60, /* 01100000 */
-   0xc0, /* 11000000 */
-   0x00, /* 00000000 */
-
-   /* 48 0x30 '0' */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0xde, /* 11011110 */
-   0xfe, /* 11111110 */
-   0xf6, /* 11110110 */
-   0xc6, /* 11000110 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 49 0x31 '1' */
-   0x18, /* 00011000 */
-   0x78, /* 01111000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-
-   /* 50 0x32 '2' */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0x0c, /* 00001100 */
-   0x18, /* 00011000 */
-   0x30, /* 00110000 */
-   0x60, /* 01100000 */
-   0xfe, /* 11111110 */
-   0x00, /* 00000000 */
-
-   /* 51 0x33 '3' */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0x06, /* 00000110 */
-   0x1c, /* 00011100 */
-   0x06, /* 00000110 */
-   0xc6, /* 11000110 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 52 0x34 '4' */
-   0x1c, /* 00011100 */
-   0x3c, /* 00111100 */
-   0x6c, /* 01101100 */
-   0xcc, /* 11001100 */
-   0xfe, /* 11111110 */
-   0x0c, /* 00001100 */
-   0x0c, /* 00001100 */
-   0x00, /* 00000000 */
-
-   /* 53 0x35 '5' */
-   0xfe, /* 11111110 */
-   0xc0, /* 11000000 */
-   0xfc, /* 11111100 */
-   0x06, /* 00000110 */
-   0x06, /* 00000110 */
-   0xc6, /* 11000110 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 54 0x36 '6' */
-   0x38, /* 00111000 */
-   0x60, /* 01100000 */
-   0xc0, /* 11000000 */
-   0xfc, /* 11111100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 55 0x37 '7' */
-   0xfe, /* 11111110 */
-   0x06, /* 00000110 */
-   0x0c, /* 00001100 */
-   0x18, /* 00011000 */
-   0x30, /* 00110000 */
-   0x60, /* 01100000 */
-   0x60, /* 01100000 */
-   0x00, /* 00000000 */
-
-   /* 56 0x38 '8' */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 57 0x39 '9' */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x7e, /* 01111110 */
-   0x06, /* 00000110 */
-   0x0c, /* 00001100 */
-   0x38, /* 00111000 */
-   0x00, /* 00000000 */
-
-   /* 58 0x3a ':' */
-   0x00, /* 00000000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-
-   /* 59 0x3b ';' */
-   0x00, /* 00000000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x30, /* 00110000 */
-
-   /* 60 0x3c '<' */
-   0x0c, /* 00001100 */
-   0x18, /* 00011000 */
-   0x30, /* 00110000 */
-   0x60, /* 01100000 */
-   0x30, /* 00110000 */
-   0x18, /* 00011000 */
-   0x0c, /* 00001100 */
-   0x00, /* 00000000 */
-
-   /* 61 0x3d '=' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x7e, /* 01111110 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x7e, /* 01111110 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 62 0x3e '>' */
-   0x30, /* 00110000 */
-   0x18, /* 00011000 */
-   0x0c, /* 00001100 */
-   0x06, /* 00000110 */
-   0x0c, /* 00001100 */
-   0x18, /* 00011000 */
-   0x30, /* 00110000 */
-   0x00, /* 00000000 */
-
-   /* 63 0x3f '?' */
-   0x3c, /* 00111100 */
-   0x66, /* 01100110 */
-   0x06, /* 00000110 */
-   0x0c, /* 00001100 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-
-   /* 64 0x40 '@' */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0xde, /* 11011110 */
-   0xde, /* 11011110 */
-   0xde, /* 11011110 */
-   0xc0, /* 11000000 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 65 0x41 'A' */
-   0x10, /* 00010000 */
-   0x38, /* 00111000 */
-   0x6c, /* 01101100 */
-   0xc6, /* 11000110 */
-   0xfe, /* 11111110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x00, /* 00000000 */
-
-   /* 66 0x42 'B' */
-   0xfc, /* 11111100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xfc, /* 11111100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xfc, /* 11111100 */
-   0x00, /* 00000000 */
-
-   /* 67 0x43 'C' */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0xc6, /* 11000110 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 68 0x44 'D' */
-   0xfc, /* 11111100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xfc, /* 11111100 */
-   0x00, /* 00000000 */
-
-   /* 69 0x45 'E' */
-   0xfe, /* 11111110 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0xf8, /* 11111000 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0xfe, /* 11111110 */
-   0x00, /* 00000000 */
-
-   /* 70 0x46 'F' */
-   0xfe, /* 11111110 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0xf8, /* 11111000 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0x00, /* 00000000 */
-
-   /* 71 0x47 'G' */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0xc0, /* 11000000 */
-   0xce, /* 11001110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 72 0x48 'H' */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xfe, /* 11111110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x00, /* 00000000 */
-
-   /* 73 0x49 'I' */
-   0x7e, /* 01111110 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x7e, /* 01111110 */
-   0x00, /* 00000000 */
-
-   /* 74 0x4a 'J' */
-   0x06, /* 00000110 */
-   0x06, /* 00000110 */
-   0x06, /* 00000110 */
-   0x06, /* 00000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 75 0x4b 'K' */
-   0xc6, /* 11000110 */
-   0xcc, /* 11001100 */
-   0xd8, /* 11011000 */
-   0xf0, /* 11110000 */
-   0xd8, /* 11011000 */
-   0xcc, /* 11001100 */
-   0xc6, /* 11000110 */
-   0x00, /* 00000000 */
-
-   /* 76 0x4c 'L' */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0xfe, /* 11111110 */
-   0x00, /* 00000000 */
-
-   /* 77 0x4d 'M' */
-   0x82, /* 10000010 */
-   0xc6, /* 11000110 */
-   0xee, /* 11101110 */
-   0xfe, /* 11111110 */
-   0xd6, /* 11010110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x00, /* 00000000 */
-
-   /* 78 0x4e 'N' */
-   0xc6, /* 11000110 */
-   0xe6, /* 11100110 */
-   0xf6, /* 11110110 */
-   0xde, /* 11011110 */
-   0xce, /* 11001110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x00, /* 00000000 */
-
-   /* 79 0x4f 'O' */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 80 0x50 'P' */
-   0xfc, /* 11111100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xfc, /* 11111100 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0x00, /* 00000000 */
-
-   /* 81 0x51 'Q' */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xf6, /* 11110110 */
-   0xde, /* 11011110 */
-   0x7c, /* 01111100 */
-   0x06, /* 00000110 */
-
-   /* 82 0x52 'R' */
-   0xfc, /* 11111100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xfc, /* 11111100 */
-   0xd8, /* 11011000 */
-   0xcc, /* 11001100 */
-   0xc6, /* 11000110 */
-   0x00, /* 00000000 */
-
-   /* 83 0x53 'S' */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0x60, /* 01100000 */
-   0x38, /* 00111000 */
-   0x0c, /* 00001100 */
-   0xc6, /* 11000110 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 84 0x54 'T' */
-   0x7e, /* 01111110 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-
-   /* 85 0x55 'U' */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 86 0x56 'V' */
-   0xc3, /* 11000011 */
-   0xc3, /* 11000011 */
-   0x66, /* 01100110 */
-   0x66, /* 01100110 */
-   0x3c, /* 00111100 */
-   0x3c, /* 00111100 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-
-   /* 87 0x57 'W' */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xd6, /* 11010110 */
-   0xfe, /* 11111110 */
-   0xee, /* 11101110 */
-   0xc6, /* 11000110 */
-   0x00, /* 00000000 */
-
-   /* 88 0x58 'X' */
-   0xc3, /* 11000011 */
-   0x66, /* 01100110 */
-   0x3c, /* 00111100 */
-   0x18, /* 00011000 */
-   0x3c, /* 00111100 */
-   0x66, /* 01100110 */
-   0xc3, /* 11000011 */
-   0x00, /* 00000000 */
-
-   /* 89 0x59 'Y' */
-   0xc3, /* 11000011 */
-   0xc3, /* 11000011 */
-   0x66, /* 01100110 */
-   0x3c, /* 00111100 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-
-   /* 90 0x5a 'Z' */
-   0xfe, /* 11111110 */
-   0x06, /* 00000110 */
-   0x0c, /* 00001100 */
-   0x18, /* 00011000 */
-   0x30, /* 00110000 */
-   0x60, /* 01100000 */
-   0xfe, /* 11111110 */
-   0x00, /* 00000000 */
-
-   /* 91 0x5b '[' */
-   0x3c, /* 00111100 */
-   0x30, /* 00110000 */
-   0x30, /* 00110000 */
-   0x30, /* 00110000 */
-   0x30, /* 00110000 */
-   0x30, /* 00110000 */
-   0x3c, /* 00111100 */
-   0x00, /* 00000000 */
-
-   /* 92 0x5c '\' */
-   0xc0, /* 11000000 */
-   0x60, /* 01100000 */
-   0x30, /* 00110000 */
-   0x18, /* 00011000 */
-   0x0c, /* 00001100 */
-   0x06, /* 00000110 */
-   0x03, /* 00000011 */
-   0x00, /* 00000000 */
-
-   /* 93 0x5d ']' */
-   0x3c, /* 00111100 */
-   0x0c, /* 00001100 */
-   0x0c, /* 00001100 */
-   0x0c, /* 00001100 */
-   0x0c, /* 00001100 */
-   0x0c, /* 00001100 */
-   0x3c, /* 00111100 */
-   0x00, /* 00000000 */
-
-   /* 94 0x5e '^' */
-   0x10, /* 00010000 */
-   0x38, /* 00111000 */
-   0x6c, /* 01101100 */
-   0xc6, /* 11000110 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 95 0x5f '_' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xfe, /* 11111110 */
-
-   /* 96 0x60 '`' */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x0c, /* 00001100 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 97 0x61 'a' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x7c, /* 01111100 */
-   0x06, /* 00000110 */
-   0x7e, /* 01111110 */
-   0xc6, /* 11000110 */
-   0x7e, /* 01111110 */
-   0x00, /* 00000000 */
-
-   /* 98 0x62 'b' */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0xfc, /* 11111100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xfc, /* 11111100 */
-   0x00, /* 00000000 */
-
-   /* 99 0x63 'c' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0xc0, /* 11000000 */
-   0xc6, /* 11000110 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 100 0x64 'd' */
-   0x06, /* 00000110 */
-   0x06, /* 00000110 */
-   0x7e, /* 01111110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x7e, /* 01111110 */
-   0x00, /* 00000000 */
-
-   /* 101 0x65 'e' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0xfe, /* 11111110 */
-   0xc0, /* 11000000 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 102 0x66 'f' */
-   0x3c, /* 00111100 */
-   0x66, /* 01100110 */
-   0x60, /* 01100000 */
-   0xf0, /* 11110000 */
-   0x60, /* 01100000 */
-   0x60, /* 01100000 */
-   0x60, /* 01100000 */
-   0x00, /* 00000000 */
-
-   /* 103 0x67 'g' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x7e, /* 01111110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x7e, /* 01111110 */
-   0x06, /* 00000110 */
-   0x7c, /* 01111100 */
-
-   /* 104 0x68 'h' */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0xfc, /* 11111100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x00, /* 00000000 */
-
-   /* 105 0x69 'i' */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-   0x38, /* 00111000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-
-   /* 106 0x6a 'j' */
-   0x06, /* 00000110 */
-   0x00, /* 00000000 */
-   0x06, /* 00000110 */
-   0x06, /* 00000110 */
-   0x06, /* 00000110 */
-   0x06, /* 00000110 */
-   0xc6, /* 11000110 */
-   0x7c, /* 01111100 */
-
-   /* 107 0x6b 'k' */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0xcc, /* 11001100 */
-   0xd8, /* 11011000 */
-   0xf0, /* 11110000 */
-   0xd8, /* 11011000 */
-   0xcc, /* 11001100 */
-   0x00, /* 00000000 */
-
-   /* 108 0x6c 'l' */
-   0x38, /* 00111000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-
-   /* 109 0x6d 'm' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xec, /* 11101100 */
-   0xfe, /* 11111110 */
-   0xd6, /* 11010110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x00, /* 00000000 */
-
-   /* 110 0x6e 'n' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xfc, /* 11111100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x00, /* 00000000 */
-
-   /* 111 0x6f 'o' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 112 0x70 'p' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xfc, /* 11111100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xfc, /* 11111100 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-
-   /* 113 0x71 'q' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x7e, /* 01111110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x7e, /* 01111110 */
-   0x06, /* 00000110 */
-   0x06, /* 00000110 */
-
-   /* 114 0x72 'r' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xdc, /* 11011100 */
-   0xe6, /* 11100110 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0x00, /* 00000000 */
-
-   /* 115 0x73 's' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x7e, /* 01111110 */
-   0xc0, /* 11000000 */
-   0x7c, /* 01111100 */
-   0x06, /* 00000110 */
-   0xfc, /* 11111100 */
-   0x00, /* 00000000 */
-
-   /* 116 0x74 't' */
-   0x30, /* 00110000 */
-   0x30, /* 00110000 */
-   0x7c, /* 01111100 */
-   0x30, /* 00110000 */
-   0x30, /* 00110000 */
-   0x36, /* 00110110 */
-   0x1c, /* 00011100 */
-   0x00, /* 00000000 */
-
-   /* 117 0x75 'u' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 118 0x76 'v' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x6c, /* 01101100 */
-   0x38, /* 00111000 */
-   0x00, /* 00000000 */
-
-   /* 119 0x77 'w' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xd6, /* 11010110 */
-   0xfe, /* 11111110 */
-   0x6c, /* 01101100 */
-   0x00, /* 00000000 */
-
-   /* 120 0x78 'x' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xc6, /* 11000110 */
-   0x6c, /* 01101100 */
-   0x38, /* 00111000 */
-   0x6c, /* 01101100 */
-   0xc6, /* 11000110 */
-   0x00, /* 00000000 */
-
-   /* 121 0x79 'y' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xc3, /* 11000011 */
-   0x66, /* 01100110 */
-   0x3c, /* 00111100 */
-   0x18, /* 00011000 */
-   0x30, /* 00110000 */
-   0x60, /* 01100000 */
-
-   /* 122 0x7a 'z' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xfe, /* 11111110 */
-   0x0c, /* 00001100 */
-   0x38, /* 00111000 */
-   0x60, /* 01100000 */
-   0xfe, /* 11111110 */
-   0x00, /* 00000000 */
-
-   /* 123 0x7b '{' */
-   0x0e, /* 00001110 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x70, /* 01110000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x0e, /* 00001110 */
-   0x00, /* 00000000 */
-
-   /* 124 0x7c '|' */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-
-   /* 125 0x7d '}' */
-   0x70, /* 01110000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x0e, /* 00001110 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x70, /* 01110000 */
-   0x00, /* 00000000 */
-
-   /* 126 0x7e '~' */
-   0x72, /* 01110010 */
-   0x9c, /* 10011100 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 127 0x7f '' */
-   0x00, /* 00000000 */
-   0x10, /* 00010000 */
-   0x38, /* 00111000 */
-   0x6c, /* 01101100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xfe, /* 11111110 */
-   0x00, /* 00000000 */
-
-   /* 128 0x80 '€' */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0xc6, /* 11000110 */
-   0x7c, /* 01111100 */
-   0x0c, /* 00001100 */
-   0x78, /* 01111000 */
-
-   /* 129 0x81 '�' */
-   0xcc, /* 11001100 */
-   0x00, /* 00000000 */
-   0xcc, /* 11001100 */
-   0xcc, /* 11001100 */
-   0xcc, /* 11001100 */
-   0xcc, /* 11001100 */
-   0x76, /* 01110110 */
-   0x00, /* 00000000 */
-
-   /* 130 0x82 '‚' */
-   0x0c, /* 00001100 */
-   0x18, /* 00011000 */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0xfe, /* 11111110 */
-   0xc0, /* 11000000 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 131 0x83 'ƒ' */
-   0x7c, /* 01111100 */
-   0x82, /* 10000010 */
-   0x78, /* 01111000 */
-   0x0c, /* 00001100 */
-   0x7c, /* 01111100 */
-   0xcc, /* 11001100 */
-   0x76, /* 01110110 */
-   0x00, /* 00000000 */
-
-   /* 132 0x84 '„' */
-   0xc6, /* 11000110 */
-   0x00, /* 00000000 */
-   0x78, /* 01111000 */
-   0x0c, /* 00001100 */
-   0x7c, /* 01111100 */
-   0xcc, /* 11001100 */
-   0x76, /* 01110110 */
-   0x00, /* 00000000 */
-
-   /* 133 0x85 '…' */
-   0x30, /* 00110000 */
-   0x18, /* 00011000 */
-   0x78, /* 01111000 */
-   0x0c, /* 00001100 */
-   0x7c, /* 01111100 */
-   0xcc, /* 11001100 */
-   0x76, /* 01110110 */
-   0x00, /* 00000000 */
-
-   /* 134 0x86 '†' */
-   0x30, /* 00110000 */
-   0x30, /* 00110000 */
-   0x78, /* 01111000 */
-   0x0c, /* 00001100 */
-   0x7c, /* 01111100 */
-   0xcc, /* 11001100 */
-   0x76, /* 01110110 */
-   0x00, /* 00000000 */
-
-   /* 135 0x87 '‡' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x7e, /* 01111110 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0x7e, /* 01111110 */
-   0x0c, /* 00001100 */
-   0x38, /* 00111000 */
-
-   /* 136 0x88 'ˆ' */
-   0x7c, /* 01111100 */
-   0x82, /* 10000010 */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0xfe, /* 11111110 */
-   0xc0, /* 11000000 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 137 0x89 '‰' */
-   0xc6, /* 11000110 */
-   0x00, /* 00000000 */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0xfe, /* 11111110 */
-   0xc0, /* 11000000 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 138 0x8a 'Š' */
-   0x30, /* 00110000 */
-   0x18, /* 00011000 */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0xfe, /* 11111110 */
-   0xc0, /* 11000000 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 139 0x8b '‹' */
-   0x66, /* 01100110 */
-   0x00, /* 00000000 */
-   0x38, /* 00111000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x3c, /* 00111100 */
-   0x00, /* 00000000 */
-
-   /* 140 0x8c 'Œ' */
-   0x7c, /* 01111100 */
-   0x82, /* 10000010 */
-   0x38, /* 00111000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x3c, /* 00111100 */
-   0x00, /* 00000000 */
-
-   /* 141 0x8d '�' */
-   0x30, /* 00110000 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-   0x38, /* 00111000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x3c, /* 00111100 */
-   0x00, /* 00000000 */
-
-   /* 142 0x8e 'Ž' */
-   0xc6, /* 11000110 */
-   0x38, /* 00111000 */
-   0x6c, /* 01101100 */
-   0xc6, /* 11000110 */
-   0xfe, /* 11111110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x00, /* 00000000 */
-
-   /* 143 0x8f '�' */
-   0x38, /* 00111000 */
-   0x6c, /* 01101100 */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0xfe, /* 11111110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x00, /* 00000000 */
-
-   /* 144 0x90 '�' */
-   0x18, /* 00011000 */
-   0x30, /* 00110000 */
-   0xfe, /* 11111110 */
-   0xc0, /* 11000000 */
-   0xf8, /* 11111000 */
-   0xc0, /* 11000000 */
-   0xfe, /* 11111110 */
-   0x00, /* 00000000 */
-
-   /* 145 0x91 '‘' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x7e, /* 01111110 */
-   0x18, /* 00011000 */
-   0x7e, /* 01111110 */
-   0xd8, /* 11011000 */
-   0x7e, /* 01111110 */
-   0x00, /* 00000000 */
-
-   /* 146 0x92 '’' */
-   0x3e, /* 00111110 */
-   0x6c, /* 01101100 */
-   0xcc, /* 11001100 */
-   0xfe, /* 11111110 */
-   0xcc, /* 11001100 */
-   0xcc, /* 11001100 */
-   0xce, /* 11001110 */
-   0x00, /* 00000000 */
-
-   /* 147 0x93 '“' */
-   0x7c, /* 01111100 */
-   0x82, /* 10000010 */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 148 0x94 '”' */
-   0xc6, /* 11000110 */
-   0x00, /* 00000000 */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 149 0x95 '•' */
-   0x30, /* 00110000 */
-   0x18, /* 00011000 */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 150 0x96 '–' */
-   0x78, /* 01111000 */
-   0x84, /* 10000100 */
-   0x00, /* 00000000 */
-   0xcc, /* 11001100 */
-   0xcc, /* 11001100 */
-   0xcc, /* 11001100 */
-   0x76, /* 01110110 */
-   0x00, /* 00000000 */
-
-   /* 151 0x97 '—' */
-   0x60, /* 01100000 */
-   0x30, /* 00110000 */
-   0xcc, /* 11001100 */
-   0xcc, /* 11001100 */
-   0xcc, /* 11001100 */
-   0xcc, /* 11001100 */
-   0x76, /* 01110110 */
-   0x00, /* 00000000 */
-
-   /* 152 0x98 '˜' */
-   0xc6, /* 11000110 */
-   0x00, /* 00000000 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x7e, /* 01111110 */
-   0x06, /* 00000110 */
-   0xfc, /* 11111100 */
-
-   /* 153 0x99 '™' */
-   0xc6, /* 11000110 */
-   0x38, /* 00111000 */
-   0x6c, /* 01101100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x6c, /* 01101100 */
-   0x38, /* 00111000 */
-   0x00, /* 00000000 */
-
-   /* 154 0x9a 'š' */
-   0xc6, /* 11000110 */
-   0x00, /* 00000000 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 155 0x9b '›' */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x7e, /* 01111110 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0x7e, /* 01111110 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-
-   /* 156 0x9c 'œ' */
-   0x38, /* 00111000 */
-   0x6c, /* 01101100 */
-   0x64, /* 01100100 */
-   0xf0, /* 11110000 */
-   0x60, /* 01100000 */
-   0x66, /* 01100110 */
-   0xfc, /* 11111100 */
-   0x00, /* 00000000 */
-
-   /* 157 0x9d '�' */
-   0x66, /* 01100110 */
-   0x66, /* 01100110 */
-   0x3c, /* 00111100 */
-   0x7e, /* 01111110 */
-   0x18, /* 00011000 */
-   0x7e, /* 01111110 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-
-   /* 158 0x9e 'ž' */
-   0xf8, /* 11111000 */
-   0xcc, /* 11001100 */
-   0xcc, /* 11001100 */
-   0xfa, /* 11111010 */
-   0xc6, /* 11000110 */
-   0xcf, /* 11001111 */
-   0xc6, /* 11000110 */
-   0xc7, /* 11000111 */
-
-   /* 159 0x9f 'Ÿ' */
-   0x0e, /* 00001110 */
-   0x1b, /* 00011011 */
-   0x18, /* 00011000 */
-   0x3c, /* 00111100 */
-   0x18, /* 00011000 */
-   0xd8, /* 11011000 */
-   0x70, /* 01110000 */
-   0x00, /* 00000000 */
-
-   /* 160 0xa0 ' ' */
-   0x18, /* 00011000 */
-   0x30, /* 00110000 */
-   0x78, /* 01111000 */
-   0x0c, /* 00001100 */
-   0x7c, /* 01111100 */
-   0xcc, /* 11001100 */
-   0x76, /* 01110110 */
-   0x00, /* 00000000 */
-
-   /* 161 0xa1 '¡' */
-   0x0c, /* 00001100 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-   0x38, /* 00111000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x3c, /* 00111100 */
-   0x00, /* 00000000 */
-
-   /* 162 0xa2 '¢' */
-   0x0c, /* 00001100 */
-   0x18, /* 00011000 */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-
-   /* 163 0xa3 '£' */
-   0x18, /* 00011000 */
-   0x30, /* 00110000 */
-   0xcc, /* 11001100 */
-   0xcc, /* 11001100 */
-   0xcc, /* 11001100 */
-   0xcc, /* 11001100 */
-   0x76, /* 01110110 */
-   0x00, /* 00000000 */
-
-   /* 164 0xa4 '¤' */
-   0x76, /* 01110110 */
-   0xdc, /* 11011100 */
-   0x00, /* 00000000 */
-   0xdc, /* 11011100 */
-   0x66, /* 01100110 */
-   0x66, /* 01100110 */
-   0x66, /* 01100110 */
-   0x00, /* 00000000 */
-
-   /* 165 0xa5 '¥' */
-   0x76, /* 01110110 */
-   0xdc, /* 11011100 */
-   0x00, /* 00000000 */
-   0xe6, /* 11100110 */
-   0xf6, /* 11110110 */
-   0xde, /* 11011110 */
-   0xce, /* 11001110 */
-   0x00, /* 00000000 */
-
-   /* 166 0xa6 '¦' */
-   0x3c, /* 00111100 */
-   0x6c, /* 01101100 */
-   0x6c, /* 01101100 */
-   0x3e, /* 00111110 */
-   0x00, /* 00000000 */
-   0x7e, /* 01111110 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 167 0xa7 '§' */
-   0x38, /* 00111000 */
-   0x6c, /* 01101100 */
-   0x6c, /* 01101100 */
-   0x38, /* 00111000 */
-   0x00, /* 00000000 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 168 0xa8 '¨' */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x30, /* 00110000 */
-   0x63, /* 01100011 */
-   0x3e, /* 00111110 */
-   0x00, /* 00000000 */
-
-   /* 169 0xa9 '©' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xfe, /* 11111110 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 170 0xaa 'ª' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xfe, /* 11111110 */
-   0x06, /* 00000110 */
-   0x06, /* 00000110 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 171 0xab '«' */
-   0x63, /* 01100011 */
-   0xe6, /* 11100110 */
-   0x6c, /* 01101100 */
-   0x7e, /* 01111110 */
-   0x33, /* 00110011 */
-   0x66, /* 01100110 */
-   0xcc, /* 11001100 */
-   0x0f, /* 00001111 */
-
-   /* 172 0xac '¬' */
-   0x63, /* 01100011 */
-   0xe6, /* 11100110 */
-   0x6c, /* 01101100 */
-   0x7a, /* 01111010 */
-   0x36, /* 00110110 */
-   0x6a, /* 01101010 */
-   0xdf, /* 11011111 */
-   0x06, /* 00000110 */
-
-   /* 173 0xad '­' */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x3c, /* 00111100 */
-   0x3c, /* 00111100 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-
-   /* 174 0xae '®' */
-   0x00, /* 00000000 */
-   0x33, /* 00110011 */
-   0x66, /* 01100110 */
-   0xcc, /* 11001100 */
-   0x66, /* 01100110 */
-   0x33, /* 00110011 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 175 0xaf '¯' */
-   0x00, /* 00000000 */
-   0xcc, /* 11001100 */
-   0x66, /* 01100110 */
-   0x33, /* 00110011 */
-   0x66, /* 01100110 */
-   0xcc, /* 11001100 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 176 0xb0 '°' */
-   0x22, /* 00100010 */
-   0x88, /* 10001000 */
-   0x22, /* 00100010 */
-   0x88, /* 10001000 */
-   0x22, /* 00100010 */
-   0x88, /* 10001000 */
-   0x22, /* 00100010 */
-   0x88, /* 10001000 */
-
-   /* 177 0xb1 '±' */
-   0x55, /* 01010101 */
-   0xaa, /* 10101010 */
-   0x55, /* 01010101 */
-   0xaa, /* 10101010 */
-   0x55, /* 01010101 */
-   0xaa, /* 10101010 */
-   0x55, /* 01010101 */
-   0xaa, /* 10101010 */
-
-   /* 178 0xb2 '²' */
-   0x77, /* 01110111 */
-   0xdd, /* 11011101 */
-   0x77, /* 01110111 */
-   0xdd, /* 11011101 */
-   0x77, /* 01110111 */
-   0xdd, /* 11011101 */
-   0x77, /* 01110111 */
-   0xdd, /* 11011101 */
-
-   /* 179 0xb3 '³' */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-
-   /* 180 0xb4 '´' */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0xf8, /* 11111000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-
-   /* 181 0xb5 'µ' */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0xf8, /* 11111000 */
-   0x18, /* 00011000 */
-   0xf8, /* 11111000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-
-   /* 182 0xb6 '¶' */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0xf6, /* 11110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-
-   /* 183 0xb7 '·' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xfe, /* 11111110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-
-   /* 184 0xb8 '¸' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xf8, /* 11111000 */
-   0x18, /* 00011000 */
-   0xf8, /* 11111000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-
-   /* 185 0xb9 '¹' */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0xf6, /* 11110110 */
-   0x06, /* 00000110 */
-   0xf6, /* 11110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-
-   /* 186 0xba 'º' */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-
-   /* 187 0xbb '»' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xfe, /* 11111110 */
-   0x06, /* 00000110 */
-   0xf6, /* 11110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-
-   /* 188 0xbc '¼' */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0xf6, /* 11110110 */
-   0x06, /* 00000110 */
-   0xfe, /* 11111110 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 189 0xbd '½' */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0xfe, /* 11111110 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 190 0xbe '¾' */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0xf8, /* 11111000 */
-   0x18, /* 00011000 */
-   0xf8, /* 11111000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 191 0xbf '¿' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xf8, /* 11111000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-
-   /* 192 0xc0 'À' */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x1f, /* 00011111 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 193 0xc1 'Á' */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0xff, /* 11111111 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 194 0xc2 'Â' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xff, /* 11111111 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-
-   /* 195 0xc3 'Ã' */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x1f, /* 00011111 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-
-   /* 196 0xc4 'Ä' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xff, /* 11111111 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 197 0xc5 'Å' */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0xff, /* 11111111 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-
-   /* 198 0xc6 'Æ' */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x1f, /* 00011111 */
-   0x18, /* 00011000 */
-   0x1f, /* 00011111 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-
-   /* 199 0xc7 'Ç' */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x37, /* 00110111 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-
-   /* 200 0xc8 'È' */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x37, /* 00110111 */
-   0x30, /* 00110000 */
-   0x3f, /* 00111111 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 201 0xc9 'É' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x3f, /* 00111111 */
-   0x30, /* 00110000 */
-   0x37, /* 00110111 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-
-   /* 202 0xca 'Ê' */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0xf7, /* 11110111 */
-   0x00, /* 00000000 */
-   0xff, /* 11111111 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 203 0xcb 'Ë' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xff, /* 11111111 */
-   0x00, /* 00000000 */
-   0xf7, /* 11110111 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-
-   /* 204 0xcc 'Ì' */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x37, /* 00110111 */
-   0x30, /* 00110000 */
-   0x37, /* 00110111 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-
-   /* 205 0xcd 'Í' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xff, /* 11111111 */
-   0x00, /* 00000000 */
-   0xff, /* 11111111 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 206 0xce 'Î' */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0xf7, /* 11110111 */
-   0x00, /* 00000000 */
-   0xf7, /* 11110111 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-
-   /* 207 0xcf 'Ï' */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0xff, /* 11111111 */
-   0x00, /* 00000000 */
-   0xff, /* 11111111 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 208 0xd0 'Ð' */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0xff, /* 11111111 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 209 0xd1 'Ñ' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xff, /* 11111111 */
-   0x00, /* 00000000 */
-   0xff, /* 11111111 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-
-   /* 210 0xd2 'Ò' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xff, /* 11111111 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-
-   /* 211 0xd3 'Ó' */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x3f, /* 00111111 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 212 0xd4 'Ô' */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x1f, /* 00011111 */
-   0x18, /* 00011000 */
-   0x1f, /* 00011111 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 213 0xd5 'Õ' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x1f, /* 00011111 */
-   0x18, /* 00011000 */
-   0x1f, /* 00011111 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-
-   /* 214 0xd6 'Ö' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x3f, /* 00111111 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-
-   /* 215 0xd7 '×' */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0xff, /* 11111111 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-
-   /* 216 0xd8 'Ø' */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0xff, /* 11111111 */
-   0x18, /* 00011000 */
-   0xff, /* 11111111 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-
-   /* 217 0xd9 'Ù' */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0xf8, /* 11111000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 218 0xda 'Ú' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x1f, /* 00011111 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-
-   /* 219 0xdb 'Û' */
-   0xff, /* 11111111 */
-   0xff, /* 11111111 */
-   0xff, /* 11111111 */
-   0xff, /* 11111111 */
-   0xff, /* 11111111 */
-   0xff, /* 11111111 */
-   0xff, /* 11111111 */
-   0xff, /* 11111111 */
-
-   /* 220 0xdc 'Ü' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xff, /* 11111111 */
-   0xff, /* 11111111 */
-   0xff, /* 11111111 */
-   0xff, /* 11111111 */
-
-   /* 221 0xdd 'Ý' */
-   0xf0, /* 11110000 */
-   0xf0, /* 11110000 */
-   0xf0, /* 11110000 */
-   0xf0, /* 11110000 */
-   0xf0, /* 11110000 */
-   0xf0, /* 11110000 */
-   0xf0, /* 11110000 */
-   0xf0, /* 11110000 */
-
-   /* 222 0xde 'Þ' */
-   0x0f, /* 00001111 */
-   0x0f, /* 00001111 */
-   0x0f, /* 00001111 */
-   0x0f, /* 00001111 */
-   0x0f, /* 00001111 */
-   0x0f, /* 00001111 */
-   0x0f, /* 00001111 */
-   0x0f, /* 00001111 */
-
-   /* 223 0xdf 'ß' */
-   0xff, /* 11111111 */
-   0xff, /* 11111111 */
-   0xff, /* 11111111 */
-   0xff, /* 11111111 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 224 0xe0 'à' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x76, /* 01110110 */
-   0xdc, /* 11011100 */
-   0xc8, /* 11001000 */
-   0xdc, /* 11011100 */
-   0x76, /* 01110110 */
-   0x00, /* 00000000 */
-
-   /* 225 0xe1 'á' */
-   0x78, /* 01111000 */
-   0xcc, /* 11001100 */
-   0xcc, /* 11001100 */
-   0xd8, /* 11011000 */
-   0xcc, /* 11001100 */
-   0xc6, /* 11000110 */
-   0xcc, /* 11001100 */
-   0x00, /* 00000000 */
-
-   /* 226 0xe2 'â' */
-   0xfe, /* 11111110 */
-   0xc6, /* 11000110 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0xc0, /* 11000000 */
-   0x00, /* 00000000 */
-
-   /* 227 0xe3 'ã' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0xfe, /* 11111110 */
-   0x6c, /* 01101100 */
-   0x6c, /* 01101100 */
-   0x6c, /* 01101100 */
-   0x6c, /* 01101100 */
-   0x00, /* 00000000 */
-
-   /* 228 0xe4 'ä' */
-   0xfe, /* 11111110 */
-   0xc6, /* 11000110 */
-   0x60, /* 01100000 */
-   0x30, /* 00110000 */
-   0x60, /* 01100000 */
-   0xc6, /* 11000110 */
-   0xfe, /* 11111110 */
-   0x00, /* 00000000 */
-
-   /* 229 0xe5 'å' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x7e, /* 01111110 */
-   0xd8, /* 11011000 */
-   0xd8, /* 11011000 */
-   0xd8, /* 11011000 */
-   0x70, /* 01110000 */
-   0x00, /* 00000000 */
-
-   /* 230 0xe6 'æ' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x66, /* 01100110 */
-   0x66, /* 01100110 */
-   0x66, /* 01100110 */
-   0x66, /* 01100110 */
-   0x7c, /* 01111100 */
-   0xc0, /* 11000000 */
-
-   /* 231 0xe7 'ç' */
-   0x00, /* 00000000 */
-   0x76, /* 01110110 */
-   0xdc, /* 11011100 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-
-   /* 232 0xe8 'è' */
-   0x7e, /* 01111110 */
-   0x18, /* 00011000 */
-   0x3c, /* 00111100 */
-   0x66, /* 01100110 */
-   0x66, /* 01100110 */
-   0x3c, /* 00111100 */
-   0x18, /* 00011000 */
-   0x7e, /* 01111110 */
-
-   /* 233 0xe9 'é' */
-   0x38, /* 00111000 */
-   0x6c, /* 01101100 */
-   0xc6, /* 11000110 */
-   0xfe, /* 11111110 */
-   0xc6, /* 11000110 */
-   0x6c, /* 01101100 */
-   0x38, /* 00111000 */
-   0x00, /* 00000000 */
-
-   /* 234 0xea 'ê' */
-   0x38, /* 00111000 */
-   0x6c, /* 01101100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x6c, /* 01101100 */
-   0x6c, /* 01101100 */
-   0xee, /* 11101110 */
-   0x00, /* 00000000 */
-
-   /* 235 0xeb 'ë' */
-   0x0e, /* 00001110 */
-   0x18, /* 00011000 */
-   0x0c, /* 00001100 */
-   0x3e, /* 00111110 */
-   0x66, /* 01100110 */
-   0x66, /* 01100110 */
-   0x3c, /* 00111100 */
-   0x00, /* 00000000 */
-
-   /* 236 0xec 'ì' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x7e, /* 01111110 */
-   0xdb, /* 11011011 */
-   0xdb, /* 11011011 */
-   0x7e, /* 01111110 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 237 0xed 'í' */
-   0x06, /* 00000110 */
-   0x0c, /* 00001100 */
-   0x7e, /* 01111110 */
-   0xdb, /* 11011011 */
-   0xdb, /* 11011011 */
-   0x7e, /* 01111110 */
-   0x60, /* 01100000 */
-   0xc0, /* 11000000 */
-
-   /* 238 0xee 'î' */
-   0x1e, /* 00011110 */
-   0x30, /* 00110000 */
-   0x60, /* 01100000 */
-   0x7e, /* 01111110 */
-   0x60, /* 01100000 */
-   0x30, /* 00110000 */
-   0x1e, /* 00011110 */
-   0x00, /* 00000000 */
-
-   /* 239 0xef 'ï' */
-   0x00, /* 00000000 */
-   0x7c, /* 01111100 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0xc6, /* 11000110 */
-   0x00, /* 00000000 */
-
-   /* 240 0xf0 'ð' */
-   0x00, /* 00000000 */
-   0xfe, /* 11111110 */
-   0x00, /* 00000000 */
-   0xfe, /* 11111110 */
-   0x00, /* 00000000 */
-   0xfe, /* 11111110 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 241 0xf1 'ñ' */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x7e, /* 01111110 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-   0x7e, /* 01111110 */
-   0x00, /* 00000000 */
-
-   /* 242 0xf2 'ò' */
-   0x30, /* 00110000 */
-   0x18, /* 00011000 */
-   0x0c, /* 00001100 */
-   0x18, /* 00011000 */
-   0x30, /* 00110000 */
-   0x00, /* 00000000 */
-   0x7e, /* 01111110 */
-   0x00, /* 00000000 */
-
-   /* 243 0xf3 'ó' */
-   0x0c, /* 00001100 */
-   0x18, /* 00011000 */
-   0x30, /* 00110000 */
-   0x18, /* 00011000 */
-   0x0c, /* 00001100 */
-   0x00, /* 00000000 */
-   0x7e, /* 01111110 */
-   0x00, /* 00000000 */
-
-   /* 244 0xf4 'ô' */
-   0x0e, /* 00001110 */
-   0x1b, /* 00011011 */
-   0x1b, /* 00011011 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-
-   /* 245 0xf5 'õ' */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0xd8, /* 11011000 */
-   0xd8, /* 11011000 */
-   0x70, /* 01110000 */
-
-   /* 246 0xf6 'ö' */
-   0x00, /* 00000000 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-   0x7e, /* 01111110 */
-   0x00, /* 00000000 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 247 0xf7 '÷' */
-   0x00, /* 00000000 */
-   0x76, /* 01110110 */
-   0xdc, /* 11011100 */
-   0x00, /* 00000000 */
-   0x76, /* 01110110 */
-   0xdc, /* 11011100 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 248 0xf8 'ø' */
-   0x38, /* 00111000 */
-   0x6c, /* 01101100 */
-   0x6c, /* 01101100 */
-   0x38, /* 00111000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 249 0xf9 'ù' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x18, /* 00011000 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 250 0xfa 'ú' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x18, /* 00011000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 251 0xfb 'û' */
-   0x0f, /* 00001111 */
-   0x0c, /* 00001100 */
-   0x0c, /* 00001100 */
-   0x0c, /* 00001100 */
-   0xec, /* 11101100 */
-   0x6c, /* 01101100 */
-   0x3c, /* 00111100 */
-   0x1c, /* 00011100 */
-
-   /* 252 0xfc 'ü' */
-   0x6c, /* 01101100 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x36, /* 00110110 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 253 0xfd 'ý' */
-   0x78, /* 01111000 */
-   0x0c, /* 00001100 */
-   0x18, /* 00011000 */
-   0x30, /* 00110000 */
-   0x7c, /* 01111100 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 254 0xfe 'þ' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x3c, /* 00111100 */
-   0x3c, /* 00111100 */
-   0x3c, /* 00111100 */
-   0x3c, /* 00111100 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-   /* 255 0xff 'ÿ' */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-   0x00, /* 00000000 */
-
-};
-
-struct fbcon_font_desc font_pearl_8x8 = {
-	PEARL8x8_IDX,
-	"PEARL8x8",
-	8,
-	8,
-	fontdata_pearl8x8,
-	2
-};
diff -Nru a/drivers/video/font_sun12x22.c b/drivers/video/font_sun12x22.c
--- a/drivers/video/font_sun12x22.c	Mon Dec  9 18:46:37 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,6220 +0,0 @@
-#include <video/font.h>
-
-#define FONTDATAMAX 11264
-
-static unsigned char fontdata_sun12x22[FONTDATAMAX] = {
-
-	/* 0 0x00 '^@' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 1 0x01 '^A' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 2 0x02 '^B' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 3 0x03 '^C' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 4 0x04 '^D' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 5 0x05 '^E' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 6 0x06 '^F' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 7 0x07 '^G' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 8 0x08 '^H' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 9 0x09 '^I' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 10 0x0a '^J' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 11 0x0b '^K' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 12 0x0c '^L' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 13 0x0d '^M' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 14 0x0e '^N' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 15 0x0f '^O' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 16 0x10 '^P' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 17 0x11 '^Q' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 18 0x12 '^R' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 19 0x13 '^S' */
-	0x00, 0x00, /* 000000000000 */
-	0x31, 0x80, /* 001100011000 */
-	0x31, 0x80, /* 001100011000 */
-	0x31, 0x80, /* 001100011000 */
-	0x31, 0x80, /* 001100011000 */
-	0x31, 0x80, /* 001100011000 */
-	0x31, 0x80, /* 001100011000 */
-	0x31, 0x80, /* 001100011000 */
-	0x31, 0x80, /* 001100011000 */
-	0x31, 0x80, /* 001100011000 */
-	0x31, 0x80, /* 001100011000 */
-	0x31, 0x80, /* 001100011000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x31, 0x80, /* 001100011000 */
-	0x31, 0x80, /* 001100011000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 20 0x14 '^T' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x1f, 0xf0, /* 000111111111 */
-	0x3c, 0xc0, /* 001111001100 */
-	0x7c, 0xc0, /* 011111001100 */
-	0x7c, 0xc0, /* 011111001100 */
-	0x7c, 0xc0, /* 011111001100 */
-	0x3c, 0xc0, /* 001111001100 */
-	0x1c, 0xc0, /* 000111001100 */
-	0x0c, 0xc0, /* 000011001100 */
-	0x0c, 0xc0, /* 000011001100 */
-	0x0c, 0xc0, /* 000011001100 */
-	0x0c, 0xc0, /* 000011001100 */
-	0x0c, 0xc0, /* 000011001100 */
-	0x0c, 0xc0, /* 000011001100 */
-	0x1c, 0xe0, /* 000111001110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 21 0x15 '^U' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x1f, 0x00, /* 000111110000 */
-	0x31, 0x80, /* 001100011000 */
-	0x31, 0x80, /* 001100011000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x1f, 0x00, /* 000111110000 */
-	0x31, 0x80, /* 001100011000 */
-	0x31, 0x80, /* 001100011000 */
-	0x1f, 0x00, /* 000111110000 */
-	0x01, 0x80, /* 000000011000 */
-	0x01, 0x80, /* 000000011000 */
-	0x31, 0x80, /* 001100011000 */
-	0x31, 0x80, /* 001100011000 */
-	0x1f, 0x00, /* 000111110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 22 0x16 '^V' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 23 0x17 '^W' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 24 0x18 '^X' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 25 0x19 '^Y' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 26 0x1a '^Z' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 27 0x1b '^[' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 28 0x1c '^\' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 29 0x1d '^]' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 30 0x1e '^^' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 31 0x1f '^_' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 32 0x20 ' ' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 33 0x21 '!' */
-	0x00, 0x00, /* 000000000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 34 0x22 '"' */
-	0x00, 0x00, /* 000000000000 */
-	0x19, 0x80, /* 000110011000 */
-	0x19, 0x80, /* 000110011000 */
-	0x19, 0x80, /* 000110011000 */
-	0x19, 0x80, /* 000110011000 */
-	0x19, 0x80, /* 000110011000 */
-	0x19, 0x80, /* 000110011000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 35 0x23 '#' */
-	0x00, 0x00, /* 000000000000 */
-	0x03, 0x30, /* 000000110011 */
-	0x03, 0x30, /* 000000110011 */
-	0x03, 0x30, /* 000000110011 */
-	0x06, 0x60, /* 000001100110 */
-	0x1f, 0xf0, /* 000111111111 */
-	0x1f, 0xf0, /* 000111111111 */
-	0x0c, 0xc0, /* 000011001100 */
-	0x0c, 0xc0, /* 000011001100 */
-	0x19, 0x80, /* 000110011000 */
-	0x19, 0x80, /* 000110011000 */
-	0x7f, 0xc0, /* 011111111100 */
-	0x7f, 0xc0, /* 011111111100 */
-	0x33, 0x00, /* 001100110000 */
-	0x66, 0x00, /* 011001100000 */
-	0x66, 0x00, /* 011001100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 36 0x24 '$' */
-	0x00, 0x00, /* 000000000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x1f, 0x80, /* 000111111000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x66, 0xe0, /* 011001101110 */
-	0x66, 0x60, /* 011001100110 */
-	0x66, 0x00, /* 011001100000 */
-	0x3e, 0x00, /* 001111100000 */
-	0x1f, 0x80, /* 000111111000 */
-	0x07, 0xc0, /* 000001111100 */
-	0x06, 0x60, /* 000001100110 */
-	0x06, 0x60, /* 000001100110 */
-	0x66, 0x60, /* 011001100110 */
-	0x7f, 0xc0, /* 011111111100 */
-	0x3f, 0x80, /* 001111111000 */
-	0x06, 0x00, /* 000001100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 37 0x25 '%' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x38, 0xc0, /* 001110001100 */
-	0x4c, 0xc0, /* 010011001100 */
-	0x45, 0x80, /* 010001011000 */
-	0x65, 0x80, /* 011001011000 */
-	0x3b, 0x00, /* 001110110000 */
-	0x03, 0x00, /* 000000110000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0d, 0xc0, /* 000011011100 */
-	0x1a, 0x60, /* 000110100110 */
-	0x1a, 0x20, /* 000110100010 */
-	0x33, 0x20, /* 001100110010 */
-	0x31, 0xc0, /* 001100011100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 38 0x26 '&' */
-	0x00, 0x00, /* 000000000000 */
-	0x07, 0x00, /* 000001110000 */
-	0x0f, 0x80, /* 000011111000 */
-	0x18, 0xc0, /* 000110001100 */
-	0x18, 0xc0, /* 000110001100 */
-	0x18, 0xc0, /* 000110001100 */
-	0x0f, 0x80, /* 000011111000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x3e, 0x00, /* 001111100000 */
-	0x77, 0x00, /* 011101110000 */
-	0x63, 0x60, /* 011000110110 */
-	0x61, 0xe0, /* 011000011110 */
-	0x61, 0xc0, /* 011000011100 */
-	0x61, 0x80, /* 011000011000 */
-	0x3f, 0xe0, /* 001111111110 */
-	0x1e, 0x60, /* 000111100110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 39 0x27 ''' */
-	0x00, 0x00, /* 000000000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x18, 0x00, /* 000110000000 */
-	0x10, 0x00, /* 000100000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 40 0x28 '(' */
-	0x00, 0x00, /* 000000000000 */
-	0x01, 0x80, /* 000000011000 */
-	0x03, 0x00, /* 000000110000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x03, 0x00, /* 000000110000 */
-	0x01, 0x80, /* 000000011000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 41 0x29 ')' */
-	0x00, 0x00, /* 000000000000 */
-	0x18, 0x00, /* 000110000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x03, 0x00, /* 000000110000 */
-	0x03, 0x00, /* 000000110000 */
-	0x03, 0x00, /* 000000110000 */
-	0x03, 0x00, /* 000000110000 */
-	0x03, 0x00, /* 000000110000 */
-	0x03, 0x00, /* 000000110000 */
-	0x03, 0x00, /* 000000110000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x18, 0x00, /* 000110000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 42 0x2a '*' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x06, 0x00, /* 000001100000 */
-	0x66, 0x60, /* 011001100110 */
-	0x76, 0xe0, /* 011101101110 */
-	0x19, 0x80, /* 000110011000 */
-	0x00, 0x00, /* 000000000000 */
-	0x19, 0x80, /* 000110011000 */
-	0x76, 0xe0, /* 011101101110 */
-	0x66, 0x60, /* 011001100110 */
-	0x06, 0x00, /* 000001100000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 43 0x2b '+' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 44 0x2c ',' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x18, 0x00, /* 000110000000 */
-	0x10, 0x00, /* 000100000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 45 0x2d '-' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 46 0x2e '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 47 0x2f '/' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x60, /* 000000000110 */
-	0x00, 0xc0, /* 000000001100 */
-	0x00, 0xc0, /* 000000001100 */
-	0x01, 0x80, /* 000000011000 */
-	0x01, 0x80, /* 000000011000 */
-	0x03, 0x00, /* 000000110000 */
-	0x03, 0x00, /* 000000110000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x18, 0x00, /* 000110000000 */
-	0x18, 0x00, /* 000110000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 48 0x30 '0' */
-	0x00, 0x00, /* 000000000000 */
-	0x07, 0x00, /* 000001110000 */
-	0x0f, 0x80, /* 000011111000 */
-	0x11, 0x80, /* 000100011000 */
-	0x10, 0xc0, /* 000100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0x80, /* 001100001000 */
-	0x18, 0x80, /* 000110001000 */
-	0x1f, 0x00, /* 000111110000 */
-	0x0e, 0x00, /* 000011100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 49 0x31 '1' */
-	0x00, 0x00, /* 000000000000 */
-	0x02, 0x00, /* 000000100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x0e, 0x00, /* 000011100000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x36, 0x00, /* 001101100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 50 0x32 '2' */
-	0x00, 0x00, /* 000000000000 */
-	0x1f, 0x00, /* 000111110000 */
-	0x3f, 0x80, /* 001111111000 */
-	0x61, 0xc0, /* 011000011100 */
-	0x40, 0xc0, /* 010000001100 */
-	0x00, 0xc0, /* 000000001100 */
-	0x00, 0xc0, /* 000000001100 */
-	0x00, 0xc0, /* 000000001100 */
-	0x01, 0x80, /* 000000011000 */
-	0x03, 0x00, /* 000000110000 */
-	0x06, 0x00, /* 000001100000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x18, 0x00, /* 000110000000 */
-	0x30, 0x20, /* 001100000010 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 51 0x33 '3' */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x80, /* 000011111000 */
-	0x1f, 0xc0, /* 000111111100 */
-	0x20, 0xe0, /* 001000001110 */
-	0x40, 0x60, /* 010000000110 */
-	0x00, 0x60, /* 000000000110 */
-	0x00, 0xe0, /* 000000001110 */
-	0x07, 0xc0, /* 000001111100 */
-	0x0f, 0xc0, /* 000011111100 */
-	0x00, 0xe0, /* 000000001110 */
-	0x00, 0x60, /* 000000000110 */
-	0x00, 0x60, /* 000000000110 */
-	0x40, 0x60, /* 010000000110 */
-	0x60, 0x40, /* 011000000100 */
-	0x3f, 0x80, /* 001111111000 */
-	0x1f, 0x00, /* 000111110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 52 0x34 '4' */
-	0x00, 0x00, /* 000000000000 */
-	0x01, 0x80, /* 000000011000 */
-	0x03, 0x80, /* 000000111000 */
-	0x03, 0x80, /* 000000111000 */
-	0x05, 0x80, /* 000001011000 */
-	0x05, 0x80, /* 000001011000 */
-	0x09, 0x80, /* 000010011000 */
-	0x09, 0x80, /* 000010011000 */
-	0x11, 0x80, /* 000100011000 */
-	0x11, 0x80, /* 000100011000 */
-	0x21, 0x80, /* 001000011000 */
-	0x3f, 0xe0, /* 001111111110 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x01, 0x80, /* 000000011000 */
-	0x01, 0x80, /* 000000011000 */
-	0x01, 0x80, /* 000000011000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 53 0x35 '5' */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0xc0, /* 000011111100 */
-	0x0f, 0xc0, /* 000011111100 */
-	0x10, 0x00, /* 000100000000 */
-	0x10, 0x00, /* 000100000000 */
-	0x20, 0x00, /* 001000000000 */
-	0x3f, 0x80, /* 001111111000 */
-	0x31, 0xc0, /* 001100011100 */
-	0x00, 0xe0, /* 000000001110 */
-	0x00, 0x60, /* 000000000110 */
-	0x00, 0x60, /* 000000000110 */
-	0x00, 0x60, /* 000000000110 */
-	0x40, 0x60, /* 010000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x30, 0xc0, /* 001100001100 */
-	0x1f, 0x80, /* 000111111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 54 0x36 '6' */
-	0x00, 0x00, /* 000000000000 */
-	0x07, 0x00, /* 000001110000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x18, 0x00, /* 000110000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x67, 0x80, /* 011001111000 */
-	0x6f, 0xc0, /* 011011111100 */
-	0x70, 0xe0, /* 011100001110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x70, 0x40, /* 011100000100 */
-	0x3f, 0x80, /* 001111111000 */
-	0x1f, 0x00, /* 000111110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 55 0x37 '7' */
-	0x00, 0x00, /* 000000000000 */
-	0x1f, 0xe0, /* 000111111110 */
-	0x3f, 0xe0, /* 001111111110 */
-	0x60, 0x40, /* 011000000100 */
-	0x00, 0x40, /* 000000000100 */
-	0x00, 0xc0, /* 000000001100 */
-	0x00, 0x80, /* 000000001000 */
-	0x00, 0x80, /* 000000001000 */
-	0x01, 0x80, /* 000000011000 */
-	0x01, 0x00, /* 000000010000 */
-	0x01, 0x00, /* 000000010000 */
-	0x03, 0x00, /* 000000110000 */
-	0x02, 0x00, /* 000000100000 */
-	0x02, 0x00, /* 000000100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x04, 0x00, /* 000001000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 56 0x38 '8' */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x11, 0x80, /* 000100011000 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x18, 0x80, /* 000110001000 */
-	0x0d, 0x00, /* 000011010000 */
-	0x06, 0x00, /* 000001100000 */
-	0x0b, 0x00, /* 000010110000 */
-	0x11, 0x80, /* 000100011000 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x18, 0x80, /* 000110001000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 57 0x39 '9' */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x80, /* 000011111000 */
-	0x11, 0xc0, /* 000100011100 */
-	0x20, 0xe0, /* 001000001110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x70, 0xe0, /* 011100001110 */
-	0x3f, 0x60, /* 001111110110 */
-	0x1e, 0x60, /* 000111100110 */
-	0x00, 0x60, /* 000000000110 */
-	0x00, 0xc0, /* 000000001100 */
-	0x00, 0xc0, /* 000000001100 */
-	0x01, 0x80, /* 000000011000 */
-	0x07, 0x00, /* 000001110000 */
-	0x3c, 0x00, /* 001111000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 58 0x3a ':' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 59 0x3b ';' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x18, 0x00, /* 000110000000 */
-	0x10, 0x00, /* 000100000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 60 0x3c '<' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x60, /* 000000000110 */
-	0x01, 0xc0, /* 000000011100 */
-	0x07, 0x00, /* 000001110000 */
-	0x1c, 0x00, /* 000111000000 */
-	0x70, 0x00, /* 011100000000 */
-	0x70, 0x00, /* 011100000000 */
-	0x1c, 0x00, /* 000111000000 */
-	0x07, 0x00, /* 000001110000 */
-	0x01, 0xc0, /* 000000011100 */
-	0x00, 0x60, /* 000000000110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 61 0x3d '=' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 62 0x3e '>' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x38, 0x00, /* 001110000000 */
-	0x0e, 0x00, /* 000011100000 */
-	0x03, 0x80, /* 000000111000 */
-	0x00, 0xe0, /* 000000001110 */
-	0x00, 0xe0, /* 000000001110 */
-	0x03, 0x80, /* 000000111000 */
-	0x0e, 0x00, /* 000011100000 */
-	0x38, 0x00, /* 001110000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 63 0x3f '?' */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x1f, 0x80, /* 000111111000 */
-	0x39, 0xc0, /* 001110011100 */
-	0x20, 0xc0, /* 001000001100 */
-	0x00, 0xc0, /* 000000001100 */
-	0x00, 0xc0, /* 000000001100 */
-	0x01, 0x80, /* 000000011000 */
-	0x03, 0x00, /* 000000110000 */
-	0x06, 0x00, /* 000001100000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 64 0x40 '@' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x80, /* 000011111000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x30, 0x60, /* 001100000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x67, 0x20, /* 011001110010 */
-	0x6f, 0xa0, /* 011011111010 */
-	0x6c, 0xa0, /* 011011001010 */
-	0x6c, 0xa0, /* 011011001010 */
-	0x67, 0xe0, /* 011001111110 */
-	0x60, 0x00, /* 011000000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x3f, 0xe0, /* 001111111110 */
-	0x0f, 0xe0, /* 000011111110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 65 0x41 'A' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x0b, 0x00, /* 000010110000 */
-	0x0b, 0x00, /* 000010110000 */
-	0x09, 0x00, /* 000010010000 */
-	0x11, 0x80, /* 000100011000 */
-	0x11, 0x80, /* 000100011000 */
-	0x10, 0x80, /* 000100001000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x20, 0xc0, /* 001000001100 */
-	0x20, 0x40, /* 001000000100 */
-	0x40, 0x60, /* 010000000110 */
-	0x40, 0x60, /* 010000000110 */
-	0xe0, 0xf0, /* 111000001111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 66 0x42 'B' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xff, 0x00, /* 111111110000 */
-	0x60, 0x80, /* 011000001000 */
-	0x60, 0xc0, /* 011000001100 */
-	0x60, 0xc0, /* 011000001100 */
-	0x60, 0xc0, /* 011000001100 */
-	0x61, 0x80, /* 011000011000 */
-	0x7f, 0x80, /* 011111111000 */
-	0x60, 0xc0, /* 011000001100 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0xc0, /* 011000001100 */
-	0xff, 0x80, /* 111111111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 67 0x43 'C' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0xc0, /* 000011111100 */
-	0x10, 0x60, /* 000100000110 */
-	0x20, 0x20, /* 001000000010 */
-	0x20, 0x00, /* 001000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x20, 0x00, /* 001000000000 */
-	0x30, 0x20, /* 001100000010 */
-	0x18, 0x40, /* 000110000100 */
-	0x0f, 0x80, /* 000011111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 68 0x44 'D' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xff, 0x00, /* 111111110000 */
-	0x61, 0xc0, /* 011000011100 */
-	0x60, 0xc0, /* 011000001100 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x40, /* 011000000100 */
-	0x61, 0x80, /* 011000011000 */
-	0xfe, 0x00, /* 111111100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 69 0x45 'E' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x7f, 0xc0, /* 011111111100 */
-	0x30, 0x40, /* 001100000100 */
-	0x30, 0x40, /* 001100000100 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x80, /* 001100001000 */
-	0x3f, 0x80, /* 001111111000 */
-	0x30, 0x80, /* 001100001000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x20, /* 001100000010 */
-	0x30, 0x20, /* 001100000010 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 70 0x46 'F' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x7f, 0xc0, /* 011111111100 */
-	0x30, 0x40, /* 001100000100 */
-	0x30, 0x40, /* 001100000100 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x80, /* 001100001000 */
-	0x3f, 0x80, /* 001111111000 */
-	0x30, 0x80, /* 001100001000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x78, 0x00, /* 011110000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 71 0x47 'G' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0xc0, /* 000011111100 */
-	0x10, 0x60, /* 000100000110 */
-	0x20, 0x20, /* 001000000010 */
-	0x20, 0x00, /* 001000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x61, 0xf0, /* 011000011111 */
-	0x60, 0x60, /* 011000000110 */
-	0x20, 0x60, /* 001000000110 */
-	0x30, 0x60, /* 001100000110 */
-	0x18, 0x60, /* 000110000110 */
-	0x0f, 0x80, /* 000011111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 72 0x48 'H' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xf0, 0xf0, /* 111100001111 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0xf0, 0xf0, /* 111100001111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 73 0x49 'I' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x1f, 0x80, /* 000111111000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x1f, 0x80, /* 000111111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 74 0x4a 'J' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x1f, 0x80, /* 000111111000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x04, 0x00, /* 000001000000 */
-	0x38, 0x00, /* 001110000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 75 0x4b 'K' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xf0, 0xe0, /* 111100001110 */
-	0x61, 0x80, /* 011000011000 */
-	0x63, 0x00, /* 011000110000 */
-	0x66, 0x00, /* 011001100000 */
-	0x6c, 0x00, /* 011011000000 */
-	0x78, 0x00, /* 011110000000 */
-	0x78, 0x00, /* 011110000000 */
-	0x7c, 0x00, /* 011111000000 */
-	0x6e, 0x00, /* 011011100000 */
-	0x67, 0x00, /* 011001110000 */
-	0x63, 0x80, /* 011000111000 */
-	0x61, 0xc0, /* 011000011100 */
-	0x60, 0xe0, /* 011000001110 */
-	0xf0, 0x70, /* 111100000111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 76 0x4c 'L' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x78, 0x00, /* 011110000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x20, /* 001100000010 */
-	0x30, 0x20, /* 001100000010 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 77 0x4d 'M' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xe0, 0x70, /* 111000000111 */
-	0x60, 0xe0, /* 011000001110 */
-	0x70, 0xe0, /* 011100001110 */
-	0x70, 0xe0, /* 011100001110 */
-	0x70, 0xe0, /* 011100001110 */
-	0x59, 0x60, /* 010110010110 */
-	0x59, 0x60, /* 010110010110 */
-	0x59, 0x60, /* 010110010110 */
-	0x4d, 0x60, /* 010011010110 */
-	0x4e, 0x60, /* 010011100110 */
-	0x4e, 0x60, /* 010011100110 */
-	0x44, 0x60, /* 010001000110 */
-	0x44, 0x60, /* 010001000110 */
-	0xe4, 0xf0, /* 111001001111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 78 0x4e 'N' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xc0, 0x70, /* 110000000111 */
-	0x60, 0x20, /* 011000000010 */
-	0x70, 0x20, /* 011100000010 */
-	0x78, 0x20, /* 011110000010 */
-	0x58, 0x20, /* 010110000010 */
-	0x4c, 0x20, /* 010011000010 */
-	0x46, 0x20, /* 010001100010 */
-	0x47, 0x20, /* 010001110010 */
-	0x43, 0x20, /* 010000110010 */
-	0x41, 0xa0, /* 010000011010 */
-	0x40, 0xe0, /* 010000001110 */
-	0x40, 0xe0, /* 010000001110 */
-	0x40, 0x60, /* 010000000110 */
-	0xe0, 0x30, /* 111000000011 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 79 0x4f 'O' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x11, 0xc0, /* 000100011100 */
-	0x20, 0xc0, /* 001000001100 */
-	0x20, 0x60, /* 001000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x20, 0x40, /* 001000000100 */
-	0x30, 0x40, /* 001100000100 */
-	0x18, 0x80, /* 000110001000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 80 0x50 'P' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x7f, 0x80, /* 011111111000 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0x60, /* 001100000110 */
-	0x30, 0x60, /* 001100000110 */
-	0x30, 0x60, /* 001100000110 */
-	0x30, 0xc0, /* 001100001100 */
-	0x37, 0x80, /* 001101111000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x78, 0x00, /* 011110000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 81 0x51 'Q' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x11, 0xc0, /* 000100011100 */
-	0x20, 0xc0, /* 001000001100 */
-	0x20, 0x60, /* 001000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x30, 0x40, /* 001100000100 */
-	0x38, 0x40, /* 001110000100 */
-	0x1f, 0x80, /* 000111111000 */
-	0x0e, 0x00, /* 000011100000 */
-	0x1f, 0x00, /* 000111110000 */
-	0x23, 0x90, /* 001000111001 */
-	0x01, 0xe0, /* 000000011110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 82 0x52 'R' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xff, 0x00, /* 111111110000 */
-	0x61, 0x80, /* 011000011000 */
-	0x60, 0xc0, /* 011000001100 */
-	0x60, 0xc0, /* 011000001100 */
-	0x60, 0xc0, /* 011000001100 */
-	0x60, 0x80, /* 011000001000 */
-	0x7f, 0x00, /* 011111110000 */
-	0x7c, 0x00, /* 011111000000 */
-	0x6e, 0x00, /* 011011100000 */
-	0x67, 0x00, /* 011001110000 */
-	0x63, 0x80, /* 011000111000 */
-	0x61, 0xc0, /* 011000011100 */
-	0x60, 0xe0, /* 011000001110 */
-	0xf0, 0x70, /* 111100000111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 83 0x53 'S' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x1f, 0xe0, /* 000111111110 */
-	0x30, 0x60, /* 001100000110 */
-	0x60, 0x20, /* 011000000010 */
-	0x60, 0x20, /* 011000000010 */
-	0x70, 0x00, /* 011100000000 */
-	0x3c, 0x00, /* 001111000000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x07, 0x80, /* 000001111000 */
-	0x01, 0xc0, /* 000000011100 */
-	0x00, 0xe0, /* 000000001110 */
-	0x40, 0x60, /* 010000000110 */
-	0x40, 0x60, /* 010000000110 */
-	0x60, 0xc0, /* 011000001100 */
-	0x7f, 0x80, /* 011111111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 84 0x54 'T' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x46, 0x20, /* 010001100010 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x1f, 0x80, /* 000111111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 85 0x55 'U' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xf0, 0x70, /* 111100000111 */
-	0x60, 0x20, /* 011000000010 */
-	0x60, 0x20, /* 011000000010 */
-	0x60, 0x20, /* 011000000010 */
-	0x60, 0x20, /* 011000000010 */
-	0x60, 0x20, /* 011000000010 */
-	0x60, 0x20, /* 011000000010 */
-	0x60, 0x20, /* 011000000010 */
-	0x60, 0x20, /* 011000000010 */
-	0x60, 0x20, /* 011000000010 */
-	0x60, 0x20, /* 011000000010 */
-	0x70, 0x40, /* 011100000100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x1f, 0x80, /* 000111111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 86 0x56 'V' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xe0, 0xe0, /* 111000001110 */
-	0x60, 0x40, /* 011000000100 */
-	0x30, 0x80, /* 001100001000 */
-	0x30, 0x80, /* 001100001000 */
-	0x30, 0x80, /* 001100001000 */
-	0x19, 0x00, /* 000110010000 */
-	0x19, 0x00, /* 000110010000 */
-	0x19, 0x00, /* 000110010000 */
-	0x0a, 0x00, /* 000010100000 */
-	0x0e, 0x00, /* 000011100000 */
-	0x0e, 0x00, /* 000011100000 */
-	0x04, 0x00, /* 000001000000 */
-	0x04, 0x00, /* 000001000000 */
-	0x04, 0x00, /* 000001000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 87 0x57 'W' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xfe, 0xf0, /* 111111101111 */
-	0x66, 0x20, /* 011001100010 */
-	0x66, 0x20, /* 011001100010 */
-	0x66, 0x20, /* 011001100010 */
-	0x76, 0x20, /* 011101100010 */
-	0x77, 0x40, /* 011101110100 */
-	0x33, 0x40, /* 001100110100 */
-	0x37, 0x40, /* 001101110100 */
-	0x3b, 0xc0, /* 001110111100 */
-	0x3b, 0x80, /* 001110111000 */
-	0x19, 0x80, /* 000110011000 */
-	0x19, 0x80, /* 000110011000 */
-	0x19, 0x80, /* 000110011000 */
-	0x19, 0x80, /* 000110011000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 88 0x58 'X' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xf0, 0x70, /* 111100000111 */
-	0x60, 0x20, /* 011000000010 */
-	0x30, 0x40, /* 001100000100 */
-	0x38, 0x80, /* 001110001000 */
-	0x18, 0x80, /* 000110001000 */
-	0x0d, 0x00, /* 000011010000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x0b, 0x00, /* 000010110000 */
-	0x11, 0x80, /* 000100011000 */
-	0x11, 0xc0, /* 000100011100 */
-	0x20, 0xc0, /* 001000001100 */
-	0x40, 0x60, /* 010000000110 */
-	0xe0, 0xf0, /* 111000001111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 89 0x59 'Y' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xf0, 0x70, /* 111100000111 */
-	0x60, 0x20, /* 011000000010 */
-	0x30, 0x40, /* 001100000100 */
-	0x18, 0x80, /* 000110001000 */
-	0x18, 0x80, /* 000110001000 */
-	0x0d, 0x00, /* 000011010000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 90 0x5a 'Z' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xe0, /* 001111111110 */
-	0x20, 0xc0, /* 001000001100 */
-	0x00, 0xc0, /* 000000001100 */
-	0x01, 0x80, /* 000000011000 */
-	0x01, 0x80, /* 000000011000 */
-	0x03, 0x00, /* 000000110000 */
-	0x03, 0x00, /* 000000110000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x18, 0x00, /* 000110000000 */
-	0x18, 0x20, /* 000110000010 */
-	0x3f, 0xe0, /* 001111111110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 91 0x5b '[' */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x80, /* 000011111000 */
-	0x0f, 0x80, /* 000011111000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0f, 0x80, /* 000011111000 */
-	0x0f, 0x80, /* 000011111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 92 0x5c '\' */
-	0x00, 0x00, /* 000000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x18, 0x00, /* 000110000000 */
-	0x18, 0x00, /* 000110000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x03, 0x00, /* 000000110000 */
-	0x03, 0x00, /* 000000110000 */
-	0x01, 0x80, /* 000000011000 */
-	0x01, 0x80, /* 000000011000 */
-	0x00, 0xc0, /* 000000001100 */
-	0x00, 0xc0, /* 000000001100 */
-	0x00, 0x60, /* 000000000110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 93 0x5d ']' */
-	0x00, 0x00, /* 000000000000 */
-	0x1f, 0x00, /* 000111110000 */
-	0x1f, 0x00, /* 000111110000 */
-	0x03, 0x00, /* 000000110000 */
-	0x03, 0x00, /* 000000110000 */
-	0x03, 0x00, /* 000000110000 */
-	0x03, 0x00, /* 000000110000 */
-	0x03, 0x00, /* 000000110000 */
-	0x03, 0x00, /* 000000110000 */
-	0x03, 0x00, /* 000000110000 */
-	0x03, 0x00, /* 000000110000 */
-	0x03, 0x00, /* 000000110000 */
-	0x03, 0x00, /* 000000110000 */
-	0x03, 0x00, /* 000000110000 */
-	0x1f, 0x00, /* 000111110000 */
-	0x1f, 0x00, /* 000111110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 94 0x5e '^' */
-	0x00, 0x00, /* 000000000000 */
-	0x04, 0x00, /* 000001000000 */
-	0x0e, 0x00, /* 000011100000 */
-	0x1b, 0x00, /* 000110110000 */
-	0x31, 0x80, /* 001100011000 */
-	0x60, 0xc0, /* 011000001100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 95 0x5f '_' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 96 0x60 '`' */
-	0x00, 0x00, /* 000000000000 */
-	0x01, 0x00, /* 000000010000 */
-	0x03, 0x00, /* 000000110000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x07, 0x80, /* 000001111000 */
-	0x07, 0x80, /* 000001111000 */
-	0x03, 0x00, /* 000000110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 97 0x61 'a' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x80, /* 000011111000 */
-	0x18, 0xc0, /* 000110001100 */
-	0x10, 0xc0, /* 000100001100 */
-	0x03, 0xc0, /* 000000111100 */
-	0x1c, 0xc0, /* 000111001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x39, 0xc0, /* 001110011100 */
-	0x1e, 0xe0, /* 000111101110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 98 0x62 'b' */
-	0x00, 0x00, /* 000000000000 */
-	0x20, 0x00, /* 001000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0xe0, 0x00, /* 111000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x67, 0x80, /* 011001111000 */
-	0x6f, 0xc0, /* 011011111100 */
-	0x70, 0xe0, /* 011100001110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x70, 0x60, /* 011100000110 */
-	0x78, 0xc0, /* 011110001100 */
-	0x4f, 0x80, /* 010011111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 99 0x63 'c' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x1f, 0x80, /* 000111111000 */
-	0x31, 0xc0, /* 001100011100 */
-	0x20, 0xc0, /* 001000001100 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x70, 0x40, /* 011100000100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x1f, 0x80, /* 000111111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 100 0x64 'd' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x60, /* 000000000110 */
-	0x00, 0xe0, /* 000000001110 */
-	0x00, 0x60, /* 000000000110 */
-	0x00, 0x60, /* 000000000110 */
-	0x00, 0x60, /* 000000000110 */
-	0x0f, 0x60, /* 000011110110 */
-	0x31, 0xe0, /* 001100011110 */
-	0x20, 0xe0, /* 001000001110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x70, 0xe0, /* 011100001110 */
-	0x39, 0x60, /* 001110010110 */
-	0x1e, 0x70, /* 000111100111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 101 0x65 'e' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x30, 0xc0, /* 001100001100 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x18, 0x60, /* 000110000110 */
-	0x0f, 0x80, /* 000011111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 102 0x66 'f' */
-	0x00, 0x00, /* 000000000000 */
-	0x03, 0x80, /* 000000111000 */
-	0x04, 0xc0, /* 000001001100 */
-	0x04, 0xc0, /* 000001001100 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x3f, 0x80, /* 001111111000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 103 0x67 'g' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x1f, 0x20, /* 000111110010 */
-	0x31, 0xe0, /* 001100011110 */
-	0x60, 0xc0, /* 011000001100 */
-	0x60, 0xc0, /* 011000001100 */
-	0x60, 0xc0, /* 011000001100 */
-	0x31, 0x80, /* 001100011000 */
-	0x3f, 0x00, /* 001111110000 */
-	0x60, 0x00, /* 011000000000 */
-	0x7f, 0xc0, /* 011111111100 */
-	0x3f, 0xe0, /* 001111111110 */
-	0x20, 0x60, /* 001000000110 */
-	0x40, 0x20, /* 010000000010 */
-	0x40, 0x20, /* 010000000010 */
-	0x7f, 0xc0, /* 011111111100 */
-	0x3f, 0x80, /* 001111111000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 104 0x68 'h' */
-	0x00, 0x00, /* 000000000000 */
-	0x10, 0x00, /* 000100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x70, 0x00, /* 011100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x37, 0x80, /* 001101111000 */
-	0x39, 0xc0, /* 001110011100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x79, 0xe0, /* 011110011110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 105 0x69 'i' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x1f, 0x80, /* 000111111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 106 0x6a 'j' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0xc0, /* 000000001100 */
-	0x00, 0xc0, /* 000000001100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x03, 0xc0, /* 000000111100 */
-	0x00, 0xc0, /* 000000001100 */
-	0x00, 0xc0, /* 000000001100 */
-	0x00, 0xc0, /* 000000001100 */
-	0x00, 0xc0, /* 000000001100 */
-	0x00, 0xc0, /* 000000001100 */
-	0x00, 0xc0, /* 000000001100 */
-	0x00, 0xc0, /* 000000001100 */
-	0x00, 0xc0, /* 000000001100 */
-	0x00, 0xc0, /* 000000001100 */
-	0x20, 0xc0, /* 001000001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x38, 0x80, /* 001110001000 */
-	0x1f, 0x00, /* 000111110000 */
-	0x0e, 0x00, /* 000011100000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 107 0x6b 'k' */
-	0x00, 0x00, /* 000000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0xe0, 0x00, /* 111000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x61, 0xc0, /* 011000011100 */
-	0x63, 0x00, /* 011000110000 */
-	0x66, 0x00, /* 011001100000 */
-	0x7c, 0x00, /* 011111000000 */
-	0x78, 0x00, /* 011110000000 */
-	0x7c, 0x00, /* 011111000000 */
-	0x6e, 0x00, /* 011011100000 */
-	0x67, 0x00, /* 011001110000 */
-	0x63, 0x80, /* 011000111000 */
-	0xf1, 0xe0, /* 111100011110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 108 0x6c 'l' */
-	0x00, 0x00, /* 000000000000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x1f, 0x80, /* 000111111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 109 0x6d 'm' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xdd, 0xc0, /* 110111011100 */
-	0x6e, 0xe0, /* 011011101110 */
-	0x66, 0x60, /* 011001100110 */
-	0x66, 0x60, /* 011001100110 */
-	0x66, 0x60, /* 011001100110 */
-	0x66, 0x60, /* 011001100110 */
-	0x66, 0x60, /* 011001100110 */
-	0x66, 0x60, /* 011001100110 */
-	0x66, 0x60, /* 011001100110 */
-	0xef, 0x70, /* 111011110111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 110 0x6e 'n' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x27, 0x80, /* 001001111000 */
-	0x79, 0xc0, /* 011110011100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x79, 0xe0, /* 011110011110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 111 0x6f 'o' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x80, /* 000011111000 */
-	0x11, 0xc0, /* 000100011100 */
-	0x20, 0xe0, /* 001000001110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x70, 0x40, /* 011100000100 */
-	0x38, 0x80, /* 001110001000 */
-	0x1f, 0x00, /* 000111110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 112 0x70 'p' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xef, 0x80, /* 111011111000 */
-	0x71, 0xc0, /* 011100011100 */
-	0x60, 0xe0, /* 011000001110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x40, /* 011000000100 */
-	0x70, 0x80, /* 011100001000 */
-	0x7f, 0x00, /* 011111110000 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0xf0, 0x00, /* 111100000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 113 0x71 'q' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x20, /* 000011110010 */
-	0x11, 0xe0, /* 000100011110 */
-	0x20, 0xe0, /* 001000001110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x70, 0x60, /* 011100000110 */
-	0x38, 0xe0, /* 001110001110 */
-	0x1f, 0xe0, /* 000111111110 */
-	0x00, 0x60, /* 000000000110 */
-	0x00, 0x60, /* 000000000110 */
-	0x00, 0x60, /* 000000000110 */
-	0x00, 0x60, /* 000000000110 */
-	0x00, 0xf0, /* 000000001111 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 114 0x72 'r' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x73, 0x80, /* 011100111000 */
-	0x34, 0xc0, /* 001101001100 */
-	0x38, 0xc0, /* 001110001100 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x78, 0x00, /* 011110000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 115 0x73 's' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x1f, 0xc0, /* 000111111100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0x40, /* 001100000100 */
-	0x38, 0x00, /* 001110000000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x07, 0x80, /* 000001111000 */
-	0x01, 0xc0, /* 000000011100 */
-	0x20, 0xc0, /* 001000001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x3f, 0x80, /* 001111111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 116 0x74 't' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x04, 0x00, /* 000001000000 */
-	0x04, 0x00, /* 000001000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x7f, 0xc0, /* 011111111100 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0c, 0x20, /* 000011000010 */
-	0x0e, 0x40, /* 000011100100 */
-	0x07, 0x80, /* 000001111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 117 0x75 'u' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x79, 0xe0, /* 011110011110 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x39, 0xc0, /* 001110011100 */
-	0x1e, 0x60, /* 000111100110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 118 0x76 'v' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xf0, 0x70, /* 111100000111 */
-	0x60, 0x20, /* 011000000010 */
-	0x30, 0x40, /* 001100000100 */
-	0x30, 0x40, /* 001100000100 */
-	0x18, 0x80, /* 000110001000 */
-	0x18, 0x80, /* 000110001000 */
-	0x0d, 0x00, /* 000011010000 */
-	0x0d, 0x00, /* 000011010000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 119 0x77 'w' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xff, 0x70, /* 111111110111 */
-	0x66, 0x20, /* 011001100010 */
-	0x66, 0x20, /* 011001100010 */
-	0x66, 0x20, /* 011001100010 */
-	0x37, 0x40, /* 001101110100 */
-	0x3b, 0x40, /* 001110110100 */
-	0x3b, 0x40, /* 001110110100 */
-	0x19, 0x80, /* 000110011000 */
-	0x19, 0x80, /* 000110011000 */
-	0x19, 0x80, /* 000110011000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 120 0x78 'x' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xf8, 0xf0, /* 111110001111 */
-	0x70, 0x40, /* 011100000100 */
-	0x38, 0x80, /* 001110001000 */
-	0x1d, 0x00, /* 000111010000 */
-	0x0e, 0x00, /* 000011100000 */
-	0x07, 0x00, /* 000001110000 */
-	0x0b, 0x80, /* 000010111000 */
-	0x11, 0xc0, /* 000100011100 */
-	0x20, 0xe0, /* 001000001110 */
-	0xf1, 0xf0, /* 111100011111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 121 0x79 'y' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xf0, 0xf0, /* 111100001111 */
-	0x60, 0x20, /* 011000000010 */
-	0x30, 0x40, /* 001100000100 */
-	0x30, 0x40, /* 001100000100 */
-	0x18, 0x80, /* 000110001000 */
-	0x18, 0x80, /* 000110001000 */
-	0x0d, 0x00, /* 000011010000 */
-	0x0d, 0x00, /* 000011010000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x04, 0x00, /* 000001000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x08, 0x00, /* 000010000000 */
-	0x78, 0x00, /* 011110000000 */
-	0x70, 0x00, /* 011100000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 122 0x7a 'z' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x60, 0xe0, /* 011000001110 */
-	0x41, 0xc0, /* 010000011100 */
-	0x03, 0x80, /* 000000111000 */
-	0x07, 0x00, /* 000001110000 */
-	0x0e, 0x00, /* 000011100000 */
-	0x1c, 0x00, /* 000111000000 */
-	0x38, 0x20, /* 001110000010 */
-	0x70, 0x60, /* 011100000110 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 123 0x7b '{' */
-	0x00, 0x00, /* 000000000000 */
-	0x03, 0x80, /* 000000111000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x38, 0x00, /* 001110000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x03, 0x80, /* 000000111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 124 0x7c '|' */
-	0x00, 0x00, /* 000000000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 125 0x7d '}' */
-	0x00, 0x00, /* 000000000000 */
-	0x1c, 0x00, /* 000111000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x03, 0x00, /* 000000110000 */
-	0x01, 0xc0, /* 000000011100 */
-	0x03, 0x00, /* 000000110000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x1c, 0x00, /* 000111000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 126 0x7e '~' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x1c, 0x20, /* 000111000010 */
-	0x3e, 0x60, /* 001111100110 */
-	0x67, 0xc0, /* 011001111100 */
-	0x43, 0x80, /* 010000111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 127 0x7f '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 128 0x80 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0xc0, /* 000011111100 */
-	0x10, 0x60, /* 000100000110 */
-	0x20, 0x20, /* 001000000010 */
-	0x20, 0x00, /* 001000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x20, 0x00, /* 001000000000 */
-	0x30, 0x20, /* 001100000010 */
-	0x18, 0x40, /* 000110000100 */
-	0x0f, 0x80, /* 000011111000 */
-	0x06, 0x00, /* 000001100000 */
-	0x03, 0x00, /* 000000110000 */
-	0x01, 0x80, /* 000000011000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 129 0x81 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x19, 0x80, /* 000110011000 */
-	0x19, 0x80, /* 000110011000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x79, 0xe0, /* 011110011110 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x39, 0xc0, /* 001110011100 */
-	0x1e, 0x60, /* 000111100110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 130 0x82 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x01, 0x80, /* 000000011000 */
-	0x03, 0x00, /* 000000110000 */
-	0x06, 0x00, /* 000001100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x30, 0xc0, /* 001100001100 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x18, 0x60, /* 000110000110 */
-	0x0f, 0x80, /* 000011111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 131 0x83 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x02, 0x00, /* 000000100000 */
-	0x07, 0x00, /* 000001110000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x18, 0xc0, /* 000110001100 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x80, /* 000011111000 */
-	0x18, 0xc0, /* 000110001100 */
-	0x10, 0xc0, /* 000100001100 */
-	0x03, 0xc0, /* 000000111100 */
-	0x1c, 0xc0, /* 000111001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x39, 0xc0, /* 001110011100 */
-	0x1e, 0xe0, /* 000111101110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 132 0x84 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x19, 0x80, /* 000110011000 */
-	0x19, 0x80, /* 000110011000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x80, /* 000011111000 */
-	0x18, 0xc0, /* 000110001100 */
-	0x10, 0xc0, /* 000100001100 */
-	0x03, 0xc0, /* 000000111100 */
-	0x1c, 0xc0, /* 000111001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x39, 0xc0, /* 001110011100 */
-	0x1e, 0xe0, /* 000111101110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 133 0x85 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x03, 0x00, /* 000000110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x80, /* 000011111000 */
-	0x18, 0xc0, /* 000110001100 */
-	0x10, 0xc0, /* 000100001100 */
-	0x03, 0xc0, /* 000000111100 */
-	0x1c, 0xc0, /* 000111001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x39, 0xc0, /* 001110011100 */
-	0x1e, 0xe0, /* 000111101110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 134 0x86 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x07, 0x00, /* 000001110000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x07, 0x00, /* 000001110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x80, /* 000011111000 */
-	0x18, 0xc0, /* 000110001100 */
-	0x10, 0xc0, /* 000100001100 */
-	0x03, 0xc0, /* 000000111100 */
-	0x1c, 0xc0, /* 000111001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x39, 0xc0, /* 001110011100 */
-	0x1e, 0xe0, /* 000111101110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 135 0x87 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x1f, 0x80, /* 000111111000 */
-	0x31, 0xc0, /* 001100011100 */
-	0x20, 0xc0, /* 001000001100 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x70, 0x40, /* 011100000100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x1f, 0x80, /* 000111111000 */
-	0x06, 0x00, /* 000001100000 */
-	0x03, 0x00, /* 000000110000 */
-	0x01, 0x80, /* 000000011000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 136 0x88 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x02, 0x00, /* 000000100000 */
-	0x07, 0x00, /* 000001110000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x18, 0xc0, /* 000110001100 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x30, 0xc0, /* 001100001100 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x18, 0x60, /* 000110000110 */
-	0x0f, 0x80, /* 000011111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 137 0x89 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x19, 0x80, /* 000110011000 */
-	0x19, 0x80, /* 000110011000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x30, 0xc0, /* 001100001100 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x18, 0x60, /* 000110000110 */
-	0x0f, 0x80, /* 000011111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 138 0x8a '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x03, 0x00, /* 000000110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x30, 0xc0, /* 001100001100 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x60, 0x00, /* 011000000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x18, 0x60, /* 000110000110 */
-	0x0f, 0x80, /* 000011111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 139 0x8b '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x19, 0x80, /* 000110011000 */
-	0x19, 0x80, /* 000110011000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x1f, 0x80, /* 000111111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 140 0x8c '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x04, 0x00, /* 000001000000 */
-	0x0e, 0x00, /* 000011100000 */
-	0x1b, 0x00, /* 000110110000 */
-	0x31, 0x80, /* 001100011000 */
-	0x00, 0x00, /* 000000000000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x1f, 0x80, /* 000111111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 141 0x8d '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x18, 0x00, /* 000110000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x1f, 0x80, /* 000111111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 142 0x8e '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x19, 0x80, /* 000110011000 */
-	0x19, 0x80, /* 000110011000 */
-	0x00, 0x00, /* 000000000000 */
-	0x04, 0x00, /* 000001000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x0b, 0x00, /* 000010110000 */
-	0x0b, 0x00, /* 000010110000 */
-	0x19, 0x80, /* 000110011000 */
-	0x11, 0x80, /* 000100011000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x20, 0xc0, /* 001000001100 */
-	0x60, 0x60, /* 011000000110 */
-	0x40, 0x60, /* 010000000110 */
-	0xe0, 0xf0, /* 111000001111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 143 0x8f '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x19, 0x80, /* 000110011000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x04, 0x00, /* 000001000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x0b, 0x00, /* 000010110000 */
-	0x0b, 0x00, /* 000010110000 */
-	0x19, 0x80, /* 000110011000 */
-	0x11, 0x80, /* 000100011000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x20, 0xc0, /* 001000001100 */
-	0x60, 0x60, /* 011000000110 */
-	0x40, 0x60, /* 010000000110 */
-	0xe0, 0xf0, /* 111000001111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 144 0x90 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x03, 0x00, /* 000000110000 */
-	0x06, 0x00, /* 000001100000 */
-	0x08, 0x00, /* 000010000000 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x30, 0x20, /* 001100000010 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x80, /* 001100001000 */
-	0x3f, 0x80, /* 001111111000 */
-	0x30, 0x80, /* 001100001000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x20, /* 001100000010 */
-	0x30, 0x20, /* 001100000010 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 145 0x91 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3d, 0xe0, /* 001111011110 */
-	0x66, 0x30, /* 011001100011 */
-	0x46, 0x30, /* 010001100011 */
-	0x06, 0x30, /* 000001100011 */
-	0x3f, 0xf0, /* 001111111111 */
-	0x66, 0x00, /* 011001100000 */
-	0xc6, 0x00, /* 110001100000 */
-	0xc6, 0x00, /* 110001100000 */
-	0xe7, 0x30, /* 111001110011 */
-	0x7d, 0xe0, /* 011111011110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 146 0x92 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x03, 0xf0, /* 000000111111 */
-	0x07, 0x10, /* 000001110001 */
-	0x07, 0x10, /* 000001110001 */
-	0x0b, 0x00, /* 000010110000 */
-	0x0b, 0x00, /* 000010110000 */
-	0x0b, 0x20, /* 000010110010 */
-	0x13, 0xe0, /* 000100111110 */
-	0x13, 0x20, /* 000100110010 */
-	0x3f, 0x00, /* 001111110000 */
-	0x23, 0x00, /* 001000110000 */
-	0x23, 0x00, /* 001000110000 */
-	0x43, 0x10, /* 010000110001 */
-	0x43, 0x10, /* 010000110001 */
-	0xe7, 0xf0, /* 111001111111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 147 0x93 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x02, 0x00, /* 000000100000 */
-	0x07, 0x00, /* 000001110000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x18, 0xc0, /* 000110001100 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x80, /* 000011111000 */
-	0x11, 0xc0, /* 000100011100 */
-	0x20, 0xe0, /* 001000001110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x70, 0x40, /* 011100000100 */
-	0x38, 0x80, /* 001110001000 */
-	0x1f, 0x00, /* 000111110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 148 0x94 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x19, 0x80, /* 000110011000 */
-	0x19, 0x80, /* 000110011000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x80, /* 000011111000 */
-	0x11, 0xc0, /* 000100011100 */
-	0x20, 0xe0, /* 001000001110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x70, 0x40, /* 011100000100 */
-	0x38, 0x80, /* 001110001000 */
-	0x1f, 0x00, /* 000111110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 149 0x95 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x03, 0x00, /* 000000110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x80, /* 000011111000 */
-	0x11, 0xc0, /* 000100011100 */
-	0x20, 0xe0, /* 001000001110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x70, 0x40, /* 011100000100 */
-	0x38, 0x80, /* 001110001000 */
-	0x1f, 0x00, /* 000111110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 150 0x96 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x02, 0x00, /* 000000100000 */
-	0x07, 0x00, /* 000001110000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x18, 0xc0, /* 000110001100 */
-	0x00, 0x00, /* 000000000000 */
-	0x79, 0xe0, /* 011110011110 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x39, 0xc0, /* 001110011100 */
-	0x1e, 0x60, /* 000111100110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 151 0x97 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x18, 0x00, /* 000110000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x79, 0xe0, /* 011110011110 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x39, 0xc0, /* 001110011100 */
-	0x1e, 0x60, /* 000111100110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 152 0x98 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x19, 0x80, /* 000110011000 */
-	0x19, 0x80, /* 000110011000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xf0, 0xf0, /* 111100001111 */
-	0x60, 0x20, /* 011000000010 */
-	0x30, 0x40, /* 001100000100 */
-	0x30, 0x40, /* 001100000100 */
-	0x18, 0x80, /* 000110001000 */
-	0x18, 0x80, /* 000110001000 */
-	0x0d, 0x00, /* 000011010000 */
-	0x0d, 0x00, /* 000011010000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x04, 0x00, /* 000001000000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x08, 0x00, /* 000010000000 */
-	0x78, 0x00, /* 011110000000 */
-	0x70, 0x00, /* 011100000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 153 0x99 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x19, 0x80, /* 000110011000 */
-	0x19, 0x80, /* 000110011000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x80, /* 000011111000 */
-	0x11, 0xc0, /* 000100011100 */
-	0x20, 0xc0, /* 001000001100 */
-	0x20, 0x60, /* 001000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x20, 0x40, /* 001000000100 */
-	0x30, 0x40, /* 001100000100 */
-	0x18, 0x80, /* 000110001000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 154 0x9a '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x19, 0x80, /* 000110011000 */
-	0x19, 0x80, /* 000110011000 */
-	0xe0, 0x30, /* 111000000011 */
-	0x60, 0x20, /* 011000000010 */
-	0x60, 0x20, /* 011000000010 */
-	0x60, 0x20, /* 011000000010 */
-	0x60, 0x20, /* 011000000010 */
-	0x60, 0x20, /* 011000000010 */
-	0x60, 0x20, /* 011000000010 */
-	0x60, 0x20, /* 011000000010 */
-	0x60, 0x20, /* 011000000010 */
-	0x60, 0x20, /* 011000000010 */
-	0x70, 0x40, /* 011100000100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x1f, 0x80, /* 000111111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 155 0x9b '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x1f, 0x80, /* 000111111000 */
-	0x36, 0xc0, /* 001101101100 */
-	0x26, 0xc0, /* 001001101100 */
-	0x66, 0x00, /* 011001100000 */
-	0x66, 0x00, /* 011001100000 */
-	0x66, 0x00, /* 011001100000 */
-	0x66, 0x00, /* 011001100000 */
-	0x76, 0x40, /* 011101100100 */
-	0x36, 0xc0, /* 001101101100 */
-	0x1f, 0x80, /* 000111111000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 156 0x9c '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x80, /* 000011111000 */
-	0x1c, 0xc0, /* 000111001100 */
-	0x18, 0xc0, /* 000110001100 */
-	0x18, 0x00, /* 000110000000 */
-	0x18, 0x00, /* 000110000000 */
-	0x18, 0x00, /* 000110000000 */
-	0x7e, 0x00, /* 011111100000 */
-	0x7e, 0x00, /* 011111100000 */
-	0x18, 0x00, /* 000110000000 */
-	0x18, 0x00, /* 000110000000 */
-	0x18, 0x00, /* 000110000000 */
-	0x18, 0x00, /* 000110000000 */
-	0x3e, 0x20, /* 001111100010 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x61, 0xc0, /* 011000011100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 157 0x9d '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x30, 0xc0, /* 001100001100 */
-	0x19, 0x80, /* 000110011000 */
-	0x19, 0x80, /* 000110011000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x06, 0x00, /* 000001100000 */
-	0x1f, 0x80, /* 000111111000 */
-	0x06, 0x00, /* 000001100000 */
-	0x1f, 0x80, /* 000111111000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 158 0x9e '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 159 0x9f '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 160 0xa0 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x01, 0x80, /* 000000011000 */
-	0x03, 0x00, /* 000000110000 */
-	0x06, 0x00, /* 000001100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x80, /* 000011111000 */
-	0x18, 0xc0, /* 000110001100 */
-	0x10, 0xc0, /* 000100001100 */
-	0x03, 0xc0, /* 000000111100 */
-	0x1c, 0xc0, /* 000111001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x39, 0xc0, /* 001110011100 */
-	0x1e, 0xe0, /* 000111101110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 161 0xa1 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x01, 0x80, /* 000000011000 */
-	0x03, 0x00, /* 000000110000 */
-	0x06, 0x00, /* 000001100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x1e, 0x00, /* 000111100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x1f, 0x80, /* 000111111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 162 0xa2 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x01, 0x80, /* 000000011000 */
-	0x03, 0x00, /* 000000110000 */
-	0x06, 0x00, /* 000001100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x80, /* 000011111000 */
-	0x11, 0xc0, /* 000100011100 */
-	0x20, 0xe0, /* 001000001110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x60, 0x60, /* 011000000110 */
-	0x70, 0x40, /* 011100000100 */
-	0x38, 0x80, /* 001110001000 */
-	0x1f, 0x00, /* 000111110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 163 0xa3 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x01, 0x80, /* 000000011000 */
-	0x03, 0x00, /* 000000110000 */
-	0x06, 0x00, /* 000001100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x79, 0xe0, /* 011110011110 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x39, 0xc0, /* 001110011100 */
-	0x1e, 0x60, /* 000111100110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 164 0xa4 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x1c, 0x40, /* 000111000100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x23, 0x80, /* 001000111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x27, 0x80, /* 001001111000 */
-	0x79, 0xc0, /* 011110011100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x79, 0xe0, /* 011110011110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 165 0xa5 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x1c, 0x40, /* 000111000100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x23, 0x80, /* 001000111000 */
-	0xc0, 0x70, /* 110000000111 */
-	0x60, 0x20, /* 011000000010 */
-	0x70, 0x20, /* 011100000010 */
-	0x78, 0x20, /* 011110000010 */
-	0x5c, 0x20, /* 010111000010 */
-	0x4e, 0x20, /* 010011100010 */
-	0x47, 0x20, /* 010001110010 */
-	0x43, 0xa0, /* 010000111010 */
-	0x41, 0xe0, /* 010000011110 */
-	0x40, 0xe0, /* 010000001110 */
-	0x40, 0x60, /* 010000000110 */
-	0xe0, 0x30, /* 111000000011 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 166 0xa6 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x1f, 0x00, /* 000111110000 */
-	0x31, 0x80, /* 001100011000 */
-	0x01, 0x80, /* 000000011000 */
-	0x07, 0x80, /* 000001111000 */
-	0x19, 0x80, /* 000110011000 */
-	0x31, 0x80, /* 001100011000 */
-	0x31, 0x80, /* 001100011000 */
-	0x33, 0x80, /* 001100111000 */
-	0x1d, 0xc0, /* 000111011100 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 167 0xa7 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x07, 0x00, /* 000001110000 */
-	0x19, 0x80, /* 000110011000 */
-	0x10, 0xc0, /* 000100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0x80, /* 001100001000 */
-	0x19, 0x80, /* 000110011000 */
-	0x0e, 0x00, /* 000011100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 168 0xa8 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x03, 0x00, /* 000000110000 */
-	0x03, 0x00, /* 000000110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x03, 0x00, /* 000000110000 */
-	0x03, 0x00, /* 000000110000 */
-	0x06, 0x00, /* 000001100000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x18, 0x00, /* 000110000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x40, /* 001100000100 */
-	0x39, 0xc0, /* 001110011100 */
-	0x1f, 0x80, /* 000111111000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 169 0xa9 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 170 0xaa '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0xc0, /* 000000001100 */
-	0x00, 0xc0, /* 000000001100 */
-	0x00, 0xc0, /* 000000001100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 171 0xab '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x10, 0x00, /* 000100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x10, 0x00, /* 000100000000 */
-	0x10, 0x40, /* 000100000100 */
-	0x10, 0x80, /* 000100001000 */
-	0x11, 0x00, /* 000100010000 */
-	0x3a, 0x00, /* 001110100000 */
-	0x05, 0xc0, /* 000001011100 */
-	0x0a, 0x20, /* 000010100010 */
-	0x10, 0x20, /* 000100000010 */
-	0x20, 0xc0, /* 001000001100 */
-	0x41, 0x00, /* 010000010000 */
-	0x02, 0x00, /* 000000100000 */
-	0x03, 0xe0, /* 000000111110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 172 0xac '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x10, 0x00, /* 000100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x10, 0x00, /* 000100000000 */
-	0x10, 0x40, /* 000100000100 */
-	0x10, 0x80, /* 000100001000 */
-	0x11, 0x00, /* 000100010000 */
-	0x3a, 0x40, /* 001110100100 */
-	0x04, 0xc0, /* 000001001100 */
-	0x09, 0x40, /* 000010010100 */
-	0x12, 0x40, /* 000100100100 */
-	0x24, 0x40, /* 001001000100 */
-	0x47, 0xe0, /* 010001111110 */
-	0x00, 0x40, /* 000000000100 */
-	0x00, 0x40, /* 000000000100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 173 0xad '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 174 0xae '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x06, 0x60, /* 000001100110 */
-	0x0c, 0xc0, /* 000011001100 */
-	0x19, 0x80, /* 000110011000 */
-	0x33, 0x00, /* 001100110000 */
-	0x66, 0x00, /* 011001100000 */
-	0x33, 0x00, /* 001100110000 */
-	0x19, 0x80, /* 000110011000 */
-	0x0c, 0xc0, /* 000011001100 */
-	0x06, 0x60, /* 000001100110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 175 0xaf '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x66, 0x00, /* 011001100000 */
-	0x33, 0x00, /* 001100110000 */
-	0x19, 0x80, /* 000110011000 */
-	0x0c, 0xc0, /* 000011001100 */
-	0x06, 0x60, /* 000001100110 */
-	0x0c, 0xc0, /* 000011001100 */
-	0x19, 0x80, /* 000110011000 */
-	0x33, 0x00, /* 001100110000 */
-	0x66, 0x00, /* 011001100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 176 0xb0 '.' */
-	0x0c, 0x30, /* 000011000011 */
-	0x08, 0x20, /* 000010000010 */
-	0x61, 0x80, /* 011000011000 */
-	0x20, 0x80, /* 001000001000 */
-	0x0c, 0x30, /* 000011000011 */
-	0x08, 0x20, /* 000010000010 */
-	0x61, 0x80, /* 011000011000 */
-	0x20, 0x80, /* 001000001000 */
-	0x0c, 0x30, /* 000011000011 */
-	0x08, 0x20, /* 000010000010 */
-	0x61, 0x80, /* 011000011000 */
-	0x20, 0x80, /* 001000001000 */
-	0x0c, 0x30, /* 000011000011 */
-	0x08, 0x20, /* 000010000010 */
-	0x61, 0x80, /* 011000011000 */
-	0x20, 0x80, /* 001000001000 */
-	0x0c, 0x30, /* 000011000011 */
-	0x08, 0x20, /* 000010000010 */
-	0x61, 0x80, /* 011000011000 */
-	0x20, 0x80, /* 001000001000 */
-	0x0c, 0x30, /* 000011000011 */
-	0x08, 0x20, /* 000010000010 */
-
-	/* 177 0xb1 '.' */
-	0x77, 0x70, /* 011101110111 */
-	0x22, 0x20, /* 001000100010 */
-	0x88, 0x80, /* 100010001000 */
-	0xdd, 0xd0, /* 110111011101 */
-	0x88, 0x80, /* 100010001000 */
-	0x22, 0x20, /* 001000100010 */
-	0x77, 0x70, /* 011101110111 */
-	0x22, 0x20, /* 001000100010 */
-	0x88, 0x80, /* 100010001000 */
-	0xdd, 0xd0, /* 110111011101 */
-	0x88, 0x80, /* 100010001000 */
-	0x22, 0x20, /* 001000100010 */
-	0x77, 0x70, /* 011101110111 */
-	0x22, 0x20, /* 001000100010 */
-	0x88, 0x80, /* 100010001000 */
-	0xdd, 0xd0, /* 110111011101 */
-	0x88, 0x80, /* 100010001000 */
-	0x22, 0x20, /* 001000100010 */
-	0x77, 0x70, /* 011101110111 */
-	0x22, 0x20, /* 001000100010 */
-	0x88, 0x80, /* 100010001000 */
-	0xdd, 0xd0, /* 110111011101 */
-
-	/* 178 0xb2 '.' */
-	0xf3, 0xc0, /* 111100111100 */
-	0xf7, 0xd0, /* 111101111101 */
-	0x9e, 0x70, /* 100111100111 */
-	0xdf, 0x70, /* 110111110111 */
-	0xf3, 0xc0, /* 111100111100 */
-	0xf7, 0xd0, /* 111101111101 */
-	0x9e, 0x70, /* 100111100111 */
-	0xdf, 0x70, /* 110111110111 */
-	0xf3, 0xc0, /* 111100111100 */
-	0xf7, 0xd0, /* 111101111101 */
-	0x9e, 0x70, /* 100111100111 */
-	0xdf, 0x70, /* 110111110111 */
-	0xf3, 0xc0, /* 111100111100 */
-	0xf7, 0xd0, /* 111101111101 */
-	0x9e, 0x70, /* 100111100111 */
-	0xdf, 0x70, /* 110111110111 */
-	0xf3, 0xc0, /* 111100111100 */
-	0xf7, 0xd0, /* 111101111101 */
-	0x9e, 0x70, /* 100111100111 */
-	0xdf, 0x70, /* 110111110111 */
-	0xf3, 0xc0, /* 111100111100 */
-	0xf7, 0xd0, /* 111101111101 */
-
-	/* 179 0xb3 '.' */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-
-	/* 180 0xb4 '.' */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0xfe, 0x00, /* 111111100000 */
-	0xfe, 0x00, /* 111111100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-
-	/* 181 0xb5 '.' */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0xfe, 0x00, /* 111111100000 */
-	0xfe, 0x00, /* 111111100000 */
-	0x06, 0x00, /* 000001100000 */
-	0xfe, 0x00, /* 111111100000 */
-	0xfe, 0x00, /* 111111100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-
-	/* 182 0xb6 '.' */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0xfd, 0x80, /* 111111011000 */
-	0xfd, 0x80, /* 111111011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-
-	/* 183 0xb7 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xff, 0x80, /* 111111111000 */
-	0xff, 0x80, /* 111111111000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-
-	/* 184 0xb8 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xfe, 0x00, /* 111111100000 */
-	0xfe, 0x00, /* 111111100000 */
-	0x06, 0x00, /* 000001100000 */
-	0xfe, 0x00, /* 111111100000 */
-	0xfe, 0x00, /* 111111100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-
-	/* 185 0xb9 '.' */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0xfd, 0x80, /* 111111011000 */
-	0xfd, 0x80, /* 111111011000 */
-	0x01, 0x80, /* 000000011000 */
-	0xfd, 0x80, /* 111111011000 */
-	0xfd, 0x80, /* 111111011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-
-	/* 186 0xba '.' */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-
-	/* 187 0xbb '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xff, 0x80, /* 111111111000 */
-	0xff, 0x80, /* 111111111000 */
-	0x01, 0x80, /* 000000011000 */
-	0xfd, 0x80, /* 111111011000 */
-	0xfd, 0x80, /* 111111011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-
-	/* 188 0xbc '.' */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0xfd, 0x80, /* 111111011000 */
-	0xfd, 0x80, /* 111111011000 */
-	0x01, 0x80, /* 000000011000 */
-	0xff, 0x80, /* 111111111000 */
-	0xff, 0x80, /* 111111111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 189 0xbd '.' */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0xff, 0x80, /* 111111111000 */
-	0xff, 0x80, /* 111111111000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 190 0xbe '.' */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0xfe, 0x00, /* 111111100000 */
-	0xfe, 0x00, /* 111111100000 */
-	0x06, 0x00, /* 000001100000 */
-	0xfe, 0x00, /* 111111100000 */
-	0xfe, 0x00, /* 111111100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 191 0xbf '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xfe, 0x00, /* 111111100000 */
-	0xfe, 0x00, /* 111111100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-
-	/* 192 0xc0 '.' */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x07, 0xf0, /* 000001111111 */
-	0x07, 0xf0, /* 000001111111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 193 0xc1 '.' */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 194 0xc2 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-
-	/* 195 0xc3 '.' */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x07, 0xf0, /* 000001111111 */
-	0x07, 0xf0, /* 000001111111 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-
-	/* 196 0xc4 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 197 0xc5 '.' */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-
-	/* 198 0xc6 '.' */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x07, 0xf0, /* 000001111111 */
-	0x07, 0xf0, /* 000001111111 */
-	0x06, 0x00, /* 000001100000 */
-	0x07, 0xf0, /* 000001111111 */
-	0x07, 0xf0, /* 000001111111 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-
-	/* 199 0xc7 '.' */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0xf0, /* 000011011111 */
-	0x0d, 0xf0, /* 000011011111 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-
-	/* 200 0xc8 '.' */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0xf0, /* 000011011111 */
-	0x0d, 0xf0, /* 000011011111 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0f, 0xf0, /* 000011111111 */
-	0x0f, 0xf0, /* 000011111111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 201 0xc9 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0xf0, /* 000011111111 */
-	0x0f, 0xf0, /* 000011111111 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0d, 0xf0, /* 000011011111 */
-	0x0d, 0xf0, /* 000011011111 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-
-	/* 202 0xca '.' */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0xfd, 0xf0, /* 111111011111 */
-	0xfd, 0xf0, /* 111111011111 */
-	0x00, 0x00, /* 000000000000 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 203 0xcb '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0x00, 0x00, /* 000000000000 */
-	0xfd, 0xf0, /* 111111011111 */
-	0xfd, 0xf0, /* 111111011111 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-
-	/* 204 0xcc '.' */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0xf0, /* 000011011111 */
-	0x0d, 0xf0, /* 000011011111 */
-	0x0c, 0x00, /* 000011000000 */
-	0x0d, 0xf0, /* 000011011111 */
-	0x0d, 0xf0, /* 000011011111 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-
-	/* 205 0xcd '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0x00, 0x00, /* 000000000000 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 206 0xce '.' */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0xfd, 0xf0, /* 111111011111 */
-	0xfd, 0xf0, /* 111111011111 */
-	0x00, 0x00, /* 000000000000 */
-	0xfd, 0xf0, /* 111111011111 */
-	0xfd, 0xf0, /* 111111011111 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-
-	/* 207 0xcf '.' */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0x00, 0x00, /* 000000000000 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 208 0xd0 '.' */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 209 0xd1 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0x00, 0x00, /* 000000000000 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-
-	/* 210 0xd2 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-
-	/* 211 0xd3 '.' */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0f, 0xf0, /* 000011111111 */
-	0x0f, 0xf0, /* 000011111111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 212 0xd4 '.' */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x07, 0xf0, /* 000001111111 */
-	0x07, 0xf0, /* 000001111111 */
-	0x06, 0x00, /* 000001100000 */
-	0x07, 0xf0, /* 000001111111 */
-	0x07, 0xf0, /* 000001111111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 213 0xd5 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x07, 0xf0, /* 000001111111 */
-	0x07, 0xf0, /* 000001111111 */
-	0x06, 0x00, /* 000001100000 */
-	0x07, 0xf0, /* 000001111111 */
-	0x07, 0xf0, /* 000001111111 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-
-	/* 214 0xd6 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0xf0, /* 000011111111 */
-	0x0f, 0xf0, /* 000011111111 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-
-	/* 215 0xd7 '.' */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-	0x0d, 0x80, /* 000011011000 */
-
-	/* 216 0xd8 '.' */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0x06, 0x00, /* 000001100000 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-
-	/* 217 0xd9 '.' */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0xfe, 0x00, /* 111111100000 */
-	0xfe, 0x00, /* 111111100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 218 0xda '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x07, 0xf0, /* 000001111111 */
-	0x07, 0xf0, /* 000001111111 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-
-	/* 219 0xdb '.' */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-
-	/* 220 0xdc '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-
-	/* 221 0xdd '.' */
-	0xfc, 0x00, /* 111111000000 */
-	0xfc, 0x00, /* 111111000000 */
-	0xfc, 0x00, /* 111111000000 */
-	0xfc, 0x00, /* 111111000000 */
-	0xfc, 0x00, /* 111111000000 */
-	0xfc, 0x00, /* 111111000000 */
-	0xfc, 0x00, /* 111111000000 */
-	0xfc, 0x00, /* 111111000000 */
-	0xfc, 0x00, /* 111111000000 */
-	0xfc, 0x00, /* 111111000000 */
-	0xfc, 0x00, /* 111111000000 */
-	0xfc, 0x00, /* 111111000000 */
-	0xfc, 0x00, /* 111111000000 */
-	0xfc, 0x00, /* 111111000000 */
-	0xfc, 0x00, /* 111111000000 */
-	0xfc, 0x00, /* 111111000000 */
-	0xfc, 0x00, /* 111111000000 */
-	0xfc, 0x00, /* 111111000000 */
-	0xfc, 0x00, /* 111111000000 */
-	0xfc, 0x00, /* 111111000000 */
-	0xfc, 0x00, /* 111111000000 */
-	0xfc, 0x00, /* 111111000000 */
-
-	/* 222 0xde '.' */
-	0x03, 0xf0, /* 000000111111 */
-	0x03, 0xf0, /* 000000111111 */
-	0x03, 0xf0, /* 000000111111 */
-	0x03, 0xf0, /* 000000111111 */
-	0x03, 0xf0, /* 000000111111 */
-	0x03, 0xf0, /* 000000111111 */
-	0x03, 0xf0, /* 000000111111 */
-	0x03, 0xf0, /* 000000111111 */
-	0x03, 0xf0, /* 000000111111 */
-	0x03, 0xf0, /* 000000111111 */
-	0x03, 0xf0, /* 000000111111 */
-	0x03, 0xf0, /* 000000111111 */
-	0x03, 0xf0, /* 000000111111 */
-	0x03, 0xf0, /* 000000111111 */
-	0x03, 0xf0, /* 000000111111 */
-	0x03, 0xf0, /* 000000111111 */
-	0x03, 0xf0, /* 000000111111 */
-	0x03, 0xf0, /* 000000111111 */
-	0x03, 0xf0, /* 000000111111 */
-	0x03, 0xf0, /* 000000111111 */
-	0x03, 0xf0, /* 000000111111 */
-	0x03, 0xf0, /* 000000111111 */
-
-	/* 223 0xdf '.' */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0xff, 0xf0, /* 111111111111 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 224 0xe0 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 225 0xe1 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x19, 0x80, /* 000110011000 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x31, 0x80, /* 001100011000 */
-	0x37, 0x80, /* 001101111000 */
-	0x31, 0x80, /* 001100011000 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x31, 0x80, /* 001100011000 */
-	0x77, 0x00, /* 011101110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 226 0xe2 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 227 0xe3 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 228 0xe4 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 229 0xe5 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 230 0xe6 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x30, 0xc0, /* 001100001100 */
-	0x39, 0xc0, /* 001110011100 */
-	0x36, 0xe0, /* 001101101110 */
-	0x30, 0x00, /* 001100000000 */
-	0x30, 0x00, /* 001100000000 */
-	0x60, 0x00, /* 011000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 231 0xe7 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 232 0xe8 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 233 0xe9 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 234 0xea '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 235 0xeb '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 236 0xec '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 237 0xed '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 238 0xee '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 239 0xef '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 240 0xf0 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 241 0xf1 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 242 0xf2 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 243 0xf3 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 244 0xf4 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 245 0xf5 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 246 0xf6 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x7f, 0xe0, /* 011111111110 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x06, 0x00, /* 000001100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 247 0xf7 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 248 0xf8 '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x19, 0x80, /* 000110011000 */
-	0x19, 0x80, /* 000110011000 */
-	0x19, 0x80, /* 000110011000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 249 0xf9 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 250 0xfa '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x06, 0x00, /* 000001100000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 251 0xfb '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 252 0xfc '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 253 0xfd '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x1f, 0x80, /* 000111111000 */
-	0x31, 0x80, /* 001100011000 */
-	0x21, 0x80, /* 001000011000 */
-	0x03, 0x00, /* 000000110000 */
-	0x06, 0x00, /* 000001100000 */
-	0x0c, 0x00, /* 000011000000 */
-	0x18, 0x40, /* 000110000100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 254 0xfe '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 255 0xff '.' */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-};
-
-
-struct fbcon_font_desc font_sun_12x22 = {
-	SUN12x22_IDX,
-	"SUN12x22",
-	12,
-	22,
-	fontdata_sun12x22,
-#ifdef __sparc__
-	5
-#else
-	-1
-#endif
-};
diff -Nru a/drivers/video/font_sun8x16.c b/drivers/video/font_sun8x16.c
--- a/drivers/video/font_sun8x16.c	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,275 +0,0 @@
-#include <video/font.h>
-
-#define FONTDATAMAX 4096
-
-static unsigned char fontdata_sun8x16[FONTDATAMAX] = {
-/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x7e,0x81,0xa5,0x81,0x81,0xbd,0x99,0x81,0x81,0x7e,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x7e,0xff,0xdb,0xff,0xff,0xc3,0xe7,0xff,0xff,0x7e,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x6c,0xfe,0xfe,0xfe,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x10,0x38,0x7c,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x18,0x3c,0x3c,0xe7,0xe7,0xe7,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x18,0x3c,0x7e,0xff,0xff,0x7e,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0xff,0xff,0xff,0xff,0xff,0xff,0xe7,0xc3,0xc3,0xe7,0xff,0xff,0xff,0xff,0xff,0xff,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x3c,0x66,0x42,0x42,0x66,0x3c,0x00,0x00,0x00,0x00,0x00,
-/* */ 0xff,0xff,0xff,0xff,0xff,0xc3,0x99,0xbd,0xbd,0x99,0xc3,0xff,0xff,0xff,0xff,0xff,
-/* */ 0x00,0x00,0x1e,0x0e,0x1a,0x32,0x78,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x3c,0x66,0x66,0x66,0x66,0x3c,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x3f,0x33,0x3f,0x30,0x30,0x30,0x30,0x70,0xf0,0xe0,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x7f,0x63,0x7f,0x63,0x63,0x63,0x63,0x67,0xe7,0xe6,0xc0,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x18,0x18,0xdb,0x3c,0xe7,0x3c,0xdb,0x18,0x18,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfe,0xf8,0xf0,0xe0,0xc0,0x80,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x02,0x06,0x0e,0x1e,0x3e,0xfe,0x3e,0x1e,0x0e,0x06,0x02,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x66,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x7f,0xdb,0xdb,0xdb,0x7b,0x1b,0x1b,0x1b,0x1b,0x1b,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x7c,0xc6,0x60,0x38,0x6c,0xc6,0xc6,0x6c,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xfe,0xfe,0xfe,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x18,0x0c,0xfe,0x0c,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xfe,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xc0,0xc0,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x24,0x66,0xff,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7c,0x7c,0xfe,0xfe,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0xfe,0xfe,0x7c,0x7c,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*!*/ 0x00,0x00,0x18,0x3c,0x3c,0x3c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
-/*"*/ 0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*#*/ 0x00,0x00,0x00,0x6c,0x6c,0xfe,0x6c,0x6c,0x6c,0xfe,0x6c,0x6c,0x00,0x00,0x00,0x00,
-/*$*/ 0x18,0x18,0x7c,0xc6,0xc2,0xc0,0x7c,0x06,0x06,0x86,0xc6,0x7c,0x18,0x18,0x00,0x00,
-/*%*/ 0x00,0x00,0x00,0x00,0xc2,0xc6,0x0c,0x18,0x30,0x60,0xc6,0x86,0x00,0x00,0x00,0x00,
-/*&*/ 0x00,0x00,0x38,0x6c,0x6c,0x38,0x76,0xdc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
-/*'*/ 0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*(*/ 0x00,0x00,0x0c,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0c,0x00,0x00,0x00,0x00,
-/*)*/ 0x00,0x00,0x30,0x18,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x18,0x30,0x00,0x00,0x00,0x00,
-/***/ 0x00,0x00,0x00,0x00,0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00,0x00,0x00,0x00,0x00,
-/*+*/ 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
-/*,*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00,
-/*-*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*.*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x02,0x06,0x0c,0x18,0x30,0x60,0xc0,0x80,0x00,0x00,0x00,0x00,
-/*0*/ 0x00,0x00,0x7c,0xc6,0xc6,0xce,0xde,0xf6,0xe6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
-/*1*/ 0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x00,0x00,0x00,0x00,
-/*2*/ 0x00,0x00,0x7c,0xc6,0x06,0x0c,0x18,0x30,0x60,0xc0,0xc6,0xfe,0x00,0x00,0x00,0x00,
-/*3*/ 0x00,0x00,0x7c,0xc6,0x06,0x06,0x3c,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00,
-/*4*/ 0x00,0x00,0x0c,0x1c,0x3c,0x6c,0xcc,0xfe,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00,
-/*5*/ 0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xfc,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00,
-/*6*/ 0x00,0x00,0x38,0x60,0xc0,0xc0,0xfc,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
-/*7*/ 0x00,0x00,0xfe,0xc6,0x06,0x06,0x0c,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00,
-/*8*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7c,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
-/*9*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7e,0x06,0x06,0x06,0x0c,0x78,0x00,0x00,0x00,0x00,
-/*:*/ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
-/*;*/ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00,
-/*<*/ 0x00,0x00,0x00,0x06,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x06,0x00,0x00,0x00,0x00,
-/*=*/ 0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*>*/ 0x00,0x00,0x00,0x60,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x60,0x00,0x00,0x00,0x00,
-/*?*/ 0x00,0x00,0x7c,0xc6,0xc6,0x0c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
-/*@*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xde,0xde,0xde,0xdc,0xc0,0x7c,0x00,0x00,0x00,0x00,
-/*A*/ 0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
-/*B*/ 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x66,0x66,0x66,0x66,0xfc,0x00,0x00,0x00,0x00,
-/*C*/ 0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x00,0x00,0x00,0x00,
-/*D*/ 0x00,0x00,0xf8,0x6c,0x66,0x66,0x66,0x66,0x66,0x66,0x6c,0xf8,0x00,0x00,0x00,0x00,
-/*E*/ 0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00,
-/*F*/ 0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
-/*G*/ 0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xde,0xc6,0xc6,0x66,0x3a,0x00,0x00,0x00,0x00,
-/*H*/ 0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
-/*I*/ 0x00,0x00,0x3c,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
-/*J*/ 0x00,0x00,0x1e,0x0c,0x0c,0x0c,0x0c,0x0c,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00,
-/*K*/ 0x00,0x00,0xe6,0x66,0x66,0x6c,0x78,0x78,0x6c,0x66,0x66,0xe6,0x00,0x00,0x00,0x00,
-/*L*/ 0x00,0x00,0xf0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00,
-/*M*/ 0x00,0x00,0xc3,0xe7,0xff,0xff,0xdb,0xc3,0xc3,0xc3,0xc3,0xc3,0x00,0x00,0x00,0x00,
-/*N*/ 0x00,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
-/*O*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
-/*P*/ 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
-/*Q*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xd6,0xde,0x7c,0x0c,0x0e,0x00,0x00,
-/*R*/ 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x6c,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00,
-/*S*/ 0x00,0x00,0x7c,0xc6,0xc6,0x60,0x38,0x0c,0x06,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
-/*T*/ 0x00,0x00,0xff,0xdb,0x99,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
-/*U*/ 0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
-/*V*/ 0x00,0x00,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x00,0x00,0x00,0x00,
-/*W*/ 0x00,0x00,0xc3,0xc3,0xc3,0xc3,0xc3,0xdb,0xdb,0xff,0x66,0x66,0x00,0x00,0x00,0x00,
-/*X*/ 0x00,0x00,0xc3,0xc3,0x66,0x3c,0x18,0x18,0x3c,0x66,0xc3,0xc3,0x00,0x00,0x00,0x00,
-/*Y*/ 0x00,0x00,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
-/*Z*/ 0x00,0x00,0xff,0xc3,0x86,0x0c,0x18,0x30,0x60,0xc1,0xc3,0xff,0x00,0x00,0x00,0x00,
-/*[*/ 0x00,0x00,0x3c,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3c,0x00,0x00,0x00,0x00,
-/*\*/ 0x00,0x00,0x00,0x80,0xc0,0xe0,0x70,0x38,0x1c,0x0e,0x06,0x02,0x00,0x00,0x00,0x00,
-/*]*/ 0x00,0x00,0x3c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3c,0x00,0x00,0x00,0x00,
-/*^*/ 0x10,0x38,0x6c,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*_*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,
-/*`*/ 0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/*a*/ 0x00,0x00,0x00,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
-/*b*/ 0x00,0x00,0xe0,0x60,0x60,0x78,0x6c,0x66,0x66,0x66,0x66,0x7c,0x00,0x00,0x00,0x00,
-/*c*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc0,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
-/*d*/ 0x00,0x00,0x1c,0x0c,0x0c,0x3c,0x6c,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
-/*e*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
-/*f*/ 0x00,0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
-/*g*/ 0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0xcc,0x78,0x00,
-/*h*/ 0x00,0x00,0xe0,0x60,0x60,0x6c,0x76,0x66,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00,
-/*i*/ 0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
-/*j*/ 0x00,0x00,0x06,0x06,0x00,0x0e,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3c,0x00,
-/*k*/ 0x00,0x00,0xe0,0x60,0x60,0x66,0x6c,0x78,0x78,0x6c,0x66,0xe6,0x00,0x00,0x00,0x00,
-/*l*/ 0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
-/*m*/ 0x00,0x00,0x00,0x00,0x00,0xe6,0xff,0xdb,0xdb,0xdb,0xdb,0xdb,0x00,0x00,0x00,0x00,
-/*n*/ 0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
-/*o*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
-/*p*/ 0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xf0,0x00,
-/*q*/ 0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x0c,0x1e,0x00,
-/*r*/ 0x00,0x00,0x00,0x00,0x00,0xdc,0x76,0x66,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
-/*s*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0x60,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00,0x00,
-/*t*/ 0x00,0x00,0x10,0x30,0x30,0xfc,0x30,0x30,0x30,0x30,0x36,0x1c,0x00,0x00,0x00,0x00,
-/*u*/ 0x00,0x00,0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
-/*v*/ 0x00,0x00,0x00,0x00,0x00,0xc3,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x00,0x00,0x00,0x00,
-/*w*/ 0x00,0x00,0x00,0x00,0x00,0xc3,0xc3,0xc3,0xdb,0xdb,0xff,0x66,0x00,0x00,0x00,0x00,
-/*x*/ 0x00,0x00,0x00,0x00,0x00,0xc3,0x66,0x3c,0x18,0x3c,0x66,0xc3,0x00,0x00,0x00,0x00,
-/*y*/ 0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0xf8,0x00,
-/*z*/ 0x00,0x00,0x00,0x00,0x00,0xfe,0xcc,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00,
-/*{*/ 0x00,0x00,0x0e,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0e,0x00,0x00,0x00,0x00,
-/*|*/ 0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
-/*}*/ 0x00,0x00,0x70,0x18,0x18,0x18,0x0e,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00,
-/*~*/ 0x00,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xc6,0xfe,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x0c,0x06,0x7c,0x00,0x00,
-/* */ 0x00,0x00,0xcc,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x0c,0x18,0x30,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x10,0x38,0x6c,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0xcc,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x60,0x30,0x18,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x38,0x6c,0x38,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x3c,0x66,0x60,0x60,0x66,0x3c,0x0c,0x06,0x3c,0x00,0x00,0x00,
-/* */ 0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x66,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x18,0x3c,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
-/* */ 0x00,0xc6,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
-/* */ 0x38,0x6c,0x38,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
-/* */ 0x18,0x30,0x60,0x00,0xfe,0x66,0x60,0x7c,0x60,0x60,0x66,0xfe,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x6e,0x3b,0x1b,0x7e,0xd8,0xdc,0x77,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x3e,0x6c,0xcc,0xcc,0xfe,0xcc,0xcc,0xcc,0xcc,0xce,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x30,0x78,0xcc,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x60,0x30,0x18,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0xc6,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0x78,0x00,
-/* */ 0x00,0xc6,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
-/* */ 0x00,0xc6,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x18,0x18,0x7e,0xc3,0xc0,0xc0,0xc0,0xc3,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xe6,0xfc,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0xc3,0x66,0x3c,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
-/* */ 0x00,0xfc,0x66,0x66,0x7c,0x62,0x66,0x6f,0x66,0x66,0x66,0xf3,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x0e,0x1b,0x18,0x18,0x18,0x7e,0x18,0x18,0x18,0x18,0x18,0xd8,0x70,0x00,0x00,
-/* */ 0x00,0x18,0x30,0x60,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x0c,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x18,0x30,0x60,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x18,0x30,0x60,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x76,0xdc,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
-/* */ 0x76,0xdc,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x3c,0x6c,0x6c,0x3e,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x38,0x6c,0x6c,0x38,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0xc0,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x60,0xce,0x9b,0x06,0x0c,0x1f,0x00,0x00,
-/* */ 0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x66,0xce,0x96,0x3e,0x06,0x06,0x00,0x00,
-/* */ 0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x3c,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x36,0x6c,0xd8,0x6c,0x36,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0xd8,0x6c,0x36,0x6c,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,
-/* */ 0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,
-/* */ 0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,
-/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* */ 0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* */ 0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* */ 0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* */ 0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* */ 0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* */ 0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* */ 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x3f,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* */ 0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* */ 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* */ 0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* */ 0x18,0x18,0x18,0x18,0x18,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
-/* */ 0x18,0x18,0x18,0x18,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* */ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-/* */ 0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,
-/* */ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
-/* */ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0xd8,0xd8,0xd8,0xdc,0x76,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x78,0xcc,0xcc,0xcc,0xd8,0xcc,0xc6,0xc6,0xc6,0xcc,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0xfe,0xc6,0xc6,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0xfe,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0xfe,0xc6,0x60,0x30,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x7e,0xd8,0xd8,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xc0,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x76,0xdc,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x7e,0x18,0x3c,0x66,0x66,0x66,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0x6c,0x38,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x38,0x6c,0xc6,0xc6,0xc6,0x6c,0x6c,0x6c,0x6c,0xee,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x1e,0x30,0x18,0x0c,0x3e,0x66,0x66,0x66,0x66,0x3c,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x7e,0xdb,0xdb,0xdb,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x03,0x06,0x7e,0xdb,0xdb,0xf3,0x7e,0x60,0xc0,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x1c,0x30,0x60,0x60,0x7c,0x60,0x60,0x60,0x30,0x1c,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0xff,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x00,0x7e,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x00,0x7e,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x0e,0x1b,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x7e,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x38,0x6c,0x6c,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x0f,0x0c,0x0c,0x0c,0x0c,0x0c,0xec,0x6c,0x6c,0x3c,0x1c,0x00,0x00,0x00,0x00,
-/* */ 0x00,0xd8,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x70,0xd8,0x30,0x60,0xc8,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x00,0x00,0x00,0x00,0x00,
-/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-};
-
-struct fbcon_font_desc font_sun_8x16 = {
-	SUN8x16_IDX,
-	"SUN8x16",
-	8,
-	16,
-	fontdata_sun8x16,
-#ifdef __sparc__
-	10
-#else
-	-1
-#endif
-};
diff -Nru a/drivers/video/fonts.c b/drivers/video/fonts.c
--- a/drivers/video/fonts.c	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,135 +0,0 @@
-/*
- * linux/drivers/video/fonts.c -- `Soft' font definitions
- *
- *    Created 1995 by Geert Uytterhoeven
- *    Rewritten 1998 by Martin Mares <mj@ucw.cz>
- *
- *	2001 - Documented with DocBook
- *	- Brad Douglas <brad@neruo.com>
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file COPYING in the main directory of this archive
- * for more details.
- */
-
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#if defined(__mc68000__) || defined(CONFIG_APUS)
-#include <asm/setup.h>
-#endif
-#include <video/font.h>
-
-#define NO_FONTS
-
-static struct fbcon_font_desc *fbcon_fonts[] = {
-#ifdef CONFIG_FONT_8x8
-#undef NO_FONTS
-    &font_vga_8x8,
-#endif
-#ifdef CONFIG_FONT_8x16
-#undef NO_FONTS
-    &font_vga_8x16,
-#endif
-#ifdef CONFIG_FONT_6x11
-#if defined(CONFIG_FBCON_ACCEL) || defined(CONFIG_FB_SBUS)
-#undef NO_FONTS
-#endif
-    &font_vga_6x11,
-#endif
-#ifdef CONFIG_FONT_SUN8x16
-#undef NO_FONTS
-    &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) || defined(CONFIG_FBCON_ACCEL)
-#undef NO_FONTS
-#endif
-    &font_sun_12x22,
-#endif
-#ifdef CONFIG_FONT_ACORN_8x8
-#undef NO_FONTS
-    &font_acorn_8x8,
-#endif
-#ifdef CONFIG_FONT_PEARL_8x8
-#undef NO_FONTS
-    &font_pearl_8x8,
-#endif
-#ifdef CONFIG_FONT_MINI_4x6
-#undef NO_FONTS
-    &font_mini_4x6,
-#endif
-};
-
-#define num_fonts (sizeof(fbcon_fonts)/sizeof(*fbcon_fonts))
-
-#ifdef NO_FONTS
-#error No fonts configured.
-#endif
-
-
-/**
- *	fbcon_find_font - find a font
- *	@name: string name of a font
- *
- *	Find a specified font with string name @name.
- *
- *	Returns %NULL if no font found, or a pointer to the
- *	specified font.
- *
- */
-
-struct fbcon_font_desc *fbcon_find_font(char *name)
-{
-   unsigned int i;
-
-   for (i = 0; i < num_fonts; i++)
-      if (!strcmp(fbcon_fonts[i]->name, name))
-	  return fbcon_fonts[i];
-   return NULL;
-}
-
-
-/**
- *	fbcon_get_default_font - get default font
- *	@xres: screen size of X
- *	@yres: screen size of Y
- *
- *	Get the default font for a specified screen size.
- *	Dimensions are in pixels.
- *
- *	Returns %NULL if no font is found, or a pointer to the
- *	chosen font.
- *
- */
-
-struct fbcon_font_desc *fbcon_get_default_font(int xres, int yres)
-{
-    int i, c, cc;
-    struct fbcon_font_desc *f, *g;
-
-    g = NULL;
-    cc = -10000;
-    for(i=0; i<num_fonts; i++) {
-	f = fbcon_fonts[i];
-	c = f->pref;
-#if defined(__mc68000__) || defined(CONFIG_APUS)
-#ifdef CONFIG_FONT_PEARL_8x8
-	if (MACH_IS_AMIGA && f->idx == PEARL8x8_IDX)
-	    c = 100;
-#endif
-#ifdef CONFIG_FONT_6x11
-	if (MACH_IS_MAC && xres < 640 && f->idx == VGA6x11_IDX)
-	    c = 100;
-#endif
-#endif
-	if ((yres < 400) == (f->height <= 8))
-	    c += 1000;
-	if (c > cc) {
-	    cc = c;
-	    g = f;
-	}
-    }
-    return g;
-}
diff -Nru a/drivers/video/g364fb.c b/drivers/video/g364fb.c
--- a/drivers/video/g364fb.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/video/g364fb.c	Mon Dec  9 18:46:34 2002
@@ -31,8 +31,6 @@
 #include <asm/io.h>
 #include <asm/jazz.h>
 
-#include <video/fbcon.h>
-
 /* 
  * Various defines for the G364
  */
@@ -74,34 +72,33 @@
 #define MON_ID_REG 	0xe4100000	/* unused */
 #define RESET_REG 	0xe4180000	/* Write only */
 
-static struct display disp;
 static struct fb_info fb_info;
 
 static struct fb_fix_screeninfo fb_fix __initdata = {
-	.id =		"G364 8plane",
-	.smem_start =	0x40000000,	/* physical address */
-	.type =		FB_TYPE_PACKED_PIXELS,
-	.visual =	FB_VISUAL_PSEUDOCOLOR,
-	.ypanstep =	1,
-	.accel =	FB_ACCEL_NONE,
+	.id 		= "G364 8plane",
+	.smem_start 	= 0x40000000,	/* physical address */
+	.type 		= FB_TYPE_PACKED_PIXELS,
+	.visual 	= FB_VISUAL_PSEUDOCOLOR,
+	.ypanstep 	= 1,
+	.accel 		= FB_ACCEL_NONE,
 };
 
 static struct fb_var_screeninfo fb_var __initdata = {
-	.bits_per_pixel =8,
-	.red =		{ 0, 8, 0 },
-      	green:		{ 0, 8, 0 },
-      	blue:		{ 0, 8, 0 },
-      	activate:FB_ACTIVATE_NOW,
-      	height:		-1,
-      	width:		-1,
-      	pixclock:39722,
-      	left_margin:	40,
-      	right_margin:	24,
-      	upper_margin:	32,
-      	lower_margin:	11,
-      	hsync_len:	96,
-      	vsync_len:	2,
-      	vmode:		FB_VMODE_NONINTERLACED,
+	.bits_per_pixel = 8,
+	.red 		= { 0, 8, 0 },
+      	.green 		= { 0, 8, 0 },
+      	.blue		= { 0, 8, 0 },
+      	.activate	= FB_ACTIVATE_NOW,
+      	.height		= -1,
+      	.width		= -1,
+      	.pixclock	= 39722,
+      	.left_margin	= 40,
+      	.right_margin	= 24,
+      	.upper_margin	= 32,
+      	.lower_margin	= 11,
+      	.hsync_len 	= 96,
+      	.vsync_len 	= 2,
+      	.vmode		= FB_VMODE_NONINTERLACED,
 };
 
 /*
@@ -109,29 +106,29 @@
  */
 int g364fb_init(void);
 
-static int g364fb_pan_display(struct fb_var_screeninfo *var, int con,
+static int g364fb_pan_display(struct fb_var_screeninfo *var,
 			      struct fb_info *info);
 static int g364fb_setcolreg(u_int regno, u_int red, u_int green,
 			    u_int blue, u_int transp,
 			    struct fb_info *info);
+static int g364fb_cursor(struct fb_info *info, struct fb_cursor *cursor);
 static int g364fb_blank(int blank, struct fb_info *info);
 
 static struct fb_ops g364fb_ops = {
 	.owner		= THIS_MODULE,
-	.fb_set_var	= gen_set_var,
-	.fb_get_cmap	= gen_get_cmap,
-	.fb_set_cmap	= gen_set_cmap,
 	.fb_setcolreg	= g364fb_setcolreg,
 	.fb_pan_display	= g364fb_pan_display,
 	.fb_blank	= g364fb_blank,
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
+	.fb_cursor	= g364fb_cursor,
 };
 
-void fbcon_g364fb_cursor(struct display *p, int mode, int x, int y)
+int g364fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
-	switch (mode) {
+	
+	switch (cursor->enable) {
 	case CM_ERASE:
 		*(unsigned int *) CTLA_REG |= CURS_TOGGLE;
 		break;
@@ -141,9 +138,10 @@
 		*(unsigned int *) CTLA_REG &= ~CURS_TOGGLE;
 		*(unsigned int *) CURS_POS_REG =
 		    ((x * fontwidth(p)) << 12) | ((y * fontheight(p)) -
-						  p->var.yoffset);
+						  info->var.yoffset);
 		break;
 	}
+	return 0;
 }
 
 /*
@@ -151,7 +149,7 @@
  *
  *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
  */
-static int g364fb_pan_display(struct fb_var_screeninfo *var, int con,
+static int g364fb_pan_display(struct fb_var_screeninfo *var, 
 			      struct fb_info *info)
 {
 	if (var->xoffset || var->yoffset + var->yres > var->yres_virtual)
@@ -239,7 +237,6 @@
 	fb_fix.smem_len = (1 << (mem * 2)) * 512 * 1024;
 	fb_var.yres_virtual = fb_fix.smem_len / fb_var.xres;
 
-	strcpy(fb_info.modename, fb_fix.id);
 	fb_info.node = NODEV;
 	fb_info.fbops = &g364fb_ops;
 	fb_info.screen_base = (char *) G364_MEM_BASE;	/* virtual kernel address */
@@ -247,21 +244,10 @@
 	fb_info.fix = fb_fix;
 	fb_info.flags = FBINFO_FLAG_DEFAULT;
 
-	fb_info.disp = &disp;
-	fb_info.currcon = -1;
-	fb_info.fontname[0] = '\0';
-	fb_info.changevar = NULL;
-	fb_info.switch_con = gen_switch;
-	fb_info.updatevar = gen_update_var;
-
 	fb_alloc_cmap(&fb_info.cmap, 255, 0);
-	gen_set_disp(-1, &fb_info);
 
 	if (register_framebuffer(&fb_info) < 0)
 		return -EINVAL;
-
-	printk("fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.node),
-	       fb_info.fix.id);
 	return 0;
 }
 
diff -Nru a/drivers/video/hgafb.c b/drivers/video/hgafb.c
--- a/drivers/video/hgafb.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/video/hgafb.c	Mon Dec  9 18:46:50 2002
@@ -7,6 +7,8 @@
  *
  * History:
  *
+ * - Revision 0.1.8 (23 Oct 2002): Ported to new framebuffer api.
+ * 
  * - Revision 0.1.7 (23 Jan 2001): fix crash resulting from MDA only cards 
  *				   being detected as Hercules.	 (Paul G.)
  * - Revision 0.1.6 (17 Aug 2000): new style structs
@@ -18,8 +20,6 @@
  * - Revision 0.1.3 (22 Jan 2000): modified for the new fb_info structure
  *                                 screen is cleared after rmmod
  *                                 virtual resolutions
- *                                 kernel parameter 'video=hga:font:{fontname}'
- *                                 module parameter 'font={fontname}'
  *                                 module parameter 'nologo={0|1}'
  *                                 the most important: boot logo :)
  * - Revision 0.1.0  (6 Dec 1999): faster scrolling and minor fixes
@@ -44,16 +44,10 @@
 #include <linux/ioport.h>
 #include <asm/io.h>
 #include <asm/vga.h>
-#include <video/fbcon.h>
-#include <video/fbcon-hga.h>
-
-#ifdef MODULE
 
 #define INCLUDE_LINUX_LOGO_DATA
 #include <linux/linux_logo.h>
 
-#endif /* MODULE */
-
 #if 0
 #define DPRINTK(args...) printk(KERN_DEBUG __FILE__": " ##args)
 #else
@@ -71,9 +65,15 @@
 static unsigned long hga_vram_base;		/* Base of video memory */
 static unsigned long hga_vram_len;		/* Size of video memory */
 
+#define HGA_ROWADDR(row) ((row%4)*8192 + (row>>2)*90)
 #define HGA_TXT			0
 #define HGA_GFX			1
 
+static inline u8* rowaddr(struct fb_info *info, u_int row)
+{
+        return info->screen_base + HGA_ROWADDR(row);
+}
+
 static int hga_mode = -1;			/* 0 = txt, 1 = gfx mode */
 
 static enum { TYPE_HERC, TYPE_HERCPLUS, TYPE_HERCCOLOR } hga_type;
@@ -111,58 +111,35 @@
 /* Framebuffer driver structures */
 
 static struct fb_var_screeninfo hga_default_var = {
-	.xres =		720,
-	.yres =		348,
-	.xres_virtual =	720,
-	.yres_virtual =	348,
-	.xoffset =	0,
-	.yoffset =	0,
-	.bits_per_pixel =1,
-	.grayscale =	0,
-	.red =		{0, 1, 0},
-	.green =	{0, 1, 0},
-	.blue =		{0, 1, 0},
-	.transp =	{0, 0, 0},
-	.nonstd =	0,			/* (FB_NONSTD_HGA ?) */
-	.activate =	0,
-	.height =	-1,
-	.width =	-1,
-	.accel_flags =	0,
-	/* pixclock */
-	/* left_margin, right_margin */
-	/* upper_margin, lower_margin */
-	/* hsync_len, vsync_len */
-	/* sync */
-	/* vmode */
+	.xres		= 720,
+	.yres 		= 348,
+	.xres_virtual 	= 720,
+	.yres_virtual	= 348,
+	.bits_per_pixel = 1,
+	.red 		= {0, 1, 0},
+	.green 		= {0, 1, 0},
+	.blue 		= {0, 1, 0},
+	.transp 	= {0, 0, 0},
+	.height 	= -1,
+	.width 		= -1,
 };
 
 static struct fb_fix_screeninfo hga_fix = {
-	.id =		"HGA",
-	.smem_start =	(unsigned long) NULL,
-	.smem_len =	0,
-	.type =		FB_TYPE_PACKED_PIXELS,	/* (not sure) */
-	.type_aux =	0,			/* (not sure) */
-	.visual =	FB_VISUAL_MONO10,
-	.xpanstep =	8,
-	.ypanstep =	8,
-	.ywrapstep =	0,
-	.line_length =	90,
-	.mmio_start =	0,
-	.mmio_len =	0,
-	.accel =	FB_ACCEL_NONE
+	.id 		= "HGA",
+	.type 		= FB_TYPE_PACKED_PIXELS,	/* (not sure) */
+	.visual 	= FB_VISUAL_MONO10,
+	.xpanstep 	= 8,
+	.ypanstep 	= 8,
+	.line_length 	= 90,
+	.accel 		= FB_ACCEL_NONE
 };
 
 static struct fb_info fb_info;
-static struct display disp;
 
 /* Don't assume that tty1 will be the initial current console. */
 static int release_io_port = 0;
 static int release_io_ports = 0;
-
-#ifdef MODULE
-static char *font = NULL;
 static int nologo = 0;
-#endif
 
 /* -------------------------------------------------------------------------
  *
@@ -205,8 +182,6 @@
 		isa_memset_io(hga_vram_base, fillchar, hga_vram_len);
 }
 
-
-#ifdef MODULE
 static void hga_txt_mode(void)
 {
 	unsigned long flags;
@@ -237,7 +212,6 @@
 	hga_mode = HGA_TXT;
 	spin_unlock_irqrestore(&hga_reg_lock, flags);
 }
-#endif /* MODULE */
 
 static void hga_gfx_mode(void)
 {
@@ -270,18 +244,16 @@
 	spin_unlock_irqrestore(&hga_reg_lock, flags);
 }
 
-#ifdef MODULE
-static void hga_show_logo(void)
+static void hga_show_logo(struct fb_info *info)
 {
-	int x, y;
 	unsigned long dest = hga_vram_base;
 	char *logo = linux_logo_bw;
+	int x, y;
+	
 	for (y = 134; y < 134 + 80 ; y++) /* this needs some cleanup */
 		for (x = 0; x < 10 ; x++)
-			isa_writeb(~*(logo++),
-				   (dest + (y%4)*8192 + (y>>2)*90 + x + 40));
+			isa_writeb(~*(logo++),(dest + HGA_ROWADDR(y) + x + 40));
 }
-#endif /* MODULE */	
 
 static void hga_pan(unsigned int xoffset, unsigned int yoffset)
 {
@@ -380,98 +352,34 @@
 	return 1;
 }
 
-/* ------------------------------------------------------------------------- *
- *
- * dispsw functions
- *
- * ------------------------------------------------------------------------- */
-
 /**
- *	hga_set_var - set the user defined part of the display
- *	@var:new video mode
- *	@con:unused
+ *	hgafb_open - open the framebuffer device
  *	@info:pointer to fb_info object containing info for current hga board
- *	
- *	This function is called for changing video modes. Since HGA cards have
- *	only one fixed mode we have not much to do. After checking input 
- *	parameters @var is copied to @info->var and @info->changevar is called.
- *	A zero is returned on success and %-EINVAL for failure.
- *	
- *	FIXME:
- *	This is the most mystical function (at least for me).
- *	What is the exact specification of xxx_set_var()?
- *	Should it handle xoffset, yoffset? Should it do panning?
- *	What does vmode mean?
+ *	@int:open by console system or userland.
  */
 
-int hga_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
+static int hgafb_open(struct fb_info *info, int init)
 {
-	CHKINFO(-EINVAL);
-	DPRINTK("hga_set_var: con:%d, activate:%x, info:0x%x, fb_info:%x\n", con, var->activate, (unsigned)info, (unsigned)&fb_info);
-	
-	if (var->xres != 720 ||	var->yres != 348 ||
-	    var->xres_virtual != 720 ||
-	    var->yres_virtual < 348 || var->yres_virtual > 348 + 16 ||
-	    var->bits_per_pixel != 1 || var->grayscale != 0) {
-		return -EINVAL;
-	}
-	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
-		info->var = *var;
-		if (info->changevar) 
-			(*info->changevar)(con);
-	}
+	hga_gfx_mode();
+	hga_clear_screen();
+	if (!nologo) hga_show_logo(info);
 	return 0;
 }
 
 /**
- *	hga_getcolreg - read color registers
- *	@regno:register index to read out
- *	@red:red value
- *	@green:green value
- *	@blue:blue value
- *	@transp:transparency value
- *	@info:unused
- *
- *	This callback function is used to read the color registers of a HGA
- *	board. Since we have only two fixed colors, RGB values are 0x0000 
- *	for register0 and 0xaaaa for register1.
- *	A zero is returned on success and 1 for failure.
+ *	hgafb_open - open the framebuffer device
+ *	@info:pointer to fb_info object containing info for current hga board
+ *	@int:open by console system or userland.
  */
 
-static int hga_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-			 u_int *transp, struct fb_info *info)
+static int hgafb_release(struct fb_info *info, int init)
 {
-	if (regno == 0) {
-		*red = *green = *blue = 0x0000;
-		*transp = 0;
-	} else if (regno == 1) {
-		*red = *green = *blue = 0xaaaa;
-		*transp = 0;
-	} else
-		return 1;
+	hga_txt_mode();
+	hga_clear_screen();
 	return 0;
 }
 
 /**
- *	hga_get_cmap - get the colormap
- *	@cmap:struct fb_cmap to fill in
- *	@kspc:called from kernel space?
- *	@con:unused
- *	@info:pointer to fb_info object containing info for current hga board
- *
- *	This wrapper function passes it's input parameters to fb_get_cmap().
- *	Callback function hga_getcolreg() is used to read the color registers.
- */
-
-int hga_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-                 struct fb_info *info)
-{
-	CHKINFO(-EINVAL);
-	DPRINTK("hga_get_cmap: con:%d\n", con);
-	return fb_get_cmap(cmap, kspc, hga_getcolreg, info);
-}
-	
-/**
  *	hgafb_setcolreg - set color registers
  *	@regno:register index to set
  *	@red:red value, unused
@@ -496,7 +404,6 @@
 /**
  *	hga_pan_display - pan or wrap the display
  *	@var:contains new xoffset, yoffset and vmode values
- *	@con:unused
  *	@info:pointer to fb_info object containing info for current hga board
  *
  *	This function looks only at xoffset, yoffset and the %FB_VMODE_YWRAP
@@ -505,12 +412,8 @@
  *	A zero is returned on success and %-EINVAL for failure.
  */
 
-int hga_pan_display(struct fb_var_screeninfo *var, int con,
-                    struct fb_info *info)
+int hgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
 {
-	CHKINFO(-EINVAL);
-	DPRINTK("pan_disp: con:%d, wrap:%d, xoff:%d, yoff:%d\n", con, var->vmode & FB_VMODE_YWRAP, var->xoffset, var->yoffset);
-
 	if (var->vmode & FB_VMODE_YWRAP) {
 		if (var->yoffset < 0 || 
 		    var->yoffset >= info->var.yres_virtual ||
@@ -524,13 +427,6 @@
 	}
 
 	hga_pan(var->xoffset, var->yoffset);
-
-	info->var.xoffset = var->xoffset;
-	info->var.yoffset = var->yoffset;
-	if (var->vmode & FB_VMODE_YWRAP)
-		info->var.vmode |= FB_VMODE_YWRAP;
-	else
-		info->var.vmode &= ~FB_VMODE_YWRAP;
 	return 0;
 }
 
@@ -549,93 +445,92 @@
 
 static int hgafb_blank(int blank_mode, struct fb_info *info)
 {
-	CHKINFO( );
-	DPRINTK("hgafb_blank: blank_mode:%d, info:%x, fb_info:%x\n", blank_mode, (unsigned)info, (unsigned)&fb_info);
-
 	hga_blank(blank_mode);
 	return 0;
 }
 
-static struct fb_ops hgafb_ops = {
-	.owner		= THIS_MODULE,
-	.fb_set_var	= hga_set_var,
-	.fb_get_cmap	= hga_get_cmap,
-	.fb_set_cmap	= gen_set_cmap,
-	.fb_setcolreg	= hgafb_setcolreg,
-	.fb_pan_display	= hga_pan_display,
-	.fb_blank	= hgafb_blank,
-};
-		
+static void hgafb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+{
+	u_int rows, y;
+	u8 *dest;
 
-/* ------------------------------------------------------------------------- *
- *
- * Functions in fb_info
- * 
- * ------------------------------------------------------------------------- */
+	y = rect->dy;
 
-/**
- *	hgafbcon_switch - switch console
- *	@con:new console to switch to
- *	@info:pointer to fb_info object containing info for current hga board
- *
- *	This function should install a new colormap and change the video mode.
- *	Since we have fixed colors and only one video mode we have nothing to 
- *	do.
- *	Only console administration is done but it should go to fbcon.c IMHO.
- *	A zero is returned on success and %-EINVAL for failure.
- */
+	for (rows = rect->height; rows--; y++) {
+		dest = rowaddr(info, y) + (rect->dx >> 3);
+		switch (rect->rop) {
+		case ROP_COPY:
+			//fb_memset(dest, rect->color, (rect->width >> 3));
+			break;
+		case ROP_XOR:
+			*dest = ~*dest;
+			break;
+		}
+	}
+}
 
-static int hgafbcon_switch(int con, struct fb_info *info)
+static void hgafb_copyarea(struct fb_info *info, struct fb_copyarea *area)
 {
-	CHKINFO(-EINVAL);
-	DPRINTK("hgafbcon_switch: currcon:%d, con:%d, info:%x, fb_info:%x\n", info->currcon, con, (unsigned)info, (unsigned)&fb_info);
+	u_int rows, y1, y2;
+	u8 *src, *dest;
 
-	/* Save the colormap and video mode */
-#if 0	/* Not necessary in hgafb, we use fixed colormap */
-	fb_copy_cmap(&info->cmap, &fb_display[info->currcon].cmap, 0);
-#endif
+	if (area->dy <= area->sy) {
+		y1 = area->sy;
+		y2 = area->dy;
 
-	if (info->currcon != -1) /* this check is absolute necessary! */
-		memcpy(&fb_display[info->currcon].var, &info->var,
-				sizeof(struct fb_var_screeninfo));
-
-	/* Install a new colormap and change the video mode. By default fbcon
-	 * sets all the colormaps and video modes to the default values at
-	 * bootup.
-	 */
-#if 0
-	fb_copy_cmap(&fb_display[con].cmap, &info->cmap, 0);
-	fb_set_cmap(&info->cmap, 1, info);
-#endif
-
-	memcpy(&info->var, &fb_display[con].var,
-			sizeof(struct fb_var_screeninfo));
-	/* hga_set_var(&info->var, con, &fb_info); is it necessary? */
-	info->currcon = con;
+		for (rows = area->height; rows--; ) {
+			src = rowaddr(info, y1) + (area->sx >> 3);
+			dest = rowaddr(info, y2) + (area->dx >> 3);
+			//fb_memmove(dest, src, (area->width >> 3));
+			y1++;
+			y2++;
+		}
+	} else {
+		y1 = area->sy + area->height - 1;
+		y2 = area->dy + area->height - 1;
 
-	/* Hack to work correctly with XF86_Mono */
-	hga_gfx_mode();
-	return 0;
+		for (rows = area->height; rows--;) {
+			src = rowaddr(info, y1) + (area->sx >> 3);
+			dest = rowaddr(info, y2) + (area->dx >> 3);
+			//fb_memmove(dest, src, (area->width >> 3));
+			y1--;
+			y2--;
+		}
+	}
 }
 
-/**
- *	hgafbcon_updatevar - update the user defined part of the display
- *	@con:console to update or -1 when no consoles defined on this fb
- *	@info:pointer to fb_info object containing info for current hga board
- *
- *	This function is called when @var is changed by fbcon.c without calling 
- *	hga_set_var(). It usually means scrolling.  hga_pan_display() is called
- *	to update the hardware and @info->var.
- *	A zero is returned on success and %-EINVAL for failure.
- */
-
-static int hgafbcon_updatevar(int con, struct fb_info *info)
+static void hgafb_imageblit(struct fb_info *info, struct fb_image *image)
 {
-	CHKINFO(-EINVAL);
-	DPRINTK("hga_update_var: con:%d, info:%x, fb_info:%x\n", con, (unsigned)info, (unsigned)&fb_info);
-	return (con < 0) ? -EINVAL : hga_pan_display(&fb_display[con].var, con, info);
+	u8 *dest, *cdat = image->data;
+	u_int rows, y = image->dy;
+	u8 d;
+
+	for (rows = image->height; rows--; y++) {
+		d = *cdat++;
+		dest = rowaddr(info, y) + (image->dx >> 3);
+		*dest = d;
+	}
 }
 
+
+static struct fb_ops hgafb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_open	= hgafb_open,
+	.fb_release	= hgafb_release,
+	.fb_setcolreg	= hgafb_setcolreg,
+	.fb_pan_display	= hgafb_pan_display,
+	.fb_blank	= hgafb_blank,
+	.fb_fillrect	= cfb_fillrect, //hgafb_fillrect,
+	.fb_copyarea	= cfb_copyarea,	//hgafb_copyarea,
+	.fb_imageblit	= cfb_imageblit,//hgafb_imageblit,
+};
+		
+/* ------------------------------------------------------------------------- *
+ *
+ * Functions in fb_info
+ * 
+ * ------------------------------------------------------------------------- */
+
 /* ------------------------------------------------------------------------- */
     
 	/*
@@ -652,35 +547,9 @@
 	printk(KERN_INFO "hgafb: %s with %ldK of memory detected.\n",
 		hga_type_name, hga_vram_len/1024);
 
-	hga_gfx_mode();
-	hga_clear_screen();
-#ifdef MODULE
-	if (!nologo) hga_show_logo();
-#endif /* MODULE */
-
 	hga_fix.smem_start = VGA_MAP_MEM(hga_vram_base);
 	hga_fix.smem_len = hga_vram_len;
 
-	disp.var = hga_default_var;
-	disp.visual = hga_fix.visual;
-	disp.type = hga_fix.type;
-	disp.type_aux = hga_fix.type_aux;
-	disp.ypanstep = hga_fix.ypanstep;
-	disp.ywrapstep = hga_fix.ywrapstep;
-	disp.line_length = hga_fix.line_length;
-	disp.can_soft_blank = 1;
-	disp.inverse = 0;
-#ifdef FBCON_HAS_HGA
-	disp.dispsw = &fbcon_hga;
-#else
-#warning HGAFB will not work as a console!
-	disp.dispsw = &fbcon_dummy;
-#endif
-	disp.dispsw_data = NULL;
-
-	disp.scrollmode = SCROLL_YREDRAW;
-	
-	strcpy (fb_info.modename, hga_fix.id);
 	fb_info.node = NODEV;
 	fb_info.flags = FBINFO_FLAG_DEFAULT;
 	fb_info.var = hga_default_var;
@@ -692,20 +561,12 @@
 	fb_info.monspecs.dpms = 0;
 	fb_info.fbops = &hgafb_ops;
 	fb_info.screen_base = (char *)hga_fix.smem_start;
-	fb_info.disp = &disp;
-	fb_info.currcon = 1;
-	fb_info.changevar = NULL;
-	fb_info.switch_con = hgafbcon_switch;
-	fb_info.updatevar = hgafbcon_updatevar;
-	fb_info.pseudo_palette = NULL; /* ??? */
-	fb_info.par = NULL;
 
         if (register_framebuffer(&fb_info) < 0)
                 return -EINVAL;
 
         printk(KERN_INFO "fb%d: %s frame buffer device\n",
-               GET_FB_IDX(fb_info.node), fb_info.modename);
-	
+               minor(fb_info.node), fb_info.fix.id);
 	return 0;
 }
 
@@ -713,49 +574,21 @@
 	 *  Setup
 	 */
 
-#ifndef MODULE
 int __init hgafb_setup(char *options)
 {
-	/* 
-	 * Parse user speficied options
-	 * `video=hga:font:VGA8x16' or
-	 * `video=hga:font:SUN8x16' recommended
-	 * Other supported fonts: VGA8x8, Acorn8x8, PEARL8x8
-	 * More different fonts can be used with the `setfont' utility.
-	 */
-
-	char *this_opt;
-
-	fb_info.fontname[0] = '\0';
-
-	if (!options || !*options)
-		return 0;
-
-	while ((this_opt = strsep(&options, ","))) {
-		if (!strncmp(this_opt, "font:", 5))
-			strcpy(fb_info.fontname, this_opt+5);
-	}
 	return 0;
 }
-#endif /* !MODULE */
-
-
-	/*
-	 * Cleanup
-	 */
 
 #ifdef MODULE
-static void hgafb_cleanup(struct fb_info *info)
+static void __exit hgafb_exit(void)
 {
 	hga_txt_mode();
 	hga_clear_screen();
-	unregister_framebuffer(info);
+	unregister_framebuffer(&fb_info);
 	if (release_io_ports) release_region(0x3b0, 12);
 	if (release_io_port) release_region(0x3bf, 1);
 }
-#endif /* MODULE */
-
-
+#endif
 
 /* -------------------------------------------------------------------------
  *
@@ -763,29 +596,14 @@
  *
  * ------------------------------------------------------------------------- */
 
-#ifdef MODULE
-int init_module(void)
-{
-	if (font)
-		strncpy(fb_info.fontname, font, sizeof(fb_info.fontname)-1);
-	else
-		fb_info.fontname[0] = '\0';
-
-	return hgafb_init();
-}
-
-void cleanup_module(void)
-{
-	hgafb_cleanup(&fb_info);
-}
-
 MODULE_AUTHOR("Ferenc Bakonyi (fero@drama.obuda.kando.hu)");
 MODULE_DESCRIPTION("FBDev driver for Hercules Graphics Adaptor");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(font, "s");
-MODULE_PARM_DESC(font, "Specifies one of the compiled-in fonts (VGA8x8, VGA8x16, SUN8x16, Acorn8x8, PEARL8x8) (default=none)");
 MODULE_PARM(nologo, "i");
 MODULE_PARM_DESC(nologo, "Disables startup logo if != 0 (default=0)");
 
-#endif /* MODULE */
+#ifdef MODULE
+module_init(hgafb_init);
+module_exit(hgafb_exit);
+#endif
diff -Nru a/drivers/video/hitfb.c b/drivers/video/hitfb.c
--- a/drivers/video/hitfb.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/video/hitfb.c	Mon Dec  9 18:46:34 2002
@@ -29,8 +29,6 @@
 #include <asm/io.h>
 #include <asm/hd64461.h>
 
-#include <video/fbcon.h>
-
 static struct fb_var_screeninfo hitfb_var __initdata = {
 	.activate =	FB_ACTIVATE_NOW,
 	.height =	-1,
@@ -46,7 +44,6 @@
 };
 
 static u16 pseudo_palette[17];
-static struct display display;
 struct fb_info fb_info;
 
 static int hitfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
@@ -125,15 +122,13 @@
 
 static struct fb_ops hitfb_ops = {
 	.owner		= THIS_MODULE,
-	.fb_set_var	= gen_set_var,
-	.fb_get_cmap	= gen_get_cmap,
-	.fb_set_cmap	= gen_set_cmap,
 	.fb_check_var	= hitfb_check_var,
 	.fb_set_par	= hitfb_set_par,
 	.fb_setcolreg	= hitfb_setcolreg,
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
+	.fb_cursor	= soft_cursor,
 };
 
 int __init hitfb_init(void)
@@ -167,24 +162,16 @@
 	fb_info.pseudo_palette 	= pseudo_palette;	
 	fb_info.flags 		= FBINFO_FLAG_DEFAULT;
     	
-	strcpy(fb_info.modename, fb_info.fix.id);
-	fb_info.currcon = -1;
-	fb_info.disp = &display;
-	fb_info.changevar = NULL;
-	fb_info.switch_con = gen_switch;
-	fb_info.updatevar = gen_update_var;
 	fb_info.screen_base = (void *) hitfb_fix.smem_start;
 
 	size = (fb_info.var.bits_per_pixel == 8) ? 256 : 16;
 	fb_alloc_cmap(&fb_info.cmap, size, 0); 	
 
-	gen_set_var(&fb_info.var, -1, &fb_info);
-    
 	if (register_framebuffer(&fb_info) < 0)
 		return -EINVAL;
     
 	printk(KERN_INFO "fb%d: %s frame buffer device\n",
-			GET_FB_IDX(fb_info.node), fb_info.fix.id);
+			minor(fb_info.node), fb_info.fix.id);
 	return 0;
 }
 
diff -Nru a/drivers/video/hpfb.c b/drivers/video/hpfb.c
--- a/drivers/video/hpfb.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/video/hpfb.c	Mon Dec  9 18:46:38 2002
@@ -19,8 +19,6 @@
 #include <asm/blinken.h>
 #include <asm/hwtest.h>
 
-#include <video/fbcon.h>
-
 static struct fb_info fb_info;
 
 unsigned long fb_regs;
@@ -67,8 +65,6 @@
 	.vmode		= FB_VMODE_NONINTERLACED,
 };
 
-static struct display display;
-
 /*
  * Set the palette.  This may not work on all boards but only experimentation 
  * will tell.
@@ -105,13 +101,11 @@
 
 static struct fb_ops hpfb_ops = {
 	.owner		= THIS_MODULE,
-	.fb_set_var	= gen_set_var,
-	.fb_get_cmap	= gen_get_cmap,
-	.fb_set_cmap	= gen_set_cmap,
 	.fb_setcolreg	= hpfb_setcolreg,
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= hpfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
+	.fb_cursor	= soft_cursor,
 };
 
 #define TOPCAT_FBOMSB	0x5d
@@ -163,15 +157,7 @@
 	fb_info.fix   = hpfb_fix;
 	fb_info.screen_base = (char *)hpfb_fix.smem_start;	// FIXME
 
-	/* The below feilds will go away !!!! */
-	fb_info.currcon		= -1;
-        strcpy(fb_info.modename, fb_info.fix.id);
-        fb_info.disp		= &display;
-        fb_info.switch_con	= gen_switch;
-        fb_info.updatevar	= gen_update_var;
 	fb_alloc_cmap(&fb_info.cmap, 256, 0);
-
-	gen_set_disp(-1, &fb_info);
 
 	if (register_framebuffer(&fb_info) < 0)
 		return 1;
diff -Nru a/drivers/video/iga.h b/drivers/video/iga.h
--- a/drivers/video/iga.h	Mon Dec  9 18:46:35 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,29 +0,0 @@
-/* $Id: iga.h,v 1.2 1999/09/11 22:56:31 zaitcev Exp $
- * iga1682.h: Sparc/PCI iga1682 driver constants etc.
- *
- * Copyleft 1998 V. Roganov and G. Raiko
- */
-
-#ifndef _IGA1682_H
-#define _IGA1682_H 1
-
-struct iga1682_info
-{
-    unsigned int total_vram;
-};
-
-#define IGA_ATTR_CTL			0x3C0
-#define   IGA_IDX_VGA_OVERSCAN		0x11
-#define DAC_W_INDEX                     0x03C8
-#define DAC_DATA                        0x03C9
-#define IGA_EXT_CNTRL                   0x3CE
-#define   IGA_IDX_EXT_BUS_CNTL          0x30
-#define     MEM_SIZE_ALIAS              0x3
-#define     MEM_SIZE_1M                 0x0
-#define     MEM_SIZE_2M                 0x1
-#define     MEM_SIZE_4M                 0x2
-#define     MEM_SIZE_RESERVED           0x3
-#define   IGA_IDX_OVERSCAN_COLOR        0x58
-#define   IGA_IDX_EXT_MEM_2             0x72
-
-#endif /* !(_IGA1682_H) */
diff -Nru a/drivers/video/igafb.c b/drivers/video/igafb.c
--- a/drivers/video/igafb.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/video/igafb.c	Mon Dec  9 18:46:38 2002
@@ -39,13 +39,9 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/fb.h>
-#include <linux/selection.h>
-#include <linux/console.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/nvram.h>
-#include <linux/kd.h>
-#include <linux/vt_kern.h>
 
 #include <asm/io.h>
 
@@ -54,16 +50,7 @@
 #include <asm/pcic.h>
 #endif
 
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb24.h>
-#include <video/fbcon-cfb32.h>
-
-#include "iga.h"
-
-static char igafb_name[16] = "IGA 1682";
-static char fontname[40] __initdata = { 0 };
+#include <video/iga.h>
 
 struct pci_mmap_map {
     unsigned long voff;
@@ -73,35 +60,18 @@
     unsigned long prot_mask;
 };
 
-struct fb_info_iga {
-    struct fb_info fb_info;
-    unsigned long frame_buffer_phys;
-    char *frame_buffer;
-    unsigned long io_base_phys;
-    unsigned long io_base;
-    u32 total_vram;
-    struct pci_mmap_map *mmap_map;
-    struct { u_short blue, green, red, pad; } palette[256];
-    int video_cmap_len;
-    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;
-#ifdef __sparc__
-    u8 open;
-    u8 mmaped;
-    int vtconsole;
-    int consolecnt;
-#endif
+struct iga_par {
+	struct pci_mmap_map *mmap_map;
+	unsigned long frame_buffer_phys;
+	unsigned long io_base;
+};
+
+struct fb_info fb_info;
+
+struct fb_fix_screeninfo igafb_fix __initdata = {
+        .id		= "IGA 1682",
+	.type		= FB_TYPE_PACKED_PIXELS;
+	.mmio_len 	= 1000;
 };
 
 struct fb_var_screeninfo default_var = {
@@ -142,21 +112,21 @@
  *
  * On sparc we happen to access I/O with memory mapped functions too.
  */ 
-#define pci_inb(info, reg)        readb(info->io_base+(reg))
-#define pci_outb(info, val, reg)  writeb(val, info->io_base+(reg))
+#define pci_inb(par, reg)        readb(par->io_base+(reg))
+#define pci_outb(par, val, reg)  writeb(val, par->io_base+(reg))
 
-static inline unsigned int iga_inb(struct fb_info_iga *info,
-				   unsigned int reg, unsigned int idx )
+static inline unsigned int iga_inb(struct iga_par *par, unsigned int reg,
+				   unsigned int idx)
 {
-        pci_outb(info, idx, reg);
-        return pci_inb(info, reg + 1);
+        pci_outb(par, idx, reg);
+        return pci_inb(par, reg + 1);
 }
 
-static inline void iga_outb(struct fb_info_iga *info, unsigned char val,
+static inline void iga_outb(struct iga_par *par, unsigned char val,
 			    unsigned int reg, unsigned int idx )
 {
-        pci_outb(info, idx, reg);
-        pci_outb(info, val, reg+1);
+        pci_outb(par, idx, reg);
+        pci_outb(par, val, reg+1);
 }
 
 #endif /* __sparc__ */
@@ -165,20 +135,19 @@
  *  Very important functionality for the JavaEngine1 computer:
  *  make screen border black (usign special IGA registers) 
  */
-static void iga_blank_border(struct fb_info_iga *info)
+static void iga_blank_border(struct iga_par *par)
 {
         int i;
-
 #if 0
 	/*
 	 * PROM does this for us, so keep this code as a reminder
 	 * about required read from 0x3DA and writing of 0x20 in the end.
 	 */
-	(void) pci_inb(info, 0x3DA);		/* required for every access */
-	pci_outb(info, IGA_IDX_VGA_OVERSCAN, IGA_ATTR_CTL);
-	(void) pci_inb(info, IGA_ATTR_CTL+1);
-	pci_outb(info, 0x38, IGA_ATTR_CTL);
-	pci_outb(info, 0x20, IGA_ATTR_CTL);	/* re-enable visual */
+	(void) pci_inb(par, 0x3DA);		/* required for every access */
+	pci_outb(par, IGA_IDX_VGA_OVERSCAN, IGA_ATTR_CTL);
+	(void) pci_inb(par, IGA_ATTR_CTL+1);
+	pci_outb(par, 0x38, IGA_ATTR_CTL);
+	pci_outb(par, 0x20, IGA_ATTR_CTL);	/* re-enable visual */
 #endif
 	/*
 	 * This does not work as it was designed because the overscan
@@ -186,68 +155,19 @@
 	 * overscan changes color.
 	 */
 	for (i=0; i < 3; i++)
-		iga_outb(info, 0, IGA_EXT_CNTRL, IGA_IDX_OVERSCAN_COLOR + i);
-}
-
-
-/*
- *  Frame buffer device API
- */
-
-static int igafb_update_var(int con, struct fb_info *info)
-{
-        return 0;
-}
-
-static int igafb_get_fix(struct fb_fix_screeninfo *fix, int con,
-                         struct fb_info *info)
-{
-        struct fb_info_iga *fb = (struct fb_info_iga*)info;
-
-        memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-        strcpy(fix->id, igafb_name);
-
-        fix->smem_start = (unsigned long) fb->frame_buffer;
-        fix->smem_len = fb->total_vram;
-        fix->xpanstep = 0;
-        fix->ypanstep = 0;
-        fix->ywrapstep = 0;
-
-	fix->type = FB_TYPE_PACKED_PIXELS;
-	fix->type_aux = 0;
-	fix->line_length = default_var.xres * (default_var.bits_per_pixel/8);
-	fix->visual = default_var.bits_per_pixel <= 8 ? FB_VISUAL_PSEUDOCOLOR
-		                                      : FB_VISUAL_DIRECTCOLOR;
-        return 0;
-}
-
-static int igafb_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));
-        else
-                *var = fb_display[con].var;
-        return 0;
-}
-
-static int igafb_set_var(struct fb_var_screeninfo *var, int con,
-                         struct fb_info *info)
-{
-        memcpy(var, &default_var, sizeof(struct fb_var_screeninfo));
-        return 0;
+		iga_outb(par, 0, IGA_EXT_CNTRL, IGA_IDX_OVERSCAN_COLOR + i);
 }
 
 #ifdef __sparc__
 static int igafb_mmap(struct fb_info *info, struct file *file,
 		      struct vm_area_struct *vma)
 {
-	struct fb_info_iga *fb = (struct fb_info_iga *)info;
+	struct iga_par *par = (struct iga_par *)info->par;
 	unsigned int size, page, map_size = 0;
 	unsigned long map_offset = 0;
 	int i;
 
-	if (!fb->mmap_map)
+	if (!par->mmap_map)
 		return -ENXIO;
 
 	size = vma->vm_end - vma->vm_start;
@@ -258,9 +178,9 @@
 	/* Each page, see which map applies */
 	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 = (vma->vm_pgoff << PAGE_SHIFT) + page;
 
 			if (start > offset)
@@ -268,8 +188,8 @@
 			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) {
@@ -279,8 +199,8 @@
 		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))
@@ -293,46 +213,13 @@
 		return -EINVAL;
 
 	vma->vm_flags |= VM_IO;
-
-	if (!fb->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;
-			vt_cons[lastconsole]->vc_mode = KD_GRAPHICS;
-		}
-	}
 	return 0;
 }
 #endif /* __sparc__ */
 
-
-static int iga_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.
-         */
-	struct fb_info_iga *info = (struct fb_info_iga*) fb_info;
-
-        if (regno >= info->video_cmap_len)
-                return 1;
-
-	*red    = info->palette[regno].red;
-	*green  = info->palette[regno].green;
-	*blue   = info->palette[regno].blue;
-	*transp = 0;
-	return 0;
-}
-
 static int igafb_setcolreg(unsigned regno, unsigned red, unsigned green,
                            unsigned blue, unsigned transp,
-                           struct fb_info *fb_info)
+                           struct fb_info *info)
 {
         /*
          *  Set a single color register. The values supplied are
@@ -340,221 +227,100 @@
          *  (according to the entries in the `var' structure). Return
          *  != 0 for invalid regno.
          */
-        
-	struct fb_info_iga *info = (struct fb_info_iga*) fb_info;
+	struct iga_par *par = (struct iga_par *)info->par;
 
-        if (regno >= info->video_cmap_len)
+        if (regno >= info->cmap.len)
                 return 1;
 
-        info->palette[regno].red   = red;
-        info->palette[regno].green = green;
-        info->palette[regno].blue  = blue;
-
-	pci_outb(info, regno, DAC_W_INDEX);
-	pci_outb(info, red,   DAC_DATA);
-	pci_outb(info, green, DAC_DATA);
-	pci_outb(info, blue,  DAC_DATA);
+	pci_outb(par, regno, DAC_W_INDEX);
+	pci_outb(par, red,   DAC_DATA);
+	pci_outb(par, green, DAC_DATA);
+	pci_outb(par, blue,  DAC_DATA);
 
 	if (regno < 16) {
-		switch (default_var.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB16
+		switch (info->var.bits_per_pixel) {
 		case 16:
-			info->fbcon_cmap.cfb16[regno] = 
+			info->pseudo_palette[regno] = 
 				(regno << 10) | (regno << 5) | regno;
 			break;
-#endif
-#ifdef FBCON_HAS_CFB24
 		case 24:
-			info->fbcon_cmap.cfb24[regno] = 
+			info->pseudo_palette[regno] = 
 				(regno << 16) | (regno << 8) | regno;
 		break;
-#endif
-#ifdef FBCON_HAS_CFB32
 		case 32:
 			{ int i;
 			i = (regno << 8) | regno;
-			info->fbcon_cmap.cfb32[regno] = (i << 16) | i;
+			info->pseudo_palette[regno] = (i << 16) | i;
 			}
 			break;
-#endif
 		}
 	}
 	return 0;
 }
 
-static int igafb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-                           struct fb_info *fb_info)
-{
-	struct fb_info_iga *info = (struct fb_info_iga*) fb_info;
-	
-        if (con == fb_info->currcon) /* current console? */
-                return fb_get_cmap(cmap, kspc, iga_getcolreg, &info->fb_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(info->video_cmap_len),
-                     cmap, kspc ? 0 : 2);
-        return 0;
-}
-
 /*
  * Framebuffer option structure
  */
 static struct fb_ops igafb_ops = {
-	.owner =	THIS_MODULE,
-	.fb_get_fix =	igafb_get_fix,
-	.fb_get_var =	igafb_get_var,
-	.fb_set_var =	igafb_set_var,
-	.fb_get_cmap =	igafb_get_cmap,
-	.fb_set_cmap =	gen_set_cmap,
-	.fb_setcolreg =	igafb_setcolreg,
+	.owner 		= THIS_MODULE,
+	.fb_setcolreg 	= igafb_setcolreg,
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit,
 #ifdef __sparc__
-	.fb_mmap =	igafb_mmap,
+	.fb_mmap 	= igafb_mmap,
 #endif
 };
 
-static void igafb_set_disp(int con, struct fb_info_iga *info)
+static int __init iga_init(struct fb_info *info, struct iga_par *par)
 {
-        struct fb_fix_screeninfo fix;
-        struct display *display;
-        struct display_switch *sw;
-
-        if (con >= 0)
-                display = &fb_display[con];
-        else 
-                display = &info->disp;        /* used during initialization */
-
-        igafb_get_fix(&fix, con, &info->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 = 0;
-        igafb_get_var(&display->var, -1, &info->fb_info);
-
-        switch (default_var.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
-        case 8:
-                sw = &fbcon_cfb8;
-                break;
-#endif
-#ifdef FBCON_HAS_CFB16
-        case 15:
-        case 16:
-                sw = &fbcon_cfb16;
-		display->dispsw_data = info->fbcon_cmap.cfb16;
-                break;
-#endif
-#ifdef FBCON_HAS_CFB24
-	case 24:
-		sw = &fbcon_cfb24;
-		display->dispsw_data = info->fbcon_cmap.cfb24;
-		break;
-#endif
-#ifdef FBCON_HAS_CFB32
-        case 32:
-                sw = &fbcon_cfb32;
-		display->dispsw_data = info->fbcon_cmap.cfb32;
-                break;
-#endif
-        default:
-		printk(KERN_WARNING "igafb_set_disp: unknown resolution %d\n",
-		    default_var.bits_per_pixel);
-                return;
-        }
-        memcpy(&info->dispsw, sw, sizeof(*sw));
-        display->dispsw = &info->dispsw;
-
-	display->scrollmode = SCROLL_YREDRAW;
-	info->dispsw.bmove = fbcon_redraw_bmove;
-}
-
-static int igafb_switch(int con, struct fb_info *fb_info)
-{
-	struct fb_info_iga *info = (struct fb_info_iga*) fb_info;
-
-        /* Do we have to save the colormap? */
-        if (fb_display[fb_info->currcon].cmap.len)
-                fb_get_cmap(&fb_display[fb_info->currcon].cmap, 1,
-                            iga_getcolreg, fb_info);
-
-	fb_info->currcon = con;
-	/* Install new colormap */
-	do_install_cmap(con, fb_info);
-	igafb_update_var(con, fb_info);
-        return 1;
-}
-
-static int __init iga_init(struct fb_info_iga *info)
-{
-        char vramsz = iga_inb(info, IGA_EXT_CNTRL, IGA_IDX_EXT_BUS_CNTL) 
+        char vramsz = iga_inb(par, IGA_EXT_CNTRL, IGA_IDX_EXT_BUS_CNTL) 
 		                                         & MEM_SIZE_ALIAS;
+	int video_cmap_len;
+
         switch (vramsz) {
         case MEM_SIZE_1M:
-                info->total_vram = 0x100000;
+                info->fix.smem_len = 0x100000;
                 break;
         case MEM_SIZE_2M:
-                info->total_vram = 0x200000;
+                info->fix.smem_len = 0x200000;
                 break;
         case MEM_SIZE_4M:
         case MEM_SIZE_RESERVED:
-                info->total_vram = 0x400000;
+                info->fix.smem_len = 0x400000;
                 break;
         }
 
-        if (default_var.bits_per_pixel > 8) {
-                info->video_cmap_len = 16;
-        } else {
-                info->video_cmap_len = 256;
-        }
-	{
-		int j, k;
-		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];
-		}
-	}
+        if (info->var.bits_per_pixel > 8) 
+                video_cmap_len = 16;
+        else 
+                video_cmap_len = 256;
 
-	strcpy(info->fb_info.modename, igafb_name);
-	info->fb_info.node = NODEV;
-	info->fb_info.fbops = &igafb_ops;
-	info->fb_info.disp = &info->disp;
-        info->fb_info.screen_base = info->frame_buffer;
-	info->fb_info.currcon = -1;
-	strcpy(info->fb_info.fontname, fontname);
-	info->fb_info.changevar = NULL;
-	info->fb_info.switch_con = &igafb_switch;
-	info->fb_info.updatevar = &igafb_update_var;
-	info->fb_info.flags=FBINFO_FLAG_DEFAULT;
+	info->node  = NODEV;
+	info->fbops = &igafb_ops;
+	info->flags = FBINFO_FLAG_DEFAULT;
 
-	igafb_set_disp(-1, info);
+	fb_alloc_cmap(info->cmap, video_cmap_len, 0);
 
-	if (register_framebuffer(&info->fb_info) < 0)
+	if (register_framebuffer(info) < 0)
 		return 0;
 
 	printk("fb%d: %s frame buffer device at 0x%08lx [%dMB VRAM]\n",
-	       GET_FB_IDX(info->fb_info.node), igafb_name, 
-	       info->frame_buffer_phys, info->total_vram >> 20);
+	       minor(info->node), info->fix.id, 
+	       par->frame_buffer_phys, info->fix.smem_len >> 20);
 
-	iga_blank_border(info); 
+	iga_blank_border(par); 
 	return 1;
 }
 
 int __init igafb_init(void)
 {
-        struct pci_dev *pdev;
-        struct fb_info_iga *info;
-        unsigned long addr;
         extern int con_is_present(void);
-	int iga2000 = 0;
+        struct fb_info *info;
+        struct pci_dev *pdev;
+        struct iga_par *par;
+	unsigned long addr;
+	int size, iga2000 = 0;
 
         /* Do not attach when we have a serial console. */
         if (!con_is_present())
@@ -573,13 +339,18 @@
 		}
 		iga2000 = 1;
 	}
+	
+	size = sizeof(struct fb_info) + sizeof(struct iga_par) + sizeof(u32)*16;
 
-        info = kmalloc(sizeof(struct fb_info_iga), GFP_ATOMIC);
+        info = kmalloc(size, GFP_ATOMIC);
         if (!info) {
-                printk("igafb_init: can't alloc fb_info_iga\n");
+                printk("igafb_init: can't alloc fb_info\n");
                 return -ENOMEM;
         }
-        memset(info, 0, sizeof(struct fb_info_iga));
+        memset(info, 0, size);
+
+	par = (struct iga_par *) (info + 1);
+	
 
 	if ((addr = pdev->resource[0].start) == 0) {
                 printk("igafb_init: no memory start\n");
@@ -587,13 +358,13 @@
 		return -ENXIO;
 	}
 
-	if ((info->frame_buffer = ioremap(addr, 1024*1024*2)) == 0) {
+	if ((info->screen_base = ioremap(addr, 1024*1024*2)) == 0) {
                 printk("igafb_init: can't remap %lx[2M]\n", addr);
 		kfree(info);
 		return -ENXIO;
 	}
 
-	info->frame_buffer_phys = addr & PCI_BASE_ADDRESS_MEM_MASK;
+	par->frame_buffer_phys = addr & PCI_BASE_ADDRESS_MEM_MASK;
 
 #ifdef __sparc__
 	/*
@@ -616,14 +387,14 @@
 	 * I/O addresses are.
 	 */
 	if (iga2000) {
-		info->io_base_phys = info->frame_buffer_phys | 0x00800000;
+		igafb_fix.mmio_start = par->frame_buffer_phys | 0x00800000;
 	} else {
-		info->io_base_phys = 0x30000000;	/* XXX */
+		igafb_fix.mmio_start = 0x30000000;	/* XXX */
 	}
-	if ((info->io_base = (int) ioremap(info->io_base_phys, 0x1000)) == 0) {
-                printk("igafb_init: can't remap %lx[4K]\n", info->io_base_phys);
-		iounmap((void *)info->frame_buffer);
-                kfree(info);
+	if ((par->io_base = (int) ioremap(igafb_fix.mmio_start, igafb_fix.smem_len)) == 0) {
+                printk("igafb_init: can't remap %lx[4K]\n", igafb_fix.mmio_start);
+		iounmap((void *)info->screen_base);
+		kfree(info);
 		return -ENXIO;
 	}
 
@@ -635,16 +406,16 @@
 	 * one additional region with size == 0. 
 	 */
 
-	info->mmap_map = kmalloc(4 * sizeof(*info->mmap_map), GFP_ATOMIC);
-	if (!info->mmap_map) {
+	par->mmap_map = kmalloc(4 * sizeof(*par->mmap_map), GFP_ATOMIC);
+	if (!par->mmap_map) {
 		printk("igafb_init: can't alloc mmap_map\n");
-		iounmap((void *)info->io_base);
-		iounmap(info->frame_buffer);
-                kfree(info);
+		iounmap((void *)par->io_base);
+		iounmap(info->screen_base);
+		kfree(info);
 		return -ENOMEM;
 	}
 
-	memset(info->mmap_map, 0, 4 * sizeof(*info->mmap_map));
+	memset(par->mmap_map, 0, 4 * sizeof(*par->mmap_map));
 
 	/*
 	 * Set default vmode and cmode from PROM properties.
@@ -691,12 +462,19 @@
             }
 
 #endif
-
-	if (!iga_init(info)) {
-		iounmap((void *)info->io_base);
-		iounmap(info->frame_buffer);
-		if (info->mmap_map)
-			kfree(info->mmap_map);
+	igafb_fix.smem_start = (unsigned long) info->screen_base;
+	igafb_fix.line_length = default_var.xres*(default_var.bits_per_pixel/8);
+	igafb_fix.visual = default_var.bits_per_pixel <= 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
+
+	info->var = default_var;
+	info->fix = igafb_fix;
+	info->pseudo_palette = (void *)(par + 1);
+
+	if (!iga_init(info, par)) {
+		iounmap((void *)par->io_base);
+		iounmap(info->screen_base);
+		if (par->mmap_map)
+			kfree(par->mmap_map);
 		kfree(info);
         }
 
@@ -706,18 +484,18 @@
 	     */
 	    
 	    /* First region is for video memory */
-	    info->mmap_map[0].voff = 0x0;  
-	    info->mmap_map[0].poff = info->frame_buffer_phys & PAGE_MASK;
-	    info->mmap_map[0].size = info->total_vram   & PAGE_MASK;
-	    info->mmap_map[0].prot_mask = SRMMU_CACHE;
-	    info->mmap_map[0].prot_flag = SRMMU_WRITE;
+	    par->mmap_map[0].voff = 0x0;  
+	    par->mmap_map[0].poff = par->frame_buffer_phys & PAGE_MASK;
+	    par->mmap_map[0].size = info->fix.smem_len & PAGE_MASK;
+	    par->mmap_map[0].prot_mask = SRMMU_CACHE;
+	    par->mmap_map[0].prot_flag = SRMMU_WRITE;
 
 	    /* Second region is for I/O ports */
-	    info->mmap_map[1].voff = info->frame_buffer_phys & PAGE_MASK;
-	    info->mmap_map[1].poff = info->io_base_phys & PAGE_MASK;
-	    info->mmap_map[1].size = PAGE_SIZE * 2; /* X wants 2 pages */
-	    info->mmap_map[1].prot_mask = SRMMU_CACHE;
-	    info->mmap_map[1].prot_flag = SRMMU_WRITE;
+	    par->mmap_map[1].voff = par->frame_buffer_phys & PAGE_MASK;
+	    par->mmap_map[1].poff = info->fix.smem_start & PAGE_MASK;
+	    par->mmap_map[1].size = PAGE_SIZE * 2; /* X wants 2 pages */
+	    par->mmap_map[1].prot_mask = SRMMU_CACHE;
+	    par->mmap_map[1].prot_flag = SRMMU_WRITE;
 #endif /* __sparc__ */
 
 	return 0;
@@ -731,17 +509,6 @@
         return 0;
 
     while ((this_opt = strsep(&options, ",")) != NULL) {
-        if (!strncmp(this_opt, "font:", 5)) {
-                char *p;
-                int i;
-
-                p = this_opt + 5;
-                for (i = 0; i < sizeof(fontname) - 1; i++)
-                        if (!*p || *p == ' ' || *p == ',')
-                                break;
-                memcpy(fontname, this_opt + 5, i);
-                fontname[i] = 0;
-        }
     }
     return 0;
 }
diff -Nru a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c
--- a/drivers/video/imsttfb.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/video/imsttfb.c	Mon Dec  9 18:46:37 2002
@@ -772,7 +772,7 @@
 static inline void
 set_offset (struct display *disp, struct fb_info_imstt *p)
 {
-	__u32 off = disp->var.yoffset * (disp->line_length >> 3)
+	__u32 off = disp->var.yoffset * (p->info.fix.line_length >> 3)
 		    + ((disp->var.xoffset * (disp->var.bits_per_pixel >> 3)) >> 3);
 	out_le32(&p->dc_regs[SSR], off);
 }
@@ -1020,7 +1020,7 @@
 	width *= Bpp;
 	width--;
 
-	line_pitch = disp->line_length;
+	line_pitch = p->info.fix.line_length;
 	bltctl = 0x05;
 	sp = line_pitch << 16;
 	cnt = height << 16;
@@ -1068,7 +1068,7 @@
 	bgc |= (bgc << 16);
 
 	Bpp = disp->var.bits_per_pixel >> 3,
-	line_pitch = disp->line_length;
+	line_pitch = p->info.fix.line_length;
 
 	sy *= fontheight(disp);
 	sy *= line_pitch;
@@ -1099,7 +1099,7 @@
 	__u32 Bpp, line_pitch, height, width;
 
 	Bpp = disp->var.bits_per_pixel >> 3,
-	line_pitch = disp->line_length;
+	line_pitch = p->info.fix.line_length;
 
 	height = fontheight(disp);
 	width = fontwidth(disp) * Bpp;
@@ -1246,28 +1246,6 @@
 	return 0;
 }
 
-static int
-imsttfb_get_fix (struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
-{
-	struct fb_info_imstt *p = (struct fb_info_imstt *)info;
-	struct fb_var_screeninfo *var = &fb_display[con].var;
-
-	*fix = p->fix;
-	fix->visual = var->bits_per_pixel == 8 ? FB_VISUAL_PSEUDOCOLOR
-					       : FB_VISUAL_DIRECTCOLOR;
-	fix->line_length = var->xres * (var->bits_per_pixel >> 3);
-
-	return 0;
-}
-
-static int
-imsttfb_get_var (struct fb_var_screeninfo *var, int con, struct fb_info *info)
-{
-	*var = fb_display[con].var;
-
-	return 0;
-}
-
 static void
 set_dispsw (struct display *disp, struct fb_info_imstt *p)
 {
@@ -1354,16 +1332,7 @@
 
 	set_dispsw(disp, p);
 
-	disp->visual = disp->var.bits_per_pixel == 8 ? FB_VISUAL_PSEUDOCOLOR
-					 	     : FB_VISUAL_DIRECTCOLOR;
-	disp->visual = p->fix.visual;
-	disp->type = p->fix.type;
-	disp->type_aux = p->fix.type_aux;
-	disp->line_length = disp->var.xres * (disp->var.bits_per_pixel >> 3);
 	disp->can_soft_blank = 1;
-	disp->inverse = inverse;
-	disp->ypanstep = 1;
-	disp->ywrapstep = 0;
 	if (accel) {
 		disp->scrollmode = SCROLL_YNOMOVE;
 		if (disp->var.yres == disp->var.yres_virtual) {
@@ -1625,8 +1594,6 @@
 
 static struct fb_ops imsttfb_ops = {
 	.owner =	THIS_MODULE,
-	.fb_get_fix =	imsttfb_get_fix,
-	.fb_get_var =	imsttfb_get_var,
 	.fb_set_var =	imsttfb_set_var,
 	.fb_get_cmap =	imsttfb_get_cmap,
 	.fb_set_cmap =	gen_set_cmap,
diff -Nru a/drivers/video/macfb.c b/drivers/video/macfb.c
--- a/drivers/video/macfb.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/video/macfb.c	Mon Dec  9 18:46:34 2002
@@ -40,8 +40,6 @@
 #include <asm/io.h>
 #include <asm/machw.h>
 
-#include <video/fbcon.h>
-
 /* Common DAC base address for the LC, RBV, Valkyrie, and IIvx */
 #define DAC_BASE 0x50f24000
 
@@ -173,7 +171,6 @@
 	.accel	= FB_ACCEL_NONE,
 };
 
-static struct display disp;
 static struct fb_info fb_info;
 static u32 pseudo_palette[17];
 static int inverse   = 0;
@@ -225,7 +222,7 @@
 
 	local_irq_save(flags);
 	
-	/* fbcon will set an entire colourmap, but X won't.  Hopefully
+	/* fbdev will set an entire colourmap, but X won't.  Hopefully
 	   this should accomodate both of them */
 	if (regno != lastreg+1) {
 		int i;
@@ -588,21 +585,17 @@
 
 static struct fb_ops macfb_ops = {
 	.owner		= THIS_MODULE,
-	.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,
+	.fb_cursor	= soft_cursor,
 };
 
 void __init macfb_setup(char *options, int *ints)
 {
 	char *this_opt;
 	
-	fb_info.fontname[0] = '\0';
-	
 	if (!options || !*options)
 		return;
 	
@@ -611,8 +604,6 @@
 		
 		if (! strcmp(this_opt, "inverse"))
 			inverse=1;
-		else if (!strncmp(this_opt, "font:", 5))
-			strcpy(fb_info.fontname, this_opt+5);
 		/* This means "turn on experimental CLUT code" */
 		else if (!strcmp(this_opt, "vidtest"))
 			vidtest=1;
@@ -952,27 +943,20 @@
 			break;
 		}
 
-	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_palette	= pseudo_palette;
 	fb_info.flags		= FBINFO_FLAG_DEFAULT;
 
 	fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0);
-	gen_set_disp(-1, &fb_info);
 	
 	if (register_framebuffer(&fb_info) < 0)
 		return;
 
 	printk("fb%d: %s frame buffer device\n",
-	       GET_FB_IDX(fb_info.node), fb_info.fix.id);
+	       minor(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	Mon Dec  9 18:46:52 2002
+++ b/drivers/video/macmodes.c	Mon Dec  9 18:46:52 2002
@@ -20,8 +20,7 @@
 #include <linux/fb.h>
 #include <linux/string.h>
 
-#include <video/fbcon.h>
-#include <video/macmodes.h>
+#include "macmodes.h"
 
     /*
      *  MacOS video mode definitions
diff -Nru a/drivers/video/macmodes.h b/drivers/video/macmodes.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/macmodes.h	Mon Dec  9 18:46:37 2002
@@ -0,0 +1,70 @@
+/*
+ *  linux/drivers/video/macmodes.h -- Standard MacOS video modes
+ *
+ *	Copyright (C) 1998 Geert Uytterhoeven
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#ifndef _VIDEO_MACMODES_H
+#define _VIDEO_MACMODES_H
+
+    /*
+     *  Video mode values.
+     *  These are supposed to be the same as the values that Apple uses in
+     *  MacOS.
+     */
+
+#define VMODE_NVRAM		0
+#define VMODE_512_384_60I	1	/* 512x384, 60Hz interlaced (NTSC) */
+#define VMODE_512_384_60	2	/* 512x384, 60Hz */
+#define VMODE_640_480_50I	3	/* 640x480, 50Hz interlaced (PAL) */
+#define VMODE_640_480_60I	4	/* 640x480, 60Hz interlaced (NTSC) */
+#define VMODE_640_480_60	5	/* 640x480, 60Hz (VGA) */
+#define VMODE_640_480_67	6	/* 640x480, 67Hz */
+#define VMODE_640_870_75P	7	/* 640x870, 75Hz (portrait) */
+#define VMODE_768_576_50I	8	/* 768x576, 50Hz (PAL full frame) */
+#define VMODE_800_600_56	9	/* 800x600, 56Hz */
+#define VMODE_800_600_60	10	/* 800x600, 60Hz */
+#define VMODE_800_600_72	11	/* 800x600, 72Hz */
+#define VMODE_800_600_75	12	/* 800x600, 75Hz */
+#define VMODE_832_624_75	13	/* 832x624, 75Hz */
+#define VMODE_1024_768_60	14	/* 1024x768, 60Hz */
+#define VMODE_1024_768_70	15	/* 1024x768, 70Hz (or 72Hz?) */
+#define VMODE_1024_768_75V	16	/* 1024x768, 75Hz (VESA) */
+#define VMODE_1024_768_75	17	/* 1024x768, 75Hz */
+#define VMODE_1152_870_75	18	/* 1152x870, 75Hz */
+#define VMODE_1280_960_75	19	/* 1280x960, 75Hz */
+#define VMODE_1280_1024_75	20	/* 1280x1024, 75Hz */
+#define VMODE_1152_768_60	21	/* 1152x768, 60Hz     Titanium PowerBook */
+#define VMODE_1600_1024_60	22	/* 1600x1024, 60Hz 22" Cinema Display */
+#define VMODE_MAX		22
+#define VMODE_CHOOSE		99
+
+#define CMODE_NVRAM		-1
+#define CMODE_CHOOSE		-2
+#define CMODE_8			0	/* 8 bits/pixel */
+#define CMODE_16		1	/* 16 (actually 15) bits/pixel */
+#define CMODE_32		2	/* 32 (actually 24) bits/pixel */
+
+
+extern int mac_vmode_to_var(int vmode, int cmode,
+			    struct fb_var_screeninfo *var);
+extern int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode,
+			    int *cmode);
+extern int mac_map_monitor_sense(int sense);
+extern int __init mac_find_mode(struct fb_var_screeninfo *var,
+				struct fb_info *info, const char *mode_option,
+				unsigned int default_bpp);
+
+
+    /*
+     *  Addresses in NVRAM where video mode and pixel size are stored.
+     */
+
+#define NV_VMODE		0x140f
+#define NV_CMODE		0x1410
+
+#endif /* _VIDEO_MACMODES_H */
diff -Nru a/drivers/video/matrox/i2c-matroxfb.c b/drivers/video/matrox/i2c-matroxfb.c
--- a/drivers/video/matrox/i2c-matroxfb.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/video/matrox/i2c-matroxfb.c	Mon Dec  9 18:46:37 2002
@@ -120,7 +120,7 @@
 	b->mask.data = data;
 	b->mask.clock = clock;
 	b->adapter = matrox_i2c_adapter_template;
-	sprintf(b->adapter.name, name, GET_FB_IDX(minfo->fbcon.node));
+	sprintf(b->adapter.name, name, minor(minfo->fbcon.node));
 	b->adapter.data = b;
 	b->adapter.algo_data = &b->bac;
 	b->bac = matrox_i2c_algo_template;
diff -Nru a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
--- a/drivers/video/matrox/matroxfb_base.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/video/matrox/matroxfb_base.c	Mon Dec  9 18:46:50 2002
@@ -1872,12 +1872,12 @@
 		goto failVideoIO;
 	}
 	printk("fb%d: %s frame buffer device\n",
-	       GET_FB_IDX(ACCESS_FBINFO(fbcon.node)), ACCESS_FBINFO(fbcon.modename));
+	       minor(ACCESS_FBINFO(fbcon.node)), ACCESS_FBINFO(fbcon.modename));
 	if (ACCESS_FBINFO(fbcon.currcon) < 0) {
 		/* there is no console on this fb... but we have to initialize hardware
 		 * until someone tells me what is proper thing to do */
 		printk(KERN_INFO "fb%d: initializing hardware\n",
-			GET_FB_IDX(ACCESS_FBINFO(fbcon.node)));
+			minor(ACCESS_FBINFO(fbcon.node)));
 		matroxfb_set_var(&vesafb_defined, -1, &ACCESS_FBINFO(fbcon));
 	}
 	return 0;
diff -Nru a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/matrox/matroxfb_crtc2.c
--- a/drivers/video/matrox/matroxfb_crtc2.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/video/matrox/matroxfb_crtc2.c	Mon Dec  9 18:46:35 2002
@@ -816,7 +816,7 @@
 		return -1;
 	}
 	printk(KERN_INFO "matroxfb_crtc2: secondary head of fb%u was registered as fb%u\n",
-		GET_FB_IDX(ACCESS_FBINFO(fbcon.node)), GET_FB_IDX(m2info->fbcon.node));
+		minor(ACCESS_FBINFO(fbcon.node)), minor(m2info->fbcon.node));
 	m2info->fbcon_registered = 1;
 	return 0;
 #undef minfo
@@ -839,7 +839,7 @@
 			printk(KERN_ERR "matroxfb_crtc2: Expect kernel crash after module unload.\n");
 			return;
 		}
-		id = GET_FB_IDX(m2info->fbcon.node);
+		id = minor(m2info->fbcon.node);
 		unregister_framebuffer(&m2info->fbcon);
 		kfree(m2info->fbcon.disp);
 		/* return memory back to primary head */
diff -Nru a/drivers/video/maxinefb.c b/drivers/video/maxinefb.c
--- a/drivers/video/maxinefb.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/video/maxinefb.c	Mon Dec  9 18:46:35 2002
@@ -34,7 +34,6 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
-#include <video/fbcon.h>
 #include "maxinefb.h"
 
 /* bootinfo.h defines the machine type values, needed when checking */
@@ -42,27 +41,29 @@
 #include <asm/bootinfo.h>
 
 static struct fb_info fb_info;
-static struct display disp;
 
 static struct fb_var_screeninfo maxinefb_defined = {
-	.xres =		1024,
-	.yres =		768,
-	.xres_virtual =	1024,
-	.yres_virtual =	768,
-	.bits_per_pixel =8,
-	.activate =	FB_ACTIVATE_NOW,
-	.height =	-1,
-	.width =	-1,
-	.vmode =	FB_VMODE_NONINTERLACED,
+	.xres 		= 1024,
+	.yres 		= 768,
+	.xres_virtual 	= 1024,
+	.yres_virtual 	= 768,
+	.bits_per_pixel = 8,
+	.red.length	= 8,
+	.green.length	= 8,
+	.blue.length	= 8,
+	.activate 	= FB_ACTIVATE_NOW,
+	.height 	= -1,
+	.width 		= -1,
+	.vmode 		= FB_VMODE_NONINTERLACED,
 };
 
 static struct fb_fix_screeninfo maxinefb_fix = {
-	.id =		"Maxine onboard graphics 1024x768x8",
-	.smem_len =	(1024*768),
-	.type =		FB_TYPE_PACKED_PIXELS,
-	.visual =	FB_VISUAL_PSEUDOCOLOR,
-	.line_length =	1024,
-}
+	.id 		= "Maxine onboard graphics 1024x768x8",
+	.smem_len 	= (1024*768),
+	.type 		= FB_TYPE_PACKED_PIXELS,
+	.visual 	= FB_VISUAL_PSEUDOCOLOR,
+	.line_length 	= 1024,
+};
 
 /* Reference to machine type set in arch/mips/dec/prom/identify.c, KM */
 extern unsigned long mips_machtype;
@@ -112,13 +113,11 @@
 
 static struct fb_ops maxinefb_ops = {
 	.owner		= THIS_MODULE,
-	.fb_set_var	= gen_set_var,
-	.fb_get_cmap	= gen_get_cmap,
-	.fb_set_cmap	= gen_set_cmap,
 	.fb_setcolreg	= maxinefb_setcolreg,	
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,		
+	.fb_cursor	= soft_cursor,
 };
 
 int __init maxinefb_init(void)
@@ -156,23 +155,14 @@
 		 */
 	}
 
-	/* Let there be consoles... */
-
-	strcpy(fb_info.modename, "Maxine onboard graphics 1024x768x8");
-	fb_info.changevar = NULL;
 	fb_info.node = NODEV;
 	fb_info.fbops = &maxinefb_ops;
 	fb_info.screen_base = (char *) maxinefb_fix.smem_start;
 	fb_info.var = maxinefb_defined;
 	fb_info.fix = maxinefb_fix;
-	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_alloc_cmap(&fb_info.cmap, 256, 0);
-	gen_set_disp(-1, &fb_info);
 
 	if (register_framebuffer(&fb_info) < 0)
 		return 1;
diff -Nru a/drivers/video/mdacon.c b/drivers/video/mdacon.c
--- a/drivers/video/mdacon.c	Mon Dec  9 18:46:38 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,632 +0,0 @@
-/*
- *  linux/drivers/video/mdacon.c -- Low level MDA based console driver
- *
- *	(c) 1998 Andrew Apted <ajapted@netspace.net.au>
- *
- *      including portions (c) 1995-1998 Patrick Caulfield.
- *
- *      slight improvements (c) 2000 Edward Betts <edward@debian.org>
- *
- *  This file is based on the VGA console driver (vgacon.c):
- *	
- *	Created 28 Sep 1997 by Geert Uytterhoeven
- *
- *	Rewritten by Martin Mares <mj@ucw.cz>, July 1998
- *
- *  and on the old console.c, vga.c and vesa_blank.c drivers:
- *
- *	Copyright (C) 1991, 1992  Linus Torvalds
- *			    1995  Jay Estabrook
- *
- *  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.
- *
- *  Changelog:
- *  Paul G. (03/2001) Fix mdacon= boot prompt to use __setup().
- */
-
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/console_struct.h>
-#include <linux/string.h>
-#include <linux/kd.h>
-#include <linux/slab.h>
-#include <linux/vt_kern.h>
-#include <linux/vt_buffer.h>
-#include <linux/selection.h>
-#include <linux/spinlock.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-#include <asm/vga.h>
-
-static spinlock_t mda_lock = SPIN_LOCK_UNLOCKED;
-
-/* description of the hardware layout */
-
-static unsigned long	mda_vram_base;		/* Base of video memory */
-static unsigned long	mda_vram_len;		/* Size of video memory */
-static unsigned int	mda_num_columns;	/* Number of text columns */
-static unsigned int	mda_num_lines;		/* Number of text lines */
-
-static unsigned int	mda_index_port;		/* Register select port */
-static unsigned int	mda_value_port;		/* Register value port */
-static unsigned int	mda_mode_port;		/* Mode control port */
-static unsigned int	mda_status_port;	/* Status and Config port */
-static unsigned int	mda_gfx_port;		/* Graphics control port */
-
-/* current hardware state */
-
-static int	mda_origin_loc=-1;
-static int	mda_cursor_loc=-1;
-static int	mda_cursor_size_from=-1;
-static int	mda_cursor_size_to=-1;
-
-static enum { TYPE_MDA, TYPE_HERC, TYPE_HERCPLUS, TYPE_HERCCOLOR } mda_type;
-static char *mda_type_name;
-
-/* console information */
-
-static int	mda_first_vc = 13;
-static int	mda_last_vc  = 16;
-
-static struct vc_data	*mda_display_fg = NULL;
-
-MODULE_PARM(mda_first_vc, "1-255i");
-MODULE_PARM(mda_last_vc,  "1-255i");
-
-/* MDA register values
- */
-
-#define MDA_CURSOR_BLINKING	0x00
-#define MDA_CURSOR_OFF		0x20
-#define MDA_CURSOR_SLOWBLINK	0x60
-
-#define MDA_MODE_GRAPHICS	0x02
-#define MDA_MODE_VIDEO_EN	0x08
-#define MDA_MODE_BLINK_EN	0x20
-#define MDA_MODE_GFX_PAGE1	0x80
-
-#define MDA_STATUS_HSYNC	0x01
-#define MDA_STATUS_VSYNC	0x80
-#define MDA_STATUS_VIDEO	0x08
-
-#define MDA_CONFIG_COL132	0x08
-#define MDA_GFX_MODE_EN		0x01
-#define MDA_GFX_PAGE_EN		0x02
-
-
-/*
- * MDA could easily be classified as "pre-dinosaur hardware".
- */
-
-static void write_mda_b(unsigned int val, unsigned char reg)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&mda_lock, flags);	
-
-	outb_p(reg, mda_index_port); 
-	outb_p(val, mda_value_port);
-
-	spin_unlock_irqrestore(&mda_lock, flags);
-}
-
-static void write_mda_w(unsigned int val, unsigned char reg)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&mda_lock, flags);
-
-	outb_p(reg,   mda_index_port); outb_p(val >> 8,   mda_value_port);
-	outb_p(reg+1, mda_index_port); outb_p(val & 0xff, mda_value_port);
-
-	spin_unlock_irqrestore(&mda_lock, flags);
-}
-
-#ifdef TEST_MDA_B
-static int test_mda_b(unsigned char val, unsigned char reg)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&mda_lock, flags);
-
-	outb_p(reg, mda_index_port); 
-	outb  (val, mda_value_port);
-
-	udelay(20); val = (inb_p(mda_value_port) == val);
-
-	spin_unlock_irqrestore(&mda_lock, flags);
-	return val;
-}
-#endif
-
-static inline void mda_set_origin(unsigned int location)
-{
-	if (mda_origin_loc == location)
-		return;
-
-	write_mda_w(location >> 1, 0x0c);
-
-	mda_origin_loc = location;
-}
-
-static inline void mda_set_cursor(unsigned int location) 
-{
-	if (mda_cursor_loc == location)
-		return;
-
-	write_mda_w(location >> 1, 0x0e);
-
-	mda_cursor_loc = location;
-}
-
-static inline void mda_set_cursor_size(int from, int to)
-{
-	if (mda_cursor_size_from==from && mda_cursor_size_to==to)
-		return;
-	
-	if (from > to) {
-		write_mda_b(MDA_CURSOR_OFF, 0x0a);	/* disable cursor */
-	} else {
-		write_mda_b(from, 0x0a);	/* cursor start */
-		write_mda_b(to,   0x0b);	/* cursor end */
-	}
-
-	mda_cursor_size_from = from;
-	mda_cursor_size_to   = to;
-}
-
-
-#ifndef MODULE
-static int __init mdacon_setup(char *str)
-{
-	/* command line format: mdacon=<first>,<last> */
-
-	int ints[3];
-
-	str = get_options(str, ARRAY_SIZE(ints), ints);
-
-	if (ints[0] < 2)
-		return 0;
-
-	if (ints[1] < 1 || ints[1] > MAX_NR_CONSOLES || 
-	    ints[2] < 1 || ints[2] > MAX_NR_CONSOLES)
-		return 0;
-
-	mda_first_vc = ints[1];
-	mda_last_vc  = ints[2];
-	return 1;
-}
-
-__setup("mdacon=", mdacon_setup);
-#endif
-
-static int __init mda_detect(void)
-{
-	int count=0;
-	u16 *p, p_save;
-	u16 *q, q_save;
-
-	/* do a memory check */
-
-	p = (u16 *) mda_vram_base;
-	q = (u16 *) (mda_vram_base + 0x01000);
-
-	p_save = scr_readw(p); q_save = scr_readw(q);
-
-	scr_writew(0xAA55, p); if (scr_readw(p) == 0xAA55) count++;
-	scr_writew(0x55AA, p); if (scr_readw(p) == 0x55AA) count++;
-	scr_writew(p_save, p);
-
-	if (count != 2) {
-		return 0;
-	}
-
-	/* check if we have 4K or 8K */
-
-	scr_writew(0xA55A, q); scr_writew(0x0000, p);
-	if (scr_readw(q) == 0xA55A) count++;
-	
-	scr_writew(0x5AA5, q); scr_writew(0x0000, p);
-	if (scr_readw(q) == 0x5AA5) count++;
-
-	scr_writew(p_save, p); scr_writew(q_save, q);
-	
-	if (count == 4) {
-		mda_vram_len = 0x02000;
-	}
-	
-	/* Ok, there is definitely a card registering at the correct
-	 * memory location, so now we do an I/O port test.
-	 */
-
-#ifdef TEST_MDA_B
-	/* Edward: These two mess `tests' mess up my cursor on bootup */
-
-	/* cursor low register */
-	if (! test_mda_b(0x66, 0x0f)) {
-		return 0;
-	}
-
-	/* cursor low register */
-	if (! test_mda_b(0x99, 0x0f)) {
-		return 0;
-	}
-#endif
-
-	/* See if the card is a Hercules, by checking whether the vsync
-	 * bit of the status register is changing.  This test lasts for
-	 * approximately 1/10th of a second.
-	 */
-	
-	p_save = q_save = inb_p(mda_status_port) & MDA_STATUS_VSYNC;
-
-	for (count=0; count < 50000 && p_save == q_save; count++) {
-		q_save = inb(mda_status_port) & MDA_STATUS_VSYNC;
-		udelay(2);
-	}
-
-	if (p_save != q_save) {
-		switch (inb_p(mda_status_port) & 0x70) {
-			case 0x10:
-				mda_type = TYPE_HERCPLUS;
-				mda_type_name = "HerculesPlus";
-				break;
-			case 0x50:
-				mda_type = TYPE_HERCCOLOR;
-				mda_type_name = "HerculesColor";
-				break;
-			default:
-				mda_type = TYPE_HERC;
-				mda_type_name = "Hercules";
-				break;
-		}
-	}
-
-	return 1;
-}
-
-static void __init mda_initialize(void)
-{
-	write_mda_b(97, 0x00);		/* horizontal total */
-	write_mda_b(80, 0x01);		/* horizontal displayed */
-	write_mda_b(82, 0x02);		/* horizontal sync pos */
-	write_mda_b(15, 0x03);		/* horizontal sync width */
-
-	write_mda_b(25, 0x04);		/* vertical total */
-	write_mda_b(6,  0x05);		/* vertical total adjust */
-	write_mda_b(25, 0x06);		/* vertical displayed */
-	write_mda_b(25, 0x07);		/* vertical sync pos */
-
-	write_mda_b(2,  0x08);		/* interlace mode */
-	write_mda_b(13, 0x09);		/* maximum scanline */
-	write_mda_b(12, 0x0a);		/* cursor start */
-	write_mda_b(13, 0x0b);		/* cursor end */
-
-	write_mda_w(0x0000, 0x0c);	/* start address */
-	write_mda_w(0x0000, 0x0e);	/* cursor location */
-
-	outb_p(MDA_MODE_VIDEO_EN | MDA_MODE_BLINK_EN, mda_mode_port);
-	outb_p(0x00, mda_status_port);
-	outb_p(0x00, mda_gfx_port);
-}
-
-static const char __init *mdacon_startup(void)
-{
-	mda_num_columns = 80;
-	mda_num_lines   = 25;
-
-	mda_vram_base = VGA_MAP_MEM(0xb0000);
-	mda_vram_len  = 0x01000;
-
-	mda_index_port  = 0x3b4;
-	mda_value_port  = 0x3b5;
-	mda_mode_port   = 0x3b8;
-	mda_status_port = 0x3ba;
-	mda_gfx_port    = 0x3bf;
-
-	mda_type = TYPE_MDA;
-	mda_type_name = "MDA";
-
-	if (! mda_detect()) {
-		printk("mdacon: MDA card not detected.\n");
-		return NULL;
-	}
-
-	if (mda_type != TYPE_MDA) {
-		mda_initialize();
-	}
-
-	/* cursor looks ugly during boot-up, so turn it off */
-	mda_set_cursor(mda_vram_len - 1);
-
-	printk("mdacon: %s with %ldK of memory detected.\n",
-		mda_type_name, mda_vram_len/1024);
-
-	return "MDA-2";
-}
-
-static void mdacon_init(struct vc_data *c, int init)
-{
-	c->vc_complement_mask = 0x0800;	 /* reverse video */
-	c->vc_display_fg = &mda_display_fg;
-
-	if (init) {
-		c->vc_cols = mda_num_columns;
-		c->vc_rows = mda_num_lines;
-	} else {
-		vc_resize_con(mda_num_lines, mda_num_columns, c->vc_num);
-        }
-	
-	/* make the first MDA console visible */
-
-	if (mda_display_fg == NULL)
-		mda_display_fg = c;
-
-	MOD_INC_USE_COUNT;
-}
-
-static void mdacon_deinit(struct vc_data *c)
-{
-	/* con_set_default_unimap(c->vc_num); */
-
-	if (mda_display_fg == c)
-		mda_display_fg = NULL;
-
-	MOD_DEC_USE_COUNT;
-}
-
-static inline u16 mda_convert_attr(u16 ch)
-{
-	u16 attr = 0x0700;
-
-	/* Underline and reverse-video are mutually exclusive on MDA.
-	 * Since reverse-video is used for cursors and selected areas,
-	 * it takes precedence. 
-	 */
-
-	if (ch & 0x0800)	attr = 0x7000;	/* reverse */
-	else if (ch & 0x0400)	attr = 0x0100;	/* underline */
-
-	return ((ch & 0x0200) << 2) | 		/* intensity */ 
-		(ch & 0x8000) |			/* blink */ 
-		(ch & 0x00ff) | attr;
-}
-
-static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity, 
-			    u8 blink, u8 underline, u8 reverse)
-{
-	/* The attribute is just a bit vector:
-	 *
-	 *	Bit 0..1 : intensity (0..2)
-	 *	Bit 2    : underline
-	 *	Bit 3    : reverse
-	 *	Bit 7    : blink
-	 */
-
-	return (intensity & 3) |
-		((underline & 1) << 2) |
-		((reverse   & 1) << 3) |
-		((blink     & 1) << 7);
-}
-
-static void mdacon_invert_region(struct vc_data *c, u16 *p, int count)
-{
-	for (; count > 0; count--) {
-		scr_writew(scr_readw(p) ^ 0x0800, p);
-		p++;
-	}
-}
-
-#define MDA_ADDR(x,y)  ((u16 *) mda_vram_base + (y)*mda_num_columns + (x))
-
-static void mdacon_putc(struct vc_data *c, int ch, int y, int x)
-{
-	scr_writew(mda_convert_attr(ch), MDA_ADDR(x, y));
-}
-
-static void mdacon_putcs(struct vc_data *c, const unsigned short *s,
-		         int count, int y, int x)
-{
-	u16 *dest = MDA_ADDR(x, y);
-
-	for (; count > 0; count--) {
-		scr_writew(mda_convert_attr(scr_readw(s++)), dest++);
-	}
-}
-
-static void mdacon_clear(struct vc_data *c, int y, int x, 
-			  int height, int width)
-{
-	u16 *dest = MDA_ADDR(x, y);
-	u16 eattr = mda_convert_attr(c->vc_video_erase_char);
-
-	if (width <= 0 || height <= 0)
-		return;
-
-	if (x==0 && width==mda_num_columns) {
-		scr_memsetw(dest, eattr, height*width*2);
-	} else {
-		for (; height > 0; height--, dest+=mda_num_columns)
-			scr_memsetw(dest, eattr, width*2);
-	}
-}
-                        
-static void mdacon_bmove(struct vc_data *c, int sy, int sx, 
-			 int dy, int dx, int height, int width)
-{
-	u16 *src, *dest;
-
-	if (width <= 0 || height <= 0)
-		return;
-		
-	if (sx==0 && dx==0 && width==mda_num_columns) {
-		scr_memmovew(MDA_ADDR(0,dy), MDA_ADDR(0,sy), height*width*2);
-
-	} else if (dy < sy || (dy == sy && dx < sx)) {
-		src  = MDA_ADDR(sx, sy);
-		dest = MDA_ADDR(dx, dy);
-
-		for (; height > 0; height--) {
-			scr_memmovew(dest, src, width*2);
-			src  += mda_num_columns;
-			dest += mda_num_columns;
-		}
-	} else {
-		src  = MDA_ADDR(sx, sy+height-1);
-		dest = MDA_ADDR(dx, dy+height-1);
-
-		for (; height > 0; height--) {
-			scr_memmovew(dest, src, width*2);
-			src  -= mda_num_columns;
-			dest -= mda_num_columns;
-		}
-	}
-}
-
-static int mdacon_switch(struct vc_data *c)
-{
-	return 1;	/* redrawing needed */
-}
-
-static int mdacon_set_palette(struct vc_data *c, unsigned char *table)
-{
-	return -EINVAL;
-}
-
-static int mdacon_blank(struct vc_data *c, int blank)
-{
-	if (mda_type == TYPE_MDA) {
-		if (blank) 
-			scr_memsetw((void *)mda_vram_base, 
-				mda_convert_attr(c->vc_video_erase_char),
-				c->vc_screenbuf_size);
-		/* Tell console.c that it has to restore the screen itself */
-		return 1;
-	} else {
-		if (blank)
-			outb_p(0x00, mda_mode_port);	/* disable video */
-		else
-			outb_p(MDA_MODE_VIDEO_EN | MDA_MODE_BLINK_EN, 
-				mda_mode_port);
-		return 0;
-	}
-}
-
-static int mdacon_font_op(struct vc_data *c, struct console_font_op *op)
-{
-	return -ENOSYS;
-}
-
-static int mdacon_scrolldelta(struct vc_data *c, int lines)
-{
-	return 0;
-}
-
-static void mdacon_cursor(struct vc_data *c, int mode)
-{
-	if (mode == CM_ERASE) {
-		mda_set_cursor(mda_vram_len - 1);
-		return;
-	}
-
-	mda_set_cursor(c->vc_y*mda_num_columns*2 + c->vc_x*2);
-
-	switch (c->vc_cursor_type & 0x0f) {
-
-		case CUR_LOWER_THIRD:	mda_set_cursor_size(10, 13); break;
-		case CUR_LOWER_HALF:	mda_set_cursor_size(7,  13); break;
-		case CUR_TWO_THIRDS:	mda_set_cursor_size(4,  13); break;
-		case CUR_BLOCK:		mda_set_cursor_size(1,  13); break;
-		case CUR_NONE:		mda_set_cursor_size(14, 13); break;
-		default:		mda_set_cursor_size(12, 13); break;
-	}
-}
-
-static int mdacon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
-{
-	u16 eattr = mda_convert_attr(c->vc_video_erase_char);
-
-	if (!lines)
-		return 0;
-
-	if (lines > c->vc_rows)   /* maximum realistic size */
-		lines = c->vc_rows;
-
-	switch (dir) {
-
-	case SM_UP:
-		scr_memmovew(MDA_ADDR(0,t), MDA_ADDR(0,t+lines),
-				(b-t-lines)*mda_num_columns*2);
-		scr_memsetw(MDA_ADDR(0,b-lines), eattr,
-				lines*mda_num_columns*2);
-		break;
-
-	case SM_DOWN:
-		scr_memmovew(MDA_ADDR(0,t+lines), MDA_ADDR(0,t),
-				(b-t-lines)*mda_num_columns*2);
-		scr_memsetw(MDA_ADDR(0,t), eattr, lines*mda_num_columns*2);
-		break;
-	}
-
-	return 0;
-}
-
-
-/*
- *  The console `switch' structure for the MDA based console
- */
-
-const struct consw mda_con = {
-	.con_startup =		mdacon_startup,
-	.con_init =		mdacon_init,
-	.con_deinit =		mdacon_deinit,
-	.con_clear =		mdacon_clear,
-	.con_putc =		mdacon_putc,
-	.con_putcs =		mdacon_putcs,
-	.con_cursor =		mdacon_cursor,
-	.con_scroll =		mdacon_scroll,
-	.con_bmove =		mdacon_bmove,
-	.con_switch =		mdacon_switch,
-	.con_blank =		mdacon_blank,
-	.con_font_op =		mdacon_font_op,
-	.con_set_palette =	mdacon_set_palette,
-	.con_scrolldelta =	mdacon_scrolldelta,
-	.con_build_attr =	mdacon_build_attr,
-	.con_invert_region =	mdacon_invert_region,
-};
-
-void __init mda_console_init(void)
-{
-	if (mda_first_vc > mda_last_vc)
-		return;
-
-	take_over_console(&mda_con, mda_first_vc-1, mda_last_vc-1, 0);
-}
-
-#ifdef MODULE
-
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
-	mda_console_init();
-
-	return 0;
-}
-
-void cleanup_module(void)
-{
-	give_up_console(&mda_con);
-}
-
-#endif
diff -Nru a/drivers/video/modedb.c b/drivers/video/modedb.c
--- a/drivers/video/modedb.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/video/modedb.c	Mon Dec  9 18:46:37 2002
@@ -16,8 +16,6 @@
 #include <linux/fb.h>
 #include <linux/sched.h>
 
-#include <video/fbcon.h>
-
 #undef DEBUG
 
 #define name_matches(v, s, l) \
@@ -277,7 +275,7 @@
 int __fb_try_mode(struct fb_var_screeninfo *var, struct fb_info *info,
 		  const struct fb_videomode *mode, unsigned int bpp)
 {
-    int err;
+    int err = 1;
 
     DPRINTK("Trying mode %s %dx%d-%d@%d\n", mode->name ? mode->name : "noname",
 	    mode->xres, mode->yres, bpp, mode->refresh);
@@ -298,7 +296,8 @@
     var->vsync_len = mode->vsync_len;
     var->sync = mode->sync;
     var->vmode = mode->vmode;
-    err = info->fbops->fb_set_var(var, PROC_CONSOLE(info), info);
+    if (info->fbops->fb_check_var)
+    	err = info->fbops->fb_check_var(var, info);
     var->activate &= ~FB_ACTIVATE_TEST;
     return !err;
 }
diff -Nru a/drivers/video/neofb.c b/drivers/video/neofb.c
--- a/drivers/video/neofb.c	Mon Dec  9 18:46:49 2002
+++ b/drivers/video/neofb.c	Mon Dec  9 18:46:49 2002
@@ -1,7 +1,7 @@
 /*
  * linux/drivers/video/neofb.c -- NeoMagic Framebuffer Driver
  *
- * Copyright (c) 2001  Denis Oliver Kropp <dok@convergence.de>
+ * Copyright (c) 2001-2002  Denis Oliver Kropp <dok@directfb.org>
  *
  *
  * Card specific code is based on XFree86's neomagic driver.
@@ -11,6 +11,16 @@
  * Public License.  See the file COPYING in the main directory of this
  * archive for more details.
  *
+ *
+ * 0.4.1
+ *  - Cosmetic changes (dok)
+ *
+ * 0.4
+ *  - Toshiba Libretto support, allow modes larger than LCD size if
+ *    LCD is disabled, keep BIOS settings if internal/external display
+ *    haven't been enabled explicitly
+ *                          (Thomas J. Moore <dark@mama.indstate.edu>)
+ *
  * 0.3.3
  *  - Porting over to new fbdev api. (jsimmons)
  *  
@@ -56,6 +66,10 @@
 #include <linux/fb.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#ifdef CONFIG_TOSHIBA
+#include <linux/toshiba.h>
+extern int tosh_smm(SMMRegisters *regs);
+#endif
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -67,20 +81,18 @@
 #include <asm/mtrr.h>
 #endif
 
-#include <video/fbcon.h>
 #include <video/neomagic.h>
 
-#define NEOFB_VERSION "0.3.3"
-
-struct neofb_par default_par;
+#define NEOFB_VERSION "0.4.1"
 
 /* --------------------------------------------------------------------- */
 
-static int disabled = 0;
-static int internal = 0;
-static int external = 0;
-static int nostretch = 0;
-static int nopciburst = 0;
+static int disabled;
+static int internal;
+static int external;
+static int libretto;
+static int nostretch;
+static int nopciburst;
 
 
 #ifdef MODULE
@@ -94,6 +106,8 @@
 MODULE_PARM_DESC(internal, "Enable output on internal LCD Display.");
 MODULE_PARM(external, "i");
 MODULE_PARM_DESC(external, "Enable output on external CRT.");
+MODULE_PARM(libretto, "i");
+MODULE_PARM_DESC(libretto, "Force Libretto 100/110 800x480 LCD.");
 MODULE_PARM(nostretch, "i");
 MODULE_PARM_DESC(nostretch,
 		 "Disable stretching of modes smaller than LCD.");
@@ -450,15 +464,17 @@
 /*
  * Hardware Acceleration for Neo2200+
  */
-static inline void neo2200_wait_idle(struct neofb_par *par)
+static inline int neo2200_sync(struct fb_info *info)
 {
+	struct neofb_par *par = (struct neofb_par *) info->par;
 	int waitcycles;
 
 	while (par->neo2200->bltStat & 1)
 		waitcycles++;
+	return 0;
 }
 
-static inline void neo2200_wait_fifo(struct neofb_par *par,
+static inline void neo2200_wait_fifo(struct fb_info *info,
 				     int requested_fifo_space)
 {
 	//  ndev->neo.waitfifo_calls++;
@@ -484,17 +500,17 @@
 	   neo_fifo_space -= requested_fifo_space;
 	 */
 
-	neo2200_wait_idle(par);
+	neo2200_sync(info);
 }
 
-static inline void neo2200_accel_init(struct fb_info *fb,
+static inline void neo2200_accel_init(struct fb_info *info,
 				      struct fb_var_screeninfo *var)
 {
-	struct neofb_par *par = (struct neofb_par *) fb->par;
+	struct neofb_par *par = (struct neofb_par *) info->par;
 	Neo2200 *neo2200 = par->neo2200;
 	u32 bltMod, pitch;
 
-	neo2200_wait_idle(par);
+	neo2200_sync(info);
 
 	switch (var->bits_per_pixel) {
 	case 8:
@@ -551,8 +567,9 @@
 	timings.sync = var->sync;
 
 	/* Is the mode larger than the LCD panel? */
-	if ((var->xres > par->NeoPanelWidth) ||
-	    (var->yres > par->NeoPanelHeight)) {
+	if (par->internal_display &&
+            ((var->xres > par->NeoPanelWidth) ||
+	     (var->yres > par->NeoPanelHeight))) {
 		printk(KERN_INFO
 		       "Mode (%dx%d) larger than the LCD panel (%dx%d)\n",
 		       var->xres, var->yres, par->NeoPanelWidth,
@@ -561,23 +578,27 @@
 	}
 
 	/* Is the mode one of the acceptable sizes? */
-	switch (var->xres) {
-	case 1280:
-		if (var->yres == 1024)
-			mode_ok = 1;
-		break;
-	case 1024:
-		if (var->yres == 768)
-			mode_ok = 1;
-		break;
-	case 800:
-		if (var->yres == 600)
-			mode_ok = 1;
-		break;
-	case 640:
-		if (var->yres == 480)
-			mode_ok = 1;
-		break;
+	if (!par->internal_display)
+		mode_ok = 1;
+	else {
+		switch (var->xres) {
+		case 1280:
+			if (var->yres == 1024)
+				mode_ok = 1;
+			break;
+		case 1024:
+			if (var->yres == 768)
+				mode_ok = 1;
+			break;
+		case 800:
+			if (var->yres == (par->libretto ? 480 : 600))
+				mode_ok = 1;
+			break;
+		case 640:
+			if (var->yres == 480)
+				mode_ok = 1;
+			break;
+		}
 	}
 
 	if (!mode_ok) {
@@ -674,6 +695,10 @@
 	if (var->yoffset + var->yres > var->yres_virtual)
 		var->yoffset = var->yres_virtual - var->yres;
 
+	var->nonstd = 0;
+	var->height = -1;
+	var->width = -1;
+
 	if (var->bits_per_pixel >= 24 || !par->neo2200)
 		var->accel_flags &= ~FB_ACCELF_TEXT;
 	return 0;
@@ -1165,10 +1190,9 @@
 /*
  *    Pan or Wrap the Display
  */
-static int neofb_pan_display(struct fb_var_screeninfo *var, int con,
-			     struct fb_info *fb)
+static int neofb_pan_display(struct fb_var_screeninfo *var,
+			     struct fb_info *info)
 {
-	struct fb_info *info = (struct fb_info *) fb;
 	u_int y_bottom;
 
 	y_bottom = var->yoffset;
@@ -1178,19 +1202,18 @@
 
 	if (var->xoffset > (var->xres_virtual - var->xres))
 		return -EINVAL;
-	if (y_bottom > fb->var.yres_virtual)
+	if (y_bottom > info->var.yres_virtual)
 		return -EINVAL;
 
 	neofb_update_start(info, var);
 
-	fb->var.xoffset = var->xoffset;
-	fb->var.yoffset = var->yoffset;
+	info->var.xoffset = var->xoffset;
+	info->var.yoffset = var->yoffset;
 
 	if (var->vmode & FB_VMODE_YWRAP)
-		fb->var.vmode |= FB_VMODE_YWRAP;
+		info->var.vmode |= FB_VMODE_YWRAP;
 	else
-		fb->var.vmode &= ~FB_VMODE_YWRAP;
-
+		info->var.vmode &= ~FB_VMODE_YWRAP;
 	return 0;
 }
 
@@ -1239,10 +1262,8 @@
 /*
  *    (Un)Blank the display.
  */
-static int neofb_blank(int blank, struct fb_info *fb)
+static int neofb_blank(int blank, struct fb_info *info)
 {
-	//  struct fb_info *info = (struct fb_info *)fb;
-
 	/*
 	 *  Blank the screen if blank_mode != 0, else unblank. If
 	 *  blank == NULL then the caller blanks by setting the CLUT
@@ -1261,6 +1282,17 @@
 
 	switch (blank) {
 	case 4:		/* powerdown - both sync lines down */
+#ifdef CONFIG_TOSHIBA
+		/* attempt to turn off backlight on toshiba; also turns off external */
+		{
+			SMMRegisters regs;
+
+			regs.eax = 0xff00; /* HCI_SET */
+			regs.ebx = 0x0002; /* HCI_BACKLIGHT */
+			regs.ecx = 0x0000; /* HCI_DISABLE */
+			tosh_smm(&regs);
+		}
+#endif
 		break;
 	case 3:		/* hsync off */
 		break;
@@ -1269,13 +1301,24 @@
 	case 1:		/* just software blanking of screen */
 		break;
 	default:		/* case 0, or anything else: unblank */
+#ifdef CONFIG_TOSHIBA
+		/* attempt to re-enable backlight/external on toshiba */
+		{
+			SMMRegisters regs;
+
+			regs.eax = 0xff00; /* HCI_SET */
+			regs.ebx = 0x0002; /* HCI_BACKLIGHT */
+			regs.ecx = 0x0001; /* HCI_ENABLE */
+			tosh_smm(&regs);
+		}
+#endif
 		break;
 	}
 	return 0;
 }
 
 static void
-neo2200fb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+neo2200_fillrect(struct fb_info *info, struct fb_fillrect *rect)
 {
 	struct neofb_par *par = (struct neofb_par *) info->par;
 	u_long dst, rop;
@@ -1283,7 +1326,7 @@
 	dst = rect->dx + rect->dy * info->var.xres_virtual;
 	rop = rect->rop ? 0x060000 : 0x0c0000;
 
-	neo2200_wait_fifo(par, 4);
+	neo2200_wait_fifo(info, 4);
 
 	/* set blt control */
 	par->neo2200->bltCntl = NEO_BC3_FIFO_EN |
@@ -1309,7 +1352,7 @@
 }
 
 static void
-neo2200fb_copyarea(struct fb_info *info, struct fb_copyarea *area)
+neo2200_copyarea(struct fb_info *info, struct fb_copyarea *area)
 {
 	struct neofb_par *par = (struct neofb_par *) info->par;
 	u_long src, dst, bltCntl;
@@ -1337,7 +1380,7 @@
 	    area->dx * (info->var.bits_per_pixel >> 3) +
 	    area->dy * info->fix.line_length;
 
-	neo2200_wait_fifo(par, 4);
+	neo2200_wait_fifo(info, 4);
 
 	/* set blt control */
 	par->neo2200->bltCntl = bltCntl;
@@ -1349,11 +1392,11 @@
 }
 
 static void
-neo2200fb_imageblit(struct fb_info *info, struct fb_image *image)
+neo2200_imageblit(struct fb_info *info, struct fb_image *image)
 {
 	struct neofb_par *par = (struct neofb_par *) info->par;
 
-	neo2200_wait_idle(par);
+	neo2200_sync(info);
 
 	switch (info->var.bits_per_pixel) {
 	case 8:
@@ -1385,98 +1428,140 @@
 	       (image->width * image->height) >> 3);
 }
 
+static void
+neofb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+{
+	if (info->var.accel_flags == FB_ACCELF_TEXT)
+		neo2200_fillrect(info, rect);	
+	else
+		cfb_fillrect(info, rect);
+}
+
+static void
+neofb_copyarea(struct fb_info *info, struct fb_copyarea *area)
+{
+	if (info->var.accel_flags == FB_ACCELF_TEXT)
+		neo2200_copyarea(info, area);	
+	else
+		cfb_copyarea(info, area);	
+}
+
+static void
+neofb_imageblit(struct fb_info *info, struct fb_image *image)
+{
+	if (info->var.accel_flags == FB_ACCELF_TEXT)
+		neo2200_imageblit(info, image);	
+	else
+		cfb_imageblit(info, image);	
+}	
+	
 static struct fb_ops neofb_ops = {
 	.owner		= THIS_MODULE,
 	.fb_check_var	= neofb_check_var,
 	.fb_set_par	= neofb_set_par,
-	.fb_set_var	= gen_set_var,
-	.fb_get_cmap	= gen_get_cmap,
-	.fb_set_cmap	= gen_set_cmap,
 	.fb_setcolreg	= neofb_setcolreg,
 	.fb_pan_display	= neofb_pan_display,
 	.fb_blank	= neofb_blank,
-	.fb_fillrect	= cfb_fillrect,
-	.fb_copyarea	= cfb_copyarea,
-	.fb_imageblit	= cfb_imageblit,
+	.fb_sync	= neo2200_sync,
+	.fb_fillrect	= neofb_fillrect,
+	.fb_copyarea	= neofb_copyarea,
+	.fb_imageblit	= neofb_imageblit,
+	.fb_cursor	= soft_cursor,
 };
 
 /* --------------------------------------------------------------------- */
 
 static struct fb_var_screeninfo __devinitdata neofb_var640x480x8 = {
-	accel_flags:	FB_ACCELF_TEXT,
-	xres:		640,
-	yres:		480,
-	xres_virtual:	640,
-	yres_virtual:	30000,
-	bits_per_pixel:	8,
-	pixclock:	39722,
-	left_margin:	48,
-	right_margin:	16,
-	upper_margin:	33,
-	lower_margin:	10,
-	hsync_len:	96,
-	vsync_len:	2,
-	vmode:		FB_VMODE_NONINTERLACED
+	.accel_flags    = FB_ACCELF_TEXT,
+	.xres           = 640,
+	.yres           = 480,
+	.xres_virtual   = 640,
+	.yres_virtual   = 30000,
+	.bits_per_pixel = 8,
+	.pixclock       = 39722,
+	.left_margin    = 48,
+	.right_margin   = 16,
+	.upper_margin   = 33,
+	.lower_margin   = 10,
+	.hsync_len      = 96,
+	.vsync_len      = 2,
+	.vmode          = FB_VMODE_NONINTERLACED
 };
 
 static struct fb_var_screeninfo __devinitdata neofb_var800x600x8 = {
-	accel_flags:	FB_ACCELF_TEXT,
-	xres:		800,
-	yres:		600,
-	xres_virtual:	800,
-	yres_virtual:	30000,
-	bits_per_pixel:	8,
-	pixclock:	25000,
-	left_margin:	88,
-	right_margin:	40,
-	upper_margin:	23,
-	lower_margin:	1,
-	hsync_len:	128,
-	vsync_len:	4,
-	sync:		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-	vmode:		FB_VMODE_NONINTERLACED
+	.accel_flags    = FB_ACCELF_TEXT,
+	.xres           = 800,
+	.yres           = 600,
+	.xres_virtual   = 800,
+	.yres_virtual   = 30000,
+	.bits_per_pixel = 8,
+	.pixclock       = 25000,
+	.left_margin    = 88,
+	.right_margin   = 40,
+	.upper_margin   = 23,
+	.lower_margin   = 1,
+	.hsync_len      = 128,
+	.vsync_len      = 4,
+	.sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+	.vmode          = FB_VMODE_NONINTERLACED
+};
+
+static struct fb_var_screeninfo __devinitdata neofb_var800x480x8 = {
+	.accel_flags    = FB_ACCELF_TEXT,
+	.xres           = 800,
+	.yres           = 480,
+	.xres_virtual   = 800,
+	.yres_virtual   = 30000,
+	.bits_per_pixel = 8,
+	.pixclock       = 25000,
+	.left_margin    = 88,
+	.right_margin   = 40,
+	.upper_margin   = 23,
+	.lower_margin   = 1,
+	.hsync_len      = 128,
+	.vsync_len      = 4,
+	.sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+	.vmode          = FB_VMODE_NONINTERLACED
 };
 
 static struct fb_var_screeninfo __devinitdata neofb_var1024x768x8 = {
-	accel_flags:	FB_ACCELF_TEXT,
-	xres:		1024,
-	yres:		768,
-	xres_virtual:	1024,
-	yres_virtual:	30000,
-	bits_per_pixel:	8,
-	pixclock:	15385,
-	left_margin:	160,
-	right_margin:	24,
-	upper_margin:	29,
-	lower_margin:	3,
-	hsync_len:	136,
-	vsync_len:	6,
-	sync:		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-	vmode:		FB_VMODE_NONINTERLACED
+	.accel_flags    = FB_ACCELF_TEXT,
+	.xres           = 1024,
+	.yres           = 768,
+	.xres_virtual   = 1024,
+	.yres_virtual   = 30000,
+	.bits_per_pixel = 8,
+	.pixclock       = 15385,
+	.left_margin    = 160,
+	.right_margin   = 24,
+	.upper_margin   = 29,
+	.lower_margin   = 3,
+	.hsync_len      = 136,
+	.vsync_len      = 6,
+	.sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+	.vmode          = FB_VMODE_NONINTERLACED
 };
 
 #ifdef NOT_DONE
 static struct fb_var_screeninfo __devinitdata neofb_var1280x1024x8 = {
-	accel_flags:	FB_ACCELF_TEXT,
-	xres:		1280,
-	yres:		1024,
-	xres_virtual:	1280,
-	yres_virtual:	30000,
-	bits_per_pixel:	8,
-	pixclock:	9260,
-	left_margin:	248,
-	right_margin:	48,
-	upper_margin:	38,
-	lower_margin:	1,
-	hsync_len:	112,
-	vsync_len:	3,
-	sync:		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-	vmode:		FB_VMODE_NONINTERLACED
+	.accel_flags    = FB_ACCELF_TEXT,
+	.xres           = 1280,
+	.yres           = 1024,
+	.xres_virtual   = 1280,
+	.yres_virtual   = 30000,
+	.bits_per_pixel = 8,
+	.pixclock       = 9260,
+	.left_margin    = 248,
+	.right_margin   = 48,
+	.upper_margin   = 38,
+	.lower_margin   = 1,
+	.hsync_len      = 112,
+	.vsync_len      = 3,
+	.sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+	.vmode          = FB_VMODE_NONINTERLACED
 };
 #endif
 
-static struct fb_var_screeninfo *neofb_var = NULL;
-
 static int __devinit neo_map_mmio(struct fb_info *info,
 				  struct pci_dev *dev)
 {
@@ -1581,6 +1666,7 @@
 static int __devinit neo_init_hw(struct fb_info *info)
 {
 	struct neofb_par *par = (struct neofb_par *) info->par;
+	unsigned char type, display;
 	int videoRam = 896;
 	int maxClock = 65000;
 	int CursorMem = 1024;
@@ -1588,7 +1674,6 @@
 	int linearSize = 1024;
 	int maxWidth = 1024;
 	int maxHeight = 1024;
-	unsigned char type, display;
 	int w;
 
 	DBG("neo_init_hw");
@@ -1609,6 +1694,13 @@
 	VGAwGR(0x09, 0x26);
 	type = VGArGR(0x21);
 	display = VGArGR(0x20);
+	if (!par->internal_display && !par->external_display) {
+		par->internal_display = display & 2 || !(display & 3) ? 1 : 0;
+		par->external_display = display & 1;
+		printk (KERN_INFO "Autodetected %s display\n",
+			par->internal_display && par->external_display ? "simultaneous" :
+			par->internal_display ? "internal" : "external");
+	}
 
 	/* Determine panel width -- used in NeoValidMode. */
 	w = VGArGR(0x20);
@@ -1617,34 +1709,34 @@
 	case 0x00:
 		par->NeoPanelWidth = 640;
 		par->NeoPanelHeight = 480;
-		neofb_var = &neofb_var640x480x8;
+		info->var = neofb_var640x480x8;
 		break;
 	case 0x01:
 		par->NeoPanelWidth = 800;
-		par->NeoPanelHeight = 600;
-		neofb_var = &neofb_var800x600x8;
+		par->NeoPanelHeight = par->libretto ? 480 : 600;
+		info->var = par->libretto ? neofb_var800x480x8 : neofb_var800x600x8;
 		break;
 	case 0x02:
 		par->NeoPanelWidth = 1024;
 		par->NeoPanelHeight = 768;
-		neofb_var = &neofb_var1024x768x8;
+		info->var = neofb_var1024x768x8;
 		break;
 	case 0x03:
 		/* 1280x1024 panel support needs to be added */
 #ifdef NOT_DONE
 		par->NeoPanelWidth = 1280;
 		par->NeoPanelHeight = 1024;
-		neofb_var = &neofb_var1280x1024x8;
+		info->var = neofb_var1280x1024x8;
 		break;
 #else
 		printk(KERN_ERR
-		       "neofb: Only 640x480, 800x600 and 1024x768 panels are currently supported\n");
+		       "neofb: Only 640x480, 800x600/480 and 1024x768 panels are currently supported\n");
 		return -1;
 #endif
 	default:
 		par->NeoPanelWidth = 640;
 		par->NeoPanelHeight = 480;
-		neofb_var = &neofb_var640x480x8;
+		info->var = neofb_var640x480x8;
 		break;
 	}
 
@@ -1750,30 +1842,24 @@
 	struct fb_info *info;
 	struct neofb_par *par;
 
-	info = kmalloc(sizeof(struct fb_info) + sizeof(struct display) +
-		       sizeof(u32) * 16, GFP_KERNEL);
+	info = kmalloc(sizeof(struct fb_info) + sizeof(struct neofb_par) + 
+		       sizeof(u32) * 17, GFP_KERNEL);
 
 	if (!info)
 		return NULL;
 
-	memset(info, 0, sizeof(struct fb_info) + sizeof(struct display));
+	memset(info, 0, sizeof(struct fb_info) + sizeof(struct neofb_par) + sizeof(u32) * 17);
 
-	par = &default_par;
-	memset(par, 0, sizeof(struct neofb_par));
+	par = (struct neofb_par *) (info + 1);
 
-	info->currcon = -1;
 	info->fix.accel = id->driver_data;
 
 	par->pci_burst = !nopciburst;
 	par->lcd_stretch = !nostretch;
+	par->libretto = libretto;
 
-	if (!internal && !external) {
-		par->internal_display = 1;
-		par->external_display = 0;
-	} else {
-		par->internal_display = internal;
-		par->external_display = external;
-	}
+	par->internal_display = internal;
+	par->external_display = external;
 
 	switch (info->fix.accel) {
 	case FB_ACCEL_NEOMAGIC_NM2070:
@@ -1812,22 +1898,10 @@
 	info->fix.ywrapstep = 0;
 	info->fix.accel = id->driver_data;
 
-	info->var.nonstd = 0;
-	info->var.activate = FB_ACTIVATE_NOW;
-	info->var.height = -1;
-	info->var.width = -1;
-	info->var.accel_flags = 0;
-
-	strcpy(info->modename, info->fix.id);
-
 	info->fbops = &neofb_ops;
-	info->changevar = NULL;
-	info->switch_con = gen_switch;
-	info->updatevar = gen_update_var;
 	info->flags = FBINFO_FLAG_DEFAULT;
 	info->par = par;
-	info->disp = (struct display *) (info + 1);
-	info->pseudo_palette = (void *) (info->disp + 1);
+	info->pseudo_palette = (void *) (par + 1);
 
 	fb_alloc_cmap(&info->cmap, NR_PALETTE, 0);
 
@@ -1881,8 +1955,6 @@
 	if (err)
 		goto failed;
 
-	gen_set_var(neofb_var, -1, info);
-
 	/*
 	 * Calculate the hsync and vsync frequencies.  Note that
 	 * we split the 1e12 constant up so that we can preserve
@@ -1908,7 +1980,7 @@
 		goto failed;
 
 	printk(KERN_INFO "fb%d: %s frame buffer device\n",
-	       GET_FB_IDX(info->node), info->modename);
+	       minor(info->node), info->fix.id);
 
 	/*
 	 * Our driver data
@@ -2008,7 +2080,6 @@
 	pci_unregister_driver(&neofb_driver);
 }
 
-
 #ifndef MODULE
 
 /* ************************* init in-kernel code ************************** */
@@ -2036,6 +2107,8 @@
 			nostretch = 1;
 		if (!strncmp(this_opt, "nopciburst", 10))
 			nopciburst = 1;
+		if (!strncmp(this_opt, "libretto", 8))
+			libretto = 1;
 	}
 
 	return 0;
diff -Nru a/drivers/video/newport_con.c b/drivers/video/newport_con.c
--- a/drivers/video/newport_con.c	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,746 +0,0 @@
-/*
- * newport_con.c: Abscon for newport hardware
- * 
- * (C) 1998 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
- * (C) 1999 Ulf Carlsson (ulfc@thepuffingruop.com)
- * 
- * This driver is based on sgicons.c and cons_newport.
- * 
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx)
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/tty.h>
-#include <linux/kd.h>
-#include <linux/selection.h>
-#include <linux/console.h>
-#include <linux/console_struct.h>
-#include <linux/vt_kern.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <video/newport.h>
-#define INCLUDE_LINUX_LOGO_DATA
-#include <asm/linux_logo.h>
-
-#include <video/font.h>
-
-#define LOGO_W		80
-#define LOGO_H		80
-
-extern struct fbcon_font_desc font_vga_8x16;
-
-#define FONT_DATA ((unsigned char *)font_vga_8x16.data)
-
-/* borrowed from fbcon.c */
-#define REFCOUNT(fd)	(((int *)(fd))[-1])
-#define FNTSIZE(fd)	(((int *)(fd))[-2])
-#define FNTCHARCNT(fd)	(((int *)(fd))[-3])
-#define FONT_EXTRA_WORDS 3
-
-static unsigned char *font_data[MAX_NR_CONSOLES];
-
-extern struct newport_regs *npregs;
-
-static int logo_active;
-static int topscan;
-static int xcurs_correction = 29;
-static int newport_xsize;
-static int newport_ysize;
-
-#define BMASK(c) (c << 24)
-
-#define RENDER(regs, cp) do { \
-(regs)->go.zpattern = BMASK((cp)[0x0]); (regs)->go.zpattern = BMASK((cp)[0x1]); \
-(regs)->go.zpattern = BMASK((cp)[0x2]); (regs)->go.zpattern = BMASK((cp)[0x3]); \
-(regs)->go.zpattern = BMASK((cp)[0x4]); (regs)->go.zpattern = BMASK((cp)[0x5]); \
-(regs)->go.zpattern = BMASK((cp)[0x6]); (regs)->go.zpattern = BMASK((cp)[0x7]); \
-(regs)->go.zpattern = BMASK((cp)[0x8]); (regs)->go.zpattern = BMASK((cp)[0x9]); \
-(regs)->go.zpattern = BMASK((cp)[0xa]); (regs)->go.zpattern = BMASK((cp)[0xb]); \
-(regs)->go.zpattern = BMASK((cp)[0xc]); (regs)->go.zpattern = BMASK((cp)[0xd]); \
-(regs)->go.zpattern = BMASK((cp)[0xe]); (regs)->go.zpattern = BMASK((cp)[0xf]); \
-} while(0)
-
-#define TESTVAL 0xdeadbeef
-#define XSTI_TO_FXSTART(val) (((val) & 0xffff) << 11)
-
-static inline void newport_render_background(int xstart, int ystart,
-					     int xend, int yend, int ci)
-{
-	newport_wait();
-	npregs->set.wrmask = 0xffffffff;
-	npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
-				 NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
-				 | NPORT_DMODE0_STOPY);
-	npregs->set.colori = ci;
-	npregs->set.xystarti =
-	    (xstart << 16) | ((ystart + topscan) & 0x3ff);
-	npregs->go.xyendi =
-	    ((xend + 7) << 16) | ((yend + topscan + 15) & 0x3ff);
-}
-
-static inline void newport_init_cmap(void)
-{
-	unsigned short i;
-
-	for (i = 0; i < 16; i++) {
-		newport_bfwait();
-		newport_cmap_setaddr(npregs, color_table[i]);
-		newport_cmap_setrgb(npregs,
-				    default_red[i],
-				    default_grn[i], default_blu[i]);
-	}
-}
-
-static inline void newport_show_logo(void)
-{
-	unsigned long i;
-
-	for (i = 0; i < LINUX_LOGO_COLORS; i++) {
-		newport_bfwait();
-		newport_cmap_setaddr(npregs, i + 0x20);
-		newport_cmap_setrgb(npregs,
-				    linux_logo_red[i],
-				    linux_logo_green[i],
-				    linux_logo_blue[i]);
-	}
-
-	newport_wait();
-	npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
-				 NPORT_DMODE0_CHOST);
-
-	npregs->set.xystarti = ((newport_xsize - LOGO_W) << 16) | (0);
-	npregs->set.xyendi = ((newport_xsize - 1) << 16);
-	newport_wait();
-
-	for (i = 0; i < LOGO_W * LOGO_H; i++)
-		npregs->go.hostrw0 = linux_logo[i] << 24;
-}
-
-static inline void newport_clear_screen(int xstart, int ystart, int xend,
-					int yend, int ci)
-{
-	if (logo_active)
-		return;
-
-	newport_wait();
-	npregs->set.wrmask = 0xffffffff;
-	npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
-				 NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
-				 | NPORT_DMODE0_STOPY);
-	npregs->set.colori = ci;
-	npregs->set.xystarti = (xstart << 16) | ystart;
-	npregs->go.xyendi = (xend << 16) | yend;
-}
-
-static inline void newport_clear_lines(int ystart, int yend, int ci)
-{
-	ystart = ((ystart << 4) + topscan) & 0x3ff;
-	yend = ((yend << 4) + topscan + 15) & 0x3ff;
-	newport_clear_screen(0, ystart, 1280 + 63, yend, ci);
-}
-
-void newport_reset(void)
-{
-	unsigned short treg;
-	int i;
-
-	newport_wait();
-	treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
-	newport_vc2_set(npregs, VC2_IREG_CONTROL,
-			(treg | VC2_CTRL_EVIDEO));
-
-	treg = newport_vc2_get(npregs, VC2_IREG_CENTRY);
-	newport_vc2_set(npregs, VC2_IREG_RADDR, treg);
-	npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
-			       NPORT_DMODE_W2 | VC2_PROTOCOL);
-	for (i = 0; i < 128; i++) {
-		newport_bfwait();
-		if (i == 92 || i == 94)
-			npregs->set.dcbdata0.byshort.s1 = 0xff00;
-		else
-			npregs->set.dcbdata0.byshort.s1 = 0x0000;
-	}
-
-	newport_init_cmap();
-
-	/* turn off popup plane */
-	npregs->set.dcbmode = (DCB_XMAP0 | R_DCB_XMAP9_PROTOCOL |
-			       XM9_CRS_CONFIG | NPORT_DMODE_W1);
-	npregs->set.dcbdata0.bybytes.b3 &= ~XM9_PUPMODE;
-	npregs->set.dcbmode = (DCB_XMAP1 | R_DCB_XMAP9_PROTOCOL |
-			       XM9_CRS_CONFIG | NPORT_DMODE_W1);
-	npregs->set.dcbdata0.bybytes.b3 &= ~XM9_PUPMODE;
-
-	topscan = 0;
-	npregs->cset.topscan = 0x3ff;
-	npregs->cset.xywin = (4096 << 16) | 4096;
-
-	/* Clear the screen. */
-	newport_clear_screen(0, 0, 1280 + 63, 1024, 0);
-}
-
-/*
- * calculate the actual screen size by reading
- * the video timing out of the VC2
- */
-void newport_get_screensize(void)
-{
-	int i, cols;
-	unsigned short ventry, treg;
-	unsigned short linetable[128];	/* should be enough */
-
-	ventry = newport_vc2_get(npregs, VC2_IREG_VENTRY);
-	newport_vc2_set(npregs, VC2_IREG_RADDR, ventry);
-	npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
-			       NPORT_DMODE_W2 | VC2_PROTOCOL);
-	for (i = 0; i < 128; i++) {
-		newport_bfwait();
-		linetable[i] = npregs->set.dcbdata0.byshort.s1;
-	}
-
-	newport_xsize = newport_ysize = 0;
-	for (i = 0; linetable[i + 1] && (i < sizeof(linetable)); i += 2) {
-		cols = 0;
-		newport_vc2_set(npregs, VC2_IREG_RADDR, linetable[i]);
-		npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
-				       NPORT_DMODE_W2 | VC2_PROTOCOL);
-		do {
-			newport_bfwait();
-			treg = npregs->set.dcbdata0.byshort.s1;
-			if ((treg & 1) == 0)
-				cols += (treg >> 7) & 0xfe;
-			if ((treg & 0x80) == 0) {
-				newport_bfwait();
-				treg = npregs->set.dcbdata0.byshort.s1;
-			}
-		} while ((treg & 0x8000) == 0);
-		if (cols) {
-			if (cols > newport_xsize)
-				newport_xsize = cols;
-			newport_ysize += linetable[i + 1];
-		}
-	}
-	printk("NG1: Screensize %dx%d\n", newport_xsize, newport_ysize);
-}
-
-static void newport_get_revisions(void)
-{
-	unsigned int tmp;
-	unsigned int board_rev;
-	unsigned int rex3_rev;
-	unsigned int vc2_rev;
-	unsigned int cmap_rev;
-	unsigned int xmap9_rev;
-	unsigned int bt445_rev;
-	unsigned int bitplanes;
-
-	rex3_rev = npregs->cset.status & NPORT_STAT_VERS;
-
-	npregs->set.dcbmode = (DCB_CMAP0 | NCMAP_PROTOCOL |
-			       NCMAP_REGADDR_RREG | NPORT_DMODE_W1);
-	tmp = npregs->set.dcbdata0.bybytes.b3;
-	cmap_rev = tmp & 7;
-	board_rev = (tmp >> 4) & 7;
-	bitplanes = ((board_rev > 1) && (tmp & 0x80)) ? 8 : 24;
-
-	npregs->set.dcbmode = (DCB_CMAP1 | NCMAP_PROTOCOL |
-			       NCMAP_REGADDR_RREG | NPORT_DMODE_W1);
-	tmp = npregs->set.dcbdata0.bybytes.b3;
-	if ((tmp & 7) < cmap_rev)
-		cmap_rev = (tmp & 7);
-
-	vc2_rev = (newport_vc2_get(npregs, VC2_IREG_CONFIG) >> 5) & 7;
-
-	npregs->set.dcbmode = (DCB_XMAP0 | R_DCB_XMAP9_PROTOCOL |
-			       XM9_CRS_REVISION | NPORT_DMODE_W1);
-	xmap9_rev = npregs->set.dcbdata0.bybytes.b3 & 7;
-
-	npregs->set.dcbmode = (DCB_BT445 | BT445_PROTOCOL |
-			       BT445_CSR_ADDR_REG | NPORT_DMODE_W1);
-	npregs->set.dcbdata0.bybytes.b3 = BT445_REVISION_REG;
-	npregs->set.dcbmode = (DCB_BT445 | BT445_PROTOCOL |
-			       BT445_CSR_REVISION | NPORT_DMODE_W1);
-	bt445_rev = (npregs->set.dcbdata0.bybytes.b3 >> 4) - 0x0a;
-
-#define L(a)     (char)('A'+(a))
-	printk
-	    ("NG1: Revision %d, %d bitplanes, REX3 revision %c, VC2 revision %c, xmap9 revision %c, cmap revision %c, bt445 revision %c\n",
-	     board_rev, bitplanes, L(rex3_rev), L(vc2_rev), L(xmap9_rev),
-	     L(cmap_rev ? (cmap_rev + 1) : 0), L(bt445_rev));
-#undef L
-
-	if (board_rev == 3)	/* I don't know all affected revisions */
-		xcurs_correction = 21;
-}
-
-#ifdef MODULE
-static const char *newport_startup(void)
-#else
-static const char *__init newport_startup(void)
-#endif
-{
-	int i;
-	struct newport_regs *p;
-
-	npregs = (struct newport_regs *) (KSEG1 + 0x1f0f0000);
-
-	p = npregs;
-	p->cset.config = NPORT_CFG_GD0;
-
-	if (newport_wait()) {
-		return NULL;
-	}
-
-	p->set.xstarti = TESTVAL;
-	if (p->set._xstart.word != XSTI_TO_FXSTART(TESTVAL))
-		return NULL;
-
-	for (i = 0; i < MAX_NR_CONSOLES; i++)
-		font_data[i] = FONT_DATA;
-
-	newport_reset();
-	newport_get_revisions();
-	newport_get_screensize();
-
-	/* gfx_init (display_desc); */
-
-	return "SGI Newport";
-}
-
-static void newport_init(struct vc_data *vc, int init)
-{
-	vc->vc_cols = newport_xsize / 8;
-	vc->vc_rows = newport_ysize / 16;
-	vc->vc_can_do_color = 1;
-}
-
-static void newport_clear(struct vc_data *vc, int sy, int sx, int height,
-			  int width)
-{
-	int xend = ((sx + width) << 3) - 1;
-	int ystart = ((sy << 4) + topscan) & 0x3ff;
-	int yend = (((sy + height) << 4) + topscan - 1) & 0x3ff;
-
-	if (logo_active)
-		return;
-
-	if (ystart < yend) {
-		newport_clear_screen(sx << 3, ystart, xend, yend,
-				     (vc->vc_color & 0xf0) >> 4);
-	} else {
-		newport_clear_screen(sx << 3, ystart, xend, 1023,
-				     (vc->vc_color & 0xf0) >> 4);
-		newport_clear_screen(sx << 3, 0, xend, yend,
-				     (vc->vc_color & 0xf0) >> 4);
-	}
-}
-
-static void newport_putc(struct vc_data *vc, int charattr, int ypos,
-			 int xpos)
-{
-	unsigned char *p;
-
-	p = &font_data[vc->vc_num][(charattr & 0xff) << 4];
-	charattr = (charattr >> 8) & 0xff;
-	xpos <<= 3;
-	ypos <<= 4;
-
-	newport_render_background(xpos, ypos, xpos, ypos,
-				  (charattr & 0xf0) >> 4);
-
-	/* Set the color and drawing mode. */
-	newport_wait();
-	npregs->set.colori = charattr & 0xf;
-	npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
-				 NPORT_DMODE0_STOPX | NPORT_DMODE0_ZPENAB |
-				 NPORT_DMODE0_L32);
-
-	/* Set coordinates for bitmap operation. */
-	npregs->set.xystarti = (xpos << 16) | ((ypos + topscan) & 0x3ff);
-	npregs->set.xyendi = ((xpos + 7) << 16);
-	newport_wait();
-
-	/* Go, baby, go... */
-	RENDER(npregs, p);
-}
-
-static void newport_putcs(struct vc_data *vc, const unsigned short *s,
-			  int count, int ypos, int xpos)
-{
-	int i;
-	int charattr;
-	unsigned char *p;
-
-	charattr = (scr_readw(s) >> 8) & 0xff;
-
-	xpos <<= 3;
-	ypos <<= 4;
-
-	if (!logo_active)
-		/* Clear the area behing the string */
-		newport_render_background(xpos, ypos,
-					  xpos + ((count - 1) << 3), ypos,
-					  (charattr & 0xf0) >> 4);
-
-	newport_wait();
-
-	/* Set the color and drawing mode. */
-	npregs->set.colori = charattr & 0xf;
-	npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
-				 NPORT_DMODE0_STOPX | NPORT_DMODE0_ZPENAB |
-				 NPORT_DMODE0_L32);
-
-	for (i = 0; i < count; i++, xpos += 8) {
-		p = &font_data[vc->vc_num][(scr_readw(s++) & 0xff) << 4];
-
-		newport_wait();
-
-		/* Set coordinates for bitmap operation. */
-		npregs->set.xystarti =
-		    (xpos << 16) | ((ypos + topscan) & 0x3ff);
-		npregs->set.xyendi = ((xpos + 7) << 16);
-
-		/* Go, baby, go... */
-		RENDER(npregs, p);
-	}
-}
-
-static void newport_cursor(struct vc_data *vc, int mode)
-{
-	unsigned short treg;
-	int xcurs, ycurs;
-
-	switch (mode) {
-	case CM_ERASE:
-		treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
-		newport_vc2_set(npregs, VC2_IREG_CONTROL,
-				(treg & ~(VC2_CTRL_ECDISP)));
-		break;
-
-	case CM_MOVE:
-	case CM_DRAW:
-		treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
-		newport_vc2_set(npregs, VC2_IREG_CONTROL,
-				(treg | VC2_CTRL_ECDISP));
-		xcurs = (vc->vc_pos - vc->vc_visible_origin) / 2;
-		ycurs = ((xcurs / vc->vc_cols) << 4) + 31;
-		xcurs = ((xcurs % vc->vc_cols) << 3) + xcurs_correction;
-		newport_vc2_set(npregs, VC2_IREG_CURSX, xcurs);
-		newport_vc2_set(npregs, VC2_IREG_CURSY, ycurs);
-	}
-}
-
-static int newport_switch(struct vc_data *vc)
-{
-	static int logo_drawn = 0;
-
-	topscan = 0;
-	npregs->cset.topscan = 0x3ff;
-
-	if (!logo_drawn) {
-		newport_show_logo();
-		logo_drawn = 1;
-		logo_active = 1;
-	}
-
-	return 1;
-}
-
-static int newport_blank(struct vc_data *c, int blank)
-{
-	unsigned short treg;
-
-	if (blank == 0) {
-		/* unblank console */
-		treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
-		newport_vc2_set(npregs, VC2_IREG_CONTROL,
-				(treg | VC2_CTRL_EDISP));
-	} else {
-		/* blank console */
-		treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
-		newport_vc2_set(npregs, VC2_IREG_CONTROL,
-				(treg & ~(VC2_CTRL_EDISP)));
-	}
-	return 1;
-}
-
-static int newport_set_font(int unit, struct console_font_op *op)
-{
-	int w = op->width;
-	int h = op->height;
-	int size = h * op->charcount;
-	int i;
-	unsigned char *new_data, *data = op->data, *p;
-
-	/* ladis: when I grow up, there will be a day... and more sizes will
-	 * be supported ;-) */
-	if ((w != 8) || (h != 16)
-	    || (op->charcount != 256 && op->charcount != 512))
-		return -EINVAL;
-
-	if (!(new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size,
-	     GFP_USER))) return -ENOMEM;
-
-	new_data += FONT_EXTRA_WORDS * sizeof(int);
-	FNTSIZE(new_data) = size;
-	FNTCHARCNT(new_data) = op->charcount;
-	REFCOUNT(new_data) = 0;	/* usage counter */
-
-	p = new_data;
-	for (i = 0; i < op->charcount; i++) {
-		memcpy(p, data, h);
-		data += 32;
-		p += h;
-	}
-
-	/* check if font is already used by other console */
-	for (i = 0; i < MAX_NR_CONSOLES; i++) {
-		if (font_data[i] != FONT_DATA
-		    && FNTSIZE(font_data[i]) == size
-		    && !memcmp(font_data[i], new_data, size)) {
-			kfree(new_data - FONT_EXTRA_WORDS * sizeof(int));
-			/* current font is the same as the new one */
-			if (i == unit)
-				return 0;
-			new_data = font_data[i];
-			break;
-		}
-	}
-	/* old font is user font */
-	if (font_data[unit] != FONT_DATA) {
-		if (--REFCOUNT(font_data[unit]) == 0)
-			kfree(font_data[unit] -
-			      FONT_EXTRA_WORDS * sizeof(int));
-	}
-	REFCOUNT(new_data)++;
-	font_data[unit] = new_data;
-
-	return 0;
-}
-
-static int newport_set_def_font(int unit, struct console_font_op *op)
-{
-	if (font_data[unit] != FONT_DATA) {
-		if (--REFCOUNT(font_data[unit]) == 0)
-			kfree(font_data[unit] -
-			      FONT_EXTRA_WORDS * sizeof(int));
-		font_data[unit] = FONT_DATA;
-	}
-
-	return 0;
-}
-
-static int newport_font_op(struct vc_data *vc, struct console_font_op *op)
-{
-	int unit = vc->vc_num;
-
-	switch (op->op) {
-	case KD_FONT_OP_SET:
-		return newport_set_font(unit, op);
-	case KD_FONT_OP_SET_DEFAULT:
-		return newport_set_def_font(unit, op);
-	default:
-		return -ENOSYS;
-	}
-}
-
-static int newport_set_palette(struct vc_data *vc, unsigned char *table)
-{
-	return -EINVAL;
-}
-
-static int newport_scrolldelta(struct vc_data *vc, int lines)
-{
-	/* there is (nearly) no off-screen memory, so we can't scroll back */
-	return 0;
-}
-
-static int newport_scroll(struct vc_data *vc, int t, int b, int dir,
-			  int lines)
-{
-	int count, x, y;
-	unsigned short *s, *d;
-	unsigned short chattr;
-
-	logo_active = 0;	/* it's time to disable the logo now.. */
-
-	if (t == 0 && b == vc->vc_rows) {
-		if (dir == SM_UP) {
-			topscan = (topscan + (lines << 4)) & 0x3ff;
-			newport_clear_lines(vc->vc_rows - lines,
-					    vc->vc_rows - 1,
-					    (vc->vc_color & 0xf0) >> 4);
-		} else {
-			topscan = (topscan + (-lines << 4)) & 0x3ff;
-			newport_clear_lines(0, lines - 1,
-					    (vc->vc_color & 0xf0) >> 4);
-		}
-		npregs->cset.topscan = (topscan - 1) & 0x3ff;
-		return 0;
-	}
-
-	count = (b - t - lines) * vc->vc_cols;
-	if (dir == SM_UP) {
-		x = 0;
-		y = t;
-		s = (unsigned short *) (vc->vc_origin +
-					vc->vc_size_row * (t + lines));
-		d = (unsigned short *) (vc->vc_origin +
-					vc->vc_size_row * t);
-		while (count--) {
-			chattr = scr_readw(s++);
-			if (chattr != scr_readw(d)) {
-				newport_putc(vc, chattr, y, x);
-				scr_writew(chattr, d);
-			}
-			d++;
-			if (++x == vc->vc_cols) {
-				x = 0;
-				y++;
-			}
-		}
-		d = (unsigned short *) (vc->vc_origin +
-					vc->vc_size_row * (b - lines));
-		x = 0;
-		y = b - lines;
-		for (count = 0; count < (lines * vc->vc_cols); count++) {
-			if (scr_readw(d) != vc->vc_video_erase_char) {
-				newport_putc(vc, vc->vc_video_erase_char,
-					     y, x);
-				scr_writew(vc->vc_video_erase_char, d);
-			}
-			d++;
-			if (++x == vc->vc_cols) {
-				x = 0;
-				y++;
-			}
-		}
-	} else {
-		x = vc->vc_cols - 1;
-		y = b - 1;
-		s = (unsigned short *) (vc->vc_origin +
-					vc->vc_size_row * (b - lines) - 2);
-		d = (unsigned short *) (vc->vc_origin +
-					vc->vc_size_row * b - 2);
-		while (count--) {
-			chattr = scr_readw(s--);
-			if (chattr != scr_readw(d)) {
-				newport_putc(vc, chattr, y, x);
-				scr_writew(chattr, d);
-			}
-			d--;
-			if (x-- == 0) {
-				x = vc->vc_cols - 1;
-				y--;
-			}
-		}
-		d = (unsigned short *) (vc->vc_origin +
-					vc->vc_size_row * t);
-		x = 0;
-		y = t;
-		for (count = 0; count < (lines * vc->vc_cols); count++) {
-			if (scr_readw(d) != vc->vc_video_erase_char) {
-				newport_putc(vc, vc->vc_video_erase_char,
-					     y, x);
-				scr_writew(vc->vc_video_erase_char, d);
-			}
-			d++;
-			if (++x == vc->vc_cols) {
-				x = 0;
-				y++;
-			}
-		}
-	}
-	return 1;
-}
-
-static void newport_bmove(struct vc_data *vc, int sy, int sx, int dy,
-			  int dx, int h, int w)
-{
-	short xs, ys, xe, ye, xoffs, yoffs, tmp;
-
-	xs = sx << 3;
-	xe = ((sx + w) << 3) - 1;
-	/*
-	 * as bmove is only used to move stuff around in the same line
-	 * (h == 1), we don't care about wrap arounds caused by topscan != 0
-	 */
-	ys = ((sy << 4) + topscan) & 0x3ff;
-	ye = (((sy + h) << 4) - 1 + topscan) & 0x3ff;
-	xoffs = (dx - sx) << 3;
-	yoffs = (dy - sy) << 4;
-	if (xoffs > 0) {
-		/* move to the right, exchange starting points */
-		tmp = xe;
-		xe = xs;
-		xs = tmp;
-	}
-	newport_wait();
-	npregs->set.drawmode0 = (NPORT_DMODE0_S2S | NPORT_DMODE0_BLOCK |
-				 NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
-				 | NPORT_DMODE0_STOPY);
-	npregs->set.xystarti = (xs << 16) | ys;
-	npregs->set.xyendi = (xe << 16) | ye;
-	npregs->go.xymove = (xoffs << 16) | yoffs;
-}
-
-static int newport_dummy(struct vc_data *c)
-{
-	return 0;
-}
-
-#define DUMMY (void *) newport_dummy
-
-const struct consw newport_con = {
-    .con_startup =	newport_startup,
-    .con_init =		newport_init,
-    .con_deinit =	DUMMY,
-    .con_clear =	newport_clear,
-    .con_putc =		newport_putc,
-    .con_putcs =	newport_putcs,
-    .con_cursor =	newport_cursor,
-    .con_scroll =	newport_scroll,
-    .con_bmove =	newport_bmove,
-    .con_switch =	newport_switch,
-    .con_blank =	newport_blank,
-    .con_font_op =	newport_font_op,
-    .con_set_palette =	newport_set_palette,
-    .con_scrolldelta =	newport_scrolldelta,
-    .con_set_origin =	DUMMY,
-    .con_save_screen =	DUMMY
-};
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
-	if (!newport_startup())
-		printk("Error loading SGI Newport Console driver\n");
-	else
-		printk("Loading SGI Newport Console Driver\n");
-	take_over_console(&newport_con, 0, MAX_NR_CONSOLES - 1, 1);
-
-	return 0;
-}
-
-int cleanup_module(void)
-{
-	int i;
-
-	printk("Unloading SGI Newport Console Driver\n");
-	/* free memory used by user font */
-	for (i = 0; i < MAX_NR_CONSOLES; i++)
-		newport_set_def_font(i, NULL);
-
-	return 0;
-}
-#endif
diff -Nru a/drivers/video/offb.c b/drivers/video/offb.c
--- a/drivers/video/offb.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/video/offb.c	Mon Dec  9 18:46:51 2002
@@ -24,7 +24,6 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/fb.h>
-#include <linux/selection.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <asm/io.h>
@@ -33,8 +32,7 @@
 #include <asm/bootx.h>
 #endif
 
-#include <video/fbcon.h>
-#include <video/macmodes.h>
+#include "macmodes.h"
 
 /* Supported palette hacks */
 enum {
@@ -83,14 +81,12 @@
 
 static struct fb_ops offb_ops = {
 	.owner		= THIS_MODULE,
-	.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,
+	.fb_cursor	= soft_cursor,
 };
 
     /*
@@ -411,7 +407,7 @@
 		return;
 	}
 
-	size = sizeof(struct fb_info) + sizeof(struct display) + sizeof(u32) * 17;
+	size = sizeof(struct fb_info) + sizeof(u32) * 17;
 
 	info = kmalloc(size, GFP_ATOMIC);
 	
@@ -528,24 +524,15 @@
 
 	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->pseudo_palette = (void *) (info + 1);
 	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);
@@ -553,7 +540,7 @@
 	}
 
 	printk(KERN_INFO "fb%d: Open Firmware frame buffer device on %s\n",
-	       GET_FB_IDX(info->node), full_name);
+	       minor(info->node), full_name);
 }
 
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
--- a/drivers/video/platinumfb.c	Mon Dec  9 18:46:36 2002
+++ b/drivers/video/platinumfb.c	Mon Dec  9 18:46:36 2002
@@ -58,14 +58,14 @@
 };
 
 struct fb_info_platinum {
-	struct fb_info			fb_info;
-	struct display			disp;
-	struct fb_par_platinum		default_par;
-	struct fb_par_platinum		current_par;
+	struct fb_info			info;
+	struct display			display; /* Will disappear */
+	struct fb_par_platinum		par;
 
 	struct {
 		__u8 red, green, blue;
 	}				palette[256];
+	u32				pseudo_palette[17];
 	
 	volatile struct cmap_regs	*cmap_regs;
 	unsigned long			cmap_regs_phys;
@@ -80,42 +80,17 @@
 	unsigned long			total_vram;
 	int				clktype;
 	int				dactype;
-
-	union {
-#ifdef FBCON_HAS_CFB16
-		u16 cfb16[16];
-#endif
-#ifdef FBCON_HAS_CFB32
-		u32 cfb32[16];
-#endif
-	} fbcon_cmap;
 };
 
 /*
  * Frame buffer device API
  */
 
-static int platinum_get_fix(struct fb_fix_screeninfo *fix, int con,
-			    struct fb_info *fb);
-static int platinum_get_var(struct fb_var_screeninfo *var, int con,
-			    struct fb_info *fb);
-static int platinum_set_var(struct fb_var_screeninfo *var, int con,
-			    struct fb_info *fb);
-static int platinum_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			     struct fb_info *info);
-static int platinum_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			     struct fb_info *info);
-static int platinum_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-			      u_int transp, struct fb_info *fb);
-static int platinum_blank(int blank, struct fb_info *fb);
-
-
-/*
- * Interface to the low level console driver
- */
-
-static int platinum_switch(int con, struct fb_info *fb);
-static int platinum_updatevar(int con, struct fb_info *fb);
+static int platinumfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+	u_int transp, struct fb_info *info);
+static int platinumfb_blank(int blank_mode, struct fb_info *info);
+static int platinumfb_set_par (struct fb_info *info);
+static int platinumfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info);
 
 /*
  * internal functions
@@ -125,21 +100,14 @@
 static inline int platinum_vram_reqd(int video_mode, int color_mode);
 static int read_platinum_sense(struct fb_info_platinum *info);
 static void set_platinum_clock(struct fb_info_platinum *info);
-static void platinum_set_par(const struct fb_par_platinum *par, struct fb_info_platinum *info);
+static void platinum_set_hardware(struct fb_info_platinum *info,
+				  const struct fb_par_platinum *par);
 static int platinum_par_to_var(struct fb_var_screeninfo *var,
 			       const struct fb_par_platinum *par,
 			       const struct fb_info_platinum *info);
 static int platinum_var_to_par(const struct fb_var_screeninfo *var,
 			       struct fb_par_platinum *par,
 			       const struct fb_info_platinum *info);
-static int platinum_encode_fix(struct fb_fix_screeninfo *fix,
-			       const struct fb_par_platinum *par,
-			       const struct fb_info_platinum *info);
-static void platinum_set_dispsw(struct display *disp,
-				struct fb_info_platinum *info, int cmode,
-				int accel);
-static int platinum_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-			      u_int *transp, struct fb_info *fb);
 
 /*
  * Interface used by the world
@@ -150,202 +118,65 @@
 
 static struct fb_ops platinumfb_ops = {
 	.owner =	THIS_MODULE,
-	.fb_get_fix =	platinum_get_fix,
-	.fb_get_var =	platinum_get_var,
-	.fb_set_var =	platinum_set_var,
-	.fb_get_cmap =	platinum_get_cmap,
-	.fb_set_cmap =	platinum_set_cmap,
-	.fb_setcolreg =	platinum_setcolreg,
-	.fb_blank =	platinum_blank,
+	.fb_set_var	= gen_set_var,
+	.fb_check_var	= platinumfb_check_var,
+	.fb_set_par	= platinumfb_set_par,
+	.fb_get_cmap	= gen_get_cmap,
+	.fb_set_cmap	= gen_set_cmap,
+	.fb_setcolreg	= platinumfb_setcolreg,
+	.fb_blank	= platinumfb_blank,
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit,
 };
 
-static int platinum_get_fix(struct fb_fix_screeninfo *fix, int con,
-			    struct fb_info *fb)
+/*
+ * Checks a var structure
+ */
+static int platinumfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info)
 {
-	const struct fb_info_platinum *info = (struct fb_info_platinum *)fb;
+	struct fb_info_platinum *p = (struct fb_info_platinum *) info;
 	struct fb_par_platinum par;
-
-	if (con == -1)
-		par = info->default_par;
-	else
-		platinum_var_to_par(&fb_display[con].var, &par, info);
-
-	platinum_encode_fix(fix, &par, info);
-	return 0;
-}
-
-static int platinum_get_var(struct fb_var_screeninfo *var, int con,
-			    struct fb_info *fb)
-{
-	const struct fb_info_platinum *info = (struct fb_info_platinum *)fb;
-
-	if (con == -1)
-		platinum_par_to_var(var, &info->default_par, info);
-	else
-		*var = fb_display[con].var;
+	int err;
+	
+	err = platinum_var_to_par(var, &par, p);
+	if (err)
+		return err;	
+	platinum_par_to_var(var, &par, p);
 
 	return 0;
 }
 
-static void platinum_set_dispsw(struct display *disp,
-				struct fb_info_platinum *info, int cmode,
-				int accel)
-{
-	switch(cmode) {
-#ifdef FBCON_HAS_CFB8
-	    case CMODE_8:
-		disp->dispsw = &fbcon_cfb8;
-		break;
-#endif
-#ifdef FBCON_HAS_CFB16
-	    case CMODE_16:
-		disp->dispsw = &fbcon_cfb16;
-		disp->dispsw_data = info->fbcon_cmap.cfb16;
-		break;
-#endif
-#ifdef FBCON_HAS_CFB32
-	    case CMODE_32:
-		disp->dispsw = &fbcon_cfb32;
-		disp->dispsw_data = info->fbcon_cmap.cfb32;
-		break;
-#endif
-	    default:
-		disp->dispsw = &fbcon_dummy;
-		break;
-	}
-}
-
-static int platinum_set_var(struct fb_var_screeninfo *var, int con,
-			    struct fb_info *fb)
+/*
+ * Applies current var to display
+ */
+static int platinumfb_set_par (struct fb_info *info)
 {
-	struct fb_info_platinum *info = (struct fb_info_platinum *) fb;
-	struct fb_par_platinum par;
-	struct display *display;
-	int oldxres, oldyres, oldvxres, oldvyres, oldbpp, err;
-	int activate = var->activate;
+	struct fb_info_platinum *p = (struct fb_info_platinum *) info;
 	struct platinum_regvals *init;
+	struct fb_par_platinum par;
+	int err;
 
-	display = (con >= 0) ? &fb_display[con] : fb->disp;
-
-	if((err = platinum_var_to_par(var, &par, info))) {
-		printk(KERN_ERR "platinum_set_var: error calling platinum_var_to_par: %d.\n", err);
+	if((err = platinum_var_to_par(&info->var, &par, p))) {
+		printk (KERN_ERR "platinumfb_set_par: error calling"
+				 " platinum_var_to_par: %d.\n", err);
 		return err;
 	}
-	
-	platinum_par_to_var(var, &par, info);
 
-	if ((activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW) {
-		printk(KERN_INFO "platinum_set_var: Not activating.\n");
-		return 0;
-	}
+	platinum_set_hardware(p, &par);
 
-	init = platinum_reg_init[par.vmode-1];
-
-	oldxres = display->var.xres;
-	oldyres = display->var.yres;
-	oldvxres = display->var.xres_virtual;
-	oldvyres = display->var.yres_virtual;
-	oldbpp = display->var.bits_per_pixel;
-	display->var = *var;
-
-	if (oldxres != var->xres || oldyres != var->yres ||
-	    oldvxres != var->xres_virtual || oldyres != var->yres_virtual ||
-	    oldbpp != var->bits_per_pixel) {
-	    struct fb_fix_screeninfo fix;
-
-	    platinum_encode_fix(&fix, &par, info);
-	    info->fb_info.screen_base = (char *) info->frame_buffer + init->fb_offset + 0x20;
-	    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;
-	    platinum_set_dispsw(display, info, par.cmode, 0);
-	    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)
-		platinum_set_par(&par, info);
-
-	if (oldbpp != var->bits_per_pixel) {
-	    if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
-	      return err;
-	    do_install_cmap(con, &info->fb_info);
-	}
-
-	return 0;
-}
-
-static int platinum_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			     struct fb_info *info)
-{
-	if (!info->display_fg ||
-	    info->display_fg->vc_num == con)	/* current console? */
-		return fb_get_cmap(cmap, kspc, platinum_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;
-}
-
-static int platinum_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			     struct fb_info *info)
-{
-	int err;
-	struct display *disp;
-
-	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 ||
-	    info->display_fg->vc_num == con)	/* current console? */
-		return fb_set_cmap(cmap, kspc, info);
-	else
-		fb_copy_cmap(cmap, &disp->cmap, kspc ? 0 : 1);
-	return 0;
-}
-
-static int platinum_switch(int con, struct fb_info *fb)
-{
-	struct fb_info_platinum *info = (struct fb_info_platinum *) fb;
-	struct fb_par_platinum par;
-
-	if (fb_display[fb->currcon].cmap.len)
-		fb_get_cmap(&fb_display[fb->currcon].cmap, 1, platinum_getcolreg,
-			    fb);
-	fb->currcon = con;
-
-	platinum_var_to_par(&fb_display[con].var, &par, info);
-	platinum_set_par(&par, info);
-	platinum_set_dispsw(&fb_display[con], info, par.cmode, 0);
-	do_install_cmap(con, fb);
-
-	return 1;
-}
+	init = platinum_reg_init[p->par.vmode-1];
+	
+	info->screen_base = (char *) p->frame_buffer + init->fb_offset + 0x20;
+	info->fix.smem_start = (p->frame_buffer_phys) + init->fb_offset + 0x20;
+	info->fix.visual = (p->par.cmode == CMODE_8) ?
+		FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
+	info->fix.line_length = vmode_attrs[p->par.vmode-1].hres * (1<<p->par.cmode) + 0x20;
 
-static int platinum_updatevar(int con, struct fb_info *fb)
-{
-	printk(KERN_ERR "platinum_updatevar is doing nothing yet.\n");
 	return 0;
 }
 
-static int platinum_blank(int blank,  struct fb_info *fb)
+static int platinumfb_blank(int blank,  struct fb_info *fb)
 {
 /*
  *  Blank the screen if blank_mode != 0, else unblank. If blank == NULL
@@ -375,26 +206,11 @@
 	return 0;
 }
 
-static int platinum_getcolreg(u_int regno, u_int *red, u_int *green,
-			      u_int *blue, u_int *transp, struct fb_info *fb)
+static int platinumfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+			      u_int transp, struct fb_info *info)
 {
-	struct fb_info_platinum *info = (struct fb_info_platinum *) 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;
-}
-
-static int platinum_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-			      u_int transp, struct fb_info *fb)
-{
-	struct fb_info_platinum *info = (struct fb_info_platinum *) fb;
-	volatile struct cmap_regs *cmap_regs = info->cmap_regs;
+	struct fb_info_platinum *p = (struct fb_info_platinum *) info;
+	volatile struct cmap_regs *cmap_regs = p->cmap_regs;
 
 	if (regno > 255)
 		return 1;
@@ -403,23 +219,30 @@
 	green >>= 8;
 	blue >>= 8;
 
-	info->palette[regno].red = red;
-	info->palette[regno].green = green;
-	info->palette[regno].blue = blue;
+	p->palette[regno].red = red;
+	p->palette[regno].green = green;
+	p->palette[regno].blue = blue;
 
 	out_8(&cmap_regs->addr, regno);		/* tell clut what addr to fill	*/
 	out_8(&cmap_regs->lut, red);		/* send one color channel at	*/
 	out_8(&cmap_regs->lut, green);		/* a time...			*/
 	out_8(&cmap_regs->lut, blue);
 
-	if(regno < 16) {
-#ifdef FBCON_HAS_CFB16
-		info->fbcon_cmap.cfb16[regno] = (regno << 10) | (regno << 5) | (regno << 0);
-#endif
-#ifdef FBCON_HAS_CFB32
-		info->fbcon_cmap.cfb32[regno] = (regno << 24) | (regno << 16) | (regno << 8) | regno;
-#endif
+	if (regno < 16) {
+		int i;
+		switch (p->par.cmode) {
+		case CMODE_16:
+			((u16 *) (info->pseudo_palette))[regno] =
+			    (regno << 10) | (regno << 5) | regno;
+			break;
+		case CMODE_32:
+			i = (regno << 8) | regno;
+			((u32 *) (info->pseudo_palette))[regno] =
+			    (i << 16) | i;
+			break;
+		}
 	}
+	
 	return 0;
 }
 
@@ -439,7 +262,7 @@
 	volatile struct cmap_regs *cmap_regs = info->cmap_regs;
 	struct platinum_regvals	*init;
 
-	init = platinum_reg_init[info->current_par.vmode-1];
+	init = platinum_reg_init[info->par.vmode-1];
 
 	STORE_D2(6, 0xc6);
 	out_8(&cmap_regs->addr,3+32);
@@ -461,7 +284,7 @@
 
 /* Now how about actually saying, Make it so! */
 /* Some things in here probably don't need to be done each time. */
-static void platinum_set_par(const struct fb_par_platinum *par, struct fb_info_platinum *info)
+static void platinum_set_hardware(struct fb_info_platinum *info, const struct fb_par_platinum *par)
 {
 	volatile struct platinum_regs	*platinum_regs = info->platinum_regs;
 	volatile struct cmap_regs	*cmap_regs = info->cmap_regs;
@@ -469,7 +292,7 @@
 	int				i;
 	int				vmode, cmode;
 	
-	info->current_par = *par;
+	info->par = *par;
 
 	vmode = par->vmode;
 	cmode = par->cmode;
@@ -509,15 +332,52 @@
 	out_be32(&platinum_regs->reg[24].r, 0);	/* turn display on */
 }
 
+/*
+ * Set misc info vars for this driver
+ */
+static void __init platinum_init_info(struct fb_info *info, struct fb_info_platinum *p)
+{
+	/* Fill fb_info */
+	strcpy(info->modename, "platinum");
+	info->currcon = -1;
+	info->par = &p->par;
+	info->node = NODEV;
+	info->fbops = &platinumfb_ops;
+	info->disp = &p->display;
+	info->pseudo_palette = p->pseudo_palette;
+        info->flags = FBINFO_FLAG_DEFAULT;
+        strncpy (info->fontname, fontname, sizeof (info->fontname));
+        info->fontname[sizeof (info->fontname) - 1] = 0;
+	info->changevar = NULL;
+        info->display_fg = NULL;
+	info->screen_base = (char *) p->frame_buffer + 0x20;
+	info->changevar  = NULL;
+	info->switch_con = gen_switch;
+	info->updatevar  = gen_update_var;
+
+	fb_alloc_cmap(&info->cmap, 256, 0);
+
+	/* Fill fix common fields */
+	strcpy(info->fix.id, "platinum");
+	info->fix.mmio_start = p->platinum_regs_phys;
+	info->fix.mmio_len = 0x1000;
+	info->fix.type = FB_TYPE_PACKED_PIXELS;
+	info->fix.smem_start = p->frame_buffer_phys + 0x20; /* will be updated later */
+	info->fix.smem_len = p->total_vram - 0x20;
+        info->fix.ywrapstep = 0;
+	info->fix.xpanstep = 0;
+	info->fix.ypanstep = 0;
+        info->fix.type_aux = 0;
+        info->fix.accel = FB_ACCEL_NONE;
+}
+
 
-static int __init init_platinum(struct fb_info_platinum *info)
+static int __init init_platinum(struct fb_info_platinum *p)
 {
 	struct fb_var_screeninfo var;
-	struct display *disp;
-	int sense;
-	int j,k;
+	int sense, rc;
 
-	sense = read_platinum_sense(info);
+	sense = read_platinum_sense(p);
 	printk(KERN_INFO "Monitor sense value = 0x%x, ", sense);
 
 	if (default_vmode == VMODE_NVRAM) {
@@ -538,44 +398,40 @@
 	/*
 	 * Reduce the pixel size if we don't have enough VRAM.
 	 */
-	while(default_cmode > CMODE_8 && platinum_vram_reqd(default_vmode, default_cmode) > info->total_vram)
+	while(default_cmode > CMODE_8 && platinum_vram_reqd(default_vmode, default_cmode) > p->total_vram)
 		default_cmode--;
 
 	printk("using video mode %d and color mode %d.\n", default_vmode, default_cmode);
 
-	mac_vmode_to_var(default_vmode, default_cmode, &var);
-
-	if (platinum_var_to_par(&var, &info->default_par, info)) {
-		printk(KERN_ERR "platinumfb: can't set default video mode\n");
-		return 0;
+	/* Setup default var */
+	if (mac_vmode_to_var(default_vmode, default_cmode, &var) < 0) {
+		/* This shouldn't happen! */
+		printk("mac_vmode_to_var(%d, %d,) failed\n", default_vmode, default_cmode);
+try_again:
+		default_vmode = VMODE_640_480_60;
+		default_cmode = CMODE_8;
+		if (mac_vmode_to_var(default_vmode, default_cmode, &var) < 0) {
+			printk(KERN_ERR "platinumfb: mac_vmode_to_var() failed\n");
+			return -ENXIO;
+		}
 	}
 
-	disp = &info->disp;
+	/* Initialize info structure */
+	platinum_init_info(&p->info, p);
 
-	strcpy(info->fb_info.modename, "platinum");
-	info->fb_info.node = NODEV;
-	info->fb_info.fbops = &platinumfb_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 = &platinum_switch;
-	info->fb_info.updatevar = &platinum_updatevar;
-	info->fb_info.flags = FBINFO_FLAG_DEFAULT;
-
-	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];
-	}
-	platinum_set_var(&var, -1, &info->fb_info);
+	/* Apply default var */
+	p->info.var = var;
+	var.activate = FB_ACTIVATE_NOW;
+	rc = gen_set_var(&var, -1, &p->info);
+	if (rc && (default_vmode != VMODE_640_480_60 || default_cmode != CMODE_8))
+		goto try_again;
 
-	if (register_framebuffer(&info->fb_info) < 0)
+	/* Register with fbdev layer */
+	if (register_framebuffer(&p->info) < 0)
 		return 0;
 
 	printk(KERN_INFO "fb%d: platinum frame buffer device\n",
-	       GET_FB_IDX(info->fb_info.node));
+	       GET_FB_IDX(p->info.node));
 
 	return 1;
 }
@@ -760,33 +616,6 @@
 {
 	return mac_vmode_to_var(par->vmode, par->cmode, var);
 }
-
-static int platinum_encode_fix(struct fb_fix_screeninfo *fix,
-			       const struct fb_par_platinum *par,
-			       const struct fb_info_platinum *info)
-{
-	struct platinum_regvals *init;
-
-	init = platinum_reg_init[par->vmode-1];
-
-	memset(fix, 0, sizeof(*fix));
-	strcpy(fix->id, "platinum");
-	fix->smem_start = (info->frame_buffer_phys) + init->fb_offset + 0x20;
-	fix->smem_len = (u32) info->total_vram;
-	fix->mmio_start = (info->platinum_regs_phys);
-	fix->mmio_len = 0x1000;
-	fix->type = FB_TYPE_PACKED_PIXELS;
-	fix->type_aux = 0;
-	fix->ywrapstep = 0;
-	fix->xpanstep = 0;
-	fix->ypanstep = 0;
-	fix->visual = (par->cmode == CMODE_8) ?
-		FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
-	fix->line_length = vmode_attrs[par->vmode-1].hres * (1<<par->cmode) + 0x20;
-
-	return 0;
-}
-
 
 /* 
  * Parse user speficied options (`video=platinumfb:')
diff -Nru a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
--- a/drivers/video/pm2fb.c	Mon Dec  9 18:46:52 2002
+++ b/drivers/video/pm2fb.c	Mon Dec  9 18:46:52 2002
@@ -1967,8 +1967,7 @@
 	struct pm2fb_par* p=(struct pm2fb_par* )par;
 	unsigned long flags;
 
-	save_flags(flags);
-	cli();
+	local_irq_save(flags);
 #ifdef __alpha__
 	disp->screen_base=i->regions.v_fb + dense_mem(i->regions.v_fb);
 #else
@@ -2014,7 +2013,7 @@
 			disp->dispsw=&fbcon_dummy;
 			break;
 	}
-	restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 #ifdef PM2FB_HW_CURSOR
@@ -2289,7 +2288,7 @@
 		return -EINVAL;
 	}
 	printk(KERN_INFO "fb%d: %s (%s), using %uK of video memory.\n",
-				GET_FB_IDX(fb_info.gen.info.node),
+				minor(fb_info.gen.info.node),
 				board_table[fb_info.board].name,
 				permedia2_name,
 				(u32 )(fb_info.regions.fb_size>>10));
diff -Nru a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c
--- a/drivers/video/pm3fb.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/video/pm3fb.c	Mon Dec  9 18:46:35 2002
@@ -1647,7 +1647,7 @@
 	pm3fb_write_mode(l_fb_info);
 	
 	printk("fb%d: %s, using %uK of video memory (%s)\n",
-	       GET_FB_IDX(l_fb_info->gen.info.node),
+	       minor(l_fb_info->gen.info.node),
 	       permedia3_name, (u32) (l_fb_info->fb_size >> 10),
 	       cardbase[l_fb_info->board_type].cardname);
 }
@@ -3297,8 +3297,7 @@
 
 	DTRACE;
 
-	save_flags(flags);
-	cli();
+	local_irq_save(flags);
 	info->info.screen_base = l_fb_info->v_fb;
 	switch (p->depth) {
 #ifdef FBCON_HAS_CFB8
@@ -3356,7 +3355,7 @@
 		DPRINTK(1, "Invalid depth, using fbcon_dummy\n");
 		break;
 	}
-	restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 /* */
diff -Nru a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c
--- a/drivers/video/pmag-ba-fb.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/video/pmag-ba-fb.c	Mon Dec  9 18:46:51 2002
@@ -36,8 +36,6 @@
 #include <asm/dec/tc.h>
 #include "pmag-ba-fb.h"
 
-#include <video/fbcon.h>
-
 struct pmag_ba_ramdac_regs {
 	unsigned char addr_low;
 	unsigned char pad0[3];
@@ -52,28 +50,30 @@
  * Max 3 TURBOchannel slots -> max 3 PMAG-BA :)
  */
 static struct fb_info pmagba_fb_info[3];
-static struct display pmagba_disp[3];
 
 static struct fb_var_screeninfo pmagbafb_defined = {
-	.xres =		1024,
-	.yres =		864,
-	.xres_virtual =	1024,
-	.yres_virtual =	864,
-	.bits_per_pixel =8,
-	.activate =	FB_ACTIVATE_NOW, 
-	.height =	274,	
-	.width =	195,
-	.accel =	FB_ACCEL_NONE,
-	.vmode =	FB_VMODE_NONINTERLACED,
-}
+	.xres 		= 1024,
+	.yres		= 864,
+	.xres_virtual 	= 1024,
+	.yres_virtual 	= 864,
+	.bits_per_pixel = 8,
+	.red.length	= 8,
+	.green.length	= 8,
+	.blue.length	= 8,
+	.activate 	= FB_ACTIVATE_NOW, 
+	.height 	= 274,	
+	.width 		= 195,
+	.accel 		= FB_ACCEL_NONE,
+	.vmode 		= FB_VMODE_NONINTERLACED,
+};
 
 static struct fb_fix_screeninfo pmagbafb_fix = {
-	.id =		"PMAG-BA",
-	.smem_len =	(1024 * 864),
-	.type =		FB_TYPE_PACKED_PIXELS,
-	.visual =	FB_VISUAL_PSEUDOCOLOR,
-	.line_length =	1024,
-}
+	.id 		= "PMAG-BA",
+	.smem_len 	= (1024 * 864),
+	.type 		= FB_TYPE_PACKED_PIXELS,
+	.visual 	= FB_VISUAL_PSEUDOCOLOR,
+	.line_length 	= 1024,
+};
 
 /*
  * Turn hardware cursor off
@@ -111,20 +111,17 @@
 
 static struct fb_ops pmagbafb_ops = {
 	.owner		= THIS_MODULE,
-	.fb_set_var	= gen_set_var,
-	.fb_get_cmap	= gen_get_cmap,
-	.fb_set_cmap	= gen_set_cmap,
 	.fb_setcolreg	= pmagbafb_setcolreg,
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
-}
+	.fb_cursor	= soft_cursor,
+};
 
 int __init pmagbafb_init_one(int slot)
 {
 	unsigned long base_addr = get_tc_base_addr(slot);
 	struct fb_info *info = &pmagba_fb_info[slot]; 
-	struct display *disp = &pmagba_disp[slot];
 
 	printk("PMAG-BA framebuffer in slot %d\n", slot);
 	/*
@@ -141,21 +138,14 @@
 	/*
 	 *      Let there be consoles..
 	 */
-	strcpy(info->modename, pmagbafb_fix.id);
-	info->changevar = NULL;
 	info->node = NODEV;
 	info->fbops = &pmagbafb_ops;
 	info->var = pmagbafb_defined;
 	info->fix = pmagbafb_fix; 
 	info->screen_base = pmagbafb_fix.smem_start;
-	info->disp = &disp;
-	info->currcon = -1;
-	info->switch_con = gen_switch;
-	info->updatevar = gen_update_var;
 	info->flags = FBINFO_FLAG_DEFAULT;
 
 	fb_alloc_cmap(&fb_info.cmap, 256, 0);
-	gen_set_disp(-1, info);
 	
 	if (register_framebuffer(info) < 0)
 		return 1;
@@ -181,11 +171,6 @@
 	} else {
 		return -ENODEV;
 	}
-}
-
-int __init pmagbafb_setup(char *options)
-{
-	return 0;
 }
 
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c
--- a/drivers/video/pmagb-b-fb.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/video/pmagb-b-fb.c	Mon Dec  9 18:46:38 2002
@@ -39,8 +39,6 @@
 #include <asm/dec/tc.h>
 #include "pmagb-b-fb.h"
 
-#include <video/fbcon.h>
-
 struct pmagb_b_ramdac_regs {
 	unsigned char addr_low;
 	unsigned char pad0[3];
@@ -55,27 +53,29 @@
  * Max 3 TURBOchannel slots -> max 3 PMAGB-B :)
  */
 static struct fb_info pmagbb_fb_info[3];
-static struct display pmagbb_disp[3];
 
 static struct fb_var_screeninfo pmagbbfb_defined = {
-	.xres =		1280,
-	.yres =		1024,
-	.xres_virtual =	1280,
-	.yres_virtual =	1024,
-	.bits_per_pixel =8,
-	.activate =	FB_ACTIVATE_NOW,
-	.height =	274,
-	.width =	195,
-	.accel_flags =	FB_ACCEL_NONE,
-	.vmode =	FB_VMODE_NONINTERLACED,
+	.xres 		= 1280,
+	.yres 		= 1024,
+	.xres_virtual 	= 1280,
+	.yres_virtual 	= 1024,
+	.bits_per_pixel = 8,
+	.red.length	= 8,
+	.green.length	= 8,
+	.blue.length	= 8,
+	.activate 	= FB_ACTIVATE_NOW,
+	.height 	= 274,
+	.width 		= 195,
+	.accel_flags 	= FB_ACCEL_NONE,
+	.vmode 		= FB_VMODE_NONINTERLACED,
 };
 
 static struct fb_fix_screeninfo pmagbafb_fix = {
-	.id =		"PMAGB-BA",
-	.smem_len =	(1280 * 1024),
-	.type =		FB_TYPE_PACKED_PIXELS,
-	.visual =	FB_VISUAL_PSEUDOCOLOR,
-	.line_length =	1280,
+	.id 		= "PMAGB-BA",
+	.smem_len 	= (1280 * 1024),
+	.type 		= FB_TYPE_PACKED_PIXELS,
+	.visual 	= FB_VISUAL_PSEUDOCOLOR,
+	.line_length 	= 1280,
 }
 
 /*
@@ -114,20 +114,17 @@
 
 static struct fb_ops pmagbbfb_ops = {
 	.owner		= THIS_MODULE,
-	.fb_set_var	= gen_set_var,
-	.fb_get_cmap	= gen_get_cmap,
-	.fb_set_cmap	= gen_set_cmap,
 	.fb_setcolreg	= pmagbbfb_setcolreg,
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
+	.fb_cursor	= soft_cursor,
 };
 
 int __init pmagbbfb_init_one(int slot)
 {
 	unsigned long base_addr = get_tc_base_addr(slot);
 	struct fb_info *info = &pmagbb_fb_info[slot];
-	struct display *disp = &pmagbb_disp[slot];
 
 	printk("PMAGB-BA framebuffer in slot %d\n", slot);
 	/*
@@ -144,21 +141,14 @@
 	/*
 	 *      Let there be consoles..
 	 */
-	strcpy(info->modename, pmagbbfb_fix.id);
-	info->changevar = NULL;
 	info->node = NODEV;
 	info->fbops = &pmagbbfb_ops;
 	info->var = pmagbbfb_defined;
 	info->fix = pmagbbfb_fix;
 	info->screen_base = pmagbbfb_fix.smem_start; 
-	info->disp = &disp;
-	info->currcon = -1;
-	info->switch_con = gen_switch;
-	info->updatevar = gen_update_var;
 	info->flags = FBINFO_FLAG_DEFAULT;
 
 	fb_alloc_cmap(&fb_info.cmap, 256, 0);
-	gen_set_disp(-1, info);
 
 	if (register_framebuffer(info) < 0)
 		return 1;
@@ -184,11 +174,6 @@
 	} else {
 		return -ENODEV;
 	}
-}
-
-int __init pmagbbfb_setup(char *options)
-{
-	return 0;
 }
 
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/prom.uni b/drivers/video/prom.uni
--- a/drivers/video/prom.uni	Mon Dec  9 18:46:49 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,11 +0,0 @@
-#
-# Unicode mapping table for font in Sun PROM
-# 
-#
-0x20-0x7e	idem
-0xa0-0xff	idem
-#
-0x7c		U+2502
-0x2d		U+2500
-0x2b		U+250c U+2510 U+2514 U+2518 U+251c U+2524 U+252c U+2534 U+253c
-0xa4		U+fffd
diff -Nru a/drivers/video/promcon.c b/drivers/video/promcon.c
--- a/drivers/video/promcon.c	Mon Dec  9 18:46:38 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,606 +0,0 @@
-/* $Id: promcon.c,v 1.17 2000/07/26 23:02:52 davem Exp $
- * Console driver utilizing PROM sun terminal emulation
- *
- * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
- * Copyright (C) 1998  Jakub Jelinek  (jj@ultra.linux.cz)
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/console.h>
-#include <linux/console_struct.h>
-#include <linux/vt_kern.h>
-#include <linux/selection.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/kd.h>
-
-#include <asm/oplib.h>
-#include <asm/uaccess.h>
-
-static short pw = 80 - 1, ph = 34 - 1;
-static short px, py;
-static unsigned long promcon_uni_pagedir[2];
-
-extern u8 promfont_unicount[];
-extern u16 promfont_unitable[];
-
-#define PROMCON_COLOR 0
-
-#if PROMCON_COLOR
-#define inverted(s)	((((s) & 0x7700) == 0x0700) ? 0 : 1)
-#else
-#define inverted(s)	(((s) & 0x0800) ? 1 : 0)
-#endif
-
-static __inline__ void
-promcon_puts(char *buf, int cnt)
-{
-	prom_printf("%*.*s", cnt, cnt, buf);
-}
-
-static int
-promcon_start(struct vc_data *conp, char *b)
-{
-	unsigned short *s = (unsigned short *)
-			(conp->vc_origin + py * conp->vc_size_row + (px << 1));
-	u16 cs;
-
-	cs = scr_readw(s);
-	if (px == pw) {
-		unsigned short *t = s - 1;
-		u16 ct = scr_readw(t);
-
-		if (inverted(cs) && inverted(ct))
-			return sprintf(b, "\b\033[7m%c\b\033[@%c\033[m", cs,
-				       ct);
-		else if (inverted(cs))
-			return sprintf(b, "\b\033[7m%c\033[m\b\033[@%c", cs,
-				       ct);
-		else if (inverted(ct))
-			return sprintf(b, "\b%c\b\033[@\033[7m%c\033[m", cs,
-				       ct);
-		else
-			return sprintf(b, "\b%c\b\033[@%c", cs, ct);
-	}
-
-	if (inverted(cs))
-		return sprintf(b, "\033[7m%c\033[m\b", cs);
-	else
-		return sprintf(b, "%c\b", cs);
-}
-
-static int
-promcon_end(struct vc_data *conp, char *b)
-{
-	unsigned short *s = (unsigned short *)
-			(conp->vc_origin + py * conp->vc_size_row + (px << 1));
-	char *p = b;
-	u16 cs;
-
-	b += sprintf(b, "\033[%d;%dH", py + 1, px + 1);
-
-	cs = scr_readw(s);
-	if (px == pw) {
-		unsigned short *t = s - 1;
-		u16 ct = scr_readw(t);
-
-		if (inverted(cs) && inverted(ct))
-			b += sprintf(b, "\b%c\b\033[@\033[7m%c\033[m", cs, ct);
-		else if (inverted(cs))
-			b += sprintf(b, "\b%c\b\033[@%c", cs, ct);
-		else if (inverted(ct))
-			b += sprintf(b, "\b\033[7m%c\b\033[@%c\033[m", cs, ct);
-		else
-			b += sprintf(b, "\b\033[7m%c\033[m\b\033[@%c", cs, ct);
-		return b - p;
-	}
-
-	if (inverted(cs))
-		b += sprintf(b, "%c\b", cs);
-	else
-		b += sprintf(b, "\033[7m%c\033[m\b", cs);
-	return b - p;
-}
-
-const char __init *promcon_startup(void)
-{
-	const char *display_desc = "PROM";
-	int node;
-	char buf[40];
-	
-	node = prom_getchild(prom_root_node);
-	node = prom_searchsiblings(node, "options");
-	if (prom_getproperty(node,  "screen-#columns", buf, 40) != -1) {
-		pw = simple_strtoul(buf, NULL, 0);
-		if (pw < 10 || pw > 256)
-			pw = 80;
-		pw--;
-	}
-	if (prom_getproperty(node,  "screen-#rows", buf, 40) != -1) {
-		ph = simple_strtoul(buf, NULL, 0);
-		if (ph < 10 || ph > 256)
-			ph = 34;
-		ph--;
-	}
-	promcon_puts("\033[H\033[J", 6);
-	return display_desc;
-}
-
-static void __init 
-promcon_init_unimap(struct vc_data *conp)
-{
-	mm_segment_t old_fs = get_fs();
-	struct unipair *p, *p1;
-	u16 *q;
-	int i, j, k;
-	
-	p = kmalloc(256*sizeof(struct unipair), GFP_KERNEL);
-	if (!p) return;
-	
-	q = promfont_unitable;
-	p1 = p;
-	k = 0;
-	for (i = 0; i < 256; i++)
-		for (j = promfont_unicount[i]; j; j--) {
-			p1->unicode = *q++;
-			p1->fontpos = i;
-			p1++;
-			k++;
-		}
-	set_fs(KERNEL_DS);
-	con_clear_unimap(conp->vc_num, NULL);
-	con_set_unimap(conp->vc_num, k, p);
-	con_protect_unimap(conp->vc_num, 1);
-	set_fs(old_fs);
-	kfree(p);
-}
-
-static void
-promcon_init(struct vc_data *conp, int init)
-{
-	unsigned long p;
-	
-	conp->vc_can_do_color = PROMCON_COLOR;
-	if (init) {
-		conp->vc_cols = pw + 1;
-		conp->vc_rows = ph + 1;
-	}
-	p = *conp->vc_uni_pagedir_loc;
-	if (conp->vc_uni_pagedir_loc == &conp->vc_uni_pagedir ||
-	    !--conp->vc_uni_pagedir_loc[1])
-		con_free_unimap(conp->vc_num);
-	conp->vc_uni_pagedir_loc = promcon_uni_pagedir;
-	promcon_uni_pagedir[1]++;
-	if (!promcon_uni_pagedir[0] && p) {
-		promcon_init_unimap(conp);
-	}
-	if (!init) {
-		if (conp->vc_cols != pw + 1 || conp->vc_rows != ph + 1)
-			vc_resize_con(ph + 1, pw + 1, conp->vc_num);
-	}
-}
-
-static void
-promcon_deinit(struct vc_data *conp)
-{
-	/* When closing the last console, reset video origin */
-	if (!--promcon_uni_pagedir[1])
-		con_free_unimap(conp->vc_num);
-	conp->vc_uni_pagedir_loc = &conp->vc_uni_pagedir;
-	con_set_default_unimap(conp->vc_num);
-}
-
-static int
-promcon_switch(struct vc_data *conp)
-{
-	return 1;
-}
-
-static unsigned short *
-promcon_repaint_line(unsigned short *s, unsigned char *buf, unsigned char **bp)
-{
-	int cnt = pw + 1;
-	int attr = -1;
-	unsigned char *b = *bp;
-
-	while (cnt--) {
-		u16 c = scr_readw(s);
-		if (attr != inverted(c)) {
-			attr = inverted(c);
-			if (attr) {
-				strcpy (b, "\033[7m");
-				b += 4;
-			} else {
-				strcpy (b, "\033[m");
-				b += 3;
-			}
-		}
-		*b++ = c;
-		s++;
-		if (b - buf >= 224) {
-			promcon_puts(buf, b - buf);
-			b = buf;
-		}
-	}
-	*bp = b;
-	return s;
-}
-
-static void
-promcon_putcs(struct vc_data *conp, const unsigned short *s,
-	      int count, int y, int x)
-{
-	unsigned char buf[256], *b = buf;
-	unsigned short attr = scr_readw(s);
-	unsigned char save;
-	int i, last = 0;
-
-	if (console_blanked)
-		return;
-	
-	if (count <= 0)
-		return;
-
-	b += promcon_start(conp, b);
-
-	if (x + count >= pw + 1) {
-		if (count == 1) {
-			x -= 1;
-			save = scr_readw((unsigned short *)(conp->vc_origin
-						   + y * conp->vc_size_row
-						   + (x << 1)));
-
-			if (px != x || py != y) {
-				b += sprintf(b, "\033[%d;%dH", y + 1, x + 1);
-				px = x;
-				py = y;
-			}
-
-			if (inverted(attr))
-				b += sprintf(b, "\033[7m%c\033[m", scr_readw(s++));
-			else
-				b += sprintf(b, "%c", scr_readw(s++));
-
-			strcpy(b, "\b\033[@");
-			b += 4;
-
-			if (inverted(save))
-				b += sprintf(b, "\033[7m%c\033[m", save);
-			else
-				b += sprintf(b, "%c", save);
-
-			px++;
-
-			b += promcon_end(conp, b);
-			promcon_puts(buf, b - buf);
-			return;
-		} else {
-			last = 1;
-			count = pw - x - 1;
-		}
-	}
-
-	if (inverted(attr)) {
-		strcpy(b, "\033[7m");
-		b += 4;
-	}
-
-	if (px != x || py != y) {
-		b += sprintf(b, "\033[%d;%dH", y + 1, x + 1);
-		px = x;
-		py = y;
-	}
-
-	for (i = 0; i < count; i++) {
-		if (b - buf >= 224) {
-			promcon_puts(buf, b - buf);
-			b = buf;
-		}
-		*b++ = scr_readw(s++);
-	}
-
-	px += count;
-
-	if (last) {
-		save = scr_readw(s++);
-		b += sprintf(b, "%c\b\033[@%c", scr_readw(s++), save);
-		px++;
-	}
-
-	if (inverted(attr)) {
-		strcpy(b, "\033[m");
-		b += 3;
-	}
-
-	b += promcon_end(conp, b);
-	promcon_puts(buf, b - buf);
-}
-
-static void
-promcon_putc(struct vc_data *conp, int c, int y, int x)
-{
-	unsigned short s;
-
-	if (console_blanked)
-		return;
-	
-	scr_writew(c, &s);
-	promcon_putcs(conp, &s, 1, y, x);
-}
-
-static void
-promcon_clear(struct vc_data *conp, int sy, int sx, int height, int width)
-{
-	unsigned char buf[256], *b = buf;
-	int i, j;
-
-	if (console_blanked)
-		return;
-	
-	b += promcon_start(conp, b);
-
-	if (!sx && width == pw + 1) {
-
-		if (!sy && height == ph + 1) {
-			strcpy(b, "\033[H\033[J");
-			b += 6;
-			b += promcon_end(conp, b);
-			promcon_puts(buf, b - buf);
-			return;
-		} else if (sy + height == ph + 1) {
-			b += sprintf(b, "\033[%dH\033[J", sy + 1);
-			b += promcon_end(conp, b);
-			promcon_puts(buf, b - buf);
-			return;
-		}
-
-		b += sprintf(b, "\033[%dH", sy + 1);
-		for (i = 1; i < height; i++) {
-			strcpy(b, "\033[K\n");
-			b += 4;
-		}
-
-		strcpy(b, "\033[K");
-		b += 3;
-
-		b += promcon_end(conp, b);
-		promcon_puts(buf, b - buf);
-		return;
-
-	} else if (sx + width == pw + 1) {
-
-		b += sprintf(b, "\033[%d;%dH", sy + 1, sx + 1);
-		for (i = 1; i < height; i++) {
-			strcpy(b, "\033[K\n");
-			b += 4;
-		}
-
-		strcpy(b, "\033[K");
-		b += 3;
-
-		b += promcon_end(conp, b);
-		promcon_puts(buf, b - buf);
-		return;
-	}
-
-	for (i = sy + 1; i <= sy + height; i++) {
-		b += sprintf(b, "\033[%d;%dH", i, sx + 1);
-		for (j = 0; j < width; j++)
-			*b++ = ' ';
-		if (b - buf + width >= 224) {
-			promcon_puts(buf, b - buf);
-			b = buf;
-		}
-	}
-
-	b += promcon_end(conp, b);
-	promcon_puts(buf, b - buf);
-}
-                        
-static void
-promcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
-	      int height, int width)
-{
-	char buf[256], *b = buf;
-
-	if (console_blanked)
-		return;
-	
-	b += promcon_start(conp, b);
-	if (sy == dy && height == 1) {
-		if (dx > sx && dx + width == conp->vc_cols)
-			b += sprintf(b, "\033[%d;%dH\033[%d@\033[%d;%dH",
-				     sy + 1, sx + 1, dx - sx, py + 1, px + 1);
-		else if (dx < sx && sx + width == conp->vc_cols)
-			b += sprintf(b, "\033[%d;%dH\033[%dP\033[%d;%dH",
-				     dy + 1, dx + 1, sx - dx, py + 1, px + 1);
-
-		b += promcon_end(conp, b);
-		promcon_puts(buf, b - buf);
-		return;
-	}
-
-	/*
-	 * FIXME: What to do here???
-	 * Current console.c should not call it like that ever.
-	 */
-	prom_printf("\033[7mFIXME: bmove not handled\033[m\n");
-}
-
-static void
-promcon_cursor(struct vc_data *conp, int mode)
-{
-	char buf[32], *b = buf;
-
-	switch (mode) {
-	case CM_ERASE:
-		break;
-
-	case CM_MOVE:
-	case CM_DRAW:
-		b += promcon_start(conp, b);
-		if (px != conp->vc_x || py != conp->vc_y) {
-			px = conp->vc_x;
-			py = conp->vc_y;
-			b += sprintf(b, "\033[%d;%dH", py + 1, px + 1);
-		}
-		promcon_puts(buf, b - buf);
-		break;
-	}
-}
-
-static int
-promcon_font_op(struct vc_data *conp, struct console_font_op *op)
-{
-	return -ENOSYS;
-}
-        
-static int
-promcon_blank(struct vc_data *conp, int blank)
-{
-	if (blank) {
-		promcon_puts("\033[H\033[J\033[7m \033[m\b", 15);
-		return 0;
-	} else {
-		/* Let console.c redraw */
-		return 1;
-	}
-}
-
-static int
-promcon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
-{
-	unsigned char buf[256], *p = buf;
-	unsigned short *s;
-	int i;
-
-	if (console_blanked)
-		return 0;
-	
-	p += promcon_start(conp, p);
-
-	switch (dir) {
-	case SM_UP:
-		if (b == ph + 1) {
-			p += sprintf(p, "\033[%dH\033[%dM", t + 1, count);
-			px = 0;
-			py = t;
-			p += promcon_end(conp, p);
-			promcon_puts(buf, p - buf);
-			break;
-		}
-
-		s = (unsigned short *)(conp->vc_origin
-				       + (t + count) * conp->vc_size_row);
-
-		p += sprintf(p, "\033[%dH", t + 1);
-
-		for (i = t; i < b - count; i++)
-			s = promcon_repaint_line(s, buf, &p);
-
-		for (; i < b - 1; i++) {
-			strcpy(p, "\033[K\n");
-			p += 4;
-			if (p - buf >= 224) {
-				promcon_puts(buf, p - buf);
-				p = buf;
-			}
-		}
-
-		strcpy(p, "\033[K");
-		p += 3;
-
-		p += promcon_end(conp, p);
-		promcon_puts(buf, p - buf);
-		break;
-
-	case SM_DOWN:
-		if (b == ph + 1) {
-			p += sprintf(p, "\033[%dH\033[%dL", t + 1, count);
-			px = 0;
-			py = t;
-			p += promcon_end(conp, p);
-			promcon_puts(buf, p - buf);
-			break;
-		}
-
-		s = (unsigned short *)(conp->vc_origin + t * conp->vc_size_row);
-
-		p += sprintf(p, "\033[%dH", t + 1);
-
-		for (i = t; i < t + count; i++) {
-			strcpy(p, "\033[K\n");
-			p += 4;
-			if (p - buf >= 224) {
-				promcon_puts(buf, p - buf);
-				p = buf;
-			}
-		}
-
-		for (; i < b; i++)
-			s = promcon_repaint_line(s, buf, &p);
-
-		p += promcon_end(conp, p);
-		promcon_puts(buf, p - buf);
-		break;
-	}
-
-	return 0;
-}
-
-#if !(PROMCON_COLOR)
-static u8 promcon_build_attr(struct vc_data *conp, u8 _color, u8 _intensity, u8 _blink, u8 _underline, u8 _reverse)
-{
-	return (_reverse) ? 0xf : 0x7;
-}
-#endif
-
-/*
- *  The console 'switch' structure for the VGA based console
- */
-
-static int promcon_dummy(void)
-{
-        return 0;
-}
-
-#define DUMMY (void *) promcon_dummy
-
-const struct consw prom_con = {
-	.con_startup =		promcon_startup,
-	.con_init =		promcon_init,
-	.con_deinit =		promcon_deinit,
-	.con_clear =		promcon_clear,
-	.con_putc =		promcon_putc,
-	.con_putcs =		promcon_putcs,
-	.con_cursor =		promcon_cursor,
-	.con_scroll =		promcon_scroll,
-	.con_bmove =		promcon_bmove,
-	.con_switch =		promcon_switch,
-	.con_blank =		promcon_blank,
-	.con_font_op =		promcon_font_op,
-	.con_set_palette =	DUMMY,
-	.con_scrolldelta =	DUMMY,
-#if !(PROMCON_COLOR)
-	.con_build_attr =	promcon_build_attr,
-#endif
-};
-
-void __init prom_con_init(void)
-{
-#ifdef CONFIG_DUMMY_CONSOLE
-	if (conswitchp == &dummy_con)
-		take_over_console(&prom_con, 0, MAX_NR_CONSOLES-1, 1);
-	else
-#endif
-	if (conswitchp == &prom_con)
-		promcon_init_unimap(vc_cons[fg_console].d);
-}
diff -Nru a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
--- a/drivers/video/pvr2fb.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/video/pvr2fb.c	Mon Dec  9 18:46:34 2002
@@ -1059,10 +1059,10 @@
 	modememused = get_line_length(var.xres_virtual, var.bits_per_pixel);
 	modememused *= var.yres_virtual;
 	printk("fb%d: %s frame buffer device, using %ldk/%ldk of video memory\n",
-	       GET_FB_IDX(fb_info.node), fb_info.modename, modememused>>10,
+	       minor(fb_info.node), fb_info.modename, modememused>>10,
 	       videomemorysize>>10);
 	printk("fb%d: Mode %dx%d-%d pitch = %ld cable: %s video output: %s\n", 
-	       GET_FB_IDX(fb_info.node), var.xres, var.yres, var.bits_per_pixel, 
+	       minor(fb_info.node), var.xres, var.yres, var.bits_per_pixel, 
 	       get_line_length(var.xres, var.bits_per_pixel),
 	       (char *)pvr2_get_param(cables, NULL, cable_type, 3),
 	       (char *)pvr2_get_param(outputs, NULL, video_output, 3));
diff -Nru a/drivers/video/q40fb.c b/drivers/video/q40fb.c
--- a/drivers/video/q40fb.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/video/q40fb.c	Mon Dec  9 18:46:35 2002
@@ -28,13 +28,10 @@
 #include <linux/module.h>
 #include <asm/pgtable.h>
 
-#include <video/fbcon.h>
-
 #define Q40_PHYS_SCREEN_ADDR 0xFE800000
 
 static u32 pseudo_palette[17];
 static struct fb_info fb_info;
-static struct display display;
 
 static struct fb_fix_screeninfo q40fb_fix __initdata = {
 	.id		= "Q40",
@@ -69,13 +66,11 @@
 
 static struct fb_ops q40fb_ops = {
 	.owner		= THIS_MODULE,
-	.fb_set_var	= gen_set_var,
-	.fb_get_cmap	= gen_get_cmap,
-	.fb_set_cmap	= gen_set_cmap,
 	.fb_setcolreg	= q40fb_setcolreg,
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
+	.fb_cursor	= soft_cursor,
 };
 
 static int q40fb_setcolreg(unsigned regno, unsigned red, unsigned green,
@@ -117,15 +112,8 @@
    	fb_info.screen_base = (char *) q40fb_fix.smem_start;
 
 	/* The below feilds will go away !!!! */
-	fb_info.currcon		= -1;
-	strcpy(fb_info.modename, fb_info.fix.id);
-	fb_info.disp		= &display;
-	fb_info.switch_con	= gen_switch;
-	fb_info.updatevar	= gen_update_var;
 	fb_alloc_cmap(&fb_info.cmap, 16, 0);
 
-        gen_set_disp(-1, &fb_info);
-	
 	master_outb(3, DISPLAY_CONTROL_REG);
 
 	if (register_framebuffer(&fb_info) < 0) {
@@ -134,7 +122,7 @@
 	}
 
         printk(KERN_INFO "fb%d: Q40 frame buffer alive and kicking !\n",
-	       GET_FB_IDX(fb_info.node));
+	       minor(fb_info.node));
 	return 0;
 }
 
diff -Nru a/drivers/video/radeon.h b/drivers/video/radeon.h
--- a/drivers/video/radeon.h	Mon Dec  9 18:46:52 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,766 +0,0 @@
-#ifndef _RADEON_H
-#define _RADEON_H
-
-
-/* radeon PCI ids */
-#define PCI_DEVICE_ID_RADEON_QD		0x5144
-#define PCI_DEVICE_ID_RADEON_QE		0x5145
-#define PCI_DEVICE_ID_RADEON_QF		0x5146
-#define PCI_DEVICE_ID_RADEON_QG		0x5147
-#define PCI_DEVICE_ID_RADEON_QY		0x5159
-#define PCI_DEVICE_ID_RADEON_QZ		0x515a
-#define PCI_DEVICE_ID_RADEON_LW		0x4c57
-#define PCI_DEVICE_ID_RADEON_LY		0x4c59
-#define PCI_DEVICE_ID_RADEON_LZ		0x4c5a
-#define PCI_DEVICE_ID_RADEON_QL		0x514c
-#define PCI_DEVICE_ID_RADEON_QW		0x5157
-
-#define RADEON_REGSIZE			0x4000
-
-
-#define MM_INDEX                               0x0000  
-#define MM_DATA                                0x0004  
-#define BUS_CNTL                               0x0030  
-#define HI_STAT                                0x004C  
-#define BUS_CNTL1                              0x0034
-#define I2C_CNTL_1			       0x0094  
-#define CONFIG_CNTL                            0x00E0  
-#define CONFIG_MEMSIZE                         0x00F8  
-#define CONFIG_APER_0_BASE                     0x0100  
-#define CONFIG_APER_1_BASE                     0x0104  
-#define CONFIG_APER_SIZE                       0x0108  
-#define CONFIG_REG_1_BASE                      0x010C  
-#define CONFIG_REG_APER_SIZE                   0x0110  
-#define PAD_AGPINPUT_DELAY                     0x0164  
-#define PAD_CTLR_STRENGTH                      0x0168  
-#define PAD_CTLR_UPDATE                        0x016C
-#define AGP_CNTL                               0x0174
-#define BM_STATUS                              0x0160
-#define CAP0_TRIG_CNTL			       0x0950
-#define VIPH_CONTROL			       0x0C40
-#define VENDOR_ID                              0x0F00  
-#define DEVICE_ID                              0x0F02  
-#define COMMAND                                0x0F04  
-#define STATUS                                 0x0F06  
-#define REVISION_ID                            0x0F08  
-#define REGPROG_INF                            0x0F09  
-#define SUB_CLASS                              0x0F0A  
-#define BASE_CODE                              0x0F0B  
-#define CACHE_LINE                             0x0F0C  
-#define LATENCY                                0x0F0D  
-#define HEADER                                 0x0F0E  
-#define BIST                                   0x0F0F  
-#define REG_MEM_BASE                           0x0F10  
-#define REG_IO_BASE                            0x0F14  
-#define REG_REG_BASE                           0x0F18
-#define ADAPTER_ID                             0x0F2C
-#define BIOS_ROM                               0x0F30
-#define CAPABILITIES_PTR                       0x0F34  
-#define INTERRUPT_LINE                         0x0F3C  
-#define INTERRUPT_PIN                          0x0F3D  
-#define MIN_GRANT                              0x0F3E  
-#define MAX_LATENCY                            0x0F3F  
-#define ADAPTER_ID_W                           0x0F4C  
-#define PMI_CAP_ID                             0x0F50  
-#define PMI_NXT_CAP_PTR                        0x0F51  
-#define PMI_PMC_REG                            0x0F52  
-#define PM_STATUS                              0x0F54  
-#define PMI_DATA                               0x0F57  
-#define AGP_CAP_ID                             0x0F58  
-#define AGP_STATUS                             0x0F5C  
-#define AGP_COMMAND                            0x0F60  
-#define AIC_CTRL                               0x01D0
-#define AIC_STAT                               0x01D4
-#define AIC_PT_BASE                            0x01D8
-#define AIC_LO_ADDR                            0x01DC  
-#define AIC_HI_ADDR                            0x01E0  
-#define AIC_TLB_ADDR                           0x01E4  
-#define AIC_TLB_DATA                           0x01E8  
-#define DAC_CNTL                               0x0058  
-#define CRTC_GEN_CNTL                          0x0050  
-#define MEM_CNTL                               0x0140  
-#define EXT_MEM_CNTL                           0x0144  
-#define MC_AGP_LOCATION                        0x014C  
-#define MEM_IO_CNTL_A0                         0x0178  
-#define MEM_INIT_LATENCY_TIMER                 0x0154  
-#define MEM_SDRAM_MODE_REG                     0x0158  
-#define AGP_BASE                               0x0170  
-#define MEM_IO_CNTL_A1                         0x017C  
-#define MEM_IO_CNTL_B0                         0x0180
-#define MEM_IO_CNTL_B1                         0x0184
-#define MC_DEBUG                               0x0188
-#define MC_STATUS                              0x0150  
-#define MEM_IO_OE_CNTL                         0x018C  
-#define MC_FB_LOCATION                         0x0148  
-#define HOST_PATH_CNTL                         0x0130  
-#define MEM_VGA_WP_SEL                         0x0038  
-#define MEM_VGA_RP_SEL                         0x003C  
-#define HDP_DEBUG                              0x0138  
-#define SW_SEMAPHORE                           0x013C  
-#define SURFACE_CNTL                           0x0B00  
-#define SURFACE0_LOWER_BOUND                   0x0B04  
-#define SURFACE1_LOWER_BOUND                   0x0B14  
-#define SURFACE2_LOWER_BOUND                   0x0B24  
-#define SURFACE3_LOWER_BOUND                   0x0B34  
-#define SURFACE4_LOWER_BOUND                   0x0B44  
-#define SURFACE5_LOWER_BOUND                   0x0B54
-#define SURFACE6_LOWER_BOUND                   0x0B64
-#define SURFACE7_LOWER_BOUND                   0x0B74
-#define SURFACE0_UPPER_BOUND                   0x0B08  
-#define SURFACE1_UPPER_BOUND                   0x0B18  
-#define SURFACE2_UPPER_BOUND                   0x0B28  
-#define SURFACE3_UPPER_BOUND                   0x0B38  
-#define SURFACE4_UPPER_BOUND                   0x0B48  
-#define SURFACE5_UPPER_BOUND                   0x0B58  
-#define SURFACE6_UPPER_BOUND                   0x0B68  
-#define SURFACE7_UPPER_BOUND                   0x0B78  
-#define SURFACE0_INFO                          0x0B0C  
-#define SURFACE1_INFO                          0x0B1C  
-#define SURFACE2_INFO                          0x0B2C  
-#define SURFACE3_INFO                          0x0B3C  
-#define SURFACE4_INFO                          0x0B4C  
-#define SURFACE5_INFO                          0x0B5C  
-#define SURFACE6_INFO                          0x0B6C
-#define SURFACE7_INFO                          0x0B7C
-#define SURFACE_ACCESS_FLAGS                   0x0BF8
-#define SURFACE_ACCESS_CLR                     0x0BFC  
-#define GEN_INT_CNTL                           0x0040  
-#define GEN_INT_STATUS                         0x0044  
-#define CRTC_EXT_CNTL                          0x0054
-#define RB3D_CNTL			       0x1C3C  
-#define WAIT_UNTIL                             0x1720  
-#define ISYNC_CNTL                             0x1724  
-#define RBBM_GUICNTL                           0x172C  
-#define RBBM_STATUS                            0x0E40  
-#define RBBM_STATUS_alt_1                      0x1740  
-#define RBBM_CNTL                              0x00EC  
-#define RBBM_CNTL_alt_1                        0x0E44  
-#define RBBM_SOFT_RESET                        0x00F0  
-#define RBBM_SOFT_RESET_alt_1                  0x0E48  
-#define NQWAIT_UNTIL                           0x0E50  
-#define RBBM_DEBUG                             0x0E6C
-#define RBBM_CMDFIFO_ADDR                      0x0E70
-#define RBBM_CMDFIFO_DATAL                     0x0E74
-#define RBBM_CMDFIFO_DATAH                     0x0E78  
-#define RBBM_CMDFIFO_STAT                      0x0E7C  
-#define CRTC_STATUS                            0x005C  
-#define GPIO_VGA_DDC                           0x0060  
-#define GPIO_DVI_DDC                           0x0064  
-#define GPIO_MONID                             0x0068  
-#define PALETTE_INDEX                          0x00B0  
-#define PALETTE_DATA                           0x00B4  
-#define PALETTE_30_DATA                        0x00B8  
-#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_DEBUG                             0x021C
-#define CRTC_OFFSET_RIGHT                      0x0220  
-#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 DISPLAY_BASE_ADDR                      0x023C  
-#define SNAPSHOT_VH_COUNTS                     0x0240  
-#define SNAPSHOT_F_COUNT                       0x0244  
-#define N_VIF_COUNT                            0x0248  
-#define SNAPSHOT_VIF_COUNT                     0x024C  
-#define FP_CRTC_H_TOTAL_DISP                   0x0250  
-#define FP_CRTC_V_TOTAL_DISP                   0x0254  
-#define CRT_CRTC_H_SYNC_STRT_WID               0x0258
-#define CRT_CRTC_V_SYNC_STRT_WID               0x025C
-#define CUR_OFFSET                             0x0260
-#define CUR_HORZ_VERT_POSN                     0x0264  
-#define CUR_HORZ_VERT_OFF                      0x0268  
-#define CUR_CLR0                               0x026C  
-#define CUR_CLR1                               0x0270  
-#define FP_HORZ_VERT_ACTIVE                    0x0278  
-#define CRTC_MORE_CNTL                         0x027C  
-#define DAC_EXT_CNTL                           0x0280  
-#define FP_GEN_CNTL                            0x0284  
-#define FP_HORZ_STRETCH                        0x028C  
-#define FP_VERT_STRETCH                        0x0290  
-#define FP_H_SYNC_STRT_WID                     0x02C4  
-#define FP_V_SYNC_STRT_WID                     0x02C8  
-#define AUX_WINDOW_HORZ_CNTL                   0x02D8  
-#define AUX_WINDOW_VERT_CNTL                   0x02DC  
-#define DDA_CONFIG			       0x02e0
-#define DDA_ON_OFF			       0x02e4
-#define GRPH_BUFFER_CNTL                       0x02F0
-#define VGA_BUFFER_CNTL                        0x02F4
-#define OV0_Y_X_START                          0x0400
-#define OV0_Y_X_END                            0x0404  
-#define OV0_PIPELINE_CNTL                      0x0408  
-#define OV0_REG_LOAD_CNTL                      0x0410  
-#define OV0_SCALE_CNTL                         0x0420  
-#define OV0_V_INC                              0x0424  
-#define OV0_P1_V_ACCUM_INIT                    0x0428  
-#define OV0_P23_V_ACCUM_INIT                   0x042C  
-#define OV0_P1_BLANK_LINES_AT_TOP              0x0430  
-#define OV0_P23_BLANK_LINES_AT_TOP             0x0434  
-#define OV0_BASE_ADDR                          0x043C  
-#define OV0_VID_BUF0_BASE_ADRS                 0x0440  
-#define OV0_VID_BUF1_BASE_ADRS                 0x0444  
-#define OV0_VID_BUF2_BASE_ADRS                 0x0448  
-#define OV0_VID_BUF3_BASE_ADRS                 0x044C  
-#define OV0_VID_BUF4_BASE_ADRS                 0x0450
-#define OV0_VID_BUF5_BASE_ADRS                 0x0454
-#define OV0_VID_BUF_PITCH0_VALUE               0x0460
-#define OV0_VID_BUF_PITCH1_VALUE               0x0464  
-#define OV0_AUTO_FLIP_CNTRL                    0x0470  
-#define OV0_DEINTERLACE_PATTERN                0x0474  
-#define OV0_SUBMIT_HISTORY                     0x0478  
-#define OV0_H_INC                              0x0480  
-#define OV0_STEP_BY                            0x0484  
-#define OV0_P1_H_ACCUM_INIT                    0x0488  
-#define OV0_P23_H_ACCUM_INIT                   0x048C  
-#define OV0_P1_X_START_END                     0x0494  
-#define OV0_P2_X_START_END                     0x0498  
-#define OV0_P3_X_START_END                     0x049C  
-#define OV0_FILTER_CNTL                        0x04A0  
-#define OV0_FOUR_TAP_COEF_0                    0x04B0  
-#define OV0_FOUR_TAP_COEF_1                    0x04B4  
-#define OV0_FOUR_TAP_COEF_2                    0x04B8
-#define OV0_FOUR_TAP_COEF_3                    0x04BC
-#define OV0_FOUR_TAP_COEF_4                    0x04C0
-#define OV0_FLAG_CNTRL                         0x04DC  
-#define OV0_SLICE_CNTL                         0x04E0  
-#define OV0_VID_KEY_CLR_LOW                    0x04E4  
-#define OV0_VID_KEY_CLR_HIGH                   0x04E8  
-#define OV0_GRPH_KEY_CLR_LOW                   0x04EC  
-#define OV0_GRPH_KEY_CLR_HIGH                  0x04F0  
-#define OV0_KEY_CNTL                           0x04F4  
-#define OV0_TEST                               0x04F8  
-#define SUBPIC_CNTL                            0x0540  
-#define SUBPIC_DEFCOLCON                       0x0544  
-#define SUBPIC_Y_X_START                       0x054C  
-#define SUBPIC_Y_X_END                         0x0550  
-#define SUBPIC_V_INC                           0x0554  
-#define SUBPIC_H_INC                           0x0558  
-#define SUBPIC_BUF0_OFFSET                     0x055C
-#define SUBPIC_BUF1_OFFSET                     0x0560
-#define SUBPIC_LC0_OFFSET                      0x0564
-#define SUBPIC_LC1_OFFSET                      0x0568  
-#define SUBPIC_PITCH                           0x056C  
-#define SUBPIC_BTN_HLI_COLCON                  0x0570  
-#define SUBPIC_BTN_HLI_Y_X_START               0x0574  
-#define SUBPIC_BTN_HLI_Y_X_END                 0x0578  
-#define SUBPIC_PALETTE_INDEX                   0x057C  
-#define SUBPIC_PALETTE_DATA                    0x0580  
-#define SUBPIC_H_ACCUM_INIT                    0x0584  
-#define SUBPIC_V_ACCUM_INIT                    0x0588  
-#define DISP_MISC_CNTL                         0x0D00  
-#define DAC_MACRO_CNTL                         0x0D04  
-#define DISP_PWR_MAN                           0x0D08  
-#define DISP_TEST_DEBUG_CNTL                   0x0D10  
-#define DISP_HW_DEBUG                          0x0D14  
-#define DAC_CRC_SIG1                           0x0D18
-#define DAC_CRC_SIG2                           0x0D1C
-#define OV0_LIN_TRANS_A                        0x0D20
-#define OV0_LIN_TRANS_B                        0x0D24  
-#define OV0_LIN_TRANS_C                        0x0D28  
-#define OV0_LIN_TRANS_D                        0x0D2C  
-#define OV0_LIN_TRANS_E                        0x0D30  
-#define OV0_LIN_TRANS_F                        0x0D34  
-#define OV0_GAMMA_0_F                          0x0D40  
-#define OV0_GAMMA_10_1F                        0x0D44  
-#define OV0_GAMMA_20_3F                        0x0D48  
-#define OV0_GAMMA_40_7F                        0x0D4C  
-#define OV0_GAMMA_380_3BF                      0x0D50  
-#define OV0_GAMMA_3C0_3FF                      0x0D54  
-#define DISP_MERGE_CNTL                        0x0D60  
-#define DISP_OUTPUT_CNTL                       0x0D64  
-#define DISP_LIN_TRANS_GRPH_A                  0x0D80  
-#define DISP_LIN_TRANS_GRPH_B                  0x0D84
-#define DISP_LIN_TRANS_GRPH_C                  0x0D88
-#define DISP_LIN_TRANS_GRPH_D                  0x0D8C
-#define DISP_LIN_TRANS_GRPH_E                  0x0D90  
-#define DISP_LIN_TRANS_GRPH_F                  0x0D94  
-#define DISP_LIN_TRANS_VID_A                   0x0D98  
-#define DISP_LIN_TRANS_VID_B                   0x0D9C  
-#define DISP_LIN_TRANS_VID_C                   0x0DA0  
-#define DISP_LIN_TRANS_VID_D                   0x0DA4  
-#define DISP_LIN_TRANS_VID_E                   0x0DA8  
-#define DISP_LIN_TRANS_VID_F                   0x0DAC  
-#define RMX_HORZ_FILTER_0TAP_COEF              0x0DB0  
-#define RMX_HORZ_FILTER_1TAP_COEF              0x0DB4  
-#define RMX_HORZ_FILTER_2TAP_COEF              0x0DB8  
-#define RMX_HORZ_PHASE                         0x0DBC  
-#define DAC_EMBEDDED_SYNC_CNTL                 0x0DC0  
-#define DAC_BROAD_PULSE                        0x0DC4  
-#define DAC_SKEW_CLKS                          0x0DC8
-#define DAC_INCR                               0x0DCC
-#define DAC_NEG_SYNC_LEVEL                     0x0DD0
-#define DAC_POS_SYNC_LEVEL                     0x0DD4  
-#define DAC_BLANK_LEVEL                        0x0DD8  
-#define CLOCK_CNTL_INDEX                       0x0008  
-#define CLOCK_CNTL_DATA                        0x000C  
-#define CP_RB_CNTL                             0x0704  
-#define CP_RB_BASE                             0x0700  
-#define CP_RB_RPTR_ADDR                        0x070C  
-#define CP_RB_RPTR                             0x0710  
-#define CP_RB_WPTR                             0x0714  
-#define CP_RB_WPTR_DELAY                       0x0718  
-#define CP_IB_BASE                             0x0738  
-#define CP_IB_BUFSZ                            0x073C  
-#define SCRATCH_REG0                           0x15E0  
-#define GUI_SCRATCH_REG0                       0x15E0  
-#define SCRATCH_REG1                           0x15E4  
-#define GUI_SCRATCH_REG1                       0x15E4  
-#define SCRATCH_REG2                           0x15E8
-#define GUI_SCRATCH_REG2                       0x15E8
-#define SCRATCH_REG3                           0x15EC
-#define GUI_SCRATCH_REG3                       0x15EC  
-#define SCRATCH_REG4                           0x15F0  
-#define GUI_SCRATCH_REG4                       0x15F0  
-#define SCRATCH_REG5                           0x15F4  
-#define GUI_SCRATCH_REG5                       0x15F4  
-#define SCRATCH_UMSK                           0x0770  
-#define SCRATCH_ADDR                           0x0774  
-#define DP_BRUSH_FRGD_CLR                      0x147C  
-#define DP_BRUSH_BKGD_CLR                      0x1478
-#define DST_LINE_START                         0x1600
-#define DST_LINE_END                           0x1604  
-#define SRC_OFFSET                             0x15AC  
-#define SRC_PITCH                              0x15B0
-#define SRC_TILE                               0x1704
-#define SRC_PITCH_OFFSET                       0x1428
-#define SRC_X                                  0x1414  
-#define SRC_Y                                  0x1418  
-#define SRC_X_Y                                0x1590  
-#define SRC_Y_X                                0x1434  
-#define DST_Y_X				       0x1438
-#define DST_WIDTH_HEIGHT		       0x1598
-#define DST_HEIGHT_WIDTH		       0x143c
-#define SRC_CLUT_ADDRESS                       0x1780  
-#define SRC_CLUT_DATA                          0x1784  
-#define SRC_CLUT_DATA_RD                       0x1788  
-#define HOST_DATA0                             0x17C0  
-#define HOST_DATA1                             0x17C4  
-#define HOST_DATA2                             0x17C8  
-#define HOST_DATA3                             0x17CC  
-#define HOST_DATA4                             0x17D0  
-#define HOST_DATA5                             0x17D4  
-#define HOST_DATA6                             0x17D8  
-#define HOST_DATA7                             0x17DC
-#define HOST_DATA_LAST                         0x17E0
-#define DP_SRC_ENDIAN                          0x15D4
-#define DP_SRC_FRGD_CLR                        0x15D8  
-#define DP_SRC_BKGD_CLR                        0x15DC  
-#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 DP_CNTL                                0x16C0  
-#define DP_CNTL_XDIR_YDIR_YMAJOR               0x16D0  
-#define DP_DATATYPE                            0x16C4  
-#define DP_MIX                                 0x16C8  
-#define DP_WRITE_MSK                           0x16CC  
-#define DP_XOP                                 0x17F8  
-#define CLR_CMP_CLR_SRC                        0x15C4
-#define CLR_CMP_CLR_DST                        0x15C8
-#define CLR_CMP_CNTL                           0x15C0
-#define CLR_CMP_MSK                            0x15CC  
-#define DSTCACHE_MODE                          0x1710  
-#define DSTCACHE_CTLSTAT                       0x1714  
-#define DEFAULT_PITCH_OFFSET                   0x16E0  
-#define DEFAULT_SC_BOTTOM_RIGHT                0x16E8  
-#define DP_GUI_MASTER_CNTL                     0x146C  
-#define SC_TOP_LEFT                            0x16EC  
-#define SC_BOTTOM_RIGHT                        0x16F0  
-#define SRC_SC_BOTTOM_RIGHT                    0x16F4  
-#define RB2D_DSTCACHE_CTLSTAT		       0x342C
-#define LVDS_GEN_CNTL			       0x02d0
-#define LVDS_PLL_CNTL			       0x02d4
-#define TMDS_CRC			       0x02a0
-
-#define RADEON_BASE_CODE		       0x0f0b
-#define RADEON_BIOS_0_SCRATCH		       0x0010
-#define RADEON_BIOS_1_SCRATCH		       0x0014
-#define RADEON_BIOS_2_SCRATCH		       0x0018
-#define RADEON_BIOS_3_SCRATCH		       0x001c
-#define RADEON_BIOS_4_SCRATCH		       0x0020
-#define RADEON_BIOS_5_SCRATCH		       0x0024
-#define RADEON_BIOS_6_SCRATCH		       0x0028
-#define RADEON_BIOS_7_SCRATCH		       0x002c
-
-
-#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 M_SPLL_REF_FB_DIV                          0x000a
-#define AGP_PLL_CNTL                               0x000b
-#define SPLL_CNTL                                  0x000c
-#define SCLK_CNTL                                  0x000d
-#define MPLL_CNTL                                  0x000e
-#define MCLK_CNTL                                  0x0012
-#define AGP_PLL_CNTL                               0x000b
-#define PLL_TEST_CNTL                              0x0013
-
-
-/* MCLK_CNTL bit constants */
-#define FORCEON_MCLKA				   (1 << 16)
-#define FORCEON_MCLKB         		   	   (1 << 17)
-#define FORCEON_YCLKA         	    	   	   (1 << 18)
-#define FORCEON_YCLKB         		   	   (1 << 19)
-#define FORCEON_MC            		   	   (1 << 20)
-#define FORCEON_AIC           		   	   (1 << 21)
-
-
-/* BUS_CNTL bit constants */
-#define BUS_DBL_RESYNC                             0x00000001
-#define BUS_MSTR_RESET                             0x00000002
-#define BUS_FLUSH_BUF                              0x00000004
-#define BUS_STOP_REQ_DIS                           0x00000008
-#define BUS_ROTATION_DIS                           0x00000010
-#define BUS_MASTER_DIS                             0x00000040
-#define BUS_ROM_WRT_EN                             0x00000080
-#define BUS_DIS_ROM                                0x00001000
-#define BUS_PCI_READ_RETRY_EN                      0x00002000
-#define BUS_AGP_AD_STEPPING_EN                     0x00004000
-#define BUS_PCI_WRT_RETRY_EN                       0x00008000
-#define BUS_MSTR_RD_MULT                           0x00100000
-#define BUS_MSTR_RD_LINE                           0x00200000
-#define BUS_SUSPEND                                0x00400000
-#define LAT_16X                                    0x00800000
-#define BUS_RD_DISCARD_EN                          0x01000000
-#define BUS_RD_ABORT_EN                            0x02000000
-#define BUS_MSTR_WS                                0x04000000
-#define BUS_PARKING_DIS                            0x08000000
-#define BUS_MSTR_DISCONNECT_EN                     0x10000000
-#define BUS_WRT_BURST                              0x20000000
-#define BUS_READ_BURST                             0x40000000
-#define BUS_RDY_READ_DLY                           0x80000000
-
-
-/* CLOCK_CNTL_INDEX bit constants */
-#define PLL_WR_EN                                  0x00000080
-
-/* CONFIG_CNTL bit constants */
-#define CFG_VGA_RAM_EN                             0x00000100
-
-/* CRTC_EXT_CNTL bit constants */
-#define VGA_ATI_LINEAR                             0x00000008
-#define VGA_128KAP_PAGING                          0x00000010
-#define	XCRT_CNT_EN				   (1 << 6)
-#define CRTC_HSYNC_DIS				   (1 << 8)
-#define CRTC_VSYNC_DIS				   (1 << 9)
-#define CRTC_DISPLAY_DIS			   (1 << 10)
-#define CRTC_CRT_ON				   (1 << 15)
-
-
-/* DSTCACHE_CTLSTAT bit constants */
-#define RB2D_DC_FLUSH				   (3 << 0)
-#define RB2D_DC_FLUSH_ALL			   0xf
-#define RB2D_DC_BUSY				   (1 << 31)
-
-
-/* CRTC_GEN_CNTL bit constants */
-#define CRTC_DBL_SCAN_EN                           0x00000001
-#define CRTC_CUR_EN                                0x00010000
-#define CRTC_INTERLACE_EN			   (1 << 1)
-#define CRTC_EXT_DISP_EN      			   (1 << 24)
-#define CRTC_EN					   (1 << 25)
-
-/* CRTC_STATUS bit constants */
-#define CRTC_VBLANK                                0x00000001
-
-/* CUR_OFFSET, CUR_HORZ_VERT_POSN, CUR_HORZ_VERT_OFF bit constants */
-#define CUR_LOCK                                   0x80000000
-
-
-/* FP bit constants */
-#define FP_CRTC_H_TOTAL_MASK			   0x000003ff
-#define FP_CRTC_H_DISP_MASK			   0x01ff0000
-#define FP_CRTC_V_TOTAL_MASK			   0x00000fff
-#define FP_CRTC_V_DISP_MASK			   0x0fff0000
-#define FP_H_SYNC_STRT_CHAR_MASK		   0x00001ff8
-#define FP_H_SYNC_WID_MASK			   0x003f0000
-#define FP_V_SYNC_STRT_MASK			   0x00000fff
-#define FP_V_SYNC_WID_MASK			   0x001f0000
-#define FP_CRTC_H_TOTAL_SHIFT			   0x00000000
-#define FP_CRTC_H_DISP_SHIFT			   0x00000010
-#define FP_CRTC_V_TOTAL_SHIFT			   0x00000000
-#define FP_CRTC_V_DISP_SHIFT			   0x00000010
-#define FP_H_SYNC_STRT_CHAR_SHIFT		   0x00000003
-#define FP_H_SYNC_WID_SHIFT			   0x00000010
-#define FP_V_SYNC_STRT_SHIFT			   0x00000000
-#define FP_V_SYNC_WID_SHIFT			   0x00000010
-
-/* FP_GEN_CNTL bit constants */
-#define FP_FPON					   (1 << 0)
-#define FP_TMDS_EN				   (1 << 2)
-#define FP_EN_TMDS				   (1 << 7)
-#define FP_DETECT_SENSE				   (1 << 8)
-#define FP_SEL_CRTC2				   (1 << 13)
-#define FP_CRTC_DONT_SHADOW_HPAR		   (1 << 15)
-#define FP_CRTC_DONT_SHADOW_VPAR		   (1 << 16)
-#define FP_CRTC_DONT_SHADOW_HEND		   (1 << 17)
-#define FP_CRTC_USE_SHADOW_VEND			   (1 << 18)
-#define FP_RMX_HVSYNC_CONTROL_EN		   (1 << 20)
-#define FP_DFP_SYNC_SEL				   (1 << 21)
-#define FP_CRTC_LOCK_8DOT			   (1 << 22)
-#define FP_CRT_SYNC_SEL				   (1 << 23)
-#define FP_USE_SHADOW_EN			   (1 << 24)
-#define FP_CRT_SYNC_ALT				   (1 << 26)
-
-/* LVDS_GEN_CNTL bit constants */
-#define LVDS_ON					   (1 << 0)
-#define LVDS_DISPLAY_DIS			   (1 << 1)
-#define LVDS_PANEL_TYPE				   (1 << 2)
-#define LVDS_PANEL_FORMAT			   (1 << 3)
-#define LVDS_EN					   (1 << 7)
-#define LVDS_DIGON				   (1 << 18)
-#define LVDS_BLON				   (1 << 19)
-#define LVDS_SEL_CRTC2				   (1 << 23)
-
-/* LVDS_PLL_CNTL bit constatns */
-#define HSYNC_DELAY_SHIFT			   0x1c
-#define HSYNC_DELAY_MASK			   (0xf << 0x1c)
-
-/* FP_HORZ_STRETCH bit constants */
-#define HORZ_STRETCH_RATIO_MASK			   0xffff
-#define HORZ_STRETCH_RATIO_MAX			   4096
-#define HORZ_PANEL_SIZE				   (0x1ff << 16)
-#define HORZ_PANEL_SHIFT			   16
-#define HORZ_STRETCH_PIXREP			   (0 << 25)
-#define HORZ_STRETCH_BLEND			   (1 << 26)
-#define HORZ_STRETCH_ENABLE			   (1 << 25)
-#define HORZ_AUTO_RATIO				   (1 << 27)
-#define HORZ_FP_LOOP_STRETCH			   (0x7 << 28)
-#define HORZ_AUTO_RATIO_INC			   (1 << 31)
-
-
-/* FP_VERT_STRETCH bit constants */
-#define VERT_STRETCH_RATIO_MASK			   0xfff
-#define VERT_STRETCH_RATIO_MAX			   4096
-#define VERT_PANEL_SIZE				   (0xfff << 12)
-#define VERT_PANEL_SHIFT			   12
-#define VERT_STRETCH_LINREP			   (0 << 26)
-#define VERT_STRETCH_BLEND			   (1 << 26)
-#define VERT_STRETCH_ENABLE			   (1 << 25)
-#define VERT_AUTO_RATIO_EN			   (1 << 27)
-#define VERT_FP_LOOP_STRETCH			   (0x7 << 28)
-#define VERT_STRETCH_RESERVED			   0xf1000000
-
-/* DAC_CNTL bit constants */   
-#define DAC_8BIT_EN                                0x00000100
-#define DAC_4BPP_PIX_ORDER                         0x00000200
-#define DAC_CRC_EN                                 0x00080000
-#define DAC_MASK_ALL				   (0xff << 24)
-#define DAC_VGA_ADR_EN				   (1 << 13)
-#define DAC_RANGE_CNTL				   (3 << 0)
-#define DAC_BLANKING				   (1 << 2)
-
-/* 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
-
-/* MEM_CNTL bit constants */
-#define MEM_CTLR_STATUS_IDLE                       0x00000000
-#define MEM_CTLR_STATUS_BUSY                       0x00100000
-#define MEM_SEQNCR_STATUS_IDLE                     0x00000000
-#define MEM_SEQNCR_STATUS_BUSY                     0x00200000
-#define MEM_ARBITER_STATUS_IDLE                    0x00000000
-#define MEM_ARBITER_STATUS_BUSY                    0x00400000
-#define MEM_REQ_UNLOCK                             0x00000000
-#define MEM_REQ_LOCK                               0x00800000
-
-
-/* RBBM_SOFT_RESET bit constants */
-#define SOFT_RESET_CP           		   (1 <<  0)
-#define SOFT_RESET_HI           		   (1 <<  1)
-#define SOFT_RESET_SE           		   (1 <<  2)
-#define SOFT_RESET_RE           		   (1 <<  3)
-#define SOFT_RESET_PP           		   (1 <<  4)
-#define SOFT_RESET_E2           		   (1 <<  5)
-#define SOFT_RESET_RB           		   (1 <<  6)
-#define SOFT_RESET_HDP          		   (1 <<  7)
-
-/* SURFACE_CNTL bit consants */
-#define SURF_TRANSLATION_DIS			   (1 << 8)
-#define NONSURF_AP0_SWP_16BPP			   (1 << 20)
-#define NONSURF_AP0_SWP_32BPP			   (1 << 21)
-
-/* DEFAULT_SC_BOTTOM_RIGHT bit constants */
-#define DEFAULT_SC_RIGHT_MAX			   (0x1fff << 0)
-#define DEFAULT_SC_BOTTOM_MAX			   (0x1fff << 16)
-
-/* MM_INDEX bit constants */
-#define MM_APER                                    0x80000000
-
-/* CLR_CMP_CNTL bit constants */
-#define COMPARE_SRC_FALSE                          0x00000000
-#define COMPARE_SRC_TRUE                           0x00000001
-#define COMPARE_SRC_NOT_EQUAL                      0x00000004
-#define COMPARE_SRC_EQUAL                          0x00000005
-#define COMPARE_SRC_EQUAL_FLIP                     0x00000007
-#define COMPARE_DST_FALSE                          0x00000000
-#define COMPARE_DST_TRUE                           0x00000100
-#define COMPARE_DST_NOT_EQUAL                      0x00000400
-#define COMPARE_DST_EQUAL                          0x00000500
-#define COMPARE_DESTINATION                        0x00000000
-#define COMPARE_SOURCE                             0x01000000
-#define COMPARE_SRC_AND_DST                        0x02000000
-
-
-/* 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_CNTL_YDIR_XDIR_YMAJOR bit constants (short version of DP_CNTL) */
-#define DST_X_MAJOR_S                              0x00000000
-#define DST_Y_MAJOR_S                              0x00000001
-#define DST_Y_BOTTOM_TO_TOP_S                      0x00000000
-#define DST_Y_TOP_TO_BOTTOM_S                      0x00008000
-#define DST_X_RIGHT_TO_LEFT_S                      0x00000000
-#define DST_X_LEFT_TO_RIGHT_S                      0x80000000
-
-
-/* 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 DST_8BPP_RGB332                            0x00000007
-#define DST_8BPP_Y8                                0x00000008
-#define DST_8BPP_RGB8                              0x00000009
-#define DST_16BPP_VYUY422                          0x0000000b
-#define DST_16BPP_YVYU422                          0x0000000c
-#define DST_32BPP_AYUV444                          0x0000000e
-#define DST_16BPP_ARGB4444                         0x0000000f
-#define BRUSH_SOLIDCOLOR                           0x00000d00
-#define SRC_MONO                                   0x00000000
-#define SRC_MONO_LBKGD                             0x00010000
-#define SRC_DSTCOLOR                               0x00030000
-#define BYTE_ORDER_MSB_TO_LSB                      0x00000000
-#define BYTE_ORDER_LSB_TO_MSB                      0x40000000
-#define DP_CONVERSION_TEMP                         0x80000000
-#define HOST_BIG_ENDIAN_EN			   (1 << 29)
-
-
-/* DP_GUI_MASTER_CNTL bit constants */
-#define GMC_SRC_PITCH_OFFSET_DEFAULT               0x00000000
-#define GMC_SRC_PITCH_OFFSET_LEAVE                 0x00000001
-#define GMC_DST_PITCH_OFFSET_DEFAULT               0x00000000
-#define GMC_DST_PITCH_OFFSET_LEAVE                 0x00000002
-#define GMC_SRC_CLIP_DEFAULT                       0x00000000
-#define GMC_SRC_CLIP_LEAVE                         0x00000004
-#define GMC_DST_CLIP_DEFAULT                       0x00000000
-#define GMC_DST_CLIP_LEAVE                         0x00000008
-#define GMC_BRUSH_8x8MONO                          0x00000000
-#define GMC_BRUSH_8x8MONO_LBKGD                    0x00000010
-#define GMC_BRUSH_8x1MONO                          0x00000020
-#define GMC_BRUSH_8x1MONO_LBKGD                    0x00000030
-#define GMC_BRUSH_1x8MONO                          0x00000040
-#define GMC_BRUSH_1x8MONO_LBKGD                    0x00000050
-#define GMC_BRUSH_32x1MONO                         0x00000060
-#define GMC_BRUSH_32x1MONO_LBKGD                   0x00000070
-#define GMC_BRUSH_32x32MONO                        0x00000080
-#define GMC_BRUSH_32x32MONO_LBKGD                  0x00000090
-#define GMC_BRUSH_8x8COLOR                         0x000000a0
-#define GMC_BRUSH_8x1COLOR                         0x000000b0
-#define GMC_BRUSH_1x8COLOR                         0x000000c0
-#define GMC_BRUSH_SOLID_COLOR                       0x000000d0
-#define GMC_DST_8BPP                               0x00000200
-#define GMC_DST_15BPP                              0x00000300
-#define GMC_DST_16BPP                              0x00000400
-#define GMC_DST_24BPP                              0x00000500
-#define GMC_DST_32BPP                              0x00000600
-#define GMC_DST_8BPP_RGB332                        0x00000700
-#define GMC_DST_8BPP_Y8                            0x00000800
-#define GMC_DST_8BPP_RGB8                          0x00000900
-#define GMC_DST_16BPP_VYUY422                      0x00000b00
-#define GMC_DST_16BPP_YVYU422                      0x00000c00
-#define GMC_DST_32BPP_AYUV444                      0x00000e00
-#define GMC_DST_16BPP_ARGB4444                     0x00000f00
-#define GMC_SRC_MONO                               0x00000000
-#define GMC_SRC_MONO_LBKGD                         0x00001000
-#define GMC_SRC_DSTCOLOR                           0x00003000
-#define GMC_BYTE_ORDER_MSB_TO_LSB                  0x00000000
-#define GMC_BYTE_ORDER_LSB_TO_MSB                  0x00004000
-#define GMC_DP_CONVERSION_TEMP_9300                0x00008000
-#define GMC_DP_CONVERSION_TEMP_6500                0x00000000
-#define GMC_DP_SRC_RECT                            0x02000000
-#define GMC_DP_SRC_HOST                            0x03000000
-#define GMC_DP_SRC_HOST_BYTEALIGN                  0x04000000
-#define GMC_3D_FCN_EN_CLR                          0x00000000
-#define GMC_3D_FCN_EN_SET                          0x08000000
-#define GMC_DST_CLR_CMP_FCN_LEAVE                  0x00000000
-#define GMC_DST_CLR_CMP_FCN_CLEAR                  0x10000000
-#define GMC_AUX_CLIP_LEAVE                         0x00000000
-#define GMC_AUX_CLIP_CLEAR                         0x20000000
-#define GMC_WRITE_MASK_LEAVE                       0x00000000
-#define GMC_WRITE_MASK_SET                         0x40000000
-#define GMC_CLR_CMP_CNTL_DIS      		   (1 << 28)
-#define GMC_SRC_DATATYPE_COLOR			   (3 << 12)
-#define ROP3_S                			   0x00cc0000
-#define ROP3_SRCCOPY				   0x00cc0000
-#define ROP3_P                			   0x00f00000
-#define ROP3_PATCOPY				   0x00f00000
-#define DP_SRC_SOURCE_MASK        		   (7    << 24)
-#define GMC_BRUSH_NONE            		   (15   <<  4)
-#define DP_SRC_SOURCE_MEMORY			   (2    << 24)
-#define GMC_BRUSH_SOLIDCOLOR			   0x000000d0
-
-/* DP_MIX bit constants */
-#define DP_SRC_RECT                                0x00000200
-#define DP_SRC_HOST                                0x00000300
-#define DP_SRC_HOST_BYTEALIGN                      0x00000400
-
-
-/* masks */
-
-#define CONFIG_MEMSIZE_MASK		0x1f000000
-#define MEM_CFG_TYPE			0x40000000
-#define DST_OFFSET_MASK			0x003fffff
-#define DST_PITCH_MASK			0x3fc00000
-#define DEFAULT_TILE_MASK		0xc0000000
-#define	PPLL_DIV_SEL_MASK		0x00000300
-#define	PPLL_RESET			0x00000001
-#define PPLL_ATOMIC_UPDATE_EN		0x00010000
-#define PPLL_REF_DIV_MASK		0x000003ff
-#define	PPLL_FB3_DIV_MASK		0x000007ff
-#define	PPLL_POST3_DIV_MASK		0x00070000
-#define PPLL_ATOMIC_UPDATE_R		0x00008000
-#define PPLL_ATOMIC_UPDATE_W		0x00008000
-#define	PPLL_VGA_ATOMIC_UPDATE_EN	0x00020000
-
-#define GUI_ACTIVE			0x80000000
-
-#endif	/* _RADEON_H */
-
diff -Nru a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c
--- a/drivers/video/radeonfb.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/video/radeonfb.c	Mon Dec  9 18:46:51 2002
@@ -2,7 +2,7 @@
  *	drivers/video/radeonfb.c
  *	framebuffer driver for ATI Radeon chipset video boards
  *
- *	Copyright 2000	Ani Joshi <ajoshi@unixbox.com>
+ *	Copyright 2000	Ani Joshi <ajoshi@kernel.crashing.org>
  *
  *
  *	ChangeLog:
@@ -15,13 +15,21 @@
  *			blanking, pan_display, and cmap fixes, 0.1.0
  *	2001-10-10	Radeon 7500 and 8500 support, and experimental
  *			flat panel support, 0.1.1
+ *	2001-11-17	Radeon M6 (ppc) support, Daniel Berlin, 0.1.2
+ *	2001-11-18	DFP fixes, Kevin Hendricks, 0.1.3
+ *	2001-11-29	more cmap, backlight fixes, Benjamin Herrenschmidt
+ *	2002-01-18	DFP panel detection via BIOS, Michael Clark, 0.1.4
+ *	2002-06-02	console switching, mode set fixes, accel fixes
+ *	2002-06-03	MTRR support, Peter Horton, 0.1.5
+ *	2002-09-21	rv250, r300, m9 initial support,
+ *			added mirror option, 0.1.6
  *
  *	Special thanks to ATI DevRel team for their hardware donations.
  *
  */
 
 
-#define RADEON_VERSION	"0.1.1"
+#define RADEON_VERSION	"0.1.6"
 
 
 #include <linux/config.h>
@@ -34,27 +42,45 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
-#include <linux/console.h>
-#include <linux/selection.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/vmalloc.h>
 
 #include <asm/io.h>
+#include <asm/uaccess.h>
 #if defined(__powerpc__)
 #include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include "macmodes.h"
+
+#ifdef CONFIG_NVRAM
+#include <linux/nvram.h>
 #endif
 
-#include <video/fbcon.h> 
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb24.h>
-#include <video/fbcon-cfb32.h>
+#ifdef CONFIG_PMAC_BACKLIGHT
+#include <asm/backlight.h>
+#endif
 
-#include "radeon.h"
+#ifdef CONFIG_BOOTX_TEXT
+#include <asm/btext.h>
+#endif
 
+#ifdef CONFIG_ADB_PMU
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#endif
 
-#define DEBUG	0
+#endif /* __powerpc__ */
+
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
+
+#include <video/radeon.h>
+#include <linux/radeonfb.h>
+
+#define DEBUG	1
 
 #if DEBUG
 #define RTRACE		printk
@@ -62,6 +88,8 @@
 #define RTRACE		if(0) printk
 #endif
 
+// XXX
+#undef CONFIG_PMAC_PBOOK
 
 
 enum radeon_chips {
@@ -71,11 +99,76 @@
 	RADEON_QG,
 	RADEON_QY,
 	RADEON_QZ,
-	RADEON_QL,
-	RADEON_QW,
 	RADEON_LW,
+	RADEON_LX,
 	RADEON_LY,
-	RADEON_LZ
+	RADEON_LZ,
+	RADEON_QL,
+	RADEON_QN,
+	RADEON_QO,
+	RADEON_Ql,
+	RADEON_BB,
+	RADEON_QW,
+	RADEON_QX,
+	RADEON_Id,
+	RADEON_Ie,
+	RADEON_If,
+	RADEON_Ig,
+	RADEON_Ld,
+	RADEON_Le,
+	RADEON_Lf,
+	RADEON_Lg,
+	RADEON_ND,
+	RADEON_NE,
+	RADEON_NF,
+	RADEON_NG
+};
+
+enum radeon_arch {
+	RADEON_R100,
+	RADEON_RV100,
+	RADEON_R200,
+	RADEON_RV200,
+	RADEON_RV250,
+	RADEON_R300,
+	RADEON_M6,
+	RADEON_M7,
+	RADEON_M9
+};
+
+static struct radeon_chip_info {
+	const char *name;
+	unsigned char arch;
+} radeon_chip_info[] __devinitdata = {
+	{ "QD", RADEON_R100 },
+	{ "QE", RADEON_R100 },
+	{ "QF", RADEON_R100 },
+	{ "QG", RADEON_R100 },
+	{ "VE QY", RADEON_RV100 },
+	{ "VE QZ", RADEON_RV100 },
+	{ "M7 LW", RADEON_M7 },
+	{ "M7 LX", RADEON_M7 },
+	{ "M6 LY", RADEON_M6 },
+	{ "M6 LZ", RADEON_M6 },
+	{ "8500 QL", RADEON_R200 },
+	{ "8500 QN", RADEON_R200 },
+	{ "8500 QO", RADEON_R200 },
+	{ "8500 Ql", RADEON_R200 },
+	{ "8500 BB", RADEON_R200 },
+	{ "7500 QW", RADEON_RV200 },
+	{ "7500 QX", RADEON_RV200 },
+	{ "9000 Id", RADEON_RV250 },
+	{ "9000 Ie", RADEON_RV250 },
+	{ "9000 If", RADEON_RV250 },
+	{ "9000 Ig", RADEON_RV250 },
+	{ "M9 Ld", RADEON_M9 },
+	{ "M9 Le", RADEON_M9 },
+	{ "M9 Lf", RADEON_M9 },
+	{ "M9 Lg", RADEON_M9 },
+	{ "9700 ND", RADEON_R300 },
+	{ "9700 NE", RADEON_R300 },
+	{ "9700 NF", RADEON_R300 },
+	{ "9700 NG", RADEON_R300 }
 };
 
 
@@ -91,17 +184,35 @@
 
 
 static struct pci_device_id radeonfb_pci_table[] __devinitdata = {
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QD},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QE},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QF},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QG},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QY},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QZ},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QL},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QW},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_LW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LW},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_LY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LY},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_LZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LZ},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QD},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QE},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QF},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QG},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QY},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QZ},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LW},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LX},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LY},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LZ},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QL},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QN, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QN},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QO},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ql, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ql},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_BB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_BB},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QW},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QX},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Id},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ie, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ie},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_If, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_If},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ig, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ig},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ld, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ld},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Le, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Le},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Lf, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Lf},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Lg, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Lg},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_ND, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_ND},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NE},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NF},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NG},
 	{ 0, }
 };
 MODULE_DEVICE_TABLE(pci, radeonfb_pci_table);
@@ -128,7 +239,15 @@
 	{ CAP0_TRIG_CNTL, 0 },
 };
 
-#define COMMON_REGS_SIZE = (sizeof(common_regs)/sizeof(common_regs[0]))
+reg_val common_regs_m6[] = {
+	{ OVR_CLR,      0 },
+	{ OVR_WID_LEFT_RIGHT,   0 },
+	{ OVR_WID_TOP_BOTTOM,   0 },
+	{ OV0_SCALE_CNTL,   0 },
+	{ SUBPIC_CNTL,      0 },
+	{ GEN_INT_CNTL,     0 },
+	{ CAP0_TRIG_CNTL,   0 } 
+};
 
 typedef struct {
         u8 clock_chip_type;
@@ -192,7 +311,6 @@
 	u32 flags;
 	u32 pix_clock;
 	int xres, yres;
-	int bpp;
 
 	/* DDA regs */
 	u32 dda_config;
@@ -201,7 +319,8 @@
 	/* PLL regs */
 	u32 ppll_div_3;
 	u32 ppll_ref_div;
-
+	u32 vclk_ecp_cntl;
+	
 	/* Flat panel regs */
 	u32 fp_crtc_h_total_disp;
 	u32 fp_crtc_v_total_disp;
@@ -214,6 +333,7 @@
 	u32 lvds_gen_cntl;
 	u32 lvds_pll_cntl;
 	u32 tmds_crc;
+	u32 tmds_transmitter_cntl;
 
 #if defined(__BIG_ENDIAN)
 	u32 surface_cntl;
@@ -227,35 +347,47 @@
 	struct radeon_regs state;
 	struct radeon_regs init_state;
 
-	char name[17];
+	char name[32];
 	char ram_type[12];
 
-	u32 mmio_base_phys;
-	u32 fb_base_phys;
+	unsigned long mmio_base_phys;
+	unsigned long fb_base_phys;
 
-	u32 mmio_base;
-	u32 fb_base;
+	unsigned long mmio_base;
+	unsigned long fb_base;
 
 	struct pci_dev *pdev;
 
-	struct display disp;
-	struct display *currcon_display;
+	unsigned char *EDID;
+	unsigned char *bios_seg;
+
+	struct display disp; /* Will disappear */
 
+	u32 pseudo_palette[17];
 	struct { u8 red, green, blue, pad; } palette[256];
 
 	int chipset;
+	unsigned char arch;
 	int video_ram;
 	u8 rev;
 	int pitch, bpp, depth;
 	int xres, yres, pixclock;
+	int xres_virtual, yres_virtual;
+	u32 accel_flags;
+
+	int use_default_var;
+	int got_dfpinfo;
 
 	int hasCRTC2;
 	int crtDisp_type;
 	int dviDisp_type;
 
 	int panel_xres, panel_yres;
+	int clock;
 	int hOver_plus, hSync_width, hblank;
 	int vOver_plus, vSync_width, vblank;
+	int hAct_high, vAct_high, interlaced;
+	int synct, misc;
 
 	u32 dp_gui_master_cntl;
 
@@ -264,22 +396,16 @@
 
 	struct ram_info ram;
 
-        u32 hack_crtc_ext_cntl;
-        u32 hack_crtc_v_sync_strt_wid;
+	int mtrr_hdl;
 
-#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
-        union {
-#if defined(FBCON_HAS_CFB16)
-                u_int16_t cfb16[16];
-#endif
-#if defined(FBCON_HAS_CFB24)
-                u_int32_t cfb24[16];
-#endif  
-#if defined(FBCON_HAS_CFB32)
-                u_int32_t cfb32[16];
-#endif  
-        } con_cmap;
-#endif  
+#ifdef CONFIG_PMAC_PBOOK
+	int pm_reg;
+	u32 save_regs[64];
+	u32 mdll, mdll2;
+#endif /* CONFIG_PMAC_PBOOK */
+	int asleep;
+	
+	struct radeonfb_info *next;
 };
 
 
@@ -290,7 +416,6 @@
         0, FB_VMODE_NONINTERLACED
 };
 
-
 /*
  * IO macros
  */
@@ -300,8 +425,12 @@
 #define INREG(addr)		readl((rinfo->mmio_base)+addr)
 #define OUTREG(addr,val)	writel(val, (rinfo->mmio_base)+addr)
 
-#define OUTPLL(addr,val)	OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000001f) | 0x00000080); \
-				OUTREG(CLOCK_CNTL_DATA, val)
+#define OUTPLL(addr,val)	\
+	do {	\
+		OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000003f) | 0x00000080); \
+		OUTREG(CLOCK_CNTL_DATA, val); \
+	} while(0)
+
 #define OUTPLLP(addr,val,mask)  					\
 	do {								\
 		unsigned int _tmp = INPLL(addr);			\
@@ -321,7 +450,7 @@
 
 static __inline__ u32 _INPLL(struct radeonfb_info *rinfo, u32 addr)
 {
-	OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000001f);
+	OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f);
 	return (INREG(CLOCK_CNTL_DATA));
 }
 
@@ -432,6 +561,14 @@
 }
 
 
+static inline int var_to_depth(const struct fb_var_screeninfo *var)
+{
+	if (var->bits_per_pixel != 16)
+		return var->bits_per_pixel;
+	return (var->green.length == 6) ? 16 : 15;
+}
+
+
 static void _radeon_engine_reset(struct radeonfb_info *rinfo)
 {
 	u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
@@ -457,8 +594,7 @@
 				SOFT_RESET_RE |
 				SOFT_RESET_PP |
 				SOFT_RESET_E2 |
-				SOFT_RESET_RB |
-				SOFT_RESET_HDP);
+				SOFT_RESET_RB);
 	INREG(RBBM_SOFT_RESET);
 	OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset & (u32)
 				~(SOFT_RESET_CP |
@@ -467,8 +603,7 @@
 				  SOFT_RESET_RE |
 				  SOFT_RESET_PP |
 				  SOFT_RESET_E2 |
-				  SOFT_RESET_RB |
-				  SOFT_RESET_HDP));
+				  SOFT_RESET_RB));
 	INREG(RBBM_SOFT_RESET);
 
 	OUTPLL(MCLK_CNTL, mclk_cntl);
@@ -542,416 +677,57 @@
  * globals
  */
         
-static char fontname[40] __initdata;
 static char *mode_option __initdata;
-static char noaccel __initdata = 0;
-static char panel_yres __initdata = 0;
-
-#ifdef FBCON_HAS_CFB8
-static struct display_switch fbcon_radeon8;
-#endif
-
+static char noaccel = 1;
+static char mirror = 0;
+static int panel_yres __initdata = 0;
+static char force_dfp __initdata = 0;
+static struct radeonfb_info *board_list = NULL;
+static char nomtrr __initdata = 0;
 
 /*
  * prototypes
  */
 
-static int radeonfb_get_fix (struct fb_fix_screeninfo *fix, int con,
-                             struct fb_info *info);
-static int radeonfb_get_var (struct fb_var_screeninfo *var, int con,
-                             struct fb_info *info);
-static int radeonfb_set_var (struct fb_var_screeninfo *var, int con,
-                             struct fb_info *info);
-static int radeonfb_get_cmap (struct fb_cmap *cmap, int kspc, int con,
-                              struct fb_info *info);
-static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green,
-                               unsigned blue, unsigned transp, struct fb_info *info);
-static int radeonfb_pan_display (struct fb_var_screeninfo *var, int con,
-                                 struct fb_info *info);
-static int radeonfb_blank (int blank, struct fb_info *info);
-static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
-                           unsigned long arg, int con, struct fb_info *info);
-static int radeonfb_switch (int con, struct fb_info *info);
-static int radeonfb_updatevar (int con, struct fb_info *info);
-static int radeon_get_cmap_len (const struct fb_var_screeninfo *var);
-static int radeon_getcolreg (unsigned regno, unsigned *red, unsigned *green,
-                             unsigned *blue, unsigned *transp,
-                             struct fb_info *info);
-static void radeon_set_dispsw (struct radeonfb_info *rinfo, struct display *disp);
 static void radeon_save_state (struct radeonfb_info *rinfo,
                                struct radeon_regs *save);
 static void radeon_engine_init (struct radeonfb_info *rinfo);
-static void radeon_load_video_mode (struct radeonfb_info *rinfo,
-                                    struct fb_var_screeninfo *mode);
 static void radeon_write_mode (struct radeonfb_info *rinfo,
                                struct radeon_regs *mode);
 static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo);
 static int __devinit radeon_init_disp (struct radeonfb_info *rinfo);
-static int radeon_init_disp_var (struct radeonfb_info *rinfo);
-static int radeonfb_pci_register (struct pci_dev *pdev,
-                                 const struct pci_device_id *ent);
-static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev);
+static int radeon_init_disp_var (struct radeonfb_info *rinfo, struct fb_var_screeninfo *var);
 static char *radeon_find_rom(struct radeonfb_info *rinfo);
 static void radeon_get_pllinfo(struct radeonfb_info *rinfo, char *bios_seg);
 static void radeon_get_moninfo (struct radeonfb_info *rinfo);
 static int radeon_get_dfpinfo (struct radeonfb_info *rinfo);
-static int radeon_read_OF (struct radeonfb_info *rinfo);
+static int radeon_get_dfpinfo_BIOS(struct radeonfb_info *rinfo);
+static void radeon_get_EDID(struct radeonfb_info *rinfo);
+static int radeon_dfp_parse_EDID(struct radeonfb_info *rinfo);
+static void radeon_update_default_var(struct radeonfb_info *rinfo);
 
-#if defined(__powerpc__)
+#ifdef CONFIG_ALL_PPC
+
+static int radeon_read_OF (struct radeonfb_info *rinfo);
+static int radeon_get_EDID_OF(struct radeonfb_info *rinfo);
 extern struct device_node *pci_device_to_OF_node(struct pci_dev *dev);
-#endif
 
-static struct fb_ops radeon_fb_ops = {
-	.fb_get_fix =		radeonfb_get_fix,
-	.fb_get_var =		radeonfb_get_var,
-	.fb_set_var =		radeonfb_set_var,
-	.fb_get_cmap =		radeonfb_get_cmap,
-	.fb_set_cmap =		gen_set_cmap,
-	.fb_setcolreg =		radeonfb_setcolreg,
-	.fb_pan_display =	radeonfb_pan_display,
-	.fb_blank =		radeonfb_blank,
-	.fb_ioctl =		radeonfb_ioctl,
+#ifdef CONFIG_PMAC_PBOOK
+int radeon_sleep_notify(struct pmu_sleep_notifier *self, int when);
+static struct pmu_sleep_notifier radeon_sleep_notifier = {
+	radeon_sleep_notify, SLEEP_LEVEL_VIDEO,
 };
-
-
-static struct pci_driver radeonfb_driver = {
-	.name =		"radeonfb",
-	.id_table =	radeonfb_pci_table,
-	.probe =	radeonfb_pci_register,
-	.remove =	__devexit_p(radeonfb_pci_unregister),
+#endif /* CONFIG_PMAC_PBOOK */
+#ifdef CONFIG_PMAC_BACKLIGHT
+static int radeon_set_backlight_enable(int on, int level, void *data);
+static int radeon_set_backlight_level(int level, void *data);
+static struct backlight_controller radeon_backlight_controller = {
+	radeon_set_backlight_enable,
+	radeon_set_backlight_level
 };
+#endif /* CONFIG_PMAC_BACKLIGHT */
 
-
-int __init radeonfb_init (void)
-{
-	return pci_module_init (&radeonfb_driver);
-}
-
-
-void __exit radeonfb_exit (void)
-{
-	pci_unregister_driver (&radeonfb_driver);
-}
-
-
-int __init radeonfb_setup (char *options)
-{
-        char *this_opt;
-
-        if (!options || !*options)
-                return 0;
- 
-	while ((this_opt = strsep (&options, ",")) != NULL) {
-		if (!*this_opt)
-			continue;
-                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);
-                } else if (!strncmp(this_opt, "noaccel", 7)) {
-			noaccel = 1;
-		} else if (!strncmp(this_opt, "panel_yres:", 11)) {
-			panel_yres = simple_strtoul((this_opt+11), NULL, 0);
-                } else
-			mode_option = this_opt;
-        }
-
-	return 0;
-}
-
-#ifdef MODULE
-module_init(radeonfb_init);
-module_exit(radeonfb_exit);
-#endif
-
-
-MODULE_AUTHOR("Ani Joshi");
-MODULE_DESCRIPTION("framebuffer driver for ATI Radeon chipset");
-MODULE_LICENSE("GPL");
-
-static int radeonfb_pci_register (struct pci_dev *pdev,
-				  const struct pci_device_id *ent)
-{
-	struct radeonfb_info *rinfo;
-	u32 tmp;
-	int i, j;
-	char *bios_seg = NULL;
-
-	RTRACE("radeonfb_pci_register BEGIN\n");
-
-	rinfo = kmalloc (sizeof (struct radeonfb_info), GFP_KERNEL);
-	if (!rinfo) {
-		printk ("radeonfb: could not allocate memory\n");
-		return -ENODEV;
-	}
-
-	memset (rinfo, 0, sizeof (struct radeonfb_info));
-
-	rinfo->pdev = pdev;
-
-	/* enable device */
-	{
-		int err;
-
-		if ((err = pci_enable_device(pdev))) {
-			printk("radeonfb: cannot enable device\n");
-			kfree (rinfo);
-			return -ENODEV;
-		}
-	}
-
-	/* set base addrs */
-	rinfo->fb_base_phys = pci_resource_start (pdev, 0);
-	rinfo->mmio_base_phys = pci_resource_start (pdev, 2);
-
-	/* request the mem regions */
-	if (!request_mem_region (rinfo->fb_base_phys,
-				 pci_resource_len(pdev, 0), "radeonfb")) {
-		printk ("radeonfb: cannot reserve FB region\n");
-		kfree (rinfo);
-		return -ENODEV;
-	}
-
-	if (!request_mem_region (rinfo->mmio_base_phys,
-				 pci_resource_len(pdev, 2), "radeonfb")) {
-		printk ("radeonfb: cannot reserve MMIO region\n");
-		release_mem_region (rinfo->fb_base_phys,
-				    pci_resource_len(pdev, 0));
-		kfree (rinfo);
-		return -ENODEV;
-	}
-
-	/* map the regions */
-	rinfo->mmio_base = (u32) ioremap (rinfo->mmio_base_phys,
-				    		    RADEON_REGSIZE);
-	if (!rinfo->mmio_base) {
-		printk ("radeonfb: cannot map MMIO\n");
-		release_mem_region (rinfo->mmio_base_phys,
-				    pci_resource_len(pdev, 2));
-		release_mem_region (rinfo->fb_base_phys,
-				    pci_resource_len(pdev, 0));
-		kfree (rinfo);
-		return -ENODEV;
-	}
-
-	rinfo->chipset = pdev->device;
-
-	/* chipset */
-	switch (pdev->device) {
-		case PCI_DEVICE_ID_RADEON_QD:
-			strcpy(rinfo->name, "Radeon QD ");
-			break;
-		case PCI_DEVICE_ID_RADEON_QE:
-			strcpy(rinfo->name, "Radeon QE ");
-			break;
-		case PCI_DEVICE_ID_RADEON_QF:
-			strcpy(rinfo->name, "Radeon QF ");
-			break;
-		case PCI_DEVICE_ID_RADEON_QG:
-			strcpy(rinfo->name, "Radeon QG ");
-			break;
-		case PCI_DEVICE_ID_RADEON_QY:
-			strcpy(rinfo->name, "Radeon QY VE ");
-			rinfo->hasCRTC2 = 1;
-			break;
-		case PCI_DEVICE_ID_RADEON_QZ:
-			strcpy(rinfo->name, "Radeon QZ VE ");
-			rinfo->hasCRTC2 = 1;
-			break;
-		case PCI_DEVICE_ID_RADEON_QW:
-			strcpy(rinfo->name, "Radeon 7500 QW ");
-			rinfo->hasCRTC2 = 1;
-			break;
-		case PCI_DEVICE_ID_RADEON_QL:
-			strcpy(rinfo->name, "Radeon 8500 QL ");
-			rinfo->hasCRTC2 = 1;
-			break;
-		case PCI_DEVICE_ID_RADEON_LW:
-			strcpy(rinfo->name, "Radeon M7 LW ");
-			rinfo->hasCRTC2 = 1;
-			break;
-		case PCI_DEVICE_ID_RADEON_LY:
-			strcpy(rinfo->name, "Radeon M6 LY ");
-			rinfo->hasCRTC2 = 1;
-			break;
-		case PCI_DEVICE_ID_RADEON_LZ:
-			strcpy(rinfo->name, "Radeon M6 LZ ");
-			rinfo->hasCRTC2 = 1;
-			break;
-		default:
-			return -ENODEV;
-	}
-
-	/* framebuffer size */
-	tmp = INREG(CONFIG_MEMSIZE);
-
-	/* mem size is bits [28:0], mask off the rest */
-	rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
-
-	/* ram type */
-	tmp = INREG(MEM_SDRAM_MODE_REG);
-	switch ((MEM_CFG_TYPE & tmp) >> 30) {
-		case 0:
-			/* SDR SGRAM (2:1) */
-			strcpy(rinfo->ram_type, "SDR SGRAM");
-			rinfo->ram.ml = 4;
-			rinfo->ram.mb = 4;
-			rinfo->ram.trcd = 1;
-			rinfo->ram.trp = 2;
-			rinfo->ram.twr = 1;
-			rinfo->ram.cl = 2;
-			rinfo->ram.loop_latency = 16;
-			rinfo->ram.rloop = 16;
-	
-			break;
-		case 1:
-			/* DDR SGRAM */
-			strcpy(rinfo->ram_type, "DDR SGRAM");
-			rinfo->ram.ml = 4;
-			rinfo->ram.mb = 4;
-			rinfo->ram.trcd = 3;
-			rinfo->ram.trp = 3;
-			rinfo->ram.twr = 2;
-			rinfo->ram.cl = 3;
-			rinfo->ram.tr2w = 1;
-			rinfo->ram.loop_latency = 16;
-			rinfo->ram.rloop = 16;
-
-			break;
-		default:
-			/* 64-bit SDR SGRAM */
-			strcpy(rinfo->ram_type, "SDR SGRAM 64");
-			rinfo->ram.ml = 4;
-			rinfo->ram.mb = 8;
-			rinfo->ram.trcd = 3;
-			rinfo->ram.trp = 3;
-			rinfo->ram.twr = 1;
-			rinfo->ram.cl = 3;
-			rinfo->ram.tr2w = 1;
-			rinfo->ram.loop_latency = 17;
-			rinfo->ram.rloop = 17;
-
-			break;
-	}
-
-	bios_seg = radeon_find_rom(rinfo);
-	radeon_get_pllinfo(rinfo, bios_seg);
-
-	RTRACE("radeonfb: probed %s %dk videoram\n", (rinfo->ram_type), (rinfo->video_ram/1024));
-
-	radeon_get_moninfo(rinfo);
-	if ((rinfo->dviDisp_type == MT_DFP) || (rinfo->dviDisp_type == MT_LCD) ||
-	    (rinfo->crtDisp_type == MT_DFP)) {
-		if (!radeon_get_dfpinfo(rinfo)) {
-			iounmap ((void*)rinfo->mmio_base);
-			release_mem_region (rinfo->mmio_base_phys,
-					    pci_resource_len(pdev, 2));
-			release_mem_region (rinfo->fb_base_phys,
-					    pci_resource_len(pdev, 0));
-			kfree (rinfo);
-			return -ENODEV;
-		}
-	}
-
-	rinfo->fb_base = (u32) ioremap (rinfo->fb_base_phys,
-				  		  rinfo->video_ram);
-	if (!rinfo->fb_base) {
-		printk ("radeonfb: cannot map FB\n");
-		iounmap ((void*)rinfo->mmio_base);
-		release_mem_region (rinfo->mmio_base_phys,
-				    pci_resource_len(pdev, 2));
-		release_mem_region (rinfo->fb_base_phys,
-				    pci_resource_len(pdev, 0));
-		kfree (rinfo);
-		return -ENODEV;
-	}
-
-	/* XXX turn off accel for now, blts aren't working right */
-	noaccel = 1;
-
-	/* set all the vital stuff */
-	radeon_set_fbinfo (rinfo);
-
-	/* save current mode regs before we switch into the new one
-	 * so we can restore this upon __exit
-	 */
-	radeon_save_state (rinfo, &rinfo->init_state);
-
-	/* init palette */
-	for (i=0; i<16; i++) {
-		j = color_table[i];
-		rinfo->palette[i].red = default_red[j];
-		rinfo->palette[i].green = default_grn[j];
-		rinfo->palette[i].blue = default_blu[j];
-	}
-
-	pci_set_drvdata(pdev, rinfo);
-
-	if (register_framebuffer ((struct fb_info *) rinfo) < 0) {
-		printk ("radeonfb: could not register framebuffer\n");
-		iounmap ((void*)rinfo->fb_base);
-		iounmap ((void*)rinfo->mmio_base);
-		release_mem_region (rinfo->mmio_base_phys,
-				    pci_resource_len(pdev, 2));
-		release_mem_region (rinfo->fb_base_phys,
-				    pci_resource_len(pdev, 0));
-		kfree (rinfo);
-		return -ENODEV;
-	}
-
-	if (!noaccel) {
-		/* initialize the engine */
-		radeon_engine_init (rinfo);
-	}
-
-	printk ("radeonfb: ATI %s %s %d MB\n", rinfo->name, rinfo->ram_type,
-		(rinfo->video_ram/(1024*1024)));
-
-	if (rinfo->hasCRTC2) {
-		printk("radeonfb: DVI port %s monitor connected\n",
-			GET_MON_NAME(rinfo->dviDisp_type));
-		printk("radeonfb: CRT port %s monitor connected\n",
-			GET_MON_NAME(rinfo->crtDisp_type));
-	} else {
-		printk("radeonfb: CRT port %s monitor connected\n",
-			GET_MON_NAME(rinfo->crtDisp_type));
-	}
-
-	RTRACE("radeonfb_pci_register END\n");
-
-	return 0;
-}
-
-
-
-static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
-{
-        struct radeonfb_info *rinfo = pci_get_drvdata(pdev);
- 
-        if (!rinfo)
-                return;
- 
-	/* restore original state */
-        radeon_write_mode (rinfo, &rinfo->init_state);
- 
-        unregister_framebuffer ((struct fb_info *) rinfo);
-                
-        iounmap ((void*)rinfo->mmio_base);
-        iounmap ((void*)rinfo->fb_base);
- 
-	release_mem_region (rinfo->mmio_base_phys,
-			    pci_resource_len(pdev, 2));
-	release_mem_region (rinfo->fb_base_phys,
-			    pci_resource_len(pdev, 0));
-        
-        kfree (rinfo);
-}
-
+#endif /* CONFIG_ALL_PPC */
 
 
 static char *radeon_find_rom(struct radeonfb_info *rinfo)
@@ -1053,7 +829,7 @@
 		printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from BIOS\n",
 			rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
 	} else {
-#if defined(__powerpc__)
+#ifdef CONFIG_ALL_PPC
 		if (radeon_read_OF(rinfo)) {
 			unsigned int tmp, Nx, M, ref_div, xclk;
 
@@ -1078,24 +854,39 @@
 #endif
 		/* no BIOS or BIOS not found, use defaults */
 		switch (rinfo->chipset) {
-			case PCI_DEVICE_ID_RADEON_QW:
+			case PCI_DEVICE_ID_ATI_RADEON_QW:
+			case PCI_DEVICE_ID_ATI_RADEON_QX:
 				rinfo->pll.ppll_max = 35000;
 				rinfo->pll.ppll_min = 12000;
 				rinfo->pll.xclk = 23000;
 				rinfo->pll.ref_div = 12;
 				rinfo->pll.ref_clk = 2700;
 				break;
-			case PCI_DEVICE_ID_RADEON_QL:
+			case PCI_DEVICE_ID_ATI_RADEON_QL:
+			case PCI_DEVICE_ID_ATI_RADEON_QN:
+			case PCI_DEVICE_ID_ATI_RADEON_QO:
+			case PCI_DEVICE_ID_ATI_RADEON_Ql:
+			case PCI_DEVICE_ID_ATI_RADEON_BB:
 				rinfo->pll.ppll_max = 35000;
 				rinfo->pll.ppll_min = 12000;
 				rinfo->pll.xclk = 27500;
 				rinfo->pll.ref_div = 12;
 				rinfo->pll.ref_clk = 2700;
 				break;
-			case PCI_DEVICE_ID_RADEON_QD:
-			case PCI_DEVICE_ID_RADEON_QE:
-			case PCI_DEVICE_ID_RADEON_QF:
-			case PCI_DEVICE_ID_RADEON_QG:
+			case PCI_DEVICE_ID_ATI_RADEON_Id:
+			case PCI_DEVICE_ID_ATI_RADEON_Ie:
+			case PCI_DEVICE_ID_ATI_RADEON_If:
+			case PCI_DEVICE_ID_ATI_RADEON_Ig:
+				rinfo->pll.ppll_max = 35000;
+				rinfo->pll.ppll_min = 12000;
+				rinfo->pll.xclk = 25000;
+				rinfo->pll.ref_div = 12;
+				rinfo->pll.ref_clk = 2700;
+				break;
+			case PCI_DEVICE_ID_ATI_RADEON_QD:
+			case PCI_DEVICE_ID_ATI_RADEON_QE:
+			case PCI_DEVICE_ID_ATI_RADEON_QF:
+			case PCI_DEVICE_ID_ATI_RADEON_QG:
 			default:
 				rinfo->pll.ppll_max = 35000;
 				rinfo->pll.ppll_min = 12000;
@@ -1115,8 +906,14 @@
 {
 	unsigned int tmp;
 
-	tmp = INREG(RADEON_BIOS_4_SCRATCH);
+	if (force_dfp) {
+		rinfo->dviDisp_type = MT_DFP;
+		return;
+	}
 
+	tmp = INREG(RADEON_BIOS_4_SCRATCH);
+	printk(KERN_DEBUG "radeon_get_moninfo: bios 4 scratch = %x\n", tmp);
+	
 	if (rinfo->hasCRTC2) {
 		/* primary DVI port */
 		if (tmp & 0x08)
@@ -1154,74 +951,254 @@
 }
 
 
-static int radeon_get_dfpinfo (struct radeonfb_info *rinfo)
+
+static void radeon_get_EDID(struct radeonfb_info *rinfo)
 {
-	unsigned int tmp;
-	unsigned short a, b;
+#ifdef CONFIG_ALL_PPC
+	if (!radeon_get_EDID_OF(rinfo))
+		RTRACE("radeonfb: could not retrieve EDID from OF\n");
+#else
+	/* XXX use other methods later */
+#endif
+}
 
-	if (panel_yres) {
-		rinfo->panel_yres = panel_yres;
-	} else {
-		tmp = INREG(FP_VERT_STRETCH);
-		tmp &= 0x00fff000;
-		rinfo->panel_yres = (unsigned short)(tmp >> 0x0c) + 1;
-	}
 
-	switch (rinfo->panel_yres) {
-		case 480:
-			rinfo->panel_xres = 640;
-			break;
-		case 600:
-			rinfo->panel_xres = 800;
-			break;
-		case 786:
-			rinfo->panel_xres = 1024;
-			break;
-		case 1024:
-			rinfo->panel_xres = 1280;
-			break;
-		case 1050:
-			rinfo->panel_xres = 1400;
-			break;
-		case 1200:
-			rinfo->panel_xres = 1600;
-			break;
-		default:
-			printk("radeonfb: Failed to detect DFP panel size\n");
-			return 0;
+#ifdef CONFIG_ALL_PPC
+static int radeon_get_EDID_OF(struct radeonfb_info *rinfo)
+{
+        struct device_node *dp;
+        unsigned char *pedid = NULL;
+        static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID", "EDID1", NULL };
+        int i;  
+
+        dp = pci_device_to_OF_node(rinfo->pdev);
+        while (dp != NULL) {
+                for (i = 0; propnames[i] != NULL; ++i) {
+                        pedid = (unsigned char *)
+                                get_property(dp, propnames[i], NULL);
+                        if (pedid != NULL) {
+                                rinfo->EDID = pedid;
+                                return 1;
+                        }
+                }
+                dp = dp->child;
+        }
+        return 0;
+}
+#endif /* CONFIG_ALL_PPC */
+
+
+static int radeon_dfp_parse_EDID(struct radeonfb_info *rinfo)
+{
+	unsigned char *block = rinfo->EDID;
+
+	if (!block)
+		return 0;
+
+	/* jump to the detailed timing block section */
+	block += 54;
+
+	rinfo->clock = (block[0] + (block[1] << 8));
+	rinfo->panel_xres = (block[2] + ((block[4] & 0xf0) << 4));
+	rinfo->hblank = (block[3] + ((block[4] & 0x0f) << 8));
+	rinfo->panel_yres = (block[5] + ((block[7] & 0xf0) << 4));
+	rinfo->vblank = (block[6] + ((block[7] & 0x0f) << 8));
+	rinfo->hOver_plus = (block[8] + ((block[11] & 0xc0) << 2));
+	rinfo->hSync_width = (block[9] + ((block[11] & 0x30) << 4));
+	rinfo->vOver_plus = ((block[10] >> 4) + ((block[11] & 0x0c) << 2));
+	rinfo->vSync_width = ((block[10] & 0x0f) + ((block[11] & 0x03) << 4));
+	rinfo->interlaced = ((block[17] & 0x80) >> 7);
+	rinfo->synct = ((block[17] & 0x18) >> 3);
+	rinfo->misc = ((block[17] & 0x06) >> 1);
+	rinfo->hAct_high = rinfo->vAct_high = 0;
+	if (rinfo->synct == 3) {
+		if (rinfo->misc & 2)
+			rinfo->hAct_high = 1;
+		if (rinfo->misc & 1)
+			rinfo->vAct_high = 1;
 	}
 
-	printk("radeonfb: detected DFP panel size: %dx%d\n",
+	printk("radeonfb: detected DFP panel size from EDID: %dx%d\n",
 		rinfo->panel_xres, rinfo->panel_yres);
 
-	tmp = INREG(FP_CRTC_H_TOTAL_DISP);
-	a = (tmp & FP_CRTC_H_TOTAL_MASK) + 4;
-	b = (tmp & 0x01ff0000) >> FP_CRTC_H_DISP_SHIFT;
-	rinfo->hblank = (a - b + 1) * 8;
-
-	tmp = INREG(FP_H_SYNC_STRT_WID);
-	rinfo->hOver_plus = (unsigned short) ((tmp & FP_H_SYNC_STRT_CHAR_MASK) >>
-				FP_H_SYNC_STRT_CHAR_SHIFT) - b - 1;
-	rinfo->hOver_plus *= 8;
-	rinfo->hSync_width = (unsigned short) ((tmp & FP_H_SYNC_WID_MASK) >>
-				FP_H_SYNC_WID_SHIFT);
-	rinfo->hSync_width *= 8;
-	tmp = INREG(FP_CRTC_V_TOTAL_DISP);
-	a = (tmp & FP_CRTC_V_TOTAL_MASK) + 1;
-	b = (tmp & FP_CRTC_V_DISP_MASK) >> FP_CRTC_V_DISP_SHIFT;
-	rinfo->vblank = a - b /* + 24 */ ;
-
-	tmp = INREG(FP_V_SYNC_STRT_WID);
-	rinfo->vOver_plus = (unsigned short) (tmp & FP_V_SYNC_STRT_MASK)
-				- b + 1;
-	rinfo->vSync_width = (unsigned short) ((tmp & FP_V_SYNC_WID_MASK) >>
-				FP_V_SYNC_WID_SHIFT);
+	rinfo->got_dfpinfo = 1;
 
 	return 1;
 }
 
 
+static void radeon_update_default_var(struct radeonfb_info *rinfo)
+{
+	struct fb_var_screeninfo *var = &radeonfb_default_var;
+
+	var->xres = rinfo->panel_xres;
+	var->yres = rinfo->panel_yres;
+	var->xres_virtual = rinfo->panel_xres;
+	var->yres_virtual = rinfo->panel_yres;
+	var->xoffset = var->yoffset = 0;
+	var->bits_per_pixel = 8;
+	var->pixclock = 100000000 / rinfo->clock;
+	var->left_margin = (rinfo->hblank - rinfo->hOver_plus - rinfo->hSync_width);
+	var->right_margin = rinfo->hOver_plus;
+	var->upper_margin = (rinfo->vblank - rinfo->vOver_plus - rinfo->vSync_width);
+	var->lower_margin = rinfo->vOver_plus;
+	var->hsync_len = rinfo->hSync_width;
+	var->vsync_len = rinfo->vSync_width;
+	var->sync = 0;
+	if (rinfo->synct == 3) {
+		if (rinfo->hAct_high)
+			var->sync |= FB_SYNC_HOR_HIGH_ACT;
+		if (rinfo->vAct_high)
+			var->sync |= FB_SYNC_VERT_HIGH_ACT;
+	}
+
+	var->vmode = 0;
+	if (rinfo->interlaced)
+		var->vmode |= FB_VMODE_INTERLACED;
+
+	rinfo->use_default_var = 1;
+}
+
+
+static int radeon_get_dfpinfo_BIOS(struct radeonfb_info *rinfo)
+{
+	char *fpbiosstart, *tmp, *tmp0;
+	char stmp[30];
+	int i;
+
+	if (!rinfo->bios_seg)
+		return 0;
+
+	if (!(fpbiosstart = rinfo->bios_seg + readw(rinfo->bios_seg + 0x48))) {
+		printk("radeonfb: Failed to detect DFP panel info using BIOS\n");
+		return 0;
+	}
+
+	if (!(tmp = rinfo->bios_seg + readw(fpbiosstart + 0x40))) {
+		printk("radeonfb: Failed to detect DFP panel info using BIOS\n");
+		return 0;
+	}
+
+	for(i=0; i<24; i++)
+		stmp[i] = readb(tmp+i+1);
+	stmp[24] = 0;
+	printk("radeonfb: panel ID string: %s\n", stmp);
+	rinfo->panel_xres = readw(tmp + 25);
+	rinfo->panel_yres = readw(tmp + 27);
+	printk("radeonfb: detected DFP panel size from BIOS: %dx%d\n",
+		rinfo->panel_xres, rinfo->panel_yres);
+
+	for(i=0; i<20; i++) {
+		tmp0 = rinfo->bios_seg + readw(tmp+64+i*2);
+		if (tmp0 == 0)
+			break;
+		if ((readw(tmp0) == rinfo->panel_xres) &&
+		    (readw(tmp0+2) == rinfo->panel_yres)) {
+			rinfo->hblank = (readw(tmp0+17) - readw(tmp0+19)) * 8;
+			rinfo->hOver_plus = ((readw(tmp0+21) - readw(tmp0+19) -1) * 8) & 0x7fff;
+			rinfo->hSync_width = readb(tmp0+23) * 8;
+			rinfo->vblank = readw(tmp0+24) - readw(tmp0+26);
+			rinfo->vOver_plus = (readw(tmp0+28) & 0x7ff) - readw(tmp0+26);
+			rinfo->vSync_width = (readw(tmp0+28) & 0xf800) >> 11;
+			rinfo->clock = readw(tmp0+9);
+
+			rinfo->got_dfpinfo = 1;
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+
+
+static int radeon_get_dfpinfo (struct radeonfb_info *rinfo)
+{
+	unsigned int tmp;
+	unsigned short a, b;
+
+	if (radeon_get_dfpinfo_BIOS(rinfo))
+		radeon_update_default_var(rinfo);
+
+	if (radeon_dfp_parse_EDID(rinfo))
+		radeon_update_default_var(rinfo);
+
+	if (!rinfo->got_dfpinfo) {
+		/*
+		 * it seems all else has failed now and we
+		 * resort to probing registers for our DFP info
+	         */
+		if (panel_yres) {
+			rinfo->panel_yres = panel_yres;
+		} else {
+			tmp = INREG(FP_VERT_STRETCH);
+			tmp &= 0x00fff000;
+			rinfo->panel_yres = (unsigned short)(tmp >> 0x0c) + 1;
+		}
+
+		switch (rinfo->panel_yres) {
+			case 480:
+				rinfo->panel_xres = 640;
+				break;
+			case 600:
+				rinfo->panel_xres = 800;
+				break;
+			case 768:
 #if defined(__powerpc__)
+				if (rinfo->dviDisp_type == MT_LCD)
+					rinfo->panel_xres = 1152;
+				else
+#endif
+				rinfo->panel_xres = 1024;
+				break;
+			case 1024:
+				rinfo->panel_xres = 1280;
+				break;
+			case 1050:
+				rinfo->panel_xres = 1400;
+				break;
+			case 1200:
+				rinfo->panel_xres = 1600;
+				break;
+			default:
+				printk("radeonfb: Failed to detect DFP panel size\n");
+				return 0;
+		}
+
+		printk("radeonfb: detected DFP panel size from registers: %dx%d\n",
+			rinfo->panel_xres, rinfo->panel_yres);
+
+		tmp = INREG(FP_CRTC_H_TOTAL_DISP);
+		a = (tmp & FP_CRTC_H_TOTAL_MASK) + 4;
+		b = (tmp & 0x01ff0000) >> FP_CRTC_H_DISP_SHIFT;
+		rinfo->hblank = (a - b + 1) * 8;
+
+		tmp = INREG(FP_H_SYNC_STRT_WID);
+		rinfo->hOver_plus = (unsigned short) ((tmp & FP_H_SYNC_STRT_CHAR_MASK) >>
+					FP_H_SYNC_STRT_CHAR_SHIFT) - b - 1;
+		rinfo->hOver_plus *= 8;
+		rinfo->hSync_width = (unsigned short) ((tmp & FP_H_SYNC_WID_MASK) >>
+					FP_H_SYNC_WID_SHIFT);
+		rinfo->hSync_width *= 8;
+		tmp = INREG(FP_CRTC_V_TOTAL_DISP);
+		a = (tmp & FP_CRTC_V_TOTAL_MASK) + 1;
+		b = (tmp & FP_CRTC_V_DISP_MASK) >> FP_CRTC_V_DISP_SHIFT;
+		rinfo->vblank = a - b /* + 24 */ ;
+
+		tmp = INREG(FP_V_SYNC_STRT_WID);
+		rinfo->vOver_plus = (unsigned short) (tmp & FP_V_SYNC_STRT_MASK)
+					- b + 1;
+		rinfo->vSync_width = (unsigned short) ((tmp & FP_V_SYNC_WID_MASK) >>
+					FP_V_SYNC_WID_SHIFT);
+
+		return 1;
+	}
+
+	return 1;
+}
+
+
+#ifdef CONFIG_ALL_PPC
 static int radeon_read_OF (struct radeonfb_info *rinfo)
 {
 	struct device_node *dp;
@@ -1251,10 +1228,10 @@
 	radeon_engine_reset ();
 
 	radeon_fifo_wait (1);
-	OUTREG(DSTCACHE_MODE, 0);
+	OUTREG(RB2D_DSTCACHE_MODE, 0);
 
 	/* XXX */
-	rinfo->pitch = ((rinfo->xres * (rinfo->depth / 8) + 0x3f)) >> 6;
+	rinfo->pitch = ((rinfo->xres_virtual * (rinfo->bpp / 8) + 0x3f)) >> 6;
 
 	radeon_fifo_wait (1);
 	temp = INREG(DEFAULT_PITCH_OFFSET);
@@ -1296,141 +1273,54 @@
 }
 
 
-
-static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
-{
-	struct fb_info *info;
-
-	info = &rinfo->info;
-
-	strcpy (info->modename, rinfo->name);
-        info->node = NODEV;
-        info->flags = FBINFO_FLAG_DEFAULT;
-        info->fbops = &radeon_fb_ops;
-        info->screen_base = (char*)rinfo->fb_base;
-  	info->display_fg = NULL;
-	info->currcon = -1;
-        strncpy (info->fontname, fontname, sizeof (info->fontname));
-        info->fontname[sizeof (info->fontname) - 1] = 0;
-        info->changevar = NULL;
-        info->switch_con = radeonfb_switch;
-        info->updatevar = radeonfb_updatevar;
-
-        if (radeon_init_disp (rinfo) < 0)
-                return -1;   
-
-        return 0;
-}
-
-
-
 static int __devinit radeon_init_disp (struct radeonfb_info *rinfo)
 {
-        struct fb_info *info;
-        struct display *disp;
+        struct fb_info *info = &rinfo->info;
+	struct fb_var_screeninfo var;
 
-        info = &rinfo->info;
-        disp = &rinfo->disp;
-        
-        disp->var = radeonfb_default_var;
-        info->disp = disp;
-
-        radeon_set_dispsw (rinfo, disp);
+        var = radeonfb_default_var;
+        if ((radeon_init_disp_var(rinfo, &var)) < 0)
+                return -1;
 
-	if (noaccel)
-	        disp->scrollmode = SCROLL_YREDRAW;
-	else
-		disp->scrollmode = 0;
+	rinfo->depth = var_to_depth(&var);
+	rinfo->bpp = var.bits_per_pixel;
         
-        rinfo->currcon_display = disp;
+	info->var = var;
+	fb_alloc_cmap(&info->cmap, 256, 0);
 
-        if ((radeon_init_disp_var (rinfo)) < 0)
-                return -1;
-        
+	var.activate = FB_ACTIVATE_NOW;
+	gen_set_var(&var, -1, info);
         return 0;
 }
 
 
-
-static int radeon_init_disp_var (struct radeonfb_info *rinfo)
+static int radeon_init_disp_var (struct radeonfb_info *rinfo,
+				 struct fb_var_screeninfo *var)
 {
 #ifndef MODULE
         if (mode_option)
-                fb_find_mode (&rinfo->disp.var, &rinfo->info, mode_option,
+                fb_find_mode (var, &rinfo->info, mode_option,
                               NULL, 0, NULL, 8);
         else
 #endif
-                fb_find_mode (&rinfo->disp.var, &rinfo->info, "640x480-8@60",
+	if (rinfo->use_default_var)
+		/* We will use the modified default far */
+		*var = radeonfb_default_var;
+	else
+
+                fb_find_mode (var, &rinfo->info, "640x480-8@60",
                               NULL, 0, NULL, 0);
 
 	if (noaccel)
-		rinfo->disp.var.accel_flags &= ~FB_ACCELF_TEXT;
+		var->accel_flags &= ~FB_ACCELF_TEXT;
 	else
-		rinfo->disp.var.accel_flags |= FB_ACCELF_TEXT;
+		var->accel_flags |= FB_ACCELF_TEXT;
  
         return 0;
 }
 
 
-
-static void radeon_set_dispsw (struct radeonfb_info *rinfo, struct display *disp)
-
-{
-        int accel;  
-                
-        accel = disp->var.accel_flags & FB_ACCELF_TEXT;
-                
-        disp->dispsw_data = NULL;
-        
-        disp->type = FB_TYPE_PACKED_PIXELS;
-        disp->type_aux = 0;
-        disp->ypanstep = 1;
-        disp->ywrapstep = 0;
-        disp->can_soft_blank = 1;
-        disp->inverse = 0;
-
-        rinfo->depth = disp->var.bits_per_pixel;
-        switch (disp->var.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
-                case 8:
-                        disp->dispsw = &fbcon_cfb8;
-                        disp->visual = FB_VISUAL_PSEUDOCOLOR;
-                        disp->line_length = disp->var.xres_virtual;
-                        break;
-#endif
-#ifdef FBCON_HAS_CFB16
-                case 16:
-                        disp->dispsw = &fbcon_cfb16;
-                        disp->dispsw_data = &rinfo->con_cmap.cfb16;
-                        disp->visual = FB_VISUAL_DIRECTCOLOR;
-                        disp->line_length = disp->var.xres_virtual * 2;
-                        break;
-#endif  
-#ifdef FBCON_HAS_CFB32       
-                case 24:
-                        disp->dispsw = &fbcon_cfb24;
-                        disp->dispsw_data = &rinfo->con_cmap.cfb24;
-                        disp->visual = FB_VISUAL_DIRECTCOLOR;
-                        disp->line_length = disp->var.xres_virtual * 4;
-                        break;
-#endif
-#ifdef FBCON_HAS_CFB32
-                case 32:
-                        disp->dispsw = &fbcon_cfb32;
-                        disp->dispsw_data = &rinfo->con_cmap.cfb32;
-                        disp->visual = FB_VISUAL_DIRECTCOLOR;
-                        disp->line_length = disp->var.xres_virtual * 4;
-                        break;   
-#endif
-                default:
-                        printk ("radeonfb: setting fbcon_dummy renderer\n");
-                        disp->dispsw = &fbcon_dummy;
-        }
-                
-        return;
-}
-                        
-static int radeonfb_do_maximize(struct radeonfb_info *rinfo,
+static int radeon_do_maximize(struct radeonfb_info *rinfo,
                                 struct fb_var_screeninfo *var,
                                 struct fb_var_screeninfo *v,
                                 int nom, int den)
@@ -1446,7 +1336,7 @@
                 {-1, -1}
         };
         int i;
-                
+  
         /* use highest possible virtual resolution */
         if (v->xres_virtual == -1 && v->yres_virtual == -1) {
                 printk("radeonfb: using max available virtual resolution\n");
@@ -1490,105 +1380,55 @@
                                 
         return 0;
 }
-                        
-
-
-/*
- * fb ops
- */
-
-static int radeonfb_get_fix (struct fb_fix_screeninfo *fix, int con,
-                             struct fb_info *info)
-{
-        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
-        struct display *disp;  
-        
-        disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
-
-        memset (fix, 0, sizeof (struct fb_fix_screeninfo));
-	strcpy (fix->id, rinfo->name);
-        
-        fix->smem_start = rinfo->fb_base_phys;
-        fix->smem_len = rinfo->video_ram;
-
-        fix->type = disp->type;
-        fix->type_aux = disp->type_aux;
-        fix->visual = disp->visual;
-
-        fix->xpanstep = 1;
-        fix->ypanstep = 1;
-        fix->ywrapstep = 0;
-        
-        fix->line_length = disp->line_length;
- 
-        fix->mmio_start = rinfo->mmio_base_phys;
-        fix->mmio_len = RADEON_REGSIZE;
-	if (noaccel)
-	        fix->accel = FB_ACCEL_NONE;
-	else
-		fix->accel = 40;	/* XXX */
-        
-        return 0;
-}
-
 
 
-static int radeonfb_get_var (struct fb_var_screeninfo *var, int con,
-                             struct fb_info *info)
+static int radeonfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info)
 {
-        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
-        
-        *var = (con < 0) ? rinfo->disp.var : fb_display[con].var;
-        
-        return 0;
-}
-
-
-
-static int radeonfb_set_var (struct fb_var_screeninfo *var, int con,
-                             struct fb_info *info)
-{
-        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
-        struct display *disp;
+        struct radeonfb_info *rinfo = (struct radeonfb_info *) info->par;
         struct fb_var_screeninfo v;
-        int nom, den, accel;
-        unsigned chgvar = 0;
-
-        disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
-
-        accel = var->accel_flags & FB_ACCELF_TEXT;
-
-        if (con >= 0) {
-                chgvar = ((disp->var.xres != var->xres) ||
-                          (disp->var.yres != var->yres) ||
-                          (disp->var.xres_virtual != var->xres_virtual) ||
-                          (disp->var.yres_virtual != var->yres_virtual) ||
-                          (disp->var.bits_per_pixel != var->bits_per_pixel) ||
-                          memcmp (&disp->var.red, &var->red, sizeof (var->red)) ||
-                          memcmp (&disp->var.green, &var->green, sizeof (var->green)) ||
-                          memcmp (&disp->var.blue, &var->blue, sizeof (var->blue)));
-        }
+        int nom, den;
 
         memcpy (&v, var, sizeof (v));
 
         switch (v.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
+		case 0 ... 8:
+			v.bits_per_pixel = 8;
+			break;
+		case 9 ... 16:
+			v.bits_per_pixel = 16;
+			break;
+		case 17 ... 24:
+#if 0 /* Doesn't seem to work */
+			v.bits_per_pixel = 24;
+			break;
+#endif			
+			return -EINVAL;
+		case 25 ... 32:
+			v.bits_per_pixel = 32;
+			break;
+		default:
+			return -EINVAL;
+	}
+
+	switch (var_to_depth(&v)) {
                 case 8:
                         nom = den = 1;
-                        disp->line_length = v.xres_virtual;
-                        disp->visual = FB_VISUAL_PSEUDOCOLOR; 
                         v.red.offset = v.green.offset = v.blue.offset = 0;
                         v.red.length = v.green.length = v.blue.length = 8;
                         v.transp.offset = v.transp.length = 0;
                         break;
-#endif
-                        
-#ifdef FBCON_HAS_CFB16
+		case 15:
+			nom = 2;
+			den = 1;
+			v.red.offset = 10;
+			v.green.offset = 5;
+			v.red.offset = 0;
+			v.red.length = v.green.length = v.blue.length = 5;
+			v.transp.offset = v.transp.length = 0;
+			break;
                 case 16:
                         nom = 2;
                         den = 1;
-                        disp->line_length = v.xres_virtual * 2;
-                        disp->visual = FB_VISUAL_DIRECTCOLOR;
                         v.red.offset = 11;
                         v.green.offset = 5;
                         v.blue.offset = 0;
@@ -1596,28 +1436,19 @@
                         v.green.length = 6;
                         v.blue.length = 5;
                         v.transp.offset = v.transp.length = 0;
-                        break;  
-#endif
-                        
-#ifdef FBCON_HAS_CFB24
+                        break;                          
                 case 24:
                         nom = 4;
                         den = 1;
-                        disp->line_length = v.xres_virtual * 3;
-                        disp->visual = FB_VISUAL_DIRECTCOLOR;
                         v.red.offset = 16;
                         v.green.offset = 8;
                         v.blue.offset = 0;
                         v.red.length = v.blue.length = v.green.length = 8;
                         v.transp.offset = v.transp.length = 0;
                         break;
-#endif
-#ifdef FBCON_HAS_CFB32
                 case 32:
                         nom = 4;
                         den = 1;
-                        disp->line_length = v.xres_virtual * 4;
-                        disp->visual = FB_VISUAL_DIRECTCOLOR;
                         v.red.offset = 16;
                         v.green.offset = 8;
                         v.blue.offset = 0;
@@ -1625,14 +1456,13 @@
                         v.transp.offset = 24;
                         v.transp.length = 8;
                         break;
-#endif
                 default:
                         printk ("radeonfb: mode %dx%dx%d rejected, color depth invalid\n",
                                 var->xres, var->yres, var->bits_per_pixel);
                         return -EINVAL;
         }
 
-        if (radeonfb_do_maximize(rinfo, var, &v, nom, den) < 0)
+        if (radeon_do_maximize(rinfo, var, &v, nom, den) < 0)
                 return -EINVAL;  
                 
         if (v.xoffset < 0)
@@ -1649,179 +1479,144 @@
         v.red.msb_right = v.green.msb_right = v.blue.msb_right =
                           v.transp.offset = v.transp.length =
                           v.transp.msb_right = 0;
-                        
-        switch (v.activate & FB_ACTIVATE_MASK) {
-                case FB_ACTIVATE_TEST:
-                        return 0;
-                case FB_ACTIVATE_NXTOPEN:
-                case FB_ACTIVATE_NOW:
-                        break;
-                default:
-                        return -EINVAL;
-        }
-        
-        memcpy (&disp->var, &v, sizeof (v));
-        
-        if (chgvar) {     
-                radeon_set_dispsw(rinfo, disp);
 
-                if (noaccel)
-                        disp->scrollmode = SCROLL_YREDRAW;
-                else
-                        disp->scrollmode = 0;
-                
-                if (info && info->changevar)
-                        info->changevar(con);
-        }
-         
-        radeon_load_video_mode (rinfo, &v);
-                
-        do_install_cmap(con, info);
-  
+	if (noaccel)
+		v.accel_flags = 0;
+			
+        memcpy(var, &v, sizeof(v));
+        
         return 0;
 }
 
 
-
-static int radeonfb_get_cmap (struct fb_cmap *cmap, int kspc, int con,
-                              struct fb_info *info)
+static int radeonfb_pan_display (struct fb_var_screeninfo *var,
+                                 struct fb_info *info)
 {
         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
-        struct display *disp;
+
+        if ((var->xoffset + var->xres > var->xres_virtual)
+	    || (var->yoffset + var->yres > var->yres_virtual))
+               return -EINVAL;
                 
-        disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
-        
-        if (con == info->currcon) {
-                int rc = fb_get_cmap (cmap, kspc, radeon_getcolreg, info);
-                return rc;
-        } else if (disp->cmap.len)
-                fb_copy_cmap (&disp->cmap, cmap, kspc ? 0 : 2);
-        else
-                fb_copy_cmap (fb_default_cmap (radeon_get_cmap_len (&disp->var)),
-                              cmap, kspc ? 0 : 2);
-                        
+        if (rinfo->asleep)
+        	return 0;
+
+        OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset)
+			     * var->bits_per_pixel / 8) & ~7);
         return 0;
 }
 
 
-
-static int radeonfb_set_cmap (struct fb_cmap *cmap, int kspc, int con,
-                              struct fb_info *info)
+static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
+                           unsigned long arg, int con, struct fb_info *info)
 {
         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
-        struct display *disp;
-        unsigned int cmap_len;
-                
-        disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
-  
-        cmap_len = radeon_get_cmap_len (&disp->var);
-        if (disp->cmap.len != cmap_len) {
-                int err = fb_alloc_cmap (&disp->cmap, cmap_len, 0);
-                if (err)
-                        return err;
-        }
- 
-        if (con == info->currcon) {
-                int rc = fb_set_cmap (cmap, kspc, info);
-                return rc;
-        } else
-                fb_copy_cmap (cmap, &disp->cmap, kspc ? 0 : 1);
-        
-        return 0;
-}               
+	unsigned int tmp;
+	u32 value = 0;
+	int rc;
 
+	switch (cmd) {
+		/*
+		 * TODO:  set mirror accordingly for non-Mobility chipsets with 2 CRTC's
+		 */
+		case FBIO_RADEON_SET_MIRROR:
+			switch (rinfo->arch) {
+				case RADEON_R100:
+				case RADEON_RV100:
+				case RADEON_R200:
+				case RADEON_RV200:
+				case RADEON_RV250:
+				case RADEON_R300:
+					return -EINVAL;
+				default:
+					/* RADEON M6, RADEON_M7, RADEON_M9 */
+					break;
+			}
 
+			rc = get_user(value, (__u32*)arg);
 
-static int radeonfb_pan_display (struct fb_var_screeninfo *var, int con,
-                                 struct fb_info *info)
-{
-        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
-        u32 offset, xoffset, yoffset;
-                
-        xoffset = (var->xoffset + 7) & ~7;
-        yoffset = var->yoffset;
-                
-        if ((xoffset + var->xres > var->xres_virtual) || (yoffset+var->yres >
-                var->yres_virtual))
-                return -EINVAL;
-                
-        offset = ((yoffset * var->xres + xoffset) * var->bits_per_pixel) >> 6;
-         
-        OUTREG(CRTC_OFFSET, offset);
-        
-        return 0;
-}
+			if (rc)
+				return rc;
 
+			if (value & 0x01) {
+				tmp = INREG(LVDS_GEN_CNTL);
 
-static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
-                           unsigned long arg, int con, struct fb_info *info)
-{
-	return -EINVAL;
-}
+				tmp |= (LVDS_ON | LVDS_BLON);
+			} else {
+				tmp = INREG(LVDS_GEN_CNTL);
 
+				tmp &= ~(LVDS_ON | LVDS_BLON);
+			}
 
-static int radeonfb_switch (int con, struct fb_info *info)
-{
-        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
-        struct display *disp;
-        struct fb_cmap *cmap;
-        int switchcon = 0;
-        
-        disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
-                
-        if (info->currcon >= 0) {
-                cmap = &(rinfo->currcon_display->cmap);
-                if (cmap->len)
-                        fb_get_cmap (cmap, 1, radeon_getcolreg, info);
-        }   
-                
-        if ((disp->var.xres != rinfo->xres) ||
-            (disp->var.yres != rinfo->yres) ||
-            (disp->var.pixclock != rinfo->pixclock) ||
-            (disp->var.bits_per_pixel != rinfo->depth))
-                switchcon = 1;
-        
-        if (switchcon) {
-                info->currcon = con;
-                rinfo->currcon_display = disp;
-                disp->var.activate = FB_ACTIVATE_NOW;
-        
-                radeonfb_set_var (&disp->var, con, info);
-                radeon_set_dispsw (rinfo, disp);
-                do_install_cmap(con, info);
-        }       
+			OUTREG(LVDS_GEN_CNTL, tmp);
 
-        /* XXX absurd hack for X to restore console */
-        {   
-		OUTREGP(CRTC_EXT_CNTL, rinfo->hack_crtc_ext_cntl,
-			CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS);
-                OUTREG(CRTC_V_SYNC_STRT_WID, rinfo->hack_crtc_v_sync_strt_wid);
-        }
+			if (value & 0x02) {
+				tmp = INREG(CRTC_EXT_CNTL);
+				tmp |= CRTC_CRT_ON;
 
-        return 0;
-}
+				mirror = 1;
+			} else {
+				tmp = INREG(CRTC_EXT_CNTL);
+				tmp &= ~CRTC_CRT_ON;
 
+				mirror = 0;
+			}
 
+			OUTREG(CRTC_EXT_CNTL, tmp);
 
-static int radeonfb_updatevar (int con, struct fb_info *info)
-{
-        int rc;
-                
-        rc = (con < 0) ? -EINVAL : radeonfb_pan_display (&fb_display[con].var,
-                                                         con, info);
-        
-        return rc;
+			break;
+		case FBIO_RADEON_GET_MIRROR:
+			switch (rinfo->arch) {
+				case RADEON_R100:
+				case RADEON_RV100:
+				case RADEON_R200:
+				case RADEON_RV200:
+				case RADEON_RV250:
+				case RADEON_R300:
+					return -EINVAL;
+				default:
+					/* RADEON M6, RADEON_M7, RADEON_M9 */
+					break;
+			}
+
+			tmp = INREG(LVDS_GEN_CNTL);
+			if ((LVDS_ON | LVDS_BLON) & tmp)
+				value |= 0x01;
+
+			tmp = INREG(CRTC_EXT_CNTL);
+			if (CRTC_CRT_ON & tmp)
+				value |= 0x02;
+
+			return put_user(value, (__u32*)arg);
+		default:
+			return -EINVAL;
+	}
+
+	return -EINVAL;
 }
 
+
 static int radeonfb_blank (int blank, struct fb_info *info)
 {
         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
         u32 val = INREG(CRTC_EXT_CNTL);
+	u32 val2 = INREG(LVDS_GEN_CNTL);
+
+	if (rinfo->asleep)
+		return 0;
+		
+#ifdef CONFIG_PMAC_BACKLIGHT
+	if (rinfo->dviDisp_type == MT_LCD && _machine == _MACH_Pmac) {
+		set_backlight_enable(!blank);
+		return 0;
+	}
+#endif
                         
         /* reset it */
         val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS |
                  CRTC_VSYNC_DIS);
-                
+	val2 &= ~(LVDS_DISPLAY_DIS);
+
         switch (blank) {
                 case VESA_NO_BLANKING:
                         break;
@@ -1834,56 +1629,31 @@
                 case VESA_POWERDOWN:
                         val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS | 
                                 CRTC_HSYNC_DIS);
+			val2 |= (LVDS_DISPLAY_DIS);
                         break;
         }
-        
-        OUTREG(CRTC_EXT_CNTL, val);
-	return 0;
-}
-
-static int radeon_get_cmap_len (const struct fb_var_screeninfo *var)
-{
-        int rc = 16;            /* reasonable default */
-        
-        switch (var->bits_per_pixel) {
-                case 8:
-                        rc = 256;
-                        break;
-                default:
-                        rc = 32;
-                        break;
-        }
-                
-        return rc;
-}
-
-
 
-static int radeon_getcolreg (unsigned regno, unsigned *red, unsigned *green,
-                             unsigned *blue, unsigned *transp,
-                             struct fb_info *info)
-{
-        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
-	
-	if (regno > 255)
-		return 1;
-     
- 	*red = (rinfo->palette[regno].red<<8) | rinfo->palette[regno].red; 
-    	*green = (rinfo->palette[regno].green<<8) | rinfo->palette[regno].green;
-    	*blue = (rinfo->palette[regno].blue<<8) | rinfo->palette[regno].blue;
-    	*transp = 0;
+	switch (rinfo->dviDisp_type) {
+		case MT_LCD:
+			OUTREG(LVDS_GEN_CNTL, val2);
+			break;
+		case MT_CRT:
+		default:
+		        OUTREG(CRTC_EXT_CNTL, val);
+			break;
+	}
 
 	return 0;
-}                            
-
+}
 
 
 static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green,
-                               unsigned blue, unsigned transp, struct fb_info *info)
+                             unsigned blue, unsigned transp, struct fb_info *info)
 {
         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
-	u32 pindex;
-
+	u32 pindex, vclk_cntl;
+	unsigned int i;
+	
 	if (regno > 255)
 		return 1;
 
@@ -1894,62 +1664,58 @@
 	rinfo->palette[regno].green = green;
 	rinfo->palette[regno].blue = blue;
 
-        /* init gamma for hicolor */
-        if ((rinfo->depth > 8) && (regno == 0)) {
-                int i;
-                
-                for (i=0; i<255; i++) {
-                        OUTREG(PALETTE_INDEX, i);
-                        OUTREG(PALETTE_DATA, (i << 16) | (i << 8) | i);
-                }
-        }
-         
         /* default */
         pindex = regno;
-        
-        /* XXX actually bpp, fixme */
-        if (rinfo->depth == 16)     
-                pindex  = regno * 8;
-                
-        if (rinfo->depth == 16) {
-                OUTREG(PALETTE_INDEX, pindex/2);
-                OUTREG(PALETTE_DATA, (rinfo->palette[regno/2].red << 16) |
-                        (green << 8) | (rinfo->palette[regno/2].blue));
-                green = rinfo->palette[regno/2].green;
-        }
-                
-        if ((rinfo->depth == 8) || (regno < 32)) {
-                OUTREG(PALETTE_INDEX, pindex);
-                OUTREG(PALETTE_DATA, (red << 16) | (green << 8) | blue);
-        }
 
+        if (!rinfo->asleep) {
+		vclk_cntl = INPLL(VCLK_ECP_CNTL);
+		OUTPLL(VCLK_ECP_CNTL, vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb);
+
+		if (rinfo->bpp == 16) {
+			pindex = regno * 8;
+
+			if (rinfo->depth == 16 && regno > 63)
+				return 1;
+			if (rinfo->depth == 15 && regno > 31)
+				return 1;
+
+			/* For 565, the green component is mixed one order below */
+			if (rinfo->depth == 16) {
+		                OUTREG(PALETTE_INDEX, pindex>>1);
+	       	         	OUTREG(PALETTE_DATA, (rinfo->palette[regno>>1].red << 16) |
+	                        	(green << 8) | (rinfo->palette[regno>>1].blue));
+	                	green = rinfo->palette[regno<<1].green;
+	        	}
+		}
 
-#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
- 	if (regno < 32) {
+		if (rinfo->depth != 16 || regno < 32) {
+			OUTREG(PALETTE_INDEX, pindex);
+			OUTREG(PALETTE_DATA, (red << 16) | (green << 8) | blue);
+		}
+
+		OUTPLL(VCLK_ECP_CNTL, vclk_cntl);
+	}
+ 	if (regno < 16) {
         	switch (rinfo->depth) {
-#ifdef FBCON_HAS_CFB16
-		        case 16:
-        			rinfo->con_cmap.cfb16[regno] = (regno << 11) | (regno << 5) |
-				                       	 	  regno;   
-			        break;
-#endif
-#ifdef FBCON_HAS_CFB24
-                        case 24:
-                                rinfo->con_cmap.cfb24[regno] = (regno << 16) | (regno << 8) | regno;
-                                break;
-#endif
-#ifdef FBCON_HAS_CFB32
-	        	case 32: {
-            			u32 i;    
-   
-  		       		i = (regno << 8) | regno;
-            			rinfo->con_cmap.cfb32[regno] = (i << 16) | i;
-		        	break;
-        		}
-#endif
+		case 15:
+			((u16 *) (info->pseudo_palette))[regno] =
+			    (regno << 10) | (regno << 5) | regno;
+			break;
+		case 16:
+			((u16 *) (info->pseudo_palette))[regno] =
+			    (regno << 11) | (regno << 6) | 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;
 		}
         }
-#endif
 	return 0;
 }
 
@@ -1982,13 +1748,16 @@
 	save->lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
 	save->lvds_pll_cntl = INREG(LVDS_PLL_CNTL);
 	save->tmds_crc = INREG(TMDS_CRC);
+	save->tmds_transmitter_cntl = INREG(TMDS_TRANSMITTER_CNTL);
+	save->vclk_ecp_cntl = INPLL(VCLK_ECP_CNTL);
 }
 
 
 
-static void radeon_load_video_mode (struct radeonfb_info *rinfo,
-                                    struct fb_var_screeninfo *mode)
+static int radeonfb_set_par (struct fb_info *info)
 {
+	struct radeonfb_info *rinfo = (struct radeonfb_info *)info->par;
+	struct fb_var_screeninfo *mode = &info->var;
 	struct radeon_regs newmode;
 	int hTotal, vTotal, hSyncStart, hSyncEnd,
 	    hSyncPol, vSyncStart, vSyncEnd, vSyncPol, cSync;
@@ -2002,9 +1771,12 @@
         int min_bits, format = 0;
 	int hsync_start, hsync_fudge, bytpp, hsync_wid, vsync_wid;
 	int primary_mon = PRIMARY_MONITOR(rinfo);
+	int depth = var_to_depth(mode);
 
 	rinfo->xres = mode->xres;
 	rinfo->yres = mode->yres;
+	rinfo->xres_virtual = mode->xres_virtual;
+	rinfo->yres_virtual = mode->yres_virtual;
 	rinfo->pixclock = mode->pixclock;
 
 	hSyncStart = mode->xres + mode->right_margin;
@@ -2021,13 +1793,13 @@
 		if (rinfo->panel_yres < mode->yres)
 			rinfo->yres = mode->yres = rinfo->panel_yres;
 
-		hTotal = mode->xres + rinfo->hblank + mode->left_margin;
-		hSyncStart = mode->xres + rinfo->hOver_plus + mode->right_margin;
-		hSyncEnd = hSyncStart + rinfo->hOver_plus + mode->hsync_len;
-
-		vTotal = mode->yres + rinfo->vblank + mode->upper_margin;
-		vSyncStart = mode->yres + rinfo->vOver_plus + mode->lower_margin;
-		vSyncEnd = vSyncStart + rinfo->vSync_width + mode->vsync_len;
+		hTotal = mode->xres + rinfo->hblank;
+		hSyncStart = mode->xres + rinfo->hOver_plus;
+		hSyncEnd = hSyncStart + rinfo->hSync_width;
+
+		vTotal = mode->yres + rinfo->vblank;
+		vSyncStart = mode->yres + rinfo->vOver_plus;
+		vSyncEnd = vSyncStart + rinfo->vSync_width;
 	}
 
 	sync = mode->sync;
@@ -2045,7 +1817,7 @@
 		hsync_wid = 1;
 	else if (hsync_wid > 0x3f)	/* max */
 		hsync_wid = 0x3f;
-	vsync_wid = mode->vsync_len;
+
 	if (vsync_wid == 0)
 		vsync_wid = 1;
 	else if (vsync_wid > 0x1f)	/* max */
@@ -2056,24 +1828,8 @@
 
 	cSync = mode->sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0;
 
-	switch (mode->bits_per_pixel) {
-		case 8:
-			format = DST_8BPP;
-			bytpp = 1;
-			break;
-		case 16:
-			format = DST_16BPP;
-			bytpp = 2;
-			break;
-		case 24:
-			format = DST_24BPP;
-			bytpp = 3;
-			break;
-		case 32:
-			format = DST_32BPP;
-			bytpp = 4;
-			break;
-	}
+	format = radeon_get_dstbpp(depth);
+	bytpp = mode->bits_per_pixel >> 3;
 
 	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD))
 		hsync_fudge = hsync_fudge_fp[format-1];
@@ -2087,6 +1843,9 @@
 
 	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
 		newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN;
+		if (mirror)
+			newmode.crtc_ext_cntl |= CRTC_CRT_ON;
+
 		newmode.crtc_gen_cntl &= ~(CRTC_DBL_SCAN_EN |
 					   CRTC_INTERLACE_EN);
 	} else {
@@ -2097,7 +1856,7 @@
 	newmode.dac_cntl = /* INREG(DAC_CNTL) | */ DAC_MASK_ALL | DAC_VGA_ADR_EN |
 			   DAC_8BIT_EN;
 
-	newmode.crtc_h_total_disp = ((((hTotal / 8) - 1) & 0xffff) |
+	newmode.crtc_h_total_disp = ((((hTotal / 8) - 1) & 0x3ff) |
 				     (((mode->xres / 8) - 1) << 16));
 
 	newmode.crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) |
@@ -2109,7 +1868,7 @@
 	newmode.crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) |
 					 (vsync_wid << 16) | (v_sync_pol  << 23));
 
-	newmode.crtc_pitch = (mode->xres >> 3);
+	newmode.crtc_pitch = (mode->xres_virtual >> 3);
 	newmode.crtc_pitch |= (newmode.crtc_pitch << 16);
 
 #if defined(__BIG_ENDIAN)
@@ -2125,8 +1884,8 @@
 	}
 #endif
 
-	rinfo->pitch = ((mode->xres * ((mode->bits_per_pixel + 1) / 8) + 0x3f)
-			& ~(0x3f)) / 64;
+	rinfo->pitch = ((mode->xres_virtual * ((mode->bits_per_pixel + 1) / 8) + 0x3f)
+ 			& ~(0x3f)) / 64;
 
 	RTRACE("h_total_disp = 0x%x\t   hsync_strt_wid = 0x%x\n",
 		newmode.crtc_h_total_disp, newmode.crtc_h_sync_strt_wid);
@@ -2137,9 +1896,7 @@
 	newmode.yres = mode->yres;
 
 	rinfo->bpp = mode->bits_per_pixel;
-
-	rinfo->hack_crtc_ext_cntl = newmode.crtc_ext_cntl;
-	rinfo->hack_crtc_v_sync_strt_wid = newmode.crtc_v_sync_strt_wid;
+	rinfo->depth = depth;
 
 	if (freq > rinfo->pll.ppll_max)
 		freq = rinfo->pll.ppll_max;
@@ -2176,6 +1933,8 @@
 		newmode.ppll_ref_div = rinfo->pll.ref_div;
 		newmode.ppll_div_3 = rinfo->fb_div | (post_div->bitvalue << 16);
 	}
+	newmode.vclk_ecp_cntl = rinfo->init_state.vclk_ecp_cntl;
+	
 
 	RTRACE("post div = 0x%x\n", rinfo->post_div);
 	RTRACE("fb_div = 0x%x\n", rinfo->fb_div);
@@ -2204,7 +1963,7 @@
 
 	if ((ron + rinfo->ram.rloop) >= roff) {
 		printk("radeonfb: error ron out of range\n");
-		return;
+		return -EINVAL;
 	}
 
 	newmode.dda_config = (xclk_per_trans_precise |
@@ -2213,48 +1972,43 @@
 	newmode.dda_on_off = (ron << 16) | roff;
 
 	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
-		int hRatio, vRatio;
-
-		if ((rinfo->panel_xres == 0) || (rinfo->panel_yres == 0)) {
-			hRatio = vRatio = 1;
-		} else {
-			if (mode->xres > rinfo->panel_xres)
-				mode->xres = rinfo->panel_xres;
-			if (mode->yres > rinfo->panel_yres)
-				mode->yres = rinfo->panel_yres;
-	
-			hRatio = mode->xres / rinfo->panel_xres;
-			vRatio = mode->yres / rinfo->panel_yres;
-		}
+		unsigned int hRatio, vRatio;
 
-		if (hRatio == 1) {
-			newmode.fp_horz_stretch =
-				rinfo->init_state.fp_horz_stretch;
-			newmode.fp_horz_stretch &= ~(HORZ_STRETCH_BLEND |
-						     HORZ_STRETCH_ENABLE);
-		} else {
-			newmode.fp_horz_stretch =
-				((((unsigned long)(hRatio * HORZ_STRETCH_RATIO_MAX +
-				(int)0.5)) & HORZ_STRETCH_RATIO_MASK)) |
-				(rinfo->init_state.fp_horz_stretch &
-				(HORZ_PANEL_SIZE | HORZ_FP_LOOP_STRETCH |
-				HORZ_AUTO_RATIO_INC));
+		/* We force the pixel clock to be always enabled. Allowing it
+		 * to be power managed during blanking would save power, but has
+		 * nasty interactions with the 2D engine & sleep code that haven't
+		 * been solved yet. --BenH
+		 */
+		newmode.vclk_ecp_cntl &= ~PIXCLK_DAC_ALWAYS_ONb;
+		
+		if (mode->xres > rinfo->panel_xres)
+			mode->xres = rinfo->panel_xres;
+		if (mode->yres > rinfo->panel_yres)
+			mode->yres = rinfo->panel_yres;
+
+		newmode.fp_horz_stretch = (((rinfo->panel_xres / 8) - 1)
+					   << HORZ_PANEL_SHIFT);
+		newmode.fp_vert_stretch = ((rinfo->panel_yres - 1)
+					   << VERT_PANEL_SHIFT);
+
+		if (mode->xres != rinfo->panel_xres) {
+			hRatio = round_div(mode->xres * HORZ_STRETCH_RATIO_MAX,
+					   rinfo->panel_xres);
+			newmode.fp_horz_stretch = (((((unsigned long)hRatio) & HORZ_STRETCH_RATIO_MASK)) |
+						   (newmode.fp_horz_stretch &
+						    (HORZ_PANEL_SIZE | HORZ_FP_LOOP_STRETCH |
+						     HORZ_AUTO_RATIO_INC)));
 			newmode.fp_horz_stretch |= (HORZ_STRETCH_BLEND |
 						    HORZ_STRETCH_ENABLE);
 		}
 		newmode.fp_horz_stretch &= ~HORZ_AUTO_RATIO;
 
-		if (vRatio == 1) {
-			newmode.fp_vert_stretch =
-				rinfo->init_state.fp_vert_stretch;
-			newmode.fp_vert_stretch &= ~(VERT_STRETCH_BLEND |
-						     VERT_STRETCH_ENABLE);
-		} else {
-			newmode.fp_vert_stretch =
-				((((unsigned long)(vRatio * VERT_STRETCH_RATIO_MAX +
-				(int)0.5)) & VERT_STRETCH_RATIO_MASK)) |
-				(rinfo->init_state.fp_vert_stretch &
-				(VERT_PANEL_SIZE | VERT_STRETCH_RESERVED));
+		if (mode->yres != rinfo->panel_yres) {
+			vRatio = round_div(mode->yres * VERT_STRETCH_RATIO_MAX,
+					   rinfo->panel_yres);
+			newmode.fp_vert_stretch = (((((unsigned long)vRatio) & VERT_STRETCH_RATIO_MASK)) |
+						   (newmode.fp_vert_stretch &
+						   (VERT_PANEL_SIZE | VERT_STRETCH_RESERVED)));
 			newmode.fp_vert_stretch |= (VERT_STRETCH_BLEND |
 						    VERT_STRETCH_ENABLE);
 		}
@@ -2269,14 +2023,14 @@
 					 FP_USE_SHADOW_EN |
 					 FP_CRTC_USE_SHADOW_VEND |
 					 FP_CRT_SYNC_ALT));
+
 		newmode.fp_gen_cntl |= (FP_CRTC_DONT_SHADOW_VPAR |
 					FP_CRTC_DONT_SHADOW_HEND);
 
 		newmode.lvds_gen_cntl = rinfo->init_state.lvds_gen_cntl;
 		newmode.lvds_pll_cntl = rinfo->init_state.lvds_pll_cntl;
 		newmode.tmds_crc = rinfo->init_state.tmds_crc;
-
-		newmode.crtc_ext_cntl &= ~CRTC_CRT_ON;
+		newmode.tmds_transmitter_cntl = rinfo->init_state.tmds_transmitter_cntl;
 
 		if (primary_mon == MT_LCD) {
 			newmode.lvds_gen_cntl |= (LVDS_ON | LVDS_BLON);
@@ -2284,22 +2038,41 @@
 		} else {
 			/* DFP */
 			newmode.fp_gen_cntl |= (FP_FPON | FP_TMDS_EN);
+			newmode.tmds_transmitter_cntl = (TMDS_RAN_PAT_RST |
+							 ICHCSEL | TMDS_PLL_EN) &
+							 ~(TMDS_PLLRST);
+			newmode.crtc_ext_cntl &= ~CRTC_CRT_ON;
 		}
 
-		newmode.fp_crtc_h_total_disp =
-				rinfo->init_state.fp_crtc_h_total_disp;
-		newmode.fp_crtc_v_total_disp =
-				rinfo->init_state.fp_crtc_v_total_disp;
-		newmode.fp_h_sync_strt_wid =
-				rinfo->init_state.fp_h_sync_strt_wid;
-		newmode.fp_v_sync_strt_wid =
-				rinfo->init_state.fp_v_sync_strt_wid;
+		newmode.fp_crtc_h_total_disp = (((rinfo->hblank / 8) & 0x3ff) |
+				(((mode->xres / 8) - 1) << 16));
+		newmode.fp_crtc_v_total_disp = (rinfo->vblank & 0xffff) |
+				((mode->yres - 1) << 16);
+		newmode.fp_h_sync_strt_wid = ((rinfo->hOver_plus & 0x1fff) |
+				(hsync_wid << 16) | (h_sync_pol << 23));
+		newmode.fp_v_sync_strt_wid = ((rinfo->vOver_plus & 0xfff) |
+				(vsync_wid << 16) | (v_sync_pol  << 23));
 	}
 
 	/* do it! */
-	radeon_write_mode (rinfo, &newmode);
+	if (!rinfo->asleep) {
+		radeon_write_mode (rinfo, &newmode);
+		/* (re)initialize the engine */
+		if (!noaccel)
+			radeon_engine_init (rinfo);
+	
+	}
+	/* Update fix */
+        info->fix.line_length = rinfo->pitch*64;
+        info->fix.visual = rinfo->depth == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
+
+#ifdef CONFIG_BOOTX_TEXT
+	/* Update debug text engine */
+	btext_update_display(rinfo->fb_base_phys, mode->xres, mode->yres,
+			     rinfo->depth, rinfo->pitch*64);
+#endif
 
-	return;
+	return 0;
 }
 
 
@@ -2309,11 +2082,16 @@
 	int i;
 	int primary_mon = PRIMARY_MONITOR(rinfo);
 
-	/* blank screen */
-	OUTREG8(CRTC_EXT_CNTL + 1, 4);
+	radeonfb_blank(VESA_POWERDOWN, (struct fb_info *)rinfo);
+
 
-	for (i=0; i<9; i++)
-		OUTREG(common_regs[i].reg, common_regs[i].val);
+	if (rinfo->arch == RADEON_M6) {
+		for (i=0; i<8; i++)
+			OUTREG(common_regs_m6[i].reg, common_regs_m6[i].val);
+	} else {
+		for (i=0; i<9; i++)
+			OUTREG(common_regs[i].reg, common_regs[i].val);
+	}
 
 	OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
 	OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
@@ -2326,16 +2104,6 @@
 	OUTREG(CRTC_OFFSET, 0);
 	OUTREG(CRTC_OFFSET_CNTL, 0);
 	OUTREG(CRTC_PITCH, mode->crtc_pitch);
-#if 1
-	printk("CRTC_H_TOTAL_DISP = 0x%x, H_SYNC = 0x%x\n",
-		mode->crtc_h_total_disp, mode->crtc_h_sync_strt_wid);
-	printk("CRTC_V_TOTAL_DISP = 0x%x, V_SYNC = 0x%x\n",
-		mode->crtc_v_total_disp, mode->crtc_v_sync_strt_wid);
-	printk("PPLL_DIV_3 = 0x%x, PPLL_REF_DIV = 0x%x\n",
-		mode->ppll_div_3, mode->ppll_ref_div);
-	printk("DDA_CONFIG = 0x%x, DDA_ON_OFF = 0x%x\n",
-		mode->dda_config, mode->dda_on_off);
-#endif
 
 #if defined(__BIG_ENDIAN)
 	OUTREG(SURFACE_CNTL, mode->surface_cntl);
@@ -2367,131 +2135,1017 @@
 
 	OUTPLLP(PPLL_CNTL, 0, ~PPLL_RESET);
 
-	OUTREG(DDA_CONFIG, mode->dda_config);
-	OUTREG(DDA_ON_OFF, mode->dda_on_off);
+//	OUTREG(DDA_CONFIG, mode->dda_config);
+//	OUTREG(DDA_ON_OFF, mode->dda_on_off);
 
 	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
 		OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp);
 		OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp);
 		OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid);
 		OUTREG(FP_V_SYNC_STRT_WID, mode->fp_v_sync_strt_wid);
-		OUTREG(TMDS_CRC, mode->tmds_crc);
 		OUTREG(FP_HORZ_STRETCH, mode->fp_horz_stretch);
 		OUTREG(FP_VERT_STRETCH, mode->fp_vert_stretch);
 		OUTREG(FP_GEN_CNTL, mode->fp_gen_cntl);
+		OUTREG(TMDS_CRC, mode->tmds_crc);
+		OUTREG(TMDS_TRANSMITTER_CNTL, mode->tmds_transmitter_cntl);
 
 		if (primary_mon == MT_LCD) {
 			unsigned int tmp = INREG(LVDS_GEN_CNTL);
 
+			mode->lvds_gen_cntl &= ~LVDS_STATE_MASK;
+			mode->lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_STATE_MASK);
+
 			if ((tmp & (LVDS_ON | LVDS_BLON)) ==
-			    (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON)))
-				OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
-		} else {
-			/* DVI */
-			if (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON)) {
-				udelay(1000);
+			    (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON))) {
 				OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
 			} else {
-				OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl |
-				       LVDS_BLON);
-				udelay(1000);
-				OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
+				if (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON)) {
+					udelay(1000);
+					OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
+				} else {
+					OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl |
+					       LVDS_BLON);
+					udelay(1000);
+					OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
+				}
 			}
 		}
 	}
 
-	/* unblank screen */
-	OUTREG8(CRTC_EXT_CNTL + 1, 0);
+	radeonfb_blank(VESA_NO_BLANKING, (struct fb_info *)rinfo);
 
+	OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl);
+	
 	return;
 }
 
+static struct fb_ops radeonfb_ops = {
+	.owner			= THIS_MODULE,
+	.fb_check_var		= radeonfb_check_var,
+	.fb_set_par		= radeonfb_set_par,
+	.fb_setcolreg		= radeonfb_setcolreg,
+	.fb_pan_display 	= radeonfb_pan_display,
+	.fb_blank		= radeonfb_blank,
+	.fb_ioctl		= radeonfb_ioctl,
+#if 0
+	.fb_fillrect	= radeonfb_fillrect,
+	.fb_copyarea	= radeonfb_copyarea,
+	.fb_imageblit	= radeonfb_imageblit,
+	.fb_rasterimg	= radeonfb_rasterimg,
+#else
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit,
+#endif
+};
+
+
+static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
+{
+	struct fb_info *info;
+
+	info = &rinfo->info;
+
+	// XXX ???
+	strncpy (info->modename, rinfo->name, sizeof(info->modename));
+	
+	info->currcon = -1;
+	info->par = rinfo;
+	info->disp = &rinfo->disp;
+	info->pseudo_palette = rinfo->pseudo_palette;
+        info->node = NODEV;
+        info->flags = FBINFO_FLAG_DEFAULT;
+        info->fbops = &radeonfb_ops;
+        info->display_fg = NULL;
+        info->screen_base = (char *)rinfo->fb_base;
+
+	/* Fill fix common fields */
+	strncpy(info->fix.id, rinfo->name, sizeof(info->fix.id));
+	info->fix.id[sizeof(info->fix.id) - 1] = '\0';
+        info->fix.smem_start = rinfo->fb_base_phys;
+        info->fix.smem_len = rinfo->video_ram;
+        info->fix.type = FB_TYPE_PACKED_PIXELS;
+        info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+        info->fix.xpanstep = 8;
+        info->fix.ypanstep = 1;
+        info->fix.ywrapstep = 0;
+        info->fix.type_aux = 0;
+        info->fix.mmio_start = rinfo->mmio_base_phys;
+        info->fix.mmio_len = RADEON_REGSIZE;
+	if (noaccel)
+	        info->fix.accel = FB_ACCEL_NONE;
+	else
+		info->fix.accel = FB_ACCEL_ATI_RADEON;
+
+        if (radeon_init_disp (rinfo) < 0)
+                return -1;   
+
+        return 0;
+}
+
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+
+/* TODO: Dbl check these tables, we don't go up to full ON backlight
+ * in these, possibly because we noticed MacOS doesn't, but I'd prefer
+ * having some more official numbers from ATI
+ */
+static int backlight_conv_m6[] = {
+	0xff, 0xc0, 0xb5, 0xaa, 0x9f, 0x94, 0x89, 0x7e,
+	0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24
+};
+static int backlight_conv_m7[] = {
+	0x00, 0x3f, 0x4a, 0x55, 0x60, 0x6b, 0x76, 0x81,
+	0x8c, 0x97, 0xa2, 0xad, 0xb8, 0xc3, 0xce, 0xd9
+};
+
+#define BACKLIGHT_LVDS_OFF
+#undef BACKLIGHT_DAC_OFF
+
+/* We turn off the LCD completely instead of just dimming the backlight.
+ * This provides some greater power saving and the display is useless
+ * without backlight anyway.
+ */
+
+static int radeon_set_backlight_enable(int on, int level, void *data)
+{
+	struct radeonfb_info *rinfo = (struct radeonfb_info *)data;
+	unsigned int lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
+	int* conv_table;
+
+	if (rinfo->arch == RADEON_M7)
+		conv_table = backlight_conv_m7;
+	else
+		conv_table = backlight_conv_m6;
+
+	lvds_gen_cntl |= (LVDS_BL_MOD_EN | LVDS_BLON);
+	if (on && (level > BACKLIGHT_OFF)) {
+		lvds_gen_cntl |= LVDS_DIGON;
+		if (!lvds_gen_cntl & LVDS_ON) {
+			lvds_gen_cntl &= ~LVDS_BLON;
+			OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
+			(void)INREG(LVDS_GEN_CNTL);
+			mdelay(10);
+			lvds_gen_cntl |= LVDS_BLON;
+			OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
+		}
+		lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
+		lvds_gen_cntl |= (conv_table[level] <<
+				  LVDS_BL_MOD_LEVEL_SHIFT);
+		lvds_gen_cntl |= (LVDS_ON | LVDS_EN);
+		lvds_gen_cntl &= ~LVDS_DISPLAY_DIS;
+	} else {
+		lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
+		lvds_gen_cntl |= (conv_table[0] <<
+				  LVDS_BL_MOD_LEVEL_SHIFT);
+		lvds_gen_cntl |= LVDS_DISPLAY_DIS;
+		OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
+		udelay(10);
+		lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGON);
+	}
+
+	OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
+	rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;
+	rinfo->init_state.lvds_gen_cntl |= (lvds_gen_cntl & LVDS_STATE_MASK);
+
+	return 0;
+}
+
+static int radeon_set_backlight_level(int level, void *data)
+{
+	return radeon_set_backlight_enable(1, level, data);
+}
+#endif /* CONFIG_PMAC_BACKLIGHT */
 
 
+#ifdef CONFIG_PMAC_PBOOK
+
+static u32 dbg_clk;
+
 /*
- * text console acceleration
+ * Radeon M6 Power Management code. This code currently only supports
+ * the mobile chips, it's based from some informations provided by ATI
+ * along with hours of tracing of MacOS drivers
  */
+ 
+static void radeon_pm_save_regs(struct radeonfb_info *rinfo)
+{
+	rinfo->save_regs[0] = INPLL(PLL_PWRMGT_CNTL);
+	rinfo->save_regs[1] = INPLL(CLK_PWRMGT_CNTL);
+	rinfo->save_regs[2] = INPLL(MCLK_CNTL);
+	rinfo->save_regs[3] = INPLL(SCLK_CNTL);
+	rinfo->save_regs[4] = INPLL(CLK_PIN_CNTL);
+	rinfo->save_regs[5] = INPLL(VCLK_ECP_CNTL);
+	rinfo->save_regs[6] = INPLL(PIXCLKS_CNTL);
+	rinfo->save_regs[7] = INPLL(MCLK_MISC);
+	rinfo->save_regs[8] = INPLL(P2PLL_CNTL);
+	
+	rinfo->save_regs[9] = INREG(DISP_MISC_CNTL);
+	rinfo->save_regs[10] = INREG(DISP_PWR_MAN);
+	rinfo->save_regs[11] = INREG(LVDS_GEN_CNTL);
+	rinfo->save_regs[12] = INREG(LVDS_PLL_CNTL);
+	rinfo->save_regs[13] = INREG(TV_DAC_CNTL);
+	rinfo->save_regs[14] = INREG(BUS_CNTL1);
+	rinfo->save_regs[15] = INREG(CRTC_OFFSET_CNTL);
+	rinfo->save_regs[16] = INREG(AGP_CNTL);
+	rinfo->save_regs[17] = (INREG(CRTC_GEN_CNTL) & 0xfdffffff) | 0x04000000;
+	rinfo->save_regs[18] = (INREG(CRTC2_GEN_CNTL) & 0xfdffffff) | 0x04000000;
+	rinfo->save_regs[19] = INREG(GPIOPAD_A);
+	rinfo->save_regs[20] = INREG(GPIOPAD_EN);
+	rinfo->save_regs[21] = INREG(GPIOPAD_MASK);
+	rinfo->save_regs[22] = INREG(ZV_LCDPAD_A);
+	rinfo->save_regs[23] = INREG(ZV_LCDPAD_EN);
+	rinfo->save_regs[24] = INREG(ZV_LCDPAD_MASK);
+	rinfo->save_regs[25] = INREG(GPIO_VGA_DDC);
+	rinfo->save_regs[26] = INREG(GPIO_DVI_DDC);
+	rinfo->save_regs[27] = INREG(GPIO_MONID);
+	rinfo->save_regs[28] = INREG(GPIO_CRT2_DDC);
+
+	rinfo->save_regs[29] = INREG(SURFACE_CNTL);
+	rinfo->save_regs[30] = INREG(MC_FB_LOCATION);
+	rinfo->save_regs[31] = INREG(DISPLAY_BASE_ADDR);
+	rinfo->save_regs[32] = INREG(MC_AGP_LOCATION);
+	rinfo->save_regs[33] = INREG(CRTC2_DISPLAY_BASE_ADDR);
+}
+
+static void radeon_pm_restore_regs(struct radeonfb_info *rinfo)
+{
+	OUTPLL(P2PLL_CNTL, rinfo->save_regs[8] & 0xFFFFFFFE); /* First */
+	
+	OUTPLL(PLL_PWRMGT_CNTL, rinfo->save_regs[0]);
+	OUTPLL(CLK_PWRMGT_CNTL, rinfo->save_regs[1]);
+	OUTPLL(MCLK_CNTL, rinfo->save_regs[2]);
+	OUTPLL(SCLK_CNTL, rinfo->save_regs[3]);
+	OUTPLL(CLK_PIN_CNTL, rinfo->save_regs[4]);
+	OUTPLL(VCLK_ECP_CNTL, rinfo->save_regs[5]);
+	OUTPLL(PIXCLKS_CNTL, rinfo->save_regs[6]);
+	OUTPLL(MCLK_MISC, rinfo->save_regs[7]);
+	
+	OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]);
+	OUTREG(DISP_PWR_MAN, rinfo->save_regs[10]);
+	OUTREG(LVDS_GEN_CNTL, rinfo->save_regs[11]);
+	OUTREG(LVDS_PLL_CNTL,rinfo->save_regs[12]);
+	OUTREG(TV_DAC_CNTL, rinfo->save_regs[13]);
+	OUTREG(BUS_CNTL1, rinfo->save_regs[14]);
+	OUTREG(CRTC_OFFSET_CNTL, rinfo->save_regs[15]);
+	OUTREG(AGP_CNTL, rinfo->save_regs[16]);
+	OUTREG(CRTC_GEN_CNTL, rinfo->save_regs[17]);
+	OUTREG(CRTC2_GEN_CNTL, rinfo->save_regs[18]);
+
+	// wait VBL before that one  ?
+	OUTPLL(P2PLL_CNTL, rinfo->save_regs[8]);
+	
+	OUTREG(GPIOPAD_A, rinfo->save_regs[19]);
+	OUTREG(GPIOPAD_EN, rinfo->save_regs[20]);
+	OUTREG(GPIOPAD_MASK, rinfo->save_regs[21]);
+	OUTREG(ZV_LCDPAD_A, rinfo->save_regs[22]);
+	OUTREG(ZV_LCDPAD_EN, rinfo->save_regs[23]);
+	OUTREG(ZV_LCDPAD_MASK, rinfo->save_regs[24]);
+	OUTREG(GPIO_VGA_DDC, rinfo->save_regs[25]);
+	OUTREG(GPIO_DVI_DDC, rinfo->save_regs[26]);
+	OUTREG(GPIO_MONID, rinfo->save_regs[27]);
+	OUTREG(GPIO_CRT2_DDC, rinfo->save_regs[28]);
+}
+
+static void radeon_pm_disable_iopad(struct radeonfb_info *rinfo)
+{		
+	OUTREG(GPIOPAD_MASK, 0x0001ffff);
+	OUTREG(GPIOPAD_EN, 0x00000400);
+	OUTREG(GPIOPAD_A, 0x00000000);		
+        OUTREG(ZV_LCDPAD_MASK, 0x00000000);
+        OUTREG(ZV_LCDPAD_EN, 0x00000000);
+      	OUTREG(ZV_LCDPAD_A, 0x00000000); 	
+	OUTREG(GPIO_VGA_DDC, 0x00030000);
+	OUTREG(GPIO_DVI_DDC, 0x00000000);
+	OUTREG(GPIO_MONID, 0x00030000);
+	OUTREG(GPIO_CRT2_DDC, 0x00000000);
+}
+
+static void radeon_pm_program_v2clk(struct radeonfb_info *rinfo)
+{
+//
+//	u32 reg;
+//
+//	OUTPLL(P2PLL_REF_DIV, 0x0c);
+//
+//      .../... figure out what macos does here
+}
+
+static void radeon_pm_low_current(struct radeonfb_info *rinfo)
+{
+	u32 reg;
+
+	reg  = INREG(BUS_CNTL1);
+	reg &= ~BUS_CNTL1_MOBILE_PLATFORM_SEL_MASK;
+	reg |= BUS_CNTL1_AGPCLK_VALID | (1<<BUS_CNTL1_MOBILE_PLATFORM_SEL_SHIFT);
+	OUTREG(BUS_CNTL1, reg);
+	
+	reg  = INPLL(PLL_PWRMGT_CNTL);
+	reg |= PLL_PWRMGT_CNTL_SPLL_TURNOFF | PLL_PWRMGT_CNTL_PPLL_TURNOFF |
+		PLL_PWRMGT_CNTL_P2PLL_TURNOFF | PLL_PWRMGT_CNTL_TVPLL_TURNOFF;
+	reg &= ~PLL_PWRMGT_CNTL_SU_MCLK_USE_BCLK;
+	reg &= ~PLL_PWRMGT_CNTL_MOBILE_SU;
+	OUTPLL(PLL_PWRMGT_CNTL, reg);
+
+//	reg  = INPLL(TV_PLL_CNTL1);
+//	reg |= TV_PLL_CNTL1__TVPLL_RESET | TV_PLL_CNTL1__TVPLL_SLEEP;
+//	OUTPLL(TV_PLL_CNTL1, reg);
+	
+	reg  = INREG(TV_DAC_CNTL);
+	reg &= ~(TV_DAC_CNTL_BGADJ_MASK |TV_DAC_CNTL_DACADJ_MASK);
+	reg |=TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD | TV_DAC_CNTL_GDACPD |
+		TV_DAC_CNTL_BDACPD |
+		(8<<TV_DAC_CNTL_BGADJ__SHIFT) | (8<<TV_DAC_CNTL_DACADJ__SHIFT);
+	OUTREG(TV_DAC_CNTL, reg);
+	
+	reg  = INREG(TMDS_TRANSMITTER_CNTL);
+	reg &= ~(TMDS_PLL_EN |TMDS_PLLRST);
+	OUTREG(TMDS_TRANSMITTER_CNTL, reg);
+
+//	lvds_pll_cntl  = regr32(g, LVDS_PLL_CNTL);
+//	lvds_pll_cntl &= ~LVDS_PLL_CNTL__LVDS_PLL_EN;											
+//	lvds_pll_cntl |=  LVDS_PLL_CNTL__LVDS_PLL_RESET;	
+//	regw32(g, LVDS_PLL_CNTL, lvds_pll_cntl);
+
+	reg = INREG(DAC_CNTL);
+	reg &= ~DAC_CMP_EN;
+	OUTREG(DAC_CNTL, reg);
+
+	reg = INREG(DAC_CNTL2);
+	reg &= ~DAC2_CMP_EN;
+	OUTREG(DAC_CNTL2, reg);
+	
+	reg  = INREG(TV_DAC_CNTL);
+	reg &= ~TV_DAC_CNTL_DETECT;
+	OUTREG(TV_DAC_CNTL, reg);
+}
 
+static void radeon_pm_setup_for_suspend(struct radeonfb_info *rinfo)
+{
+	/* This code is disabled. It does what is in the pm_init
+	 * function of the MacOS driver code ATI sent me. However,
+	 * it doesn't fix my sleep problem, and is causing other issues
+	 * on wakeup (bascially the machine dying when switching consoles
+	 * I haven't had time to investigate this yet
+	 */
+#if 0
+	u32 disp_misc_cntl;
+	u32 disp_pwr_man;
+	u32 temp;
 
-static void fbcon_radeon_bmove(struct display *p, int srcy, int srcx,
-			       int dsty, int dstx, int height, int width)
+	// set SPLL, MPLL, PPLL, P2PLL, TVPLL, SCLK, MCLK, PCLK, P2CLK,
+	// TCLK and TEST_MODE to 0
+	temp = INPLL(CLK_PWRMGT_CNTL);
+	OUTPLL(CLK_PWRMGT_CNTL , temp & ~0xc00002ff);
+
+	// Turn on Power Management
+	temp = INPLL(CLK_PWRMGT_CNTL);
+	OUTPLL(CLK_PWRMGT_CNTL , temp | 0x00000400);
+
+	// Turn off display clock if using mobile chips
+	temp = INPLL(CLK_PWRMGT_CNTL);
+	OUTREG(CLK_PWRMGT_CNTL , temp | 0x00100000);
+
+	// Force PIXCLK_ALWAYS_ON and PIXCLK_DAC_ALWAYS_ON
+	temp = INPLL(VCLK_ECP_CNTL);
+	OUTPLL(VCLK_ECP_CNTL, temp & ~0x000000c0);
+
+	// Force ECP_FORCE_ON to 1
+	temp = INPLL(VCLK_ECP_CNTL);
+	OUTPLL(VCLK_ECP_CNTL, temp | 0x00040000);
+
+	// Force PIXCLK_BLEND_ALWAYS_ON and PIXCLK_GV_ALWAYS_ON
+	temp = INPLL(PIXCLKS_CNTL);
+       	OUTPLL(PIXCLKS_CNTL, temp & ~0x00001800);
+
+	// Forcing SCLK_CNTL to ON
+	OUTPLL(SCLK_CNTL, (INPLL(SCLK_CNTL)& 0x00000007) | 0xffff8000 );
+
+	// Set PM control over XTALIN pad
+	temp = INPLL(CLK_PIN_CNTL);
+	OUTPLL(CLK_PIN_CNTL, temp | 0x00080000);
+
+	// Force MCLK and YCLK and MC as dynamic
+    	temp = INPLL(MCLK_CNTL);
+	OUTPLL(MCLK_CNTL, temp & 0xffeaffff);
+
+	// PLL_TURNOFF
+	temp = INPLL(PLL_PWRMGT_CNTL);
+	OUTPLL(PLL_PWRMGT_CNTL, temp | 0x0000001f);
+ 
+	// set MOBILE_SU to 1 if M6 or DDR64 is detected
+	temp = INPLL(PLL_PWRMGT_CNTL);
+	OUTPLL(PLL_PWRMGT_CNTL, temp | 0x00010000);
+
+	// select PM access mode (PM_MODE_SEL) (use ACPI mode)
+//      temp = INPLL(PLL_PWRMGT_CNTL);
+//      OUTPLL(PLL_PWRMGT_CNTL, temp | 0x00002000);
+	temp = INPLL(PLL_PWRMGT_CNTL);
+        OUTPLL(PLL_PWRMGT_CNTL, temp & ~0x00002000);
+
+	// set DISP_MISC_CNTL register
+	disp_misc_cntl = INREG(DISP_MISC_CNTL);
+	disp_misc_cntl &= ~(	DISP_MISC_CNTL_SOFT_RESET_GRPH_PP |
+				DISP_MISC_CNTL_SOFT_RESET_SUBPIC_PP |
+				DISP_MISC_CNTL_SOFT_RESET_OV0_PP |
+				DISP_MISC_CNTL_SOFT_RESET_GRPH_SCLK |
+				DISP_MISC_CNTL_SOFT_RESET_SUBPIC_SCLK |
+				DISP_MISC_CNTL_SOFT_RESET_OV0_SCLK |
+				DISP_MISC_CNTL_SOFT_RESET_GRPH2_PP |
+				DISP_MISC_CNTL_SOFT_RESET_GRPH2_SCLK |
+				DISP_MISC_CNTL_SOFT_RESET_LVDS |
+				DISP_MISC_CNTL_SOFT_RESET_TMDS |
+				DISP_MISC_CNTL_SOFT_RESET_DIG_TMDS |
+				DISP_MISC_CNTL_SOFT_RESET_TV);
+	OUTREG(DISP_MISC_CNTL, disp_misc_cntl);
+
+	// set DISP_PWR_MAN register
+	disp_pwr_man = INREG(DISP_PWR_MAN);
+	// clau - 9.29.2000 - changes made to bit23:18 to set to 1 as requested by George
+	disp_pwr_man |= (DISP_PWR_MAN_DIG_TMDS_ENABLE_RST |
+                    DISP_PWR_MAN_TV_ENABLE_RST |
+ //                 DISP_PWR_MAN_AUTO_PWRUP_EN |
+                    DISP_PWR_MAN_DISP_D3_GRPH_RST |
+                    DISP_PWR_MAN_DISP_D3_SUBPIC_RST |
+                    DISP_PWR_MAN_DISP_D3_OV0_RST |
+                    DISP_PWR_MAN_DISP_D1D2_GRPH_RST |
+                    DISP_PWR_MAN_DISP_D1D2_SUBPIC_RST |
+                    DISP_PWR_MAN_DISP_D1D2_OV0_RST);
+	disp_pwr_man &= ~(DISP_PWR_MAN_DISP_PWR_MAN_D3_CRTC_EN |
+                    DISP_PWR_MAN_DISP2_PWR_MAN_D3_CRTC2_EN|
+                    DISP_PWR_MAN_DISP_D3_RST |
+                    DISP_PWR_MAN_DISP_D3_REG_RST);
+	OUTREG(DISP_PWR_MAN, disp_pwr_man);
+
+	// clau - 10.24.2000
+	// - add in setting for BUS_CNTL1 b27:26 = 0x01 and b31 = 0x1
+	// - add in setting for AGP_CNTL  b7:0 = 0x20
+	// - add in setting for DVI_DDC_DATA_OUT_EN b17:16 = 0x0
+
+	// the following settings (two lines) are applied at a later part of this function, only on mobile platform
+	// requres -mobile flag
+	OUTREG(BUS_CNTL1, (INREG(BUS_CNTL1) & 0xf3ffffff) | 0x04000000);
+	OUTREG(BUS_CNTL1,  INREG(BUS_CNTL1) | 0x80000000);
+	OUTREG(AGP_CNTL, (INREG(AGP_CNTL) & 0xffffff00) | 0x20);
+	OUTREG(GPIO_DVI_DDC, INREG(GPIO_DVI_DDC) & 0xfffcffff);
+
+	// yulee - 12.12.2000
+	// A12 only
+	// EN_MCLK_TRISTATE_IN_SUSPEND@MCLK_MISC = 1
+	// ACCESS_REGS_IN_SUSPEND@CLK_PIN_CNTL = 0
+	// only on mobile platform
+        OUTPLL(MCLK_MISC, INPLL(MCLK_MISC) | 0x00040000 );
+    	
+	// yulee -12.12.2000
+	// AGPCLK_VALID@BUS_CNTL1 = 1
+	// MOBILE_PLATFORM_SEL@BUS_CNTL1 = 01
+	// CRTC_STEREO_SYNC_OUT_EN@CRTC_OFFSET_CNTL = 0
+	// CG_CLK_TO_OUTPIN@CLK_PIN_CNTL = 0
+	// only on mobile platform
+        OUTPLL(CLK_PIN_CNTL, INPLL(CLK_PIN_CNTL ) & 0xFFFFF7FF );
+        OUTREG(BUS_CNTL1, (INREG(BUS_CNTL1 ) & 0xF3FFFFFF) | 0x84000000 );
+        OUTREG(CRTC_OFFSET_CNTL, INREG(CRTC_OFFSET_CNTL ) & 0xFFEFFFFF );
+
+        mdelay(100);
+#endif
+
+	/* Disable CRTCs */
+	OUTREG(CRTC_GEN_CNTL, (INREG(CRTC_GEN_CNTL) & ~CRTC_EN) | CRTC_DISP_REQ_EN_B);
+	OUTREG(CRTC2_GEN_CNTL, (INREG(CRTC2_GEN_CNTL) & ~CRTC2_EN) | CRTC2_DISP_REQ_EN_B);
+	(void)INREG(CRTC2_GEN_CNTL);
+	mdelay(17);
+}
+
+static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
 {
-	struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
-	u32 dp_cntl = DST_LAST_PEL;
+	u16 pwr_cmd;
 
-	srcx *= fontwidth(p);
-	srcy *= fontheight(p);
-	dstx *= fontwidth(p);
-	dsty *= fontheight(p);
-	width *= fontwidth(p);
-	height *= fontheight(p);
-
-	if (srcy < dsty) {
-		srcy += height - 1;
-		dsty += height - 1;
-	} else
-		dp_cntl |= DST_Y_TOP_TO_BOTTOM;
-
-	if (srcx < dstx) {
-		srcx += width - 1;
-		dstx += width - 1;
-	} else
-		dp_cntl |= DST_X_LEFT_TO_RIGHT;
+	if (!rinfo->pm_reg)
+		return;
 
-	radeon_fifo_wait(6);
-	OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
-				    GMC_BRUSH_NONE |
-				    GMC_SRC_DATATYPE_COLOR |
-				    ROP3_S |
-				    DP_SRC_SOURCE_MEMORY));
-	OUTREG(DP_WRITE_MSK, 0xffffffff);
-	OUTREG(DP_CNTL, dp_cntl);
-	OUTREG(SRC_Y_X, (srcy << 16) | srcx);
-	OUTREG(DST_Y_X, (dsty << 16) | dstx);
-	OUTREG(DST_HEIGHT_WIDTH, (height << 16) | width);
+	/* Set the chip into appropriate suspend mode (we use D2,
+	 * D3 would require a compete re-initialization of the chip,
+	 * including PCI config registers, clocks, AGP conf, ...)
+	 */
+	if (suspend) {
+		/* According to ATI, we should program V2CLK here, I have
+		 * to verify what's up exactly
+		 */
+		/* Save some registers */
+		radeon_pm_save_regs(rinfo);
+
+		/* Check that on M7 too, might work might not. M7 may also
+		 * need explicit enabling of PM
+		 */
+		if (rinfo->arch == RADEON_M6) {
+			/* Program V2CLK */
+			radeon_pm_program_v2clk(rinfo);
+		
+			/* Disable IO PADs */
+			radeon_pm_disable_iopad(rinfo);
+
+			/* Set low current */
+			radeon_pm_low_current(rinfo);
+
+			/* Prepare chip for power management */
+			radeon_pm_setup_for_suspend(rinfo);
+
+			/* Reset the MDLL */
+			OUTPLL(MDLL_CKO, INPLL(MDLL_CKO) | MCKOA_RESET);
+			(void)INPLL(MDLL_RDCKA);
+			OUTPLL(MDLL_CKO, INPLL(MDLL_CKO) & ~MCKOA_RESET);
+			(void)INPLL(MDLL_RDCKA);
+		}
+
+		/* Switch PCI power managment to D2. */
+		for (;;) {
+			pci_read_config_word(
+				rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
+				&pwr_cmd);
+			if (pwr_cmd & 2)
+				break;			
+			pci_write_config_word(
+				rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
+				(pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2);
+			mdelay(500);
+		}
+	} else {
+		/* Switch back PCI powermanagment to D0 */
+		mdelay(200);
+		pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, 0);
+		mdelay(500);
+
+		dbg_clk = INPLL(1);
+
+		/* Do we need that on M7 ? */
+		if (rinfo->arch == RADEON_M6) {
+			/* Restore the MDLL */
+			OUTPLL(MDLL_CKO, INPLL(MDLL_CKO) & ~MCKOA_RESET);
+			(void)INPLL(MDLL_CKO);			
+		}
+		
+		/* Restore some registers */
+		radeon_pm_restore_regs(rinfo);
+	}
 }
 
+/*
+ * Save the contents of the framebuffer when we go to sleep,
+ * and restore it when we wake up again.
+ */
 
+int radeon_sleep_notify(struct pmu_sleep_notifier *self, int when)
+{
+	struct radeonfb_info *rinfo;
+
+	for (rinfo = board_list; rinfo != NULL; rinfo = rinfo->next) {
+		struct fb_fix_screeninfo fix;
+		int nb;
+	        struct display *disp;  
+
+        	disp = (rinfo->currcon < 0) ? rinfo->info.disp : &fb_display[rinfo->currcon];
+
+		switch (rinfo->arch) {
+			case RADEON_M6:
+			case RADEON_M7:
+			case RADEON_M9:
+				break;
+			default:
+				return PBOOK_SLEEP_REFUSE;
+		}
+
+		radeonfb_get_fix(&fix, fg_console, (struct fb_info *)rinfo);
+		nb = fb_display[fg_console].var.yres * fix.line_length;
+
+		switch (when) {
+			case PBOOK_SLEEP_NOW:
+				acquire_console_sem();
+				disp->dispsw = &fbcon_dummy;
+
+				if (!noaccel) {
+					/* Make sure engine is reset */
+					radeon_engine_reset();
+					radeon_engine_idle();
+				}
+
+				/* Blank display and LCD */
+				radeonfb_blank(VESA_POWERDOWN+1,
+					       (struct fb_info *)rinfo);
+
+				/* Sleep */
+				rinfo->asleep = 1;
+				radeon_set_suspend(rinfo, 1);
+				release_console_sem();
+				
+				break;
+			case PBOOK_WAKE:
+				acquire_console_sem();
+				/* Wakeup */
+				radeon_set_suspend(rinfo, 0);
+
+				if (!noaccel)
+					radeon_engine_init(rinfo);
+				rinfo->asleep = 0;
+				radeon_set_dispsw(rinfo, disp);
+				radeon_load_video_mode(rinfo, &disp->var);
+				do_install_cmap(rinfo->currcon < 0 ? 0 : rinfo->currcon,
+						(struct fb_info *)rinfo);
+
+				radeonfb_blank(0, (struct fb_info *)rinfo);
+				release_console_sem();
+				printk("CLK_PIN_CNTL on wakeup was: %08x\n", dbg_clk);
+				break;
+		}
+	}
 
-static void fbcon_radeon_clear(struct vc_data *conp, struct display *p,
-			       int srcy, int srcx, int height, int width)
+	return PBOOK_SLEEP_OK;
+}
+
+#endif /* CONFIG_PMAC_PBOOK */
+
+static int radeonfb_pci_register (struct pci_dev *pdev,
+				  const struct pci_device_id *ent)
 {
-	struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
-	u32 clr;
+	struct radeonfb_info *rinfo;
+	struct radeon_chip_info *rci = &radeon_chip_info[ent->driver_data];
+	u32 tmp;
 
-	clr = attr_bgcol_ec(p, conp);
-	clr |= (clr << 8);
-	clr |= (clr << 16);
+	RTRACE("radeonfb_pci_register BEGIN\n");
 
-	srcx *= fontwidth(p);
-	srcy *= fontheight(p);
-	width *= fontwidth(p);
-	height *= fontheight(p);
+	/* Enable device in PCI config */
+	if (pci_enable_device(pdev) != 0) {
+		printk(KERN_ERR "radeonfb: Cannot enable PCI device\n");
+		return -ENODEV;
+	}
 
-	radeon_fifo_wait(6);
-	OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
-				    GMC_BRUSH_SOLID_COLOR |
-				    GMC_SRC_DATATYPE_COLOR |
-				    ROP3_P));
-	OUTREG(DP_BRUSH_FRGD_CLR, clr);
-	OUTREG(DP_WRITE_MSK, 0xffffffff);
-	OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
-	OUTREG(DST_Y_X, (srcy << 16) | srcx);
-	OUTREG(DST_WIDTH_HEIGHT, (width << 16) | height);
+	rinfo = kmalloc (sizeof (struct radeonfb_info), GFP_KERNEL);
+	if (!rinfo) {
+		printk ("radeonfb: could not allocate memory\n");
+		return -ENODEV;
+	}
+
+	memset (rinfo, 0, sizeof (struct radeonfb_info));
+	//info = &rinfo->info;
+	rinfo->pdev = pdev;
+	strcpy(rinfo->name, rci->name);
+	rinfo->arch = rci->arch;
+
+	/* Set base addrs */
+	rinfo->fb_base_phys = pci_resource_start (pdev, 0);
+	rinfo->mmio_base_phys = pci_resource_start (pdev, 2);
+
+	/* request the mem regions */
+	if (!request_mem_region (rinfo->fb_base_phys,
+				 pci_resource_len(pdev, 0), "radeonfb")) {
+		printk ("radeonfb: cannot reserve FB region\n");
+		kfree (rinfo);
+		return -ENODEV;
+	}
+
+	if (!request_mem_region (rinfo->mmio_base_phys,
+				 pci_resource_len(pdev, 2), "radeonfb")) {
+		printk ("radeonfb: cannot reserve MMIO region\n");
+		release_mem_region (rinfo->fb_base_phys,
+				    pci_resource_len(pdev, 0));
+		kfree (rinfo);
+		return -ENODEV;
+	}
+
+	/* map the regions */
+	rinfo->mmio_base = (u32) ioremap (rinfo->mmio_base_phys,
+				    		    RADEON_REGSIZE);
+	if (!rinfo->mmio_base) {
+		printk ("radeonfb: cannot map MMIO\n");
+		release_mem_region (rinfo->mmio_base_phys,
+				    pci_resource_len(pdev, 2));
+		release_mem_region (rinfo->fb_base_phys,
+				    pci_resource_len(pdev, 0));
+		kfree (rinfo);
+		return -ENODEV;
+	}
+
+	rinfo->chipset = pdev->device;
+
+	switch (rinfo->arch) {
+		case RADEON_R100:
+			rinfo->hasCRTC2 = 0;
+			break;
+		default:
+			/* all the rest have it */
+			rinfo->hasCRTC2 = 1;
+			break;
+	}
+#if 0
+	if (rinfo->arch == RADEON_M7) {
+		/*
+		 * Noticed some errors in accel with M7, will have to work these out...
+		 */
+		noaccel = 1;
+	}
+#endif
+	if (mirror)
+		printk("radeonfb: mirroring display to CRT\n");
+
+	/* framebuffer size */
+	tmp = INREG(CONFIG_MEMSIZE);
+
+	/* mem size is bits [28:0], mask off the rest */
+	rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
+
+	/* ram type */
+	tmp = INREG(MEM_SDRAM_MODE_REG);
+	switch ((MEM_CFG_TYPE & tmp) >> 30) {
+		case 0:
+			/* SDR SGRAM (2:1) */
+			strcpy(rinfo->ram_type, "SDR SGRAM");
+			rinfo->ram.ml = 4;
+			rinfo->ram.mb = 4;
+			rinfo->ram.trcd = 1;
+			rinfo->ram.trp = 2;
+			rinfo->ram.twr = 1;
+			rinfo->ram.cl = 2;
+			rinfo->ram.loop_latency = 16;
+			rinfo->ram.rloop = 16;
+	
+			break;
+		case 1:
+			/* DDR SGRAM */
+			strcpy(rinfo->ram_type, "DDR SGRAM");
+			rinfo->ram.ml = 4;
+			rinfo->ram.mb = 4;
+			rinfo->ram.trcd = 3;
+			rinfo->ram.trp = 3;
+			rinfo->ram.twr = 2;
+			rinfo->ram.cl = 3;
+			rinfo->ram.tr2w = 1;
+			rinfo->ram.loop_latency = 16;
+			rinfo->ram.rloop = 16;
+
+			break;
+		default:
+			/* 64-bit SDR SGRAM */
+			strcpy(rinfo->ram_type, "SDR SGRAM 64");
+			rinfo->ram.ml = 4;
+			rinfo->ram.mb = 8;
+			rinfo->ram.trcd = 3;
+			rinfo->ram.trp = 3;
+			rinfo->ram.twr = 1;
+			rinfo->ram.cl = 3;
+			rinfo->ram.tr2w = 1;
+			rinfo->ram.loop_latency = 17;
+			rinfo->ram.rloop = 17;
+
+			break;
+	}
+
+	rinfo->bios_seg = radeon_find_rom(rinfo);
+	radeon_get_pllinfo(rinfo, rinfo->bios_seg);
+
+	/*
+	 * Hack to get around some busted production M6's
+	 * reporting no ram
+	 */
+	if (rinfo->video_ram == 0) {
+		switch (pdev->device) {
+			case PCI_DEVICE_ID_ATI_RADEON_LY:
+			case PCI_DEVICE_ID_ATI_RADEON_LZ:
+				rinfo->video_ram = 8192;
+				break;
+			default:
+				break;
+		}
+	}
+
+
+	RTRACE("radeonfb: probed %s %dk videoram\n", (rinfo->ram_type), (rinfo->video_ram/1024));
+
+#if !defined(__powerpc__)
+	radeon_get_moninfo(rinfo);
+#else
+	switch (pdev->device) {
+		case PCI_DEVICE_ID_ATI_RADEON_LW:
+		case PCI_DEVICE_ID_ATI_RADEON_LX:
+		case PCI_DEVICE_ID_ATI_RADEON_LY:
+		case PCI_DEVICE_ID_ATI_RADEON_LZ:
+			rinfo->dviDisp_type = MT_LCD;
+			break;
+		default:
+			radeon_get_moninfo(rinfo);
+			break;
+	}
+#endif
+
+	radeon_get_EDID(rinfo);
+
+	if ((rinfo->dviDisp_type == MT_DFP) || (rinfo->dviDisp_type == MT_LCD) ||
+	    (rinfo->crtDisp_type == MT_DFP)) {
+		if (!radeon_get_dfpinfo(rinfo)) {
+			iounmap ((void*)rinfo->mmio_base);
+			release_mem_region (rinfo->mmio_base_phys,
+					    pci_resource_len(pdev, 2));
+			release_mem_region (rinfo->fb_base_phys,
+					    pci_resource_len(pdev, 0));
+			kfree (rinfo);
+			return -ENODEV;
+		}
+	}
+
+	rinfo->fb_base = (u32) ioremap (rinfo->fb_base_phys,
+				  		  rinfo->video_ram);
+	if (!rinfo->fb_base) {
+		printk ("radeonfb: cannot map FB\n");
+		iounmap ((void*)rinfo->mmio_base);
+		release_mem_region (rinfo->mmio_base_phys,
+				    pci_resource_len(pdev, 2));
+		release_mem_region (rinfo->fb_base_phys,
+				    pci_resource_len(pdev, 0));
+		kfree (rinfo);
+		return -ENODEV;
+	}
+
+	/* I SHOULD FIX THAT CRAP ! I should probably mimmic XFree DRI
+	 * driver setup here.
+	 * 
+	 * On PPC, OF based cards setup the internal memory
+	 * mapping in strange ways. We change it so that the
+	 * framebuffer is mapped at 0 and given half of the card's
+	 * address space (2Gb). AGP is mapped high (0xe0000000) and
+	 * can use up to 512Mb. Once DRI is fully implemented, we
+	 * will have to setup the PCI remapper to remap the agp_special_page
+	 * memory page somewhere between those regions so that the card
+	 * use a normal PCI bus master cycle to access the ring read ptr.
+	 * --BenH.
+	 */
+#ifdef CONFIG_ALL_PPC
+	if (rinfo->hasCRTC2)
+		OUTREG(CRTC2_GEN_CNTL,
+			(INREG(CRTC2_GEN_CNTL) & ~CRTC2_EN) | CRTC2_DISP_REQ_EN_B);
+	OUTREG(CRTC_EXT_CNTL, INREG(CRTC_EXT_CNTL) | CRTC_DISPLAY_DIS);
+	OUTREG(MC_FB_LOCATION, 0x7fff0000);
+	OUTREG(MC_AGP_LOCATION, 0xffffe000);
+	OUTREG(DISPLAY_BASE_ADDR, 0x00000000);
+	if (rinfo->hasCRTC2)
+		OUTREG(CRTC2_DISPLAY_BASE_ADDR, 0x00000000);
+	OUTREG(SRC_OFFSET, 0x00000000);
+	OUTREG(DST_OFFSET, 0x00000000);
+	mdelay(10);
+	OUTREG(CRTC_EXT_CNTL, INREG(CRTC_EXT_CNTL) & ~CRTC_DISPLAY_DIS);
+#endif /* CONFIG_ALL_PPC */
+
+	/* save current mode regs before we switch into the new one
+	 * so we can restore this upon __exit
+	 */
+	radeon_save_state (rinfo, &rinfo->init_state);
+
+	if (!noaccel) {
+		/* initialize the engine */
+		radeon_engine_init (rinfo);
+	}
+
+	/* set all the vital stuff */
+	radeon_set_fbinfo (rinfo);
+
+	pci_set_drvdata(pdev, rinfo);
+	rinfo->next = board_list;
+	board_list = rinfo;
+
+	if (register_framebuffer ((struct fb_info *) rinfo) < 0) {
+		printk ("radeonfb: could not register framebuffer\n");
+		iounmap ((void*)rinfo->fb_base);
+		iounmap ((void*)rinfo->mmio_base);
+		release_mem_region (rinfo->mmio_base_phys,
+				    pci_resource_len(pdev, 2));
+		release_mem_region (rinfo->fb_base_phys,
+				    pci_resource_len(pdev, 0));
+		kfree (rinfo);
+		return -ENODEV;
+	}
+
+#ifdef CONFIG_MTRR
+	rinfo->mtrr_hdl = nomtrr ? -1 : mtrr_add(rinfo->fb_base_phys,
+						 rinfo->video_ram,
+						 MTRR_TYPE_WRCOMB, 1);
+#endif
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+	if (rinfo->dviDisp_type == MT_LCD)
+		register_backlight_controller(&radeon_backlight_controller,
+					      rinfo, "ati");
+#endif
+
+#ifdef CONFIG_PMAC_PBOOK
+	if (rinfo->dviDisp_type == MT_LCD) {
+		rinfo->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM);
+		pmu_register_sleep_notifier(&radeon_sleep_notifier);
+	}
+#endif
+
+	printk ("radeonfb: ATI Radeon %s %s %d MB\n", rinfo->name, rinfo->ram_type,
+		(rinfo->video_ram/(1024*1024)));
+
+	if (rinfo->hasCRTC2) {
+		printk("radeonfb: DVI port %s monitor connected\n",
+			GET_MON_NAME(rinfo->dviDisp_type));
+		printk("radeonfb: CRT port %s monitor connected\n",
+			GET_MON_NAME(rinfo->crtDisp_type));
+	} else {
+		printk("radeonfb: CRT port %s monitor connected\n",
+			GET_MON_NAME(rinfo->crtDisp_type));
+	}
+
+	RTRACE("radeonfb_pci_register END\n");
+
+	return 0;
 }
 
 
 
+static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
+{
+        struct radeonfb_info *rinfo = pci_get_drvdata(pdev);
+ 
+        if (!rinfo)
+                return;
+ 
+	/* restore original state
+	 * 
+	 * Doesn't quite work yet, possibly because of the PPC hacking
+	 * I do on startup, disable for now. --BenH
+	 */
+        radeon_write_mode (rinfo, &rinfo->init_state);
+ 
+#ifdef CONFIG_MTRR
+	if (rinfo->mtrr_hdl >= 0)
+		mtrr_del(rinfo->mtrr_hdl, 0, 0);
+#endif
+
+        unregister_framebuffer ((struct fb_info *) rinfo);
+                
+        iounmap ((void*)rinfo->mmio_base);
+        iounmap ((void*)rinfo->fb_base);
+ 
+	release_mem_region (rinfo->mmio_base_phys,
+			    pci_resource_len(pdev, 2));
+	release_mem_region (rinfo->fb_base_phys,
+			    pci_resource_len(pdev, 0));
+        
+        kfree (rinfo);
+}
+
 
-#ifdef FBCON_HAS_CFB8
-static struct display_switch fbcon_radeon8 = {
-	.setup =		fbcon_cfb8_setup,
-	.bmove =		fbcon_radeon_bmove,
-	.clear =		fbcon_radeon_clear,
-	.putc =			fbcon_cfb8_putc,
-	.putcs =		fbcon_cfb8_putcs,
-	.revc =			fbcon_cfb8_revc,
-	.clear_margins =	fbcon_cfb8_clear_margins,
-	.fontwidthmask =	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+static struct pci_driver radeonfb_driver = {
+	name:		"radeonfb",
+	id_table:	radeonfb_pci_table,
+	probe:		radeonfb_pci_register,
+	remove:		__devexit_p(radeonfb_pci_unregister),
 };
+
+
+int __init radeonfb_init (void)
+{
+	return pci_module_init (&radeonfb_driver);
+}
+
+
+void __exit radeonfb_exit (void)
+{
+	pci_unregister_driver (&radeonfb_driver);
+}
+
+
+int __init radeonfb_setup (char *options)
+{
+        char *this_opt;
+
+        if (!options || !*options)
+                return 0;
+ 
+	while ((this_opt = strsep (&options, ",")) != NULL) {
+		if (!*this_opt)
+			continue;
+                if (!strncmp(this_opt, "noaccel", 7)) {
+			noaccel = 1;
+                } else if (!strncmp(this_opt, "mirror", 6)) {
+			mirror = 1;
+		} else if (!strncmp(this_opt, "dfp", 3)) {
+			force_dfp = 1;
+		} else if (!strncmp(this_opt, "panel_yres:", 11)) {
+			panel_yres = simple_strtoul((this_opt+11), NULL, 0);
+		} else if (!strncmp(this_opt, "nomtrr", 6)) {
+			nomtrr = 1;
+                } else
+			mode_option = this_opt;
+        }
+
+	return 0;
+}
+
+#ifdef MODULE
+module_init(radeonfb_init);
+module_exit(radeonfb_exit);
 #endif
+
+
+MODULE_AUTHOR("Ani Joshi");
+MODULE_DESCRIPTION("framebuffer driver for ATI Radeon chipset");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/retz3fb.c b/drivers/video/retz3fb.c
--- a/drivers/video/retz3fb.c	Mon Dec  9 18:46:51 2002
+++ b/drivers/video/retz3fb.c	Mon Dec  9 18:46:51 2002
@@ -1430,7 +1430,7 @@
 			return -EINVAL;
 
 		printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of "
-		       "video memory\n", GET_FB_IDX(fb_info->node),
+		       "video memory\n", minor(fb_info->node),
 		       fb_info->modename, zinfo->fbsize>>10);
 
 		/* FIXME: This driver cannot be unloaded yet */
diff -Nru a/drivers/video/riva/Makefile b/drivers/video/riva/Makefile
--- a/drivers/video/riva/Makefile	Mon Dec  9 18:46:34 2002
+++ b/drivers/video/riva/Makefile	Mon Dec  9 18:46:34 2002
@@ -4,6 +4,6 @@
 
 obj-$(CONFIG_FB_RIVA) += rivafb.o
 
-rivafb-objs := fbdev.o riva_hw.o accel.o
+rivafb-objs := fbdev.o riva_hw.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/drivers/video/riva/accel.c b/drivers/video/riva/accel.c
--- a/drivers/video/riva/accel.c	Mon Dec  9 18:46:52 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,427 +0,0 @@
-/*
- * linux/drivers/video/accel.c - nVidia RIVA 128/TNT/TNT2 fb driver
- *
- * Copyright 2000 Jindrich Makovicka, Ani Joshi
- *
- * 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 "rivafb.h"
-
-/* acceleration routines */
-
-inline void wait_for_idle(struct rivafb_info *rinfo)
-{
-	while (rinfo->riva.Busy(&rinfo->riva));
-}
-
-/* set copy ROP, no mask */
-static void riva_setup_ROP(struct rivafb_info *rinfo)
-{
-	RIVA_FIFO_FREE(rinfo->riva, Patt, 5);
-	rinfo->riva.Patt->Shape = 0;
-	rinfo->riva.Patt->Color0 = 0xffffffff;
-	rinfo->riva.Patt->Color1 = 0xffffffff;
-	rinfo->riva.Patt->Monochrome[0] = 0xffffffff;
-	rinfo->riva.Patt->Monochrome[1] = 0xffffffff;
-
-	RIVA_FIFO_FREE(rinfo->riva, Rop, 1);
-	rinfo->riva.Rop->Rop3 = 0xCC;
-}
-
-void riva_setup_accel(struct rivafb_info *rinfo)
-{
-	RIVA_FIFO_FREE(rinfo->riva, Clip, 2);
-	rinfo->riva.Clip->TopLeft     = 0x0;
-	rinfo->riva.Clip->WidthHeight = 0x80008000;
-	riva_setup_ROP(rinfo);
-	wait_for_idle(rinfo);
-}
-
-static void riva_rectfill(struct rivafb_info *rinfo, int sy,
-			  int sx, int height, int width, u_int color)
-{
-	RIVA_FIFO_FREE(rinfo->riva, Bitmap, 1);
-	rinfo->riva.Bitmap->Color1A = color;
-
-	RIVA_FIFO_FREE(rinfo->riva, Bitmap, 2);
-	rinfo->riva.Bitmap->UnclippedRectangle[0].TopLeft     = (sx << 16) | sy; 
-	rinfo->riva.Bitmap->UnclippedRectangle[0].WidthHeight = (width << 16) | height;
-}
-
-static void fbcon_riva_bmove(struct display *p, int sy, int sx, int dy, int dx,
-			    int height, int width)
-{
-	struct rivafb_info *rinfo = (struct rivafb_info *)(p->fb_info);
-
-	sx *= fontwidth(p);
-	sy *= fontheight(p);
-	dx *= fontwidth(p);
-	dy *= fontheight(p);
-	width *= fontwidth(p);
-	height *= fontheight(p);
-
-	RIVA_FIFO_FREE(rinfo->riva, Blt, 3);
-	rinfo->riva.Blt->TopLeftSrc  = (sy << 16) | sx;
-	rinfo->riva.Blt->TopLeftDst  = (dy << 16) | dx;
-	rinfo->riva.Blt->WidthHeight = (height  << 16) | width;
-}
-
-static void riva_clear_margins(struct vc_data *conp, struct display *p,
-				int bottom_only, u32 bgx)
-{
-	struct rivafb_info *rinfo = (struct rivafb_info *)(p->fb_info);
-
-	unsigned int right_start = conp->vc_cols*fontwidth(p);
-	unsigned int bottom_start = conp->vc_rows*fontheight(p);
-	unsigned int right_width, bottom_width;
-
-	if (!bottom_only && (right_width = p->var.xres - right_start))
-		riva_rectfill(rinfo, 0, right_start, p->var.yres_virtual,
-			      right_width, bgx);
-	if ((bottom_width = p->var.yres - bottom_start))
-		riva_rectfill(rinfo, p->var.yoffset + bottom_start, 0,
-			      bottom_width, right_start, bgx);
-}
-
-static u8 byte_rev[256] = {
-	0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
-	0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 
-	0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 
-	0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 
-	0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 
-	0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 
-	0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 
-	0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 
-	0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 
-	0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 
-	0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 
-	0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 
-	0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 
-	0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 
-	0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 
-	0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
-};
-
-static inline void fbcon_reverse_order(u32 *l)
-{
-	u8 *a = (u8 *)l;
-	*a++ = byte_rev[*a];
-/*	*a++ = byte_rev[*a];
-	*a++ = byte_rev[*a];*/
-	*a = byte_rev[*a];
-}
-
-static void fbcon_riva_writechr(struct vc_data *conp, struct display *p,
-			        int c, int fgx, int bgx, int yy, int xx)
-{
-	u8 *cdat;
-	struct rivafb_info *rinfo = (struct rivafb_info *)(p->fb_info);
-	int w, h;
-	volatile u32 *d;
-	u32 cdat2;
-	int i, j, cnt;
-
-	w = fontwidth(p);
-	h = fontheight(p);
-
-	if (w <= 8)
-		cdat = p->fontdata + (c & p->charmask) * h;
-	else
-		cdat = p->fontdata + ((c & p->charmask) * h << 1);
-
-        RIVA_FIFO_FREE(rinfo->riva, Bitmap, 7);
-        rinfo->riva.Bitmap->ClipE.TopLeft     = (yy << 16) | (xx & 0xFFFF);
-        rinfo->riva.Bitmap->ClipE.BottomRight = ((yy+h) << 16) | ((xx+w) & 0xffff);
-        rinfo->riva.Bitmap->Color0E           = bgx;
-        rinfo->riva.Bitmap->Color1E           = fgx;
-        rinfo->riva.Bitmap->WidthHeightInE  = (h << 16) | 32;
-        rinfo->riva.Bitmap->WidthHeightOutE = (h << 16) | 32;
-        rinfo->riva.Bitmap->PointE          = (yy << 16) | (xx & 0xFFFF);
-	
-	d = &rinfo->riva.Bitmap->MonochromeData01E;
-	for (i = h; i > 0; i-=16) {
-		if (i >= 16)
-			cnt = 16;
-		else
-			cnt = i;
-		RIVA_FIFO_FREE(rinfo->riva, Bitmap, cnt);
-		for (j = 0; j < cnt; j++) {
-			if (w <= 8) 
-				cdat2 = *cdat++;
-			else
-				cdat2 = *((u16*)cdat)++;
-			fbcon_reverse_order(&cdat2);
-			d[j] = cdat2;
-		}
-	}
-}
-
-#ifdef FBCON_HAS_CFB8
-void fbcon_riva8_setup(struct display *p)
-{
-    p->next_line = p->line_length ? p->line_length : p->var.xres_virtual;
-    p->next_plane = 0;
-}
-
-static void fbcon_riva8_clear(struct vc_data *conp, struct display *p, int sy,
-			     int sx, int height, int width)
-{
-	u32 bgx;
-
-	struct rivafb_info *rinfo = (struct rivafb_info *)(p->fb_info);
-
-	bgx = attr_bgcol_ec(p, conp);
-
-	sx *= fontwidth(p);
-	sy *= fontheight(p);
-	width *= fontwidth(p);
-	height *= fontheight(p);
-
-	riva_rectfill(rinfo, sy, sx, height, width, bgx);
-}
-
-static void fbcon_riva8_putc(struct vc_data *conp, struct display *p, int c,
-			    int yy, int xx)
-{
-	u32 fgx,bgx;
-
-	fgx = attr_fgcol(p,c);
-	bgx = attr_bgcol(p,c);
-	
-	xx *= fontwidth(p);
-	yy *= fontheight(p);
-
-	fbcon_riva_writechr(conp, p, c, fgx, bgx, yy, xx);
-}
-
-static void fbcon_riva8_putcs(struct vc_data *conp, struct display *p,
-			     const unsigned short *s, int count, int yy,
-			     int xx)
-{
-	u16 c;
-	u32 fgx,bgx;
-
-	xx *= fontwidth(p);
-	yy *= fontheight(p);
-
-	c = scr_readw(s);
-	fgx = attr_fgcol(p, c);
-	bgx = attr_bgcol(p, c);
-	while (count--) {
-		c = scr_readw(s++);
-		fbcon_riva_writechr(conp, p, c, fgx, bgx, yy, xx);
-		xx += fontwidth(p);
-	}
-}
-
-static void fbcon_riva8_revc(struct display *p, int xx, int yy)
-{
-	struct rivafb_info *rinfo = (struct rivafb_info *) (p->fb_info);
-
-	xx *= fontwidth(p);
-	yy *= fontheight(p);
-
-	RIVA_FIFO_FREE(rinfo->riva, Rop, 1);
-	rinfo->riva.Rop->Rop3 = 0x66; // XOR
-	riva_rectfill(rinfo, yy, xx, fontheight(p), fontwidth(p), 0x0f);
-	RIVA_FIFO_FREE(rinfo->riva, Rop, 1);
-	rinfo->riva.Rop->Rop3 = 0xCC; // back to COPY
-}
-
-static void fbcon_riva8_clear_margins(struct vc_data *conp, struct display *p,
-				       int bottom_only)
-{
-	riva_clear_margins(conp, p, bottom_only, attr_bgcol_ec(p, conp));
-}
-
-struct display_switch fbcon_riva8 = {
-	.setup =	fbcon_riva8_setup,
-	.bmove =	fbcon_riva_bmove,
-	.clear =	fbcon_riva8_clear,
-	.putc =		fbcon_riva8_putc,
-	.putcs =	fbcon_riva8_putcs,
-	.revc =		fbcon_riva8_revc,
-	.clear_margins =fbcon_riva8_clear_margins,
-	.fontwidthmask =FONTWIDTHRANGE(4, 16)
-};
-#endif
-
-#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
-static void fbcon_riva1632_revc(struct display *p, int xx, int yy)
-{
-	struct rivafb_info *rinfo = (struct rivafb_info *) (p->fb_info);
-
-	xx *= fontwidth(p);
-	yy *= fontheight(p);
-
-	RIVA_FIFO_FREE(rinfo->riva, Rop, 1);
-	rinfo->riva.Rop->Rop3 = 0x66; // XOR
-	riva_rectfill(rinfo, yy, xx, fontheight(p), fontwidth(p), 0xffffffff);
-	RIVA_FIFO_FREE(rinfo->riva, Rop, 1);
-	rinfo->riva.Rop->Rop3 = 0xCC; // back to COPY
-}
-#endif
-
-#ifdef FBCON_HAS_CFB16
-void fbcon_riva16_setup(struct display *p)
-{
-    p->next_line = p->line_length ? p->line_length : p->var.xres_virtual<<1;
-    p->next_plane = 0;
-}
-
-static void fbcon_riva16_clear(struct vc_data *conp, struct display *p, int sy,
-			     int sx, int height, int width)
-{
-	u32 bgx;
-
-	struct rivafb_info *rinfo = (struct rivafb_info *)(p->fb_info);
-
-	bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-
-	sx *= fontwidth(p);
-	sy *= fontheight(p);
-	width *= fontwidth(p);
-	height *= fontheight(p);
-
-	riva_rectfill(rinfo, sy, sx, height, width, bgx);
-}
-
-static inline void convert_bgcolor_16(u32 *col)
-{
-	*col = ((*col & 0x00007C00) << 9)
-             | ((*col & 0x000003E0) << 6)
-             | ((*col & 0x0000001F) << 3)
-             |          0xFF000000;
-}
-
-static void fbcon_riva16_putc(struct vc_data *conp, struct display *p, int c,
-			    int yy, int xx)
-{
-	u32 fgx,bgx;
-
-	fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p,c)];
-	bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p,c)];
-	if (p->var.green.length == 6)
-		convert_bgcolor_16(&bgx);
-	xx *= fontwidth(p);
-	yy *= fontheight(p);
-
-	fbcon_riva_writechr(conp, p, c, fgx, bgx, yy, xx);
-}
-
-static void fbcon_riva16_putcs(struct vc_data *conp, struct display *p,
-			     const unsigned short *s, int count, int yy,
-			     int xx)
-{
-	u16 c;
-	u32 fgx,bgx;
-
-	xx *= fontwidth(p);
-	yy *= fontheight(p);
-
-	c = scr_readw(s);
-	fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)];
-	bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)];
-	if (p->var.green.length == 6)
-		convert_bgcolor_16(&bgx);
-	while (count--) {
-		c = scr_readw(s++);
-		fbcon_riva_writechr(conp, p, c, fgx, bgx, yy, xx);
-		xx += fontwidth(p);
-	}
-}
-
-static void fbcon_riva16_clear_margins(struct vc_data *conp, struct display *p,
-				       int bottom_only)
-{
-	riva_clear_margins(conp, p, bottom_only, ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)]);
-}
-
-struct display_switch fbcon_riva16 = {
-	.setup =	fbcon_riva16_setup,
-	.bmove =	fbcon_riva_bmove,
-	.clear =	fbcon_riva16_clear,
-	.putc =		fbcon_riva16_putc,
-	.putcs =	fbcon_riva16_putcs,
-	.revc =		fbcon_riva1632_revc,
-	.clear_margins =fbcon_riva16_clear_margins,
-	.fontwidthmask =FONTWIDTHRANGE(4, 16)
-};
-#endif
-
-#ifdef FBCON_HAS_CFB32
-void fbcon_riva32_setup(struct display *p)
-{
-    p->next_line = p->line_length ? p->line_length : p->var.xres_virtual<<2;
-    p->next_plane = 0;
-}
-
-static void fbcon_riva32_clear(struct vc_data *conp, struct display *p, int sy,
-			     int sx, int height, int width)
-{
-	u32 bgx;
-
-	struct rivafb_info *rinfo = (struct rivafb_info *)(p->fb_info);
-
-	bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-
-	sx *= fontwidth(p);
-	sy *= fontheight(p);
-	width *= fontwidth(p);
-	height *= fontheight(p);
-
-	riva_rectfill(rinfo, sy, sx, height, width, bgx);
-}
-
-static void fbcon_riva32_putc(struct vc_data *conp, struct display *p, int c,
-			    int yy, int xx)
-{
-	u32 fgx,bgx;
-
-	fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p,c)];
-	bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p,c)];
-	xx *= fontwidth(p);
-	yy *= fontheight(p);
-	fbcon_riva_writechr(conp, p, c, fgx, bgx, yy, xx);
-}
-
-static void fbcon_riva32_putcs(struct vc_data *conp, struct display *p,
-			     const unsigned short *s, int count, int yy,
-			     int xx)
-{
-	u16 c;
-	u32 fgx,bgx;
-
-	xx *= fontwidth(p);
-	yy *= fontheight(p);
-
-	c = scr_readw(s);
-	fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p, c)];
-	bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p, c)];
-	while (count--) {
-		c = scr_readw(s++);
-		fbcon_riva_writechr(conp, p, c, fgx, bgx, yy, xx);
-		xx += fontwidth(p);
-	}
-}
-
-static void fbcon_riva32_clear_margins(struct vc_data *conp, struct display *p,
-				       int bottom_only)
-{
-	riva_clear_margins(conp, p, bottom_only, ((u32 *)p->dispsw_data)[attr_bgcol_ec(p, conp)]);
-}
-
-struct display_switch fbcon_riva32 = {
-	.setup =	fbcon_riva32_setup,
-	.bmove =	fbcon_riva_bmove,
-	.clear =	fbcon_riva32_clear,
-	.putc =		fbcon_riva32_putc,
-	.putcs =	fbcon_riva32_putcs,
-	.revc =		fbcon_riva1632_revc,
-	.clear_margins =fbcon_riva32_clear_margins,
-	.fontwidthmask =FONTWIDTHRANGE(4, 16)
-};
-#endif
diff -Nru a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
--- a/drivers/video/riva/fbdev.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/video/riva/fbdev.c	Mon Dec  9 18:46:50 2002
@@ -25,7 +25,6 @@
  * Known bugs and issues:
  *	restoring text mode fails
  *	doublescan modes are broken
- *	option 'noaccel' has no effect
  */
 
 #include <linux/config.h>
@@ -34,17 +33,15 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/selection.h>
 #include <linux/tty.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
-#include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/pci.h>
-#include <linux/console.h>
 #ifdef CONFIG_MTRR
 #include <asm/mtrr.h>
 #endif
+
 #include "rivafb.h"
 #include "nvreg.h"
 
@@ -52,12 +49,8 @@
 #error This driver requires PCI support.
 #endif
 
-
-
 /* version number of this driver */
-#define RIVAFB_VERSION "0.9.2a"
-
-
+#define RIVAFB_VERSION "0.9.3"
 
 /* ------------------------------------------------------------------------- *
  *
@@ -109,10 +102,7 @@
 
 static int rivafb_blank(int blank, struct fb_info *info);
 
-extern void riva_setup_accel(struct rivafb_info *rinfo);
-extern inline void wait_for_idle(struct rivafb_info *rinfo);
-
-
+extern inline void wait_for_idle(struct riva_par *par);
 
 /* ------------------------------------------------------------------------- *
  *
@@ -136,6 +126,11 @@
 	CH_GEFORCE2_GTS,
 	CH_GEFORCE2_ULTRA,
 	CH_QUADRO2_PRO,
+	CH_GEFORCE2_GO,
+        CH_GEFORCE3,
+        CH_GEFORCE3_1,
+        CH_GEFORCE3_2,
+        CH_QUADRO_DDC
 };
 
 /* directly indexed by riva_chips enum, above */
@@ -158,6 +153,11 @@
 	{ "GeForce2-GTS", NV_ARCH_10},
 	{ "GeForce2-ULTRA", NV_ARCH_10},
 	{ "Quadro2-PRO", NV_ARCH_10},
+        { "GeForce2-Go", NV_ARCH_10},
+        { "GeForce3", NV_ARCH_20}, 
+        { "GeForce3 Ti 200", NV_ARCH_20},
+        { "GeForce3 Ti 500", NV_ARCH_20},
+        { "Quadro DDC", NV_ARCH_20}
 };
 
 static struct pci_device_id rivafb_pci_tbl[] __devinitdata = {
@@ -195,6 +195,16 @@
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE2_ULTRA },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO2_PRO },
+        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO,
+          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE2_GO },
+        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3,
+          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE3 },
+        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_1,
+          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE3_1 },
+        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_2,
+          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE3_2 },
+        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_DDC,
+          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO_DDC },
 	{ 0, } /* terminate list */
 };
 MODULE_DEVICE_TABLE(pci, rivafb_pci_tbl);
@@ -207,24 +217,9 @@
  *
  * ------------------------------------------------------------------------- */
 
-#ifdef FBCON_HAS_CFB8
 extern struct display_switch fbcon_riva8;
-#endif
-#ifdef FBCON_HAS_CFB16
 extern struct display_switch fbcon_riva16;
-#endif
-#ifdef FBCON_HAS_CFB32
 extern struct display_switch fbcon_riva32;
-#endif
-
-#if 0
-/* describes the state of a Riva board */
-struct rivafb_par {
-	struct riva_regs state;	/* state of hw board */
-	__u32 visual;		/* FB_VISUAL_xxx */
-	unsigned depth;		/* bpp of current mode */
-};
-#endif
 
 struct riva_cursor {
 	int enable;
@@ -239,59 +234,56 @@
 	struct timer_list *timer;
 };
 
-
-
 /* ------------------------------------------------------------------------- *
  *
  * global variables
  *
  * ------------------------------------------------------------------------- */
 
-struct rivafb_info *riva_boards = NULL;
-
 /* command line data, set in rivafb_setup() */
-static char fontname[40] __initdata = { 0 };
-static char noaccel __initdata = 0;
-static char nomove = 0;
-static char nohwcursor __initdata = 0;
-static char noblink = 0;
+static u32  pseudo_palette[17];
 #ifdef CONFIG_MTRR
 static char nomtrr __initdata = 0;
 #endif
 
 #ifndef MODULE
 static char *mode_option __initdata = NULL;
-#else
-static char *font = NULL;
 #endif
 
+static struct fb_fix_screeninfo rivafb_fix = {
+	id:		"nVidia",
+	type:		FB_TYPE_PACKED_PIXELS,
+	xpanstep:	1,
+	ypanstep:	1,
+};
+
 static struct fb_var_screeninfo rivafb_default_var = {
-	.xres =		640,
-	.yres =		480,
-	.xres_virtual =	640,
-	.yres_virtual =	480,
-	.xoffset =	0,
-	.yoffset =	0,
-	.bits_per_pixel =8,
-	.grayscale =	0,
-	.red =		{0, 6, 0},
-	.green =	{0, 6, 0},
-	.blue =		{0, 6, 0},
-	.transp =	{0, 0, 0},
-	.nonstd =	0,
-	.activate =	0,
-	.height =	-1,
-	.width =	-1,
-	.accel_flags =	0,
-	.pixclock =	39721,
-	.left_margin =	40,
-	.right_margin =	24,
-	.upper_margin =	32,
-	.lower_margin =	11,
-	.hsync_len =	96,
-	.vsync_len =	2,
-	.sync =		0,
-	.vmode =	FB_VMODE_NONINTERLACED
+	xres:		640,
+	yres:		480,
+	xres_virtual:	640,
+	yres_virtual:	480,
+	xoffset:	0,
+	yoffset:	0,
+	bits_per_pixel:	8,
+	grayscale:	0,
+	red:		{0, 6, 0},
+	green:		{0, 6, 0},
+	blue:		{0, 6, 0},
+	transp:		{0, 0, 0},
+	nonstd:		0,
+	activate:	0,
+	height:		-1,
+	width:		-1,
+	accel_flags:	 FB_ACCELF_TEXT, 
+	pixclock:	39721,
+	left_margin:	40,
+	right_margin:	24,
+	upper_margin:	32,
+	lower_margin:	11,
+	hsync_len:	96,
+	vsync_len:	2,
+	sync:		0,
+	vmode:		FB_VMODE_NONINTERLACED
 };
 
 /* from GGI */
@@ -323,70 +315,70 @@
  *
  * ------------------------------------------------------------------------- */
 
-static inline void CRTCout(struct rivafb_info *rinfo, unsigned char index,
+static inline void CRTCout(struct riva_par *par, unsigned char index,
 			   unsigned char val)
 {
-	VGA_WR08(rinfo->riva.PCIO, 0x3d4, index);
-	VGA_WR08(rinfo->riva.PCIO, 0x3d5, val);
+	VGA_WR08(par->riva.PCIO, 0x3d4, index);
+	VGA_WR08(par->riva.PCIO, 0x3d5, val);
 }
 
-static inline unsigned char CRTCin(struct rivafb_info *rinfo,
+static inline unsigned char CRTCin(struct riva_par *par,
 				   unsigned char index)
 {
-	VGA_WR08(rinfo->riva.PCIO, 0x3d4, index);
-	return (VGA_RD08(rinfo->riva.PCIO, 0x3d5));
+	VGA_WR08(par->riva.PCIO, 0x3d4, index);
+	return (VGA_RD08(par->riva.PCIO, 0x3d5));
 }
 
-static inline void GRAout(struct rivafb_info *rinfo, unsigned char index,
+static inline void GRAout(struct riva_par *par, unsigned char index,
 			  unsigned char val)
 {
-	VGA_WR08(rinfo->riva.PVIO, 0x3ce, index);
-	VGA_WR08(rinfo->riva.PVIO, 0x3cf, val);
+	VGA_WR08(par->riva.PVIO, 0x3ce, index);
+	VGA_WR08(par->riva.PVIO, 0x3cf, val);
 }
 
-static inline unsigned char GRAin(struct rivafb_info *rinfo,
+static inline unsigned char GRAin(struct riva_par *par,
 				  unsigned char index)
 {
-	VGA_WR08(rinfo->riva.PVIO, 0x3ce, index);
-	return (VGA_RD08(rinfo->riva.PVIO, 0x3cf));
+	VGA_WR08(par->riva.PVIO, 0x3ce, index);
+	return (VGA_RD08(par->riva.PVIO, 0x3cf));
 }
 
-static inline void SEQout(struct rivafb_info *rinfo, unsigned char index,
+static inline void SEQout(struct riva_par *par, unsigned char index,
 			  unsigned char val)
 {
-	VGA_WR08(rinfo->riva.PVIO, 0x3c4, index);
-	VGA_WR08(rinfo->riva.PVIO, 0x3c5, val);
+	VGA_WR08(par->riva.PVIO, 0x3c4, index);
+	VGA_WR08(par->riva.PVIO, 0x3c5, val);
 }
 
-static inline unsigned char SEQin(struct rivafb_info *rinfo,
+static inline unsigned char SEQin(struct riva_par *par,
 				  unsigned char index)
 {
-	VGA_WR08(rinfo->riva.PVIO, 0x3c4, index);
-	return (VGA_RD08(rinfo->riva.PVIO, 0x3c5));
+	VGA_WR08(par->riva.PVIO, 0x3c4, index);
+	return (VGA_RD08(par->riva.PVIO, 0x3c5));
 }
 
-static inline void ATTRout(struct rivafb_info *rinfo, unsigned char index,
+static inline void ATTRout(struct riva_par *par, unsigned char index,
 			   unsigned char val)
 {
-	VGA_WR08(rinfo->riva.PCIO, 0x3c0, index);
-	VGA_WR08(rinfo->riva.PCIO, 0x3c0, val);
+	VGA_WR08(par->riva.PCIO, 0x3c0, index);
+	VGA_WR08(par->riva.PCIO, 0x3c0, val);
 }
 
-static inline unsigned char ATTRin(struct rivafb_info *rinfo,
+static inline unsigned char ATTRin(struct riva_par *par,
 				   unsigned char index)
 {
-	VGA_WR08(rinfo->riva.PCIO, 0x3c0, index);
-	return (VGA_RD08(rinfo->riva.PCIO, 0x3c1));
+	VGA_WR08(par->riva.PCIO, 0x3c0, index);
+	return (VGA_RD08(par->riva.PCIO, 0x3c1));
 }
 
-static inline void MISCout(struct rivafb_info *rinfo, unsigned char val)
+static inline void MISCout(struct riva_par *par, unsigned char val)
 {
-	VGA_WR08(rinfo->riva.PVIO, 0x3c2, val);
+	VGA_WR08(par->riva.PVIO, 0x3c2, val);
 }
 
-static inline unsigned char MISCin(struct rivafb_info *rinfo)
+static inline unsigned char MISCin(struct riva_par *par)
 {
-	return (VGA_RD08(rinfo->riva.PVIO, 0x3cc));
+	return (VGA_RD08(par->riva.PVIO, 0x3cc));
 }
 
 
@@ -398,240 +390,63 @@
  * ------------------------------------------------------------------------- */
 
 /**
- * riva_cursor_timer_handler - blink timer
- * @dev_addr: pointer to rivafb_info object containing info for current riva board
- *
- * DESCRIPTION:
- * Cursor blink timer.
- */
-static void riva_cursor_timer_handler(unsigned long dev_addr)
-{
-	struct rivafb_info *rinfo = (struct rivafb_info *)dev_addr;
-
-	if (!rinfo->cursor) return;
-
-	if (!rinfo->cursor->enable) goto out;
-
-	if (rinfo->cursor->last_move_delay < 1000)
-		rinfo->cursor->last_move_delay++;
-
-	if (rinfo->cursor->vbl_cnt && --rinfo->cursor->vbl_cnt == 0) {
-		rinfo->cursor->on ^= 1;
-		if (rinfo->cursor->on)
-			*(rinfo->riva.CURSORPOS) = (rinfo->cursor->pos.x & 0xFFFF)
-						   | (rinfo->cursor->pos.y << 16);
-		rinfo->riva.ShowHideCursor(&rinfo->riva, rinfo->cursor->on);
-		if (!noblink)
-			rinfo->cursor->vbl_cnt = rinfo->cursor->blink_rate;
-	}
-out:
-	rinfo->cursor->timer->expires = jiffies + (HZ / 100);
-	add_timer(rinfo->cursor->timer);
-}
-
-/**
- * rivafb_init_cursor - allocates cursor structure and starts blink timer
- * @rinfo: pointer to rivafb_info object containing info for current riva board
- *
- * DESCRIPTION:
- * Allocates cursor structure and starts blink timer.
- *
- * RETURNS:
- * Pointer to allocated cursor structure.
- *
- * CALLED FROM:
- * rivafb_init_one()
- */
-static struct riva_cursor * __init rivafb_init_cursor(struct rivafb_info *rinfo)
-{
-	struct riva_cursor *cursor;
-
-	cursor = kmalloc(sizeof(struct riva_cursor), GFP_KERNEL);
-	if (!cursor) return 0;
-	memset(cursor, 0, sizeof(*cursor));
-
-	cursor->timer = kmalloc(sizeof(*cursor->timer), GFP_KERNEL);
-	if (!cursor->timer) {
-		kfree(cursor);
-		return 0;
-	}
-	memset(cursor->timer, 0, sizeof(*cursor->timer));
-
-	cursor->blink_rate = DEFAULT_CURSOR_BLINK_RATE;
-
-	init_timer(cursor->timer);
-	cursor->timer->expires = jiffies + (HZ / 100);
-	cursor->timer->data = (unsigned long)rinfo;
-	cursor->timer->function = riva_cursor_timer_handler;
-	add_timer(cursor->timer);
-
-	return cursor;
-}
-
-/**
- * rivafb_exit_cursor - stops blink timer and releases cursor structure
- * @rinfo: pointer to rivafb_info object containing info for current riva board
- *
- * DESCRIPTION:
- * Stops blink timer and releases cursor structure.
- *
- * CALLED FROM:
- * rivafb_init_one()
- * rivafb_remove_one()
- */
-static void rivafb_exit_cursor(struct rivafb_info *rinfo)
-{
-	struct riva_cursor *cursor = rinfo->cursor;
-
-	if (cursor) {
-		if (cursor->timer) {
-			del_timer_sync(cursor->timer);
-			kfree(cursor->timer);
-		}
-		kfree(cursor);
-		rinfo->cursor = 0;
-	}
-}
-
-/**
- * rivafb_download_cursor - writes cursor shape into card registers
- * @rinfo: pointer to rivafb_info object containing info for current riva board
- *
- * DESCRIPTION:
- * Writes cursor shape into card registers.
- *
- * CALLED FROM:
- * riva_load_video_mode()
- */
-static void rivafb_download_cursor(struct rivafb_info *rinfo)
-{
-	int i, save;
-	int *image;
-	
-	if (!rinfo->cursor) return;
-
-	image = (int *)rinfo->cursor->image;
-	save = rinfo->riva.ShowHideCursor(&rinfo->riva, 0);
-	for (i = 0; i < (MAX_CURS*MAX_CURS*2)/sizeof(int); i++)
-		writel(image[i], rinfo->riva.CURSOR + i);
-
-	rinfo->riva.ShowHideCursor(&rinfo->riva, save);
-}
-
-/**
- * rivafb_create_cursor - sets rectangular cursor
- * @rinfo: pointer to rivafb_info object containing info for current riva board
- * @width: cursor width in pixels
- * @height: cursor height in pixels
- *
- * DESCRIPTION:
- * Sets rectangular cursor.
+ * rivafb_load_cursor_image - load cursor image to hardware
+ * @data: address to monochrome bitmap (1 = foreground color, 0 = background)
+ * @mask: address to mask (1 = write image pixel, 0 = do not write pixel)
+ * @par:  pointer to private data
+ * @w:    width of cursor image in pixels
+ * @h:    height of cursor image in scanlines
+ * @bg:   background color (ARGB1555) - alpha bit determines opacity
+ * @fg:   foreground color (ARGB1555)
+ *
+ * DESCRIPTiON:
+ * Loads cursor image based on a monochrome source and mask bitmap.  The
+ * mask bit determines if the image pixel is to be written to the framebuffer
+ * or not.  The imaage bits determines the color of the pixel, 0 for 
+ * background, 1 for foreground.  Only the affected region (as determined 
+ * by @w and @h parameters) will be updated.
  *
  * CALLED FROM:
- * rivafb_set_font()
- * rivafb_set_var()
- */
-static void rivafb_create_cursor(struct rivafb_info *rinfo, int width, int height)
-{
-	struct riva_cursor *c = rinfo->cursor;
-	int i, j, idx;
-
-	if (c) {
-		if (width <= 0 || height <= 0) {
-			width = 8;
-			height = 16;
-		}
-		if (width > MAX_CURS) width = MAX_CURS;
-		if (height > MAX_CURS) height = MAX_CURS;
-
-		c->size.x = width;
-		c->size.y = height;
-		
-		idx = 0;
-
-		for (i = 0; i < height; i++) {
-			for (j = 0; j < width; j++,idx++)
-				c->image[idx] = CURSOR_COLOR;
-			for (j = width; j < MAX_CURS; j++,idx++)
-				c->image[idx] = TRANSPARENT_COLOR;
-		}
-		for (i = height; i < MAX_CURS; i++)
-			for (j = 0; j < MAX_CURS; j++,idx++)
-				c->image[idx] = TRANSPARENT_COLOR;
-	}
-}
-
-/**
- * rivafb_set_font - change font size
- * @p: pointer to display object
- * @width: font width in pixels
- * @height: font height in pixels
- *
- * DESCRIPTION:
- * Callback function called if font settings changed.
- *
- * RETURNS:
- * 1 (Always succeeds.)
- */
-static int rivafb_set_font(struct display *p, int width, int height)
-{
-	struct rivafb_info *fb = (struct rivafb_info *)(p->fb_info);
-
-	rivafb_create_cursor(fb, width, height);
-	return 1;
-}
-
-/**
- * rivafb_cursor - cursor handler
- * @p: pointer to display object
- * @mode: cursor mode (see CM_*)
- * @x: cursor x coordinate in characters
- * @y: cursor y coordinate in characters
- *
- * DESCRIPTION:
- * Cursor handler.
+ * rivafb_cursor()
  */
-static void rivafb_cursor(struct display *p, int mode, int x, int y)
+static void rivafb_load_cursor_image(u8 *data, u8 *mask, struct riva_par *par, 
+				     int w, int h, u16 bg, u16 fg)
 {
-	struct rivafb_info *rinfo = (struct rivafb_info *)(p->fb_info);
-	struct riva_cursor *c = rinfo->cursor;
-
-	if (!c)	return;
-
-	x = x * fontwidth(p) - p->var.xoffset;
-	y = y * fontheight(p) - p->var.yoffset;
-
-	if (c->pos.x == x && c->pos.y == y && (mode == CM_ERASE) == !c->enable)
-		return;
-
-	c->enable = 0;
-	if (c->on) rinfo->riva.ShowHideCursor(&rinfo->riva, 0);
-		
-	c->pos.x = x;
-	c->pos.y = y;
-
-	switch (mode) {
-	case CM_ERASE:
-		c->on = 0;
-		break;
-	case CM_DRAW:
-	case CM_MOVE:
-		if (c->last_move_delay <= 1) { /* rapid cursor movement */
-			c->vbl_cnt = CURSOR_SHOW_DELAY;
-		} else {
-			*(rinfo->riva.CURSORPOS) = (x & 0xFFFF) | (y << 16);
-			rinfo->riva.ShowHideCursor(&rinfo->riva, 1);
-			if (!noblink) c->vbl_cnt = CURSOR_HIDE_DELAY;
-			c->on = 1;
+	int i, j, k = 0;
+	u32 b, m, tmp;
+       
+
+	for (i = 0; i < h; i++) {
+		b = *((u32 *)data)++;
+		m = *((u32 *)mask)++;
+		for (j = 0; j < w/2; j++) {
+			tmp = 0;
+#if defined (__BIG_ENDIAN__) 
+			if (m & (1 << 31))
+				tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
+			b <<= 1;
+			m <<= 1;
+
+			if (m & (1 << 31))
+				tmp |= (b & (1 << 31)) ? fg : bg;
+			b <<= 1;
+			m <<= 1;
+#else
+			if (m & 1)
+				tmp = (b & 1) ? fg : bg;
+			b >>= 1;
+			m >>= 1;
+			if (m & 1)
+				tmp |= (b & 1) ? fg << 16 : bg << 16;
+			b >>= 1;
+			m >>= 1;
+#endif
+			writel(tmp, par->riva.CURSOR + k++);
 		}
-		c->last_move_delay = 0;
-		c->enable = 1;
-		break;
+		k += (MAX_CURS - w)/2;
 	}
 }
 
-
-
 /* ------------------------------------------------------------------------- *
  *
  * general utility functions
@@ -639,80 +454,6 @@
  * ------------------------------------------------------------------------- */
 
 /**
- * riva_set_dispsw - sets dispsw
- * @rinfo: pointer to internal driver struct for a given Riva card
- * @disp: pointer to display object
- *
- * DESCRIPTION:
- * Sets up console low level operations depending on the current? color depth
- * of the display.
- *
- * CALLED FROM:
- * rivafb_set_var()
- * rivafb_switch()
- * riva_init_disp()
- */
-static void riva_set_dispsw(struct rivafb_info *rinfo, struct display *disp)
-{
-	int accel = disp->var.accel_flags & FB_ACCELF_TEXT;
-
-	DPRINTK("ENTER\n");
-
-	assert(rinfo != NULL);
-
-	disp->dispsw_data = NULL;
-
-	disp->type = FB_TYPE_PACKED_PIXELS;
-	disp->type_aux = 0;
-	disp->ypanstep = 1;
-	disp->ywrapstep = 0;
-	disp->can_soft_blank = 1;
-	disp->inverse = 0;
-
-	switch (disp->var.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
-	case 8:
-		rinfo->dispsw = accel ? fbcon_riva8 : fbcon_cfb8;
-		disp->dispsw = &rinfo->dispsw;
-		disp->line_length = disp->var.xres_virtual;
-		disp->visual = FB_VISUAL_PSEUDOCOLOR;
-		break;
-#endif
-#ifdef FBCON_HAS_CFB16
-	case 16:
-		rinfo->dispsw = accel ? fbcon_riva16 : fbcon_cfb16;
-		disp->dispsw_data = &rinfo->con_cmap.cfb16;
-		disp->dispsw = &rinfo->dispsw;
-		disp->line_length = disp->var.xres_virtual * 2;
-		disp->visual = FB_VISUAL_DIRECTCOLOR;
-		break;
-#endif
-#ifdef FBCON_HAS_CFB32
-	case 32:
-		rinfo->dispsw = accel ? fbcon_riva32 : fbcon_cfb32;
-		disp->dispsw_data = rinfo->con_cmap.cfb32;
-		disp->dispsw = &rinfo->dispsw;
-		disp->line_length = disp->var.xres_virtual * 4;
-		disp->visual = FB_VISUAL_DIRECTCOLOR;
-		break;
-#endif
-	default:
-		DPRINTK("Setting fbcon_dummy renderer\n");
-		rinfo->dispsw = fbcon_dummy;
-		disp->dispsw = &rinfo->dispsw;
-	}
-
-	/* FIXME: verify that the above code sets dsp->* fields correctly */
-
-	if (rinfo->cursor) {
-		rinfo->dispsw.cursor = rivafb_cursor;
-		rinfo->dispsw.set_font = rivafb_set_font;
-	}
-
-	DPRINTK("EXIT\n");
-}
-
-/**
  * riva_wclut - set CLUT entry
  * @chip: pointer to RIVA_HW_INST object
  * @regnum: register number
@@ -738,7 +479,7 @@
 
 /**
  * riva_save_state - saves current chip state
- * @rinfo: pointer to rivafb_info object containing info for current riva board
+ * @par: pointer to riva_par object containing info for current riva board
  * @regs: pointer to riva_regs object
  *
  * DESCRIPTION:
@@ -748,36 +489,36 @@
  * rivafb_init_one()
  */
 /* from GGI */
-static void riva_save_state(struct rivafb_info *rinfo, struct riva_regs *regs)
+static void riva_save_state(struct riva_par *par, struct riva_regs *regs)
 {
 	int i;
 
-	rinfo->riva.LockUnlock(&rinfo->riva, 0);
+	par->riva.LockUnlock(&par->riva, 0);
 
-	rinfo->riva.UnloadStateExt(&rinfo->riva, &regs->ext);
+	par->riva.UnloadStateExt(&par->riva, &regs->ext);
 
-	regs->misc_output = MISCin(rinfo);
+	regs->misc_output = MISCin(par);
 
 	for (i = 0; i < NUM_CRT_REGS; i++) {
-		regs->crtc[i] = CRTCin(rinfo, i);
+		regs->crtc[i] = CRTCin(par, i);
 	}
 
 	for (i = 0; i < NUM_ATC_REGS; i++) {
-		regs->attr[i] = ATTRin(rinfo, i);
+		regs->attr[i] = ATTRin(par, i);
 	}
 
 	for (i = 0; i < NUM_GRC_REGS; i++) {
-		regs->gra[i] = GRAin(rinfo, i);
+		regs->gra[i] = GRAin(par, i);
 	}
 
 	for (i = 0; i < NUM_SEQ_REGS; i++) {
-		regs->seq[i] = SEQin(rinfo, i);
+		regs->seq[i] = SEQin(par, i);
 	}
 }
 
 /**
  * riva_load_state - loads current chip state
- * @rinfo: pointer to rivafb_info object containing info for current riva board
+ * @par: pointer to riva_par object containing info for current riva board
  * @regs: pointer to riva_regs object
  *
  * DESCRIPTION:
@@ -789,18 +530,18 @@
  * rivafb_remove_one()
  */
 /* from GGI */
-static void riva_load_state(struct rivafb_info *rinfo, struct riva_regs *regs)
+static void riva_load_state(struct riva_par *par, struct riva_regs *regs)
 {
-	int i;
 	RIVA_HW_STATE *state = &regs->ext;
+	int i;
 
-	CRTCout(rinfo, 0x11, 0x00);
+	CRTCout(par, 0x11, 0x00);
 
-	rinfo->riva.LockUnlock(&rinfo->riva, 0);
+	par->riva.LockUnlock(&par->riva, 0);
 
-	rinfo->riva.LoadStateExt(&rinfo->riva, state);
+	par->riva.LoadStateExt(&par->riva, state);
 
-	MISCout(rinfo, regs->misc_output);
+	MISCout(par, regs->misc_output);
 
 	for (i = 0; i < NUM_CRT_REGS; i++) {
 		switch (i) {
@@ -808,26 +549,26 @@
 		case 0x20 ... 0x40:
 			break;
 		default:
-			CRTCout(rinfo, i, regs->crtc[i]);
+			CRTCout(par, i, regs->crtc[i]);
 		}
 	}
 
 	for (i = 0; i < NUM_ATC_REGS; i++) {
-		ATTRout(rinfo, i, regs->attr[i]);
+		ATTRout(par, i, regs->attr[i]);
 	}
 
 	for (i = 0; i < NUM_GRC_REGS; i++) {
-		GRAout(rinfo, i, regs->gra[i]);
+		GRAout(par, i, regs->gra[i]);
 	}
 
 	for (i = 0; i < NUM_SEQ_REGS; i++) {
-		SEQout(rinfo, i, regs->seq[i]);
+		SEQout(par, i, regs->seq[i]);
 	}
 }
 
 /**
  * riva_load_video_mode - calculate timings
- * @rinfo: pointer to rivafb_info object containing info for current riva board
+ * @info: pointer to fb_info object containing info for current riva board
  * @video_mode: video mode to set
  *
  * DESCRIPTION:
@@ -836,36 +577,36 @@
  * CALLED FROM:
  * rivafb_set_var()
  */
-static void riva_load_video_mode(struct rivafb_info *rinfo,
-				 struct fb_var_screeninfo *video_mode)
+static void riva_load_video_mode(struct fb_info *info)
 {
-	struct riva_regs newmode;
 	int bpp, width, hDisplaySize, hDisplay, hStart,
 	    hEnd, hTotal, height, vDisplay, vStart, vEnd, vTotal, dotClock;
+	struct riva_par *par = (struct riva_par *) info->par;
+	struct riva_regs newmode;
 
 	/* time to calculate */
 
-	rivafb_blank(1, (struct fb_info *)rinfo);
+	rivafb_blank(1, info);
 
-	bpp = video_mode->bits_per_pixel;
-	if (bpp == 16 && video_mode->green.length == 5)
+	bpp = info->var.bits_per_pixel;
+	if (bpp == 16 && info->var.green.length == 5)
 		bpp = 15;
-	width = video_mode->xres_virtual;
-	hDisplaySize = video_mode->xres;
+	width = info->var.xres_virtual;
+	hDisplaySize = info->var.xres;
 	hDisplay = (hDisplaySize / 8) - 1;
-	hStart = (hDisplaySize + video_mode->right_margin) / 8 + 2;
-	hEnd = (hDisplaySize + video_mode->right_margin +
-		video_mode->hsync_len) / 8 - 1;
-	hTotal = (hDisplaySize + video_mode->right_margin +
-		  video_mode->hsync_len + video_mode->left_margin) / 8 - 1;
-	height = video_mode->yres_virtual;
-	vDisplay = video_mode->yres - 1;
-	vStart = video_mode->yres + video_mode->lower_margin - 1;
-	vEnd = video_mode->yres + video_mode->lower_margin +
-	       video_mode->vsync_len - 1;
-	vTotal = video_mode->yres + video_mode->lower_margin +
-		 video_mode->vsync_len + video_mode->upper_margin + 2;
-	dotClock = 1000000000 / video_mode->pixclock;
+	hStart = (hDisplaySize + info->var.right_margin) / 8 + 2;
+	hEnd = (hDisplaySize + info->var.right_margin +
+		info->var.hsync_len) / 8 - 1;
+	hTotal = (hDisplaySize + info->var.right_margin +
+		  info->var.hsync_len + info->var.left_margin) / 8 - 1;
+	height = info->var.yres_virtual;
+	vDisplay = info->var.yres - 1;
+	vStart = info->var.yres + info->var.lower_margin - 1;
+	vEnd = info->var.yres + info->var.lower_margin +
+	       info->var.vsync_len - 1;
+	vTotal = info->var.yres + info->var.lower_margin +
+		 info->var.vsync_len + info->var.upper_margin + 2;
+	dotClock = 1000000000 / info->var.pixclock;
 
 	memcpy(&newmode, &reg_template, sizeof(struct riva_regs));
 
@@ -899,83 +640,19 @@
 	newmode.ext.width = width;
 	newmode.ext.height = height;
 
-	rinfo->riva.CalcStateExt(&rinfo->riva, &newmode.ext, bpp, width,
+	par->riva.CalcStateExt(&par->riva, &newmode.ext, bpp, width,
 				  hDisplaySize, hDisplay, hStart, hEnd,
 				  hTotal, height, vDisplay, vStart, vEnd,
 				  vTotal, dotClock);
 
-	rinfo->current_state = newmode;
-	riva_load_state(rinfo, &rinfo->current_state);
-
-	rinfo->riva.LockUnlock(&rinfo->riva, 0); /* important for HW cursor */
-	rivafb_download_cursor(rinfo);
-}
-
-/**
- * riva_board_list_add - maintains board list
- * @board_list: root node of list of boards
- * @new_node: new node to be added
- *
- * DESCRIPTION:
- * Adds @new_node to the list referenced by @board_list.
- *
- * RETURNS:
- * New root node
- *
- * CALLED FROM:
- * rivafb_init_one()
- */
-static struct rivafb_info *riva_board_list_add(struct rivafb_info *board_list,
-					       struct rivafb_info *new_node)
-{
-	struct rivafb_info *i_p = board_list;
-
-	new_node->next = NULL;
-
-	if (board_list == NULL)
-		return new_node;
-
-	while (i_p->next != NULL)
-		i_p = i_p->next;
-	i_p->next = new_node;
-
-	return board_list;
-}
-
-/**
- * riva_board_list_del - maintains board list
- * @board_list: root node of list of boards
- * @del_node: node to be removed
- *
- * DESCRIPTION:
- * Removes @del_node from the list referenced by @board_list.
- *
- * RETURNS:
- * New root node
- *
- * CALLED FROM:
- * rivafb_remove_one()
- */
-static struct rivafb_info *riva_board_list_del(struct rivafb_info *board_list,
-					       struct rivafb_info *del_node)
-{
-	struct rivafb_info *i_p = board_list;
-
-	if (board_list == del_node)
-		return del_node->next;
-
-	while (i_p->next != del_node)
-		i_p = i_p->next;
-	i_p->next = del_node->next;
-
-	return board_list;
+	par->current_state = newmode;
+	riva_load_state(par, &par->current_state);
 }
 
 /**
  * rivafb_do_maximize - 
- * @rinfo: pointer to rivafb_info object containing info for current riva board
+ * @info: pointer to fb_info object containing info for current riva board
  * @var:
- * @v:
  * @nom:
  * @den:
  *
@@ -989,9 +666,8 @@
  * CALLED FROM:
  * rivafb_set_var()
  */
-static int rivafb_do_maximize(struct rivafb_info *rinfo,
+static int rivafb_do_maximize(struct fb_info *info,
 			      struct fb_var_screeninfo *var,
-			      struct fb_var_screeninfo *v,
 			      int nom, int den)
 {
 	static struct {
@@ -1007,12 +683,12 @@
 	int i;
 
 	/* use highest possible virtual resolution */
-	if (v->xres_virtual == -1 && v->yres_virtual == -1) {
+	if (var->xres_virtual == -1 && var->yres_virtual == -1) {
 		printk(KERN_WARNING PFX
 		       "using maximum available virtual resolution\n");
 		for (i = 0; modes[i].xres != -1; i++) {
 			if (modes[i].xres * nom / den * modes[i].yres <
-			    rinfo->ram_amount / 2)
+			    info->fix.smem_len / 2)
 				break;
 		}
 		if (modes[i].xres == -1) {
@@ -1021,26 +697,26 @@
 			DPRINTK("EXIT - EINVAL error\n");
 			return -EINVAL;
 		}
-		v->xres_virtual = modes[i].xres;
-		v->yres_virtual = modes[i].yres;
+		var->xres_virtual = modes[i].xres;
+		var->yres_virtual = modes[i].yres;
 
 		printk(KERN_INFO PFX
 		       "virtual resolution set to maximum of %dx%d\n",
-		       v->xres_virtual, v->yres_virtual);
-	} else if (v->xres_virtual == -1) {
-		v->xres_virtual = (rinfo->ram_amount * den /
-			(nom * v->yres_virtual * 2)) & ~15;
+		       var->xres_virtual, var->yres_virtual);
+	} else if (var->xres_virtual == -1) {
+		var->xres_virtual = (info->fix.smem_len * den /
+			(nom * var->yres_virtual * 2)) & ~15;
 		printk(KERN_WARNING PFX
-		       "setting virtual X resolution to %d\n", v->xres_virtual);
-	} else if (v->yres_virtual == -1) {
-		v->xres_virtual = (v->xres_virtual + 15) & ~15;
-		v->yres_virtual = rinfo->ram_amount * den /
-			(nom * v->xres_virtual * 2);
+		       "setting virtual X resolution to %d\n", var->xres_virtual);
+	} else if (var->yres_virtual == -1) {
+		var->xres_virtual = (var->xres_virtual + 15) & ~15;
+		var->yres_virtual = info->fix.smem_len * den /
+			(nom * var->xres_virtual * 2);
 		printk(KERN_WARNING PFX
-		       "setting virtual Y resolution to %d\n", v->yres_virtual);
+		       "setting virtual Y resolution to %d\n", var->yres_virtual);
 	} else {
-		v->xres_virtual = (v->xres_virtual + 15) & ~15;
-		if (v->xres_virtual * nom / den * v->yres_virtual > rinfo->ram_amount) {
+		var->xres_virtual = (var->xres_virtual + 15) & ~15;
+		if (var->xres_virtual * nom / den * var->yres_virtual > info->fix.smem_len) {
 			printk(KERN_ERR PFX
 			       "mode %dx%dx%d rejected...resolution too high to fit into video memory!\n",
 			       var->xres, var->yres, var->bits_per_pixel);
@@ -1049,397 +725,535 @@
 		}
 	}
 	
-	if (v->xres_virtual * nom / den >= 8192) {
+	if (var->xres_virtual * nom / den >= 8192) {
 		printk(KERN_WARNING PFX
 		       "virtual X resolution (%d) is too high, lowering to %d\n",
-		       v->xres_virtual, 8192 * den / nom - 16);
-		v->xres_virtual = 8192 * den / nom - 16;
+		       var->xres_virtual, 8192 * den / nom - 16);
+		var->xres_virtual = 8192 * den / nom - 16;
 	}
 	
-	if (v->xres_virtual < v->xres) {
+	if (var->xres_virtual < var->xres) {
 		printk(KERN_ERR PFX
-		       "virtual X resolution (%d) is smaller than real\n", v->xres_virtual);
+		       "virtual X resolution (%d) is smaller than real\n", var->xres_virtual);
 		return -EINVAL;
 	}
 
-	if (v->yres_virtual < v->yres) {
+	if (var->yres_virtual < var->yres) {
 		printk(KERN_ERR PFX
-		       "virtual Y resolution (%d) is smaller than real\n", v->yres_virtual);
+		       "virtual Y resolution (%d) is smaller than real\n", var->yres_virtual);
 		return -EINVAL;
 	}
-	
 	return 0;
 }
 
+/* acceleration routines */
+inline void wait_for_idle(struct riva_par *par)
+{
+	while (par->riva.Busy(&par->riva));
+}
+
+/* set copy ROP, no mask */
+static void riva_setup_ROP(struct riva_par *par)
+{
+	RIVA_FIFO_FREE(par->riva, Patt, 5);
+	par->riva.Patt->Shape = 0;
+	par->riva.Patt->Color0 = 0xffffffff;
+	par->riva.Patt->Color1 = 0xffffffff;
+	par->riva.Patt->Monochrome[0] = 0xffffffff;
+	par->riva.Patt->Monochrome[1] = 0xffffffff;
 
+	RIVA_FIFO_FREE(par->riva, Rop, 1);
+	par->riva.Rop->Rop3 = 0xCC;
+}
 
-/* ------------------------------------------------------------------------- *
- *
- * internal fb_ops helper functions
- *
- * ------------------------------------------------------------------------- */
+void riva_setup_accel(struct riva_par *par)
+{
+	RIVA_FIFO_FREE(par->riva, Clip, 2);
+	par->riva.Clip->TopLeft     = 0x0;
+	par->riva.Clip->WidthHeight = 0x80008000;
+	riva_setup_ROP(par);
+}
 
 /**
- * riva_get_cmap_len - query current color map length
- * @var: standard kernel fb changeable data
- *
+ * rivafb_fillrect - hardware accelerated color fill function
+ * @info: pointer to fb_info structure
+ * @rect: pointer to fb_fillrect structure
+ * 
  * DESCRIPTION:
- * Get current color map length.
- *
- * RETURNS:
- * Length of color map
+ * This function fills up a region of framebuffer memory with a solid
+ * color with a choice of two different ROP's, copy or invert.
  *
  * CALLED FROM:
- * riva_getcolreg()
- * rivafb_setcolreg()
- * rivafb_get_cmap()
- * rivafb_set_cmap()
+ * framebuffer hook
  */
-static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
+static void rivafb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
 {
-	int rc = 16;		/* reasonable default */
+	struct riva_par *par = (struct riva_par *) info->par;
+	u_int color, rop = 0;
 
-	assert(var != NULL);
+	if (info->var.bits_per_pixel == 8)
+		color = rect->color;
+	else
+		color = par->riva_palette[rect->color];
 
-	switch (var->bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
-	case 8:
-		rc = 256;	/* pseudocolor... 256 entries HW palette */
-		break;
-#endif
-#ifdef FBCON_HAS_CFB16
-	case 15:
-		rc = 15;	/* fix for 15 bpp depths on Riva 128 based cards */
+	switch (rect->rop) {
+	case ROP_XOR:
+		rop = 0x66;
 		break;
-	case 16:
-		rc = 16;	/* directcolor... 16 entries SW palette */
-		break;		/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
-#endif
-#ifdef FBCON_HAS_CFB32
-	case 32:
-		rc = 16;	/* directcolor... 16 entries SW palette */
-		break;		/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
-#endif
+	case ROP_COPY:
 	default:
-		/* should not occur */
+		rop = 0xCC;
 		break;
 	}
 
-	return rc;
+	RIVA_FIFO_FREE(par->riva, Rop, 1);
+	par->riva.Rop->Rop3 = rop;
+
+	RIVA_FIFO_FREE(par->riva, Bitmap, 1);
+	par->riva.Bitmap->Color1A = color;
+
+	RIVA_FIFO_FREE(par->riva, Bitmap, 2);
+	par->riva.Bitmap->UnclippedRectangle[0].TopLeft = 
+		(rect->dx << 16) | rect->dy;
+	par->riva.Bitmap->UnclippedRectangle[0].WidthHeight =
+		(rect->width << 16) | rect->height;
 }
 
 /**
- * riva_getcolreg
- * @regno: register index
- * @red: red component
- * @green: green component
- * @blue: blue component
- * @transp: transparency
- * @info: pointer to rivafb_info object containing info for current riva board
+ * rivafb_copyarea - hardware accelerated blit function
+ * @info: pointer to fb_info structure
+ * @region: pointer to fb_copyarea structure
  *
  * DESCRIPTION:
- * Read a single color register and split it into colors/transparent.
- * The return values must have a 16 bit magnitude.
- *
- * RETURNS:
- * Return != 0 for invalid regno.
+ * This copies an area of pixels from one location to another
  *
  * CALLED FROM:
- * rivafb_get_cmap()
- * rivafb_switch()
- * fbcmap.c:fb_get_cmap()
- *	fbgen.c:fbgen_get_cmap()
- *	fbgen.c:fbgen_switch()
+ * framebuffer hook
  */
-static int riva_getcolreg(unsigned regno, unsigned *red, unsigned *green,
-			  unsigned *blue, unsigned *transp,
-			  struct fb_info *info)
+static void rivafb_copyarea(struct fb_info *info, struct fb_copyarea *region)
 {
-	struct rivafb_info *rivainfo = (struct rivafb_info *)info;
-
-	if (regno >= riva_get_cmap_len(&rivainfo->currcon_display->var))
-		return 1;
+	struct riva_par *par = (struct riva_par *) info->par;
 
-	*red = rivainfo->palette[regno].red;
-	*green = rivainfo->palette[regno].green;
-	*blue = rivainfo->palette[regno].blue;
-	*transp = 0;
-
-	return 0;
-}
+	RIVA_FIFO_FREE(par->riva, Blt, 3);
+	par->riva.Blt->TopLeftSrc  = (region->sy << 16) | region->sx;
+	par->riva.Blt->TopLeftDst  = (region->dy << 16) | region->dx;
+	par->riva.Blt->WidthHeight = (region->height << 16) | region->width;
+	wait_for_idle(par);
+}
+
+static u8 byte_rev[256] = {
+	0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 
+	0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+	0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 
+	0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 
+	0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 
+	0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 
+	0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 
+	0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 
+	0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 
+	0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 
+	0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 
+	0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 
+	0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 
+	0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 
+	0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 
+	0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 
+	0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 
+	0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 
+	0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 
+	0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 
+	0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 
+	0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 
+	0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 
+	0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 
+	0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+	0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 
+	0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+	0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 
+	0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+	0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 
+	0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+	0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
+};
 
 /**
- * rivafb_setcolreg
- * @regno: register index
- * @red: red component
- * @green: green component
- * @blue: blue component
- * @transp: transparency
- * @info: pointer to rivafb_info object containing info for current riva board
+ * rivafb_imageblit: hardware accelerated color expand function
+ * @info: pointer to fb_info structure
+ * @image: pointer to fb_image structure
  *
  * DESCRIPTION:
- * Set a single color register. The values supplied have a 16 bit
- * magnitude.
+ * If the source is a monochrome bitmap, the function fills up a a region
+ * of framebuffer memory with pixels whose color is determined by the bit
+ * setting of the bitmap, 1 - foreground, 0 - background.
  *
- * RETURNS:
- * Return != 0 for invalid regno.
+ * If the source is not a monochrome bitmap, color expansion is not done.
+ * In this case, it is channeled to a software function.
  *
  * CALLED FROM:
- * rivafb_set_cmap()
- * fbcmap.c:fb_set_cmap()
- *	fbgen.c:fbgen_get_cmap()
- *	fbgen.c:do_install_cmap()
- *		fbgen.c:fbgen_set_var()
- *		fbgen.c:fbgen_switch()
- *		fbgen.c:fbgen_blank()
- *	fbgen.c:fbgen_blank()
+ * framebuffer hook
  */
-static int rivafb_setcolreg(unsigned regno, unsigned red, unsigned green,
-			    unsigned blue, unsigned transp,
-			    struct fb_info *info)
+static void rivafb_imageblit(struct fb_info *info, struct fb_image *image)
 {
-	struct rivafb_info *rivainfo = (struct rivafb_info *)info;
-	RIVA_HW_INST *chip = &rivainfo->riva;
-	struct display *p;
-
-	DPRINTK("ENTER\n");
-
-	assert(rivainfo != NULL);
-	assert(rivainfo->currcon_display != NULL);
-
-	p = rivainfo->currcon_display;
+	struct riva_par *par = (struct riva_par *) info->par;
+	u8 *cdat = image->data, *dat;
+	int w, h, dx, dy;
+	volatile u32 *d;
+	u32 fgx = 0, bgx = 0, size, width, mod;
+	int i, j;
+
+	if (image->depth != 1) {
+		wait_for_idle(par);
+		cfb_imageblit(info, image);
+		return;
+	}
 
-	if (regno >= riva_get_cmap_len(&p->var))
-		return -EINVAL;
+	w = image->width;
+	h = image->height;
+	dx = image->dx;
+	dy = image->dy;
 
-	rivainfo->palette[regno].red = red;
-	rivainfo->palette[regno].green = green;
-	rivainfo->palette[regno].blue = blue;
+	width = (w + 7)/8;
 
-	if (p->var.grayscale) {
-		/* gray = 0.30*R + 0.59*G + 0.11*B */
-		red = green = blue =
-		    (red * 77 + green * 151 + blue * 28) >> 8;
+	size = width * h;
+	dat = cdat;
+	for (i = 0; i < size; i++) {
+		*dat = byte_rev[*dat];
+		dat++;
 	}
 
-	switch (p->var.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
+	switch (info->var.bits_per_pixel) {
 	case 8:
-		/* "transparent" stuff is completely ignored. */
-		riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);
+		fgx = image->fg_color | ~((1 << 8) - 1);
+		bgx = image->bg_color | ~((1 << 8) - 1);
+		
 		break;
-#endif /* FBCON_HAS_CFB8 */
-#ifdef FBCON_HAS_CFB16
 	case 16:
-		assert(regno < 16);
-		if (p->var.green.length == 5) {
-			/* 0rrrrrgg gggbbbbb */
-			rivainfo->con_cmap.cfb16[regno] =
-			    ((red & 0xf800) >> 1) |
-			    ((green & 0xf800) >> 6) | ((blue & 0xf800) >> 11);
-		} else {
-			/* rrrrrggg gggbbbbb */
-			rivainfo->con_cmap.cfb16[regno] =
-			    ((red & 0xf800) >> 0) |
-			    ((green & 0xf800) >> 5) | ((blue & 0xf800) >> 11);
+		/* set alpha bit */
+		if (info->var.green.length == 5) {
+			fgx = 1 << 15;
+			bgx = fgx;
 		}
-		break;
-#endif /* FBCON_HAS_CFB16 */
-#ifdef FBCON_HAS_CFB32
+        /* Fall through... */
 	case 32:
-		assert(regno < 16);
-		rivainfo->con_cmap.cfb32[regno] =
-		    ((red & 0xff00) << 8) |
-		    ((green & 0xff00)) | ((blue & 0xff00) >> 8);
-		break;
-#endif /* FBCON_HAS_CFB32 */
-	default:
-		/* do nothing */
+		fgx |= par->riva_palette[image->fg_color];
+		bgx |= par->riva_palette[image->bg_color];
 		break;
 	}
 
-	return 0;
-}
+        RIVA_FIFO_FREE(par->riva, Bitmap, 7);
+        par->riva.Bitmap->ClipE.TopLeft     = (dy << 16) | (dx & 0xFFFF);
+        par->riva.Bitmap->ClipE.BottomRight = (((dy + h) << 16) | 
+					       ((dx + w) & 0xffff));
+        par->riva.Bitmap->Color0E           = bgx;
+        par->riva.Bitmap->Color1E           = fgx;
+        par->riva.Bitmap->WidthHeightInE    = (h << 16) | ((w + 31) & ~31);
+        par->riva.Bitmap->WidthHeightOutE   = (h << 16) | ((w + 31) & ~31);
+        par->riva.Bitmap->PointE            = (dy << 16) | (dx & 0xFFFF);
+	
+	d = &par->riva.Bitmap->MonochromeData01E;
+
+	mod = width % 4;
 
+	if (width >= 4) {
+		while (h--) {
+			size = width / 4;
+			while (size >= 16) {
+				RIVA_FIFO_FREE(par->riva, Bitmap, 16);
+				for (i = 0; i < 16; i++)
+					d[i] = *((u32 *)cdat)++;
+				size -= 16;
+			}
+			
+			if (size) {
+				RIVA_FIFO_FREE(par->riva, Bitmap, size);
+				for (i = 0; i < size; i++)
+					d[i] = *((u32 *) cdat)++;
+			}
+			
+			if (mod) {
+				u32 tmp;
+				RIVA_FIFO_FREE(par->riva, Bitmap, 1);
+				for (i = 0; i < mod; i++) 
+					((u8 *)&tmp)[i] = *cdat++;
+				d[i] = tmp;
+			}
+		}
+	}
+	else {
+		u32 k, tmp;
 
+		for (i = h; i > 0; i-=16) {
+			if (i >= 16)
+				size = 16;
+			else
+				size = i;
+			RIVA_FIFO_FREE(par->riva, Bitmap, size);
+			for (j = 0; j < size; j++) {
+				for (k = 0; k < width; k++)
+					((u8 *)&tmp)[k] = *cdat++;
+				d[j] = tmp;
+			}
+		}
+	}
+}
 
-/* ------------------------------------------------------------------------- *
+/**
+ * rivafb_cursor - hardware cursor function
+ * @info: pointer to info structure
+ * @cursor: pointer to fbcursor structure
  *
- * framebuffer operations
+ * DESCRIPTION:
+ * A cursor function that supports displaying a cursor image via hardware.
+ * Within the kernel, copy and invert rops are supported.  If exported
+ * to user space, only the copy rop will be supported.
  *
- * ------------------------------------------------------------------------- */
-
-static int rivafb_get_fix(struct fb_fix_screeninfo *fix, int con,
-			  struct fb_info *info)
+ * CALLED FROM
+ * framebuffer hook
+ */
+static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor) 
 {
-	struct rivafb_info *rivainfo = (struct rivafb_info *)info;
-	struct display *p;
+	static u8 data[MAX_CURS*MAX_CURS/8], mask[MAX_CURS*MAX_CURS/8];
+	struct riva_par *par = (struct riva_par *) info->par;
+	int i, j, d_idx = 0, s_idx = 0;
+	u16 flags = cursor->set, fg, bg;
+
+	/*
+	 * Can't do invert if one of the operands (dest) is missing,
+	 * ie, only opaque cursor supported.  This should be
+	 * standard for GUI apps.
+	 */
+	if (cursor->dest == NULL && cursor->rop == ROP_XOR)
+		return 1;
 
-	DPRINTK("ENTER\n");
+	if (par->cursor_reset) {
+		flags = FB_CUR_SETALL;
+		par->cursor_reset = 0;
+	}
 
-	assert(fix != NULL);
-	assert(info != NULL);
-	assert(rivainfo->drvr_name && rivainfo->drvr_name[0]);
-	assert(rivainfo->fb_base_phys > 0);
-	assert(rivainfo->ram_amount > 0);
+	par->riva.ShowHideCursor(&par->riva, 0);
 
-	p = (con < 0) ? rivainfo->info.disp : &fb_display[con];
+	if (flags & FB_CUR_SETPOS) {
+		u32 xx, yy, temp;
+	
+		yy = cursor->image.dy - info->var.yoffset;
+		xx = cursor->image.dx - info->var.xoffset;
+		temp = xx & 0xFFFF;
+		temp |= yy << 16;
+
+		*(par->riva.CURSORPOS) = temp;
+	}
+
+	if (flags & FB_CUR_SETSIZE) {
+		memset(data, 0, MAX_CURS * MAX_CURS/8);
+		memset(mask, 0, MAX_CURS * MAX_CURS/8);
+		memset_io(par->riva.CURSOR, 0, MAX_CURS * MAX_CURS * 2);
+	}
+
+	if (flags & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETDEST)) { 
+		int bg_idx = cursor->image.bg_color;
+		int fg_idx = cursor->image.fg_color;
+
+		switch (cursor->rop) {
+		case ROP_XOR:
+			for (i = 0; i < cursor->image.height; i++) {
+				for (j = 0; j < (cursor->image.width + 7)/8;
+				     j++) {
+					d_idx = i * MAX_CURS/8  + j;
+					data[d_idx] =  byte_rev[((u8 *)cursor->image.data)[s_idx] ^
+							       ((u8 *)cursor->dest)[s_idx]];
+					mask[d_idx] = byte_rev[((u8 *)cursor->mask)[s_idx]];
+					s_idx++;
+				}
+			}
+			break;
+		case ROP_COPY:
+		default:
+			for (i = 0; i < cursor->image.height; i++) {
+				for (j = 0; j < (cursor->image.width + 7)/8; j++) {
+					d_idx = i * MAX_CURS/8 + j;
+					data[d_idx] = byte_rev[((u8 *)cursor->image.data)[s_idx]];
+					mask[d_idx] = byte_rev[((u8 *)cursor->mask)[s_idx]];
+					s_idx++;
+				}
+			}
+			break;
+		}
+			
+		bg = ((par->cmap[bg_idx].red & 0xf8) << 7) | 
+			((par->cmap[bg_idx].green & 0xf8) << 2) |
+			((par->cmap[bg_idx].blue & 0xf8) >> 3) | 1 << 15;
+		
+		fg = ((par->cmap[fg_idx].red & 0xf8) << 7) | 
+			((par->cmap[fg_idx].green & 0xf8) << 2) |
+			((par->cmap[fg_idx].blue & 0xf8) >> 3) | 1 << 15;
+
+		par->riva.LockUnlock(&par->riva, 0);
+		rivafb_load_cursor_image(data, mask, par, cursor->image.width, 
+					 cursor->image.height, bg, fg);
+	}
+	
+	if (cursor->enable)
+		par->riva.ShowHideCursor(&par->riva, 1);
 
-	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-	sprintf(fix->id, "nVidia %s", rivainfo->drvr_name);
+	return 0;
+}
 
-	fix->smem_start = rivainfo->fb_base_phys;
-	fix->smem_len = rivainfo->ram_amount;
+static int rivafb_sync(struct fb_info *info)
+{
+	struct riva_par *par = (struct riva_par *) info->par;
 
-	fix->type = p->type;
-	fix->type_aux = p->type_aux;
-	fix->visual = p->visual;
+	wait_for_idle(par);
+	
+	return 0;
+}
 
-	fix->xpanstep = 1;
-	fix->ypanstep = 1;
-	fix->ywrapstep = 0;	/* FIXME: no ywrap for now */
+/* ------------------------------------------------------------------------- *
+ *
+ * internal fb_ops helper functions
+ *
+ * ------------------------------------------------------------------------- */
 
-	fix->line_length = p->line_length;
+/**
+ * riva_get_cmap_len - query current color map length
+ * @var: standard kernel fb changeable data
+ *
+ * DESCRIPTION:
+ * Get current color map length.
+ *
+ * RETURNS:
+ * Length of color map
+ *
+ * CALLED FROM:
+ * riva_getcolreg()
+ * rivafb_setcolreg()
+ * rivafb_get_cmap()
+ * rivafb_set_cmap()
+ */
+static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
+{
+	int rc = 16;		/* reasonable default */
 
-	fix->mmio_start = rivainfo->ctrl_base_phys;
-	fix->mmio_len = rivainfo->base0_region_size;
-	fix->smem_start = rivainfo->fb_base_phys;
-	fix->smem_len = rivainfo->base1_region_size;
+	assert(var != NULL);
 
-	switch (rivainfo->riva.Architecture) {
-	case NV_ARCH_03:
-		fix->accel = FB_ACCEL_NV3;
-		break;
-	case NV_ARCH_04:	/* riva_hw.c now doesn't distinguish between TNT & TNT2 */
-		fix->accel = FB_ACCEL_NV4;
+	switch (var->green.length) {
+	case 5:
+		rc = 32;	/* fix for 15 bpp depths on Riva 128 based cards */
 		break;
-	case NV_ARCH_10:	/* FIXME: ID for GeForce */
-		fix->accel = FB_ACCEL_NV4;
+	case 6:
+		rc = 64;	/* directcolor... 16 entries SW palette */
+		break;		/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
+	default:
+		rc = 256;	/* pseudocolor... 256 entries HW palette */
 		break;
-
 	}
 
-	DPRINTK("EXIT, returning 0\n");
-
-	return 0;
+	return rc;
 }
 
-static int rivafb_get_var(struct fb_var_screeninfo *var, int con,
-			  struct fb_info *info)
+/* ------------------------------------------------------------------------- *
+ *
+ * framebuffer operations
+ *
+ * ------------------------------------------------------------------------- */
+static int rivafb_open(struct fb_info *info, int user)
 {
-	struct rivafb_info *rivainfo = (struct rivafb_info *)info;
+	struct riva_par *par = (struct riva_par *) info->par;
+	int cnt = atomic_read(&par->ref_count);
 
-	DPRINTK("ENTER\n");
-
-	assert(info != NULL);
-	assert(var != NULL);
-
-	*var = (con < 0) ? rivainfo->disp.var : fb_display[con].var;
-
-	DPRINTK("EXIT, returning 0\n");
+	if (!cnt) {
+		memset(&par->state, 0, sizeof(struct vgastate));
+		par->state.flags = VGA_SAVE_MODE  | VGA_SAVE_FONTS;
+		/* save the DAC for Riva128 */
+		if (par->riva.Architecture == NV_ARCH_03)
+			par->state.flags |= VGA_SAVE_CMAP;
+		save_vga(&par->state);
 
+		RivaGetConfig(&par->riva);
+		riva_save_state(par, &par->initial_state);
+	}
+	
+	atomic_inc(&par->ref_count);
 	return 0;
 }
 
-static int rivafb_set_var(struct fb_var_screeninfo *var, int con,
-			  struct fb_info *info)
+static int rivafb_release(struct fb_info *info, int user)
 {
-	struct rivafb_info *rivainfo = (struct rivafb_info *)info;
-	struct display *dsp;
-	struct fb_var_screeninfo v;
-	int nom, den;		/* translating from pixels->bytes */
-	int accel;
-	unsigned chgvar = 0;
+	struct riva_par *par = (struct riva_par *) info->par;
+	int cnt = atomic_read(&par->ref_count);
 
-	DPRINTK("ENTER\n");
-
-	assert(info != NULL);
-	assert(var != NULL);
+	if (!cnt)
+		return -EINVAL;
+	if (cnt == 1) {
+		par->riva.LockUnlock(&par->riva, 0);
+		par->riva.LoadStateExt(&par->riva, &par->initial_state.ext);
 
-	DPRINTK("Requested: %dx%dx%d\n", var->xres, var->yres,
-		var->bits_per_pixel);
-	DPRINTK("  virtual: %dx%d\n", var->xres_virtual,
-		var->yres_virtual);
-	DPRINTK("   offset: (%d,%d)\n", var->xoffset, var->yoffset);
-	DPRINTK("grayscale: %d\n", var->grayscale);
-
-	dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];
-	assert(dsp != NULL);
-
-	/* if var has changed, we should call changevar() later */
-	if (con >= 0) {
-		chgvar = ((dsp->var.xres != var->xres) ||
-			  (dsp->var.yres != var->yres) ||
-			  (dsp->var.xres_virtual != var->xres_virtual) ||
-			  (dsp->var.yres_virtual != var->yres_virtual) ||
-			  (dsp->var.accel_flags != var->accel_flags) ||
-			  (dsp->var.bits_per_pixel != var->bits_per_pixel)
-			  || memcmp(&dsp->var.red, &var->red,
-				    sizeof(var->red))
-			  || memcmp(&dsp->var.green, &var->green,
-				    sizeof(var->green))
-			  || memcmp(&dsp->var.blue, &var->blue,
-				    sizeof(var->blue)));
+		restore_vga(&par->state);
+		par->riva.LockUnlock(&par->riva, 1);
 	}
 
-	memcpy(&v, var, sizeof(v));
+	atomic_dec(&par->ref_count);
 
-	accel = v.accel_flags & FB_ACCELF_TEXT;
+	return 0;
+}
+
+static int rivafb_check_var(struct fb_var_screeninfo *var,
+                            struct fb_info *info)
+{
+	struct riva_par *par = (struct riva_par *) info->par;
+	int nom, den;		/* translating from pixels->bytes */
+	
+	if (par->riva.Architecture == NV_ARCH_03 &&
+	    var->bits_per_pixel == 16)
+		var->bits_per_pixel = 15;
 
-	switch (v.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
+	switch (var->bits_per_pixel) {
 	case 1 ... 8:
-		v.bits_per_pixel = 8;
+		var->bits_per_pixel = 8;
 		nom = 1;
 		den = 1;
-		v.red.offset = 0;
-		v.red.length = 8;
-		v.green.offset = 0;
-		v.green.length = 8;
-		v.blue.offset = 0;
-		v.blue.length = 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;
 		break;
-#endif
-#ifdef FBCON_HAS_CFB16
 	case 9 ... 15:
-		v.green.length = 5;
+		var->green.length = 5;
 		/* fall through */
 	case 16:
-		v.bits_per_pixel = 16;
+		var->bits_per_pixel = 16;
 		nom = 2;
 		den = 1;
-		if (v.green.length == 5) {
+		if (var->green.length == 5) {
 			/* 0rrrrrgg gggbbbbb */
-			v.red.offset = 10;
-			v.green.offset = 5;
-			v.blue.offset = 0;
-			v.red.length = 5;
-			v.green.length = 5;
-			v.blue.length = 5;
+			var->red.offset = 10;
+			var->green.offset = 5;
+			var->blue.offset = 0;
+			var->red.length = 5;
+			var->green.length = 5;
+			var->blue.length = 5;
 		} else {
 			/* rrrrrggg gggbbbbb */
-			v.red.offset = 11;
-			v.green.offset = 5;
-			v.blue.offset = 0;
-			v.red.length = 5;
-			v.green.length = 6;
-			v.blue.length = 5;
+			var->red.offset = 11;
+			var->green.offset = 5;
+			var->blue.offset = 0;
+			var->red.length = 5;
+			var->green.length = 6;
+			var->blue.length = 5;
 		}
 		break;
-#endif
-#ifdef FBCON_HAS_CFB32
 	case 17 ... 32:
-		v.bits_per_pixel = 32;
+		var->bits_per_pixel = 32;
 		nom = 4;
 		den = 1;
-		v.red.offset = 16;
-		v.green.offset = 8;
-		v.blue.offset = 0;
-		v.red.length = 8;
-		v.green.length = 8;
-		v.blue.length = 8;
+		var->red.offset = 16;
+		var->green.offset = 8;
+		var->blue.offset = 0;
+		var->red.length = 8;
+		var->green.length = 8;
+		var->blue.length = 8;
 		break;
-#endif
 	default:
 		printk(KERN_ERR PFX
 		       "mode %dx%dx%d rejected...color depth not supported.\n",
@@ -1448,122 +1262,53 @@
 		return -EINVAL;
 	}
 
-	if (rivafb_do_maximize(rivainfo, var, &v, nom, den) < 0)
+	if (rivafb_do_maximize(info, var, nom, den) < 0)
 		return -EINVAL;
 
-	if (v.xoffset < 0)
-		v.xoffset = 0;
-	if (v.yoffset < 0)
-		v.yoffset = 0;
+	if (var->xoffset < 0)
+		var->xoffset = 0;
+	if (var->yoffset < 0)
+		var->yoffset = 0;
 
 	/* truncate xoffset and yoffset to maximum if too high */
-	if (v.xoffset > v.xres_virtual - v.xres)
-		v.xoffset = v.xres_virtual - v.xres - 1;
-
-	if (v.yoffset > v.yres_virtual - v.yres)
-		v.yoffset = v.yres_virtual - v.yres - 1;
-
-	v.red.msb_right =
-	    v.green.msb_right =
-	    v.blue.msb_right =
-	    v.transp.offset = v.transp.length = v.transp.msb_right = 0;
-
-	switch (v.activate & FB_ACTIVATE_MASK) {
-	case FB_ACTIVATE_TEST:
-		DPRINTK("EXIT - FB_ACTIVATE_TEST\n");
-		return 0;
-	case FB_ACTIVATE_NXTOPEN:	/* ?? */
-	case FB_ACTIVATE_NOW:
-		break;		/* continue */
-	default:
-		DPRINTK("EXIT - unknown activation type\n");
-		return -EINVAL;	/* unknown */
-	}
+	if (var->xoffset > var->xres_virtual - var->xres)
+		var->xoffset = var->xres_virtual - var->xres - 1;
 
-	memcpy(&dsp->var, &v, sizeof(v));
-	if (chgvar) {
-		riva_set_dispsw(rivainfo, dsp);
+	if (var->yoffset > var->yres_virtual - var->yres)
+		var->yoffset = var->yres_virtual - var->yres - 1;
 
-		if (accel) {
-			if (nomove)
-				dsp->scrollmode = SCROLL_YNOMOVE;
-			else
-				dsp->scrollmode = 0;
-		} else
-			dsp->scrollmode = SCROLL_YREDRAW;
-
-		if (info && info->changevar)
-			info->changevar(con);
-	}
-
-	rivafb_create_cursor(rivainfo, fontwidth(dsp), fontheight(dsp));
-	riva_load_video_mode(rivainfo, &v);
-	if (accel) riva_setup_accel(rivainfo);
-
-	DPRINTK("EXIT, returning 0\n");
+	var->red.msb_right =
+	    var->green.msb_right =
+	    var->blue.msb_right =
+	    var->transp.offset = var->transp.length = var->transp.msb_right = 0;
 	return 0;
 }
 
-static int rivafb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			   struct fb_info *info)
+static int rivafb_set_par(struct fb_info *info)
 {
-	struct rivafb_info *rivainfo = (struct rivafb_info *)info;
-	struct display *dsp;
-
-	DPRINTK("ENTER\n");
-
-	assert(rivainfo != NULL);
-	assert(cmap != NULL);
-
-	dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];
-
-	if (con == info->currcon) {	/* current console? */
-		int rc = fb_get_cmap(cmap, kspc, riva_getcolreg, info);
-		DPRINTK("EXIT - returning %d\n", rc);
-		return rc;
-	} else if (dsp->cmap.len)	/* non default colormap? */
-		fb_copy_cmap(&dsp->cmap, cmap, kspc ? 0 : 2);
-	else
-		fb_copy_cmap(fb_default_cmap
-			     (riva_get_cmap_len(&dsp->var)), cmap,
-			     kspc ? 0 : 2);
-
-	DPRINTK("EXIT, returning 0\n");
-
-	return 0;
-}
-
-static int rivafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			   struct fb_info *info)
-{
-	struct rivafb_info *rivainfo = (struct rivafb_info *)info;
-	struct display *dsp;
-	unsigned int cmap_len;
-
-	DPRINTK("ENTER\n");
-	
-	assert(rivainfo != NULL);
-	assert(cmap != NULL);
-
-	dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];
-
-	cmap_len = riva_get_cmap_len(&dsp->var);
-	if (dsp->cmap.len != cmap_len) {
-		int err = fb_alloc_cmap(&dsp->cmap, cmap_len, 0);
-		if (err) {
-			DPRINTK("EXIT - returning %d\n", err);
-			return err;
-		}
-	}
-	if (con == info->currcon) {	/* current console? */
-		int rc = fb_set_cmap(cmap, kspc, info);
-		DPRINTK("EXIT - returning %d\n", rc);
-		return rc;
-	} else
-		fb_copy_cmap(cmap, &dsp->cmap, kspc ? 0 : 1);
-
-	DPRINTK("EXIT, returning 0\n");
+	struct riva_par *par = (struct riva_par *) info->par;
 
+	//rivafb_create_cursor(info, fontwidth(dsp), fontheight(dsp));
+	riva_load_video_mode(info);
+	if (info->var.accel_flags) {
+		riva_setup_accel(par);
+		info->fbops->fb_fillrect  = rivafb_fillrect;
+		info->fbops->fb_copyarea  = rivafb_copyarea;
+		info->fbops->fb_imageblit = rivafb_imageblit;
+		info->fbops->fb_cursor    = rivafb_cursor;
+		info->fbops->fb_sync      = rivafb_sync;
+	}
+	else {
+		info->fbops->fb_fillrect  = cfb_fillrect;
+		info->fbops->fb_copyarea  = cfb_copyarea;
+		info->fbops->fb_imageblit = cfb_imageblit;
+		info->fbops->fb_cursor    = soft_cursor;
+		info->fbops->fb_sync      = NULL;
+	}
+
+	info->fix.line_length = (info->var.xres_virtual * (info->var.bits_per_pixel >> 3));
+	info->fix.visual = (info->var.bits_per_pixel == 8) ? 
+				FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
 	return 0;
 }
 
@@ -1580,135 +1325,58 @@
  *
  * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
  */
-static int rivafb_pan_display(struct fb_var_screeninfo *var, int con,
+static int rivafb_pan_display(struct fb_var_screeninfo *var,
 			      struct fb_info *info)
 {
+	struct riva_par *par = (struct riva_par *) info->par;
 	unsigned int base;
-	struct display *dsp;
-	struct rivafb_info *rivainfo = (struct rivafb_info *)info;
-
-	DPRINTK("ENTER\n");
-
-	assert(rivainfo != NULL);
-
+	
 	if (var->xoffset > (var->xres_virtual - var->xres))
 		return -EINVAL;
 	if (var->yoffset > (var->yres_virtual - var->yres))
 		return -EINVAL;
 
-	dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];
-
 	if (var->vmode & FB_VMODE_YWRAP) {
 		if (var->yoffset < 0
-		    || var->yoffset >= dsp->var.yres_virtual
+		    || var->yoffset >= info->var.yres_virtual
 		    || var->xoffset) return -EINVAL;
 	} else {
-		if (var->xoffset + dsp->var.xres > dsp->var.xres_virtual ||
-		    var->yoffset + dsp->var.yres > dsp->var.yres_virtual)
+		if (var->xoffset + info->var.xres > info->var.xres_virtual ||
+		    var->yoffset + info->var.yres > info->var.yres_virtual)
 			return -EINVAL;
 	}
 
-	base = var->yoffset * dsp->line_length + var->xoffset;
+	base = var->yoffset * info->fix.line_length + var->xoffset;
 
-	if (con == info->currcon) {
-		rivainfo->riva.SetStartAddress(&rivainfo->riva, base);
-	}
+	par->riva.SetStartAddress(&par->riva, base);
 
-	dsp->var.xoffset = var->xoffset;
-	dsp->var.yoffset = var->yoffset;
+	info->var.xoffset = var->xoffset;
+	info->var.yoffset = var->yoffset;
 
 	if (var->vmode & FB_VMODE_YWRAP)
-		dsp->var.vmode |= FB_VMODE_YWRAP;
+		info->var.vmode |= FB_VMODE_YWRAP;
 	else
-		dsp->var.vmode &= ~FB_VMODE_YWRAP;
-
-	DPRINTK("EXIT, returning 0\n");
-
-	return 0;
-}
-
-static int rivafb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-			unsigned long arg, int con, struct fb_info *info)
-{
-	struct rivafb_info *rivainfo = (struct rivafb_info *)info;
-
-	DPRINTK("ENTER\n");
-
-	assert(rivainfo != NULL);
-
-	/* no rivafb-specific ioctls */
-
-	DPRINTK("EXIT, returning -EINVAL\n");
-
-	return -EINVAL;
-}
-
-static int rivafb_rasterimg(struct fb_info *info, int start)
-{
-	struct rivafb_info *rinfo = (struct rivafb_info *)info;
-
-	wait_for_idle(rinfo);
-
-	return 0;
-}
-
-static int rivafb_switch(int con, struct fb_info *info)
-{
-	struct rivafb_info *rivainfo = (struct rivafb_info *)info;
-	struct fb_cmap *cmap;
-	struct display *dsp;
-	
-	DPRINTK("ENTER\n");
-	
-	assert(rivainfo != NULL);
-
-	dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];
-
-	if (info->currcon >= 0) {
-		/* Do we have to save the colormap? */
-		cmap = &(rivainfo->currcon_display->cmap);
-		DPRINTK("switch1: con = %d, cmap.len = %d\n",
-			 info->currcon, cmap->len);
+		info->var.vmode &= ~FB_VMODE_YWRAP;
 
-		if (cmap->len) {
-			DPRINTK("switch1a: %p %p %p %p\n", cmap->red,
-				 cmap->green, cmap->blue, cmap->transp);
-			fb_get_cmap(cmap, 1, riva_getcolreg, info);
-		}
-	}
-	info->currcon = con;
-	rivainfo->currcon_display = dsp;
-
-	rivafb_set_var(&dsp->var, con, info);
-	riva_set_dispsw(rivainfo, dsp);
+	/*
+	 * HACK: The hardware cursor occasionally disappears during fast scrolling.
+	 *       We just reset the cursor each time we change the start address.
+	 *       This also has a beneficial side effect of restoring the cursor 
+	 *       image when switching from X.
+	 */
+	par->cursor_reset = 1;
 
 	DPRINTK("EXIT, returning 0\n");
 	return 0;
 }
 
-static int rivafb_updatevar(int con, struct fb_info *info)
-{
-	int rc;
-
-	DPRINTK("ENTER\n");
-
-	rc = (con < 0) ? -EINVAL : rivafb_pan_display(&fb_display[con].var,
-						      con, info);
-	DPRINTK("EXIT, returning %d\n", rc);
-	return rc;
-}
-
 static int rivafb_blank(int blank, struct fb_info *info)
 {
+	struct riva_par *par = (struct riva_par *) info->par;
 	unsigned char tmp, vesa;
-	struct rivafb_info *rinfo = (struct rivafb_info *)info;
-
-	DPRINTK("ENTER\n");
 
-	assert(rinfo != NULL);
-
-	tmp = SEQin(rinfo, 0x01) & ~0x20;	/* screen on/off */
-	vesa = CRTCin(rinfo, 0x1a) & ~0xc0;	/* sync on/off */
+	tmp = SEQin(par, 0x01) & ~0x20;	/* screen on/off */
+	vesa = CRTCin(par, 0x1a) & ~0xc0;	/* sync on/off */
 
 	if (blank) {
 		tmp |= 0x20;
@@ -1727,14 +1395,127 @@
 		}
 	}
 
-	SEQout(rinfo, 0x01, tmp);
-	CRTCout(rinfo, 0x1a, vesa);
+	SEQout(par, 0x01, tmp);
+	CRTCout(par, 0x1a, vesa);
 
 	DPRINTK("EXIT\n");
 	return 0;
 }
 
+/**
+ * rivafb_setcolreg
+ * @regno: register index
+ * @red: red component
+ * @green: green component
+ * @blue: blue component
+ * @transp: transparency
+ * @info: pointer to rivafb_info object containing info for current riva board
+ *
+ * DESCRIPTION:
+ * Set a single color register. The values supplied have a 16 bit
+ * magnitude.
+ *
+ * RETURNS:
+ * Return != 0 for invalid regno.
+ *
+ * CALLED FROM:
+ * rivafb_set_cmap()
+ * fbcmap.c:fb_set_cmap()
+ *	fbgen.c:fbgen_get_cmap()
+ *	fbgen.c:do_install_cmap()
+ *		fbgen.c:fbgen_set_var()
+ *		fbgen.c:fbgen_switch()
+ *		fbgen.c:fbgen_blank()
+ *	fbgen.c:fbgen_blank()
+ */
+static int rivafb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			    unsigned blue, unsigned transp,
+			    struct fb_info *info)
+{
+	struct riva_par *par = (struct riva_par *) info->par;
+	RIVA_HW_INST *chip = &par->riva;
+	int i;
+
+	if (regno >= riva_get_cmap_len(&info->var))
+		return -EINVAL;
+
+	if (info->var.grayscale) {
+		/* gray = 0.30*R + 0.59*G + 0.11*B */
+		red = green = blue =
+		    (red * 77 + green * 151 + blue * 28) >> 8;
+	}
+
+	if (!regno) {
+		for (i = 0; i < 256; i++) {
+			par->cmap[i].red = 0;
+			par->cmap[i].green = 0;
+			par->cmap[i].blue = 0;
+		}
+	}
+	par->cmap[regno].red   = (u8) red;
+	par->cmap[regno].green = (u8) green;
+	par->cmap[regno].blue  = (u8) blue;
+	
+	if (info->var.green.length == 5) {
+		 /* RGB555: all components have 32 entries, 8 indices apart */
+		for (i = 0; i < 8; i++)
+			riva_wclut(chip, (regno*8)+i, (u8) red, (u8) green, (u8) blue);
+	}
+	else if (info->var.green.length == 6) {
+		/* 
+		 * RGB 565: red and blue have 32 entries, 8 indices apart, while
+		 *          green has 64 entries, 4 indices apart
+		 */
+		if (regno < 32) {
+			for (i = 0; i < 8; i++) {
+				riva_wclut(chip, (regno*8)+i, (u8) red, 
+					   par->cmap[regno*2].green,
+					   (u8) blue);
+			}
+		}
+		for (i = 0; i < 4; i++) {
+			riva_wclut(chip, (regno*4)+i, par->cmap[regno/2].red,
+				   (u8) green, par->cmap[regno/2].blue);
+		
+		}
+	}
+	else {
+		riva_wclut(chip, regno, (u8) red, (u8) green, (u8) blue);
+	}
 
+	if (regno < 16) {
+		switch (info->var.bits_per_pixel) {
+		case 16:
+			if (info->var.green.length == 5) {
+				/* 0rrrrrgg gggbbbbb */
+				((u32 *)(info->pseudo_palette))[regno] =
+					(regno << 10) | (regno << 5) | regno;
+				par->riva_palette[regno] = 
+					((red & 0xf800) >> 1) |
+					((green & 0xf800) >> 6) | ((blue & 0xf800) >> 11);
+
+			} else {
+				/* rrrrrggg gggbbbbb */
+				((u32 *)(info->pseudo_palette))[regno] =
+					(regno << 11) | (regno << 6) | regno;
+				par->riva_palette[regno] = ((red & 0xf800) >> 0) |
+					((green & 0xf800) >> 5) | ((blue & 0xf800) >> 11);
+			}
+			break;
+		case 32:
+			((u32 *)(info->pseudo_palette))[regno] =
+				(regno << 16) | (regno << 8) | regno;
+			par->riva_palette[regno] =
+				((red & 0xff00) << 8) |
+				((green & 0xff00)) | ((blue & 0xff00) >> 8);
+			break;
+		default:
+			/* do nothing */
+			break;
+		}
+	}
+	return 0;
+}
 
 /* ------------------------------------------------------------------------- *
  *
@@ -1745,294 +1526,341 @@
 /* kernel interface */
 static struct fb_ops riva_fb_ops = {
 	.owner =	THIS_MODULE,
-	.fb_get_fix =	rivafb_get_fix,
-	.fb_get_var =	rivafb_get_var,
-	.fb_set_var =	rivafb_set_var,
-	.fb_get_cmap =	rivafb_get_cmap,
-	.fb_set_cmap =	rivafb_set_cmap,
+	.fb_open =      rivafb_open,
+	.fb_release =   rivafb_release,
+	.fb_check_var =	rivafb_check_var,
+	.fb_set_par =	rivafb_set_par,
 	.fb_setcolreg =	rivafb_setcolreg,
-	.fb_pan_display =rivafb_pan_display,
+	.fb_pan_display=rivafb_pan_display,
 	.fb_blank =	rivafb_blank,
-	.fb_ioctl =	rivafb_ioctl,
-	.fb_rasterimg =	rivafb_rasterimg,
+	.fb_fillrect =	rivafb_fillrect,
+	.fb_copyarea =	rivafb_copyarea,
+	.fb_imageblit =	rivafb_imageblit,
+	.fb_cursor =    rivafb_cursor,
+	.fb_sync =      rivafb_sync,
 };
 
-static int __devinit riva_init_disp_var(struct rivafb_info *rinfo)
-{
-#ifndef MODULE
-	if (mode_option)
-		fb_find_mode(&rinfo->disp.var, &rinfo->info, mode_option,
-			     NULL, 0, NULL, 8);
-#endif
-	return 0;
-}
-
-static int __devinit riva_init_disp(struct rivafb_info *rinfo)
+static int __devinit riva_set_fbinfo(struct fb_info *info)
 {
-	struct fb_info *info;
-	struct display *disp;
-
-	DPRINTK("ENTER\n");
-
-	assert(rinfo != NULL);
-
-	info = &rinfo->info;
-	disp = &rinfo->disp;
-
-	disp->var = rivafb_default_var;
-	
-	if (noaccel)
-		disp->var.accel_flags &= ~FB_ACCELF_TEXT;
-	else
-		disp->var.accel_flags |= FB_ACCELF_TEXT;
-	
-	info->disp = disp;
-
-	/* FIXME: assure that disp->cmap is completely filled out */
-
-	rinfo->currcon_display = disp;
-
-	if ((riva_init_disp_var(rinfo)) < 0) {
-		DPRINTK("EXIT, returning -1\n");
-		return -1;
-	}
-
-	riva_set_dispsw(rinfo, disp);
-
-	DPRINTK("EXIT, returning 0\n");
-	return 0;
-
-}
-
-static int __devinit riva_set_fbinfo(struct rivafb_info *rinfo)
-{
-	struct fb_info *info;
-
-	assert(rinfo != NULL);
-
-	info = &rinfo->info;
+	unsigned int cmap_len;
 
-	strcpy(info->modename, rinfo->drvr_name);
 	info->node = NODEV;
 	info->flags = FBINFO_FLAG_DEFAULT;
 	info->fbops = &riva_fb_ops;
-	info->screen_base = rinfo->fb_base;
-	/* FIXME: set monspecs to what??? */
+	info->var = rivafb_default_var;
+	info->fix = rivafb_fix;
 
+	/* FIXME: set monspecs to what??? */
 	info->display_fg = NULL;
-	info->currcon = -1;
-	strncpy(info->fontname, fontname, sizeof(info->fontname));
-	info->fontname[sizeof(info->fontname) - 1] = 0;
-
-	info->changevar = NULL;
-	info->switch_con = rivafb_switch;
-	info->updatevar = rivafb_updatevar;
-
-	if (riva_init_disp(rinfo) < 0)	/* must be done last */
-		return -1;
+	info->pseudo_palette = pseudo_palette;
 
+	cmap_len = riva_get_cmap_len(&info->var);
+	fb_alloc_cmap(&info->cmap, cmap_len, 0);
+#ifndef MODULE
+	if (mode_option)
+		fb_find_mode(&info->var, info, mode_option,
+			     NULL, 0, NULL, 8);
+#endif
 	return 0;
 }
 
-
-
 /* ------------------------------------------------------------------------- *
  *
  * PCI bus
  *
  * ------------------------------------------------------------------------- */
 
+static void __devinit rivafb_get_mem_len(struct riva_par *par,
+					 struct fb_fix_screeninfo *fix)
+{
+	RIVA_HW_INST *chip = &par->riva;
+
+	switch (chip->Architecture) {
+	case NV_ARCH_03:
+		if (chip->PFB[0x00000000/4] & 0x00000020) {
+			if (((chip->PMC[0x00000000/4] & 0xF0) == 0x20)
+			    && ((chip->PMC[0x00000000/4] & 0x0F) >= 0x02)) {   
+				/*
+				 * SDRAM 128 ZX.
+				 */
+				switch (chip->PFB[0x00000000/4] & 0x03) {
+				case 2:
+					fix->smem_len = 1024 * 1024 * 4;
+					break;
+				case 1:
+					fix->smem_len = 1024 * 1024 * 2;
+					break;
+				default:
+					fix->smem_len = 1024 * 1024 * 8;
+					break;
+				}
+			}            
+			else  {
+				fix->smem_len = 1024 * 1024 * 8;
+			}            
+		}
+		else {
+			/*
+			 * SGRAM 128.
+			 */
+			switch (chip->PFB[0x00000000/4] & 0x00000003) {
+			case 0:
+				fix->smem_len = 1024 * 1024 * 8;
+				break;
+			case 2:
+				fix->smem_len = 1024 * 1024 * 4;
+				break;
+			default:
+				fix->smem_len = 1024 * 1024 * 2;
+				break;
+			}
+		}
+		break;
+	case NV_ARCH_04:
+		if (chip->PFB[0x00000000/4] & 0x00000100) {
+			fix->smem_len = (((chip->PFB[0x00000000/4] >> 12)
+					 & 0x0F) * 1024 * 2 + 1024 * 2) * 1024;
+		}
+		else {
+			switch (chip->PFB[0x00000000/4] & 0x00000003) {
+			case 0:
+				fix->smem_len = 1024 * 1024 * 32;
+				break;
+			case 1:
+				fix->smem_len = 1024 * 1024 * 4;
+				break;
+			case 2:
+				fix->smem_len = 1024 * 1024 * 8;
+				break;
+			case 3:
+			default:
+				fix->smem_len = 1024 * 1024 * 16;
+				break;
+			}
+		}
+		break;
+	case NV_ARCH_10:
+	case NV_ARCH_20:
+		switch ((chip->PFB[0x0000020C/4] >> 20) & 0x000000FF) {
+		case 0x02:
+			fix->smem_len = 1024 * 1024 * 2;
+			break;
+		case 0x04:
+			fix->smem_len = 1024 * 1024 * 4;
+			break;
+		case 0x08:
+			fix->smem_len = 1024 * 1024 * 8;
+			break;
+		case 0x10:
+			fix->smem_len = 1024 * 1024 * 16;
+			break;
+		case 0x20:
+			fix->smem_len = 1024 * 1024 * 32;
+			break;
+		case 0x40:
+			fix->smem_len = 1024 * 1024 * 64;
+			break;
+		case 0x80:
+			fix->smem_len = 1024 * 1024 * 128;
+			break;
+		default:
+			fix->smem_len = 1024 * 1024 * 16;
+			break;
+		}
+	}
+}
+
 static int __devinit rivafb_init_one(struct pci_dev *pd,
 				     const struct pci_device_id *ent)
 {
-	struct rivafb_info *rinfo;
 	struct riva_chip_info *rci = &riva_chip_info[ent->driver_data];
+	struct riva_par *default_par;
+	struct fb_info *info;
 
 	assert(pd != NULL);
 	assert(rci != NULL);
 
-	rinfo = kmalloc(sizeof(struct rivafb_info), GFP_KERNEL);
-	if (!rinfo)
+	info = kmalloc(sizeof(struct fb_info), GFP_KERNEL);
+	if (!info)
 		goto err_out;
 
-	memset(rinfo, 0, sizeof(struct rivafb_info));
+	default_par = kmalloc(sizeof(struct riva_par), GFP_KERNEL);
+	if (!default_par) 
+		goto err_out_kfree;
 
-	rinfo->drvr_name = rci->name;
-	rinfo->riva.Architecture = rci->arch_rev;
+	memset(info, 0, sizeof(struct fb_info));
+	memset(default_par, 0, sizeof(struct riva_par));
 
-	rinfo->pd = pd;
-	rinfo->base0_region_size = pci_resource_len(pd, 0);
-	rinfo->base1_region_size = pci_resource_len(pd, 1);
+	strcat(rivafb_fix.id, rci->name);
+	default_par->riva.Architecture = rci->arch_rev;
 
-	assert(rinfo->base0_region_size >= 0x00800000);	/* from GGI */
-	assert(rinfo->base1_region_size >= 0x01000000);	/* from GGI */
+	rivafb_fix.mmio_len = pci_resource_len(pd, 0);
+	rivafb_fix.smem_len = pci_resource_len(pd, 1);
 
-	rinfo->ctrl_base_phys = pci_resource_start(rinfo->pd, 0);
-	rinfo->fb_base_phys = pci_resource_start(rinfo->pd, 1);
+	rivafb_fix.mmio_start = pci_resource_start(pd, 0);
+	rivafb_fix.smem_start = pci_resource_start(pd, 1);
 
-	if (!request_mem_region(rinfo->ctrl_base_phys,
-				rinfo->base0_region_size, "rivafb")) {
+	if (!request_mem_region(rivafb_fix.mmio_start,
+				rivafb_fix.mmio_len, "rivafb")) {
 		printk(KERN_ERR PFX "cannot reserve MMIO region\n");
 		goto err_out_kfree;
 	}
 
-	if (!request_mem_region(rinfo->fb_base_phys,
-				rinfo->base1_region_size, "rivafb")) {
-		printk(KERN_ERR PFX "cannot reserve FB region\n");
-		goto err_out_free_base0;
-	}
-	
-	rinfo->ctrl_base = ioremap(rinfo->ctrl_base_phys,
-				   rinfo->base0_region_size);
-	if (!rinfo->ctrl_base) {
+	default_par->ctrl_base = ioremap(rivafb_fix.mmio_start,
+				   rivafb_fix.mmio_len);
+	if (!default_par->ctrl_base) {
 		printk(KERN_ERR PFX "cannot ioremap MMIO base\n");
 		goto err_out_free_base1;
 	}
 	
-	rinfo->fb_base = ioremap(rinfo->fb_base_phys,
-				 rinfo->base1_region_size);
-	if (!rinfo->fb_base) {
+	info->screen_base = ioremap(rivafb_fix.smem_start,
+				   rivafb_fix.smem_len);
+	if (!info->screen_base) {
 		printk(KERN_ERR PFX "cannot ioremap FB base\n");
 		goto err_out_iounmap_ctrl;
 	}
 	
-#ifdef CONFIG_MTRR
-	if (!nomtrr) {
-		rinfo->mtrr.vram = mtrr_add(rinfo->fb_base_phys,
-					    rinfo->base1_region_size, MTRR_TYPE_WRCOMB, 1);
-		if (rinfo->mtrr.vram < 0) {
-			printk(KERN_ERR PFX "unable to setup MTRR\n");
-		} else {
-			rinfo->mtrr.vram_valid = 1;
-			/* let there be speed */
-			printk(KERN_INFO PFX "RIVA MTRR set to ON\n");
-		}
-	}
-#endif /* CONFIG_MTRR */
-
-	rinfo->riva.EnableIRQ = 0;
-	rinfo->riva.PRAMDAC = (unsigned *)(rinfo->ctrl_base + 0x00680000);
-	rinfo->riva.PFB = (unsigned *)(rinfo->ctrl_base + 0x00100000);
-	rinfo->riva.PFIFO = (unsigned *)(rinfo->ctrl_base + 0x00002000);
-	rinfo->riva.PGRAPH = (unsigned *)(rinfo->ctrl_base + 0x00400000);
-	rinfo->riva.PEXTDEV = (unsigned *)(rinfo->ctrl_base + 0x00101000);
-	rinfo->riva.PTIMER = (unsigned *)(rinfo->ctrl_base + 0x00009000);
-	rinfo->riva.PMC = (unsigned *)(rinfo->ctrl_base + 0x00000000);
-	rinfo->riva.FIFO = (unsigned *)(rinfo->ctrl_base + 0x00800000);
-
-	rinfo->riva.PCIO = (U008 *)(rinfo->ctrl_base + 0x00601000);
-	rinfo->riva.PDIO = (U008 *)(rinfo->ctrl_base + 0x00681000);
-	rinfo->riva.PVIO = (U008 *)(rinfo->ctrl_base + 0x000C0000);
+	default_par->riva.EnableIRQ = 0;
+	default_par->riva.PRAMDAC = (unsigned *)(default_par->ctrl_base + 
+						 0x00680000);
+	default_par->riva.PFB = (unsigned *)(default_par->ctrl_base + 
+					     0x00100000);
+	default_par->riva.PFIFO = (unsigned *)(default_par->ctrl_base + 
+					       0x00002000);
+	default_par->riva.PGRAPH = (unsigned *)(default_par->ctrl_base + 
+						0x00400000);
+	default_par->riva.PEXTDEV = (unsigned *)(default_par->ctrl_base +
+						 0x00101000);
+	default_par->riva.PTIMER = (unsigned *)(default_par->ctrl_base + 
+						0x00009000);
+	default_par->riva.PMC = (unsigned *)(default_par->ctrl_base + 
+					     0x00000000);
+	default_par->riva.FIFO = (unsigned *)(default_par->ctrl_base + 
+					      0x00800000);
+
+	default_par->riva.PCIO = (U008 *)(default_par->ctrl_base + 0x00601000);
+	default_par->riva.PDIO = (U008 *)(default_par->ctrl_base + 0x00681000);
+	default_par->riva.PVIO = (U008 *)(default_par->ctrl_base + 0x000C0000);
 
-	rinfo->riva.IO = (MISCin(rinfo) & 0x01) ? 0x3D0 : 0x3B0;
+	default_par->riva.IO = (MISCin(default_par) & 0x01) ? 0x3D0 : 0x3B0;
 
-	switch (rinfo->riva.Architecture) {
+	switch (default_par->riva.Architecture) {
 	case NV_ARCH_03:
-		rinfo->riva.PRAMIN = (unsigned *)(rinfo->fb_base + 0x00C00000);
+		default_par->riva.PRAMIN = (unsigned *)(info->screen_base + 
+							0x00C00000);
+		default_par->dclk_max = 256000000;
+		rivafb_fix.accel = FB_ACCEL_NV3;
 		break;
 	case NV_ARCH_04:
 	case NV_ARCH_10:
-		rinfo->riva.PCRTC = (unsigned *)(rinfo->ctrl_base + 0x00600000);
-		rinfo->riva.PRAMIN = (unsigned *)(rinfo->ctrl_base + 0x00710000);
+	case NV_ARCH_20:
+		default_par->riva.PCRTC = (unsigned *)(default_par->ctrl_base 
+						       + 0x00600000);
+		default_par->riva.PRAMIN = (unsigned *)(default_par->ctrl_base
+							+ 0x00710000);
+		default_par->dclk_max = 250000000;
+		rivafb_fix.accel = FB_ACCEL_NV4;
 		break;
 	}
 
-	RivaGetConfig(&rinfo->riva);
+	rivafb_get_mem_len(default_par, &rivafb_fix);
 
-	/* back to normal */
+	info->par = default_par;
 
-	assert(rinfo->pd != NULL);
-
-	/* unlock io */
-	CRTCout(rinfo, 0x11, 0xFF);	/* vgaHWunlock() + riva unlock (0x7F) */
-	rinfo->riva.LockUnlock(&rinfo->riva, 0);
-
-	riva_save_state(rinfo, &rinfo->initial_state);
-
-	rinfo->ram_amount = rinfo->riva.RamAmountKBytes * 1024;
-	rinfo->dclk_max = rinfo->riva.MaxVClockFreqKHz * 1000;
+	if (!request_mem_region(rivafb_fix.smem_start,
+				rivafb_fix.smem_len, "rivafb")) {
+		printk(KERN_ERR PFX "cannot reserve FB region\n");
+		goto err_out_free_base0;
+	}
+	
+	info->screen_base = ioremap(rivafb_fix.smem_start,
+				 	  rivafb_fix.smem_len);
+	if (!info->screen_base) {
+		printk(KERN_ERR PFX "cannot ioremap FB base\n");
+		goto err_out_iounmap_ctrl;
+	}
 
-	if (!nohwcursor) rinfo->cursor = rivafb_init_cursor(rinfo);
+#ifdef CONFIG_MTRR
+	if (!nomtrr) {
+		default_par->mtrr.vram = mtrr_add(rivafb_fix.smem_start,
+					    rivafb_fix.smem_len,
+					    MTRR_TYPE_WRCOMB, 1);
+		if (default_par->mtrr.vram < 0) {
+			printk(KERN_ERR PFX "unable to setup MTRR\n");
+		} else {
+			default_par->mtrr.vram_valid = 1;
+			/* let there be speed */
+			printk(KERN_INFO PFX "RIVA MTRR set to ON\n");
+		}
+	}
+#endif /* CONFIG_MTRR */
 
-	if (riva_set_fbinfo(rinfo) < 0) {
+	if (riva_set_fbinfo(info) < 0) {
 		printk(KERN_ERR PFX "error setting initial video mode\n");
 		goto err_out_cursor;
 	}
 
-	if (register_framebuffer((struct fb_info *)rinfo) < 0) {
+	if (register_framebuffer(info) < 0) {
 		printk(KERN_ERR PFX
 			"error registering riva framebuffer\n");
 		goto err_out_load_state;
 	}
 
-	riva_boards = riva_board_list_add(riva_boards, rinfo);
-
-	pci_set_drvdata(pd, rinfo);
+	pci_set_drvdata(pd,info);
 
 	printk(KERN_INFO PFX
-		"PCI nVidia NV%d framebuffer ver %s (%s, %dMB @ 0x%lX)\n",
-		rinfo->riva.Architecture,
+		"PCI nVidia NV%x framebuffer ver %s (%s, %dMB @ 0x%lX)\n",
+		default_par->riva.Architecture,
 		RIVAFB_VERSION,
-		rinfo->drvr_name,
-		rinfo->ram_amount / (1024 * 1024),
-		rinfo->fb_base_phys);
+		info->fix.id,
+		info->fix.smem_len / (1024 * 1024),
+		info->fix.smem_start);
 
 	return 0;
 
 err_out_load_state:
-	riva_load_state(rinfo, &rinfo->initial_state);
 err_out_cursor:
-	rivafb_exit_cursor(rinfo);
 /* err_out_iounmap_fb: */
-	iounmap(rinfo->fb_base);
+	iounmap(info->screen_base);
 err_out_iounmap_ctrl:
-	iounmap(rinfo->ctrl_base);
+	iounmap(default_par->ctrl_base);
 err_out_free_base1:
-	release_mem_region(rinfo->fb_base_phys, rinfo->base1_region_size);
+	release_mem_region(info->fix.smem_start, info->fix.smem_len);
 err_out_free_base0:
-	release_mem_region(rinfo->ctrl_base_phys, rinfo->base0_region_size);
+	release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
 err_out_kfree:
-	kfree(rinfo);
+	kfree(info);
 err_out:
 	return -ENODEV;
 }
 
 static void __devexit rivafb_remove_one(struct pci_dev *pd)
 {
-	struct rivafb_info *board = pci_get_drvdata(pd);
+	struct fb_info *info = pci_get_drvdata(pd);
+	struct riva_par *par = (struct riva_par *) info->par;
 	
-	if (!board)
+	if (!info)
 		return;
 
-	riva_boards = riva_board_list_del(riva_boards, board);
-
-	riva_load_state(board, &board->initial_state);
-
-	unregister_framebuffer((struct fb_info *)board);
-
-	rivafb_exit_cursor(board);
+	unregister_framebuffer(info);
 
 #ifdef CONFIG_MTRR
-	if (board->mtrr.vram_valid)
-		mtrr_del(board->mtrr.vram, board->fb_base_phys,
-			 board->base1_region_size);
+	if (par->mtrr.vram_valid)
+		mtrr_del(par->mtrr.vram, info->fix.smem_start,
+			 info->fix.smem_len);
 #endif /* CONFIG_MTRR */
 
-	iounmap(board->ctrl_base);
-	iounmap(board->fb_base);
-
-	release_mem_region(board->ctrl_base_phys,
-			   board->base0_region_size);
-	release_mem_region(board->fb_base_phys,
-			   board->base1_region_size);
-
-	kfree(board);
+	iounmap(par->ctrl_base);
+	iounmap(info->screen_base);
 
+	release_mem_region(info->fix.mmio_start,
+			   info->fix.mmio_len);
+	release_mem_region(info->fix.smem_start,
+			   info->fix.smem_len);
+	kfree(info);
 	pci_set_drvdata(pd, NULL);
 }
 
-
-
 /* ------------------------------------------------------------------------- *
  *
  * initialization
@@ -2050,30 +1878,11 @@
 	while ((this_opt = strsep(&options, ",")) != NULL) {
 		if (!*this_opt)
 			continue;
-		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)) {
-			noblink = 1;
-		} else if (!strncmp(this_opt, "noaccel", 7)) {
-			noaccel = 1;
-		} else if (!strncmp(this_opt, "nomove", 6)) {
-			nomove = 1;
 #ifdef CONFIG_MTRR
-		} else if (!strncmp(this_opt, "nomtrr", 6)) {
+		if (!strncmp(this_opt, "nomtrr", 6)) {
 			nomtrr = 1;
-#endif
-		} else if (!strncmp(this_opt, "nohwcursor", 10)) {
-			nohwcursor = 1;
 		} else
+#endif
 			mode_option = this_opt;
 	}
 	return 0;
@@ -2081,10 +1890,10 @@
 #endif /* !MODULE */
 
 static struct pci_driver rivafb_driver = {
-	.name =		"rivafb",
-	.id_table =	rivafb_pci_tbl,
-	.probe =	rivafb_init_one,
-	.remove =	__devexit_p(rivafb_remove_one),
+	name:		"rivafb",
+	id_table:	rivafb_pci_tbl,
+	probe:		rivafb_init_one,
+	remove:		__devexit_p(rivafb_remove_one),
 };
 
 
@@ -2098,9 +1907,7 @@
 int __init rivafb_init(void)
 {
 	int err;
-#ifdef MODULE
-	if (font) strncpy(fontname, font, sizeof(fontname)-1);
-#endif
+
 	err = pci_module_init(&rivafb_driver);
 	if (err)
 		return err;
@@ -2121,12 +1928,6 @@
 MODULE_PARM_DESC(font, "Specifies one of the compiled-in fonts (default=none)");
 MODULE_PARM(noaccel, "i");
 MODULE_PARM_DESC(noaccel, "Disables hardware acceleration (0 or 1=disabled) (default=0)");
-MODULE_PARM(nomove, "i");
-MODULE_PARM_DESC(nomove, "Enables YSCROLL_NOMOVE (0 or 1=enabled) (default=0)");
-MODULE_PARM(nohwcursor, "i");
-MODULE_PARM_DESC(nohwcursor, "Disables hardware cursor (0 or 1=disabled) (default=0)");
-MODULE_PARM(noblink, "i");
-MODULE_PARM_DESC(noblink, "Disables hardware cursor blinking (0 or 1=disabled) (default=0)");
 #ifdef CONFIG_MTRR
 MODULE_PARM(nomtrr, "i");
 MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) (default=0)");
diff -Nru a/drivers/video/riva/riva_hw.h b/drivers/video/riva/riva_hw.h
--- a/drivers/video/riva/riva_hw.h	Mon Dec  9 18:46:51 2002
+++ b/drivers/video/riva/riva_hw.h	Mon Dec  9 18:46:51 2002
@@ -74,6 +74,7 @@
 #define NV_ARCH_03  0x03
 #define NV_ARCH_04  0x04
 #define NV_ARCH_10  0x10
+#define NV_ARCH_20  0x20
 /***************************************************************************\
 *                                                                           *
 *                             FIFO registers.                               *
diff -Nru a/drivers/video/riva/rivafb.h b/drivers/video/riva/rivafb.h
--- a/drivers/video/riva/rivafb.h	Mon Dec  9 18:46:35 2002
+++ b/drivers/video/riva/rivafb.h	Mon Dec  9 18:46:35 2002
@@ -3,11 +3,7 @@
 
 #include <linux/config.h>
 #include <linux/fb.h>
-#include <video/fbcon.h>
-#include <video/fbcon-cfb4.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb32.h>
+#include <video/vga.h>
 #include "riva_hw.h"
 
 /* GGI compatibility macros */
@@ -31,52 +27,20 @@
 	unsigned char red, green, blue, transp;
 } riva_cfb8_cmap_t;
 
-struct rivafb_info;
-struct rivafb_info {
-	struct fb_info info;	/* kernel framebuffer info */
-
+struct riva_par {
 	RIVA_HW_INST riva;	/* interface to riva_hw.c */
 
-	const char *drvr_name;	/* Riva hardware board type */
-
-	unsigned long ctrl_base_phys;	/* physical control register base addr */
-	unsigned long fb_base_phys;	/* physical framebuffer base addr */
-
 	caddr_t ctrl_base;	/* virtual control register base addr */
-	caddr_t fb_base;	/* virtual framebuffer base addr */
-
-	unsigned ram_amount;	/* amount of RAM on card, in bytes */
 	unsigned dclk_max;	/* max DCLK */
 
 	struct riva_regs initial_state;	/* initial startup video mode */
 	struct riva_regs current_state;
-
-	struct display disp;
-	int currcon;
-	struct display *currcon_display;
-
-	struct rivafb_info *next;
-
-	struct pci_dev *pd;	/* pointer to board's pci info */
-	unsigned base0_region_size;	/* size of control register region */
-	unsigned base1_region_size;	/* size of framebuffer region */
-
-	struct riva_cursor *cursor;
-
-	struct display_switch dispsw;
-
-	riva_cfb8_cmap_t palette[256];	/* VGA DAC palette cache */
-
-#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
-	union {
-#ifdef FBCON_HAS_CFB16
-		u_int16_t cfb16[16];
-#endif
-#ifdef FBCON_HAS_CFB32
-		u_int32_t cfb32[16];
-#endif
-	} con_cmap;
-#endif				/* FBCON_HAS_CFB16 | FBCON_HAS_CFB32 */
+	struct vgastate state;
+	atomic_t ref_count;
+	riva_cfb8_cmap_t cmap[256];	/* VGA DAC palette cache */
+	u32 riva_palette[16];
+	u32 cursor_data[32 * 32/4];
+	int cursor_reset;
 #ifdef CONFIG_MTRR
 	struct { int vram; int vram_valid; } mtrr;
 #endif
diff -Nru a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
--- a/drivers/video/sa1100fb.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/video/sa1100fb.c	Mon Dec  9 18:46:35 2002
@@ -1432,7 +1432,7 @@
 	LCCR0 &= ~LCCR0_LEN;	/* Disable LCD Controller */
 
 	schedule_timeout(20 * HZ / 1000);
-	current->state = TASK_RUNNING;
+	set_current_state(TASK_RUNNING);
 	remove_wait_queue(&fbi->ctrlr_wait, &wait);
 }
 
diff -Nru a/drivers/video/sbusfb.c b/drivers/video/sbusfb.c
--- a/drivers/video/sbusfb.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/video/sbusfb.c	Mon Dec  9 18:46:50 2002
@@ -1066,7 +1066,7 @@
 		kfree(fb);
 		return;
 	}
-	printk(KERN_INFO "fb%d: %s\n", GET_FB_IDX(fb->info.node), p);
+	printk(KERN_INFO "fb%d: %s\n", minor(fb->info.node), p);
 }
 
 static inline int known_card(char *name)
diff -Nru a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c
--- a/drivers/video/sgivwfb.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/video/sgivwfb.c	Mon Dec  9 18:46:37 2002
@@ -23,17 +23,16 @@
 #include <asm/uaccess.h>
 #include <linux/fb.h>
 #include <linux/init.h>
+#include <linux/ioport.h>
 #include <asm/io.h>
 #include <asm/mtrr.h>
 
-#include <video/fbcon.h>
-
 #define INCLUDE_TIMING_TABLE_DATA
-#define DBE_REG_BASE regs
-#include <video/sgivw.h>
+#define DBE_REG_BASE default_par.regs
+#include <asm/sgi-vwdbe.h>
 
 struct sgivw_par {
-	asregs *regs;
+	struct asregs *regs;
 	u32 cmap_fifo;
 	u_long timing_num;
 };
@@ -46,11 +45,12 @@
  */
 
 /* set by arch/i386/kernel/setup.c */
-u_long sgivwfb_mem_phys;
-u_long sgivwfb_mem_size;
+extern unsigned long sgivwfb_mem_phys;
+extern unsigned long sgivwfb_mem_size;
 
-static struct fb_info fb_info;
 static struct sgivw_par default_par;
+static u32 pseudo_palette[17];
+static struct fb_info fb_info;
 static int ypan = 0;
 static int ywrap = 0;
 
@@ -60,7 +60,7 @@
         .visual		= FB_VISUAL_PSEUDOCOLOR,
 	.mmio_start	= DBE_REG_PHYS,
 	.mmio_len	= DBE_REG_SIZE,
-        .accel_flags	= FB_ACCEL_NONE
+        .accel		= FB_ACCEL_NONE
 };
 
 static struct fb_var_screeninfo sgivwfb_var __initdata = {
@@ -85,9 +85,6 @@
         .vmode		= FB_VMODE_NONINTERLACED
 };
 
-/* console related variables */
-static struct display disp;
-
 /*
  *  Interface used by the world
  */
@@ -104,15 +101,13 @@
 
 static struct fb_ops sgivwfb_ops = {
 	.owner		= THIS_MODULE,
-	.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_cursor	= soft_cursor,
 	.fb_mmap	= sgivwfb_mmap,
 };
 
@@ -159,8 +154,8 @@
 
 static void dbe_TurnOffDma(void)
 {
-	int i;
 	unsigned int readVal;
+	int i;
 
 	// Check to see if things are already turned off:
 	// 1) Check to see if dbe is not using the internal dotclock.
@@ -226,7 +221,7 @@
 static int sgivwfb_check_var(struct fb_var_screeninfo *var, 
 			     struct fb_info *info)
 {
-	int err, activate = var->activate;
+	struct sgivw_par *par = (struct sgivw_par *)info->par;
 	struct dbe_timing_info *timing;
 	u_long line_length;
 	u_long min_mode;
@@ -240,8 +235,8 @@
 
 	if (var->vmode & FB_VMODE_CONUPDATE) {
 		var->vmode |= FB_VMODE_YWRAP;
-		var->xoffset = display->var.xoffset;
-		var->yoffset = display->var.yoffset;
+		var->xoffset = info->var.xoffset;
+		var->yoffset = info->var.yoffset;
 	}
 
 	/* XXX FIXME - forcing var's */
@@ -369,7 +364,7 @@
 	u32 readVal, outputVal;
 	int wholeTilesX, maxPixelsPerTileX;
 	int frmWrite1, frmWrite2, frmWrite3b;
-	dbe_timing_info_t *currentTiming;	/* Current Video Timing */
+	struct dbe_timing_info_t *currentTiming; /* Current Video Timing */
 	int xpmax, ypmax;	// Monitor resolution
 	int bytesPerPixel;	// Bytes per pixel
 
@@ -705,11 +700,16 @@
 	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 (!request_mem_region(DBE_REG_PHYS, DBE_REG_SIZE, "sgivwfb")) {
+		printk(KERN_ERR "sgivwfb: couldn't reserve mmio region\n");
+		goto fail_request_mem_region;
+	}
+	default_par.regs = (struct 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);
@@ -720,41 +720,29 @@
 	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);
+	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);
+	fb_alloc_cmap(&fb_info.cmap, 256, 0);
 
 	if (register_framebuffer(&fb_info) < 0) {
-		printk(KERN_ERR
-		       "sgivwfb: couldn't register framebuffer\n");
+		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);
-
+	printk(KERN_INFO "fb%d: SGI BDE frame buffer device, using %ldK of video memory\n", minor(fb_info.node, sgivwfb_mem_size >> 10);
 	return 0;
 
       fail_register_framebuffer:
diff -Nru a/drivers/video/sis/Makefile b/drivers/video/sis/Makefile
--- a/drivers/video/sis/Makefile	Mon Dec  9 18:46:51 2002
+++ b/drivers/video/sis/Makefile	Mon Dec  9 18:46:51 2002
@@ -6,7 +6,7 @@
 
 obj-$(CONFIG_FB_SIS) += sisfb.o
 
-sisfb-objs := sis_main.o init.o init301.o
+sisfb-objs := sis_main.o sis_accel.o init.o init301.o
 
 include $(TOPDIR)/Rules.make
 
diff -Nru a/drivers/video/sis/sis_accel.c b/drivers/video/sis/sis_accel.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/sis/sis_accel.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,495 @@
+/*
+ * SiS 300/630/730/540/315/550/650/740 frame buffer driver
+ * for Linux kernels 2.4.x and 2.5.x
+ *
+ * 2D acceleration part
+ *
+ * Based on the X driver's sis300_accel.c which is
+ *     Copyright Xavier Ducoin <x.ducoin@lectra.com>
+ *     Copyright 2002 by Thomas Winischhofer, Vienna, Austria
+ * and sis310_accel.c which is
+ *     Copyright 2002 by Thomas Winischhofer, Vienna, Austria
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *			(see http://www.winischhofer.net/
+ *			for more information and updates)
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/console.h>
+#include <linux/selection.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/vt_kern.h>
+#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 <video/fbcon.h>
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33)
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb16.h>
+#include <video/fbcon-cfb24.h>
+#include <video/fbcon-cfb32.h>
+#endif
+
+#include "osdef.h"
+#include "vgatypes.h"
+#include "vstruct.h"
+#include "sis_accel.h"
+
+extern struct     video_info ivideo;
+extern VGA_ENGINE sisvga_engine;
+
+static const int sisALUConv[] =
+{
+    0x00,       /* dest = 0;            0,      GXclear,        0 */
+    0x88,       /* dest &= src;         DSa,    GXand,          0x1 */
+    0x44,       /* dest = src & ~dest;  SDna,   GXandReverse,   0x2 */
+    0xCC,       /* dest = src;          S,      GXcopy,         0x3 */
+    0x22,       /* dest &= ~src;        DSna,   GXandInverted,  0x4 */
+    0xAA,       /* dest = dest;         D,      GXnoop,         0x5 */
+    0x66,       /* dest = ^src;         DSx,    GXxor,          0x6 */
+    0xEE,       /* dest |= src;         DSo,    GXor,           0x7 */
+    0x11,       /* dest = ~src & ~dest; DSon,   GXnor,          0x8 */
+    0x99,       /* dest ^= ~src ;       DSxn,   GXequiv,        0x9 */
+    0x55,       /* dest = ~dest;        Dn,     GXInvert,       0xA */
+    0xDD,       /* dest = src|~dest ;   SDno,   GXorReverse,    0xB */
+    0x33,       /* dest = ~src;         Sn,     GXcopyInverted, 0xC */
+    0xBB,       /* dest |= ~src;        DSno,   GXorInverted,   0xD */
+    0x77,       /* dest = ~src|~dest;   DSan,   GXnand,         0xE */
+    0xFF,       /* dest = 0xFF;         1,      GXset,          0xF */
+};
+/* same ROP but with Pattern as Source */
+static const int sisPatALUConv[] =
+{
+    0x00,       /* dest = 0;            0,      GXclear,        0 */
+    0xA0,       /* dest &= src;         DPa,    GXand,          0x1 */
+    0x50,       /* dest = src & ~dest;  PDna,   GXandReverse,   0x2 */
+    0xF0,       /* dest = src;          P,      GXcopy,         0x3 */
+    0x0A,       /* dest &= ~src;        DPna,   GXandInverted,  0x4 */
+    0xAA,       /* dest = dest;         D,      GXnoop,         0x5 */
+    0x5A,       /* dest = ^src;         DPx,    GXxor,          0x6 */
+    0xFA,       /* dest |= src;         DPo,    GXor,           0x7 */
+    0x05,       /* dest = ~src & ~dest; DPon,   GXnor,          0x8 */
+    0xA5,       /* dest ^= ~src ;       DPxn,   GXequiv,        0x9 */
+    0x55,       /* dest = ~dest;        Dn,     GXInvert,       0xA */
+    0xF5,       /* dest = src|~dest ;   PDno,   GXorReverse,    0xB */
+    0x0F,       /* dest = ~src;         Pn,     GXcopyInverted, 0xC */
+    0xAF,       /* dest |= ~src;        DPno,   GXorInverted,   0xD */
+    0x5F,       /* dest = ~src|~dest;   DPan,   GXnand,         0xE */
+    0xFF,       /* dest = 0xFF;         1,      GXset,          0xF */
+};
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)
+static const unsigned char myrops[] = {
+   	3, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
+   };
+#endif
+
+/* 300 series */
+
+static void
+SiS300Sync(void)
+{
+	SiS300Idle
+}
+
+static void
+SiS310Sync(void)
+{
+	SiS310Idle
+}
+
+static void
+SiS300SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
+                                unsigned int planemask, int trans_color)
+{
+	SiS300SetupDSTColorDepth(ivideo.DstColor);
+	SiS300SetupSRCPitch(ivideo.video_linelength)
+	SiS300SetupDSTRect(ivideo.video_linelength, -1)
+
+	if(trans_color != -1) {
+		SiS300SetupROP(0x0A)
+		SiS300SetupSRCTrans(trans_color)
+		SiS300SetupCMDFlag(TRANSPARENT_BITBLT)
+	} else {
+	        SiS300SetupROP(sisALUConv[rop])
+	}
+	if(xdir > 0) {
+		SiS300SetupCMDFlag(X_INC)
+	}
+	if(ydir > 0) {
+		SiS300SetupCMDFlag(Y_INC)
+	}
+}
+
+static void
+SiS300SubsequentScreenToScreenCopy(int src_x, int src_y, int dst_x, int dst_y,
+                                int width, int height)
+{
+	long srcbase, dstbase;
+
+	srcbase = dstbase = 0;
+	if (src_y >= 2048) {
+		srcbase = ivideo.video_linelength * src_y;
+		src_y = 0;
+	}
+	if (dst_y >= 2048) {
+		dstbase = ivideo.video_linelength * dst_y;
+		dst_y = 0;
+	}
+
+	SiS300SetupSRCBase(srcbase);
+	SiS300SetupDSTBase(dstbase);
+
+	if(!(ivideo.CommandReg & X_INC))  {
+		src_x += width-1;
+		dst_x += width-1;
+	}
+	if(!(ivideo.CommandReg & Y_INC))  {
+		src_y += height-1;
+		dst_y += height-1;
+	}
+	SiS300SetupRect(width, height)
+	SiS300SetupSRCXY(src_x, src_y)
+	SiS300SetupDSTXY(dst_x, dst_y)
+	SiS300DoCMD
+}
+
+static void
+SiS300SetupForSolidFill(int color, int rop, unsigned int planemask)
+{
+	SiS300SetupPATFG(color)
+	SiS300SetupDSTRect(ivideo.video_linelength, -1)
+	SiS300SetupDSTColorDepth(ivideo.DstColor);
+	SiS300SetupROP(sisPatALUConv[rop])
+	SiS300SetupCMDFlag(PATFG)
+}
+
+static void
+SiS300SubsequentSolidFillRect(int x, int y, int w, int h)
+{
+	long dstbase;
+
+	dstbase = 0;
+	if(y >= 2048) {
+		dstbase = ivideo.video_linelength * y;
+		y = 0;
+	}
+	SiS300SetupDSTBase(dstbase)
+	SiS300SetupDSTXY(x,y)
+	SiS300SetupRect(w,h)
+	SiS300SetupCMDFlag(X_INC | Y_INC | BITBLT)
+	SiS300DoCMD
+}
+
+/* 310/325 series ------------------------------------------------ */
+
+static void
+SiS310SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
+                                unsigned int planemask, int trans_color)
+{
+	SiS310SetupDSTColorDepth(ivideo.DstColor);
+	SiS310SetupSRCPitch(ivideo.video_linelength)
+	SiS310SetupDSTRect(ivideo.video_linelength, -1)
+	if (trans_color != -1) {
+		SiS310SetupROP(0x0A)
+		SiS310SetupSRCTrans(trans_color)
+		SiS310SetupCMDFlag(TRANSPARENT_BITBLT)
+	} else {
+	        SiS310SetupROP(sisALUConv[rop])
+		/* Set command - not needed, both 0 */
+		/* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */
+	}
+	SiS310SetupCMDFlag(ivideo.SiS310_AccelDepth)
+	/* TW: The 310/325 series is smart enough to know the direction */
+}
+
+static void
+SiS310SubsequentScreenToScreenCopy(int src_x, int src_y, int dst_x, int dst_y,
+                                int width, int height)
+{
+	long srcbase, dstbase;
+
+	srcbase = dstbase = 0;
+	if (src_y >= 2048) {
+		srcbase = ivideo.video_linelength * src_y;
+		src_y = 0;
+	}
+	if (dst_y >= 2048) {
+		dstbase = ivideo.video_linelength * dst_y;
+		dst_y = 0;
+	}
+
+	SiS310SetupSRCBase(srcbase);
+	SiS310SetupDSTBase(dstbase);
+	SiS310SetupRect(width, height)
+	SiS310SetupSRCXY(src_x, src_y)
+	SiS310SetupDSTXY(dst_x, dst_y)
+	SiS310DoCMD
+}
+
+static void
+SiS310SetupForSolidFill(int color, int rop, unsigned int planemask)
+{
+	SiS310SetupPATFG(color)
+	SiS310SetupDSTRect(ivideo.video_linelength, -1)
+	SiS310SetupDSTColorDepth(ivideo.DstColor);
+	SiS310SetupROP(sisPatALUConv[rop])
+	SiS310SetupCMDFlag(PATFG | ivideo.SiS310_AccelDepth)
+}
+
+static void
+SiS310SubsequentSolidFillRect(int x, int y, int w, int h)
+{
+	long dstbase;
+
+	dstbase = 0;
+	if(y >= 2048) {
+		dstbase = ivideo.video_linelength * y;
+		y = 0;
+	}
+	SiS310SetupDSTBase(dstbase)
+	SiS310SetupDSTXY(x,y)
+	SiS310SetupRect(w,h)
+	SiS310SetupCMDFlag(BITBLT)
+	SiS310DoCMD
+}
+
+/* --------------------------------------------------------------------- */
+
+/* The exported routines */
+
+int sisfb_initaccel(void)
+{
+#ifdef SISFB_USE_SPINLOCKS
+    spin_lock_init(&ivideo.lockaccel);
+#endif
+    return(0);
+}
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)  /* --- KERNEL 2.5.34 and later --- */
+
+void fbcon_sis_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+{
+   CRITFLAGS
+
+   if(!rect->width || !rect->height)
+   	return;
+
+   if(sisvga_engine == SIS_300_VGA) {
+	   CRITBEGIN
+	   SiS300SetupForSolidFill(rect->color, myrops[rect->rop], 0);
+	   SiS300SubsequentSolidFillRect(rect->dx, rect->dy, rect->width, rect->height);
+	   CRITEND
+	   SiS300Sync();
+   } else {
+	   CRITBEGIN
+	   SiS310SetupForSolidFill(rect->color, myrops[rect->rop], 0);
+	   SiS310SubsequentSolidFillRect(rect->dx, rect->dy, rect->width, rect->height);
+	   CRITEND
+	   SiS310Sync();
+   }
+
+}
+
+void fbcon_sis_copyarea(struct fb_info *info, struct fb_copyarea *area)
+{
+   int xdir, ydir;
+   CRITFLAGS
+
+   if(!area->width || !area->height)
+   	return;
+
+   if(area->sx < area->dx) xdir = 0;
+   else                    xdir = 1;
+   if(area->sy < area->dy) ydir = 0;
+   else                    ydir = 1;
+
+   if(sisvga_engine == SIS_300_VGA) {
+      CRITBEGIN
+      SiS300SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
+      SiS300SubsequentScreenToScreenCopy(area->sx, area->sy, area->dx, area->dy, area->width, area->height);
+      CRITEND
+      SiS300Sync();
+   } else {
+      CRITBEGIN
+      SiS310SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
+      SiS310SubsequentScreenToScreenCopy(area->sx, area->sy, area->dx, area->dy, area->width, area->height);
+      CRITEND
+      SiS310Sync();
+   }
+}
+
+#endif
+
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33)  /* ------ KERNEL <2.5.34 ------ */
+
+void fbcon_sis_bmove(struct display *p, int srcy, int srcx,
+			    int dsty, int dstx, int height, int width)
+{
+        int xdir, ydir;
+	CRITFLAGS
+
+	srcx *= fontwidth(p);
+	srcy *= fontheight(p);
+	dstx *= fontwidth(p);
+	dsty *= fontheight(p);
+	width *= fontwidth(p);
+	height *= fontheight(p);
+
+
+	if(srcx < dstx) xdir = 0;
+	else            xdir = 1;
+	if(srcy < dsty) ydir = 0;
+	else            ydir = 1;
+
+	if(sisvga_engine == SIS_300_VGA) {
+	   CRITBEGIN
+	   SiS300SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
+	   SiS300SubsequentScreenToScreenCopy(srcx, srcy, dstx, dsty, width, height);
+	   CRITEND
+	   SiS300Sync();
+	} else {
+	   CRITBEGIN
+	   SiS310SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
+	   SiS310SubsequentScreenToScreenCopy(srcx, srcy, dstx, dsty, width, height);
+	   CRITEND
+	   SiS310Sync();
+	}
+}
+
+
+static void fbcon_sis_clear(struct vc_data *conp, struct display *p,
+			int srcy, int srcx, int height, int width, int color)
+{
+	CRITFLAGS
+
+	srcx *= fontwidth(p);
+	srcy *= fontheight(p);
+	width *= fontwidth(p);
+	height *= fontheight(p);
+
+	if(sisvga_engine == SIS_300_VGA) {
+	   CRITBEGIN
+	   SiS300SetupForSolidFill(color, 3, 0);
+	   SiS300SubsequentSolidFillRect(srcx, srcy, width, height);
+	   CRITEND
+	   SiS300Sync();
+	} else {
+	   CRITBEGIN
+	   SiS310SetupForSolidFill(color, 3, 0);
+	   SiS310SubsequentSolidFillRect(srcx, srcy, width, height);
+	   CRITEND
+	   SiS310Sync();
+	}
+}
+
+void fbcon_sis_clear8(struct vc_data *conp, struct display *p,
+			int srcy, int srcx, int height, int width)
+{
+	u32 bgx;
+
+	bgx = attr_bgcol_ec(p, conp);
+	fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
+}
+
+void fbcon_sis_clear16(struct vc_data *conp, struct display *p,
+			int srcy, int srcx, int height, int width)
+{
+	u32 bgx;
+
+	bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
+	fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
+}
+
+void fbcon_sis_clear32(struct vc_data *conp, struct display *p,
+			int srcy, int srcx, int height, int width)
+{
+	u32 bgx;
+
+	bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
+	fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
+}
+
+void fbcon_sis_revc(struct display *p, int srcx, int srcy)
+{
+	CRITFLAGS
+
+	srcx *= fontwidth(p);
+	srcy *= fontheight(p);
+
+	if(sisvga_engine == SIS_300_VGA) {
+	   CRITBEGIN
+	   SiS300SetupForSolidFill(0, 0x0a, 0);
+	   SiS300SubsequentSolidFillRect(srcx, srcy, fontwidth(p), fontheight(p));
+	   CRITEND
+	   SiS300Sync();
+	} else {
+	   CRITBEGIN
+	   SiS310SetupForSolidFill(0, 0x0a, 0);
+	   SiS310SubsequentSolidFillRect(srcx, srcy, fontwidth(p), fontheight(p));
+	   CRITEND
+	   SiS310Sync();
+	}
+}
+
+#ifdef FBCON_HAS_CFB8
+struct display_switch fbcon_sis8 = {
+	setup:			fbcon_cfb8_setup,
+	bmove:			fbcon_sis_bmove,
+	clear:			fbcon_sis_clear8,
+	putc:			fbcon_cfb8_putc,
+	putcs:			fbcon_cfb8_putcs,
+	revc:			fbcon_cfb8_revc,
+	clear_margins:		fbcon_cfb8_clear_margins,
+	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
+#ifdef FBCON_HAS_CFB16
+struct display_switch fbcon_sis16 = {
+	setup:			fbcon_cfb16_setup,
+	bmove:			fbcon_sis_bmove,
+	clear:			fbcon_sis_clear16,
+	putc:			fbcon_cfb16_putc,
+	putcs:			fbcon_cfb16_putcs,
+	revc:			fbcon_sis_revc,
+	clear_margins:		fbcon_cfb16_clear_margins,
+	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
+#ifdef FBCON_HAS_CFB32
+struct display_switch fbcon_sis32 = {
+	setup:			fbcon_cfb32_setup,
+	bmove:			fbcon_sis_bmove,
+	clear:			fbcon_sis_clear32,
+	putc:			fbcon_cfb32_putc,
+	putcs:			fbcon_cfb32_putcs,
+	revc:			fbcon_sis_revc,
+	clear_margins:		fbcon_cfb32_clear_margins,
+	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
+
+#endif /* KERNEL VERSION */
+
+
diff -Nru a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
--- a/drivers/video/sis/sis_main.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/video/sis/sis_main.c	Mon Dec  9 18:46:50 2002
@@ -3391,7 +3391,7 @@
 			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,
+	       		minor(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);
diff -Nru a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
--- a/drivers/video/skeletonfb.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/video/skeletonfb.c	Mon Dec  9 18:46:35 2002
@@ -125,9 +125,6 @@
      */
 static struct xxx_par __initdata current_par;
 
-    /* To go away in the near future */ 
-static struct display disp;
-
 int xxxfb_init(void);
 int xxxfb_setup(char*);
 
@@ -287,6 +284,12 @@
 }
 
 /**
+ *	xxxfb_cursor -
+ *
+ *	Returns negative errno on error, or zero on success.
+ */
+
+/**
  *      xxxfb_pan_display - NOT a required function. Pans the display.
  *      @var: frame buffer variable screen structure
  *      @info: frame buffer structure that represents a single frame buffer
@@ -298,7 +301,7 @@
  *      Returns negative errno on error, or zero on success.
  *
  */
-static int xxxfb_pan_display(struct fb_var_screeninfo *var, int con,
+static int xxxfb_pan_display(struct fb_var_screeninfo *var,
 			     const struct fb_info *info)
 {
     /* ... */
@@ -421,15 +424,6 @@
     info.flags = FBINFO_FLAG_DEFAULT;
     info.par = current_par;
 
-    /* The following has to be set but in th efuture will go away */
-    strcpy(info.modename, xxxfb_fix.id);
-    info.changevar = NULL;
-    info.currcon = -1;
-    info.disp = &disp; 			
-    info.switch_con = gen_switch;
-    info.updatevar = gen_update_var;
-    
-
     /*
      * This should give a reasonable default video mode. The following is
      * done when we can set a video mode. 
@@ -450,11 +444,10 @@
      * mode. If we are setting the mode ourselves we don't call this. 
      */	
     info.var = xxxfb_var;
-    gen_set_disp(-1, &fb_info);
 	
     if (register_framebuffer(&info) < 0)
 	return -EINVAL;
-    printk(KERN_INFO "fb%d: %s frame buffer device\n", GET_FB_IDX(info.node),
+    printk(KERN_INFO "fb%d: %s frame buffer device\n", minor(info.node),
 	   info.fix.id);
     return 0;
 }
@@ -510,11 +503,6 @@
 	.owner		= THIS_MODULE,
 	.fb_open	= xxxfb_open,    /* only if you need it to do something */
 	.fb_release	= xxxfb_release, /* only if you need it to do something */
-	/* Stuff to go away. Use generic functions for now */
-	.fb_set_var	= gen_set_var,	
-	.fb_get_cmap	= gen_get_cmap,
-	.fb_set_cmap	= gen_set_cmap,
-
 	.fb_check_var	= xxxfb_check_var,
 	.fb_set_par	= xxxfb_set_par,	/* optional */	
 	.fb_setcolreg	= xxxfb_setcolreg,
diff -Nru a/drivers/video/softcursor.c b/drivers/video/softcursor.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/softcursor.c	Mon Dec  9 18:46:37 2002
@@ -0,0 +1,62 @@
+/*
+ * linux/drivers/video/softcursor.c -- Generic software cursor for frame buffer devices
+ *
+ *  Created 14 Nov 2002 by James Simmons 
+ *
+ * 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/string.h>
+#include <linux/tty.h>
+#include <linux/fb.h>
+#include <linux/slab.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+	int i, size = ((cursor->image.width + 7) / 8) * cursor->image.height;
+	struct fb_image image;
+	static char data[64];
+
+	if (cursor->enable) {
+		switch (cursor->rop) {
+		case ROP_XOR:
+			for (i = 0; i < size; i++)
+				data[i] = (cursor->image.data[i] &
+					   cursor->mask[i]) ^
+				    	   cursor->dest[i];
+			break;
+		case ROP_COPY:
+		default:
+			for (i = 0; i < size; i++)
+				data[i] =
+				    cursor->image.data[i] & cursor->mask[i];
+			break;
+		}
+	} else
+		memcpy(data, cursor->dest, size);
+
+	image.bg_color = cursor->image.bg_color;
+	image.fg_color = cursor->image.fg_color;
+	image.dx = cursor->image.dx;
+	image.dy = cursor->image.dy;
+	image.width = cursor->image.width;
+	image.height = cursor->image.height;
+	image.depth = cursor->image.depth;
+	image.data = data;
+
+	if (info->fbops->fb_imageblit)
+		info->fbops->fb_imageblit(info, &image);
+	return 0;
+}
+
+EXPORT_SYMBOL(soft_cursor);
+
+MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
+MODULE_DESCRIPTION("Generic software cursor");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/sstfb.c b/drivers/video/sstfb.c
--- a/drivers/video/sstfb.c	Mon Dec  9 18:46:49 2002
+++ b/drivers/video/sstfb.c	Mon Dec  9 18:46:49 2002
@@ -1906,7 +1906,7 @@
 		goto fail;
 	}
 	printk(KERN_INFO "fb%d: %s frame buffer device\n",
-	       GET_FB_IDX(sst_info->info.node),sst_info->info.modename);
+	       minor(sst_info->info.node),sst_info->info.modename);
 	return 0;
 
 fail:
diff -Nru a/drivers/video/sti-bmode.h b/drivers/video/sti-bmode.h
--- a/drivers/video/sti-bmode.h	Mon Dec  9 18:46:52 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,287 +0,0 @@
-#define STI_REGION_MAX 8
-#define STI_DEV_NAME_LENGTH 32
-
-typedef struct {
-	 u8 res[3];
-	 u8 data;
-} __attribute__((packed)) sti_u8;
-
-typedef struct {
-	sti_u8 data[2];
-} __attribute__((packed)) sti_u16;
-
-typedef struct {
-	sti_u8 data[4];
-} __attribute__((packed)) sti_u32;
-
-#define  STI_U8( u8) ((u8).data)
-#define STI_U16(u16) ((STI_U8((u16).data[0])<<8) | STI_U8((u16).data[1]))
-#define STI_U32(u32) ((STI_U8((u32).data[0])<<24) | \
-		      (STI_U8((u32).data[1])<<16) | \
-		      (STI_U8((u32).data[2])<< 8) | \
-		      (STI_U8((u32).data[3])<< 0))
-
-struct sti_rom_region {
-	sti_u32 region;
-};
-
-struct sti_rom_font {
-	sti_u16 first_char;
-	sti_u16 last_char;
-	 sti_u8 width;
-	 sti_u8 height;
-	 sti_u8 font_type;
-	 sti_u8 bytes_per_char;
-	sti_u32 next_font;
-	 sti_u8 underline_height;
-	 sti_u8 underline_pos;
-	 sti_u8 res008[2];
-};
-
-struct sti_rom {
-	 sti_u8 type;
-	 sti_u8 num_mons;
-	 sti_u8 revno[2];
-
-	 sti_u8 graphics_id[8];			/* 0x010 */
-
-	sti_u32 font_start;			/* 0x030 */
-	sti_u32 statesize;
-	sti_u32 last_addr;
-	sti_u32 region_list;
-
-	sti_u16 reentsize;			/* 0x070 */
-	sti_u16 maxtime;
-	sti_u32 mon_tbl_addr;
-	sti_u32 user_data_addr;
-	sti_u32 sti_mem_req;
-
-	sti_u32 user_data_size;			/* 0x0b0 */
-	sti_u16 power;				/* 0x0c0 */
-	 sti_u8 bus_support;
-	 sti_u8 ext_bus_support;
-	 sti_u8 alt_code_type;			/* 0x0d0 */
-	 sti_u8 ext_dd_struct[3];
-	sti_u32 cfb_addr;			/* 0x0e0 */
-	
-	 sti_u8 res0f0[4];			
-
-	sti_u32 init_graph;		/* 0x0e0 */
-	sti_u32 state_mgmt;
-	sti_u32 font_unpmv;
-	sti_u32 block_move;
-	sti_u32 self_test;
-	sti_u32 excep_hdlr;
-	sti_u32 inq_conf;
-	sti_u32 set_cm_entry;
-	sti_u32 dma_ctrl;
-	sti_u32 flow_ctrl;
-	sti_u32 user_timing;
-	sti_u32 process_mgr;
-	sti_u32 sti_util;
-	sti_u32 end_addr;
-	sti_u32 res0b8;
-	sti_u32 res0bc;
-
-	sti_u32 init_graph_m68k;		/* 0x0e0 */
-	sti_u32 state_mgmt_m68k;
-	sti_u32 font_unpmv_m68k;
-	sti_u32 block_move_m68k;
-	sti_u32 self_test_m68k;
-	sti_u32 excep_hdlr_m68k;
-	sti_u32 inq_conf_m68k;
-	sti_u32 set_cm_entry_m68k;
-	sti_u32 dma_ctrl_m68k;
-	sti_u32 flow_ctrl_m68k;
-	sti_u32 user_timing_m68k;
-	sti_u32 process_mgr_m68k;
-	sti_u32 sti_util_m68k;
-	sti_u32 end_addr_m68k;
-	sti_u32 res0b8_m68k;
-	sti_u32 res0bc_m68k;
-
-	 sti_u8 res040[7 * 4];
-};
-	
-struct sti_cooked_font {
-	struct sti_rom_font *raw;
-	struct sti_cooked_font *next_font;
-};
-
-struct sti_cooked_rom {
-	struct sti_rom *raw;
-	struct sti_cooked_font *font_start;
-	u32 *region_list;
-};
-
-struct sti_glob_cfg_ext {
-	 u8 curr_mon;
-	 u8 friendly_boot;
-	s16 power;
-	s32 freq_ref;
-	s32 *sti_mem_addr;
-	s32 *future_ptr;
-};
-
-struct sti_glob_cfg {
-	s32 text_planes;
-	s16 onscreen_x;
-	s16 onscreen_y;
-	s16 offscreen_x;
-	s16 offscreen_y;
-	s16 total_x;
-	s16 total_y;
-	u32 region_ptrs[STI_REGION_MAX];
-	s32 reent_lvl;
-	s32 *save_addr;
-	struct sti_glob_cfg_ext *ext_ptr;
-};
-
-struct sti_init_flags {
-	u32 wait : 1;
-	u32 reset : 1;
-	u32 text : 1;
-	u32 nontext : 1;
-	u32 clear : 1;
-	u32 cmap_blk : 1;
-	u32 enable_be_timer : 1;
-	u32 enable_be_int : 1;
-	u32 no_chg_tx : 1;
-	u32 no_chg_ntx : 1;
-	u32 no_chg_bet : 1;
-	u32 no_chg_bei : 1;
-	u32 init_cmap_tx : 1;
-	u32 cmt_chg : 1;
-	u32 retain_ie : 1;
-	u32 pad : 17;
-
-	s32 *future_ptr;
-};
-
-struct sti_init_inptr_ext {
-	u8  config_mon_type;
-	u8  pad[1];
-	u16 inflight_data;
-	s32 *future_ptr;
-};
-
-struct sti_init_inptr {
-	s32 text_planes;
-	struct sti_init_inptr_ext *ext_ptr;
-};
-
-struct sti_init_outptr {
-	s32 errno;
-	s32 text_planes;
-	s32 *future_ptr;
-};
-
-struct sti_conf_flags {
-	u32 wait : 1;
-	u32 pad : 31;
-	s32 *future_ptr;
-};
-
-struct sti_conf_inptr {
-	s32 *future_ptr;
-};
-
-struct sti_conf_outptr_ext {
-	u32 crt_config[3];
-	u32 crt_hdw[3];
-	s32 *future_ptr;
-};
-
-struct sti_conf_outptr {
-	s32 errno;
-	s16 onscreen_x;
-	s16 onscreen_y;
-	s16 offscreen_x;
-	s16 offscreen_y;
-	s16 total_x;
-	s16 total_y;
-	s32 bits_per_pixel;
-	s32 bits_used;
-	s32 planes;
-	 u8 dev_name[STI_DEV_NAME_LENGTH];
-	u32 attributes;
-	struct sti_conf_outptr_ext *ext_ptr;
-};
-
-
-struct sti_font_inptr {
-	u32 font_start_addr;
-	s16 index;
-	u8 fg_color;
-	u8 bg_color;
-	s16 dest_x;
-	s16 dest_y;
-	s32 *future_ptr;
-};
-
-struct sti_font_flags {
-	u32 wait : 1;
-	u32 non_text : 1;
-	u32 pad : 30;
-
-	s32 *future_ptr;
-};
-	
-struct sti_font_outptr {
-	s32 errno;
-	s32 *future_ptr;
-};
-
-struct sti_blkmv_flags {
-	u32 wait : 1;
-	u32 color : 1;
-	u32 clear : 1;
-	u32 non_text : 1;
-	u32 pad : 28;
-	s32 *future_ptr;
-};
-
-struct sti_blkmv_inptr {
-	u8 fg_color;
-	u8 bg_color;
-	s16 src_x;
-	s16 src_y;
-	s16 dest_x;
-	s16 dest_y;
-	s16 width;
-	s16 height;
-	s32 *future_ptr;
-};
-
-struct sti_blkmv_outptr {
-	s32 errno;
-	s32 *future_ptr;
-};
-
-struct sti_struct {
-	spinlock_t lock;
-
-	struct sti_cooked_rom *rom;
-
-	unsigned long font_unpmv;
-	unsigned long block_move;
-	unsigned long init_graph;
-	unsigned long inq_conf;
-
-	struct sti_glob_cfg *glob_cfg;
-	struct sti_rom_font *font;
-
-	s32 text_planes;
-
-	char **mon_strings;
-	u32 *regions;
-	 u8 *pci_regions;
-};
-
-#define STI_CALL(func, flags, inptr, outptr, glob_cfg) \
-	({	 						\
-		real32_call( func, (unsigned long)STI_PTR(flags), \
-				    STI_PTR(inptr), STI_PTR(outptr), \
-				    glob_cfg); \
-	})
-
diff -Nru a/drivers/video/sti.h b/drivers/video/sti.h
--- a/drivers/video/sti.h	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,289 +0,0 @@
-#define STI_REGION_MAX 8
-#define STI_DEV_NAME_LENGTH 32
-
-struct sti_rom_font {
-	u16 first_char;
-	u16 last_char;
-	 u8 width;
-	 u8 height;
-	 u8 font_type;
-	 u8 bytes_per_char;
-	u32 next_font;
-	 u8 underline_height;
-	 u8 underline_pos;
-	 u8 res008[2];
-};
-
-struct sti_rom {
-	 u8 type[4];
-	 u8 res004;
-	 u8 num_mons;
-	 u8 revno[2];
-	 u8 graphics_id[8];
-
-	u32 font_start;
-	u32 statesize;
-	u32 last_addr;
-	u32 region_list;
-
-	u16 reentsize;
-	u16 maxtime;
-	u32 mon_tbl_addr;
-	u32 user_data_addr;
-	u32 sti_mem_req;
-
-	u32 user_data_size;
-	u16 power;
-	 u8 bus_support;
-	 u8 ext_bus_support;
-	 u8 alt_code_type;
-	 u8 ext_dd_struct[3];
-	u32 cfb_addr;
-	
-	u32 init_graph;
-	u32 state_mgmt;
-	u32 font_unpmv;
-	u32 block_move;
-	u32 self_test;
-	u32 excep_hdlr;
-	u32 inq_conf;
-	u32 set_cm_entry;
-	u32 dma_ctrl;
-	 u8 res040[7 * 4];
-	
-	u32 init_graph_m68k;
-	u32 flow_ctrl;
-	u32 user_timing;
-	u32 process_mgr;
-	u32 sti_util;
-	u32 end_addr;
-	u32 res0b8;
-	u32 res0bc;
-};
-	
-struct sti_cooked_font {
-	struct sti_rom_font *raw;
-	struct sti_cooked_font *next_font;
-};
-
-struct sti_cooked_rom {
-	struct sti_rom *raw;
-	struct sti_cooked_font *font_start;
-	u32 *region_list;
-};
-
-struct sti_glob_cfg_ext {
-	u8  curr_mon;
-	u8  friendly_boot;
-	s16 power;
-	s32 freq_ref;
-	s32 *sti_mem_addr;
-	s32 *future_ptr;
-};
-
-struct sti_glob_cfg {
-	s32 text_planes;
-	s16 onscreen_x;
-	s16 onscreen_y;
-	s16 offscreen_x;
-	s16 offscreen_y;
-	s16 total_x;
-	s16 total_y;
-	u32 region_ptrs[STI_REGION_MAX];
-	s32 reent_lvl;
-	s32 *save_addr;
-	struct sti_glob_cfg_ext *ext_ptr;
-};
-
-struct sti_init_flags {
-	u32 wait : 1;
-	u32 reset : 1;
-	u32 text : 1;
-	u32 nontext : 1;
-	u32 clear : 1;
-	u32 cmap_blk : 1;
-	u32 enable_be_timer : 1;
-	u32 enable_be_int : 1;
-	u32 no_chg_tx : 1;
-	u32 no_chg_ntx : 1;
-	u32 no_chg_bet : 1;
-	u32 no_chg_bei : 1;
-	u32 init_cmap_tx : 1;
-	u32 cmt_chg : 1;
-	u32 retain_ie : 1;
-	u32 pad : 17;
-
-	s32 *future_ptr;
-};
-
-struct sti_init_inptr_ext {
-	u8  config_mon_type;
-	u8  pad[1];
-	u16 inflight_data;
-	s32 *future_ptr;
-};
-
-struct sti_init_inptr {
-	s32 text_planes;
-	struct sti_init_inptr_ext *ext_ptr;
-};
-
-struct sti_init_outptr {
-	s32 errno;
-	s32 text_planes;
-	s32 *future_ptr;
-};
-
-struct sti_conf_flags {
-	u32 wait : 1;
-	u32 pad : 31;
-	s32 *future_ptr;
-};
-
-struct sti_conf_inptr {
-	s32 *future_ptr;
-};
-
-struct sti_conf_outptr_ext {
-	u32 crt_config[3];
-	u32 crt_hdw[3];
-	s32 *future_ptr;
-};
-
-struct sti_conf_outptr {
-	s32 errno;
-	s16 onscreen_x;
-	s16 onscreen_y;
-	s16 offscreen_x;
-	s16 offscreen_y;
-	s16 total_x;
-	s16 total_y;
-	s32 bits_per_pixel;
-	s32 bits_used;
-	s32 planes;
-	 u8 dev_name[STI_DEV_NAME_LENGTH];
-	u32 attributes;
-	struct sti_conf_outptr_ext *ext_ptr;
-};
-
-
-struct sti_font_inptr {
-	u32 font_start_addr;
-	s16 index;
-	u8 fg_color;
-	u8 bg_color;
-	s16 dest_x;
-	s16 dest_y;
-	s32 *future_ptr;
-};
-
-struct sti_font_flags {
-	u32 wait : 1;
-	u32 non_text : 1;
-	u32 pad : 30;
-
-	s32 *future_ptr;
-};
-	
-struct sti_font_outptr {
-	s32 errno;
-	s32 *future_ptr;
-};
-
-struct sti_blkmv_flags {
-	u32 wait : 1;
-	u32 color : 1;
-	u32 clear : 1;
-	u32 non_text : 1;
-	u32 pad : 28;
-	s32 *future_ptr;
-};
-
-struct sti_blkmv_inptr {
-	u8 fg_color;
-	u8 bg_color;
-	s16 src_x;
-	s16 src_y;
-	s16 dest_x;
-	s16 dest_y;
-	s16 width;
-	s16 height;
-	s32 *future_ptr;
-};
-
-struct sti_blkmv_outptr {
-	s32 errno;
-	s32 *future_ptr;
-};
-
-struct sti_struct {
-	spinlock_t lock;
-
-	struct sti_cooked_rom *rom;
-
-	unsigned long font_unpmv;
-	unsigned long block_move;
-	unsigned long init_graph;
-	unsigned long inq_conf;
-
-	struct sti_glob_cfg *glob_cfg;
-	struct sti_rom_font *font;
-
-	s32 text_planes;
-
-	char **mon_strings;
-	u32 *regions;
-	 u8 *pci_regions;
-};
-
-#define STI_CALL(func, flags, inptr, outptr, glob_cfg) \
-	({							\
-		real32_call( func, (unsigned long)STI_PTR(flags), \
-				    STI_PTR(inptr), STI_PTR(outptr), \
-				    glob_cfg); \
-	})
-
-/* The latency of the STI functions cannot really be reduced by setting
- * this to 0;  STI doesn't seem to be designed to allow calling a different
- * function (or the same function with different arguments) after a
- * function exited with 1 as return value.
- *
- * As all of the functions below could be called from interrupt context,
- * we have to spin_lock_irqsave around the do { ret = bla(); } while(ret==1)
- * block.  Really bad latency there.
- *
- * Probably the best solution to all this is have the generic code manage
- * the screen buffer and a kernel thread to call STI occasionally.
- * 
- * Luckily, the frame buffer guys have the same problem so we can just wait
- * for them to fix it and steal their solution.   prumpf
- *
- * Actually, another long-term viable solution is to completely do STI
- * support in userspace - that way we avoid the potential license issues
- * of using proprietary fonts, too. */
- 
-#define STI_WAIT 1
-#define STI_PTR(p) ( (typeof(p)) virt_to_phys(p))
-#define PTR_STI(p) ( (typeof(p)) phys_to_virt((unsigned long)p) )
-
-#define sti_onscreen_x(sti) (PTR_STI(sti->glob_cfg)->onscreen_x)
-#define sti_onscreen_y(sti) (PTR_STI(sti->glob_cfg)->onscreen_y)
-#define sti_font_x(sti) (PTR_STI(sti->font)->width)
-#define sti_font_y(sti) (PTR_STI(sti->font)->height)
-
-extern struct sti_struct * sti_init_roms(void);
-
-void sti_init_graph(struct sti_struct *sti);
-void sti_inq_conf(struct sti_struct *sti);
-void sti_putc(struct sti_struct *sti, int c, int y, int x);
-void sti_set(struct sti_struct *sti, int src_y, int src_x,
-	     int height, int width, u8 color);
-void sti_clear(struct sti_struct *sti, int src_y, int src_x,
-	       int height, int width);
-void sti_bmove(struct sti_struct *sti, int src_y, int src_x,
-	       int dst_y, int dst_x, int height, int width);
-
-/* XXX: this probably should not be here, but we rely on STI being
-   initialized early and independently of stifb at the moment, so
-   there's no other way for stifb to find it. */
-extern struct sti_struct default_sti;
diff -Nru a/drivers/video/sticon-bmode.c b/drivers/video/sticon-bmode.c
--- a/drivers/video/sticon-bmode.c	Mon Dec  9 18:46:51 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,895 +0,0 @@
-/*
-TPG CVS users: please don't commit changes to this file directly, send
-them to prumpf@tux.org and wait for a new version instead.  Otherwise,
-your changes will get lost when prumpf releases the next version, as
-this file *will* be replaced with it.  You have been warned.
-
-2000-05-30, <deller@gmx.de>
-*/
-#if 1
-#define DPRINTK(x)	printk x
-#else
-#define DPRINTK(x)
-#endif
-
-/*
- *  linux/drivers/video/sticon.c  - console driver using HP's STI firmware
- *
- *	Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
- *
- *  Based on linux/drivers/video/vgacon.c and linux/drivers/video/fbcon.c,
- *  which were
- *
- *	Created 28 Sep 1997 by Geert Uytterhoeven
- *	Rewritten by Martin Mares <mj@ucw.cz>, July 1998
- *	Copyright (C) 1991, 1992  Linus Torvalds
- *			    1995  Jay Estabrook
- *	Copyright (C) 1995 Geert Uytterhoeven
- *	Copyright (C) 1993 Bjoern Brauel
- *			   Roman Hodek
- *	Copyright (C) 1993 Hamish Macdonald
- *			   Greg Harp
- *	Copyright (C) 1994 David Carter [carter@compsci.bristol.ac.uk]
- *
- *	      with work by William Rucklidge (wjr@cs.cornell.edu)
- *			   Geert Uytterhoeven
- *			   Jes Sorensen (jds@kom.auc.dk)
- *			   Martin Apel
- *	      with work by Guenther Kelleter
- *			   Martin Schaller
- *			   Andreas Schwab
- *			   Emmanuel Marty (core@ggi-project.org)
- *			   Jakub Jelinek (jj@ultra.linux.cz)
- *			   Martin Mares <mj@ucw.cz>
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive for
- *  more details.
- */
-/*
- *  TODO:
- *   - call STI in virtual mode rather than in real mode
- *   - support for PCI-only STI ROMs (which don't have a traditional region
- *     list)
- *   - safe detection (i.e. verify there is a graphics device at a given
- *     address first, not just read a random device's io space)
- *   - support for multiple STI devices in one machine
- *   - support for byte-mode STI ROMs
- *   - support for just using STI to switch to a colour fb (stifb ?)
- *   - try to make it work on m68k hp workstations ;)
- */
-
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/string.h>
-#include <linux/kd.h>
-#include <linux/slab.h>
-#include <linux/vt_kern.h>
-#include <linux/selection.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-
-#include <asm/io.h>
-#include <asm/real.h>
-
-#include <linux/module.h>
-#include <linux/fb.h>
-#include <linux/smp.h>
-
-#include <asm/irq.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-
-#include <video/fbcon.h>
-#include <video/font.h>
-
-#include "sti-bmode.h"
-
-/* The latency of the STI functions cannot really be reduced by setting
- * this to 0;  STI doesn't seem to be designed to allow calling a different
- * function (or the same function with different arguments) after a
- * function exited with 1 as return value.
- *
- * As all of the functions below could be called from interrupt context,
- * we have to spin_lock_irqsave around the do { ret = bla(); } while(ret==1)
- * block.  Really bad latency there.
- *
- * Probably the best solution to all this is have the generic code manage
- * the screen buffer and a kernel thread to call STI occasionally.
- * 
- * Luckily, the frame buffer guys have the same problem so we can just wait
- * for them to fix it and steal their solution.   prumpf
- *
- * Actually, another long-term viable solution is to completely do STI
- * support in userspace - that way we avoid the potential license issues
- * of using proprietary fonts, too. */
- 
-#define STI_WAIT 1
-#define STI_PTR(p) ( (typeof(p)) virt_to_phys(p))
-#define PTR_STI(p) ( (typeof(p)) phys_to_virt((unsigned long)p) )
-
-static struct sti_struct default_sti = {
-	SPIN_LOCK_UNLOCKED,
-};
-
-static struct sti_font_flags default_font_flags = {
-	STI_WAIT, 0, 0, NULL
-};
-
-/* The colour indices used by STI are
- *   0 - Black
- *   1 - White
- *   2 - Red
- *   3 - Yellow/Brown
- *   4 - Green
- *   5 - Cyan
- *   6 - Blue
- *   7 - Magenta
- *
- * So we have the same colours as VGA (basically one bit each for R, G, B),
- * but have to translate them, anyway. */
-
-static u8 col_trans[8] = {
-        0, 6, 4, 5,
-        2, 7, 3, 1
-};
-
-#define c_fg(sti, c) col_trans[((c>> 8) & 7)]
-#define c_bg(sti, c) col_trans[((c>>11) & 7)]
-#define c_index(sti, c) (c&0xff)
-
-#define sti_onscreen_x(sti) (PTR_STI(sti->glob_cfg)->onscreen_x)
-#define sti_onscreen_y(sti) (PTR_STI(sti->glob_cfg)->onscreen_y)
-#define sti_font_x(sti) (STI_U8(PTR_STI(sti->font)->width))
-#define sti_font_y(sti) (STI_U8(PTR_STI(sti->font)->height))
-
-static struct sti_init_flags default_init_flags = {
-	STI_WAIT, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, NULL
-};
-
-static void sti_init_graph(struct sti_struct *sti) 
-{
-	struct sti_init_inptr_ext inptr_ext = {
-		0, { 0 }, 0, NULL
-	};
-	struct sti_init_inptr inptr = {
-		3, STI_PTR(&inptr_ext)
-	};
-	struct sti_init_outptr outptr = { 0 };
-	unsigned long flags;
-	s32 ret;
-
-	spin_lock_irqsave(&sti->lock, flags);
-
-	ret = STI_CALL(sti->init_graph, &default_init_flags, &inptr,
-		&outptr, sti->glob_cfg);
-
-	spin_unlock_irqrestore(&sti->lock, flags);
-
-	sti->text_planes = outptr.text_planes;
-}
-
-#if 0
-static struct sti_conf_flags default_conf_flags = {
-	STI_WAIT, 0, NULL
-};
-
-static void sti_inq_conf(struct sti_struct *sti)
-{
-	struct sti_conf_inptr inptr = { NULL };
-	struct sti_conf_outptr_ext outptr_ext = { .future_ptr = NULL };
-	struct sti_conf_outptr outptr = {
-		.ext_ptr = STI_PTR(&outptr_ext)
-	};
-	unsigned long flags;
-	s32 ret;
-	
-	do {
-		spin_lock_irqsave(&sti->lock, flags);
-		ret = STI_CALL(sti->inq_conf, &default_conf_flags,
-			&inptr, &outptr, sti->glob_cfg);
-		spin_unlock_irqrestore(&sti->lock, flags);
-	} while(ret == 1);
-}
-#endif
-
-static void sti_putc(struct sti_struct *sti, int c, int y, int x)
-{
-	struct sti_font_inptr inptr = {
-		(u32) sti->font, c_index(sti, c), c_fg(sti, c), c_bg(sti, c),
-		x * sti_font_x(sti), y * sti_font_y(sti), NULL
-	};
-	struct sti_font_outptr outptr = {
-		0, NULL
-	};
-	s32 ret;
-	unsigned long flags;
-
-	do {
-		spin_lock_irqsave(&sti->lock, flags);
-		ret = STI_CALL(sti->font_unpmv, &default_font_flags,
-			&inptr, &outptr, sti->glob_cfg);
-		spin_unlock_irqrestore(&sti->lock, flags);
-	} while(ret == 1);
-}
-
-static struct sti_blkmv_flags clear_blkmv_flags = {
-	STI_WAIT, 1, 1, 0, 0, NULL
-};
-
-static void sti_set(struct sti_struct *sti, int src_y, int src_x,
-	int height, int width, u8 color)
-{
-	struct sti_blkmv_inptr inptr = {
-		color, color,
-		src_x, src_y ,
-		src_x, src_y ,
-		width, height,
-		NULL
-	};
-	struct sti_blkmv_outptr outptr = { 0, NULL };
-	s32 ret = 0;
-	unsigned long flags;
-	
-	do {
-		spin_lock_irqsave(&sti->lock, flags);
-		ret = STI_CALL(sti->block_move, &clear_blkmv_flags,
-			&inptr, &outptr, sti->glob_cfg);
-		spin_unlock_irqrestore(&sti->lock, flags);
-	} while(ret == 1);
-}
-
-static void sti_clear(struct sti_struct *sti, int src_y, int src_x,
-	int height, int width)
-{
-	struct sti_blkmv_inptr inptr = {
-		0, 0,
-		src_x * sti_font_x(sti), src_y * sti_font_y(sti),
-		src_x * sti_font_x(sti), src_y * sti_font_y(sti),
-		width * sti_font_x(sti), height* sti_font_y(sti),
-		NULL
-	};
-	struct sti_blkmv_outptr outptr = { 0, NULL };
-	s32 ret = 0;
-	unsigned long flags;
-
-	do {
-		spin_lock_irqsave(&sti->lock, flags);
-		ret = STI_CALL(sti->block_move, &clear_blkmv_flags,
-			&inptr, &outptr, sti->glob_cfg);
-		spin_unlock_irqrestore(&sti->lock, flags);
-	} while(ret == 1);
-}
-
-static struct sti_blkmv_flags default_blkmv_flags = {
-	STI_WAIT, 0, 0, 0, 0, NULL
-};
-
-static void sti_bmove(struct sti_struct *sti, int src_y, int src_x,
-	int dst_y, int dst_x, int height, int width)
-{
-	struct sti_blkmv_inptr inptr = {
-		0, 0,
-		src_x * sti_font_x(sti), src_y * sti_font_y(sti),
-		dst_x * sti_font_x(sti), dst_y * sti_font_y(sti),
-		width * sti_font_x(sti), height* sti_font_y(sti),
-		NULL
-	};
-	struct sti_blkmv_outptr outptr = { 0, NULL };
-	s32 ret = 0;
-	unsigned long flags;
-
-	do {
-		spin_lock_irqsave(&sti->lock, flags);
-		ret = STI_CALL(sti->block_move, &default_blkmv_flags,
-			&inptr, &outptr, sti->glob_cfg);
-		spin_unlock_irqrestore(&sti->lock, flags);
-	} while(ret == 1);
-}
-
-
-/* STICON */
-
-static const char __init *sticon_startup(void)
-{
-	return "STI console";
-}
-
-static int sticon_set_palette(struct vc_data *c, unsigned char *table)
-{
-	return -EINVAL;
-}
-static int sticon_font_op(struct vc_data *c, struct console_font_op *op)
-{
-	return -ENOSYS;
-}
-
-static void sticon_putc(struct vc_data *conp, int c, int ypos, int xpos)
-{
-	sti_putc(&default_sti, c, ypos, xpos);
-}
-
-static void sticon_putcs(struct vc_data *conp, const unsigned short *s,
-	int count, int ypos, int xpos)
-{
-	while(count--) {
-		sti_putc(&default_sti, scr_readw(s++), ypos, xpos++);
-	}
-}
-
-static void sticon_cursor(struct vc_data *conp, int mode)
-{
-}
-
-static int sticon_scroll(struct vc_data *conp, int t, int b, int dir,
-			int count)
-{
-	struct sti_struct *sti = &default_sti;
-
-	if(console_blanked)
-		return 0;
-
-	sticon_cursor(conp, CM_ERASE);
-
-	switch(dir) {
-	case SM_UP:
-		sti_bmove(sti, t+count, 0, t, 0, b-t-count, conp->vc_cols);
-		sti_clear(sti, b-count, 0, count, conp->vc_cols);
-
-		break;
-
-	case SM_DOWN:
-		sti_bmove(sti, t, 0, t+count, 0, b-t-count, conp->vc_cols);
-		sti_clear(sti, t, 0, count, conp->vc_cols);
-
-		break;
-	}
-
-	return 0;
-}
-	
-static void sticon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
-	int height, int width)
-{
-	sti_bmove(&default_sti, sy, sx, dy, dx, height, width);
-}
-
-static void sticon_init(struct vc_data *c, int init)
-{
-	struct sti_struct *sti = &default_sti;
-	int vc_cols, vc_rows;
-
-	sti_set(sti, 0, 0, sti_onscreen_y(sti), sti_onscreen_x(sti), 0);
-	c->vc_can_do_color = 1;
-	vc_cols = PTR_STI(sti->glob_cfg)->onscreen_x / sti_font_x(sti);
-	vc_rows = PTR_STI(sti->glob_cfg)->onscreen_y / sti_font_y(sti);
-
-	vc_resize_con(vc_rows, vc_cols, c->vc_num);
-}
-
-static void sticon_deinit(struct vc_data *c)
-{
-}
-
-static void sticon_clear(struct vc_data *conp, int sy, int sx, int height,
-			int width)
-{
-	sti_clear(&default_sti, sy, sx, height, width);
-}
-
-static int sticon_switch(struct vc_data *conp)
-{
-	return 0;
-}
-
-static int sticon_blank(struct vc_data *conp, int blank)
-{
-	return 0;
-}
-
-static int sticon_scrolldelta(struct vc_data *conp, int lines)
-{
-	return 0;
-}
-
-static int sticon_set_origin(struct vc_data *conp)
-{
-	return 0;
-}
-
-static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens, u8 blink, u8 underline, u8 reverse)
-{
-	u8 attr = ((color & 0x70) >> 1) | ((color & 7));
-
-	if(reverse) {
-		color = ((color>>3)&0x7) | ((color &0x7)<<3);
-	}
-
-
-	return attr;
-}
-
-static struct consw sti_con = {
-	.con_startup = 		sticon_startup, 
-	.con_init = 		sticon_init,
-	.con_deinit = 		sticon_deinit,
-	.con_clear = 		sticon_clear,
-	.con_putc = 		sticon_putc,
-	.con_putcs = 		sticon_putcs,
-	.con_cursor = 		sticon_cursor,
-	.con_scroll = 		sticon_scroll,
-	.con_bmove = 		sticon_bmove,
-	.con_switch = 		sticon_switch,
-	.con_blank = 		sticon_blank,
-	.con_font_op =		sticon_font_op,
-	.con_set_palette =	sticon_set_palette,
-	.con_scrolldelta =	sticon_scrolldelta,
-	.con_set_origin = 	sticon_set_origin,
-	.con_build_attr =	sticon_build_attr,
-};
-
-#include <asm/pgalloc.h>	/* need cache flush routines */
-static void __init sti_rom_copy(unsigned long base, unsigned long offset,
-				unsigned long count, void *dest)
-{
-	void *savedest = dest;
-	int savecount = count;
-
-	while(count >= 4) {
-		count -= 4;
-		*(u32 *)dest = gsc_readl(base + offset);
-#if 0
-		DPRINTK(("%08x\n", *(u32 *)dest));
-		if(*(u32 *)dest == 0x64646464) {
-		  DPRINTK(("!!!!\n"));
-		  { u32 foo = 0; while(foo += 0x100); }
-		}
-#endif
-		offset += 4;
-		dest += 4;
-	}
-	while(count) {
-		count--;
-		*(u8 *)dest = gsc_readb(base + offset);
-		offset++;
-		dest++;
-	}
-
-	flush_kernel_dcache_range((unsigned long)dest, count);
-	flush_icache_range((unsigned long)dest, dest + count);
-}
-
-static void dump_sti_rom(struct sti_rom *rom)
-{
-	printk("STI byte mode ROM type %d\n", STI_U8(rom->type));
-	printk(" supports %d monitors\n", STI_U8(rom->num_mons));
-	printk(" conforms to STI ROM spec revision %d.%02x\n",
-		STI_U8(rom->revno[0]) >> 4, STI_U8(rom->revno[0]) & 0x0f);
-	printk(__FUNCTION__ ": %d\n", __LINE__);
-	printk(" graphics id %02x%02x%02x%02x%02x%02x%02x%02x\n",
-		(unsigned int) STI_U8(rom->graphics_id[0]), 
-		(unsigned int) STI_U8(rom->graphics_id[1]), 
-		(unsigned int) STI_U8(rom->graphics_id[2]), 
-		(unsigned int) STI_U8(rom->graphics_id[3]), 
-		(unsigned int) STI_U8(rom->graphics_id[4]), 
-		(unsigned int) STI_U8(rom->graphics_id[5]), 
-		(unsigned int) STI_U8(rom->graphics_id[6]), 
-		(unsigned int) STI_U8(rom->graphics_id[7]));
-	printk(__FUNCTION__ ": %d\n", __LINE__);
-	printk(" font start %08x\n",  STI_U32(rom->font_start));
-	printk(__FUNCTION__ ": %d\n", __LINE__);
-	printk(" region list %08x\n", STI_U32(rom->region_list));
-	printk(__FUNCTION__ ": %d\n", __LINE__);
-	printk(" init_graph %08x\n",  STI_U32(rom->init_graph));
-	printk(__FUNCTION__ ": %d\n", __LINE__);
-	printk(" alternate code type %d\n", STI_U8(rom->alt_code_type));
-	printk(__FUNCTION__ ": %d\n", __LINE__);
-}
-
-static void __init sti_cook_fonts(struct sti_cooked_rom *cooked_rom,
-				  struct sti_rom *raw_rom)
-{
-	struct sti_rom_font *raw_font;
-	struct sti_cooked_font *cooked_font;
-	struct sti_rom_font *font_start;
-
-	cooked_font =
-		kmalloc(sizeof *cooked_font, GFP_KERNEL);
-	if(!cooked_font)
-		return;
-
-	cooked_rom->font_start = cooked_font;
-
-#if 0
-	DPRINTK(("%p = %p + %08x\n",
-	       ((void *)raw_rom) + (STI_U32(raw_rom->font_start)),
-	       ((void *)raw_rom), (STI_U32(raw_rom->font_start))));
-#endif
-	raw_font = ((void *)raw_rom) + STI_U32(raw_rom->font_start) - 3;
-
-	font_start = raw_font;
-	cooked_font->raw = raw_font;
-
-	DPRINTK(("next font %08x\n", STI_U32(raw_font->next_font)));
-
-	while(0 && STI_U32(raw_font->next_font)) {
-		raw_font = ((void *)font_start) + STI_U32(raw_font->next_font);
-		
-		cooked_font->next_font =
-			kmalloc(sizeof *cooked_font, GFP_KERNEL);
-		if(!cooked_font->next_font)
-			return;
-
-		cooked_font = cooked_font->next_font;
-
-//		cooked_font->raw = raw_font;
-
-		DPRINTK(("raw_font %p\n",
-		       raw_font));
-		DPRINTK(("next_font %08x %p\n",
-		       STI_U32(raw_font->next_font),
-		       ((void *)font_start) + STI_U32(raw_font->next_font)));
-	}
-
-	cooked_font->next_font = NULL;
-}
-
-static unsigned long __init sti_cook_function(void *function,
-					      u32 size)
-{
-	sti_u32 *func = (sti_u32 *)function;
-	u32 *ret;
-	int i;
-
-	ret = kmalloc(size, GFP_KERNEL);
-	if(!ret) {
-		printk(KERN_ERR __FILE__ ": could not get memory.\n");
-		return 0;
-	}
-
-	for(i=0; i<(size/4); i++)
-	    ret[i] = STI_U32(func[i]);
-
-	flush_all_caches();
-	
-	return virt_to_phys(ret);
-}
-
-static int font_index, font_height, font_width;
-
-static int __init sti_search_font(struct sti_cooked_rom *rom,
-				  int height, int width)
-{
-	struct sti_cooked_font *font;
-	int i = 0;
-	
-	for(font = rom->font_start; font; font = font->next_font, i++) {
-		if((STI_U8(font->raw->width) == width) &&
-		   (STI_U8(font->raw->height) == height))
-			return i;
-	}
-
-	return 0;
-}
-
-static struct sti_cooked_font * __init
-sti_select_font(struct sti_cooked_rom *rom)
-{
-	struct sti_cooked_font *font;
-	int i;
-
-	if(font_width && font_height)
-		font_index = sti_search_font(rom, font_height, font_width);
-
-	for(font = rom->font_start, i = font_index;
-	    font && (i > 0);
-	    font = font->next_font, i--);
-
-	if(font)
-		return font;
-	else
-		return rom->font_start;
-}
-	
-/* address is a pointer to a word mode or pci rom */
-static struct sti_struct * __init sti_read_rom(unsigned long address)
-{
-	struct sti_struct *ret = NULL;
-	struct sti_cooked_rom *cooked = NULL;
-	struct sti_rom *raw = NULL;
-	unsigned long size;
-
-	ret = &default_sti;
-
-	if(!ret)
-		goto out_err;
-
-	cooked = kmalloc(sizeof *cooked, GFP_KERNEL);
-	raw = kmalloc(sizeof *raw, GFP_KERNEL);
-	
-	if(!(raw && cooked))
-		goto out_err;
-
-	/* reallocate raw */
-	sti_rom_copy(address, 0, sizeof *raw, raw);
-
-	dump_sti_rom(raw);
-
-	size = STI_U32(raw->last_addr) + 1;
-	size = 128*1024;
-//	DPRINTK(("size %08lx\n", size));
-//	DPRINTK(("font_start %08x\n", STI_U32(raw->font_start)));
-//	kfree(raw);
-	raw = kmalloc(size, GFP_KERNEL);
-	if(!raw)
-		goto out_err;
-	sti_rom_copy(address, 0, size-1, raw);
-
-	sti_cook_fonts(cooked, raw);
-//	sti_cook_regions(cooked, raw);
-//	sti_cook_functions(cooked, raw);
-
-	if(STI_U32(raw->region_list)) {
-		struct sti_rom_region *region =
-			((void *)raw) + STI_U32(raw->region_list) - 3;
-
-//		DPRINTK(("region_list %08x\n", STI_U32(raw->region_list)));
-
-		ret->regions = kmalloc(32, GFP_KERNEL); /* FIXME!! */
-
-		ret->regions[0] = STI_U32(region[0].region);
-		ret->regions[1] = STI_U32(region[1].region);
-		ret->regions[2] = STI_U32(region[2].region);
-		ret->regions[3] = STI_U32(region[3].region);
-		ret->regions[4] = STI_U32(region[4].region);
-		ret->regions[5] = STI_U32(region[5].region);
-		ret->regions[6] = STI_U32(region[6].region);
-		ret->regions[7] = STI_U32(region[7].region);
-	}
-
-	address = virt_to_phys(raw);
-
-#if 0
-	DPRINTK(("init_graph %08x %08x\n"
-	       "state_mgmt %08x %08x\n"
-	       "font_unpmv %08x %08x\n"
-	       "block_move %08x %08x\n"
-	       "self_test  %08x %08x\n"
-	       "excep_hdlr %08x %08x\n"
-	       "irq_conf   %08x %08x\n"
-	       "set_cm_e   %08x %08x\n"
-	       "dma_ctrl   %08x %08x\n"
-	       "flow_ctrl  %08x %08x\n"
-	       "user_timin %08x %08x\n"
-	       "process_m  %08x %08x\n"
-	       "sti_util   %08x %08x\n"
-	       "end_addr   %08x %08x\n",
-	       STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
-	       STI_U32(raw->state_mgmt), STI_U32(raw->state_mgmt_m68k),
-	       STI_U32(raw->font_unpmv), STI_U32(raw->font_unpmv_m68k),
-	       STI_U32(raw->block_move), STI_U32(raw->block_move_m68k),
-	       STI_U32(raw->self_test), STI_U32(raw->self_test_m68k),
-	       STI_U32(raw->excep_hdlr), STI_U32(raw->excep_hdlr_m68k),
-	       STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
-	       STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
-	       STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
-	       STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
-	       STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
-	       STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
-	       STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
-	       STI_U32(raw->end_addr), STI_U32(raw->end_addr_m68k) ) );
-#endif
-
-	ret->init_graph = sti_cook_function(((void *)raw)+STI_U32(raw->init_graph)-3,
-					    (STI_U32(raw->state_mgmt) -
-					     STI_U32(raw->init_graph))/4);
-
-
-	ret->font_unpmv = sti_cook_function(((void *)raw)+STI_U32(raw->font_unpmv)-3,
-					    (STI_U32(raw->block_move) -
-					     STI_U32(raw->font_unpmv))/4);
-
-	ret->block_move = sti_cook_function(((void *)raw)+STI_U32(raw->block_move)-3,
-					    (STI_U32(raw->self_test) -
-					     STI_U32(raw->block_move))/4);
-
-	ret->inq_conf = sti_cook_function(((void *)raw)+STI_U32(raw->inq_conf),
-					  STI_U32(raw->set_cm_entry) -
-					  STI_U32(raw->inq_conf));
-
-	ret->rom = cooked;
-	ret->rom->raw = raw;
-
-	ret->font = (struct sti_rom_font *) virt_to_phys(sti_select_font(ret->rom)->raw);
-
-	return ret;
-
-out_err:
-	if(raw)
-		kfree(raw);
-	if(cooked)
-		kfree(cooked);
-
-	return NULL;
-}
-
-#if 0
-static void dump_globcfg_ext(struct sti_glob_cfg_ext *cfg)
-{
-	DPRINTK(("monitor %d\n"
-		"in friendly mode: %d\n"
-		"power consumption %d watts\n"
-		"freq ref %d\n"
-		"sti_mem_addr %p\n",
-		cfg->curr_mon,
-		cfg->friendly_boot,
-		cfg->power,
-		cfg->freq_ref,
-		cfg->sti_mem_addr));
-}
-
-static void dump_globcfg(struct sti_glob_cfg *glob_cfg)
-{
-	DPRINTK(("%d text planes\n"
-		"%4d x %4d screen resolution\n"
-		"%4d x %4d offscreen\n"
-		"%4d x %4d layout\n"
-		"regions at %08x %08x %08x %08x\n"
-		"regions at %08x %08x %08x %08x\n"
-		"reent_lvl %d\n"
-		"save_addr %p\n",
-		glob_cfg->text_planes,
-		glob_cfg->onscreen_x, glob_cfg->onscreen_y,
-		glob_cfg->offscreen_x, glob_cfg->offscreen_y,
-		glob_cfg->total_x, glob_cfg->total_y,
-		glob_cfg->region_ptrs[0], glob_cfg->region_ptrs[1],
-		glob_cfg->region_ptrs[2], glob_cfg->region_ptrs[3],
-		glob_cfg->region_ptrs[4], glob_cfg->region_ptrs[5],
-		glob_cfg->region_ptrs[6], glob_cfg->region_ptrs[7],
-		glob_cfg->reent_lvl,
-		glob_cfg->save_addr));
-	dump_globcfg_ext(PTR_STI(glob_cfg->ext_ptr));
-}
-#endif
-		
-static void __init sti_init_glob_cfg(struct sti_struct *sti, unsigned long hpa,
-				     unsigned long rom_address)
-{
-	struct sti_glob_cfg *glob_cfg;
-	struct sti_glob_cfg_ext *glob_cfg_ext;
-	void *save_addr;
-	void *sti_mem_addr;
-
-	glob_cfg = kmalloc(sizeof *sti->glob_cfg, GFP_KERNEL);
-	glob_cfg_ext = kmalloc(sizeof *glob_cfg_ext, GFP_KERNEL);
-	save_addr = kmalloc(1024 /*XXX*/, GFP_KERNEL);
-	sti_mem_addr = kmalloc(1024, GFP_KERNEL);
-
-	if((!glob_cfg) || (!glob_cfg_ext) || (!save_addr) || (!sti_mem_addr))
-		return;
-
-	memset(glob_cfg, 0, sizeof *glob_cfg);
-	memset(glob_cfg_ext, 0, sizeof *glob_cfg_ext);
-	memset(save_addr, 0, 1024);
-	memset(sti_mem_addr, 0, 1024);
-
-	glob_cfg->ext_ptr = STI_PTR(glob_cfg_ext);
-	glob_cfg->save_addr = STI_PTR(save_addr);
-	glob_cfg->region_ptrs[0] = ((sti->regions[0]>>18)<<12) + rom_address;
-	glob_cfg->region_ptrs[1] = ((sti->regions[1]>>18)<<12) + hpa;
-	glob_cfg->region_ptrs[2] = ((sti->regions[2]>>18)<<12) + hpa;
-	glob_cfg->region_ptrs[3] = ((sti->regions[3]>>18)<<12) + hpa;
-	glob_cfg->region_ptrs[4] = ((sti->regions[4]>>18)<<12) + hpa;
-	glob_cfg->region_ptrs[5] = ((sti->regions[5]>>18)<<12) + hpa;
-	glob_cfg->region_ptrs[6] = ((sti->regions[6]>>18)<<12) + hpa;
-	glob_cfg->region_ptrs[7] = ((sti->regions[7]>>18)<<12) + hpa;
-
-	glob_cfg_ext->sti_mem_addr = STI_PTR(sti_mem_addr);
-
-	sti->glob_cfg = STI_PTR(glob_cfg);
-}
-
-static void __init sti_try_rom(unsigned long address, unsigned long hpa)
-{
-	struct sti_struct *sti = NULL;
-	u16 sig;
-	
-	/* if we can't read the ROM, bail out early.  Not being able
-	 * to read the hpa is okay, for romless sti */
-	if(pdc_add_valid((void*)address))
-		return;
-
-	printk("found potential STI ROM at %08lx\n", address);
-
-	sig = le16_to_cpu(gsc_readw(address));
-
-	if((sig&0xff) == 0x01) {
-		sti = sti_read_rom(address);
-	}
-
-	if(sig == 0x0303) {
-		printk("STI word mode ROM at %08lx, ignored\n",
-		       address);
-
-		sti = NULL;
-	}
-
-	if(!sti)
-		return;
-
-	/* this is hacked.  We need a better way to find out the HPA for
-	 * romless STI (eg search for the graphics devices we know about
-	 * by sversion) */
-	if (!pdc_add_valid((void *)0xf5000000)) DPRINTK(("f4000000 b\n"));
-	if (!pdc_add_valid((void *)0xf7000000)) DPRINTK(("f6000000 b\n"));
-	if (!pdc_add_valid((void *)0xf9000000)) DPRINTK(("f8000000 b\n"));
-	if (!pdc_add_valid((void *)0xfb000000)) DPRINTK(("fa000000 b\n"));
-	sti_init_glob_cfg(sti, hpa, address);
-
-	sti_init_graph(sti);
-
-	//sti_inq_conf(sti);
-#if !defined(SERIAL_CONSOLE)	
-	{ 
-	    extern void pdc_console_die(void);  
-	    pdc_console_die(); 
-	}
-#endif
-		
-	take_over_console(&sti_con, 0, MAX_NR_CONSOLES-1, 1);
-
-	/* sti_inq_conf(sti); */
-}
-
-static unsigned long sti_address;
-static unsigned long sti_hpa;
-
-static void __init sti_init_roms(void)
-{
-	/* handle the command line */
-	if(sti_address && sti_hpa) {
-		sti_try_rom(sti_address, sti_hpa);
-
-		return;
-	}
-
-	/* 712, 715, some other boxes don't have a separate STI ROM,
-	 * but use part of the regular flash */
-	if(PAGE0->proc_sti) {
-		printk("STI ROM from PDC at %08x\n", PAGE0->proc_sti);
-		if(!pdc_add_valid((void *)0xf9000000))
-			sti_try_rom(PAGE0->proc_sti, 0xf8000000);
-		else if(!pdc_add_valid((void *)0xf5000000))
-			sti_try_rom(PAGE0->proc_sti, 0xf4000000);
-		else if(!pdc_add_valid((void *)0xf7000000))
-			sti_try_rom(PAGE0->proc_sti, 0xf6000000);
-		else if(!pdc_add_valid((void *)0xfb000000))
-			sti_try_rom(PAGE0->proc_sti, 0xfa000000);
-	}
-
-	/* standard locations for GSC graphic devices */
-	if(!pdc_add_valid((void *)0xf4000000))
-		sti_try_rom(0xf4000000, 0xf4000000);
-	if(!pdc_add_valid((void *)0xf6000000))
-		sti_try_rom(0xf6000000, 0xf6000000);
-	if(!pdc_add_valid((void *)0xf8000000))
-		sti_try_rom(0xf8000000, 0xf8000000);
-	if(!pdc_add_valid((void *)0xfa000000))
-		sti_try_rom(0xfa000000, 0xfa000000);
-}
-
-static int __init sti_init(void)
-{
-	printk("searching for byte mode STI ROMs\n");
-	sti_init_roms();
-	return 0;
-}
-
-module_init(sti_init)
-
-MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/sticon.c b/drivers/video/sticon.c
--- a/drivers/video/sticon.c	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,215 +0,0 @@
-/*
- *  linux/drivers/video/sticon.c  - console driver using HP's STI firmware
- *
- *	Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
- *
- *  Based on linux/drivers/video/vgacon.c and linux/drivers/video/fbcon.c,
- *  which were
- *
- *	Created 28 Sep 1997 by Geert Uytterhoeven
- *	Rewritten by Martin Mares <mj@ucw.cz>, July 1998
- *	Copyright (C) 1991, 1992  Linus Torvalds
- *			    1995  Jay Estabrook
- *	Copyright (C) 1995 Geert Uytterhoeven
- *	Copyright (C) 1993 Bjoern Brauel
- *			   Roman Hodek
- *	Copyright (C) 1993 Hamish Macdonald
- *			   Greg Harp
- *	Copyright (C) 1994 David Carter [carter@compsci.bristol.ac.uk]
- *
- *	      with work by William Rucklidge (wjr@cs.cornell.edu)
- *			   Geert Uytterhoeven
- *			   Jes Sorensen (jds@kom.auc.dk)
- *			   Martin Apel
- *	      with work by Guenther Kelleter
- *			   Martin Schaller
- *			   Andreas Schwab
- *			   Emmanuel Marty (core@ggi-project.org)
- *			   Jakub Jelinek (jj@ultra.linux.cz)
- *			   Martin Mares <mj@ucw.cz>
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive for
- *  more details.
- */
-/*
- *  TODO:
- *   - call STI in virtual mode rather than in real mode
- *   - support for PCI-only STI ROMs (which don't have a traditional region
- *     list)
- *   - safe detection (i.e. verify there is a graphics device at a given
- *     address first, not just read a random device's io space)
- *   - support for multiple STI devices in one machine
- *   - support for byte-mode STI ROMs
- *   - support for just using STI to switch to a colour fb (stifb ?)
- *   - try to make it work on m68k hp workstations ;)
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/console_struct.h>
-#include <linux/errno.h>
-#include <linux/vt_kern.h>
-#include <linux/selection.h>
-
-#include <asm/io.h>
-
-#include "sti.h"
-
-/* STICON */
-
-static const char * __init
-sticon_startup(void)
-{
-	return "STI console";
-}
-
-static int
-sticon_set_palette(struct vc_data *c, unsigned char *table)
-{
-	return -EINVAL;
-}
-static int
-sticon_font_op(struct vc_data *c, struct console_font_op *op)
-{
-	return -ENOSYS;
-}
-
-static void sticon_putc(struct vc_data *conp, int c, int ypos, int xpos)
-{
-	sti_putc(&default_sti, c, ypos, xpos);
-}
-
-static void sticon_putcs(struct vc_data *conp, const unsigned short *s,
-	int count, int ypos, int xpos)
-{
-	while(count--) {
-		sti_putc(&default_sti, scr_readw(s++), ypos, xpos++);
-	}
-}
-
-static void sticon_cursor(struct vc_data *conp, int mode)
-{
-}
-
-static int sticon_scroll(struct vc_data *conp, int t, int b, int dir,
-			int count)
-{
-	struct sti_struct *sti = &default_sti;
-
-	if(console_blanked)
-		return 0;
-
-	sticon_cursor(conp, CM_ERASE);
-
-	switch(dir) {
-	case SM_UP:
-		sti_bmove(sti, t+count, 0, t, 0, b-t-count, conp->vc_cols);
-		sti_clear(sti, b-count, 0, count, conp->vc_cols);
-
-		break;
-
-	case SM_DOWN:
-		sti_bmove(sti, t, 0, t+count, 0, b-t-count, conp->vc_cols);
-		sti_clear(sti, t, 0, count, conp->vc_cols);
-
-		break;
-	}
-
-	return 0;
-}
-	
-static void sticon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
-			 int height, int width)
-{
-	sti_bmove(&default_sti, sy, sx, dy, dx, height, width);
-}
-
-static void sticon_init(struct vc_data *c, int init)
-{
-	struct sti_struct *sti = &default_sti;
-	int vc_cols, vc_rows;
-
-	sti_set(sti, 0, 0, sti_onscreen_y(sti), sti_onscreen_x(sti), 0);
-	c->vc_can_do_color = 1;
-	vc_cols = PTR_STI(sti->glob_cfg)->onscreen_x / sti_font_x(sti);
-	vc_rows = PTR_STI(sti->glob_cfg)->onscreen_y / sti_font_y(sti);
-
-	vc_resize_con(vc_rows, vc_cols, c->vc_num);
-}
-
-static void sticon_deinit(struct vc_data *c)
-{
-}
-
-static void sticon_clear(struct vc_data *conp, int sy, int sx, int height,
-			int width)
-{
-	sti_clear(&default_sti, sy, sx, height, width);
-}
-
-static int sticon_switch(struct vc_data *conp)
-{
-	return 0;
-}
-
-static int sticon_blank(struct vc_data *conp, int blank)
-{
-	return 0;
-}
-
-static int sticon_scrolldelta(struct vc_data *conp, int lines)
-{
-	return 0;
-}
-
-static int sticon_set_origin(struct vc_data *conp)
-{
-	return 0;
-}
-
-static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens, u8 blink, u8 underline, u8 reverse)
-{
-	u8 attr = ((color & 0x70) >> 1) | ((color & 7));
-
-	if(reverse) {
-		color = ((color>>3)&0x7) | ((color &0x7)<<3);
-	}
-
-
-	return attr;
-}
-
-struct consw sti_con = {
-	.con_startup = 		sticon_startup, 
-	.con_init = 		sticon_init,
-	.con_deinit = 		sticon_deinit,
-	.con_clear = 		sticon_clear,
-	.con_putc = 		sticon_putc,
-	.con_putcs = 		sticon_putcs,
-	.con_cursor = 		sticon_cursor,
-	.con_scroll = 		sticon_scroll,
-	.con_bmove = 		sticon_bmove,
-	.con_switch = 		sticon_switch,
-	.con_blank = 		sticon_blank,
-	.con_font_op =		sticon_font_op,
-	.con_set_palette =	sticon_set_palette,
-	.con_scrolldelta =	sticon_scrolldelta,
-	.con_set_origin = 	sticon_set_origin,
-	.con_build_attr =	sticon_build_attr,
-};
-
-static int __init sti_init(void)
-{
-	printk("searching for word mode STI ROMs\n");
-	if (sti_init_roms()) {
-		pdc_console_die();
-		take_over_console(&sti_con, 0, MAX_NR_CONSOLES-1, 1);
-		return 0;
-	} else
-		return -ENODEV;
-}
-
-module_init(sti_init)
diff -Nru a/drivers/video/sticore.c b/drivers/video/sticore.c
--- a/drivers/video/sticore.c	Mon Dec  9 18:46:35 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,601 +0,0 @@
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-
-#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
-#include <asm/io.h>
-
-#include "sti.h"
-
-struct sti_struct default_sti = {
-	SPIN_LOCK_UNLOCKED,
-};
-
-static struct sti_font_flags default_font_flags = {
-	STI_WAIT, 0, 0, NULL
-};
-
-/* The colour indices used by STI are
- *   0 - Black
- *   1 - White
- *   2 - Red
- *   3 - Yellow/Brown
- *   4 - Green
- *   5 - Cyan
- *   6 - Blue
- *   7 - Magenta
- *
- * So we have the same colours as VGA (basically one bit each for R, G, B),
- * but have to translate them, anyway. */
-
-static u8 col_trans[8] = {
-        0, 6, 4, 5,
-        2, 7, 3, 1
-};
-
-#define c_fg(sti, c) col_trans[((c>> 8) & 7)]
-#define c_bg(sti, c) col_trans[((c>>11) & 7)]
-#define c_index(sti, c) (c&0xff)
-
-static struct sti_init_flags default_init_flags = {
-	STI_WAIT, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, NULL
-};
-
-void
-sti_init_graph(struct sti_struct *sti) 
-{
-	struct sti_init_inptr_ext inptr_ext = {
-		0, { 0 }, 0, NULL
-	};
-	struct sti_init_inptr inptr = {
-		3, STI_PTR(&inptr_ext)
-	};
-	struct sti_init_outptr outptr = { 0 };
-	unsigned long flags;
-	s32 ret;
-
-	spin_lock_irqsave(&sti->lock, flags);
-
-	ret = STI_CALL(sti->init_graph, &default_init_flags, &inptr,
-		&outptr, sti->glob_cfg);
-
-	spin_unlock_irqrestore(&sti->lock, flags);
-
-	sti->text_planes = outptr.text_planes;
-}
-
-static struct sti_conf_flags default_conf_flags = {
-	STI_WAIT, 0, NULL
-};
-
-void
-sti_inq_conf(struct sti_struct *sti)
-{
-	struct sti_conf_inptr inptr = { NULL };
-	struct sti_conf_outptr_ext outptr_ext = { .future_ptr = NULL };
-	struct sti_conf_outptr outptr = {
-		.ext_ptr = STI_PTR(&outptr_ext)
-	};
-	unsigned long flags;
-	s32 ret;
-	
-	do {
-		spin_lock_irqsave(&sti->lock, flags);
-		ret = STI_CALL(sti->inq_conf, &default_conf_flags,
-			&inptr, &outptr, sti->glob_cfg);
-		spin_unlock_irqrestore(&sti->lock, flags);
-	} while(ret == 1);
-}
-
-void
-sti_putc(struct sti_struct *sti, int c, int y, int x)
-{
-	struct sti_font_inptr inptr = {
-		(u32) sti->font, c_index(sti, c), c_fg(sti, c), c_bg(sti, c),
-		x * sti_font_x(sti), y * sti_font_y(sti), NULL
-	};
-	struct sti_font_outptr outptr = {
-		0, NULL
-	};
-	s32 ret;
-	unsigned long flags;
-
-	do {
-		spin_lock_irqsave(&sti->lock, flags);
-		ret = STI_CALL(sti->font_unpmv, &default_font_flags,
-			&inptr, &outptr, sti->glob_cfg);
-		spin_unlock_irqrestore(&sti->lock, flags);
-	} while(ret == 1);
-}
-
-static struct sti_blkmv_flags clear_blkmv_flags = {
-	STI_WAIT, 1, 1, 0, 0, NULL
-};
-
-void
-sti_set(struct sti_struct *sti, int src_y, int src_x,
-	int height, int width, u8 color)
-{
-	struct sti_blkmv_inptr inptr = {
-		color, color,
-		src_x, src_y ,
-		src_x, src_y ,
-		width, height,
-		NULL
-	};
-	struct sti_blkmv_outptr outptr = { 0, NULL };
-	s32 ret = 0;
-	unsigned long flags;
-	
-	do {
-		spin_lock_irqsave(&sti->lock, flags);
-		ret = STI_CALL(sti->block_move, &clear_blkmv_flags,
-			&inptr, &outptr, sti->glob_cfg);
-		spin_unlock_irqrestore(&sti->lock, flags);
-	} while(ret == 1);
-}
-
-void
-sti_clear(struct sti_struct *sti, int src_y, int src_x,
-	  int height, int width)
-{
-	struct sti_blkmv_inptr inptr = {
-		0, 0,
-		src_x * sti_font_x(sti), src_y * sti_font_y(sti),
-		src_x * sti_font_x(sti), src_y * sti_font_y(sti),
-		width * sti_font_x(sti), height* sti_font_y(sti),
-		NULL
-	};
-	struct sti_blkmv_outptr outptr = { 0, NULL };
-	s32 ret = 0;
-	unsigned long flags;
-
-	do {
-		spin_lock_irqsave(&sti->lock, flags);
-		ret = STI_CALL(sti->block_move, &clear_blkmv_flags,
-			&inptr, &outptr, sti->glob_cfg);
-		spin_unlock_irqrestore(&sti->lock, flags);
-	} while(ret == 1);
-}
-
-static struct sti_blkmv_flags default_blkmv_flags = {
-	STI_WAIT, 0, 0, 0, 0, NULL
-};
-
-void
-sti_bmove(struct sti_struct *sti, int src_y, int src_x,
-	  int dst_y, int dst_x, int height, int width)
-{
-	struct sti_blkmv_inptr inptr = {
-		0, 0,
-		src_x * sti_font_x(sti), src_y * sti_font_y(sti),
-		dst_x * sti_font_x(sti), dst_y * sti_font_y(sti),
-		width * sti_font_x(sti), height* sti_font_y(sti),
-		NULL
-	};
-	struct sti_blkmv_outptr outptr = { 0, NULL };
-	s32 ret = 0;
-	unsigned long flags;
-
-	do {
-		spin_lock_irqsave(&sti->lock, flags);
-		ret = STI_CALL(sti->block_move, &default_blkmv_flags,
-			&inptr, &outptr, sti->glob_cfg);
-		spin_unlock_irqrestore(&sti->lock, flags);
-	} while(ret == 1);
-}
-
-
-static void __init
-sti_rom_copy(unsigned long base, unsigned long offset,
-	     unsigned long count, void *dest)
-{
-	void *savedest = dest;
-	int savecount = count;
-
-	while(count >= 4) {
-		count -= 4;
-		*(u32 *)dest = gsc_readl(base + offset);
-		offset += 4;
-		dest += 4;
-	}
-	while(count) {
-		count--;
-		*(u8 *)dest = gsc_readb(base + offset);
-		offset++;
-		dest++;
-	}
-
-	flush_kernel_dcache_range((unsigned long)dest, count);
-	flush_icache_range((unsigned long)dest, dest + count);
-}
-
-static void dump_sti_rom(struct sti_rom *rom)
-{
-	printk("STI word mode ROM type %d\n", rom->type[3]);
-	printk(" supports %d monitors\n", rom->num_mons);
-	printk(" conforms to STI ROM spec revision %d.%02x\n",
-		rom->revno[0] >> 4, rom->revno[0] & 0x0f);
-	printk(" graphics id %02x%02x%02x%02x%02x%02x%02x%02x\n",
-		rom->graphics_id[0], 
-		rom->graphics_id[1], 
-		rom->graphics_id[2], 
-		rom->graphics_id[3], 
-		rom->graphics_id[4], 
-		rom->graphics_id[5], 
-		rom->graphics_id[6], 
-		rom->graphics_id[7]);
-	printk(" font start %08x\n", rom->font_start);
-	printk(" region list %08x\n", rom->region_list);
-	printk(" init_graph %08x\n", rom->init_graph);
-	printk(" alternate code type %d\n", rom->alt_code_type);
-}
-
-static void __init sti_cook_fonts(struct sti_cooked_rom *cooked_rom,
-				  struct sti_rom *raw_rom)
-{
-	struct sti_rom_font *raw_font;
-	struct sti_cooked_font *cooked_font;
-	struct sti_rom_font *font_start;
-	
-	cooked_font =
-		kmalloc(sizeof *cooked_font, GFP_KERNEL);
-	if(!cooked_font)
-		return;
-
-	cooked_rom->font_start = cooked_font;
-
-	raw_font = ((void *)raw_rom) + (raw_rom->font_start);
-
-	font_start = raw_font;
-	cooked_font->raw = raw_font;
-
-	while(raw_font->next_font) {
-		raw_font = ((void *)font_start) + (raw_font->next_font);
-		
-		cooked_font->next_font =
-			kmalloc(sizeof *cooked_font, GFP_KERNEL);
-		if(!cooked_font->next_font)
-			return;
-
-		cooked_font = cooked_font->next_font;
-
-		cooked_font->raw = raw_font;
-	}
-
-	cooked_font->next_font = NULL;
-}
-
-static int font_index, font_height, font_width;
-
-static int __init sti_font_setup(char *str)
-{
-	char *x;
-
-	/* we accept sti_font=10x20, sti_font=10*20 or sti_font=7 style
-	 * command lines. */
-
-	if((x = strchr(str, 'x')) || (x = strchr(str, '*'))) {
-		font_height = simple_strtoul(str, NULL, 0);
-		font_width = simple_strtoul(x+1, NULL, 0);
-	} else {
-		font_index = simple_strtoul(str, NULL, 0);
-	}
-
-	return 0;
-}
-
-__setup("sti_font=", sti_font_setup);
-
-static int __init sti_search_font(struct sti_cooked_rom *rom,
-				  int height, int width)
-{
-	struct sti_cooked_font *font;
-	int i = 0;
-	
-	for(font = rom->font_start; font; font = font->next_font, i++) {
-		if((font->raw->width == width) && (font->raw->height == height))
-			return i;
-	}
-
-	return 0;
-}
-
-static struct sti_cooked_font * __init
-sti_select_font(struct sti_cooked_rom *rom)
-{
-	struct sti_cooked_font *font;
-	int i;
-
-	if(font_width && font_height)
-		font_index = sti_search_font(rom, font_height, font_width);
-
-	for(font = rom->font_start, i = font_index;
-	    font && (i > 0);
-	    font = font->next_font, i--);
-
-	if(font)
-		return font;
-	else
-		return rom->font_start;
-}
-	
-static void __init
-sti_dump_globcfg_ext(struct sti_glob_cfg_ext *cfg)
-{
-	printk(	"monitor %d\n"
-		"in friendly mode: %d\n"
-		"power consumption %d watts\n"
-		"freq ref %d\n"
-		"sti_mem_addr %p\n",
-		cfg->curr_mon,
-		cfg->friendly_boot,
-		cfg->power,
-		cfg->freq_ref,
-		cfg->sti_mem_addr);
-}
-
-void __init
-sti_dump_globcfg(struct sti_glob_cfg *glob_cfg)
-{
-	printk(	"%d text planes\n"
-		"%4d x %4d screen resolution\n"
-		"%4d x %4d offscreen\n"
-		"%4d x %4d layout\n"
-		"regions at %08x %08x %08x %08x\n"
-		"regions at %08x %08x %08x %08x\n"
-		"reent_lvl %d\n"
-		"save_addr %p\n",
-		glob_cfg->text_planes,
-		glob_cfg->onscreen_x, glob_cfg->onscreen_y,
-		glob_cfg->offscreen_x, glob_cfg->offscreen_y,
-		glob_cfg->total_x, glob_cfg->total_y,
-		glob_cfg->region_ptrs[0], glob_cfg->region_ptrs[1],
-		glob_cfg->region_ptrs[2], glob_cfg->region_ptrs[3],
-		glob_cfg->region_ptrs[4], glob_cfg->region_ptrs[5],
-		glob_cfg->region_ptrs[6], glob_cfg->region_ptrs[7],
-		glob_cfg->reent_lvl,
-		glob_cfg->save_addr);
-	sti_dump_globcfg_ext(PTR_STI(glob_cfg->ext_ptr));
-}
-		
-static void __init
-sti_init_glob_cfg(struct sti_struct *sti, unsigned long hpa,
-		  unsigned long rom_address)
-{
-	struct sti_glob_cfg *glob_cfg;
-	struct sti_glob_cfg_ext *glob_cfg_ext;
-	void *save_addr;
-	void *sti_mem_addr;
-
-	glob_cfg = kmalloc(sizeof *sti->glob_cfg, GFP_KERNEL);
-	glob_cfg_ext = kmalloc(sizeof *glob_cfg_ext, GFP_KERNEL);
-	save_addr = kmalloc(1024 /*XXX*/, GFP_KERNEL);
-	sti_mem_addr = kmalloc(1024, GFP_KERNEL);
-
-	if((!glob_cfg) || (!glob_cfg_ext) || (!save_addr) || (!sti_mem_addr))
-		return;
-
-	memset(glob_cfg, 0, sizeof *glob_cfg);
-	memset(glob_cfg_ext, 0, sizeof *glob_cfg_ext);
-	memset(save_addr, 0, 1024);
-	memset(sti_mem_addr, 0, 1024);
-
-	glob_cfg->ext_ptr = STI_PTR(glob_cfg_ext);
-	glob_cfg->save_addr = STI_PTR(save_addr);
-	glob_cfg->region_ptrs[0] = ((sti->regions[0]>>18)<<12) + rom_address;
-	glob_cfg->region_ptrs[1] = ((sti->regions[1]>>18)<<12) + hpa;
-	glob_cfg->region_ptrs[2] = ((sti->regions[2]>>18)<<12) + hpa;
-	glob_cfg->region_ptrs[3] = ((sti->regions[3]>>18)<<12) + hpa;
-	glob_cfg->region_ptrs[4] = ((sti->regions[4]>>18)<<12) + hpa;
-	glob_cfg->region_ptrs[5] = ((sti->regions[5]>>18)<<12) + hpa;
-	glob_cfg->region_ptrs[6] = ((sti->regions[6]>>18)<<12) + hpa;
-	glob_cfg->region_ptrs[7] = ((sti->regions[7]>>18)<<12) + hpa;
-	
-	glob_cfg_ext->sti_mem_addr = STI_PTR(sti_mem_addr);
-
-	sti->glob_cfg = STI_PTR(glob_cfg);
-}
-
-/* address is a pointer to a word mode or pci rom */
-static struct sti_struct * __init
-sti_read_rom(unsigned long address)
-{
-	struct sti_struct *ret = NULL;
-	struct sti_cooked_rom *cooked = NULL;
-	struct sti_rom *raw = NULL;
-	unsigned long size;
-
-	ret = &default_sti;
-
-	if(!ret)
-		goto out_err;
-
-	cooked = kmalloc(sizeof *cooked, GFP_KERNEL);
-	raw = kmalloc(sizeof *raw, GFP_KERNEL);
-	
-	if(!(raw && cooked))
-		goto out_err;
-
-	/* reallocate raw */
-	sti_rom_copy(address, 0, sizeof *raw, raw);
-
-	dump_sti_rom(raw);
-
-	size = raw->last_addr;
-	/* kfree(raw); */
-	raw = kmalloc(size, GFP_KERNEL);
-	if(!raw)
-		goto out_err;
-	sti_rom_copy(address, 0, size, raw);
-
-	sti_cook_fonts(cooked, raw);
-#if 0
-	sti_cook_regions(cooked, raw);
-	sti_cook_functions(cooked, raw);
-#endif
-
-	if(raw->region_list) {
-		ret->regions = kmalloc(32, GFP_KERNEL);	/* FIXME */
-
-		memcpy(ret->regions, ((void *)raw)+raw->region_list, 32);
-	}
-
-	address = virt_to_phys(raw);
-
-	ret->font_unpmv = address+(raw->font_unpmv & 0x03ffffff);
-	ret->block_move = address+(raw->block_move & 0x03ffffff);
-	ret->init_graph = address+(raw->init_graph & 0x03ffffff);
-	ret->inq_conf = address+(raw->inq_conf     & 0x03ffffff);
-
-	ret->rom = cooked;
-	ret->rom->raw = raw;
-
-	ret->font = (struct sti_rom_font *) virt_to_phys(sti_select_font(ret->rom)->raw);
-
-	return ret;
-
-out_err:
-	if(raw)
-		kfree(raw);
-	if(cooked)
-		kfree(cooked);
-
-	return NULL;
-}
-
-static struct sti_struct * __init
-sti_try_rom(unsigned long address, unsigned long hpa)
-{
-	struct sti_struct *sti = NULL;
-	u16 sig;
-	
-test_rom:
-	/* if we can't read the ROM, bail out early.  Not being able
-	 * to read the hpa is okay, for romless sti */
-	if(pdc_add_valid((void*)address))
-		return NULL;
-
-	printk("found potential STI ROM at %08lx\n", address);
-
-	sig = le16_to_cpu(gsc_readw(address));
-
-	if((sig==0x55aa) || (sig==0xaa55)) {
-		address += le32_to_cpu(gsc_readl(address+8));
-		printk("sig %04x, PCI STI ROM at %08lx\n",
-		       sig, address);
-
-		goto test_rom;
-	}
-
-	if((sig&0xff) == 0x01) {
-		printk("STI byte mode ROM at %08lx, ignored\n",
-		       address);
-
-		sti = NULL;
-	}
-
-	if(sig == 0x0303) {
-		printk("STI word mode ROM at %08lx\n",
-		       address);
-
-		sti = sti_read_rom(address);
-	}
-
-	if (!sti)
-		return NULL;
-
-	/* this is hacked.  We need a better way to find out the HPA for
-	 * romless STI (eg search for the graphics devices we know about
-	 * by sversion) */
-	if (!pdc_add_valid((void *)0xf5000000)) printk("f4000000 g\n");
-	if (!pdc_add_valid((void *)0xf7000000)) printk("f6000000 g\n");
-	if (!pdc_add_valid((void *)0xf9000000)) printk("f8000000 g\n");
-	if (!pdc_add_valid((void *)0xfb000000)) printk("fa000000 g\n");
-	sti_init_glob_cfg(sti, hpa, address);
-
-	sti_init_graph(sti);
-
-	sti_inq_conf(sti);
-	sti_dump_globcfg(PTR_STI(sti->glob_cfg));
-
-	return sti;
-}
-
-static unsigned long sti_address;
-static unsigned long sti_hpa;
-
-/* XXX: should build a list of STI ROMs */
-struct sti_struct * __init
-sti_init_roms(void)
-{
-	struct sti_struct *tmp = NULL, *sti = NULL;
-
-	/* handle the command line */
-	if (sti_address && sti_hpa) {
-		return sti_try_rom(sti_address, sti_hpa);
-	}
-
-	/* 712, 715, some other boxes don't have a separate STI ROM,
-	 * but use part of the regular flash */
-	if (PAGE0->proc_sti) {
-		printk("STI ROM from PDC at %08x\n", PAGE0->proc_sti);
-		if (!pdc_add_valid((void *)0xf9000000))
-			sti = sti_try_rom(PAGE0->proc_sti, 0xf8000000);
-		else if (!pdc_add_valid((void *)0xf5000000))
-			sti = sti_try_rom(PAGE0->proc_sti, 0xf4000000);
-		else if (!pdc_add_valid((void *)0xf7000000))
-			sti = sti_try_rom(PAGE0->proc_sti, 0xf6000000);
-		else if (!pdc_add_valid((void *)0xfb000000))
-			sti = sti_try_rom(PAGE0->proc_sti, 0xfa000000);
-
-	}
-
-	/* standard locations for GSC graphic devices */
-	if (!pdc_add_valid((void *)0xf4000000))
-		tmp = sti_try_rom(0xf4000000, 0xf4000000);
-	sti = tmp ? tmp : sti;
-	if (!pdc_add_valid((void *)0xf6000000))
-		tmp = sti_try_rom(0xf6000000, 0xf6000000);
-	sti = tmp ? tmp : sti;
-	if (!pdc_add_valid((void *)0xf8000000))
-		tmp = sti_try_rom(0xf8000000, 0xf8000000);
-	sti = tmp ? tmp : sti;
-	if (!pdc_add_valid((void *)0xfa000000))
-		tmp = sti_try_rom(0xfa000000, 0xfa000000);
-	sti = tmp ? tmp : sti;
-
-	return sti;
-}
-
-static int __init
-sti_setup(char *str)
-{
-	char *end;
-
-	if(strcmp(str, "pdc") == 0) {
-		sti_address = PAGE0->proc_sti;
-
-		return 1;
-	} else {
-		sti_address = simple_strtoul(str, &end, 16);
-
-		if((end == str) || (sti_address < 0xf0000000)) {
-			sti_address = 0;
-			return 0;
-		}
-
-		sti_hpa = sti_address;
-
-		return 1;
-	}
-
-	return 0;
-}
-
-__setup("sti=", sti_setup);
-
-MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/sticore.h b/drivers/video/sticore.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/sticore.h	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,407 @@
+#ifndef STICORE_H
+#define STICORE_H
+
+/* generic STI structures & functions */
+
+#if 0
+#define DPRINTK(x)	printk x
+#else
+#define DPRINTK(x) 
+#endif
+
+#define MAX_STI_ROMS 4		/* max no. of ROMs which this driver handles */
+
+#define STI_REGION_MAX 8	/* hardcoded STI constants */
+#define STI_DEV_NAME_LENGTH 32
+#define STI_MONITOR_MAX 256
+
+#define STI_FONT_HPROMAN8 1
+#define STI_FONT_KANA8 2
+
+/* The latency of the STI functions cannot really be reduced by setting
+ * this to 0;  STI doesn't seem to be designed to allow calling a different
+ * function (or the same function with different arguments) after a
+ * function exited with 1 as return value.
+ *
+ * As all of the functions below could be called from interrupt context,
+ * we have to spin_lock_irqsave around the do { ret = bla(); } while(ret==1)
+ * block.  Really bad latency there.
+ *
+ * Probably the best solution to all this is have the generic code manage
+ * the screen buffer and a kernel thread to call STI occasionally.
+ * 
+ * Luckily, the frame buffer guys have the same problem so we can just wait
+ * for them to fix it and steal their solution.   prumpf
+ */
+ 
+#define STI_WAIT 1
+
+#include <asm/io.h> /* for USE_HPPA_IOREMAP */
+
+#if USE_HPPA_IOREMAP
+
+#define STI_PTR(p)	(p)
+#define PTR_STI(p)	(p)
+static int inline STI_CALL( unsigned long func, 
+		void *flags, void *inptr, void *outptr, void *glob_cfg )
+{
+       int (*f)(void *,void *,void *,void *);
+       f = (void*)func;
+       return f(flags, inptr, outptr, glob_cfg);
+}
+
+#else /* !USE_HPPA_IOREMAP */
+
+#define STI_PTR(p)	( virt_to_phys(p) )
+#define PTR_STI(p)	( phys_to_virt((long)p) )
+#define STI_CALL(func, flags, inptr, outptr, glob_cfg) \
+       ({                                                      \
+               pdc_sti_call( func, (unsigned long)STI_PTR(flags), \
+                                   (unsigned long)STI_PTR(inptr), \
+                                   (unsigned long)STI_PTR(outptr), \
+                                   (unsigned long)STI_PTR(glob_cfg)); \
+       })
+
+#endif /* USE_HPPA_IOREMAP */
+
+
+#define sti_onscreen_x(sti) (sti->glob_cfg->onscreen_x)
+#define sti_onscreen_y(sti) (sti->glob_cfg->onscreen_y)
+
+/* sti_font_xy() use the native font ROM ! */
+#define sti_font_x(sti) (PTR_STI(sti->font)->width)
+#define sti_font_y(sti) (PTR_STI(sti->font)->height)
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
+#endif
+
+extern struct sti_struct *sti_init_roms(void);
+
+/* XXX: this probably should not be here, but we rely on STI being
+   initialized early and independently of stifb at the moment, so
+   there's no other way for stifb to find it. */
+extern struct sti_struct *default_sti;
+
+extern struct display_switch fbcon_sti; /* fbcon-sti.c */
+
+int  sti_init_graph(struct sti_struct *sti);
+void sti_inq_conf(struct sti_struct *sti);
+void sti_putc(struct sti_struct *sti, int c, int y, int x);
+void sti_set(struct sti_struct *sti, int src_y, int src_x,
+	     int height, int width, u8 color);
+void sti_clear(struct sti_struct *sti, int src_y, int src_x,
+	       int height, int width, int c);
+void sti_bmove(struct sti_struct *sti, int src_y, int src_x,
+	       int dst_y, int dst_x, int height, int width);
+
+
+/* STI function configuration structs */
+
+typedef union region {
+	struct { 
+		u32 offset	: 14;	/* offset in 4kbyte page */
+		u32 sys_only	: 1;	/* don't map to user space */
+		u32 cache	: 1;	/* map to data cache */
+		u32 btlb	: 1;	/* map to block tlb */
+		u32 last	: 1;	/* last region in list */
+		u32 length	: 14;	/* length in 4kbyte page */
+	} region_desc;
+
+	u32 region;			/* complete region value */
+} region_t;
+
+#define REGION_OFFSET_TO_PHYS( rt, hpa ) \
+	(((rt).region_desc.offset << 12) + (hpa))
+
+struct sti_glob_cfg_ext {
+	 u8 curr_mon;			/* current monitor configured */
+	 u8 friendly_boot;		/* in friendly boot mode */
+	s16 power;			/* power calculation (in Watts) */
+	s32 freq_ref;			/* frequency refrence */
+	u32 sti_mem_addr;		/* pointer to global sti memory (size=sti_mem_request) */
+	u32 future_ptr; 		/* pointer to future data */
+};
+
+struct sti_glob_cfg {
+	s32 text_planes;		/* number of planes used for text */
+	s16 onscreen_x;			/* screen width in pixels */
+	s16 onscreen_y;			/* screen height in pixels */
+	s16 offscreen_x;		/* offset width in pixels */
+	s16 offscreen_y;		/* offset height in pixels */
+	s16 total_x;			/* frame buffer width in pixels */
+	s16 total_y;			/* frame buffer height in pixels */
+	u32 region_ptrs[STI_REGION_MAX]; /* region pointers */
+	s32 reent_lvl;			/* storage for reentry level value */
+	u32 save_addr;			/* where to save or restore reentrant state */
+	u32 ext_ptr;			/* pointer to extended glob_cfg data structure */
+};
+
+
+/* STI init function structs */
+
+struct sti_init_flags {
+	u32 wait : 1;		/* should routine idle wait or not */
+	u32 reset : 1;		/* hard reset the device? */
+	u32 text : 1;		/* turn on text display planes? */
+	u32 nontext : 1;	/* turn on non-text display planes? */
+	u32 clear : 1;		/* clear text display planes? */
+	u32 cmap_blk : 1;	/* non-text planes cmap black? */
+	u32 enable_be_timer : 1; /* enable bus error timer */
+	u32 enable_be_int : 1;	/* enable bus error timer interrupt */
+	u32 no_chg_tx : 1;	/* don't change text settings */
+	u32 no_chg_ntx : 1;	/* don't change non-text settings */
+	u32 no_chg_bet : 1;	/* don't change berr timer settings */
+	u32 no_chg_bei : 1;	/* don't change berr int settings */
+	u32 init_cmap_tx : 1;	/* initialize cmap for text planes */
+	u32 cmt_chg : 1;	/* change current monitor type */
+	u32 retain_ie : 1;	/* don't allow reset to clear int enables */
+	u32 caller_bootrom : 1;	/* set only by bootrom for each call */
+	u32 caller_kernel : 1;	/* set only by kernel for each call */
+	u32 caller_other : 1;	/* set only by non-[BR/K] caller */
+	u32 pad	: 14;		/* pad to word boundary */
+	u32 future_ptr; 	/* pointer to future data */
+};
+
+struct sti_init_inptr_ext {
+	u8  config_mon_type;	/* configure to monitor type */
+	u8  pad[1];		/* pad to word boundary */
+	u16 inflight_data;	/* inflight data possible on PCI */
+	u32 future_ptr; 	/* pointer to future data */
+};
+
+struct sti_init_inptr {
+	s32 text_planes;	/* number of planes to use for text */
+	u32 ext_ptr;		 /* pointer to extended init_graph inptr data structure*/
+};
+
+
+struct sti_init_outptr {
+	s32 errno;		/* error number on failure */
+	s32 text_planes;	/* number of planes used for text */
+	u32 future_ptr; 	/* pointer to future data */
+};
+
+
+
+/* STI configuration function structs */
+
+struct sti_conf_flags {
+	u32 wait : 1;		/* should routine idle wait or not */
+	u32 pad : 31;		/* pad to word boundary */
+	u32 future_ptr; 	/* pointer to future data */
+};
+
+struct sti_conf_inptr {
+	u32 future_ptr; 	/* pointer to future data */
+};
+
+struct sti_conf_outptr_ext {
+	u32 crt_config[3];	/* hardware specific X11/OGL information */	
+	u32 crt_hdw[3];
+	u32 future_ptr;
+};
+
+struct sti_conf_outptr {
+	s32 errno;		/* error number on failure */
+	s16 onscreen_x;		/* screen width in pixels */
+	s16 onscreen_y;		/* screen height in pixels */
+	s16 offscreen_x;	/* offscreen width in pixels */
+	s16 offscreen_y;	/* offscreen height in pixels */
+	s16 total_x;		/* frame buffer width in pixels */
+	s16 total_y;		/* frame buffer height in pixels */
+	s32 bits_per_pixel;	/* bits/pixel device has configured */
+	s32 bits_used;		/* bits which can be accessed */
+	s32 planes;		/* number of fb planes in system */
+	 u8 dev_name[STI_DEV_NAME_LENGTH]; /* null terminated product name */
+	u32 attributes;		/* flags denoting attributes */
+	u32 ext_ptr;		/* pointer to future data */
+};
+
+struct sti_rom {
+	 u8 type[4];
+	 u8 res004;
+	 u8 num_mons;
+	 u8 revno[2];
+	u32 graphics_id[2];
+
+	u32 font_start;
+	u32 statesize;
+	u32 last_addr;
+	u32 region_list;
+
+	u16 reentsize;
+	u16 maxtime;
+	u32 mon_tbl_addr;
+	u32 user_data_addr;
+	u32 sti_mem_req;
+
+	u32 user_data_size;
+	u16 power;
+	 u8 bus_support;
+	 u8 ext_bus_support;
+	 u8 alt_code_type;
+	 u8 ext_dd_struct[3];
+	u32 cfb_addr;
+
+	u32 init_graph;
+	u32 state_mgmt;
+	u32 font_unpmv;
+	u32 block_move;
+	u32 self_test;
+	u32 excep_hdlr;
+	u32 inq_conf;
+	u32 set_cm_entry;
+	u32 dma_ctrl;
+	 u8 res040[7 * 4];
+	
+	u32 init_graph_addr;
+	u32 state_mgmt_addr;
+	u32 font_unp_addr;
+	u32 block_move_addr;
+	u32 self_test_addr;
+	u32 excep_hdlr_addr;
+	u32 inq_conf_addr;
+	u32 set_cm_entry_addr;
+	u32 image_unpack_addr;
+	u32 pa_risx_addrs[7];
+};
+
+struct sti_rom_font {
+	u16 first_char;
+	u16 last_char;
+	 u8 width;
+	 u8 height;
+	 u8 font_type;		/* language type */
+	 u8 bytes_per_char;
+	u32 next_font;
+	 u8 underline_height;
+	 u8 underline_pos;
+	 u8 res008[2];
+};
+
+/* sticore internal font handling */
+
+struct sti_cooked_font {
+        struct sti_rom_font *raw;
+	struct sti_cooked_font *next_font;
+};
+
+struct sti_cooked_rom {
+        struct sti_rom *raw;
+	struct sti_cooked_font *font_start;
+};
+
+/* STI font printing function structs */
+
+struct sti_font_inptr {
+	u32 font_start_addr;	/* address of font start */
+	s16 index;		/* index into font table of character */
+	u8 fg_color;		/* foreground color of character */
+	u8 bg_color;		/* background color of character */
+	s16 dest_x;		/* X location of character upper left */
+	s16 dest_y;		/* Y location of character upper left */
+	u32 future_ptr; 	/* pointer to future data */
+};
+
+struct sti_font_flags {
+	u32 wait : 1;		/* should routine idle wait or not */
+	u32 non_text : 1;	/* font unpack/move in non_text planes =1, text =0 */
+	u32 pad : 30;		/* pad to word boundary */
+	u32 future_ptr; 	/* pointer to future data */
+};
+	
+struct sti_font_outptr {
+	s32 errno;		/* error number on failure */
+	u32 future_ptr; 	/* pointer to future data */
+};
+
+/* STI blockmove structs */
+
+struct sti_blkmv_flags {
+	u32 wait : 1;		/* should routine idle wait or not */
+	u32 color : 1;		/* change color during move? */
+	u32 clear : 1;		/* clear during move? */
+	u32 non_text : 1;	/* block move in non_text planes =1, text =0 */
+	u32 pad : 28;		/* pad to word boundary */
+	u32 future_ptr; 	/* pointer to future data */
+};
+
+struct sti_blkmv_inptr {
+	u8 fg_color;		/* foreground color after move */
+	u8 bg_color;		/* background color after move */
+	s16 src_x;		/* source upper left pixel x location */
+	s16 src_y;		/* source upper left pixel y location */
+	s16 dest_x;		/* dest upper left pixel x location */
+	s16 dest_y;		/* dest upper left pixel y location */
+	s16 width;		/* block width in pixels */
+	s16 height;		/* block height in pixels */
+	u32 future_ptr; 	/* pointer to future data */
+};
+
+struct sti_blkmv_outptr {
+	s32 errno;		/* error number on failure */
+	u32 future_ptr; 	/* pointer to future data */
+};
+
+
+/* internal generic STI struct */
+
+struct sti_struct {
+	spinlock_t lock;
+		
+	/* the following fields needs to be filled in by the word/byte routines */
+	int font_width;	
+	int font_height;
+	/* char **mon_strings; */
+	int sti_mem_request;
+	u32 graphics_id[2];
+
+	struct sti_cooked_rom *rom;
+
+	unsigned long font_unpmv;
+	unsigned long block_move;
+	unsigned long init_graph;
+	unsigned long inq_conf;
+
+	/* all following fields are initialized by the generic routines */
+	int text_planes;
+	region_t regions[STI_REGION_MAX];
+	unsigned long regions_phys[STI_REGION_MAX];
+
+	struct sti_glob_cfg *glob_cfg;
+	struct sti_cooked_font *font;	/* ptr to selected font (cooked) */
+
+	struct sti_conf_outptr outptr; /* configuration */
+	struct sti_conf_outptr_ext outptr_ext;
+
+	/* PCI data structures (pg. 17ff from sti.pdf) */
+	struct pci_dev *pd;
+	u8 rm_entry[16]; /* pci region mapper array == pci config space offset */
+};
+
+
+
+/* helper functions */
+struct sti_struct *sti_init_roms(void);
+struct sti_struct *sti_get_rom(int);
+void sti_rom_copy(unsigned long base, unsigned long count, void *dest);
+struct sti_cooked_font *sti_select_font(struct sti_cooked_rom *rom,
+	    int (*search_font_fnc) (struct sti_cooked_rom *,int,int) );
+
+int sti_read_rom(int wordmode, struct sti_struct *sti,
+	    unsigned long address);
+
+
+/* FIXME: Do we have another solution for this ? */
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <asm/cacheflush.h>
+static inline void sti_flush(unsigned long from, unsigned long len)
+{
+	flush_data_cache();
+	flush_kernel_dcache_range(from, len);
+	flush_icache_range(from, from+len);
+}
+
+#endif	/* STICORE_H */
diff -Nru a/drivers/video/stifb.c b/drivers/video/stifb.c
--- a/drivers/video/stifb.c	Mon Dec  9 18:46:52 2002
+++ b/drivers/video/stifb.c	Mon Dec  9 18:46:52 2002
@@ -1,27 +1,59 @@
 /*
- * linux/drivers/video/stifb.c - Generic frame buffer driver for HP
- * workstations with STI (standard text interface) video firmware.
+ * linux/drivers/video/sti/stifb.c - 
+ * Frame buffer driver for HP workstations with STI (standard text interface) 
+ * video firmware.
  *
+ * Copyright (C) 2001-2002 Helge Deller <deller@gmx.de>
+ * Portions Copyright (C) 2001 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+ * 
  * Based on:
- * linux/drivers/video/artistfb.c -- Artist frame buffer driver
- *
+ * - linux/drivers/video/artistfb.c -- Artist frame buffer driver
  *	Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
- *
- *  based on skeletonfb, which was
+ *   - based on skeletonfb, which was
  *	Created 28 Dec 1997 by Geert Uytterhoeven
+ * - HP Xhp cfb-based X11 window driver for XFree86
+ *	(c)Copyright 1992 Hewlett-Packard Co.
+ *
+ * 
+ *  The following graphics display devices (NGLE family) are supported by this driver:
+ *
+ *  HPA4070A	known as "HCRX", a 1280x1024 color device with 8 planes
+ *  HPA4071A	known as "HCRX24", a 1280x1024 color device with 24 planes,
+ *		optionally available with a hardware accelerator as HPA4071A_Z
+ *  HPA1659A	known as "CRX", a 1280x1024 color device with 8 planes
+ *  HPA1439A	known as "CRX24", a 1280x1024 color device with 24 planes,
+ *		optionally available with a hardware accelerator.
+ *  HPA1924A	known as "GRX", a 1280x1024 grayscale device with 8 planes
+ *  HPA2269A	known as "Dual CRX", a 1280x1024 color device with 8 planes,
+ *		implements support for two displays on a single graphics card.
+ *  HP710C	internal graphics support optionally available on the HP9000s710 SPU,
+ *		supports 1280x1024 color displays with 8 planes.
+ *  HP710G	same as HP710C, 1280x1024 grayscale only
+ *  HP710L	same as HP710C, 1024x768 color only
+ *  HP712	internal graphics support on HP9000s712 SPU, supports 640x480, 
+ *		1024x768 or 1280x1024 color displays on 8 planes (Artist)
  *
  * 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.  */
+ * for more details.
+ */
 
-/*
- * Notes:
- *
- * This driver assumes that the video has been set up in 1bpp mode by
- * the firmware.  Since HP video tends to be planar rather than
- * packed-pixel this will probably work anyway even if it isn't.
+/* TODO:
+ *	- remove the static fb_info to support multiple cards
+ *	- remove the completely untested 1bpp mode
+ *	- add support for h/w acceleration
+ *	- add hardware cursor
+ *	-
  */
 
+
+/* on supported graphic devices you may:
+ * #define FALLBACK_TO_1BPP to fall back to 1 bpp, or
+ * #undef  FALLBACK_TO_1BPP to reject support for unsupported cards */
+#undef FALLBACK_TO_1BPP
+
+
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -32,179 +64,1322 @@
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/init.h>
+#include <linux/selection.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
 
 #include <video/fbcon.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb32.h>
+
+#include <asm/grfioctl.h>	/* for HP-UX compatibility */
 
-#include "sti.h"
+#include "sticore.h"
 
-static struct fb_ops stifb_ops;
+#ifdef __LP64__
+/* return virtual address */
+#define REGION_BASE(fb_info, index) \
+	(fb_info->sti->glob_cfg->region_ptrs[index] | 0xffffffff00000000)
+#else
+/* return virtual address */
+#define REGION_BASE(fb_info, index) \
+	fb_info->sti->glob_cfg->region_ptrs[index]
+#endif
+
+#define NGLEDEVDEPROM_CRT_REGION 1
+
+typedef struct {
+	__s32	video_config_reg;
+	__s32	misc_video_start;
+	__s32	horiz_timing_fmt;
+	__s32	serr_timing_fmt;
+	__s32	vert_timing_fmt;
+	__s32	horiz_state;
+	__s32	vert_state;
+	__s32	vtg_state_elements;
+	__s32	pipeline_delay;
+	__s32	misc_video_end;
+} video_setup_t;
+
+typedef struct {                  
+	__s16	sizeof_ngle_data;
+	__s16	x_size_visible;	    /* visible screen dim in pixels  */
+	__s16	y_size_visible;
+	__s16	pad2[15];
+	__s16	cursor_pipeline_delay;
+	__s16	video_interleaves;
+	__s32	pad3[11];
+} ngle_rom_t;
 
 struct stifb_info {
-	struct fb_info_gen gen;
+	struct fb_info info;
+	unsigned int id;
+	ngle_rom_t ngle_rom;
 	struct sti_struct *sti;
+	int deviceSpecificConfig;
+	struct display disp;
 };
 
-struct stifb_par {
-};
+static int stifb_force_bpp[MAX_STI_ROMS] = {0, };
 
-static struct stifb_info fb_info;
-static struct display disp;
+/* ------------------- chipset specific functions -------------------------- */
 
-int stifb_init(void);
-int stifb_setup(char*);
+/* offsets to graphic-chip internal registers */
 
-extern struct display_switch fbcon_sti;
+#define REG_1		0x000118
+#define REG_2		0x000480
+#define REG_3		0x0004a0
+#define REG_4		0x000600
+#define REG_6		0x000800
+#define REG_8		0x000820
+#define REG_9		0x000a04
+#define REG_10		0x018000
+#define REG_11		0x018004
+#define REG_12		0x01800c
+#define REG_13		0x018018
+#define REG_14  	0x01801c
+#define REG_15		0x200000
+#define REG_15b0	0x200000
+#define REG_16b1	0x200005
+#define REG_16b3	0x200007
+#define REG_21		0x200218
+#define REG_22		0x0005a0
+#define REG_23		0x0005c0
+#define REG_26		0x200118
+#define REG_27		0x200308
+#define REG_32		0x21003c
+#define REG_33		0x210040
+#define REG_34		0x200008
+#define REG_35		0x018010
+#define REG_38		0x210020
+#define REG_39		0x210120
+#define REG_40		0x210130
+#define REG_42		0x210028
+#define REG_43		0x21002c
+#define REG_44		0x210030
+#define REG_45		0x210034
+
+#define READ_BYTE(fb,reg)		__raw_readb((fb)->info.fix.mmio_start + (reg))
+#define READ_WORD(fb,reg)		__raw_readl((fb)->info.fix.mmio_start + (reg))
+#define WRITE_BYTE(value,fb,reg)	__raw_writeb((value),(fb)->info.fix.mmio_start + (reg))
+#define WRITE_WORD(value,fb,reg)	__raw_writel((value),(fb)->info.fix.mmio_start + (reg))
 
-/* ------------------- chipset specific functions -------------------------- */
+#define ENABLE	1	/* for enabling/disabling screen */	
+#define DISABLE 0
 
-static int
-sti_encode_fix(struct fb_fix_screeninfo *fix,
-	       const void *par, struct fb_info_gen *info)
+#define NGLE_LOCK(fb_info)	do { } while (0) 
+#define NGLE_UNLOCK(fb_info)	do { } while (0)
+
+static void
+SETUP_HW(struct stifb_info *fb)
 {
-	/* XXX: what about smem_len? */
-	fix->smem_start = PTR_STI(fb_info.sti->glob_cfg)->region_ptrs[1];
-	fix->type = FB_TYPE_PLANES; /* well, sort of */
+	char stat;
 
-	return 0;
+	do {
+		stat = READ_BYTE(fb, REG_15b0);
+		if (!stat)
+	    		stat = READ_BYTE(fb, REG_15b0);
+	} while (stat);
 }
 
-static int
-sti_decode_var(const struct fb_var_screeninfo *var,
-	void *par, struct fb_info_gen *info)
+
+static void
+SETUP_FB(struct stifb_info *fb)
+{	
+	unsigned int reg10_value = 0;
+	
+	SETUP_HW(fb);
+	switch (fb->id)
+	{
+		case CRT_ID_VISUALIZE_EG:
+		case S9000_ID_ARTIST:
+		case S9000_ID_A1659A:
+			reg10_value = 0x13601000;
+			break;
+		case S9000_ID_A1439A:
+			if (fb->info.var.bits_per_pixel == 32)						
+				reg10_value = 0xBBA0A000;
+			else 
+				reg10_value = 0x13601000;
+			break;
+		case S9000_ID_HCRX:
+			if (fb->info.var.bits_per_pixel == 32)
+				reg10_value = 0xBBA0A000;
+			else					
+				reg10_value = 0x13602000;
+			break;
+		case S9000_ID_TIMBER:
+		case CRX24_OVERLAY_PLANES:
+			reg10_value = 0x13602000;
+			break;
+	}
+	if (reg10_value)
+		WRITE_WORD(reg10_value, fb, REG_10);
+	WRITE_WORD(0x83000300, fb, REG_14);
+	SETUP_HW(fb);
+	WRITE_BYTE(1, fb, REG_16b1);
+}
+
+static void
+START_IMAGE_COLORMAP_ACCESS(struct stifb_info *fb)
 {
-	return 0;
+	SETUP_HW(fb);
+	WRITE_WORD(0xBBE0F000, fb, REG_10);
+	WRITE_WORD(0x03000300, fb, REG_14);
+	WRITE_WORD(~0, fb, REG_13);
 }
 
-static int
-sti_encode_var(struct fb_var_screeninfo *var,
-	       const void *par, struct fb_info_gen *info)
+static void
+WRITE_IMAGE_COLOR(struct stifb_info *fb, int index, int color) 
 {
-	var->xres = PTR_STI(fb_info.sti->glob_cfg)->onscreen_x;
-	var->yres = PTR_STI(fb_info.sti->glob_cfg)->onscreen_y;
-	var->xres_virtual = PTR_STI(fb_info.sti->glob_cfg)->total_x;
-	var->yres_virtual = PTR_STI(fb_info.sti->glob_cfg)->total_y;
-	var->xoffset = var->yoffset = 0;
+	SETUP_HW(fb);
+	WRITE_WORD(((0x100+index)<<2), fb, REG_3);
+	WRITE_WORD(color, fb, REG_4);
+}
 
-	var->bits_per_pixel = 1;
-	var->grayscale = 0;
+static void
+FINISH_IMAGE_COLORMAP_ACCESS(struct stifb_info *fb) 
+{		
+	WRITE_WORD(0x400, fb, REG_2);
+	if (fb->info.var.bits_per_pixel == 32) {
+		WRITE_WORD(0x83000100, fb, REG_1);
+	} else {
+		if (fb->id == S9000_ID_ARTIST || fb->id == CRT_ID_VISUALIZE_EG)
+			WRITE_WORD(0x80000100, fb, REG_26);
+		else							
+			WRITE_WORD(0x80000100, fb, REG_1);
+	}
+	SETUP_FB(fb);
+}
 
-	return 0;
+static void
+SETUP_RAMDAC(struct stifb_info *fb) 
+{
+	SETUP_HW(fb);
+	WRITE_WORD(0x04000000, fb, 0x1020);
+	WRITE_WORD(0xff000000, fb, 0x1028);
+}
+
+static void 
+CRX24_SETUP_RAMDAC(struct stifb_info *fb) 
+{
+	SETUP_HW(fb);
+	WRITE_WORD(0x04000000, fb, 0x1000);
+	WRITE_WORD(0x02000000, fb, 0x1004);
+	WRITE_WORD(0xff000000, fb, 0x1008);
+	WRITE_WORD(0x05000000, fb, 0x1000);
+	WRITE_WORD(0x02000000, fb, 0x1004);
+	WRITE_WORD(0x03000000, fb, 0x1008);
+}
+
+#if 0
+static void 
+HCRX_SETUP_RAMDAC(struct stifb_info *fb)
+{
+	WRITE_WORD(0xffffffff, fb, REG_32);
+}
+#endif
+
+static void 
+CRX24_SET_OVLY_MASK(struct stifb_info *fb)
+{
+	SETUP_HW(fb);
+	WRITE_WORD(0x13a02000, fb, REG_11);
+	WRITE_WORD(0x03000300, fb, REG_14);
+	WRITE_WORD(0x000017f0, fb, REG_3);
+	WRITE_WORD(0xffffffff, fb, REG_13);
+	WRITE_WORD(0xffffffff, fb, REG_22);
+	WRITE_WORD(0x00000000, fb, REG_23);
 }
 
 static void
-sti_get_par(void *par, struct fb_info_gen *info)
+ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable)
 {
+	unsigned int value = enable ? 0x43000000 : 0x03000000;
+        SETUP_HW(fb);
+        WRITE_WORD(0x06000000,	fb, 0x1030);
+        WRITE_WORD(value, 	fb, 0x1038);
+}
+
+static void 
+CRX24_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable)
+{
+	unsigned int value = enable ? 0x10000000 : 0x30000000;
+	SETUP_HW(fb);
+	WRITE_WORD(0x01000000,	fb, 0x1000);
+	WRITE_WORD(0x02000000,	fb, 0x1004);
+	WRITE_WORD(value,	fb, 0x1008);
+}
+
+static void
+ARTIST_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable) 
+{
+	u32 DregsMiscVideo = REG_21;
+	u32 DregsMiscCtl = REG_27;
+	
+	SETUP_HW(fb);
+	if (enable) {
+	  WRITE_WORD(READ_WORD(fb, DregsMiscVideo) | 0x0A000000, fb, DregsMiscVideo);
+	  WRITE_WORD(READ_WORD(fb, DregsMiscCtl)   | 0x00800000, fb, DregsMiscCtl);
+	} else {
+	  WRITE_WORD(READ_WORD(fb, DregsMiscVideo) & ~0x0A000000, fb, DregsMiscVideo);
+	  WRITE_WORD(READ_WORD(fb, DregsMiscCtl)   & ~0x00800000, fb, DregsMiscCtl);
+	}
+}
+
+#define GET_ROMTABLE_INDEX(fb) \
+	(READ_BYTE(fb, REG_16b3) - 1)
+
+#define HYPER_CONFIG_PLANES_24 0x00000100
+	
+#define IS_24_DEVICE(fb) \
+	(fb->deviceSpecificConfig & HYPER_CONFIG_PLANES_24)
+
+#define IS_888_DEVICE(fb) \
+	(!(IS_24_DEVICE(fb)))
+
+#define GET_FIFO_SLOTS(fb, cnt, numslots)			\
+{	while (cnt < numslots) 					\
+		cnt = READ_WORD(fb, REG_34);	\
+	cnt -= numslots;					\
+}
+
+#define	    IndexedDcd	0	/* Pixel data is indexed (pseudo) color */
+#define	    Otc04	2	/* Pixels in each longword transfer (4) */
+#define	    Otc32	5	/* Pixels in each longword transfer (32) */
+#define	    Ots08	3	/* Each pixel is size (8)d transfer (1) */
+#define	    OtsIndirect	6	/* Each bit goes through FG/BG color(8) */
+#define	    AddrLong	5	/* FB address is Long aligned (pixel) */
+#define	    BINovly	0x2	/* 8 bit overlay */
+#define	    BINapp0I	0x0	/* Application Buffer 0, Indexed */
+#define	    BINapp1I	0x1	/* Application Buffer 1, Indexed */
+#define	    BINapp0F8	0xa	/* Application Buffer 0, Fractional 8-8-8 */
+#define	    BINattr	0xd	/* Attribute Bitmap */
+#define	    RopSrc 	0x3
+#define	    BitmapExtent08  3	/* Each write hits ( 8) bits in depth */
+#define	    BitmapExtent32  5	/* Each write hits (32) bits in depth */
+#define	    DataDynamic	    0	/* Data register reloaded by direct access */
+#define	    MaskDynamic	    1	/* Mask register reloaded by direct access */
+#define	    MaskOtc	    0	/* Mask contains Object Count valid bits */
+
+#define MaskAddrOffset(offset) (offset)
+#define StaticReg(en) (en)
+#define BGx(en) (en)
+#define FGx(en) (en)
+
+#define BAJustPoint(offset) (offset)
+#define BAIndexBase(base) (base)
+#define BA(F,C,S,A,J,B,I) \
+	(((F)<<31)|((C)<<27)|((S)<<24)|((A)<<21)|((J)<<16)|((B)<<12)|(I))
+
+#define IBOvals(R,M,X,S,D,L,B,F) \
+	(((R)<<8)|((M)<<16)|((X)<<24)|((S)<<29)|((D)<<28)|((L)<<31)|((B)<<1)|(F))
+
+#define NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb, val) \
+	WRITE_WORD(val, fb, REG_14)
+
+#define NGLE_QUICK_SET_DST_BM_ACCESS(fb, val) \
+	WRITE_WORD(val, fb, REG_11)
+
+#define NGLE_QUICK_SET_CTL_PLN_REG(fb, val) \
+	WRITE_WORD(val, fb, REG_12)
+
+#define NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, plnmsk32) \
+	WRITE_WORD(plnmsk32, fb, REG_13)
+
+#define NGLE_REALLY_SET_IMAGE_FG_COLOR(fb, fg32) \
+	WRITE_WORD(fg32, fb, REG_35)
+
+#define NGLE_SET_TRANSFERDATA(fb, val) \
+	WRITE_WORD(val, fb, REG_8)
+
+#define NGLE_SET_DSTXY(fb, val) \
+	WRITE_WORD(val, fb, REG_6)
+
+#define NGLE_LONG_FB_ADDRESS(fbaddrbase, x, y) (		\
+	(u32) (fbaddrbase) +				\
+	    (	(unsigned int)  ( (y) << 13      ) |		\
+		(unsigned int)  ( (x) << 2       )	)	\
+	)
+
+#define NGLE_BINC_SET_DSTADDR(fb, addr) \
+	WRITE_WORD(addr, fb, REG_3)
+
+#define NGLE_BINC_SET_SRCADDR(fb, addr) \
+	WRITE_WORD(addr, fb, REG_2)
+
+#define NGLE_BINC_SET_DSTMASK(fb, mask) \
+	WRITE_WORD(mask, fb, REG_22)
+
+#define NGLE_BINC_WRITE32(fb, data32) \
+	WRITE_WORD(data32, fb, REG_23)
+
+#define START_COLORMAPLOAD(fb, cmapBltCtlData32) \
+	WRITE_WORD((cmapBltCtlData32), fb, REG_38)
+
+#define SET_LENXY_START_RECFILL(fb, lenxy) \
+	WRITE_WORD(lenxy, fb, REG_9)
+
+static void
+HYPER_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable)
+{
+	u32 DregsHypMiscVideo = REG_33;
+	unsigned int value;
+	SETUP_HW(fb);
+	value = READ_WORD(fb, DregsHypMiscVideo);
+	if (enable)
+		value |= 0x0A000000;
+	else
+		value &= ~0x0A000000;
+	WRITE_WORD(value, fb, DregsHypMiscVideo);
+}
+
+
+/* BufferNumbers used by SETUP_ATTR_ACCESS() */
+#define BUFF0_CMAP0	0x00001e02
+#define BUFF1_CMAP0	0x02001e02
+#define BUFF1_CMAP3	0x0c001e02
+#define ARTIST_CMAP0	0x00000102
+#define HYPER_CMAP8	0x00000100
+#define HYPER_CMAP24	0x00000800
+
+static void
+SETUP_ATTR_ACCESS(struct stifb_info *fb, unsigned BufferNumber)
+{
+	SETUP_HW(fb);
+	WRITE_WORD(0x2EA0D000, fb, REG_11);
+	WRITE_WORD(0x23000302, fb, REG_14);
+	WRITE_WORD(BufferNumber, fb, REG_12);
+	WRITE_WORD(0xffffffff, fb, REG_8);
 }
 
 static void
-sti_set_par(const void *par, struct fb_info_gen *info)
+SET_ATTR_SIZE(struct stifb_info *fb, int width, int height) 
 {
+	WRITE_WORD(0x00000000, fb, REG_6);
+	WRITE_WORD((width<<16) | height, fb, REG_9);
+	WRITE_WORD(0x05000000, fb, REG_6);
+	WRITE_WORD(0x00040001, fb, REG_9);
 }
 
+static void
+FINISH_ATTR_ACCESS(struct stifb_info *fb) 
+{
+	SETUP_HW(fb);
+	WRITE_WORD(0x00000000, fb, REG_12);
+}
+
+static void
+elkSetupPlanes(struct stifb_info *fb)
+{
+	SETUP_RAMDAC(fb);
+	SETUP_FB(fb);
+}
+
+static void 
+ngleSetupAttrPlanes(struct stifb_info *fb, int BufferNumber)
+{
+	SETUP_ATTR_ACCESS(fb, BufferNumber);
+	SET_ATTR_SIZE(fb, fb->info.var.xres, fb->info.var.yres);
+	FINISH_ATTR_ACCESS(fb);
+	SETUP_FB(fb);
+}
+
+
+static void
+rattlerSetupPlanes(struct stifb_info *fb)
+{
+	CRX24_SETUP_RAMDAC(fb);
+    
+	/* replacement for: SETUP_FB(fb, CRX24_OVERLAY_PLANES); */
+	WRITE_WORD(0x83000300, fb, REG_14);
+	SETUP_HW(fb);
+	WRITE_BYTE(1, fb, REG_16b1);
+
+	/* XXX: replace by fb_setmem(), smem_start or screen_base ? */
+	memset_io(fb->info.fix.smem_start, 0xff,
+		fb->info.var.yres*fb->info.fix.line_length);
+    
+	CRX24_SET_OVLY_MASK(fb);
+	SETUP_FB(fb);
+}
+
+
+#define HYPER_CMAP_TYPE				0
+#define NGLE_CMAP_INDEXED0_TYPE			0
+#define NGLE_CMAP_OVERLAY_TYPE			3
+
+/* typedef of LUT (Colormap) BLT Control Register */
+typedef union	/* Note assumption that fields are packed left-to-right */
+{	u32 all;
+	struct
+	{
+		unsigned enable              :  1;
+		unsigned waitBlank           :  1;
+		unsigned reserved1           :  4;
+		unsigned lutOffset           : 10;   /* Within destination LUT */
+		unsigned lutType             :  2;   /* Cursor, image, overlay */
+		unsigned reserved2           :  4;
+		unsigned length              : 10;
+	} fields;
+} NgleLutBltCtl;
+
+
+#if 0
+static NgleLutBltCtl
+setNgleLutBltCtl(struct stifb_info *fb, int offsetWithinLut, int length)
+{
+	NgleLutBltCtl lutBltCtl;
+
+	/* set enable, zero reserved fields */
+	lutBltCtl.all           = 0x80000000;
+	lutBltCtl.fields.length = length;
+
+	switch (fb->id) 
+	{
+	case S9000_ID_A1439A:		/* CRX24 */
+		if (fb->var.bits_per_pixel == 8) {
+			lutBltCtl.fields.lutType = NGLE_CMAP_OVERLAY_TYPE;
+			lutBltCtl.fields.lutOffset = 0;
+		} else {
+			lutBltCtl.fields.lutType = NGLE_CMAP_INDEXED0_TYPE;
+			lutBltCtl.fields.lutOffset = 0 * 256;
+		}
+		break;
+		
+	case S9000_ID_ARTIST:
+		lutBltCtl.fields.lutType = NGLE_CMAP_INDEXED0_TYPE;
+		lutBltCtl.fields.lutOffset = 0 * 256;
+		break;
+		
+	default:
+		lutBltCtl.fields.lutType = NGLE_CMAP_INDEXED0_TYPE;
+		lutBltCtl.fields.lutOffset = 0;
+		break;
+	}
+
+	/* Offset points to start of LUT.  Adjust for within LUT */
+	lutBltCtl.fields.lutOffset += offsetWithinLut;
+
+	return lutBltCtl;
+}
+#endif
+
+static NgleLutBltCtl
+setHyperLutBltCtl(struct stifb_info *fb, int offsetWithinLut, int length) 
+{
+	NgleLutBltCtl lutBltCtl;
+
+	/* set enable, zero reserved fields */
+	lutBltCtl.all = 0x80000000;
+
+	lutBltCtl.fields.length = length;
+	lutBltCtl.fields.lutType = HYPER_CMAP_TYPE;
+
+	/* Expect lutIndex to be 0 or 1 for image cmaps, 2 or 3 for overlay cmaps */
+	if (fb->info.var.bits_per_pixel == 8)
+		lutBltCtl.fields.lutOffset = 2 * 256;
+	else
+		lutBltCtl.fields.lutOffset = 0 * 256;
+
+	/* Offset points to start of LUT.  Adjust for within LUT */
+	lutBltCtl.fields.lutOffset += offsetWithinLut;
+
+	return lutBltCtl;
+}
+
+
+static void hyperUndoITE(struct stifb_info *fb)
+{
+	int nFreeFifoSlots = 0;
+	u32 fbAddr;
+
+	NGLE_LOCK(fb);
+
+	GET_FIFO_SLOTS(fb, nFreeFifoSlots, 1);
+	WRITE_WORD(0xffffffff, fb, REG_32);
+
+	/* Write overlay transparency mask so only entry 255 is transparent */
+
+	/* Hardware setup for full-depth write to "magic" location */
+	GET_FIFO_SLOTS(fb, nFreeFifoSlots, 7);
+	NGLE_QUICK_SET_DST_BM_ACCESS(fb, 
+		BA(IndexedDcd, Otc04, Ots08, AddrLong,
+		BAJustPoint(0), BINovly, BAIndexBase(0)));
+	NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb,
+		IBOvals(RopSrc, MaskAddrOffset(0),
+		BitmapExtent08, StaticReg(0),
+		DataDynamic, MaskOtc, BGx(0), FGx(0)));
+
+	/* Now prepare to write to the "magic" location */
+	fbAddr = NGLE_LONG_FB_ADDRESS(0, 1532, 0);
+	NGLE_BINC_SET_DSTADDR(fb, fbAddr);
+	NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, 0xffffff);
+	NGLE_BINC_SET_DSTMASK(fb, 0xffffffff);
+
+	/* Finally, write a zero to clear the mask */
+	NGLE_BINC_WRITE32(fb, 0);
+
+	NGLE_UNLOCK(fb);
+}
+
+static void 
+ngleDepth8_ClearImagePlanes(struct stifb_info *fb)
+{
+	/* FIXME! */
+}
+
+static void 
+ngleDepth24_ClearImagePlanes(struct stifb_info *fb)
+{
+	/* FIXME! */
+}
+
+static void
+ngleResetAttrPlanes(struct stifb_info *fb, unsigned int ctlPlaneReg)
+{
+	int nFreeFifoSlots = 0;
+	u32 packed_dst;
+	u32 packed_len;
+
+	NGLE_LOCK(fb);
+
+	GET_FIFO_SLOTS(fb, nFreeFifoSlots, 4);
+	NGLE_QUICK_SET_DST_BM_ACCESS(fb, 
+				     BA(IndexedDcd, Otc32, OtsIndirect,
+					AddrLong, BAJustPoint(0),
+					BINattr, BAIndexBase(0)));
+	NGLE_QUICK_SET_CTL_PLN_REG(fb, ctlPlaneReg);
+	NGLE_SET_TRANSFERDATA(fb, 0xffffffff);
+
+	NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb,
+				       IBOvals(RopSrc, MaskAddrOffset(0),
+					       BitmapExtent08, StaticReg(1),
+					       DataDynamic, MaskOtc,
+					       BGx(0), FGx(0)));
+	packed_dst = 0;
+	packed_len = (fb->info.var.xres << 16) | fb->info.var.yres;
+	GET_FIFO_SLOTS(fb, nFreeFifoSlots, 2);
+	NGLE_SET_DSTXY(fb, packed_dst);
+	SET_LENXY_START_RECFILL(fb, packed_len);
+
+	/*
+	 * In order to work around an ELK hardware problem (Buffy doesn't
+	 * always flush it's buffers when writing to the attribute
+	 * planes), at least 4 pixels must be written to the attribute
+	 * planes starting at (X == 1280) and (Y != to the last Y written
+	 * by BIF):
+	 */
+
+	if (fb->id == S9000_ID_A1659A) {   /* ELK_DEVICE_ID */
+		/* It's safe to use scanline zero: */
+		packed_dst = (1280 << 16);
+		GET_FIFO_SLOTS(fb, nFreeFifoSlots, 2);
+		NGLE_SET_DSTXY(fb, packed_dst);
+		packed_len = (4 << 16) | 1;
+		SET_LENXY_START_RECFILL(fb, packed_len);
+	}   /* ELK Hardware Kludge */
+
+	/**** Finally, set the Control Plane Register back to zero: ****/
+	GET_FIFO_SLOTS(fb, nFreeFifoSlots, 1);
+	NGLE_QUICK_SET_CTL_PLN_REG(fb, 0);
+	
+	NGLE_UNLOCK(fb);
+}
+    
+static void
+ngleClearOverlayPlanes(struct stifb_info *fb, int mask, int data)
+{
+	int nFreeFifoSlots = 0;
+	u32 packed_dst;
+	u32 packed_len;
+    
+	NGLE_LOCK(fb);
+
+	/* Hardware setup */
+	GET_FIFO_SLOTS(fb, nFreeFifoSlots, 8);
+	NGLE_QUICK_SET_DST_BM_ACCESS(fb, 
+				     BA(IndexedDcd, Otc04, Ots08, AddrLong,
+					BAJustPoint(0), BINovly, BAIndexBase(0)));
+
+        NGLE_SET_TRANSFERDATA(fb, 0xffffffff);  /* Write foreground color */
+
+        NGLE_REALLY_SET_IMAGE_FG_COLOR(fb, data);
+        NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, mask);
+    
+        packed_dst = 0;
+        packed_len = (fb->info.var.xres << 16) | fb->info.var.yres;
+        NGLE_SET_DSTXY(fb, packed_dst);
+    
+        /* Write zeroes to overlay planes */		       
+	NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb,
+				       IBOvals(RopSrc, MaskAddrOffset(0),
+					       BitmapExtent08, StaticReg(0),
+					       DataDynamic, MaskOtc, BGx(0), FGx(0)));
+		       
+        SET_LENXY_START_RECFILL(fb, packed_len);
+
+	NGLE_UNLOCK(fb);
+}
+
+static void 
+hyperResetPlanes(struct stifb_info *fb, int enable)
+{
+	unsigned int controlPlaneReg;
+
+	NGLE_LOCK(fb);
+
+	if (IS_24_DEVICE(fb))
+		if (fb->info.var.bits_per_pixel == 32)
+			controlPlaneReg = 0x04000F00;
+		else
+			controlPlaneReg = 0x00000F00;   /* 0x00000800 should be enought, but lets clear all 4 bits */
+	else
+		controlPlaneReg = 0x00000F00; /* 0x00000100 should be enought, but lets clear all 4 bits */
+
+	switch (enable) {
+	case 1:		/* ENABLE */
+		/* clear screen */
+		if (IS_24_DEVICE(fb))
+			ngleDepth24_ClearImagePlanes(fb);
+		else
+			ngleDepth8_ClearImagePlanes(fb);
+
+		/* Paint attribute planes for default case.
+		 * On Hyperdrive, this means all windows using overlay cmap 0. */
+		ngleResetAttrPlanes(fb, controlPlaneReg);
+
+		/* clear overlay planes */
+	        ngleClearOverlayPlanes(fb, 0xff, 255);
+
+		/**************************************************
+		 ** Also need to counteract ITE settings 
+		 **************************************************/
+		hyperUndoITE(fb);
+		break;
+
+	case 0:		/* DISABLE */
+		/* clear screen */
+		if (IS_24_DEVICE(fb))
+			ngleDepth24_ClearImagePlanes(fb);
+		else
+			ngleDepth8_ClearImagePlanes(fb);
+		ngleResetAttrPlanes(fb, controlPlaneReg);
+		ngleClearOverlayPlanes(fb, 0xff, 0);
+		break;
+
+	case -1:	/* RESET */
+		hyperUndoITE(fb);
+		ngleResetAttrPlanes(fb, controlPlaneReg);
+		break;
+    	}
+	
+	NGLE_UNLOCK(fb);
+}
+
+/* Return pointer to in-memory structure holding ELK device-dependent ROM values. */
+
+static void 
+ngleGetDeviceRomData(struct stifb_info *fb)
+{
+#if 0
+XXX: FIXME: !!!
+	int	*pBytePerLongDevDepData;/* data byte == LSB */
+	int 	*pRomTable;
+	NgleDevRomData	*pPackedDevRomData;
+	int	sizePackedDevRomData = sizeof(*pPackedDevRomData);
+	char	*pCard8;
+	int	i;
+	char	*mapOrigin = NULL;
+    
+	int romTableIdx;
+
+	pPackedDevRomData = fb->ngle_rom;
+
+	SETUP_HW(fb);
+	if (fb->id == S9000_ID_ARTIST) {
+		pPackedDevRomData->cursor_pipeline_delay = 4;
+		pPackedDevRomData->video_interleaves     = 4;
+	} else {
+		/* Get pointer to unpacked byte/long data in ROM */
+		pBytePerLongDevDepData = fb->sti->regions[NGLEDEVDEPROM_CRT_REGION];
+
+		/* Tomcat supports several resolutions: 1280x1024, 1024x768, 640x480 */
+		if (fb->id == S9000_ID_TOMCAT)
+	{
+	    /*  jump to the correct ROM table  */
+	    GET_ROMTABLE_INDEX(romTableIdx);
+	    while  (romTableIdx > 0)
+	    {
+		pCard8 = (Card8 *) pPackedDevRomData;
+		pRomTable = pBytePerLongDevDepData;
+		/* Pack every fourth byte from ROM into structure */
+		for (i = 0; i < sizePackedDevRomData; i++)
+		{
+		    *pCard8++ = (Card8) (*pRomTable++);
+		}
+
+		pBytePerLongDevDepData = (Card32 *)
+			((Card8 *) pBytePerLongDevDepData +
+			       pPackedDevRomData->sizeof_ngle_data);
+
+		romTableIdx--;
+	    }
+	}
+
+	pCard8 = (Card8 *) pPackedDevRomData;
+
+	/* Pack every fourth byte from ROM into structure */
+	for (i = 0; i < sizePackedDevRomData; i++)
+	{
+	    *pCard8++ = (Card8) (*pBytePerLongDevDepData++);
+	}
+    }
+
+    SETUP_FB(fb);
+#endif
+}
+
+
+#define HYPERBOWL_MODE_FOR_8_OVER_88_LUT0_NO_TRANSPARENCIES	4
+#define HYPERBOWL_MODE01_8_24_LUT0_TRANSPARENT_LUT1_OPAQUE	8
+#define HYPERBOWL_MODE01_8_24_LUT0_OPAQUE_LUT1_OPAQUE		10
+#define HYPERBOWL_MODE2_8_24					15
+
+/* HCRX specific boot-time initialization */
+static void __init
+SETUP_HCRX(struct stifb_info *fb)
+{
+	int	hyperbowl;
+        int	nFreeFifoSlots = 0;
+
+	if (fb->id != S9000_ID_HCRX)
+		return;
+
+	/* Initialize Hyperbowl registers */
+	GET_FIFO_SLOTS(fb, nFreeFifoSlots, 7);
+	
+	if (IS_24_DEVICE(fb)) {
+		hyperbowl = (fb->info.var.bits_per_pixel == 32) ?
+			HYPERBOWL_MODE01_8_24_LUT0_TRANSPARENT_LUT1_OPAQUE :
+			HYPERBOWL_MODE01_8_24_LUT0_OPAQUE_LUT1_OPAQUE;
+
+		/* First write to Hyperbowl must happen twice (bug) */
+		WRITE_WORD(hyperbowl, fb, REG_40);
+		WRITE_WORD(hyperbowl, fb, REG_40);
+		
+		WRITE_WORD(HYPERBOWL_MODE2_8_24, fb, REG_39);
+		
+		WRITE_WORD(0x014c0148, fb, REG_42); /* Set lut 0 to be the direct color */
+		WRITE_WORD(0x404c4048, fb, REG_43);
+		WRITE_WORD(0x034c0348, fb, REG_44);
+		WRITE_WORD(0x444c4448, fb, REG_45);
+	} else {
+		hyperbowl = HYPERBOWL_MODE_FOR_8_OVER_88_LUT0_NO_TRANSPARENCIES;
+
+		/* First write to Hyperbowl must happen twice (bug) */
+		WRITE_WORD(hyperbowl, fb, REG_40);
+		WRITE_WORD(hyperbowl, fb, REG_40);
+
+		WRITE_WORD(0x00000000, fb, REG_42);
+		WRITE_WORD(0x00000000, fb, REG_43);
+		WRITE_WORD(0x00000000, fb, REG_44);
+		WRITE_WORD(0x444c4048, fb, REG_45);
+	}
+}
+
+
+/* ------------------- driver specific functions --------------------------- */
+
+
 static int
-sti_getcolreg(unsigned regno, unsigned *red, unsigned *green,
-	      unsigned *blue, unsigned *transp, struct fb_info *info)
+stifb_setcolreg(u_int regno, u_int red, u_int green,
+	      u_int blue, u_int transp, struct fb_info *info)
 {
+	struct stifb_info *fb = (struct stifb_info *) info;
+	u32 color;
+
+	if (regno >= 256)  /* no. of hw registers */
+		return 1;
+	
+	START_IMAGE_COLORMAP_ACCESS(fb);
+	
+	if (fb->info.var.grayscale) {
+		/* gray = 0.30*R + 0.59*G + 0.11*B */
+		color = ((red * 77) +
+			 (green * 151) +
+			 (blue * 28)) >> 8;
+	} else {
+		color = ((red << 16) |
+			 (green << 8) |
+			 (blue));
+	}
+
+	WRITE_IMAGE_COLOR(fb, regno, color);
+	
+	if (fb->id == S9000_ID_HCRX) {
+		NgleLutBltCtl lutBltCtl;
+
+		lutBltCtl = setHyperLutBltCtl(fb,
+				0,	/* Offset w/i LUT */
+				256);	/* Load entire LUT */
+		NGLE_BINC_SET_SRCADDR(fb,
+				NGLE_LONG_FB_ADDRESS(0, 0x100, 0)); 
+				/* 0x100 is same as used in WRITE_IMAGE_COLOR() */
+		START_COLORMAPLOAD(fb, lutBltCtl.all);
+		SETUP_FB(fb);
+	} else {
+		/* cleanup colormap hardware */
+		FINISH_IMAGE_COLORMAP_ACCESS(fb);
+	}
+
 	return 0;
 }
 
+#if 0
 static void
-sti_set_disp(const void *par, struct display *disp,
-	     struct fb_info_gen *info)
+stifb_loadcmap(struct stifb_info *fb)
 {
-	disp->dispsw = &fbcon_sti;
+	u32 color;
+	int i;
+
+	if (!fb->cmap_reload)
+		return;
+
+	START_IMAGE_COLORMAP_ACCESS(fb);
+	for (i = 0; i < 256; i++) {
+		if (fb->info.var.bits_per_pixel > 8) {
+			color = (i << 16) | (i << 8) | i;
+		} else {
+			if (fb->info.var.grayscale) {
+				/* gray = 0.30*R + 0.59*G + 0.11*B */
+				color = ((fb->palette[i].red * 77) +
+					 (fb->palette[i].green * 151) +
+					 (fb->palette[i].blue * 28)) >> 8;
+			} else {
+				color = ((fb->palette[i].red << 16) |
+					 (fb->palette[i].green << 8) |
+					 (fb->palette[i].blue));
+			}
+		}
+		WRITE_IMAGE_COLOR(fb, i, color);
+	}
+	if (fb->id == S9000_ID_HCRX) {
+		NgleLutBltCtl lutBltCtl;
+
+		lutBltCtl = setHyperLutBltCtl(fb,
+				0,	/* Offset w/i LUT */
+				256);	/* Load entire LUT */
+		NGLE_BINC_SET_SRCADDR(fb,
+				NGLE_LONG_FB_ADDRESS(0, 0x100, 0)); 
+				/* 0x100 is same as used in WRITE_IMAGE_COLOR() */
+		START_COLORMAPLOAD(fb, lutBltCtl.all);
+		SETUP_FB(fb);
+	} else {
+		/* cleanup colormap hardware */
+		FINISH_IMAGE_COLORMAP_ACCESS(fb);
+	}
+	fb->cmap_reload = 0;
 }
+#endif
 
-static void
-sti_detect(void)
+static int
+stifb_blank(int blank_mode, struct fb_info *info)
 {
+	struct stifb_info *fb = (struct stifb_info *) info;
+	int enable = (blank_mode == 0) ? ENABLE : DISABLE;
+
+	switch (fb->id) {
+	case S9000_ID_A1439A:
+		CRX24_ENABLE_DISABLE_DISPLAY(fb, enable);
+		break;
+	case CRT_ID_VISUALIZE_EG:
+	case S9000_ID_ARTIST:
+		ARTIST_ENABLE_DISABLE_DISPLAY(fb, enable);
+		break;
+	case S9000_ID_HCRX:
+		HYPER_ENABLE_DISABLE_DISPLAY(fb, enable);
+		break;
+	case S9000_ID_A1659A:;	/* fall through */
+	case S9000_ID_TIMBER:;
+	case CRX24_OVERLAY_PLANES:;
+	default:
+		ENABLE_DISABLE_DISPLAY(fb, enable);
+		break;
+	}
+	
+	SETUP_FB(fb);
+	return 0;
 }
 
+static void __init
+stifb_init_display(struct stifb_info *fb)
+{
+	int id = fb->id;
+
+	SETUP_FB(fb);
+
+	/* HCRX specific initialization */
+	SETUP_HCRX(fb);
+	
+	/*
+	if (id == S9000_ID_HCRX)
+		hyperInitSprite(fb);
+	else
+		ngleInitSprite(fb);
+	*/
+	
+	/* Initialize the image planes. */ 
+        switch (id) {
+	 case S9000_ID_HCRX:
+	    hyperResetPlanes(fb, ENABLE);
+	    break;
+	 case S9000_ID_A1439A:
+	    rattlerSetupPlanes(fb);
+	    break;
+	 case S9000_ID_A1659A:
+	 case S9000_ID_ARTIST:
+	 case CRT_ID_VISUALIZE_EG:
+	    elkSetupPlanes(fb);
+	    break;
+	}
+
+	/* Clear attribute planes on non HCRX devices. */
+        switch (id) {
+	 case S9000_ID_A1659A:
+	 case S9000_ID_A1439A:
+	    if (fb->info.var.bits_per_pixel == 32)
+		ngleSetupAttrPlanes(fb, BUFF1_CMAP3);
+	    else {
+		ngleSetupAttrPlanes(fb, BUFF1_CMAP0);
+	    }
+	    if (id == S9000_ID_A1439A)
+		ngleClearOverlayPlanes(fb, 0xff, 0);
+	    break;
+	 case S9000_ID_ARTIST:
+	 case CRT_ID_VISUALIZE_EG:
+	    if (fb->info.var.bits_per_pixel == 32)
+		ngleSetupAttrPlanes(fb, BUFF1_CMAP3);
+	    else {
+		ngleSetupAttrPlanes(fb, ARTIST_CMAP0);
+	    }
+	    break;
+	}
+	stifb_blank(0, (struct fb_info *)fb);	/* 0=enable screen */
+
+	SETUP_FB(fb);
+}
+
+
 /* ------------ Interfaces to hardware functions ------------ */
 
-struct fbgen_hwswitch sti_switch = {
-	.detect =	sti_detect,
-	.encode_fix =	sti_encode_fix,
-	.decode_var =	sti_decode_var,
-	.encode_var =	sti_encode_var,
-	.get_par =	sti_get_par,
-	.set_par =	sti_set_par,
-	.getcolreg =	sti_getcolreg,
-	.set_disp =	sti_set_disp
+static struct fb_ops stifb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_set_var	= gen_set_var,
+	.fb_get_cmap	= gen_get_cmap,
+	.fb_set_cmap	= gen_set_cmap,
+	.fb_setcolreg	= stifb_setcolreg,
+	/* .fb_pan_display = stifb_pan_display, */
+	.fb_blank	= stifb_blank,
+
+	/*
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit, 
+	*/
 };
 
 
-/* ------------ Hardware Independent Functions ------------ */
-
     /*
      *  Initialization
      */
 
 int __init
-stifb_init(void)
+stifb_init_fb(struct sti_struct *sti, int force_bpp)
 {
-	printk("searching for word mode STI ROMs\n");
-	/* XXX: in the future this will return a list of ROMs */
-	if ((fb_info.sti = sti_init_roms()) == NULL)
-		return -ENXIO;
-
-	fb_info.gen.info.node = NODEV;
-	fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
-	fb_info.gen.info.fbops = &stifb_ops;
-	fb_info.gen.info.disp = &disp;
-	fb_info.gen.info.changevar = NULL;
-	fb_info.gen.info.switch_con = &fbgen_switch;
-	fb_info.gen.info.updatevar = &fbgen_update_var;
-	strcpy(fb_info.gen.info.modename, "STI Generic");
-	fb_info.gen.fbhw = &sti_switch;
-	fb_info.gen.fbhw->detect();
-	fb_info.gen.info.screen_base = 
-		(void *) PTR_STI(fb_info.sti->glob_cfg)->region_ptrs[1];
-	/* This should give a reasonable default video mode */
-	fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
-	fbgen_do_set_var(&disp.var, 1, &fb_info.gen);
-	fbgen_set_disp(-1, &fb_info.gen);
-	do_install_cmap(0, &fb_info.gen);
-	pdc_console_die();
-	if (register_framebuffer(&fb_info.gen.info) < 0)
-		return -EINVAL;
-
-	printk(KERN_INFO "fb%d: %s frame buffer device\n",
-		GET_FB_IDX(fb_info.gen.info.node), fb_info.gen.info.modename);
+	struct fb_fix_screeninfo *fix;
+	struct fb_var_screeninfo *var;
+	struct display *disp;
+	struct display_switch *dispsw;
+	struct stifb_info *fb;
+	struct fb_info *info;
+	unsigned long sti_rom_address;
+	char *dev_name;
+	int bpp, xres, yres;
+
+	fb = kmalloc(sizeof(*fb), GFP_ATOMIC);
+	if (!fb) {
+		printk(KERN_ERR "stifb: Could not allocate stifb structure\n");
+		return -ENODEV;
+	}
+	
+	info = &fb->info;
+
+	/* set struct to a known state */
+	memset(fb, 0, sizeof(*fb));
+	fix = &info->fix;
+	var = &info->var;
+	disp = &fb->disp;
+	info->disp = &fb->disp;
+
+	fb->sti = sti;
+	/* store upper 32bits of the graphics id */
+	fb->id = fb->sti->graphics_id[0];
+
+	/* only supported cards are allowed */
+	switch (fb->id) {
+	case S9000_ID_ARTIST:
+	case S9000_ID_HCRX:
+	case S9000_ID_TIMBER:
+	case S9000_ID_A1659A:
+	case S9000_ID_A1439A:
+	case CRT_ID_VISUALIZE_EG:
+		break;
+	default:
+		printk(KERN_WARNING "stifb: Unsupported gfx card id 0x%08x\n",
+			fb->id);
+		goto out_err1;
+	}
+	
+	/* default to 8 bpp on most graphic chips */
+	bpp = 8;
+	xres = sti_onscreen_x(fb->sti);
+	yres = sti_onscreen_y(fb->sti);
+
+	ngleGetDeviceRomData(fb);
+
+	/* get (virtual) io region base addr */
+	fix->mmio_start = REGION_BASE(fb,2);
+	fix->mmio_len   = 0x400000;
+
+       	/* Reject any device not in the NGLE family */
+	switch (fb->id) {
+	case S9000_ID_A1659A:	/* CRX/A1659A */
+		break;
+	case S9000_ID_ELM:	/* GRX, grayscale but else same as A1659A */
+		var->grayscale = 1;
+		fb->id = S9000_ID_A1659A;
+		break;
+	case S9000_ID_TIMBER:	/* HP9000/710 Any (may be a grayscale device) */
+		dev_name = fb->sti->outptr.dev_name;
+		if (strstr(dev_name, "GRAYSCALE") || 
+		    strstr(dev_name, "Grayscale") ||
+		    strstr(dev_name, "grayscale"))
+			var->grayscale = 1;
+		break;
+	case S9000_ID_TOMCAT:	/* Dual CRX, behaves else like a CRX */
+		/* FIXME: TomCat supports two heads:
+		 * fb.iobase = REGION_BASE(fb_info,3);
+		 * fb.screen_base = (void*) REGION_BASE(fb_info,2);
+		 * for now we only support the left one ! */
+		xres = fb->ngle_rom.x_size_visible;
+		yres = fb->ngle_rom.y_size_visible;
+		fb->id = S9000_ID_A1659A;
+		break;
+	case S9000_ID_A1439A:	/* CRX24/A1439A */
+		bpp = 32;
+		break;
+	case S9000_ID_HCRX:	/* Hyperdrive/HCRX */
+		memset(&fb->ngle_rom, 0, sizeof(fb->ngle_rom));
+		if ((fb->sti->regions_phys[0] & 0xfc000000) ==
+		    (fb->sti->regions_phys[2] & 0xfc000000))
+			sti_rom_address = fb->sti->regions_phys[0];
+		else
+			sti_rom_address = fb->sti->regions_phys[1];
+#ifdef __LP64__
+	        sti_rom_address |= 0xffffffff00000000;
+#endif
+		fb->deviceSpecificConfig = __raw_readl(sti_rom_address);
+		if (IS_24_DEVICE(fb)) {
+			if (force_bpp == 8 || force_bpp == 32)
+				bpp = force_bpp;
+			else
+				bpp = 32;
+		} else
+			bpp = 8;
+		READ_WORD(fb, REG_15);
+		SETUP_HW(fb);
+		break;
+	case CRT_ID_VISUALIZE_EG:
+	case S9000_ID_ARTIST:	/* Artist */
+		break;
+	default: 
+#ifdef FALLBACK_TO_1BPP
+	       	printk(KERN_WARNING 
+			"stifb: Unsupported graphics card (id=0x%08x) "
+				"- now trying 1bpp mode instead\n",
+			fb->id);
+		bpp = 1;	/* default to 1 bpp */
+		break;
+#else
+	       	printk(KERN_WARNING 
+			"stifb: Unsupported graphics card (id=0x%08x) "
+				"- skipping.\n",
+			fb->id);
+		goto out_err1;
+#endif
+	}
+
+
+	/* get framebuffer pysical and virtual base addr & len (64bit ready) */
+	fix->smem_start = fb->sti->regions_phys[1] | 0xffffffff00000000;
+	fix->smem_len = fb->sti->regions[1].region_desc.length * 4096;
+
+	fix->line_length = (fb->sti->glob_cfg->total_x * bpp) / 8;
+	if (!fix->line_length)
+		fix->line_length = 2048; /* default */
+	fix->accel = FB_ACCEL_NONE;
+
+	switch (bpp) {
+	    case 1:
+		fix->type = FB_TYPE_PLANES;	/* well, sort of */
+		fix->visual = FB_VISUAL_MONO10;
+		dispsw = &fbcon_sti;
+		break;
+#ifdef FBCON_HAS_CFB8		
+	    case 8:
+		fix->type = FB_TYPE_PACKED_PIXELS;
+		fix->visual = FB_VISUAL_PSEUDOCOLOR;
+	 	dispsw = &fbcon_cfb8;
+		var->red.length = var->green.length = var->blue.length = 8;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB32
+	    case 32:
+		fix->type = FB_TYPE_PACKED_PIXELS;
+		fix->visual = FB_VISUAL_TRUECOLOR;
+		dispsw = &fbcon_cfb32;
+		var->red.length = var->green.length = var->blue.length = var->transp.length = 8;
+		var->blue.offset = 0;
+		var->green.offset = 8;
+		var->red.offset = 16;
+		var->transp.offset = 24;
+		break;
+#endif
+	    default:
+		dispsw = &fbcon_dummy;
+		break;
+	}
+	
+	var->xres = var->xres_virtual = xres;
+	var->yres = var->yres_virtual = yres;
+	var->bits_per_pixel = bpp;
+
+	strcpy(info->modename, "stifb");
+	info->node = NODEV;
+	info->fbops = &stifb_ops;
+	info->screen_base = (void*) REGION_BASE(fb,1);
+	info->disp = disp;
+	info->changevar = NULL;
+	info->switch_con = gen_switch;
+	info->updatevar = &gen_update_var;
+	info->flags = FBINFO_FLAG_DEFAULT;
+	info->currcon = -1;
+
+	/* This has to been done !!! */
+	fb_alloc_cmap(&info->cmap, 256, 0);
+	stifb_init_display(fb);
+	gen_set_disp(-1, info);
+	disp->dispsw = dispsw;
+
+	if (!request_mem_region(fix->smem_start, fix->smem_len, "stifb")) {
+		printk(KERN_ERR "stifb: cannot reserve fb region 0x%04lx-0x%04lx\n",
+				fix->smem_start, fix->smem_start+fix->smem_len);
+		goto out_err1;
+	}
+		
+	if (!request_mem_region(fix->mmio_start, fix->mmio_len, "stifb mmio")) {
+		printk(KERN_ERR "stifb: cannot reserve sti mmio region 0x%04lx-0x%04lx\n",
+				fix->mmio_start, fix->mmio_start+fix->mmio_len);
+		goto out_err2;
+	}
+
+	if (register_framebuffer(&fb->info) < 0)
+		goto out_err3;
+
+	printk(KERN_INFO 
+	    "fb%d: %s %dx%d-%d frame buffer device, id: %04x, mmio: 0x%04lx\n",
+		minor(fb->info.node), 
+		fb->info.modename,
+		disp->var.xres, 
+		disp->var.yres,
+		disp->var.bits_per_pixel,
+		fb->id, 
+		fix->mmio_start);
 
 	return 0;
-}
 
 
-    /*
-     *  Cleanup
-     */
+out_err3:
+	release_mem_region(fix->mmio_start, fix->mmio_len);
+out_err2:
+	release_mem_region(fix->smem_start, fix->smem_len);
+out_err1:
+	kfree(fb);
+	return -ENXIO;
+}
 
-void
-stifb_cleanup(struct fb_info *info)
+int __init
+stifb_init(void)
 {
-	printk("stifb_cleanup: you're on crack\n");
+	struct sti_struct *sti;
+	int i;
+	
+	
+	if (sti_init_roms() == NULL)
+		return -ENXIO; /* no STI cards available */
+
+	for (i = 0; i < MAX_STI_ROMS; i++) {
+		sti = sti_get_rom(i);
+		if (sti)
+			stifb_init_fb(sti, stifb_force_bpp[i]);
+		else
+			break;
+	}
+	return 0;
 }
 
+/*
+ *  Cleanup
+ */
+
+static void __exit
+stifb_cleanup(void)
+{
+	// unregister_framebuffer(); 
+}
 
 int __init
 stifb_setup(char *options)
 {
-	/* XXX: we should take the resolution, bpp as command line arguments. */
+	int i;
+	
+	if (!options || !*options)
+		return 0;
+	
+	if (strncmp(options, "bpp", 3) == 0) {
+		options += 3;
+		for (i = 0; i < MAX_STI_ROMS; i++) {
+			if (*options++ == ':')
+				stifb_force_bpp[i] = simple_strtoul(options, &options, 10);
+			else
+				break;
+		}
+	}
 	return 0;
 }
 
+__setup("stifb=", stifb_setup);
 
-/* ------------------------------------------------------------------------- */
+#ifdef MODULE
+module_init(stifb_init);
+#endif
+module_exit(stifb_cleanup);
+
+MODULE_AUTHOR("Helge Deller <deller@gmx.de>, Thomas Bogendoerfer <tsbogend@alpha.franken.de>");
+MODULE_DESCRIPTION("Framebuffer driver for HP's NGLE series graphics cards in HP PARISC machines");
+MODULE_LICENSE("GPL");
 
+MODULE_PARM(bpp, "i");
+MODULE_PARM_DESC(mem, "Bits per pixel (default: 8)");
 
-static struct fb_ops stifb_ops = {
-	.owner =	THIS_MODULE,
-	.fb_get_fix =	fbgen_get_fix,
-	.fb_get_var =	fbgen_get_var,
-	.fb_set_var =	fbgen_set_var,
-	.fb_get_cmap =	fbgen_get_cmap,
-	.fb_set_cmap =	gen_set_cmap,
-	.fb_pan_display =fbgen_pan_display,
-	.fb_blank =	fbgen_blank,
-};
diff -Nru a/drivers/video/sun3fb.c b/drivers/video/sun3fb.c
--- a/drivers/video/sun3fb.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/video/sun3fb.c	Mon Dec  9 18:46:35 2002
@@ -646,7 +646,7 @@
 		kfree(fb);
 		return -EINVAL;
 	}
-	printk("fb%d: %s\n", GET_FB_IDX(fb->info.node), p);
+	printk("fb%d: %s\n", minor(fb->info.node), p);
 
 	return 0;
 }
diff -Nru a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
--- a/drivers/video/tdfxfb.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/video/tdfxfb.c	Mon Dec  9 18:46:35 2002
@@ -77,7 +77,6 @@
 #include <linux/spinlock.h>
 
 #include <video/tdfx.h>
-#include <video/fbcon.h>
 
 #undef TDFXFB_DEBUG 
 #ifdef TDFXFB_DEBUG
@@ -143,10 +142,10 @@
 };
 
 static struct pci_driver tdfxfb_driver = {
-	.name =		"tdfxfb",
-	.id_table =	tdfxfb_id_table,
-	.probe =	tdfxfb_probe,
-	.remove =	__devexit_p(tdfxfb_remove),
+	.name		= "tdfxfb",
+	.id_table 	= tdfxfb_id_table,
+	.probe 		= tdfxfb_probe,
+	.remove 	= __devexit_p(tdfxfb_remove),
 };
 
 MODULE_DEVICE_TABLE(pci, tdfxfb_id_table);
@@ -162,16 +161,14 @@
 static int tdfxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, 
 			    u_int transp, struct fb_info *info); 
 static int tdfxfb_blank(int blank, struct fb_info *info); 
-static int tdfxfb_pan_display(struct fb_var_screeninfo *var, int con, struct fb_info *info);
+static int tdfxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
 static void tdfxfb_fillrect(struct fb_info *info, struct fb_fillrect *rect);
 static void tdfxfb_copyarea(struct fb_info *info, struct fb_copyarea *area);  
 static void tdfxfb_imageblit(struct fb_info *info, struct fb_image *image); 
+static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor);
 
 static struct fb_ops tdfxfb_ops = {
 	.owner		= THIS_MODULE,
-	.fb_set_var	= gen_set_var,
-	.fb_get_cmap	= gen_get_cmap,
-	.fb_set_cmap	= gen_set_cmap,
 	.fb_check_var	= tdfxfb_check_var,
 	.fb_set_par	= tdfxfb_set_par,
 	.fb_setcolreg	= tdfxfb_setcolreg,
@@ -180,20 +177,20 @@
 	.fb_fillrect	= tdfxfb_fillrect,
 	.fb_copyarea	= tdfxfb_copyarea,
 	.fb_imageblit	= tdfxfb_imageblit,
+	.fb_sync	= banshee_wait_idle,
+	.fb_cursor	= soft_cursor,
 };
 
 /*
  * do_xxx: Hardware-specific functions
  */
 static u32 do_calc_pll(int freq, int *freq_out);
-static void  do_write_regs(struct banshee_reg *reg);
-static unsigned long do_lfb_size(unsigned short);
+static void  do_write_regs(struct fb_info *info, struct banshee_reg *reg);
+static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short);
 
 /*
  * Driver data 
  */
-static struct tdfx_par default_par;
-
 static int  nopan   = 0;
 static int  nowrap  = 1;      // not implemented (yet)
 static int  inverse = 0;
@@ -204,132 +201,133 @@
  * ------------------------------------------------------------------------- */
 
 #ifdef VGA_REG_IO 
-static inline  u8 vga_inb(u32 reg) { return inb(reg); }
-static inline u16 vga_inw(u32 reg) { return inw(reg); }
-static inline u16 vga_inl(u32 reg) { return inl(reg); }
-
-static inline void vga_outb(u32 reg,  u8 val) { outb(val, reg); }
-static inline void vga_outw(u32 reg, u16 val) { outw(val, reg); }
-static inline void vga_outl(u32 reg, u32 val) { outl(val, reg); }
+static inline  u8 vga_inb(struct tdfx_par *par, u32 reg) { return inb(reg); }
+static inline u16 vga_inw(struct tdfx_par *par, u32 reg) { return inw(reg); }
+static inline u16 vga_inl(struct tdfx_par *par, u32 reg) { return inl(reg); }
+
+static inline void vga_outb(struct tdfx_par *par, u32 reg,  u8 val) { outb(val, reg); }
+static inline void vga_outw(struct tdfx_par *par, u32 reg, u16 val) { outw(val, reg); }
+static inline void vga_outl(struct tdfx_par *par, u32 reg, u32 val) { outl(val, reg); }
 #else
-static inline  u8 vga_inb(u32 reg) { 
-	return inb(default_par.iobase + reg - 0x300); 
+static inline  u8 vga_inb(struct tdfx_par *par, u32 reg) { 
+	return inb(par->iobase + reg - 0x300); 
 }
-static inline u16 vga_inw(u32 reg) { 
-	return inw(default_par.iobase + reg - 0x300); 
+static inline u16 vga_inw(struct tdfx_par *par, u32 reg) { 
+	return inw(par->iobase + reg - 0x300); 
 }
-static inline u16 vga_inl(u32 reg) { 
-	return inl(default_par.iobase + reg - 0x300); 
+static inline u16 vga_inl(struct tdfx_par *par, u32 reg) { 
+	return inl(par->iobase + reg - 0x300); 
 }
-static inline void vga_outb(u32 reg,  u8 val) { 
-	outb(val, default_par.iobase + reg - 0x300); 
+static inline void vga_outb(struct tdfx_par *par, u32 reg,  u8 val) { 
+	outb(val, par->iobase + reg - 0x300); 
 }
-static inline void vga_outw(u32 reg, u16 val) { 
-	outw(val, default_par.iobase + reg - 0x300); 
+static inline void vga_outw(struct tdfx_par *par, u32 reg, u16 val) { 
+	outw(val, par->iobase + reg - 0x300); 
 }
-static inline void vga_outl(u32 reg, u32 val) { 
-	outl(val, default_par.iobase + reg - 0x300); 
+static inline void vga_outl(struct tdfx_par *par, u32 reg, u32 val) { 
+	outl(val, par->iobase + reg - 0x300); 
 }
 #endif
 
-static inline void gra_outb(u32 idx, u8 val) {
-	vga_outb(GRA_I, idx); vga_outb(GRA_D, val);
+static inline void gra_outb(struct tdfx_par *par, u32 idx, u8 val) {
+	vga_outb(par, GRA_I, idx); vga_outb(par, GRA_D, val);
 }
 
-static inline u8 gra_inb(u32 idx) {
-	vga_outb(GRA_I, idx); return vga_inb(GRA_D);
+static inline u8 gra_inb(struct tdfx_par *par, u32 idx) {
+	vga_outb(par, GRA_I, idx); return vga_inb(par, GRA_D);
 }
 
-static inline void seq_outb(u32 idx, u8 val) {
-	vga_outb(SEQ_I, idx); vga_outb(SEQ_D, val);
+static inline void seq_outb(struct tdfx_par *par, u32 idx, u8 val) {
+	vga_outb(par, SEQ_I, idx); vga_outb(par, SEQ_D, val);
 }
 
-static inline u8 seq_inb(u32 idx) {
-	vga_outb(SEQ_I, idx); return vga_inb(SEQ_D);
+static inline u8 seq_inb(struct tdfx_par *par, u32 idx) {
+	vga_outb(par, SEQ_I, idx); return vga_inb(par, SEQ_D);
 }
 
-static inline void crt_outb(u32 idx, u8 val) {
-	vga_outb(CRT_I, idx); vga_outb(CRT_D, val);
+static inline void crt_outb(struct tdfx_par *par, u32 idx, u8 val) {
+	vga_outb(par, CRT_I, idx); vga_outb(par, CRT_D, val);
 }
 
-static inline u8 crt_inb(u32 idx) {
-	vga_outb(CRT_I, idx); return vga_inb(CRT_D);
+static inline u8 crt_inb(struct tdfx_par *par, u32 idx) {
+	vga_outb(par, CRT_I, idx); return vga_inb(par, CRT_D);
 }
 
-static inline void att_outb(u32 idx, u8 val) 
+static inline void att_outb(struct tdfx_par *par, u32 idx, u8 val) 
 {
 	unsigned char tmp;
 	
-	tmp = vga_inb(IS1_R);
-	vga_outb(ATT_IW, idx);
-	vga_outb(ATT_IW, val);
+	tmp = vga_inb(par, IS1_R);
+	vga_outb(par, ATT_IW, idx);
+	vga_outb(par, ATT_IW, val);
 }
 
-static inline u8 att_inb(u32 idx) 
+static inline u8 att_inb(struct tdfx_par *par, u32 idx) 
 {
 	unsigned char tmp;
 
-	tmp = vga_inb(IS1_R);
-	vga_outb(ATT_IW, idx);
-	return vga_inb(ATT_IW);
+	tmp = vga_inb(par, IS1_R);
+	vga_outb(par, ATT_IW, idx);
+	return vga_inb(par, ATT_IW);
 }
 
-static inline void vga_disable_video(void)
+static inline void vga_disable_video(struct tdfx_par *par)
 {
 	unsigned char s;
 
-	s = seq_inb(0x01) | 0x20;
-	seq_outb(0x00, 0x01);
-	seq_outb(0x01, s);
-	seq_outb(0x00, 0x03);
+	s = seq_inb(par, 0x01) | 0x20;
+	seq_outb(par, 0x00, 0x01);
+	seq_outb(par, 0x01, s);
+	seq_outb(par, 0x00, 0x03);
 }
 
-static inline void vga_enable_video(void)
+static inline void vga_enable_video(struct tdfx_par *par)
 {
 	unsigned char s;
 
-	s = seq_inb(0x01) & 0xdf;
-	seq_outb(0x00, 0x01);
-	seq_outb(0x01, s);
-	seq_outb(0x00, 0x03);
+	s = seq_inb(par, 0x01) & 0xdf;
+	seq_outb(par, 0x00, 0x01);
+	seq_outb(par, 0x01, s);
+	seq_outb(par, 0x00, 0x03);
 }
 
-static inline void vga_disable_palette(void)
+static inline void vga_disable_palette(struct tdfx_par *par)
 {
-	vga_inb(IS1_R);
-	vga_outb(ATT_IW, 0x00);
+	vga_inb(par, IS1_R);
+	vga_outb(par, ATT_IW, 0x00);
 }
 
-static inline void vga_enable_palette(void)
+static inline void vga_enable_palette(struct tdfx_par *par)
 {
-	vga_inb(IS1_R);
-	vga_outb(ATT_IW, 0x20);
+	vga_inb(par, IS1_R);
+	vga_outb(par, ATT_IW, 0x20);
 }
 
-static inline u32 tdfx_inl(unsigned int reg) 
+static inline u32 tdfx_inl(struct tdfx_par *par, unsigned int reg) 
 {
-	return readl(default_par.regbase_virt + reg);
+	return readl(par->regbase_virt + reg);
 }
 
-static inline void tdfx_outl(unsigned int reg, u32 val)
+static inline void tdfx_outl(struct tdfx_par *par, unsigned int reg, u32 val)
 {
-	writel(val, default_par.regbase_virt + reg);
+	writel(val, par->regbase_virt + reg);
 }
 
-static inline void banshee_make_room(int size)
+static inline void banshee_make_room(struct tdfx_par *par, int size)
 {
-	while((tdfx_inl(STATUS) & 0x1f) < size);
+	while((tdfx_inl(par, STATUS) & 0x1f) < size);
 }
  
-static inline void banshee_wait_idle(void)
+static inline void banshee_wait_idle(struct fb_info *info)
 {
+	struct tdfx_par *par = (struct tdfx_par *) info->par; 
 	int i = 0;
 
-	banshee_make_room(1);
-	tdfx_outl(COMMAND_3D, COMMAND_3D_NOP);
+	banshee_make_room(par, 1);
+	tdfx_outl(par, COMMAND_3D, COMMAND_3D_NOP);
 
 	while(1) {
-		i = (tdfx_inl(STATUS) & STATUS_BUSY) ? 0 : i + 1;
+		i = (tdfx_inl(par, STATUS) & STATUS_BUSY) ? 0 : i + 1;
 		if(i == 3) break;
 	}
 }
@@ -337,11 +335,11 @@
 /*
  * Set the color of a palette entry in 8bpp mode 
  */
-static inline void do_setpalentry(unsigned regno, u32 c)
+static inline void do_setpalentry(struct tdfx_par *par, unsigned regno, u32 c)
 {  
-	banshee_make_room(2);
-	tdfx_outl(DACADDR, regno);
-	tdfx_outl(DACDATA, c);
+	banshee_make_room(par, 2);
+	tdfx_outl(par, DACADDR, regno);
+	tdfx_outl(par, DACDATA, c);
 }
 
 static u32 do_calc_pll(int freq, int* freq_out) 
@@ -373,71 +371,72 @@
 	return (n << 8) | (m << 2) | k;
 }
 
-static void do_write_regs(struct banshee_reg* reg) 
+static void do_write_regs(struct fb_info *info, struct banshee_reg* reg) 
 {
+	struct tdfx_par *par = (struct tdfx_par *) info->par; 
 	int i;
 
-	banshee_wait_idle();
+	banshee_wait_idle(info);
 
-	tdfx_outl(MISCINIT1, tdfx_inl(MISCINIT1) | 0x01);
+	tdfx_outl(par, MISCINIT1, tdfx_inl(par, MISCINIT1) | 0x01);
 
-	crt_outb(0x11, crt_inb(0x11) & 0x7f); /* CRT unprotect */
+	crt_outb(par, 0x11, crt_inb(par, 0x11) & 0x7f); /* CRT unprotect */
 
-	banshee_make_room(3);
-	tdfx_outl(VGAINIT1,	reg->vgainit1 &  0x001FFFFF);
-	tdfx_outl(VIDPROCCFG,	reg->vidcfg   & ~0x00000001);
+	banshee_make_room(par, 3);
+	tdfx_outl(par, VGAINIT1,	reg->vgainit1 &  0x001FFFFF);
+	tdfx_outl(par, VIDPROCCFG,	reg->vidcfg   & ~0x00000001);
 #if 0
-	tdfx_outl(PLLCTRL1, reg->mempll);
-	tdfx_outl(PLLCTRL2, reg->gfxpll);
+	tdfx_outl(par, PLLCTRL1, reg->mempll);
+	tdfx_outl(par, PLLCTRL2, reg->gfxpll);
 #endif
-	tdfx_outl(PLLCTRL0,	reg->vidpll);
+	tdfx_outl(par, PLLCTRL0,	reg->vidpll);
 
-	vga_outb(MISC_W, reg->misc[0x00] | 0x01);
+	vga_outb(par, MISC_W, reg->misc[0x00] | 0x01);
 
 	for (i = 0; i < 5; i++)
-		seq_outb(i, reg->seq[i]);
+		seq_outb(par, i, reg->seq[i]);
 
 	for (i = 0; i < 25; i++)
-		crt_outb(i, reg->crt[i]);
+		crt_outb(par, i, reg->crt[i]);
 
 	for (i = 0; i < 9; i++)
-		gra_outb(i, reg->gra[i]);
+		gra_outb(par, i, reg->gra[i]);
 
 	for (i = 0; i < 21; i++)
-		att_outb(i, reg->att[i]);
+		att_outb(par, i, reg->att[i]);
 
-	crt_outb(0x1a, reg->ext[0]);
-	crt_outb(0x1b, reg->ext[1]);
+	crt_outb(par, 0x1a, reg->ext[0]);
+	crt_outb(par, 0x1b, reg->ext[1]);
 
-	vga_enable_palette();
-	vga_enable_video();
+	vga_enable_palette(par);
+	vga_enable_video(par);
 
-	banshee_make_room(11);
-	tdfx_outl(VGAINIT0,      reg->vgainit0);
-	tdfx_outl(DACMODE,       reg->dacmode);
-	tdfx_outl(VIDDESKSTRIDE, reg->stride);
-	tdfx_outl(HWCURPATADDR,  0);
+	banshee_make_room(par, 11);
+	tdfx_outl(par, 	VGAINIT0,      reg->vgainit0);
+	tdfx_outl(par,	DACMODE,       reg->dacmode);
+	tdfx_outl(par,	VIDDESKSTRIDE, reg->stride);
+	tdfx_outl(par,	HWCURPATADDR,  0);
    
-	tdfx_outl(VIDSCREENSIZE,reg->screensize);
-	tdfx_outl(VIDDESKSTART,	reg->startaddr);
-	tdfx_outl(VIDPROCCFG,	reg->vidcfg);
-	tdfx_outl(VGAINIT1,	reg->vgainit1);  
-	tdfx_outl(MISCINIT0,	reg->miscinit0);	
-
-	banshee_make_room(8);
-	tdfx_outl(SRCBASE,         reg->srcbase);
-	tdfx_outl(DSTBASE,         reg->dstbase);
-	tdfx_outl(COMMANDEXTRA_2D, 0);
-	tdfx_outl(CLIP0MIN,        0);
-	tdfx_outl(CLIP0MAX,        0x0fff0fff);
-	tdfx_outl(CLIP1MIN,        0);
-	tdfx_outl(CLIP1MAX,        0x0fff0fff);
-	tdfx_outl(SRCXY,	   0);
+	tdfx_outl(par,	VIDSCREENSIZE,reg->screensize);
+	tdfx_outl(par,	VIDDESKSTART,	reg->startaddr);
+	tdfx_outl(par,	VIDPROCCFG,	reg->vidcfg);
+	tdfx_outl(par,	VGAINIT1,	reg->vgainit1);  
+	tdfx_outl(par,	MISCINIT0,	reg->miscinit0);	
+
+	banshee_make_room(par,	8);
+	tdfx_outl(par,	SRCBASE,         reg->srcbase);
+	tdfx_outl(par,	DSTBASE,         reg->dstbase);
+	tdfx_outl(par,	COMMANDEXTRA_2D, 0);
+	tdfx_outl(par,	CLIP0MIN,        0);
+	tdfx_outl(par,	CLIP0MAX,        0x0fff0fff);
+	tdfx_outl(par,	CLIP1MIN,        0);
+	tdfx_outl(par,	CLIP1MAX,        0x0fff0fff);
+	tdfx_outl(par,	SRCXY,	   0);
 
-	banshee_wait_idle();
+	banshee_wait_idle(info);
 }
 
-static unsigned long do_lfb_size(unsigned short dev_id) 
+static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short dev_id) 
 {
 	u32 draminit0 = 0;
 	u32 draminit1 = 0;
@@ -445,8 +444,8 @@
 	u32 lfbsize   = 0;
 	int sgram_p   = 0;
 
-	draminit0 = tdfx_inl(DRAMINIT0);  
-	draminit1 = tdfx_inl(DRAMINIT1);
+	draminit0 = tdfx_inl(par, DRAMINIT0);  
+	draminit1 = tdfx_inl(par, DRAMINIT1);
  
 	if ((dev_id == PCI_DEVICE_ID_3DFX_BANSHEE) ||
 	    (dev_id == PCI_DEVICE_ID_3DFX_VOODOO3)) {             	 
@@ -467,12 +466,12 @@
 		lfbsize <<= 20;
 	}                 
 	/* disable block writes for SDRAM (why?) */
-	miscinit1 = tdfx_inl(MISCINIT1);
+	miscinit1 = tdfx_inl(par, MISCINIT1);
 	miscinit1 |= sgram_p ? 0 : MISCINIT1_2DBLOCK_DIS;
 	miscinit1 |= MISCINIT1_CLUT_INV;
 
-	banshee_make_room(1); 
-	tdfx_outl(MISCINIT1, miscinit1);
+	banshee_make_room(par, 1); 
+	tdfx_outl(par, MISCINIT1, miscinit1);
 	return lfbsize;
 }
 
@@ -710,7 +709,7 @@
 			VGAINIT0_WAKEUP_3C3   |
 			VGAINIT0_ALT_READBACK |
 			VGAINIT0_EXTSHIFTOUT;
-	reg.vgainit1 = tdfx_inl(VGAINIT1) & 0x1fffff;
+	reg.vgainit1 = tdfx_inl(par, VGAINIT1) & 0x1fffff;
 
 	reg.cursloc   = 0;
    
@@ -740,7 +739,7 @@
 
 	reg.screensize = info->var.xres | (info->var.yres << 12);
 	reg.vidcfg &= ~VIDCFG_HALF_MODE;
-	reg.miscinit0 = tdfx_inl(MISCINIT0);
+	reg.miscinit0 = tdfx_inl(par, MISCINIT0);
 
 #if defined(__BIG_ENDIAN)
 	switch (info->var.bits_per_pixel) {
@@ -758,8 +757,8 @@
 			reg.miscinit0 &= ~(1 << 31);
 			break;
 	}
-#endif             
-	do_write_regs(&reg);
+#endif 
+	do_write_regs(par, &reg);
 
 	/* Now change fb_fix_screeninfo according to changes in par */
 	info->fix.line_length = info->var.xres * ((info->var.bits_per_pixel + 7)>>3);
@@ -773,6 +772,7 @@
 static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green,  
 			    unsigned blue,unsigned transp,struct fb_info *info) 
 {
+	struct tdfx_par *par = (struct tdfx_par *) info->par;
 	u32 rgbcol;
    
 	if (regno >= info->cmap.len) return 1;
@@ -782,7 +782,7 @@
 			rgbcol =(((u32)red   & 0xff00) << 8) |
 				(((u32)green & 0xff00) << 0) |
 				(((u32)blue  & 0xff00) >> 8);
-			do_setpalentry(regno, rgbcol);
+			do_setpalentry(par, regno, rgbcol);
 			break;
 		/* Truecolor has no hardware color palettes. */
 		case FB_VISUAL_TRUECOLOR:
@@ -805,9 +805,10 @@
 /* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
 static int tdfxfb_blank(int blank, struct fb_info *info)
 { 
+	struct tdfx_par *par = (struct tdfx_par *) info->par;
 	u32 dacmode, state = 0, vgablank = 0;
 
-	dacmode = tdfx_inl(DACMODE);
+	dacmode = tdfx_inl(par, DACMODE);
 
 	switch (blank) {
 		case 0: /* Screen: On; HSync: On, VSync: On */    
@@ -834,21 +835,22 @@
 
 	dacmode &= ~(BIT(1) | BIT(3));
 	dacmode |= state;
-	banshee_make_room(1); 
-	tdfx_outl(DACMODE, dacmode);
+	banshee_make_room(par, 1); 
+	tdfx_outl(par, DACMODE, dacmode);
 	if (vgablank) 
-		vga_disable_video();
+		vga_disable_video(par);
 	else
-		vga_enable_video();
+		vga_enable_video(par);
 	return 0;
 }
 
 /*   
  * Set the starting position of the visible screen to var->yoffset
  */   
-static int tdfxfb_pan_display(struct fb_var_screeninfo *var, int con,
+static int tdfxfb_pan_display(struct fb_var_screeninfo *var,
 			      struct fb_info *info) 
 {
+	struct tdfx_par *par = (struct tdfx_par *) info->par;
 	u32 addr;  	
 
 	if (nopan || var->xoffset || (var->yoffset > var->yres_virtual))
@@ -857,8 +859,8 @@
 		return -EINVAL;
 
 	addr = var->yoffset * info->fix.line_length;
-	banshee_make_room(1);
-	tdfx_outl(VIDDESKSTART, addr);
+	banshee_make_room(par, 1);
+	tdfx_outl(par, VIDDESKSTART, addr);
    
 	info->var.xoffset = var->xoffset;
 	info->var.yoffset = var->yoffset; 
@@ -870,6 +872,7 @@
  */
 static void tdfxfb_fillrect(struct fb_info *info, struct fb_fillrect *rect) 
 {
+	struct tdfx_par *par = (struct tdfx_par *) info->par;
 	u32 bpp = info->var.bits_per_pixel;
 	u32 stride = info->fix.line_length;
 	u32 fmt= stride | ((bpp+((bpp==8) ? 0 : 8)) << 13); 
@@ -880,13 +883,13 @@
 	else 			 
 		tdfx_rop = TDFX_ROP_XOR;
 
-	banshee_make_room(5);
-	tdfx_outl(DSTFORMAT, fmt);
-	tdfx_outl(COLORFORE, rect->color);
-	tdfx_outl(COMMAND_2D, COMMAND_2D_FILLRECT | (tdfx_rop << 24));
-	tdfx_outl(DSTSIZE,    rect->width | (rect->height << 16));
-	tdfx_outl(LAUNCH_2D,  rect->dx | (rect->dy << 16));
-	banshee_wait_idle();
+	banshee_make_room(par, 5);
+	tdfx_outl(par,	DSTFORMAT, fmt);
+	tdfx_outl(par,	COLORFORE, rect->color);
+	tdfx_outl(par,	COMMAND_2D, COMMAND_2D_FILLRECT | (tdfx_rop << 24));
+	tdfx_outl(par,	DSTSIZE,    rect->width | (rect->height << 16));
+	tdfx_outl(par,	LAUNCH_2D,  rect->dx | (rect->dy << 16));
+	banshee_wait_idle(info);
 }
 
 /*
@@ -894,6 +897,7 @@
  */
 static void tdfxfb_copyarea(struct fb_info *info, struct fb_copyarea *area)  
 {
+	struct tdfx_par *par = (struct tdfx_par *) info->par;
 	u32 bpp = info->var.bits_per_pixel;
 	u32 stride = info->fix.line_length;
 	u32 blitcmd = COMMAND_2D_S2S_BITBLT | (TDFX_ROP_COPY << 24);
@@ -912,19 +916,20 @@
 		area->dy += area->height - 1;
 	}
    
-	banshee_make_room(6);
+	banshee_make_room(par, 6);
 
-	tdfx_outl(SRCFORMAT, fmt);
-	tdfx_outl(DSTFORMAT, fmt);
-	tdfx_outl(COMMAND_2D, blitcmd); 
-	tdfx_outl(DSTSIZE,   area->width | (area->height << 16));
-	tdfx_outl(DSTXY,     area->dx | (area->dy << 16));
-	tdfx_outl(LAUNCH_2D, area->sx | (area->sy << 16)); 
-	banshee_wait_idle();
+	tdfx_outl(par,	SRCFORMAT, fmt);
+	tdfx_outl(par,	DSTFORMAT, fmt);
+	tdfx_outl(par,	COMMAND_2D, blitcmd); 
+	tdfx_outl(par,	DSTSIZE,   area->width | (area->height << 16));
+	tdfx_outl(par,	DSTXY,     area->dx | (area->dy << 16));
+	tdfx_outl(par,	LAUNCH_2D, area->sx | (area->sy << 16)); 
+	banshee_wait_idle(info);
 }
 
 static void tdfxfb_imageblit(struct fb_info *info, struct fb_image *pixmap) 
 {
+	struct tdfx_par *par = (struct tdfx_par *) info->par;
 	int size = pixmap->height*((pixmap->width*pixmap->depth + 7)>>3);
 	int i, stride = info->fix.line_length;
 	u32 bpp = info->var.bits_per_pixel;
@@ -933,25 +938,25 @@
 	u32 srcfmt;
 
 	if (pixmap->depth == 1) {
-		banshee_make_room(8 + ((size + 3) >> 2));
-		tdfx_outl(COLORFORE, pixmap->fg_color);
-		tdfx_outl(COLORBACK, pixmap->bg_color);
+		banshee_make_room(par, 8 + ((size + 3) >> 2));
+		tdfx_outl(par, COLORFORE, pixmap->fg_color);
+		tdfx_outl(par, COLORBACK, pixmap->bg_color);
 		srcfmt = 0x400000;
 	} else {
-		banshee_make_room(6 + ((size + 3) >> 2));
-		srcfmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13) | 0x400000;
+		//banshee_make_room(par, 6 + ((size + 3) >> 2));
+		//srcfmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13) | 0x400000;
 	}	
 
-	tdfx_outl(SRCXY,     0);
-	tdfx_outl(DSTXY,     pixmap->dx | (pixmap->dy << 16));
-	tdfx_outl(COMMAND_2D, COMMAND_2D_H2S_BITBLT | (TDFX_ROP_COPY << 24));
-	tdfx_outl(SRCFORMAT, srcfmt);
-	tdfx_outl(DSTFORMAT, dstfmt);
-	tdfx_outl(DSTSIZE,   pixmap->width | (pixmap->height << 16));
+	tdfx_outl(par,	SRCXY,     0);
+	tdfx_outl(par,	DSTXY,     pixmap->dx | (pixmap->dy << 16));
+	tdfx_outl(par,	COMMAND_2D, COMMAND_2D_H2S_BITBLT | (TDFX_ROP_COPY << 24));
+	tdfx_outl(par,	SRCFORMAT, srcfmt);
+	tdfx_outl(par,	DSTFORMAT, dstfmt);
+	tdfx_outl(par,	DSTSIZE,   pixmap->width | (pixmap->height << 16));
 
 	/* Send four bytes at a time of data */	
 	for (i = (size >> 2) ; i > 0; i--) { 
-		tdfx_outl(LAUNCH_2D,*(u32*)chardata);
+		tdfx_outl(par,	LAUNCH_2D,*(u32*)chardata);
 		chardata += 4; 
 	}	
 
@@ -959,11 +964,148 @@
 	i = size%4;	
 	switch (i) {
 		case 0: break;
-		case 1:  tdfx_outl(LAUNCH_2D,*chardata); break;
-		case 2:  tdfx_outl(LAUNCH_2D,*(u16*)chardata); break;
-		case 3:  tdfx_outl(LAUNCH_2D,*(u16*)chardata | ((chardata[3]) << 24)); break;
+		case 1:  tdfx_outl(par,	LAUNCH_2D,*chardata); break;
+		case 2:  tdfx_outl(par,	LAUNCH_2D,*(u16*)chardata); break;
+		case 3:  tdfx_outl(par,	LAUNCH_2D,*(u16*)chardata | ((chardata[3]) << 24)); break;
 	}
-	banshee_wait_idle();
+	banshee_wait_idle(info);
+}
+
+static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+	struct tdfx_par *par = (struct tdfx_par *) info->par;
+	unsigned long flags;
+
+	/*
+	 * If the cursor is not be changed this means either we want the 
+	 * current cursor state (if enable is set) or we want to query what
+	 * we can do with the cursor (if enable is not set) 
+ 	 */
+	if (!cursor->set) return 0;
+
+	/* Too large of a cursor :-( */
+	if (cursor->image.width > 64 || cursor->image.height > 64)
+		return -ENXIO;
+
+	/* 
+	 * If we are going to be changing things we should disable
+	 * the cursor first 
+	 */
+	if (info->cursor.enable) {
+		spin_lock_irqsave(&par->DAClock, flags);
+		info->cursor.enable = 0;
+		del_timer(&(par->hwcursor.timer));
+		tdfx_outl(par, VIDPROCCFG, par->hwcursor.disable);
+		spin_unlock_irqrestore(&par->DAClock, flags);
+	}
+
+	/* Disable the Cursor */
+	if ((cursor->set && FB_CUR_SETCUR) && !cursor->enable)
+		return 0;
+
+	/* fix cursor color - XFree86 forgets to restore it properly */
+	if (cursor->set && FB_CUR_SETCMAP) {
+		struct fb_cmap cmap = cursor->image.cmap;
+		unsigned long bg_color, fg_color;
+
+		cmap.len = 2;/* Voodoo 3+ only support 2 color cursors*/
+		fg_color = ((cmap.red[cmap.start] << 16) |
+			    (cmap.green[cmap.start] << 8)  |
+			    (cmap.blue[cmap.start]));
+		bg_color = ((cmap.red[cmap.start+1] << 16) |
+			    (cmap.green[cmap.start+1] << 8) |
+			    (cmap.blue[cmap.start+1]));
+		fb_copy_cmap(&cmap, &info->cursor.image.cmap, 0);
+		spin_lock_irqsave(&par->DAClock, flags);
+		banshee_make_room(par, 2);
+		tdfx_outl(par, HWCURC0, bg_color);
+		tdfx_outl(par, HWCURC1, fg_color);
+		spin_unlock_irqrestore(&par->DAClock, flags);
+	}
+
+	if (cursor->set && FB_CUR_SETPOS) {
+		int x, y;
+
+		x = cursor->image.dx;
+		y = cursor->image.dy;
+		y -= info->var.yoffset;
+		info->cursor.image.dx = x;
+		info->cursor.image.dy = y;
+		x += 63;
+		y += 63;
+		spin_lock_irqsave(&par->DAClock, flags);
+		banshee_make_room(par, 1);
+		tdfx_outl(par, HWCURLOC, (y << 16) + x);
+		spin_unlock_irqrestore(&par->DAClock, flags);
+	}
+
+	/* Not supported so we fake it */
+	if (cursor->set && FB_CUR_SETHOT) {
+		info->cursor.hot.x = cursor->hot.x;
+		info->cursor.hot.y = cursor->hot.y;
+	}
+
+	if (cursor->set && FB_CUR_SETSHAPE) {
+		/*
+	 	 * Voodoo 3 and above cards use 2 monochrome cursor patterns.
+		 *    The reason is so the card can fetch 8 words at a time
+		 * and are stored on chip for use for the next 8 scanlines.
+		 * This reduces the number of times for access to draw the
+		 * cursor for each screen refresh.
+		 *    Each pattern is a bitmap of 64 bit wide and 64 bit high
+		 * (total of 8192 bits or 1024 Kbytes). The two patterns are
+		 * stored in such a way that pattern 0 always resides in the
+		 * lower half (least significant 64 bits) of a 128 bit word
+		 * and pattern 1 the upper half. If you examine the data of
+		 * the cursor image the graphics card uses then from the
+		 * begining you see line one of pattern 0, line one of
+		 * pattern 1, line two of pattern 0, line two of pattern 1,
+		 * etc etc. The linear stride for the cursor is always 16 bytes
+		 * (128 bits) which is the maximum cursor width times two for
+		 * the two monochrome patterns.
+		 */
+		u8 *cursorbase = (u8 *) info->cursor.image.data;
+		char *bitmap = cursor->image.data;
+		char *mask = cursor->mask;
+		int i, j, k, h = 0;
+
+		for (i = 0; i < 64; i++) {
+			if (i < cursor->image.height) {
+				j = (cursor->image.width + 7) >> 3;
+				k = 8 - j;
+
+				for (;j > 0; j--) {
+				/* Pattern 0. Copy the cursor bitmap to it */
+					fb_writeb(*bitmap, cursorbase + h);
+					bitmap++;
+				/* Pattern 1. Copy the cursor mask to it */
+					fb_writeb(*mask, cursorbase + h + 8);
+					mask++;
+					h++;
+				}
+				for (;k > 0; k--) {
+					fb_writeb(0, cursorbase + h);
+					fb_writeb(~0, cursorbase + h + 8);
+					h++;
+				}
+			} else {
+				fb_writel(0, cursorbase + h);
+				fb_writel(0, cursorbase + h + 4);
+				fb_writel(~0, cursorbase + h + 8);
+				fb_writel(~0, cursorbase + h + 12);
+				h += 16;
+			}
+		}
+	}
+	/* Turn the cursor on */
+	cursor->enable = 1;
+	info->cursor = *cursor;
+	mod_timer(&par->hwcursor.timer, jiffies+HZ/2);
+	spin_lock_irqsave(&par->DAClock, flags);
+	banshee_make_room(par, 1);
+	tdfx_outl(par, VIDPROCCFG, par->hwcursor.enable);
+	spin_unlock_irqrestore(&par->DAClock, flags);
+	return 0;
 }
 
 /**
@@ -978,6 +1120,7 @@
 static int __devinit tdfxfb_probe(struct pci_dev *pdev,
                                   const struct pci_device_id *id)
 {
+	struct tdfx_par *default_par;
 	struct fb_info *info;
 	int size, err;
 
@@ -986,33 +1129,36 @@
 		return err;
 	}
 
-	info = kmalloc(sizeof(struct fb_info) + sizeof(struct display) +
-			sizeof(u32) * 16, GFP_KERNEL);
+	size = sizeof(struct fb_info)+sizeof(struct tdfx_par)+16*sizeof(u32);
+
+	info = kmalloc(size, GFP_KERNEL);
 
 	if (!info)	return -ENOMEM;
 		
-	memset(info, 0, sizeof(info) + sizeof(struct display) + sizeof(u32) * 16);
-     
+	memset(info, 0, size);
+    
+	default_par = (struct tdfx_par *) (info + 1);
+ 
 	/* Configure the default fb_fix_screeninfo first */
 	switch (pdev->device) {
 		case PCI_DEVICE_ID_3DFX_BANSHEE:	
 			strcat(tdfx_fix.id, " Banshee");
-			default_par.max_pixclock = BANSHEE_MAX_PIXCLOCK;
+			default_par->max_pixclock = BANSHEE_MAX_PIXCLOCK;
 			break;
 		case PCI_DEVICE_ID_3DFX_VOODOO3:
 			strcat(tdfx_fix.id, " Voodoo3");
-			default_par.max_pixclock = VOODOO3_MAX_PIXCLOCK;
+			default_par->max_pixclock = VOODOO3_MAX_PIXCLOCK;
 			break;
 		case PCI_DEVICE_ID_3DFX_VOODOO5:
 			strcat(tdfx_fix.id, " Voodoo5");
-			default_par.max_pixclock = VOODOO5_MAX_PIXCLOCK;
+			default_par->max_pixclock = VOODOO5_MAX_PIXCLOCK;
 			break;
 	}
 
 	tdfx_fix.mmio_start = pci_resource_start(pdev, 0);
 	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) {
+	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);
 		goto out_err;
 	}
@@ -1024,7 +1170,7 @@
 	} 
 
 	tdfx_fix.smem_start = pci_resource_start(pdev, 1);
-	if (!(tdfx_fix.smem_len = do_lfb_size(pdev->device))) {
+	if (!(tdfx_fix.smem_len = do_lfb_size(default_par, pdev->device))) {
 		printk("fb: Can't count %s memory.\n", tdfx_fix.id);
 		release_mem_region(pci_resource_start(pdev, 0),
 				   pci_resource_len(pdev, 0));
@@ -1050,7 +1196,7 @@
 		goto out_err;
 	}
 
-	default_par.iobase = pci_resource_start(pdev, 2);
+	default_par->iobase = pci_resource_start(pdev, 2);
     
 	if (!request_region(pci_resource_start(pdev, 2),
 	    pci_resource_len(pdev, 2), "tdfx iobase")) {
@@ -1073,17 +1219,10 @@
 	info->node		= NODEV;
 	info->fbops		= &tdfxfb_ops;
 	info->fix		= tdfx_fix; 	
-	info->par		= &default_par;
-	info->disp		= (struct display *)(info + 1);	
-	info->pseudo_palette	= (void *)(info->disp + 1); 
+	info->par		= default_par;
+	info->pseudo_palette	= (void *)(default_par + 1); 
 	info->flags		= FBINFO_FLAG_DEFAULT;
 
-	/* The below feilds will go away !!!! */
-	strcpy(info->modename, info->fix.id);
-	info->currcon		= -1;
-	info->switch_con	= gen_switch;			 
-	info->updatevar		= gen_update_var;
-
 	if (!mode_option)
 		mode_option = "640x480@60";
 	 
@@ -1094,8 +1233,6 @@
 	size = (info->var.bits_per_pixel == 8) ? 256 : 16;
 	fb_alloc_cmap(&info->cmap, size, 0);  
 
-	gen_set_var(&info->var, -1, info);
-
 	if (register_framebuffer(info) < 0) {
 		printk("tdfxfb: can't register framebuffer\n");
 		goto out_err;
@@ -1110,8 +1247,8 @@
 	/*
 	 * Cleanup after anything that was remapped/allocated.
 	 */
-	if (default_par.regbase_virt)
-		iounmap(default_par.regbase_virt);
+	if (default_par->regbase_virt)
+		iounmap(default_par->regbase_virt);
 	if (info->screen_base)
 		iounmap(info->screen_base);
 	kfree(info);
@@ -1160,8 +1297,6 @@
 MODULE_AUTHOR("Hannu Mallat <hmallat@cc.hut.fi>");
 MODULE_DESCRIPTION("3Dfx framebuffer device driver");
 MODULE_LICENSE("GPL");
-MODULE_PARM(noaccel, "i");
-MODULE_PARM_DESC(noaccel, "Disable hardware acceleration (1 = disabled), enabled by default.");
  
 #ifdef MODULE
 module_init(tdfxfb_init);
diff -Nru a/drivers/video/tgafb.c b/drivers/video/tgafb.c
--- a/drivers/video/tgafb.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/video/tgafb.c	Mon Dec  9 18:46:50 2002
@@ -780,8 +780,7 @@
     u32 vhcr, vvcr, vvvr;
     unsigned long flags;
     
-    save_flags(flags);
-    cli();
+    local_irq_save(flags);
 
     vhcr = TGA_READ_REG(TGA_HORIZ_REG);
     vvcr = TGA_READ_REG(TGA_VERT_REG);
@@ -821,7 +820,7 @@
 	break;
     }
 
-    restore_flags(flags);
+    local_irq_restore(flags);
     return 0;
 }
 
@@ -982,7 +981,7 @@
     if (register_framebuffer(&fb_info.gen.info) < 0)
 	return -EINVAL;
     printk(KERN_INFO "fb%d: %s frame buffer device at 0x%lx\n", 
-	    GET_FB_IDX(fb_info.gen.info.node), fb_info.gen.info.modename, 
+	    minor(fb_info.gen.info.node), fb_info.gen.info.modename, 
 	    pdev->resource[0].start);
     return 0;
 }
diff -Nru a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
--- a/drivers/video/tridentfb.c	Mon Dec  9 18:46:37 2002
+++ b/drivers/video/tridentfb.c	Mon Dec  9 18:46:37 2002
@@ -1235,7 +1235,7 @@
 	}
 
 	output("fb%d: %s frame buffer device %dx%d-%dbpp\n",
-	   GET_FB_IDX(fb_info.gen.info.node), fb_info.gen.info.modename,default_var.xres,
+	   minor(fb_info.gen.info.node), fb_info.gen.info.modename,default_var.xres,
 	   default_var.yres,default_var.bits_per_pixel);
 	return 0;
 }
diff -Nru a/drivers/video/tx3912fb.c b/drivers/video/tx3912fb.c
--- a/drivers/video/tx3912fb.c	Mon Dec  9 18:46:38 2002
+++ b/drivers/video/tx3912fb.c	Mon Dec  9 18:46:38 2002
@@ -21,7 +21,6 @@
 #include <linux/init.h>
 #include <linux/pm.h>
 #include <linux/fb.h>
-#include <video/fbcon.h>
 #include <asm/io.h>
 #include <asm/bootinfo.h>
 #include <asm/uaccess.h>
@@ -33,7 +32,6 @@
  */
 static struct fb_info fb_info;
 static u32 cfb8[16];
-static struct display disp;
 
 static struct fb_fix_screeninfo tx3912fb_fix __initdata = {
 	.id =		"tx3912fb",
@@ -96,13 +94,11 @@
  */
 static struct fb_ops tx3912fb_ops = {
 	.owner		= THIS_MODULE,
-	.fb_set_var	= gen_set_var,
-	.fb_get_cmap	= gen_get_cmap,
-	.fb_set_cmap	= gen_set_cmap,
 	.fb_setcolreg	= tx3912fb_setcolreg,
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
+	.fb_cursor	= soft_cursor,
 };
 
 static int tx3912fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
@@ -215,6 +211,7 @@
 int __init tx3912fb_init(void)
 {
 	u_long tx3912fb_paddr = 0;
+	int size = (info->var.bits_per_pixel == 8) ? 256 : 16;
 
 	/* Disable the video logic */
 	outl(inl(TX3912_VIDEO_CTRL1) &
@@ -295,17 +292,11 @@
 	if ((tx3912fb_fix.line_length * tx3912fb_var.yres_virtual) > tx3912fb_fix.smem_len)
 		return -ENOMEM;
 
-	strcpy(fb_info.modename, tx3912fb_fix.id);
-	fb_info.changevar = NULL;
 	fb_info.node = NODEV;
-	fb_info.currcon = -1;
 	fb_info.fbops = &tx3912fb_ops;
 	fb_info.var = tx3912fb_var;
 	fb_info.fix = tx3912fb_fix;
 	fb_info.pseudo_palette = pseudo_palette;
-	fb_info.disp = &disp;
-	fb_info.switch_con = gen_switch;
-	fb_info.updatevar = gen_update_var;
 	fb_info.flags = FBINFO_FLAG_DEFAULT;
 
 	/* Clear the framebuffer */
@@ -313,17 +304,16 @@
 	udelay(200);
 
 	fb_alloc_cmap(&info->cmap, size, 0);
-	gen_set_disp(-1, &disp);	
 
 	if (register_framebuffer(&fb_info) < 0)
 		return -1;
 
 	printk(KERN_INFO "fb%d: TX3912 frame buffer using %uKB.\n",
-	       GET_FB_IDX(fb_info.node), (u_int) (fb_info.fix.smem_len >> 10));
+	       minor(fb_info.node), (u_int) (fb_info.fix.smem_len >> 10));
 	return 0;
 }
 
-void __init tx3912fb_setup(char *options)
+int __init tx3912fb_setup(char *options)
 {
 	char *this_opt;
 
@@ -334,6 +324,7 @@
 		if (!strncmp(options, "bpp:", 4))	
 			tx3912fb_var.bits_per_pixel = simple_strtoul(options+4, NULL, 0);
 	}	
+	return 0;
 }
 
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c
--- a/drivers/video/valkyriefb.c	Mon Dec  9 18:46:50 2002
+++ b/drivers/video/valkyriefb.c	Mon Dec  9 18:46:50 2002
@@ -127,10 +127,6 @@
 int valkyriefb_init(void);
 int valkyriefb_setup(char*);
 
-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,
-			 struct fb_info *info);
 static int valkyrie_set_var(struct fb_var_screeninfo *var, int con,
 			 struct fb_info *info);
 static int valkyrie_get_cmap(struct fb_cmap *cmap, int kspc, int con,
@@ -157,8 +153,6 @@
 
 static struct fb_ops valkyriefb_ops = {
 	.owner =	THIS_MODULE,
-	.fb_get_fix =	valkyrie_get_fix,
-	.fb_get_var =	valkyrie_get_var,
 	.fb_set_var =	valkyrie_set_var,
 	.fb_get_cmap =	valkyrie_get_cmap,
 	.fb_set_cmap =	gen_set_cmap,
@@ -169,24 +163,6 @@
 static int valkyriefb_getcolreg(u_int regno, u_int *red, u_int *green,
 			     u_int *blue, u_int *transp, struct fb_info *info);
 
-static int valkyrie_get_fix(struct fb_fix_screeninfo *fix, int con,
-			 struct fb_info *info)
-{
-	struct fb_info_valkyrie *cp = (struct fb_info_valkyrie *) info;
-
-	*fix = cp->fix;
-	return 0;
-}
-
-static int valkyrie_get_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *info)
-{
-	struct fb_info_valkyrie *cp = (struct fb_info_valkyrie *) info;
-
-	*var = cp->var;
-	return 0;
-}
-
 /* Sets everything according to var */
 static int valkyrie_set_var(struct fb_var_screeninfo *var, int con,
 			 struct fb_info *info)
@@ -705,7 +681,6 @@
 static void valkyrie_init_display(struct display *disp)
 {
 	memset(disp, 0, sizeof(*disp));
-	disp->type = /* fix->type */ FB_TYPE_PACKED_PIXELS;
 	disp->can_soft_blank = can_soft_blank;
 	disp->scrollmode = SCROLL_YREDRAW;
 }
@@ -714,8 +689,6 @@
   struct display *disp, struct fb_fix_screeninfo *fix, struct fb_info_valkyrie *p)
 {
 	disp->var = p->var;
-	disp->visual = fix->visual;
-	disp->line_length = fix->line_length;
 
 	if(disp->scrollmode != SCROLL_YREDRAW) {
 		printk(KERN_ERR "Scroll mode not YREDRAW in valkyrie_par_to_display\n");
diff -Nru a/drivers/video/vesafb.c b/drivers/video/vesafb.c
--- a/drivers/video/vesafb.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/video/vesafb.c	Mon Dec  9 18:46:34 2002
@@ -17,16 +17,12 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
-#include <linux/console.h>
-#include <linux/selection.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 
 #include <asm/io.h>
 #include <asm/mtrr.h>
 
-#include <video/fbcon.h>
-
 #define dac_reg	(0x3c8)
 #define dac_val	(0x3c9)
 
@@ -49,7 +45,6 @@
 	.accel	= FB_ACCEL_NONE,
 };
 
-static struct display disp;
 static struct fb_info fb_info;
 static u32 pseudo_palette[17];
 
@@ -64,7 +59,7 @@
 
 /* --------------------------------------------------------------------- */
 
-static int vesafb_pan_display(struct fb_var_screeninfo *var, int con,
+static int vesafb_pan_display(struct fb_var_screeninfo *var,
                               struct fb_info *info)
 {
 	int offset;
@@ -175,22 +170,18 @@
 
 static struct fb_ops vesafb_ops = {
 	.owner		= THIS_MODULE,
-	.fb_set_var	= gen_set_var,
-	.fb_get_cmap	= gen_get_cmap,
-	.fb_set_cmap	= gen_set_cmap,
 	.fb_setcolreg	= vesafb_setcolreg,
 	.fb_pan_display	= vesafb_pan_display,
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
+	.fb_cursor	= soft_cursor,
 };
 
 int __init vesafb_setup(char *options)
 {
 	char *this_opt;
 	
-	fb_info.fontname[0] = '\0';
-	
 	if (!options || !*options)
 		return 0;
 	
@@ -211,8 +202,6 @@
 			pmi_setpal=1;
 		else if (! strcmp(this_opt, "mtrr"))
 			mtrr=1;
-		else if (!strncmp(this_opt, "font:", 5))
-			strcpy(fb_info.fontname, this_opt+5);
 	}
 	return 0;
 }
@@ -351,27 +340,20 @@
 		}
 	}
 	
-	strcpy(fb_info.modename, vesafb_fix.id);
-	fb_info.changevar = NULL;
 	fb_info.node = NODEV;
 	fb_info.fbops = &vesafb_ops;
 	fb_info.var = vesafb_defined;
 	fb_info.fix = vesafb_fix;
-	fb_info.currcon = -1;
-	fb_info.disp = &disp;
-	fb_info.switch_con = gen_switch;
-	fb_info.updatevar = gen_update_var;
 	fb_info.pseudo_palette = pseudo_palette;
 	fb_info.flags = FBINFO_FLAG_DEFAULT;
 
 	fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0);
-	gen_set_disp(-1, &fb_info);
 
 	if (register_framebuffer(&fb_info)<0)
 		return -EINVAL;
 
 	printk(KERN_INFO "fb%d: %s frame buffer device\n",
-	       GET_FB_IDX(fb_info.node), fb_info.fix.id);
+	       minor(fb_info.node), fb_info.fix.id);
 	return 0;
 }
 
diff -Nru a/drivers/video/vfb.c b/drivers/video/vfb.c
--- a/drivers/video/vfb.c	Mon Dec  9 18:46:34 2002
+++ b/drivers/video/vfb.c	Mon Dec  9 18:46:34 2002
@@ -24,8 +24,6 @@
 #include <linux/fb.h>
 #include <linux/init.h>
 
-#include <video/fbcon.h>
-
     /*
      *  RAM we reserve for the frame buffer. This defines the maximum screen
      *  size
@@ -42,7 +40,6 @@
 
 static struct fb_info fb_info;
 static u32 vfb_pseudo_palette[17];
-static struct display disp;
 
 static struct fb_var_screeninfo vfb_default __initdata = {
 	.xres =		640,
@@ -90,23 +87,21 @@
 static int vfb_set_par(struct fb_info *info);
 static int vfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 			 u_int transp, struct fb_info *info);
-static int vfb_pan_display(struct fb_var_screeninfo *var, int con,
+static int vfb_pan_display(struct fb_var_screeninfo *var,
 			   struct fb_info *info);
 static int vfb_mmap(struct fb_info *info, struct file *file,
 		    struct vm_area_struct *vma);
 
 static struct fb_ops vfb_ops = {
-	.fb_set_var	gen_set_var,
-	.fb_get_cmap	gen_set_cmap,
-	.fb_set_cmap	gen_set_cmap,
-	.fb_check_var	vfb_check_var,
-	.fb_set_par	vfb_set_par,
-	.fb_setcolreg	vfb_setcolreg,
-	.fb_pan_display	vfb_pan_display,
-	.fb_fillrect	cfb_fillrect,
-	.fb_copyarea	cfb_copyarea,
-	.fb_imageblit	cfb_imageblit,
-	.fb_mmap	vfb_mmap,
+	.fb_check_var	= vfb_check_var,
+	.fb_set_par	= vfb_set_par,
+	.fb_setcolreg	= vfb_setcolreg,
+	.fb_pan_display	= vfb_pan_display,
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit,
+	.fb_cursor	= soft_cursor,
+	.fb_mmap	= vfb_mmap,
 };
 
     /*
@@ -356,7 +351,7 @@
      *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
      */
 
-static int vfb_pan_display(struct fb_var_screeninfo *var, int con,
+static int vfb_pan_display(struct fb_var_screeninfo *var,
 			   struct fb_info *info)
 {
 	if (var->vmode & FB_VMODE_YWRAP) {
@@ -444,13 +439,6 @@
 	fb_info.pseudo_palette = &vfb_pseudo_palette;
 	fb_info.flags = FBINFO_FLAG_DEFAULT;
 
-	strcpy(fb_info.modename, vfb_fix.id);
-	fb_info.changevar = NULL;
-	fb_info.currcon = -1;
-	fb_info.disp = &disp;
-	fb_info.switch_con = gen_switch;
-	fb_info.updatevar = gen_update_var;
-
 	fb_alloc_cmap(&fb_info.cmap, 256, 0);
 
 	if (register_framebuffer(&fb_info) < 0) {
@@ -460,7 +448,7 @@
 
 	printk(KERN_INFO
 	       "fb%d: Virtual frame buffer device, using %ldK of video memory\n",
-	       GET_FB_IDX(fb_info.node), videomemorysize >> 10);
+	       minor(fb_info.node), videomemorysize >> 10);
 	return 0;
 }
 
diff -Nru a/drivers/video/vga.h b/drivers/video/vga.h
--- a/drivers/video/vga.h	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,457 +0,0 @@
-/*
- * linux/include/video/vga.h -- standard VGA chipset interaction
- *
- * Copyright 1999 Jeff Garzik <jgarzik@pobox.com>
- * 
- * Copyright history from vga16fb.c:
- *	Copyright 1999 Ben Pfaff and Petr Vandrovec
- *	Based on VGA info at http://www.goodnet.com/~tinara/FreeVGA/home.htm
- *	Based on VESA framebuffer (c) 1998 Gerd Knorr
- *
- * 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 __linux_video_vga_h__
-#define __linux_video_vga_h__
-
-#include <linux/config.h>
-#include <linux/types.h>
-#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>
-
-
-/* Some of the code below is taken from SVGAlib.  The original,
-   unmodified copyright notice for that code is below. */
-/* VGAlib version 1.2 - (c) 1993 Tommy Frandsen                    */
-/*                                                                 */
-/* This library is free software; you can redistribute it and/or   */
-/* modify it without any restrictions. This library is distributed */
-/* in the hope that it will be useful, but without any warranty.   */
-
-/* Multi-chipset support Copyright 1993 Harm Hanemaayer */
-/* partially copyrighted (C) 1993 by Hartmut Schirmer */
-
-/* VGA data register ports */
-#define VGA_CRT_DC  	0x3D5	/* CRT Controller Data Register - color emulation */
-#define VGA_CRT_DM  	0x3B5	/* CRT Controller Data Register - mono emulation */
-#define VGA_ATT_R   	0x3C1	/* Attribute Controller Data Read Register */
-#define VGA_ATT_W   	0x3C0	/* Attribute Controller Data Write Register */
-#define VGA_GFX_D   	0x3CF	/* Graphics Controller Data Register */
-#define VGA_SEQ_D   	0x3C5	/* Sequencer Data Register */
-#define VGA_MIS_R   	0x3CC	/* Misc Output Read Register */
-#define VGA_MIS_W   	0x3C2	/* Misc Output Write Register */
-#define VGA_FTC_R	0x3CA	/* Feature Control Read Register */
-#define VGA_IS1_RC  	0x3DA	/* Input Status Register 1 - color emulation */
-#define VGA_IS1_RM  	0x3BA	/* Input Status Register 1 - mono emulation */
-#define VGA_PEL_D   	0x3C9	/* PEL Data Register */
-#define VGA_PEL_MSK 	0x3C6	/* PEL mask register */
-
-/* EGA-specific registers */
-#define EGA_GFX_E0	0x3CC	/* Graphics enable processor 0 */
-#define EGA_GFX_E1	0x3CA	/* Graphics enable processor 1 */
-
-/* VGA index register ports */
-#define VGA_CRT_IC  	0x3D4	/* CRT Controller Index - color emulation */
-#define VGA_CRT_IM  	0x3B4	/* CRT Controller Index - mono emulation */
-#define VGA_ATT_IW  	0x3C0	/* Attribute Controller Index & Data Write Register */
-#define VGA_GFX_I   	0x3CE	/* Graphics Controller Index */
-#define VGA_SEQ_I   	0x3C4	/* Sequencer Index */
-#define VGA_PEL_IW  	0x3C8	/* PEL Write Index */
-#define VGA_PEL_IR  	0x3C7	/* PEL Read Index */
-
-/* standard VGA indexes max counts */
-#define VGA_CRT_C   	0x19	/* Number of CRT Controller Registers */
-#define VGA_ATT_C   	0x15	/* Number of Attribute Controller Registers */
-#define VGA_GFX_C   	0x09	/* Number of Graphics Controller Registers */
-#define VGA_SEQ_C   	0x05	/* Number of Sequencer Registers */
-#define VGA_MIS_C   	0x01	/* Number of Misc Output Register */
-
-/* VGA misc register bit masks */
-#define VGA_MIS_COLOR		0x01
-#define VGA_MIS_ENB_MEM_ACCESS	0x02
-#define VGA_MIS_DCLK_28322_720	0x04
-#define VGA_MIS_ENB_PLL_LOAD	(0x04 | 0x08)
-#define VGA_MIS_SEL_HIGH_PAGE	0x20
-
-/* VGA CRT controller register indices */
-#define VGA_CRTC_H_TOTAL	0
-#define VGA_CRTC_H_DISP		1
-#define VGA_CRTC_H_BLANK_START	2
-#define VGA_CRTC_H_BLANK_END	3
-#define VGA_CRTC_H_SYNC_START	4
-#define VGA_CRTC_H_SYNC_END	5
-#define VGA_CRTC_V_TOTAL	6
-#define VGA_CRTC_OVERFLOW	7
-#define VGA_CRTC_PRESET_ROW	8
-#define VGA_CRTC_MAX_SCAN	9
-#define VGA_CRTC_CURSOR_START	0x0A
-#define VGA_CRTC_CURSOR_END	0x0B
-#define VGA_CRTC_START_HI	0x0C
-#define VGA_CRTC_START_LO	0x0D
-#define VGA_CRTC_CURSOR_HI	0x0E
-#define VGA_CRTC_CURSOR_LO	0x0F
-#define VGA_CRTC_V_SYNC_START	0x10
-#define VGA_CRTC_V_SYNC_END	0x11
-#define VGA_CRTC_V_DISP_END	0x12
-#define VGA_CRTC_OFFSET		0x13
-#define VGA_CRTC_UNDERLINE	0x14
-#define VGA_CRTC_V_BLANK_START	0x15
-#define VGA_CRTC_V_BLANK_END	0x16
-#define VGA_CRTC_MODE		0x17
-#define VGA_CRTC_LINE_COMPARE	0x18
-#define VGA_CRTC_REGS		VGA_CRT_C
-
-/* VGA CRT controller bit masks */
-#define VGA_CR11_LOCK_CR0_CR7	0x80 /* lock writes to CR0 - CR7 */
-#define VGA_CR17_H_V_SIGNALS_ENABLED 0x80
-
-/* VGA attribute controller register indices */
-#define VGA_ATC_PALETTE0	0x00
-#define VGA_ATC_PALETTE1	0x01
-#define VGA_ATC_PALETTE2	0x02
-#define VGA_ATC_PALETTE3	0x03
-#define VGA_ATC_PALETTE4	0x04
-#define VGA_ATC_PALETTE5	0x05
-#define VGA_ATC_PALETTE6	0x06
-#define VGA_ATC_PALETTE7	0x07
-#define VGA_ATC_PALETTE8	0x08
-#define VGA_ATC_PALETTE9	0x09
-#define VGA_ATC_PALETTEA	0x0A
-#define VGA_ATC_PALETTEB	0x0B
-#define VGA_ATC_PALETTEC	0x0C
-#define VGA_ATC_PALETTED	0x0D
-#define VGA_ATC_PALETTEE	0x0E
-#define VGA_ATC_PALETTEF	0x0F
-#define VGA_ATC_MODE		0x10
-#define VGA_ATC_OVERSCAN	0x11
-#define VGA_ATC_PLANE_ENABLE	0x12
-#define VGA_ATC_PEL		0x13
-#define VGA_ATC_COLOR_PAGE	0x14
-
-#define VGA_AR_ENABLE_DISPLAY	0x20
-
-/* VGA sequencer register indices */
-#define VGA_SEQ_RESET		0x00
-#define VGA_SEQ_CLOCK_MODE	0x01
-#define VGA_SEQ_PLANE_WRITE	0x02
-#define VGA_SEQ_CHARACTER_MAP	0x03
-#define VGA_SEQ_MEMORY_MODE	0x04
-
-/* VGA sequencer register bit masks */
-#define VGA_SR01_CHAR_CLK_8DOTS	0x01 /* bit 0: character clocks 8 dots wide are generated */
-#define VGA_SR01_SCREEN_OFF	0x20 /* bit 5: Screen is off */
-#define VGA_SR02_ALL_PLANES	0x0F /* bits 3-0: enable access to all planes */
-#define VGA_SR04_EXT_MEM	0x02 /* bit 1: allows complete mem access to 256K */
-#define VGA_SR04_SEQ_MODE	0x04 /* bit 2: directs system to use a sequential addressing mode */
-#define VGA_SR04_CHN_4M		0x08 /* bit 3: selects modulo 4 addressing for CPU access to display memory */
-
-/* VGA graphics controller register indices */
-#define VGA_GFX_SR_VALUE	0x00
-#define VGA_GFX_SR_ENABLE	0x01
-#define VGA_GFX_COMPARE_VALUE	0x02
-#define VGA_GFX_DATA_ROTATE	0x03
-#define VGA_GFX_PLANE_READ	0x04
-#define VGA_GFX_MODE		0x05
-#define VGA_GFX_MISC		0x06
-#define VGA_GFX_COMPARE_MASK	0x07
-#define VGA_GFX_BIT_MASK	0x08
-
-/* VGA graphics controller bit masks */
-#define VGA_GR06_GRAPHICS_MODE	0x01
-
-/* macro for composing an 8-bit VGA register index and value
- * into a single 16-bit quantity */
-#define VGA_OUT16VAL(v, r)       (((v) << 8) | (r))
-
-/* decide whether we should enable the faster 16-bit VGA register writes */
-#ifdef __LITTLE_ENDIAN
-#define VGA_OUTW_WRITE
-#endif
-
-
-/*
- * generic VGA port read/write
- */
- 
-static inline unsigned char vga_io_r (unsigned short port)
-{
-	return inb (port);
-}
-
-static inline void vga_io_w (unsigned short port, unsigned char val)
-{
-	outb (val, port);
-}
-
-static inline void vga_io_w_fast (unsigned short port, unsigned char reg,
-				  unsigned char val)
-{
-	outw (VGA_OUT16VAL (val, reg), port);
-}
-
-static inline unsigned char vga_mm_r (caddr_t regbase, unsigned short port)
-{
-	return readb (regbase + port);
-}
-
-static inline void vga_mm_w (caddr_t regbase, unsigned short port, unsigned char val)
-{
-	writeb (val, regbase + port);
-}
-
-static inline void vga_mm_w_fast (caddr_t regbase, unsigned short port,
-				  unsigned char reg, unsigned char val)
-{
-	writew (VGA_OUT16VAL (val, reg), regbase + port);
-}
-
-static inline unsigned char vga_r (caddr_t regbase, unsigned short port)
-{
-	if (regbase)
-		return vga_mm_r (regbase, port);
-	else
-		return vga_io_r (port);
-}
-
-static inline void vga_w (caddr_t regbase, unsigned short port, unsigned char val)
-{
-	if (regbase)
-		vga_mm_w (regbase, port, val);
-	else
-		vga_io_w (port, val);
-}
-
-
-static inline void vga_w_fast (caddr_t regbase, unsigned short port,
-			       unsigned char reg, unsigned char val)
-{
-	if (regbase)
-		vga_mm_w_fast (regbase, port, reg, val);
-	else
-		vga_io_w_fast (port, reg, val);
-}
-
-
-/*
- * VGA CRTC register read/write
- */
- 
-static inline unsigned char vga_rcrt (caddr_t regbase, unsigned char reg)
-{
-        vga_w (regbase, VGA_CRT_IC, reg);
-        return vga_r (regbase, VGA_CRT_DC);
-}
-
-static inline void vga_wcrt (caddr_t regbase, unsigned char reg, unsigned char val)
-{
-#ifdef VGA_OUTW_WRITE
-	vga_w_fast (regbase, VGA_CRT_IC, reg, val);
-#else
-        vga_w (regbase, VGA_CRT_IC, reg);
-        vga_w (regbase, VGA_CRT_DC, val);
-#endif /* VGA_OUTW_WRITE */
-}
-
-static inline unsigned char vga_io_rcrt (unsigned char reg)
-{
-        vga_io_w (VGA_CRT_IC, reg);
-        return vga_io_r (VGA_CRT_DC);
-}
-
-static inline void vga_io_wcrt (unsigned char reg, unsigned char val)
-{
-#ifdef VGA_OUTW_WRITE
-	vga_io_w_fast (VGA_CRT_IC, reg, val);
-#else
-        vga_io_w (VGA_CRT_IC, reg);
-        vga_io_w (VGA_CRT_DC, val);
-#endif /* VGA_OUTW_WRITE */
-}
-
-static inline unsigned char vga_mm_rcrt (caddr_t regbase, unsigned char reg)
-{
-        vga_mm_w (regbase, VGA_CRT_IC, reg);
-        return vga_mm_r (regbase, VGA_CRT_DC);
-}
-
-static inline void vga_mm_wcrt (caddr_t regbase, unsigned char reg, unsigned char val)
-{
-#ifdef VGA_OUTW_WRITE
-	vga_mm_w_fast (regbase, VGA_CRT_IC, reg, val);
-#else
-        vga_mm_w (regbase, VGA_CRT_IC, reg);
-        vga_mm_w (regbase, VGA_CRT_DC, val);
-#endif /* VGA_OUTW_WRITE */
-}
-
-
-/*
- * VGA sequencer register read/write
- */
- 
-static inline unsigned char vga_rseq (caddr_t regbase, unsigned char reg)
-{
-        vga_w (regbase, VGA_SEQ_I, reg);
-        return vga_r (regbase, VGA_SEQ_D);
-}
-
-static inline void vga_wseq (caddr_t regbase, unsigned char reg, unsigned char val)
-{
-#ifdef VGA_OUTW_WRITE
-	vga_w_fast (regbase, VGA_SEQ_I, reg, val);
-#else
-        vga_w (regbase, VGA_SEQ_I, reg);
-        vga_w (regbase, VGA_SEQ_D, val);
-#endif /* VGA_OUTW_WRITE */
-}
-
-static inline unsigned char vga_io_rseq (unsigned char reg)
-{
-        vga_io_w (VGA_SEQ_I, reg);
-        return vga_io_r (VGA_SEQ_D);
-}
-
-static inline void vga_io_wseq (unsigned char reg, unsigned char val)
-{
-#ifdef VGA_OUTW_WRITE
-	vga_io_w_fast (VGA_SEQ_I, reg, val);
-#else
-        vga_io_w (VGA_SEQ_I, reg);
-        vga_io_w (VGA_SEQ_D, val);
-#endif /* VGA_OUTW_WRITE */
-}
-
-static inline unsigned char vga_mm_rseq (caddr_t regbase, unsigned char reg)
-{
-        vga_mm_w (regbase, VGA_SEQ_I, reg);
-        return vga_mm_r (regbase, VGA_SEQ_D);
-}
-
-static inline void vga_mm_wseq (caddr_t regbase, unsigned char reg, unsigned char val)
-{
-#ifdef VGA_OUTW_WRITE
-	vga_mm_w_fast (regbase, VGA_SEQ_I, reg, val);
-#else
-        vga_mm_w (regbase, VGA_SEQ_I, reg);
-        vga_mm_w (regbase, VGA_SEQ_D, val);
-#endif /* VGA_OUTW_WRITE */
-}
-
-
-
-/*
- * VGA graphics controller register read/write
- */
- 
-static inline unsigned char vga_rgfx (caddr_t regbase, unsigned char reg)
-{
-        vga_w (regbase, VGA_GFX_I, reg);
-        return vga_r (regbase, VGA_GFX_D);
-}
-
-static inline void vga_wgfx (caddr_t regbase, unsigned char reg, unsigned char val)
-{
-#ifdef VGA_OUTW_WRITE
-	vga_w_fast (regbase, VGA_GFX_I, reg, val);
-#else
-        vga_w (regbase, VGA_GFX_I, reg);
-        vga_w (regbase, VGA_GFX_D, val);
-#endif /* VGA_OUTW_WRITE */
-}
-
-static inline unsigned char vga_io_rgfx (unsigned char reg)
-{
-        vga_io_w (VGA_GFX_I, reg);
-        return vga_io_r (VGA_GFX_D);
-}
-
-static inline void vga_io_wgfx (unsigned char reg, unsigned char val)
-{
-#ifdef VGA_OUTW_WRITE
-	vga_io_w_fast (VGA_GFX_I, reg, val);
-#else
-        vga_io_w (VGA_GFX_I, reg);
-        vga_io_w (VGA_GFX_D, val);
-#endif /* VGA_OUTW_WRITE */
-}
-
-static inline unsigned char vga_mm_rgfx (caddr_t regbase, unsigned char reg)
-{
-        vga_mm_w (regbase, VGA_GFX_I, reg);
-        return vga_mm_r (regbase, VGA_GFX_D);
-}
-
-static inline void vga_mm_wgfx (caddr_t regbase, unsigned char reg, unsigned char val)
-{
-#ifdef VGA_OUTW_WRITE
-	vga_mm_w_fast (regbase, VGA_GFX_I, reg, val);
-#else
-        vga_mm_w (regbase, VGA_GFX_I, reg);
-        vga_mm_w (regbase, VGA_GFX_D, val);
-#endif /* VGA_OUTW_WRITE */
-}
-
-
-/*
- * VGA attribute controller register read/write
- */
- 
-static inline unsigned char vga_rattr (caddr_t regbase, unsigned char reg)
-{
-        vga_w (regbase, VGA_ATT_IW, reg);
-        return vga_r (regbase, VGA_ATT_R);
-}
-
-static inline void vga_wattr (caddr_t regbase, unsigned char reg, unsigned char val)
-{
-        vga_w (regbase, VGA_ATT_IW, reg);
-        vga_w (regbase, VGA_ATT_W, val);
-}
-
-static inline unsigned char vga_io_rattr (unsigned char reg)
-{
-        vga_io_w (VGA_ATT_IW, reg);
-        return vga_io_r (VGA_ATT_R);
-}
-
-static inline void vga_io_wattr (unsigned char reg, unsigned char val)
-{
-        vga_io_w (VGA_ATT_IW, reg);
-        vga_io_w (VGA_ATT_W, val);
-}
-
-static inline unsigned char vga_mm_rattr (caddr_t regbase, unsigned char reg)
-{
-        vga_mm_w (regbase, VGA_ATT_IW, reg);
-        return vga_mm_r (regbase, VGA_ATT_R);
-}
-
-static inline void vga_mm_wattr (caddr_t regbase, unsigned char reg, unsigned char val)
-{
-        vga_mm_w (regbase, VGA_ATT_IW, reg);
-        vga_mm_w (regbase, VGA_ATT_W, val);
-}
-
-
-
-
-#endif /* __linux_video_vga_h__ */
diff -Nru a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
--- a/drivers/video/vga16fb.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/video/vga16fb.c	Mon Dec  9 18:46:35 2002
@@ -7,7 +7,8 @@
  *
  * 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.  */
+ * archive for more details.  
+ */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -18,35 +19,41 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
-#include <linux/console.h>
-#include <linux/selection.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
-#include <linux/interrupt.h>
 
 #include <asm/io.h>
+#include <video/vga.h>
+
+#define GRAPHICS_ADDR_REG VGA_GFX_I	/* Graphics address register. */
+#define GRAPHICS_DATA_REG VGA_GFX_D	/* Graphics data register. */
 
-#include <video/fbcon.h>
-#include <video/fbcon-vga-planes.h>
-#include "vga.h"
+#define SET_RESET_INDEX 	VGA_GFX_SR_VALUE	/* Set/Reset Register index. */
+#define ENABLE_SET_RESET_INDEX	VGA_GFX_SR_ENABLE	/* Enable Set/Reset Register index. */
+#define DATA_ROTATE_INDEX	VGA_GFX_DATA_ROTATE	/* Data Rotate Register index. */
+#define GRAPHICS_MODE_INDEX	VGA_GFX_MODE		/* Graphics Mode Register index. */
+#define BIT_MASK_INDEX		VGA_GFX_BIT_MASK	/* Bit Mask Register index. */
 
-#define dac_reg	(0x3c8)
-#define dac_val	(0x3c9)
+#define dac_reg	(VGA_PEL_IW)
+#define dac_val	(VGA_PEL_D)
 
 #define VGA_FB_PHYS 0xA0000
 #define VGA_FB_PHYS_LEN 65536
 
+#define MODE_SKIP4	1
+#define MODE_8BPP	2
+#define MODE_CFB	4
+#define MODE_TEXT	8
+
 /* --------------------------------------------------------------------- */
 
 /*
  * card parameters
  */
 
-static struct vga16fb_info {
-	struct fb_info  fb_info;
-	char *video_vbase;			/* 0xa0000 map address */
-	int isVGA;
-	
+static struct fb_info vga16fb; 
+
+static struct vga16fb_par {
 	/* structure holding original VGA register settings when the
            screen is blanked */
 	struct {
@@ -63,109 +70,200 @@
 		unsigned char	ModeControl;		/* CRT-Controller:17h */
 		unsigned char	ClockingMode;		/* Seq-Controller:01h */
 	} vga_state;
-
-	int palette_blanked;
-	int vesa_blanked;
-} vga16fb;
-
-
-struct vga16fb_par {
+	struct vgastate state;
+	atomic_t ref_count;
+	int palette_blanked, vesa_blanked, mode, isVGA;
+	u8 misc, pel_msk, vss, clkdiv;
 	u8 crtc[VGA_CRT_C];
-	u8 atc[VGA_ATT_C];
-	u8 gdc[VGA_GFX_C];
-	u8 seq[VGA_SEQ_C];
-	u8 misc;
-	u8 vss;
-	struct fb_var_screeninfo var;
-};
+} vga16_par;
 
 /* --------------------------------------------------------------------- */
 
 static struct fb_var_screeninfo vga16fb_defined = {
-        .xres           = 640,
-        .yres           = 480,
-        .xres_virtual   = 640,
-        .yres_virtual   = 480,
-        .bits_per_pixel = 4,
-        .activate       = FB_ACTIVATE_NOW,
-        .height         = -1,
-        .width          = -1,
-        .pixclock       = 39721,
-        .left_margin    = 48,
-        .right_margin   = 16,
-        .upper_margin   = 39,
-        .lower_margin   = 8,
-        .hsync_len      = 96,
-        .vsync_len      = 2,
-        .vmode          = FB_VMODE_NONINTERLACED,
+	.xres		= 640,
+	.yres		= 480,
+	.xres_virtual	= 640,
+	.yres_virtual	= 480,
+	.bits_per_pixel	= 4,	
+	.activate	= FB_ACTIVATE_TEST,
+	.height		= -1,
+	.width		= -1,
+	.pixclock	= 39721,
+	.left_margin	= 48,
+	.right_margin	= 16,
+	.upper_margin	= 39,
+	.lower_margin	= 8,
+	.hsync_len 	= 96,
+	.vsync_len	= 2,
+	.vmode		= FB_VMODE_NONINTERLACED,
 };
 
+/* name should not depend on EGA/VGA */
 static struct fb_fix_screeninfo vga16fb_fix __initdata = {
-        .id             = "VGA16 VGA",
-        .smem_start     = VGA_FB_PHYS,
-        .smem_len       = VGA_FB_PHYS_LEN,
-        .type           = FB_TYPE_VGA_PLANES,
-        .visual         = FB_VISUAL_PSEUDOCOLOR,
-        .xpanstep       = 8,
-        .ypanstep       = 1,
-        .line_length    = 640 / 8,
+	.id		= "VGA16 VGA",
+	.smem_start	= VGA_FB_PHYS,
+	.smem_len	= VGA_FB_PHYS_LEN,
+	.type		= FB_TYPE_VGA_PLANES,
+	.type_aux	= FB_AUX_VGA_PLANES_VGA4,
+	.visual		= FB_VISUAL_PSEUDOCOLOR,
+	.xpanstep	= 8,
+	.ypanstep	= 1,
+	.line_length	= 640/8,
+	.accel		= FB_ACCEL_NONE
 };
 
-static struct display disp;
-static struct { u_short blue, green, red, pad; } palette[256];
+/* The VGA's weird architecture often requires that we read a byte and
+   write a byte to the same location.  It doesn't matter *what* byte
+   we write, however.  This is because all the action goes on behind
+   the scenes in the VGA's 32-bit latch register, and reading and writing
+   video memory just invokes latch behavior.
+
+   To avoid race conditions (is this necessary?), reading and writing
+   the memory byte should be done with a single instruction.  One
+   suitable instruction is the x86 bitwise OR.  The following
+   read-modify-write routine should optimize to one such bitwise
+   OR. */
+static inline void rmw(volatile char *p)
+{
+	readb(p);
+	writeb(1, p);
+}
 
-/* --------------------------------------------------------------------- */
+/* Set the Graphics Mode Register, and return its previous value.
+   Bits 0-1 are write mode, bit 3 is read mode. */
+static inline int setmode(int mode)
+{
+	int oldmode;
+	
+	vga_io_w(GRAPHICS_ADDR_REG, GRAPHICS_MODE_INDEX);
+	oldmode = vga_io_r(GRAPHICS_DATA_REG);
+	vga_io_w(GRAPHICS_DATA_REG, mode);
+	return oldmode;
+}
 
-static void vga16fb_pan_var(struct fb_info *info, struct fb_var_screeninfo *var)
+/* Select the Bit Mask Register and return its value. */
+static inline int selectmask(void)
 {
-	u32 pos = (var->xres_virtual * var->yoffset + var->xoffset) >> 3;
-	outb(VGA_CRTC_START_HI, VGA_CRT_IC);
-	outb(pos >> 8, VGA_CRT_DC);
-	outb(VGA_CRTC_START_LO, VGA_CRT_IC);
-	outb(pos & 0xFF, VGA_CRT_DC);
-#if 0
-	/* if someone supports xoffset in bit resolution */
-	inb(VGA_IS1_RC);		/* reset flip-flop */
-	outb(VGA_ATC_PEL, VGA_ATT_IW);
-	outb(xoffset & 7, VGA_ATT_IW);
-	inb(VGA_IS1_RC);
-	outb(0x20, VGA_ATT_IW);
-#endif
+	return vga_io_rgfx(BIT_MASK_INDEX);
+}
+
+/* Set the value of the Bit Mask Register.  It must already have been
+   selected with selectmask(). */
+static inline void setmask(int mask)
+{
+	vga_io_w(GRAPHICS_DATA_REG, mask);
+}
+
+/* Set the Data Rotate Register and return its old value. 
+   Bits 0-2 are rotate count, bits 3-4 are logical operation
+   (0=NOP, 1=AND, 2=OR, 3=XOR). */
+static inline int setop(int op)
+{
+	int oldop;
+	
+	vga_io_w(GRAPHICS_ADDR_REG, DATA_ROTATE_INDEX);
+	oldop = vga_io_r(GRAPHICS_DATA_REG);
+	vga_io_w(GRAPHICS_DATA_REG, op);
+	return oldop;
+}
+
+/* Set the Enable Set/Reset Register and return its old value.  
+   The code here always uses value 0xf for thsi register. */
+static inline int setsr(int sr)
+{
+	int oldsr;
+
+	vga_io_w(GRAPHICS_ADDR_REG, ENABLE_SET_RESET_INDEX);
+	oldsr = vga_io_r(GRAPHICS_DATA_REG);
+	vga_io_w(GRAPHICS_DATA_REG, sr);
+	return oldsr;
 }
 
-static void vga16fb_set_disp(int con, struct vga16fb_info *info)
+/* Set the Set/Reset Register and return its old value. */
+static inline int setcolor(int color)
 {
-        struct display *display = (con < 0) ? info->fb_info.disp : (fb_display + con);
+	int oldcolor;
+
+	vga_io_w(GRAPHICS_ADDR_REG, SET_RESET_INDEX);
+	oldcolor = vga_io_r(GRAPHICS_DATA_REG);
+	vga_io_w(GRAPHICS_DATA_REG, color);
+	return oldcolor;
+}
 
-	display->can_soft_blank = 1;
-        display->dispsw_data = NULL;
-        display->var = info->fb_info.var;
-	display->inverse = 0;
-
-        /*
-         * If we are setting all the virtual consoles, also set
-         * the defaults used to create new consoles.
-         */
-        if (con < 0 || info->fb_info.var.activate & FB_ACTIVATE_ALL)
-                info->fb_info.disp->var = info->fb_info.var;
+/* Return the value in the Graphics Address Register. */
+static inline int getindex(void)
+{
+	return vga_io_r(GRAPHICS_ADDR_REG);
+}
 
-	if (info->isVGA)
-		display->dispsw = &fbcon_vga_planes;
+/* Set the value in the Graphics Address Register. */
+static inline void setindex(int index)
+{
+	vga_io_w(GRAPHICS_ADDR_REG, index);
+}
+
+static void vga16fb_pan_var(struct fb_info *info, 
+			    struct fb_var_screeninfo *var)
+{
+	struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+	u32 xoffset, pos;
+
+	xoffset = var->xoffset;
+	if (info->var.bits_per_pixel == 8) {
+		pos = (info->var.xres_virtual * var->yoffset + xoffset) >> 2;
+	} else if (par->mode & MODE_TEXT) {
+		int fh = 16; // FIXME !!! font height. Fugde for now.
+		pos = (info->var.xres_virtual * (var->yoffset / fh) + xoffset) >> 3;
+	} else {
+		if (info->var.nonstd)
+			xoffset--;
+		pos = (info->var.xres_virtual * var->yoffset + xoffset) >> 3;
+	}
+	vga_io_wcrt(VGA_CRTC_START_HI, pos >> 8);
+	vga_io_wcrt(VGA_CRTC_START_LO, pos & 0xFF);
+	/* if we support CFB4, then we must! support xoffset with pixel
+	 * granularity if someone supports xoffset in bit resolution */
+	vga_io_r(VGA_IS1_RC);		/* reset flip-flop */
+	vga_io_w(VGA_ATT_IW, VGA_ATC_PEL);
+	if (var->bits_per_pixel == 8)
+		vga_io_w(VGA_ATT_IW, (xoffset & 3) << 1);
 	else
-		display->dispsw = &fbcon_ega_planes;
-	display->scrollmode = SCROLL_YREDRAW;
+		vga_io_w(VGA_ATT_IW, xoffset & 7);
+	vga_io_r(VGA_IS1_RC);
+	vga_io_w(VGA_ATT_IW, 0x20);
 }
 
-static void vga16fb_encode_var(struct fb_var_screeninfo *var,
-			       const struct vga16fb_par *par,
-			       const struct vga16fb_info *info)
+static void vga16fb_update_fix(struct fb_info *info)
 {
-	*var = par->var;
+	if (info->var.bits_per_pixel == 4) {
+		if (info->var.nonstd) {
+			info->fix.type = FB_TYPE_PACKED_PIXELS;
+			info->fix.line_length = info->var.xres_virtual / 2;
+		} else {
+			info->fix.type = FB_TYPE_VGA_PLANES;
+			info->fix.type_aux = FB_AUX_VGA_PLANES_VGA4;
+			info->fix.line_length = info->var.xres_virtual / 8;
+		}
+	} else if (info->var.bits_per_pixel == 0) {
+		info->fix.type = FB_TYPE_TEXT;
+		info->fix.type_aux = FB_AUX_TEXT_CGA;
+		info->fix.line_length = info->var.xres_virtual / 4;
+	} else {	/* 8bpp */
+		if (info->var.nonstd) {
+			info->fix.type = FB_TYPE_VGA_PLANES;
+			info->fix.type_aux = FB_AUX_VGA_PLANES_CFB8;
+			info->fix.line_length = info->var.xres_virtual / 4;
+		} else {
+			info->fix.type = FB_TYPE_PACKED_PIXELS;
+			info->fix.line_length = info->var.xres_virtual;
+		}
+	}
 }
 
 static void vga16fb_clock_chip(struct vga16fb_par *par,
 			       unsigned int pixclock,
-			       const struct vga16fb_info *info)
+			       const struct fb_info *info,
+			       int mul, int div)
 {
 	static struct {
 		u32 pixclock;
@@ -179,6 +277,7 @@
 		{     0 /* bad */,    0x00, 0x00}};
 	int err;
 
+	pixclock = (pixclock * mul) / div;
 	best = vgaclocks;
 	err = pixclock - best->pixclock;
 	if (err < 0) err = -err;
@@ -193,25 +292,98 @@
 		}
 	}
 	par->misc |= best->misc;
-	par->seq[VGA_SEQ_CLOCK_MODE] |= best->seq_clock_mode;
-	par->var.pixclock = best->pixclock;		
+	par->clkdiv = best->seq_clock_mode;
+	pixclock = (best->pixclock * div) / mul;		
 }
 			       
 #define FAIL(X) return -EINVAL
 
-static int vga16fb_decode_var(const struct fb_var_screeninfo *var,
-			      struct vga16fb_par *par,
-			      const struct vga16fb_info *info)
+static int vga16fb_open(struct fb_info *info, int user)
+{
+	struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+	int cnt = atomic_read(&par->ref_count);
+
+	if (!cnt) {
+		memset(&par->state, 0, sizeof(struct vgastate));
+		par->state.flags = 8;
+		save_vga(&par->state);
+	}
+	atomic_inc(&par->ref_count);
+	return 0;
+}
+
+static int vga16fb_release(struct fb_info *info, int user)
+{
+	struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+	int cnt = atomic_read(&par->ref_count);
+
+	if (!cnt)
+		return -EINVAL;
+	if (cnt == 1)
+		restore_vga(&par->state);
+	atomic_dec(&par->ref_count);
+
+	return 0;
+}
+
+static int vga16fb_check_var(struct fb_var_screeninfo *var,
+			     struct fb_info *info)
 {
+#ifdef FBCON_HAS_VGA
+	struct display *p = (info->currcon < 0) ? info->disp : (fb_display + info->currcon);
+#endif
+	struct vga16fb_par *par = (struct vga16fb_par *) info->par;
 	u32 xres, right, hslen, left, xtotal;
 	u32 yres, lower, vslen, upper, ytotal;
 	u32 vxres, xoffset, vyres, yoffset;
 	u32 pos;
 	u8 r7, rMode;
-	int i;
-
-	if (var->bits_per_pixel != 4)
+	int shift;
+	int mode;
+	u32 maxmem;
+
+	par->pel_msk = 0xFF;
+
+	if (var->bits_per_pixel == 4) {
+		if (var->nonstd) {
+			if (!par->isVGA)
+				return -EINVAL;
+			shift = 3;
+			mode = MODE_SKIP4 | MODE_CFB;
+			maxmem = 16384;
+			par->pel_msk = 0x0F;
+		} else {
+			shift = 3;
+			mode = 0;
+			maxmem = 65536;
+		}
+	} else if (var->bits_per_pixel == 8) {
+		if (!par->isVGA)
+			return -EINVAL;	/* no support on EGA */
+		shift = 2;
+		if (var->nonstd) {
+			mode = MODE_8BPP | MODE_CFB;
+			maxmem = 65536;
+		} else {
+			mode = MODE_SKIP4 | MODE_8BPP | MODE_CFB;
+			maxmem = 16384;
+		}
+	}
+#ifdef FBCON_HAS_VGA	
+	else if (var->bits_per_pixel == 0) {
+		int fh;
+
+		shift = 3;
+		mode = MODE_TEXT;
+		fh = fontheight(p);
+		if (!fh)
+			fh = 16;
+		maxmem = 32768 * fh;
+	}
+#endif
+	else
 		return -EINVAL;
+
 	xres = (var->xres + 7) & ~7;
 	vxres = (var->xres_virtual + 0xF) & ~0xF;
 	xoffset = (var->xoffset + 7) & ~7;
@@ -224,18 +396,18 @@
 	if (xres + xoffset > vxres)
 		xoffset = vxres - xres;
 
-	par->var.xres = xres;
-	par->var.right_margin = right;
-	par->var.hsync_len = hslen;
-	par->var.left_margin = left;
-	par->var.xres_virtual = vxres;
-	par->var.xoffset = xoffset;
-
-	xres >>= 3;
-	right >>= 3;
-	hslen >>= 3;
-	left >>= 3;
-	vxres >>= 3;
+	var->xres = xres;
+	var->right_margin = right;
+	var->hsync_len = hslen;
+	var->left_margin = left;
+	var->xres_virtual = vxres;
+	var->xoffset = xoffset;
+
+	xres >>= shift;
+	right >>= shift;
+	hslen >>= shift;
+	left >>= shift;
+	vxres >>= shift;
 	xtotal = xres + right + hslen + left;
 	if (xtotal >= 256)
 		FAIL("xtotal too big");
@@ -264,19 +436,19 @@
 
 	if (yres > vyres)
 		vyres = yres;
-	if (vxres * vyres > 65536) {
-		vyres = 65536 / vxres;
+	if (vxres * vyres > maxmem) {
+		vyres = maxmem / vxres;
 		if (vyres < yres)
 			return -ENOMEM;
 	}
 	if (yoffset + yres > vyres)
 		yoffset = vyres - yres;
-	par->var.yres = yres;
-	par->var.lower_margin = lower;
-	par->var.vsync_len = vslen;
-	par->var.upper_margin = upper;
-	par->var.yres_virtual = vyres;
-	par->var.yoffset = yoffset;
+	var->yres = yres;
+	var->lower_margin = lower;
+	var->vsync_len = vslen;
+	var->upper_margin = upper;
+	var->yres_virtual = vyres;
+	var->yoffset = yoffset;
 
 	if (var->vmode & FB_VMODE_DOUBLE) {
 		yres <<= 1;
@@ -304,12 +476,13 @@
 	if (ytotal & 0x200) r7 |= 0x20;
 	par->crtc[VGA_CRTC_PRESET_ROW] = 0;
 	par->crtc[VGA_CRTC_MAX_SCAN] = 0x40;	/* 1 scanline, no linecmp */
-	par->var.vmode = var->vmode;
 	if (var->vmode & FB_VMODE_DOUBLE)
 		par->crtc[VGA_CRTC_MAX_SCAN] |= 0x80;
 	par->crtc[VGA_CRTC_CURSOR_START] = 0x20;
 	par->crtc[VGA_CRTC_CURSOR_END]   = 0x00;
-	pos = yoffset * vxres + (xoffset >> 3);
+	if ((mode & (MODE_CFB | MODE_8BPP)) == MODE_CFB)
+		xoffset--;
+	pos = yoffset * vxres + (xoffset >> shift);
 	par->crtc[VGA_CRTC_START_HI]     = pos >> 8;
 	par->crtc[VGA_CRTC_START_LO]     = pos & 0xFF;
 	par->crtc[VGA_CRTC_CURSOR_HI]    = 0x00;
@@ -337,166 +510,199 @@
 	if (vxres >= 512)
 		FAIL("vxres too long");
 	par->crtc[VGA_CRTC_OFFSET] = vxres >> 1;
-	par->crtc[VGA_CRTC_UNDERLINE] = 0x1F;
-	par->crtc[VGA_CRTC_MODE] = rMode | 0xE3;
+	if (mode & MODE_SKIP4)
+		par->crtc[VGA_CRTC_UNDERLINE] = 0x5F;	/* 256, cfb8 */
+	else
+		par->crtc[VGA_CRTC_UNDERLINE] = 0x1F;	/* 16, vgap */
+	par->crtc[VGA_CRTC_MODE] = rMode | ((mode & MODE_TEXT) ? 0xA3 : 0xE3);
 	par->crtc[VGA_CRTC_LINE_COMPARE] = 0xFF;
 	par->crtc[VGA_CRTC_OVERFLOW] = r7;
 
 	par->vss = 0x00;	/* 3DA */
 
-	for (i = 0x00; i < 0x10; i++)
-		par->atc[i] = i;
-	par->atc[VGA_ATC_MODE] = 0x81;
-	par->atc[VGA_ATC_OVERSCAN] = 0x00;	/* 0 for EGA, 0xFF for VGA */
-	par->atc[VGA_ATC_PLANE_ENABLE] = 0x0F;
-	par->atc[VGA_ATC_PEL] = xoffset & 7;
-	par->atc[VGA_ATC_COLOR_PAGE] = 0x00;
-	
-	par->misc = 0xC3;	/* enable CPU, ports 0x3Dx, positive sync */
-	par->var.sync = var->sync;
+	par->misc = 0xE3;	/* enable CPU, ports 0x3Dx, positive sync */
 	if (var->sync & FB_SYNC_HOR_HIGH_ACT)
 		par->misc &= ~0x40;
 	if (var->sync & FB_SYNC_VERT_HIGH_ACT)
 		par->misc &= ~0x80;
 	
-	par->seq[VGA_SEQ_CLOCK_MODE] = 0x01;
-	par->seq[VGA_SEQ_PLANE_WRITE] = 0x0F;
-	par->seq[VGA_SEQ_CHARACTER_MAP] = 0x00;
-	par->seq[VGA_SEQ_MEMORY_MODE] = 0x06;
-	
-	par->gdc[VGA_GFX_SR_VALUE] = 0x00;
-	par->gdc[VGA_GFX_SR_ENABLE] = 0x0F;
-	par->gdc[VGA_GFX_COMPARE_VALUE] = 0x00;
-	par->gdc[VGA_GFX_DATA_ROTATE] = 0x20;
-	par->gdc[VGA_GFX_PLANE_READ] = 0;
-	par->gdc[VGA_GFX_MODE] = 0x00;
-	par->gdc[VGA_GFX_MISC] = 0x05;
-	par->gdc[VGA_GFX_COMPARE_MASK] = 0x0F;
-	par->gdc[VGA_GFX_BIT_MASK] = 0xFF;
-
-	vga16fb_clock_chip(par, var->pixclock, info);
-
-	par->var.bits_per_pixel = 4;
-	par->var.grayscale = var->grayscale;
-	par->var.red.offset = par->var.green.offset = par->var.blue.offset = 
-	par->var.transp.offset = 0;
-	par->var.red.length = par->var.green.length = par->var.blue.length =
-		(info->isVGA) ? 6 : 2;
-	par->var.transp.length = 0;
-	par->var.nonstd = 0;
-	par->var.activate = FB_ACTIVATE_NOW;
-	par->var.height = -1;
-	par->var.width = -1;
-	par->var.accel_flags = 0;
+	par->mode = mode;
+
+	if (mode & MODE_8BPP)
+		/* pixel clock == vga clock / 2 */
+		vga16fb_clock_chip(par, var->pixclock, info, 1, 2);
+	else
+		/* pixel clock == vga clock */
+		vga16fb_clock_chip(par, var->pixclock, info, 1, 1);
 	
+	var->red.offset = var->green.offset = var->blue.offset = 
+	var->transp.offset = 0;
+	var->red.length = var->green.length = var->blue.length =
+		(par->isVGA) ? 6 : 2;
+	var->transp.length = 0;
+	var->activate = FB_ACTIVATE_NOW;
+	var->height = -1;
+	var->width = -1;
+	var->accel_flags = 0;
 	return 0;
 }
 #undef FAIL
 
-static int vga16fb_set_par(const struct vga16fb_par *par,
-			   struct vga16fb_info *info)
+#ifdef FBCON_HAS_VGA
+static void vga16fb_load_font(struct display* p)
 {
-	int i;
+	int chars;
+	unsigned char* font;
+	unsigned char* dest;
+	int chars;
+	
+	if (!p || !p->fontdata)
+		return;
+	chars = 256;
+	font = p->fontdata;
+	dest = vga16fb.screen_base;
+	
+	vga_io_wseq(0x00, 0x01);
+	vga_io_wseq(VGA_SEQ_PLANE_WRITE, 0x04);
+	vga_io_wseq(VGA_SEQ_MEMORY_MODE, 0x07);
+	vga_io_wseq(0x00, 0x03);
+	vga_io_wgfx(VGA_GFX_MODE, 0x00);
+	vga_io_wgfx(VGA_GFX_MISC, 0x04);
+	while (chars--) {
+		int i;
+		
+		for (i = fontheight(p); i > 0; i--)
+			writeb(*font++, dest++);
+		dest += 32 - fontheight(p);
+	}
+	vga_io_wseq(0x00, 0x01);
+	vga_io_wseq(VGA_SEQ_PLANE_WRITE, 0x03);
+	vga_io_wseq(VGA_SEQ_MEMORY_MODE, 0x03);
+	vga_io_wseq(0x00, 0x03);
+	vga_io_wgfx(VGA_GFX_MODE, 0x10);
+	vga_io_wgfx(VGA_GFX_MISC, 0x06);
+}
+#endif
+
+static int vga16fb_set_par(struct fb_info *info)
+{
+	struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+	u8 gdc[VGA_GFX_C];
+	u8 seq[VGA_SEQ_C];
+	u8 atc[VGA_ATT_C];
+	int fh, i;
+
+	seq[VGA_SEQ_CLOCK_MODE] = 0x01 | par->clkdiv;
+	if (par->mode & MODE_TEXT)
+		seq[VGA_SEQ_PLANE_WRITE] = 0x03;
+	else
+		seq[VGA_SEQ_PLANE_WRITE] = 0x0F;
+	seq[VGA_SEQ_CHARACTER_MAP] = 0x00;
+	if (par->mode & MODE_TEXT)
+		seq[VGA_SEQ_MEMORY_MODE] = 0x03;
+	else if (par->mode & MODE_SKIP4)
+		seq[VGA_SEQ_MEMORY_MODE] = 0x0E;
+	else
+		seq[VGA_SEQ_MEMORY_MODE] = 0x06;
+
+	gdc[VGA_GFX_SR_VALUE] = 0x00;
+	gdc[VGA_GFX_SR_ENABLE] = 0x00;
+	gdc[VGA_GFX_COMPARE_VALUE] = 0x00;
+	gdc[VGA_GFX_DATA_ROTATE] = 0x00;
+	gdc[VGA_GFX_PLANE_READ] = 0;
+	if (par->mode & MODE_TEXT) {
+		gdc[VGA_GFX_MODE] = 0x10;
+		gdc[VGA_GFX_MISC] = 0x06;
+	} else {
+		if (par->mode & MODE_CFB)
+			gdc[VGA_GFX_MODE] = 0x40;
+		else
+			gdc[VGA_GFX_MODE] = 0x00;
+		gdc[VGA_GFX_MISC] = 0x05;
+	}
+	gdc[VGA_GFX_COMPARE_MASK] = 0x0F;
+	gdc[VGA_GFX_BIT_MASK] = 0xFF;
+
+	for (i = 0x00; i < 0x10; i++)
+		atc[i] = i;
+	if (par->mode & MODE_TEXT)
+		atc[VGA_ATC_MODE] = 0x04;
+	else if (par->mode & MODE_8BPP)
+		atc[VGA_ATC_MODE] = 0x41;
+	else
+		atc[VGA_ATC_MODE] = 0x81;
+	atc[VGA_ATC_OVERSCAN] = 0x00;	/* 0 for EGA, 0xFF for VGA */
+	atc[VGA_ATC_PLANE_ENABLE] = 0x0F;
+	if (par->mode & MODE_8BPP)
+		atc[VGA_ATC_PEL] = (info->var.xoffset & 3) << 1;
+	else
+		atc[VGA_ATC_PEL] = info->var.xoffset & 7;
+	atc[VGA_ATC_COLOR_PAGE] = 0x00;
+	
+	if (par->mode & MODE_TEXT) {
+		fh = 16; // FIXME !!! Fudge font height. 
+		par->crtc[VGA_CRTC_MAX_SCAN] = (par->crtc[VGA_CRTC_MAX_SCAN] 
+					       & ~0x1F) | (fh - 1);
+	}
 
-	outb(inb(VGA_MIS_R) | 0x01, VGA_MIS_W);
+	vga_io_w(VGA_MIS_W, vga_io_r(VGA_MIS_R) | 0x01);
 
 	/* Enable graphics register modification */
-	if (!info->isVGA) {
-		outb(0x00, EGA_GFX_E0);
-		outb(0x01, EGA_GFX_E1);
+	if (!par->isVGA) {
+		vga_io_w(EGA_GFX_E0, 0x00);
+		vga_io_w(EGA_GFX_E1, 0x01);
 	}
 	
 	/* update misc output register */
-	outb(par->misc, VGA_MIS_W);
+	vga_io_w(VGA_MIS_W, par->misc);
 	
 	/* synchronous reset on */
-	outb(0x00, VGA_SEQ_I);
-	outb(0x01, VGA_SEQ_D);
-	
+	vga_io_wseq(0x00, 0x01);
+
+	if (par->isVGA)
+		vga_io_w(VGA_PEL_MSK, par->pel_msk);
+
 	/* write sequencer registers */
-	outb(1, VGA_SEQ_I);
-	outb(par->seq[1] | 0x20, VGA_SEQ_D);
+	vga_io_wseq(VGA_SEQ_CLOCK_MODE, seq[VGA_SEQ_CLOCK_MODE] | 0x20);
 	for (i = 2; i < VGA_SEQ_C; i++) {
-		outb(i, VGA_SEQ_I);
-		outb(par->seq[i], VGA_SEQ_D);
+		vga_io_wseq(i, seq[i]);
 	}
 	
 	/* synchronous reset off */
-	outb(0x00, VGA_SEQ_I);
-	outb(0x03, VGA_SEQ_D);
-	
+	vga_io_wseq(0x00, 0x03);
+
 	/* deprotect CRT registers 0-7 */
-	outb(0x11, VGA_CRT_IC);
-	outb(par->crtc[0x11], VGA_CRT_DC);
+	vga_io_wcrt(VGA_CRTC_V_SYNC_END, par->crtc[VGA_CRTC_V_SYNC_END]);
 
 	/* write CRT registers */
-	for (i = 0; i < VGA_CRT_C; i++) {
-		outb(i, VGA_CRT_IC);
-		outb(par->crtc[i], VGA_CRT_DC);
+	for (i = 0; i < VGA_CRTC_REGS; i++) {
+		vga_io_wcrt(i, par->crtc[i]);
 	}
 	
 	/* write graphics controller registers */
 	for (i = 0; i < VGA_GFX_C; i++) {
-		outb(i, VGA_GFX_I);
-		outb(par->gdc[i], VGA_GFX_D);
+		vga_io_wgfx(i, gdc[i]);
 	}
 	
 	/* write attribute controller registers */
 	for (i = 0; i < VGA_ATT_C; i++) {
-		inb_p(VGA_IS1_RC);		/* reset flip-flop */
-		outb_p(i, VGA_ATT_IW);
-		outb_p(par->atc[i], VGA_ATT_IW);
+		vga_io_r(VGA_IS1_RC);		/* reset flip-flop */
+		vga_io_wattr(i, atc[i]);
 	}
 
+#ifdef FBCON_HAS_VGA
+	if (par->mode & MODE_TEXT)
+		vga16fb_load_font(p);
+#endif	
 	/* Wait for screen to stabilize. */
 	mdelay(50);
 
-	outb(0x01, VGA_SEQ_I);
-	outb(par->seq[1], VGA_SEQ_D);
-
-	inb(VGA_IS1_RC);
-	outb(0x20, VGA_ATT_IW);
-	
-	return 0;
-}
+	vga_io_wseq(VGA_SEQ_CLOCK_MODE, seq[VGA_SEQ_CLOCK_MODE]);
 
-static int vga16fb_set_var(struct fb_var_screeninfo *var, int con,
-			  struct fb_info *fb)
-{
-	struct vga16fb_info *info = (struct vga16fb_info*)fb;
-	struct vga16fb_par par;
-        struct display *display = (con < 0) ? fb->disp : (fb_display + con);
-	int err;
-
-	if ((err = vga16fb_decode_var(var, &par, info)) != 0)
-		return err;
-	vga16fb_encode_var(var, &par, info);
-	
-	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST)
-		return 0;
-
-	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
-		u32 oldxres, oldyres, oldvxres, oldvyres, oldbpp;
-
-		oldxres = display->var.xres;
-		oldyres = display->var.yres;
-		oldvxres = display->var.xres_virtual;
-		oldvyres = display->var.yres_virtual;
-		oldbpp = display->var.bits_per_pixel;
-
-		display->var = *var;
-
-		if (oldxres != var->xres || oldyres != var->yres ||
-		    oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
-		    oldbpp != var->bits_per_pixel) {
-			vga16fb_set_disp(con, info);
-			if (info->fb_info.changevar)
-				info->fb_info.changevar(con);
-		}
-		if (con == info->fb_info.currcon)
-			vga16fb_set_par(&par, info);
-	}
+	vga_io_r(VGA_IS1_RC);
+	vga_io_w(VGA_ATT_IW, 0x20);
 
+	vga16fb_update_fix(info);
 	return 0;
 }
 
@@ -505,12 +711,13 @@
 	static unsigned char map[] = { 000, 001, 010, 011 };
 	int val;
 	
+	if (regno >= 16)
+		return;
 	val = map[red>>14] | ((map[green>>14]) << 1) | ((map[blue>>14]) << 2);
-	inb_p(0x3DA);   /* ! 0x3BA */
-	outb_p(regno, 0x3C0);
-	outb_p(val, 0x3C0);
-	inb_p(0x3DA);   /* some clones need it */
-	outb_p(0x20, 0x3C0); /* unblank screen */
+	vga_io_r(VGA_IS1_RC);   /* ! 0x3BA */
+	vga_io_wattr(regno, val);
+	vga_io_r(VGA_IS1_RC);   /* some clones need it */
+	vga_io_w(VGA_ATT_IW, 0x20); /* unblank screen */
 }
 
 static void vga16_setpalette(int regno, unsigned red, unsigned green, unsigned blue)
@@ -523,8 +730,9 @@
 
 static int vga16fb_setcolreg(unsigned regno, unsigned red, unsigned green,
 			     unsigned blue, unsigned transp,
-			     struct fb_info *fb_info)
+			     struct fb_info *info)
 {
+	struct vga16fb_par *par = (struct vga16fb_par *) info->par;
 	int gray;
 
 	/*
@@ -534,40 +742,34 @@
 	 *  != 0 for invalid regno.
 	 */
 	
-	if (regno >= 16)
+	if (regno >= 256)
 		return 1;
 
-	palette[regno].red   = red;
-	palette[regno].green = green;
-	palette[regno].blue  = blue;
+	gray = info->var.grayscale;
 	
-	if (fb_info->currcon < 0)
-		gray = disp.var.grayscale;
-	else
-		gray = fb_display[fb_info->currcon].var.grayscale;
 	if (gray) {
 		/* gray = 0.30*R + 0.59*G + 0.11*B */
 		red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
 	}
-	if (((struct vga16fb_info *) fb_info)->isVGA) 
+	if (par->isVGA) 
 		vga16_setpalette(regno,red,green,blue);
 	else
 		ega16_setpalette(regno,red,green,blue);
-	
 	return 0;
 }
 
-static int vga16fb_pan_display(struct fb_var_screeninfo *var, int con,
+static int vga16fb_pan_display(struct fb_var_screeninfo *var,
 			       struct fb_info *info) 
 {
-	if (var->xoffset + fb_display[con].var.xres > fb_display[con].var.xres_virtual ||
-	    var->yoffset + fb_display[con].var.yres > fb_display[con].var.yres_virtual)
+	if (var->xoffset + info->var.xres > info->var.xres_virtual ||
+	    var->yoffset + info->var.yres > info->var.yres_virtual)
 		return -EINVAL;
-	if (con == info->currcon)
-		vga16fb_pan_var(info, var);
-	fb_display[con].var.xoffset = var->xoffset;
-	fb_display[con].var.yoffset = var->yoffset;
-	fb_display[con].var.vmode &= ~FB_VMODE_YWRAP;
+
+	vga16fb_pan_var(info, var);
+
+	info->var.xoffset = var->xoffset;
+	info->var.yoffset = var->yoffset;
+	info->var.vmode &= ~FB_VMODE_YWRAP;
 	return 0;
 }
 
@@ -575,59 +777,49 @@
    blanking code was originally by Huang shi chao, and modified by
    Christoph Rimek (chrimek@toppoint.de) and todd j. derr
    (tjd@barefoot.org) for Linux. */
-#define attrib_port	0x3c0
-#define seq_port_reg	0x3c4
-#define seq_port_val	0x3c5
-#define gr_port_reg	0x3ce
-#define gr_port_val	0x3cf
-#define video_misc_rd	0x3cc
-#define video_misc_wr	0x3c2
-#define vga_video_port_reg	0x3d4
-#define vga_video_port_val	0x3d5
+#define attrib_port		VGA_ATC_IW
+#define seq_port_reg		VGA_SEQ_I
+#define seq_port_val		VGA_SEQ_D
+#define gr_port_reg		VGA_GFX_I
+#define gr_port_val		VGA_GFX_D
+#define video_misc_rd		VGA_MIS_R
+#define video_misc_wr		VGA_MIS_W
+#define vga_video_port_reg	VGA_CRT_IC
+#define vga_video_port_val	VGA_CRT_DC
 
-static void vga_vesa_blank(struct vga16fb_info *info, int mode)
+static void vga_vesa_blank(struct vga16fb_par *par, int mode)
 {
 	unsigned char SeqCtrlIndex;
 	unsigned char CrtCtrlIndex;
 	
-	cli();
-	SeqCtrlIndex = inb_p(seq_port_reg);
-	CrtCtrlIndex = inb_p(vga_video_port_reg);
+	//cli();
+	SeqCtrlIndex = vga_io_r(seq_port_reg);
+	CrtCtrlIndex = vga_io_r(vga_video_port_reg);
 
 	/* save original values of VGA controller registers */
-	if(!info->vesa_blanked) {
-		info->vga_state.CrtMiscIO = inb_p(video_misc_rd);
-		sti();
-
-		outb_p(0x00,vga_video_port_reg);	/* HorizontalTotal */
-		info->vga_state.HorizontalTotal = inb_p(vga_video_port_val);
-		outb_p(0x01,vga_video_port_reg);	/* HorizDisplayEnd */
-		info->vga_state.HorizDisplayEnd = inb_p(vga_video_port_val);
-		outb_p(0x04,vga_video_port_reg);	/* StartHorizRetrace */
-		info->vga_state.StartHorizRetrace = inb_p(vga_video_port_val);
-		outb_p(0x05,vga_video_port_reg);	/* EndHorizRetrace */
-		info->vga_state.EndHorizRetrace = inb_p(vga_video_port_val);
-		outb_p(0x07,vga_video_port_reg);	/* Overflow */
-		info->vga_state.Overflow = inb_p(vga_video_port_val);
-		outb_p(0x10,vga_video_port_reg);	/* StartVertRetrace */
-		info->vga_state.StartVertRetrace = inb_p(vga_video_port_val);
-		outb_p(0x11,vga_video_port_reg);	/* EndVertRetrace */
-		info->vga_state.EndVertRetrace = inb_p(vga_video_port_val);
-		outb_p(0x17,vga_video_port_reg);	/* ModeControl */
-		info->vga_state.ModeControl = inb_p(vga_video_port_val);
-		outb_p(0x01,seq_port_reg);		/* ClockingMode */
-		info->vga_state.ClockingMode = inb_p(seq_port_val);
+	if(!par->vesa_blanked) {
+		par->vga_state.CrtMiscIO = vga_io_r(video_misc_rd);
+		//sti();
+
+		par->vga_state.HorizontalTotal = vga_io_rcrt(0x00);	/* HorizontalTotal */
+		par->vga_state.HorizDisplayEnd = vga_io_rcrt(0x01);	/* HorizDisplayEnd */
+		par->vga_state.StartHorizRetrace = vga_io_rcrt(0x04);	/* StartHorizRetrace */
+		par->vga_state.EndHorizRetrace = vga_io_rcrt(0x05);	/* EndHorizRetrace */
+		par->vga_state.Overflow = vga_io_rcrt(0x07);		/* Overflow */
+		par->vga_state.StartVertRetrace = vga_io_rcrt(0x10);	/* StartVertRetrace */
+		par->vga_state.EndVertRetrace = vga_io_rcrt(0x11);	/* EndVertRetrace */
+		par->vga_state.ModeControl = vga_io_rcrt(0x17);	/* ModeControl */
+		par->vga_state.ClockingMode = vga_io_rseq(0x01);	/* ClockingMode */
 	}
 
 	/* assure that video is enabled */
 	/* "0x20" is VIDEO_ENABLE_bit in register 01 of sequencer */
-	cli();
-	outb_p(0x01,seq_port_reg);
-	outb_p(info->vga_state.ClockingMode | 0x20,seq_port_val);
+	//cli();
+	vga_io_wseq(0x01, par->vga_state.ClockingMode | 0x20);
 
 	/* test for vertical retrace in process.... */
-	if ((info->vga_state.CrtMiscIO & 0x80) == 0x80)
-		outb_p(info->vga_state.CrtMiscIO & 0xef,video_misc_wr);
+	if ((par->vga_state.CrtMiscIO & 0x80) == 0x80)
+		vga_io_w(video_misc_wr, par->vga_state.CrtMiscIO & 0xef);
 
 	/*
 	 * Set <End of vertical retrace> to minimum (0) and
@@ -640,7 +832,7 @@
 		outb_p(0x11,vga_video_port_reg);	/* EndVertRetrace */
 		outb_p(0x40,vga_video_port_val);	/* minimum (bits 0..3)  */
 		outb_p(0x07,vga_video_port_reg);	/* Overflow */
-		outb_p(info->vga_state.Overflow | 0x84,vga_video_port_val); /* bits 9,10 of vert. retrace */
+		outb_p(par->vga_state.Overflow | 0x84,vga_video_port_val); /* bits 9,10 of vert. retrace */
 	}
 
 	if (mode & VESA_HSYNC_SUSPEND) {
@@ -658,44 +850,44 @@
 	/* restore both index registers */
 	outb_p(SeqCtrlIndex,seq_port_reg);
 	outb_p(CrtCtrlIndex,vga_video_port_reg);
-	sti();
+	//sti();
 }
 
-static void vga_vesa_unblank(struct vga16fb_info *info)
+static void vga_vesa_unblank(struct vga16fb_par *par)
 {
 	unsigned char SeqCtrlIndex;
 	unsigned char CrtCtrlIndex;
 	
-	cli();
-	SeqCtrlIndex = inb_p(seq_port_reg);
-	CrtCtrlIndex = inb_p(vga_video_port_reg);
+	//cli();
+	SeqCtrlIndex = vga_io_r(seq_port_reg);
+	CrtCtrlIndex = vga_io_r(vga_video_port_reg);
 
 	/* restore original values of VGA controller registers */
-	outb_p(info->vga_state.CrtMiscIO,video_misc_wr);
+	vga_io_w(video_misc_wr, par->vga_state.CrtMiscIO);
 
-	outb_p(0x00,vga_video_port_reg);		/* HorizontalTotal */
-	outb_p(info->vga_state.HorizontalTotal,vga_video_port_val);
-	outb_p(0x01,vga_video_port_reg);		/* HorizDisplayEnd */
-	outb_p(info->vga_state.HorizDisplayEnd,vga_video_port_val);
-	outb_p(0x04,vga_video_port_reg);		/* StartHorizRetrace */
-	outb_p(info->vga_state.StartHorizRetrace,vga_video_port_val);
-	outb_p(0x05,vga_video_port_reg);		/* EndHorizRetrace */
-	outb_p(info->vga_state.EndHorizRetrace,vga_video_port_val);
-	outb_p(0x07,vga_video_port_reg);		/* Overflow */
-	outb_p(info->vga_state.Overflow,vga_video_port_val);
-	outb_p(0x10,vga_video_port_reg);		/* StartVertRetrace */
-	outb_p(info->vga_state.StartVertRetrace,vga_video_port_val);
-	outb_p(0x11,vga_video_port_reg);		/* EndVertRetrace */
-	outb_p(info->vga_state.EndVertRetrace,vga_video_port_val);
-	outb_p(0x17,vga_video_port_reg);		/* ModeControl */
-	outb_p(info->vga_state.ModeControl,vga_video_port_val);
-	outb_p(0x01,seq_port_reg);		/* ClockingMode */
-	outb_p(info->vga_state.ClockingMode,seq_port_val);
+	/* HorizontalTotal */
+	vga_io_wcrt(0x00, par->vga_state.HorizontalTotal);
+	/* HorizDisplayEnd */
+	vga_io_wcrt(0x01, par->vga_state.HorizDisplayEnd);
+	/* StartHorizRetrace */
+	vga_io_wcrt(0x04, par->vga_state.StartHorizRetrace);
+	/* EndHorizRetrace */
+	vga_io_wcrt(0x05, par->vga_state.EndHorizRetrace);
+	/* Overflow */
+	vga_io_wcrt(0x07, par->vga_state.Overflow);
+	/* StartVertRetrace */
+	vga_io_wcrt(0x10, par->vga_state.StartVertRetrace);
+	/* EndVertRetrace */
+	vga_io_wcrt(0x11, par->vga_state.EndVertRetrace);
+	/* ModeControl */
+	vga_io_wcrt(0x17, par->vga_state.ModeControl);
+	/* ClockingMode */
+	vga_io_wseq(0x01, par->vga_state.ClockingMode);
 
 	/* restore index/control registers */
-	outb_p(SeqCtrlIndex,seq_port_reg);
-	outb_p(CrtCtrlIndex,vga_video_port_reg);
-	sti();
+	vga_io_w(seq_port_reg, SeqCtrlIndex);
+	vga_io_w(vga_video_port_reg, CrtCtrlIndex);
+	//sti();
 }
 
 static void vga_pal_blank(void)
@@ -711,127 +903,562 @@
 }
 
 /* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
-static int vga16fb_blank(int blank, struct fb_info *fb_info)
+static int vga16fb_blank(int blank, struct fb_info *info)
 {
-	struct vga16fb_info *info = (struct vga16fb_info*)fb_info;
+	struct vga16fb_par *par = (struct vga16fb_par *) info->par;
 
 	switch (blank) {
 	case 0:				/* Unblank */
-		if (info->vesa_blanked) {
-			vga_vesa_unblank(info);
-			info->vesa_blanked = 0;
+		if (par->vesa_blanked) {
+			vga_vesa_unblank(par);
+			par->vesa_blanked = 0;
 		}
-		if (info->palette_blanked) {
-			do_install_cmap(fb_info->currcon, fb_info);
-			info->palette_blanked = 0;
+		if (par->palette_blanked) {
+			//do_install_cmap(info->currcon, info);
+			par->palette_blanked = 0;
 		}
 		break;
 	case 1:				/* blank */
 		vga_pal_blank();
-		info->palette_blanked = 1;
+		par->palette_blanked = 1;
 		break;
 	default:			/* VESA blanking */
-		vga_vesa_blank(info, blank-1);
-		info->vesa_blanked = 1;
+		vga_vesa_blank(par, blank-1);
+		par->vesa_blanked = 1;
 		break;
 	}
 	return 0;
 }
 
+void vga_8planes_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+{
+        char oldindex = getindex();
+        char oldmode = setmode(0x40);
+        char oldmask = selectmask();
+        int line_ofs, height;
+        char oldop, oldsr;
+        char *where;
+
+        rect->dx /= 4;
+        where = info->screen_base + rect->dx + rect->dy * info->fix.line_length;
+
+        if (rect->rop == ROP_COPY) {
+                oldop = setop(0);
+                oldsr = setsr(0);
+
+                rect->width /= 4;
+                line_ofs = info->fix.line_length - rect->width;
+                setmask(0xff);
+
+                height = rect->height;
+
+                while (height--) {
+                        int x;
+
+                        /* we can do memset... */
+                        for (x = rect->width; x > 0; --x) {
+                                writeb(rect->color, where);
+                                where++;
+                        }
+                        where += line_ofs;
+                }
+        } else {
+                char oldcolor = setcolor(0xf);
+                int y;
+
+                oldop = setop(0x18);
+                oldsr = setsr(0xf);
+                setmask(0x0F);
+                for (y = 0; y < rect->height; y++) {
+                        rmw(where);
+                        rmw(where+1);
+                        where += info->fix.line_length;
+                }
+                setcolor(oldcolor);
+        }
+        setmask(oldmask);
+        setsr(oldsr);
+        setop(oldop);
+        setmode(oldmode);
+        setindex(oldindex);
+}
+
+void vga16fb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+{
+	int x, x2, y2, vxres, vyres, width, height, line_ofs;
+	char *dst;
+
+	vxres = info->var.xres_virtual;
+	vyres = info->var.yres_virtual;
+
+	if (!rect->width || !rect->height || rect->dx > vxres || rect->dy > vyres)
+		return;
+
+	/* We could use hardware clipping but on many cards you get around
+	 * hardware clipping by writing to framebuffer directly. */
+
+	x2 = rect->dx + rect->width;
+	y2 = rect->dy + rect->height;
+	x2 = x2 < vxres ? x2 : vxres;
+	y2 = y2 < vyres ? y2 : vyres;
+	rect->width = x2 - rect->dx;
+
+	switch (info->fix.type) {
+	case FB_TYPE_VGA_PLANES:
+		if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4) {
+
+			height = y2 - rect->dy;
+			width = rect->width/8;
+
+			line_ofs = info->fix.line_length - width;
+			dst = info->screen_base + (rect->dx/8) + rect->dy * info->fix.line_length;
+
+			switch (rect->rop) {
+			case ROP_COPY:
+				setmode(0);
+				setop(0);
+				setsr(0xf);
+				setcolor(rect->color);
+				selectmask();
+
+				setmask(0xff);
+
+				while (height--) {
+					for (x = 0; x < width; x++) {
+						writeb(0, dst);
+						dst++;
+					}
+					dst += line_ofs;
+				}
+				break;
+			case ROP_XOR:
+				setmode(0);
+				setop(0x18);
+				setsr(0xf);
+				setcolor(0xf);
+				selectmask();
+
+				setmask(0xff);
+				while (height--) {
+					for (x = 0; x < width; x++) {
+						rmw(dst);
+						dst++;
+					}
+					dst += line_ofs;
+				}
+				break;
+			}
+		} else 
+			vga_8planes_fillrect(info, rect);
+		break;
+#ifdef FBCON_HAS_VGA
+	case FB_TYPE_TEXT:
+		break;
+#endif
+	case FB_TYPE_PACKED_PIXELS:
+	default:
+		cfb_fillrect(info, rect);
+		break;
+	}
+}
+
+void vga_8planes_copyarea(struct fb_info *info, struct fb_copyarea *area)
+{
+        int height, line_ofs, x;
+        char oldindex = getindex();
+        char oldmode = setmode(0x41);
+        char oldop = setop(0);
+        char oldsr = setsr(0xf);
+        char *dest, *src;
+
+        height = area->height;
+
+        area->sx = area->sx / 4;
+        area->dx = area->dx / 4;
+        area->width = area->width / 4;
+
+        if (area->dy < area->sy || (area->dy == area->sy && area->dx < area->sx)) {
+                line_ofs = info->fix.line_length - area->width;
+                dest = info->screen_base + area->dx + area->dy * info->fix.line_length;
+                src = info->screen_base + area->sx + area->sy * info->fix.line_length;
+                while (height--) {
+                        for (x = 0; x < area->width; x++) {
+                                readb(src);
+                                writeb(0, dest);
+                                src++;
+                                dest++;
+                        }
+                        src += line_ofs;
+                        dest += line_ofs;
+                }
+        } else {
+                line_ofs = info->fix.line_length - area->width;
+                dest = info->screen_base + area->dx + area->width +
+			(area->dy + height - 1) * info->fix.line_length;
+                src = info->screen_base + area->sx + area->width +
+			(area->sy + height - 1) * info->fix.line_length;
+                while (height--) {
+                        for (x = 0; x < area->width; x++) {
+                                --src;
+                                --dest;
+                                readb(src);
+                                writeb(0, dest);
+                        }
+                        src -= line_ofs;
+                        dest -= line_ofs;
+                }
+        }
+
+        setsr(oldsr);
+        setop(oldop);
+        setmode(oldmode);
+        setindex(oldindex);
+}
+
+void vga16fb_copyarea(struct fb_info *info, struct fb_copyarea *area)
+{
+	int x, x2, y2, old_dx, old_dy, vxres, vyres;
+	int height, width, line_ofs;
+	char *dst = NULL, *src = NULL;
+
+	vxres = info->var.xres_virtual;
+	vyres = info->var.yres_virtual;
+
+	if (area->dx > vxres || area->sx > vxres || area->dy > vyres ||
+	    area->sy > vyres)
+		return;
+
+	/* clip the destination */
+	old_dx = area->dx;
+	old_dy = area->dy;
+
+	/*
+	 * We could use hardware clipping but on many cards you get around
+	 * hardware clipping by writing to framebuffer directly.
+	 */
+	x2 = area->dx + area->width;
+	y2 = area->dy + area->height;
+	area->dx = area->dx > 0 ? area->dx : 0;
+	area->dy = area->dy > 0 ? area->dy : 0;
+	x2 = x2 < vxres ? x2 : vxres;
+	y2 = y2 < vyres ? y2 : vyres;
+	area->width = x2 - area->dx;
+	area->height = y2 - area->dy;
+
+	/* update sx1,sy1 */
+	area->sx += (area->dx - old_dx);
+	area->sy += (area->dy - old_dy);
+
+	/* the source must be completely inside the virtual screen */
+	if (area->sx < 0 || area->sy < 0 ||
+	    (area->sx + area->width) > vxres ||
+	    (area->sy + area->height) > vyres)
+		return;
+
+	switch (info->fix.type) {
+	case FB_TYPE_VGA_PLANES:
+		if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4) {
+			width = area->width/8;
+			height = area->height;
+			line_ofs = info->fix.line_length - width;
+
+			setmode(1);
+			setop(0);
+			setsr(0xf);
+
+			if (area->dy < area->sy || (area->dy == area->sy && area->dx < area->sx)) {
+				dst = info->screen_base + (area->dx/8) + area->dy * info->fix.line_length;
+				src = info->screen_base + (area->sx/8) + area->sy * info->fix.line_length;
+				while (height--) {
+					for (x = 0; x < width; x++) {
+						readb(src);
+						writeb(0, dst);
+						dst++;
+						src++;
+					}
+					src += line_ofs;
+					dst += line_ofs;
+				}
+			} else {
+				dst = info->screen_base + (area->dx/8) + width + 
+					(area->dy + height - 1) * info->fix.line_length;
+				src = info->screen_base + (area->sx/8) + width + 
+					(area->sy + height  - 1) * info->fix.line_length;
+				while (height--) {
+					for (x = 0; x < width; x++) {
+						dst--;
+						src--;
+						readb(src);
+						writeb(0, dst);
+					}
+					src -= line_ofs;
+					dst -= line_ofs;
+				}
+			}
+		} else 
+			vga_8planes_copyarea(info, area);
+		break;
+#ifdef FBCON_HAS_VGA
+	case FB_TYPE_TEXT:
+		break;
+#endif
+	case FB_TYPE_PACKED_PIXELS:
+	default:
+		cfb_copyarea(info, area);
+		break;
+	}
+}
+
+#ifdef __LITTLE_ENDIAN
+static unsigned int transl_l[] =
+{0x0,0x8,0x4,0xC,0x2,0xA,0x6,0xE,0x1,0x9,0x5,0xD,0x3,0xB,0x7,0xF};
+static unsigned int transl_h[] =
+{0x000, 0x800, 0x400, 0xC00, 0x200, 0xA00, 0x600, 0xE00,
+ 0x100, 0x900, 0x500, 0xD00, 0x300, 0xB00, 0x700, 0xF00};
+#else
+#ifdef __BIG_ENDIAN
+static unsigned int transl_h[] =
+{0x0,0x8,0x4,0xC,0x2,0xA,0x6,0xE,0x1,0x9,0x5,0xD,0x3,0xB,0x7,0xF};
+static unsigned int transl_l[] =
+{0x000, 0x800, 0x400, 0xC00, 0x200, 0xA00, 0x600, 0xE00,
+ 0x100, 0x900, 0x500, 0xD00, 0x300, 0xB00, 0x700, 0xF00};
+#else
+#error "Only __BIG_ENDIAN and __LITTLE_ENDIAN are supported in vga-planes"
+#endif
+#endif
+
+void vga_8planes_imageblit(struct fb_info *info, struct fb_image *image)
+{
+        char oldindex = getindex();
+        char oldmode = setmode(0x40);
+        char oldop = setop(0);
+        char oldsr = setsr(0);
+        char oldmask = selectmask();
+        u8 *cdat = image->data;
+        char *where;
+        int y;
+
+        image->dx /= 4;
+        where = info->screen_base + image->dx + image->dy * info->fix.line_length;
+
+        setmask(0xff);
+        writeb(image->bg_color, where);
+        readb(where);
+        selectmask();
+        setmask(image->fg_color ^ image->bg_color);
+        setmode(0x42);
+        setop(0x18);
+        for (y = 0; y < image->height; y++, where += info->fix.line_length)
+                writew(transl_h[cdat[y]&0xF] | transl_l[cdat[y] >> 4], where);
+        setmask(oldmask);
+        setsr(oldsr);
+        setop(oldop);
+        setmode(oldmode);
+        setindex(oldindex);
+}
+
+void vga_imageblit_expand(struct fb_info *info, struct fb_image *image)
+{
+	char *where = info->screen_base + (image->dx/8) + 
+		image->dy * info->fix.line_length;
+	struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+	u8 *cdat = image->data, *dst;
+	int x, y;
+
+	switch (info->fix.type) {
+	case FB_TYPE_VGA_PLANES:
+		if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4) {
+			if (par->isVGA) {
+				setmode(2);
+				setop(0);
+				setsr(0xf);
+				setcolor(image->fg_color);
+				selectmask();
+				
+				setmask(0xff);
+				writeb(image->bg_color, where);
+				rmb();
+				readb(where); /* fill latches */
+				setmode(3);
+				wmb();
+				for (y = 0; y < image->height; y++) {
+					dst = where;
+					for (x = image->width/8; x--;) 
+						writeb(*cdat++, dst++);
+					where += info->fix.line_length;
+				}
+				wmb();
+			} else {
+				setmode(0);
+				setop(0);
+				setsr(0xf);
+				setcolor(image->bg_color);
+				selectmask();
+				
+				setmask(0xff);
+				for (y = 0; y < image->height; y++) {
+					dst = where;
+					for (x=image->width/8; x--;){
+						rmw(dst);
+						setcolor(image->fg_color);
+						selectmask();
+						if (*cdat) {
+							setmask(*cdat++);
+							rmw(dst++);
+						}
+					}
+					where += info->fix.line_length;
+				}
+			}
+		} else 
+			vga_8planes_imageblit(info, image);
+		break;
+#ifdef FBCON_HAS_VGA
+	case FB_TYPE_TEXT:
+		break;
+#endif
+	case FB_TYPE_PACKED_PIXELS:
+	default:
+		cfb_imageblit(info, image);
+		break;
+	}
+}
+
+void vga_imageblit_color(struct fb_info *info, struct fb_image *image) 
+{
+	/*
+	 * Draw logo 
+	 */
+	struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+	char *where = info->screen_base + image->dy * info->fix.line_length + 
+		image->dx/8;
+	char *cdat = image->data, *dst;
+	int x, y;
+
+	switch (info->fix.type) {
+	case FB_TYPE_VGA_PLANES:
+		if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4 &&
+		    par->isVGA) {
+			setsr(0xf);
+			setop(0);
+			setmode(0);
+			
+			for (y = 0; y < image->height; y++) {
+				for (x = 0; x < image->width; x++) {
+					dst = where + x/8;
+
+					setcolor(*cdat);
+					selectmask();
+					setmask(1 << (7 - (x % 8)));
+					fb_readb(dst);
+					fb_writeb(0, dst);
+
+					cdat++;
+				}
+				where += info->fix.line_length;
+			}
+		}
+		break;
+	case FB_TYPE_PACKED_PIXELS:
+		cfb_imageblit(info, image);
+		break;
+	default:
+		break;
+	}
+}
+				
+void vga16fb_imageblit(struct fb_info *info, struct fb_image *image)
+{
+	if (image->depth == 1)
+		vga_imageblit_expand(info, image);
+	else if (image->depth == info->var.bits_per_pixel)
+		vga_imageblit_color(info, image);
+}
+
 static struct fb_ops vga16fb_ops = {
-	.owner =	THIS_MODULE,
-	.fb_set_var =	vga16fb_set_var,
-	.fb_get_cmap =	gen_get_cmap,
-	.fb_set_cmap =	gen_set_cmap,
-	.fb_setcolreg =	vga16fb_setcolreg,
-	.fb_pan_display =vga16fb_pan_display,
-	.fb_blank =	vga16fb_blank,
+	.owner		= THIS_MODULE,
+	.fb_open        = vga16fb_open,
+	.fb_release     = vga16fb_release,
+	.fb_check_var	= vga16fb_check_var,
+	.fb_set_par	= vga16fb_set_par,
+	.fb_setcolreg 	= vga16fb_setcolreg,
+	.fb_pan_display = vga16fb_pan_display,
+	.fb_blank 	= vga16fb_blank,
+	.fb_fillrect	= vga16fb_fillrect,
+	.fb_copyarea	= vga16fb_copyarea,
+	.fb_imageblit	= vga16fb_imageblit,
+	.fb_cursor      = soft_cursor,
 };
 
 int vga16fb_setup(char *options)
 {
 	char *this_opt;
 	
-	vga16fb.fb_info.fontname[0] = '\0';
-	
 	if (!options || !*options)
 		return 0;
 	
 	while ((this_opt = strsep(&options, ",")) != NULL) {
 		if (!*this_opt) continue;
-		
-		if (!strncmp(this_opt, "font:", 5))
-			strcpy(vga16fb.fb_info.fontname, this_opt+5);
 	}
 	return 0;
 }
 
 int __init vga16fb_init(void)
 {
-	int i,j;
+	int i;
 
 	printk(KERN_DEBUG "vga16fb: initializing\n");
 
-	/* XXX share VGA_FB_PHYS region with vgacon */
+	/* XXX share VGA_FB_PHYS and I/O region with vgacon and others */
 
-        vga16fb.video_vbase = ioremap(VGA_FB_PHYS, VGA_FB_PHYS_LEN);
-	if (!vga16fb.video_vbase) {
+        vga16fb.screen_base = ioremap(VGA_FB_PHYS, VGA_FB_PHYS_LEN);
+	if (!vga16fb.screen_base) {
 		printk(KERN_ERR "vga16fb: unable to map device\n");
 		return -ENOMEM;
 	}
-	printk(KERN_INFO "vga16fb: mapped to 0x%p\n", vga16fb.video_vbase);
+	printk(KERN_INFO "vga16fb: mapped to 0x%p\n", vga16fb.screen_base);
 
-	vga16fb.isVGA = ORIG_VIDEO_ISVGA;
-	vga16fb.palette_blanked = 0;
-	vga16fb.vesa_blanked = 0;
+	vga16_par.isVGA = ORIG_VIDEO_ISVGA;
+	vga16_par.palette_blanked = 0;
+	vga16_par.vesa_blanked = 0;
 
-	i = vga16fb.isVGA? 6 : 2;
+	i = vga16_par.isVGA? 6 : 2;
 	
 	vga16fb_defined.red.length   = i;
 	vga16fb_defined.green.length = i;
 	vga16fb_defined.blue.length  = i;	
-	for(i = 0; i < 16; i++) {
-		j = color_table[i];
-		palette[i].red   = default_red[j];
-		palette[i].green = default_grn[j];
-		palette[i].blue  = default_blu[j];
-	}
-
-	/* XXX share VGA I/O region with vgacon and others */
-
-	disp.var = vga16fb_defined;
-
-	strcpy(vga16fb.fb_info.modename, vga16fb_fix.id);
-	vga16fb.fb_info.changevar = NULL;
-	vga16fb.fb_info.node = NODEV;
-        vga16fb.fb_info.var = vga16fb_defined;
-        vga16fb.fb_info.fix = vga16fb_fix;
-	vga16fb.fb_info.fbops = &vga16fb_ops;
-	vga16fb.fb_info.screen_base = vga16fb.video_vbase;
-	vga16fb.fb_info.disp=&disp;
-	vga16fb.fb_info.currcon = -1;
-	vga16fb.fb_info.switch_con=&gen_switch;
-	vga16fb.fb_info.updatevar=&gen_update_var;
-	vga16fb.fb_info.flags=FBINFO_FLAG_DEFAULT;
-	vga16fb_set_disp(-1, &vga16fb);
 
-	fb_alloc_cmap(&vga16fb.fb_info.cmap, 16, 0);
+	/* name should not depend on EGA/VGA */
+	vga16fb.node = NODEV;
+	vga16fb.fbops = &vga16fb_ops;
+	vga16fb.var = vga16fb_defined;
+	vga16fb.fix = vga16fb_fix;
+	vga16fb.par = &vga16_par;
+	vga16fb.flags = FBINFO_FLAG_DEFAULT;
+
+	i = (vga16fb_defined.bits_per_pixel == 8) ? 256 : 16;
+	fb_alloc_cmap(&vga16fb.cmap, i, 0);
+
+	if (vga16fb_check_var(&vga16fb.var, &vga16fb))
+		return -EINVAL;
+
+	vga16fb_update_fix(&vga16fb);
 
-	if (register_framebuffer(&vga16fb.fb_info)<0) {
-		iounmap(vga16fb.video_vbase);
+	if (register_framebuffer(&vga16fb) < 0) {
+		iounmap(vga16fb.screen_base);
 		return -EINVAL;
 	}
 
 	printk(KERN_INFO "fb%d: %s frame buffer device\n",
-	       GET_FB_IDX(vga16fb.fb_info.node), vga16fb.fb_info.modename);
+	       minor(vga16fb.node), vga16fb.fix.id);
 
 	return 0;
 }
 
 static void __exit vga16fb_exit(void)
 {
-    unregister_framebuffer(&vga16fb.fb_info);
-    iounmap(vga16fb.video_vbase);
+    unregister_framebuffer(&vga16fb);
+    iounmap(vga16fb.screen_base);
     /* XXX unshare VGA regions */
 }
 
diff -Nru a/drivers/video/vgacon.c b/drivers/video/vgacon.c
--- a/drivers/video/vgacon.c	Mon Dec  9 18:46:36 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1055 +0,0 @@
-/*
- *  linux/drivers/video/vgacon.c -- Low level VGA based console driver
- *
- *	Created 28 Sep 1997 by Geert Uytterhoeven
- *
- *	Rewritten by Martin Mares <mj@ucw.cz>, July 1998
- *
- *  This file is based on the old console.c, vga.c and vesa_blank.c drivers.
- *
- *	Copyright (C) 1991, 1992  Linus Torvalds
- *			    1995  Jay Estabrook
- *
- *	User definable mapping table and font loading by Eugene G. Crosser,
- *	<crosser@average.org>
- *
- *	Improved loadable font/UTF-8 support by H. Peter Anvin
- *	Feb-Sep 1995 <peter.anvin@linux.org>
- *
- *	Colour palette handling, by Simon Tatham
- *	17-Jun-95 <sgt20@cam.ac.uk>
- *
- *	if 512 char mode is already enabled don't re-enable it,
- *	because it causes screen to flicker, by Mitja Horvat
- *	5-May-96 <mitja.horvat@guest.arnes.si>
- *
- *	Use 2 outw instead of 4 outb_p to reduce erroneous text
- *	flashing on RHS of screen during heavy console scrolling .
- *	Oct 1996, Paul Gortmaker.
- *
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/console_struct.h>
-#include <linux/string.h>
-#include <linux/kd.h>
-#include <linux/slab.h>
-#include <linux/vt_kern.h>
-#include <linux/selection.h>
-#include <linux/spinlock.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-
-static spinlock_t vga_lock = SPIN_LOCK_UNLOCKED;
-
-#define BLANK 0x0020
-
-#define CAN_LOAD_EGA_FONTS	/* undefine if the user must not do this */
-#define CAN_LOAD_PALETTE	/* undefine if the user must not do this */
-
-/* You really do _NOT_ want to define this, unless you have buggy
- * Trident VGA which will resize cursor when moving it between column
- * 15 & 16. If you define this and your VGA is OK, inverse bug will
- * appear.
- */
-#undef TRIDENT_GLITCH
-
-#define dac_reg		0x3c8
-#define dac_val		0x3c9
-#define attrib_port	0x3c0
-#define seq_port_reg	0x3c4
-#define seq_port_val	0x3c5
-#define gr_port_reg	0x3ce
-#define gr_port_val	0x3cf
-#define video_misc_rd	0x3cc
-#define video_misc_wr	0x3c2
-
-/*
- *  Interface used by the world
- */
-
-static const char *vgacon_startup(void);
-static void vgacon_init(struct vc_data *c, int init);
-static void vgacon_deinit(struct vc_data *c);
-static void vgacon_cursor(struct vc_data *c, int mode);
-static int vgacon_switch(struct vc_data *c);
-static int vgacon_blank(struct vc_data *c, int blank);
-static int vgacon_font_op(struct vc_data *c, struct console_font_op *op);
-static int vgacon_set_palette(struct vc_data *c, unsigned char *table);
-static int vgacon_scrolldelta(struct vc_data *c, int lines);
-static int vgacon_set_origin(struct vc_data *c);
-static void vgacon_save_screen(struct vc_data *c);
-static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, int lines);
-static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity, u8 blink, u8 underline, u8 reverse);
-static void vgacon_invert_region(struct vc_data *c, u16 *p, int count);
-static unsigned long vgacon_uni_pagedir[2];
-
-
-/* Description of the hardware situation */
-static unsigned long   vga_vram_base;		/* Base of video memory */
-static unsigned long   vga_vram_end;		/* End of video memory */
-static u16             vga_video_port_reg;	/* Video register select port */
-static u16             vga_video_port_val;	/* Video register value port */
-static unsigned int    vga_video_num_columns;	/* Number of text columns */
-static unsigned int    vga_video_num_lines;	/* Number of text lines */
-static int	       vga_can_do_color = 0;	/* Do we support colors? */
-static unsigned int    vga_default_font_height;	/* Height of default screen font */
-static unsigned char   vga_video_type;		/* Card type */
-static unsigned char   vga_hardscroll_enabled;
-static unsigned char   vga_hardscroll_user_enable = 1;
-static unsigned char   vga_font_is_default = 1;
-static int	       vga_vesa_blanked;
-static int	       vga_palette_blanked;
-static int	       vga_is_gfx;
-static int	       vga_512_chars;
-static int	       vga_video_font_height;
-static unsigned int    vga_rolled_over = 0;
-
-
-static int __init no_scroll(char *str)
-{
-	/*
-	 * Disabling scrollback is required for the Braillex ib80-piezo
-	 * Braille reader made by F.H. Papenmeier (Germany).
-	 * Use the "no-scroll" bootflag.
-	 */
-	vga_hardscroll_user_enable = vga_hardscroll_enabled = 0;
-	return 1;
-}
-
-__setup("no-scroll", no_scroll);
-
-/*
- * By replacing the four outb_p with two back to back outw, we can reduce
- * the window of opportunity to see text mislocated to the RHS of the
- * console during heavy scrolling activity. However there is the remote
- * possibility that some pre-dinosaur hardware won't like the back to back
- * I/O. Since the Xservers get away with it, we should be able to as well.
- */
-static inline void write_vga(unsigned char reg, unsigned int val)
-{
-	unsigned int v1, v2;
-	unsigned long flags;
-
-	/*
-	 * ddprintk might set the console position from interrupt
-	 * handlers, thus the write has to be IRQ-atomic.
-	 */
-	spin_lock_irqsave(&vga_lock, flags);	
-
-#ifndef SLOW_VGA
-	v1 = reg + (val & 0xff00);
-	v2 = reg + 1 + ((val << 8) & 0xff00);
-	outw(v1, vga_video_port_reg);
-	outw(v2, vga_video_port_reg);
-#else
-	outb_p(reg, vga_video_port_reg);
-	outb_p(val >> 8, vga_video_port_val);
-	outb_p(reg+1, vga_video_port_reg);
-	outb_p(val & 0xff, vga_video_port_val);
-#endif
-	spin_unlock_irqrestore(&vga_lock, flags);
-}
-
-static const char __init *vgacon_startup(void)
-{
-	const char *display_desc = NULL;
-	u16 saved1, saved2;
-	volatile u16 *p;
-
-	if (ORIG_VIDEO_ISVGA == VIDEO_TYPE_VLFB) {
-	no_vga:
-#ifdef CONFIG_DUMMY_CONSOLE
-		conswitchp = &dummy_con;
-		return conswitchp->con_startup();
-#else
-		return NULL;
-#endif
-	}
-
-
-	vga_video_num_lines = ORIG_VIDEO_LINES;
-	vga_video_num_columns = ORIG_VIDEO_COLS;
-
-	if (ORIG_VIDEO_MODE == 7)	/* Is this a monochrome display? */
-	{
-		vga_vram_base = 0xb0000;
-		vga_video_port_reg = 0x3b4;
-		vga_video_port_val = 0x3b5;
-		if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
-		{
-			static struct resource ega_console_resource = { "ega", 0x3B0, 0x3BF };
-			vga_video_type = VIDEO_TYPE_EGAM;
-			vga_vram_end = 0xb8000;
-			display_desc = "EGA+";
-			request_resource(&ioport_resource, &ega_console_resource);
-		}
-		else
-		{
-			static struct resource mda1_console_resource = { "mda", 0x3B0, 0x3BB };
-			static struct resource mda2_console_resource = { "mda", 0x3BF, 0x3BF };
-			vga_video_type = VIDEO_TYPE_MDA;
-			vga_vram_end = 0xb2000;
-			display_desc = "*MDA";
-			request_resource(&ioport_resource, &mda1_console_resource);
-			request_resource(&ioport_resource, &mda2_console_resource);
-			vga_video_font_height = 14;
-		}
-	}
-	else				/* If not, it is color. */
-	{
-		vga_can_do_color = 1;
-		vga_vram_base = 0xb8000;
-		vga_video_port_reg = 0x3d4;
-		vga_video_port_val = 0x3d5;
-		if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
-		{
-			int i;
-
-			vga_vram_end = 0xc0000;
-
-			if (!ORIG_VIDEO_ISVGA) {
-				static struct resource ega_console_resource = { "ega", 0x3C0, 0x3DF };
-				vga_video_type = VIDEO_TYPE_EGAC;
-				display_desc = "EGA";
-				request_resource(&ioport_resource, &ega_console_resource);
-			} else {
-				static struct resource vga_console_resource = { "vga+", 0x3C0, 0x3DF };
-				vga_video_type = VIDEO_TYPE_VGAC;
-				display_desc = "VGA+";
-				request_resource(&ioport_resource, &vga_console_resource);
-
-#ifdef VGA_CAN_DO_64KB
-				/*
-				 * get 64K rather than 32K of video RAM.
-				 * This doesn't actually work on all "VGA"
-				 * controllers (it seems like setting MM=01
-				 * and COE=1 isn't necessarily a good idea)
-				 */
-				vga_vram_base = 0xa0000;
-				vga_vram_end = 0xb0000;
-				outb_p (6, 0x3ce) ;
-				outb_p (6, 0x3cf) ;
-#endif
-
-				/*
-				 * Normalise the palette registers, to point
-				 * the 16 screen colours to the first 16
-				 * DAC entries.
-				 */
-
-				for (i=0; i<16; i++) {
-					inb_p (0x3da) ;
-					outb_p (i, 0x3c0) ;
-					outb_p (i, 0x3c0) ;
-				}
-				outb_p (0x20, 0x3c0) ;
-
-				/* now set the DAC registers back to their
-				 * default values */
-
-				for (i=0; i<16; i++) {
-					outb_p (color_table[i], 0x3c8) ;
-					outb_p (default_red[i], 0x3c9) ;
-					outb_p (default_grn[i], 0x3c9) ;
-					outb_p (default_blu[i], 0x3c9) ;
-				}
-			}
-		}
-		else
-		{
-			static struct resource cga_console_resource = { "cga", 0x3D4, 0x3D5 };
-			vga_video_type = VIDEO_TYPE_CGA;
-			vga_vram_end = 0xba000;
-			display_desc = "*CGA";
-			request_resource(&ioport_resource, &cga_console_resource);
-			vga_video_font_height = 8;
-		}
-	}
-
-	vga_vram_base = VGA_MAP_MEM(vga_vram_base);
-	vga_vram_end = VGA_MAP_MEM(vga_vram_end);
-
-	/*
-	 *	Find out if there is a graphics card present.
-	 *	Are there smarter methods around?
-	 */
-	p = (volatile u16 *)vga_vram_base;
-	saved1 = scr_readw(p);
-	saved2 = scr_readw(p + 1);
-	scr_writew(0xAA55, p);
-	scr_writew(0x55AA, p + 1);
-	if (scr_readw(p) != 0xAA55 || scr_readw(p + 1) != 0x55AA) {
-		scr_writew(saved1, p);
-		scr_writew(saved2, p + 1);
-		goto no_vga;
-	}
-	scr_writew(0x55AA, p);
-	scr_writew(0xAA55, p + 1);
-	if (scr_readw(p) != 0x55AA || scr_readw(p + 1) != 0xAA55) {
-		scr_writew(saved1, p);
-		scr_writew(saved2, p + 1);
-		goto no_vga;
-	}
-	scr_writew(saved1, p);
-	scr_writew(saved2, p + 1);
-
-	if (vga_video_type == VIDEO_TYPE_EGAC
-	    || vga_video_type == VIDEO_TYPE_VGAC
-	    || vga_video_type == VIDEO_TYPE_EGAM) {
-		vga_hardscroll_enabled = vga_hardscroll_user_enable;
-		vga_default_font_height = ORIG_VIDEO_POINTS;
-		vga_video_font_height = ORIG_VIDEO_POINTS;
-		/* This may be suboptimal but is a safe bet - go with it */
-		video_scan_lines =
-			vga_video_font_height * vga_video_num_lines;
-	}
-	video_font_height = vga_video_font_height;
-
-	return display_desc;
-}
-
-static void vgacon_init(struct vc_data *c, int init)
-{
-	unsigned long p;
-	
-	/* We cannot be loaded as a module, therefore init is always 1 */
-	c->vc_can_do_color = vga_can_do_color;
-	c->vc_cols = vga_video_num_columns;
-	c->vc_rows = vga_video_num_lines;
-	c->vc_complement_mask = 0x7700;
-	p = *c->vc_uni_pagedir_loc;
-	if (c->vc_uni_pagedir_loc == &c->vc_uni_pagedir ||
-	    !--c->vc_uni_pagedir_loc[1])
-		con_free_unimap(c->vc_num);
-	c->vc_uni_pagedir_loc = vgacon_uni_pagedir;
-	vgacon_uni_pagedir[1]++;
-	if (!vgacon_uni_pagedir[0] && p)
-		con_set_default_unimap(c->vc_num);
-}
-
-static inline void vga_set_mem_top(struct vc_data *c)
-{
-	write_vga(12, (c->vc_visible_origin-vga_vram_base)/2);
-}
-
-static void vgacon_deinit(struct vc_data *c)
-{
-	/* When closing the last console, reset video origin */
-	if (!--vgacon_uni_pagedir[1]) {
-		c->vc_visible_origin = vga_vram_base;
-		vga_set_mem_top(c);
-		con_free_unimap(c->vc_num);
-	}
-	c->vc_uni_pagedir_loc = &c->vc_uni_pagedir;
-	con_set_default_unimap(c->vc_num);
-}
-
-static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity, u8 blink, u8 underline, u8 reverse)
-{
-	u8 attr = color;
-
-	if (vga_can_do_color) {
-		if (underline)
-			attr = (attr & 0xf0) | c->vc_ulcolor;
-		else if (intensity == 0)
-			attr = (attr & 0xf0) | c->vc_halfcolor;
-	}
-	if (reverse)
-		attr = ((attr) & 0x88) | ((((attr) >> 4) | ((attr) << 4)) & 0x77);
-	if (blink)
-		attr ^= 0x80;
-	if (intensity == 2)
-		attr ^= 0x08;
-	if (!vga_can_do_color) {
-		if (underline)
-			attr = (attr & 0xf8) | 0x01;
-		else if (intensity == 0)
-			attr = (attr & 0xf0) | 0x08;
-	}
-	return attr;
-}
-
-static void vgacon_invert_region(struct vc_data *c, u16 *p, int count)
-{
-	int col = vga_can_do_color;
-
-	while (count--) {
-		u16 a = scr_readw(p);
-		if (col)
-			a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4);
-		else
-			a ^= ((a & 0x0700) == 0x0100) ? 0x7000 : 0x7700;
-		scr_writew(a, p++);
-	}
-}
-
-static void vgacon_set_cursor_size(int xpos, int from, int to)
-{
-	unsigned long flags;
-	int curs, cure;
-	static int lastfrom, lastto;
-
-#ifdef TRIDENT_GLITCH
-	if (xpos<16) from--, to--;
-#endif
-
-	if ((from == lastfrom) && (to == lastto)) return;
-	lastfrom = from; lastto = to;
-
-	spin_lock_irqsave(&vga_lock, flags);
-	outb_p(0x0a, vga_video_port_reg);		/* Cursor start */
-	curs = inb_p(vga_video_port_val);
-	outb_p(0x0b, vga_video_port_reg);		/* Cursor end */
-	cure = inb_p(vga_video_port_val);
-
-	curs = (curs & 0xc0) | from;
-	cure = (cure & 0xe0) | to;
-
-	outb_p(0x0a, vga_video_port_reg);		/* Cursor start */
-	outb_p(curs, vga_video_port_val);
-	outb_p(0x0b, vga_video_port_reg);		/* Cursor end */
-	outb_p(cure, vga_video_port_val);
-	spin_unlock_irqrestore(&vga_lock, flags);
-}
-
-static void vgacon_cursor(struct vc_data *c, int mode)
-{
-    if (c->vc_origin != c->vc_visible_origin)
-	vgacon_scrolldelta(c, 0);
-    switch (mode) {
-	case CM_ERASE:
-	    write_vga(14, (vga_vram_end - vga_vram_base - 1)/2);
-	    break;
-
-	case CM_MOVE:
-	case CM_DRAW:
-	    write_vga(14, (c->vc_pos-vga_vram_base)/2);
-	    switch (c->vc_cursor_type & 0x0f) {
-		case CUR_UNDERLINE:
-			vgacon_set_cursor_size(c->vc_x, 
-					video_font_height - (video_font_height < 10 ? 2 : 3),
-					video_font_height - (video_font_height < 10 ? 1 : 2));
-			break;
-		case CUR_TWO_THIRDS:
-			vgacon_set_cursor_size(c->vc_x, 
-					 video_font_height / 3,
-					 video_font_height - (video_font_height < 10 ? 1 : 2));
-			break;
-		case CUR_LOWER_THIRD:
-			vgacon_set_cursor_size(c->vc_x, 
-					 (video_font_height*2) / 3,
-					 video_font_height - (video_font_height < 10 ? 1 : 2));
-			break;
-		case CUR_LOWER_HALF:
-			vgacon_set_cursor_size(c->vc_x, 
-					 video_font_height / 2,
-					 video_font_height - (video_font_height < 10 ? 1 : 2));
-			break;
-		case CUR_NONE:
-			vgacon_set_cursor_size(c->vc_x, 31, 30);
-			break;
-          	default:
-			vgacon_set_cursor_size(c->vc_x, 1, video_font_height);
-			break;
-		}
-	    break;
-    }
-}
-
-static int vgacon_switch(struct vc_data *c)
-{
-	/*
-	 * We need to save screen size here as it's the only way
-	 * we can spot the screen has been resized and we need to
-	 * set size of freshly allocated screens ourselves.
-	 */
-	vga_video_num_columns = c->vc_cols;
-	vga_video_num_lines = c->vc_rows;
-	if (!vga_is_gfx)
-		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size);
-	return 0;	/* Redrawing not needed */
-}
-
-static void vga_set_palette(struct vc_data *c, unsigned char *table)
-{
-	int i, j ;
-
-	for (i=j=0; i<16; i++) {
-		outb_p (table[i], dac_reg) ;
-		outb_p (c->vc_palette[j++]>>2, dac_val) ;
-		outb_p (c->vc_palette[j++]>>2, dac_val) ;
-		outb_p (c->vc_palette[j++]>>2, dac_val) ;
-	}
-}
-
-static int vgacon_set_palette(struct vc_data *c, unsigned char *table)
-{
-#ifdef CAN_LOAD_PALETTE
-	if (vga_video_type != VIDEO_TYPE_VGAC || vga_palette_blanked || !CON_IS_VISIBLE(c))
-		return -EINVAL;
-	vga_set_palette(c, table);
-	return 0;
-#else
-	return -EINVAL;
-#endif
-}
-
-/* structure holding original VGA register settings */
-static struct {
-	unsigned char	SeqCtrlIndex;		/* Sequencer Index reg.   */
-	unsigned char	CrtCtrlIndex;		/* CRT-Contr. Index reg.  */
-	unsigned char	CrtMiscIO;		/* Miscellaneous register */
-	unsigned char	HorizontalTotal;	/* CRT-Controller:00h */
-	unsigned char	HorizDisplayEnd;	/* CRT-Controller:01h */
-	unsigned char	StartHorizRetrace;	/* CRT-Controller:04h */
-	unsigned char	EndHorizRetrace;	/* CRT-Controller:05h */
-	unsigned char	Overflow;		/* CRT-Controller:07h */
-	unsigned char	StartVertRetrace;	/* CRT-Controller:10h */
-	unsigned char	EndVertRetrace;		/* CRT-Controller:11h */
-	unsigned char	ModeControl;		/* CRT-Controller:17h */
-	unsigned char	ClockingMode;		/* Seq-Controller:01h */
-} vga_state;
-
-static void vga_vesa_blank(int mode)
-{
-	/* save original values of VGA controller registers */
-	if(!vga_vesa_blanked) {
-		spin_lock_irq(&vga_lock);
-		vga_state.SeqCtrlIndex = inb_p(seq_port_reg);
-		vga_state.CrtCtrlIndex = inb_p(vga_video_port_reg);
-		vga_state.CrtMiscIO = inb_p(video_misc_rd);
-		spin_unlock_irq(&vga_lock);
-
-		outb_p(0x00,vga_video_port_reg);	/* HorizontalTotal */
-		vga_state.HorizontalTotal = inb_p(vga_video_port_val);
-		outb_p(0x01,vga_video_port_reg);	/* HorizDisplayEnd */
-		vga_state.HorizDisplayEnd = inb_p(vga_video_port_val);
-		outb_p(0x04,vga_video_port_reg);	/* StartHorizRetrace */
-		vga_state.StartHorizRetrace = inb_p(vga_video_port_val);
-		outb_p(0x05,vga_video_port_reg);	/* EndHorizRetrace */
-		vga_state.EndHorizRetrace = inb_p(vga_video_port_val);
-		outb_p(0x07,vga_video_port_reg);	/* Overflow */
-		vga_state.Overflow = inb_p(vga_video_port_val);
-		outb_p(0x10,vga_video_port_reg);	/* StartVertRetrace */
-		vga_state.StartVertRetrace = inb_p(vga_video_port_val);
-		outb_p(0x11,vga_video_port_reg);	/* EndVertRetrace */
-		vga_state.EndVertRetrace = inb_p(vga_video_port_val);
-		outb_p(0x17,vga_video_port_reg);	/* ModeControl */
-		vga_state.ModeControl = inb_p(vga_video_port_val);
-		outb_p(0x01,seq_port_reg);		/* ClockingMode */
-		vga_state.ClockingMode = inb_p(seq_port_val);
-	}
-
-	/* assure that video is enabled */
-	/* "0x20" is VIDEO_ENABLE_bit in register 01 of sequencer */
-	spin_lock_irq(&vga_lock);
-	outb_p(0x01,seq_port_reg);
-	outb_p(vga_state.ClockingMode | 0x20,seq_port_val);
-
-	/* test for vertical retrace in process.... */
-	if ((vga_state.CrtMiscIO & 0x80) == 0x80)
-		outb_p(vga_state.CrtMiscIO & 0xef,video_misc_wr);
-
-	/*
-	 * Set <End of vertical retrace> to minimum (0) and
-	 * <Start of vertical Retrace> to maximum (incl. overflow)
-	 * Result: turn off vertical sync (VSync) pulse.
-	 */
-	if (mode & VESA_VSYNC_SUSPEND) {
-		outb_p(0x10,vga_video_port_reg);	/* StartVertRetrace */
-		outb_p(0xff,vga_video_port_val); 	/* maximum value */
-		outb_p(0x11,vga_video_port_reg);	/* EndVertRetrace */
-		outb_p(0x40,vga_video_port_val);	/* minimum (bits 0..3)  */
-		outb_p(0x07,vga_video_port_reg);	/* Overflow */
-		outb_p(vga_state.Overflow | 0x84,vga_video_port_val); /* bits 9,10 of vert. retrace */
-	}
-
-	if (mode & VESA_HSYNC_SUSPEND) {
-		/*
-		 * Set <End of horizontal retrace> to minimum (0) and
-		 *  <Start of horizontal Retrace> to maximum
-		 * Result: turn off horizontal sync (HSync) pulse.
-		 */
-		outb_p(0x04,vga_video_port_reg);	/* StartHorizRetrace */
-		outb_p(0xff,vga_video_port_val);	/* maximum */
-		outb_p(0x05,vga_video_port_reg);	/* EndHorizRetrace */
-		outb_p(0x00,vga_video_port_val);	/* minimum (0) */
-	}
-
-	/* restore both index registers */
-	outb_p(vga_state.SeqCtrlIndex,seq_port_reg);
-	outb_p(vga_state.CrtCtrlIndex,vga_video_port_reg);
-	spin_unlock_irq(&vga_lock);
-}
-
-static void vga_vesa_unblank(void)
-{
-	/* restore original values of VGA controller registers */
-	spin_lock_irq(&vga_lock);
-	outb_p(vga_state.CrtMiscIO,video_misc_wr);
-
-	outb_p(0x00,vga_video_port_reg);		/* HorizontalTotal */
-	outb_p(vga_state.HorizontalTotal,vga_video_port_val);
-	outb_p(0x01,vga_video_port_reg);		/* HorizDisplayEnd */
-	outb_p(vga_state.HorizDisplayEnd,vga_video_port_val);
-	outb_p(0x04,vga_video_port_reg);		/* StartHorizRetrace */
-	outb_p(vga_state.StartHorizRetrace,vga_video_port_val);
-	outb_p(0x05,vga_video_port_reg);		/* EndHorizRetrace */
-	outb_p(vga_state.EndHorizRetrace,vga_video_port_val);
-	outb_p(0x07,vga_video_port_reg);		/* Overflow */
-	outb_p(vga_state.Overflow,vga_video_port_val);
-	outb_p(0x10,vga_video_port_reg);		/* StartVertRetrace */
-	outb_p(vga_state.StartVertRetrace,vga_video_port_val);
-	outb_p(0x11,vga_video_port_reg);		/* EndVertRetrace */
-	outb_p(vga_state.EndVertRetrace,vga_video_port_val);
-	outb_p(0x17,vga_video_port_reg);		/* ModeControl */
-	outb_p(vga_state.ModeControl,vga_video_port_val);
-	outb_p(0x01,seq_port_reg);		/* ClockingMode */
-	outb_p(vga_state.ClockingMode,seq_port_val);
-
-	/* restore index/control registers */
-	outb_p(vga_state.SeqCtrlIndex,seq_port_reg);
-	outb_p(vga_state.CrtCtrlIndex,vga_video_port_reg);
-	spin_unlock_irq(&vga_lock);
-}
-
-static void vga_pal_blank(void)
-{
-	int i;
-
-	for (i=0; i<16; i++) {
-		outb_p (i, dac_reg) ;
-		outb_p (0, dac_val) ;
-		outb_p (0, dac_val) ;
-		outb_p (0, dac_val) ;
-	}
-}
-
-static int vgacon_blank(struct vc_data *c, int blank)
-{
-	switch (blank) {
-	case 0:				/* Unblank */
-		if (vga_vesa_blanked) {
-			vga_vesa_unblank();
-			vga_vesa_blanked = 0;
-		}
-		if (vga_palette_blanked) {
-			vga_set_palette(c, color_table);
-			vga_palette_blanked = 0;
-			return 0;
-		}
-		vga_is_gfx = 0;
-		/* Tell console.c that it has to restore the screen itself */
-		return 1;
-	case 1:				/* Normal blanking */
-		if (vga_video_type == VIDEO_TYPE_VGAC) {
-			vga_pal_blank();
-			vga_palette_blanked = 1;
-			return 0;
-		}
-		vgacon_set_origin(c);
-		scr_memsetw((void *)vga_vram_base, BLANK, c->vc_screenbuf_size);
-		return 1;
-	case -1:			/* Entering graphic mode */
-		scr_memsetw((void *)vga_vram_base, BLANK, c->vc_screenbuf_size);
-		vga_is_gfx = 1;
-		return 1;
-	default:			/* VESA blanking */
-		if (vga_video_type == VIDEO_TYPE_VGAC) {
-			vga_vesa_blank(blank-1);
-			vga_vesa_blanked = blank;
-		}
-		return 0;
-	}
-}
-
-/*
- * PIO_FONT support.
- *
- * The font loading code goes back to the codepage package by
- * Joel Hoffman (joel@wam.umd.edu). (He reports that the original
- * reference is: "From: p. 307 of _Programmer's Guide to PC & PS/2
- * Video Systems_ by Richard Wilton. 1987.  Microsoft Press".)
- *
- * Change for certain monochrome monitors by Yury Shevchuck
- * (sizif@botik.yaroslavl.su).
- */
-
-#ifdef CAN_LOAD_EGA_FONTS
-
-#define colourmap 0xa0000
-/* Pauline Middelink <middelin@polyware.iaf.nl> reports that we
-   should use 0xA0000 for the bwmap as well.. */
-#define blackwmap 0xa0000
-#define cmapsz 8192
-
-static int
-vgacon_do_font_op(char *arg, int set, int ch512)
-{
-	int i;
-	char *charmap;
-	int beg;
-	unsigned short video_port_status = vga_video_port_reg + 6;
-	int font_select = 0x00;
-
-	if (vga_video_type != VIDEO_TYPE_EGAM) {
-		charmap = (char *)VGA_MAP_MEM(colourmap);
-		beg = 0x0e;
-#ifdef VGA_CAN_DO_64KB
-		if (vga_video_type == VIDEO_TYPE_VGAC)
-			beg = 0x06;
-#endif
-	} else {
-		charmap = (char *)VGA_MAP_MEM(blackwmap);
-		beg = 0x0a;
-	}
-	
-#ifdef BROKEN_GRAPHICS_PROGRAMS
-	/*
-	 * All fonts are loaded in slot 0 (0:1 for 512 ch)
-	 */
-
-	if (!arg)
-		return -EINVAL;		/* Return to default font not supported */
-
-	vga_font_is_default = 0;
-	font_select = ch512 ? 0x04 : 0x00;
-#else	
-	/*
-	 * The default font is kept in slot 0 and is never touched.
-	 * A custom font is loaded in slot 2 (256 ch) or 2:3 (512 ch)
-	 */
-
-	if (set) {
-		vga_font_is_default = !arg;
-		if (!arg)
-			ch512 = 0;		/* Default font is always 256 */
-		font_select = arg ? (ch512 ? 0x0e : 0x0a) : 0x00;
-	}
-
-	if ( !vga_font_is_default )
-		charmap += 4*cmapsz;
-#endif
-
-	spin_lock_irq(&vga_lock);
-	outb_p( 0x00, seq_port_reg );   /* First, the sequencer */
-	outb_p( 0x01, seq_port_val );   /* Synchronous reset */
-	outb_p( 0x02, seq_port_reg );
-	outb_p( 0x04, seq_port_val );   /* CPU writes only to map 2 */
-	outb_p( 0x04, seq_port_reg );
-	outb_p( 0x07, seq_port_val );   /* Sequential addressing */
-	outb_p( 0x00, seq_port_reg );
-	outb_p( 0x03, seq_port_val );   /* Clear synchronous reset */
-
-	outb_p( 0x04, gr_port_reg );    /* Now, the graphics controller */
-	outb_p( 0x02, gr_port_val );    /* select map 2 */
-	outb_p( 0x05, gr_port_reg );
-	outb_p( 0x00, gr_port_val );    /* disable odd-even addressing */
-	outb_p( 0x06, gr_port_reg );
-	outb_p( 0x00, gr_port_val );    /* map start at A000:0000 */
-	spin_unlock_irq(&vga_lock);
-	
-	if (arg) {
-		if (set)
-			for (i=0; i<cmapsz ; i++)
-				vga_writeb(arg[i], charmap + i);
-		else
-			for (i=0; i<cmapsz ; i++)
-				arg[i] = vga_readb(charmap + i);
-
-		/*
-		 * In 512-character mode, the character map is not contiguous if
-		 * we want to remain EGA compatible -- which we do
-		 */
-
-		if (ch512) {
-			charmap += 2*cmapsz;
-			arg += cmapsz;
-			if (set)
-				for (i=0; i<cmapsz ; i++)
-					vga_writeb(arg[i], charmap+i);
-			else
-				for (i=0; i<cmapsz ; i++)
-					arg[i] = vga_readb(charmap+i);
-		}
-	}
-	
-	spin_lock_irq(&vga_lock);
-	outb_p( 0x00, seq_port_reg );   /* First, the sequencer */
-	outb_p( 0x01, seq_port_val );   /* Synchronous reset */
-	outb_p( 0x02, seq_port_reg );
-	outb_p( 0x03, seq_port_val );   /* CPU writes to maps 0 and 1 */
-	outb_p( 0x04, seq_port_reg );
-	outb_p( 0x03, seq_port_val );   /* odd-even addressing */
-	if (set) {
-		outb_p( 0x03, seq_port_reg ); /* Character Map Select */
-		outb_p( font_select, seq_port_val );
-	}
-	outb_p( 0x00, seq_port_reg );
-	outb_p( 0x03, seq_port_val );   /* clear synchronous reset */
-
-	outb_p( 0x04, gr_port_reg );    /* Now, the graphics controller */
-	outb_p( 0x00, gr_port_val );    /* select map 0 for CPU */
-	outb_p( 0x05, gr_port_reg );
-	outb_p( 0x10, gr_port_val );    /* enable even-odd addressing */
-	outb_p( 0x06, gr_port_reg );
-	outb_p( beg, gr_port_val );     /* map starts at b800:0 or b000:0 */
-
-	/* if 512 char mode is already enabled don't re-enable it. */
-	if ((set)&&(ch512!=vga_512_chars)) {	/* attribute controller */
-		int i;
-		for(i=0; i<MAX_NR_CONSOLES; i++) {
-			struct vc_data *c = vc_cons[i].d;
-			if (c && c->vc_sw == &vga_con)
-				c->vc_hi_font_mask = ch512 ? 0x0800 : 0;
-		}
-		vga_512_chars=ch512;
-		/* 256-char: enable intensity bit
-		   512-char: disable intensity bit */
-		inb_p( video_port_status );	/* clear address flip-flop */
-		outb_p ( 0x12, attrib_port ); /* color plane enable register */
-		outb_p ( ch512 ? 0x07 : 0x0f, attrib_port );
-		/* Wilton (1987) mentions the following; I don't know what
-		   it means, but it works, and it appears necessary */
-		inb_p( video_port_status );
-		outb_p ( 0x20, attrib_port );
-	}
-	spin_unlock_irq(&vga_lock);
-	return 0;
-}
-
-/*
- * Adjust the screen to fit a font of a certain height
- */
-static int
-vgacon_adjust_height(unsigned fontheight)
-{
-	int rows, maxscan;
-	unsigned char ovr, vde, fsr;
-
-	if (fontheight == vga_video_font_height)
-		return 0;
-
-	vga_video_font_height = video_font_height = fontheight;
-
-	rows = video_scan_lines/fontheight;	/* Number of video rows we end up with */
-	maxscan = rows*fontheight - 1;		/* Scan lines to actually display-1 */
-
-	/* Reprogram the CRTC for the new font size
-	   Note: the attempt to read the overflow register will fail
-	   on an EGA, but using 0xff for the previous value appears to
-	   be OK for EGA text modes in the range 257-512 scan lines, so I
-	   guess we don't need to worry about it.
-
-	   The same applies for the spill bits in the font size and cursor
-	   registers; they are write-only on EGA, but it appears that they
-	   are all don't care bits on EGA, so I guess it doesn't matter. */
-
-	spin_lock_irq(&vga_lock);
-	outb_p( 0x07, vga_video_port_reg );		/* CRTC overflow register */
-	ovr = inb_p(vga_video_port_val);
-	outb_p( 0x09, vga_video_port_reg );		/* Font size register */
-	fsr = inb_p(vga_video_port_val);
-	spin_unlock_irq(&vga_lock);
-
-	vde = maxscan & 0xff;			/* Vertical display end reg */
-	ovr = (ovr & 0xbd) +			/* Overflow register */
-	      ((maxscan & 0x100) >> 7) +
-	      ((maxscan & 0x200) >> 3);
-	fsr = (fsr & 0xe0) + (fontheight-1);    /*  Font size register */
-
-	spin_lock_irq(&vga_lock);
-	outb_p( 0x07, vga_video_port_reg );		/* CRTC overflow register */
-	outb_p( ovr, vga_video_port_val );
-	outb_p( 0x09, vga_video_port_reg );		/* Font size */
-	outb_p( fsr, vga_video_port_val );
-	outb_p( 0x12, vga_video_port_reg );		/* Vertical display limit */
-	outb_p( vde, vga_video_port_val );
-	spin_unlock_irq(&vga_lock);	
-
-	vc_resize_all(rows, 0);			/* Adjust console size */
-	return 0;
-}
-
-static int vgacon_font_op(struct vc_data *c, struct console_font_op *op)
-{
-	int rc;
-
-	if (vga_video_type < VIDEO_TYPE_EGAM)
-		return -EINVAL;
-
-	if (op->op == KD_FONT_OP_SET) {
-		if (op->width != 8 || (op->charcount != 256 && op->charcount != 512))
-			return -EINVAL;
-		rc = vgacon_do_font_op(op->data, 1, op->charcount == 512);
-		if (!rc && !(op->flags & KD_FONT_FLAG_DONT_RECALC))
-			rc = vgacon_adjust_height(op->height);
-	} else if (op->op == KD_FONT_OP_GET) {
-		op->width = 8;
-		op->height = vga_video_font_height;
-		op->charcount = vga_512_chars ? 512 : 256;
-		if (!op->data) return 0;
-		rc = vgacon_do_font_op(op->data, 0, 0);
-	} else
-		rc = -ENOSYS;
-	return rc;
-}
-
-#else
-
-static int vgacon_font_op(struct vc_data *c, struct console_font_op *op)
-{
-	return -ENOSYS;
-}
-
-#endif
-
-static int vgacon_scrolldelta(struct vc_data *c, int lines)
-{
-	if (!lines)			/* Turn scrollback off */
-		c->vc_visible_origin = c->vc_origin;
-	else {
-		int vram_size = vga_vram_end - vga_vram_base;
-		int margin = c->vc_size_row * 4;
-		int ul, we, p, st;
-
-		if (vga_rolled_over > (c->vc_scr_end - vga_vram_base) + margin) {
-			ul = c->vc_scr_end - vga_vram_base;
-			we = vga_rolled_over + c->vc_size_row;
-		} else {
-			ul = 0;
-			we = vram_size;
-		}
-		p = (c->vc_visible_origin - vga_vram_base - ul + we) % we + lines * c->vc_size_row;
-		st = (c->vc_origin - vga_vram_base - ul + we) % we;
-		if (p < margin)
-			p = 0;
-		if (p > st - margin)
-			p = st;
-		c->vc_visible_origin = vga_vram_base + (p + ul) % we;
-	}
-	vga_set_mem_top(c);
-	return 1;
-}
-
-static int vgacon_set_origin(struct vc_data *c)
-{
-	if (vga_is_gfx ||	/* We don't play origin tricks in graphic modes */
-	    (console_blanked && !vga_palette_blanked))	/* Nor we write to blanked screens */
-		return 0;
-	c->vc_origin = c->vc_visible_origin = vga_vram_base;
-	vga_set_mem_top(c);
-	vga_rolled_over = 0;
-	return 1;
-}
-
-static void vgacon_save_screen(struct vc_data *c)
-{
-	static int vga_bootup_console = 0;
-
-	if (!vga_bootup_console) {
-		/* This is a gross hack, but here is the only place we can
-		 * set bootup console parameters without messing up generic
-		 * console initialization routines.
-		 */
-		vga_bootup_console = 1;
-		c->vc_x = ORIG_X;
-		c->vc_y = ORIG_Y;
-	}
-	if (!vga_is_gfx)
-		scr_memcpyw((u16 *) c->vc_screenbuf, (u16 *) c->vc_origin, c->vc_screenbuf_size);
-}
-
-static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
-{
-	unsigned long oldo;
-	unsigned int delta;
-	
-	if (t || b != c->vc_rows || vga_is_gfx)
-		return 0;
-
-	if (c->vc_origin != c->vc_visible_origin)
-		vgacon_scrolldelta(c, 0);
-
-	if (!vga_hardscroll_enabled || lines >= c->vc_rows/2)
-		return 0;
-
-	oldo = c->vc_origin;
-	delta = lines * c->vc_size_row;
-	if (dir == SM_UP) {
-		if (c->vc_scr_end + delta >= vga_vram_end) {
-			scr_memcpyw((u16 *)vga_vram_base,
-				    (u16 *)(oldo + delta),
-				    c->vc_screenbuf_size - delta);
-			c->vc_origin = vga_vram_base;
-			vga_rolled_over = oldo - vga_vram_base;
-		} else
-			c->vc_origin += delta;
-		scr_memsetw((u16 *)(c->vc_origin + c->vc_screenbuf_size - delta), c->vc_video_erase_char, delta);
-	} else {
-		if (oldo - delta < vga_vram_base) {
-			scr_memmovew((u16 *)(vga_vram_end - c->vc_screenbuf_size + delta),
-				     (u16 *)oldo,
-				     c->vc_screenbuf_size - delta);
-			c->vc_origin = vga_vram_end - c->vc_screenbuf_size;
-			vga_rolled_over = 0;
-		} else
-			c->vc_origin -= delta;
-		c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;
-		scr_memsetw((u16 *)(c->vc_origin), c->vc_video_erase_char, delta);
-	}
-	c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;
-	c->vc_visible_origin = c->vc_origin;
-	vga_set_mem_top(c);
-	c->vc_pos = (c->vc_pos - oldo) + c->vc_origin;
-	return 1;
-}
-
-
-/*
- *  The console `switch' structure for the VGA based console
- */
-
-static int vgacon_dummy(struct vc_data *c)
-{
-	return 0;
-}
-
-#define DUMMY (void *) vgacon_dummy
-
-const struct consw vga_con = {
-	.con_startup =		vgacon_startup,
-	.con_init =		vgacon_init,
-	.con_deinit =		vgacon_deinit,
-	.con_clear =		DUMMY,
-	.con_putc =		DUMMY,
-	.con_putcs =		DUMMY,
-	.con_cursor =		vgacon_cursor,
-	.con_scroll =		vgacon_scroll,
-	.con_bmove =		DUMMY,
-	.con_switch =		vgacon_switch,
-	.con_blank =		vgacon_blank,
-	.con_font_op =		vgacon_font_op,
-	.con_set_palette =	vgacon_set_palette,
-	.con_scrolldelta =	vgacon_scrolldelta,
-	.con_set_origin =	vgacon_set_origin,
-	.con_save_screen =	vgacon_save_screen,
-	.con_build_attr =	vgacon_build_attr,
-	.con_invert_region =	vgacon_invert_region,
-};
-
-MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/vgastate.c b/drivers/video/vgastate.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/vgastate.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,503 @@
+/*
+ * linux/drivers/video/vgastate.c -- VGA state save/restore
+ *
+ * Copyright 2002 James Simmons
+ * 
+ * Copyright history from vga16fb.c:
+ *	Copyright 1999 Ben Pfaff and Petr Vandrovec
+ *	Based on VGA info at http://www.goodnet.com/~tinara/FreeVGA/home.htm
+ *	Based on VESA framebuffer (c) 1998 Gerd Knorr
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.  
+ *
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/fb.h>
+#include <video/vga.h>
+
+struct regstate {
+	__u8 *vga_font0;
+	__u8 *vga_font1;
+	__u8 *vga_text;
+	__u8 *vga_cmap;
+	__u8 *attr;
+	__u8 *crtc;
+	__u8 *gfx;
+	__u8 *seq;
+	__u8 misc;
+};	
+
+static inline unsigned char vga_rcrtcs(caddr_t regbase, unsigned short iobase, 
+				       unsigned char reg)
+{
+	vga_w(regbase, iobase + 0x4, reg);
+	return vga_r(regbase, iobase + 0x5);
+}
+
+static inline void vga_wcrtcs(caddr_t regbase, unsigned short iobase, 
+			      unsigned char reg, unsigned char val)
+{
+	vga_w(regbase, iobase + 0x4, reg);
+	vga_w(regbase, iobase + 0x5, val);
+}
+
+static void save_vga_text(struct vgastate *state, caddr_t fbbase)
+{
+	struct regstate *saved = (struct regstate *) state->vidstate;
+	int i;
+	u8 misc, attr10, gr4, gr5, gr6, seq1, seq2, seq4;
+
+	/* if in graphics mode, no need to save */
+	attr10 = vga_rattr(state->vgabase, 0x10);
+	if (attr10 & 1)
+		return;
+	
+	/* save regs */
+	misc = vga_r(state->vgabase, VGA_MIS_R);
+	gr4 = vga_rgfx(state->vgabase, VGA_GFX_PLANE_READ);
+	gr5 = vga_rgfx(state->vgabase, VGA_GFX_MODE);
+	gr6 = vga_rgfx(state->vgabase, VGA_GFX_MISC);
+	seq2 = vga_rseq(state->vgabase, VGA_SEQ_PLANE_WRITE);
+	seq4 = vga_rseq(state->vgabase, VGA_SEQ_MEMORY_MODE);
+	
+	/* force graphics mode */
+	vga_w(state->vgabase, VGA_MIS_W, misc | 1);
+
+	/* blank screen */
+	seq1 = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE);
+	vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
+	vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, seq1 | 1 << 5);
+	vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x3);
+
+	/* save font at plane 2 */
+	if (state->flags & VGA_SAVE_FONT0) {
+		vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x4);
+		vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6);
+		vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x2);
+		vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
+		vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
+		for (i = 0; i < 4 * 8192; i++) 
+			saved->vga_font0[i] = vga_r(fbbase, i);
+	}
+
+	/* save font at plane 3 */
+	if (state->flags & VGA_SAVE_FONT1) {
+		vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x8);
+		vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6);
+		vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x3);
+		vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
+		vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
+		for (i = 0; i < state->memsize; i++) 
+			saved->vga_font1[i] = vga_r(fbbase, i);
+	}
+	
+	/* save font at plane 0/1 */
+	if (state->flags & VGA_SAVE_TEXT) {
+		vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x1);
+		vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6);
+		vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x0);
+		vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
+		vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
+		for (i = 0; i < 8192; i++) 
+			saved->vga_text[i] = vga_r(fbbase, i);
+
+		vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x2);
+		vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6);
+		vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x1);
+		vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
+		vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
+		for (i = 0; i < 8192; i++) 
+			saved->vga_text[i] = vga_r(fbbase + 2 * 8192, i); 
+	}
+
+	/* restore regs */
+	vga_wattr(state->vgabase, 0x10, attr10);
+
+	vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, seq2);
+	vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, seq4);
+
+	vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, gr4);
+	vga_wgfx(state->vgabase, VGA_GFX_MODE, gr5);
+	vga_wgfx(state->vgabase, VGA_GFX_MISC, gr6);
+	vga_w(state->vgabase, VGA_MIS_W, misc);
+
+	/* unblank screen */
+	vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
+	vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, seq1 & ~(1 << 5));
+	vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x3);
+
+	vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, seq1);
+}
+
+static void restore_vga_text(struct vgastate *state, caddr_t fbbase)
+{
+	struct regstate *saved = (struct regstate *) state->vidstate;
+	int i;
+	u8 misc, gr1, gr3, gr4, gr5, gr6, gr8; 
+	u8 seq1, seq2, seq4;
+
+	/* save regs */
+	misc = vga_r(state->vgabase, VGA_MIS_R);
+	gr1 = vga_rgfx(state->vgabase, VGA_GFX_SR_ENABLE);
+	gr3 = vga_rgfx(state->vgabase, VGA_GFX_DATA_ROTATE);
+	gr4 = vga_rgfx(state->vgabase, VGA_GFX_PLANE_READ);
+	gr5 = vga_rgfx(state->vgabase, VGA_GFX_MODE);
+	gr6 = vga_rgfx(state->vgabase, VGA_GFX_MISC);
+	gr8 = vga_rgfx(state->vgabase, VGA_GFX_BIT_MASK);
+	seq2 = vga_rseq(state->vgabase, VGA_SEQ_PLANE_WRITE);
+	seq4 = vga_rseq(state->vgabase, VGA_SEQ_MEMORY_MODE);
+	
+	/* force graphics mode */
+	vga_w(state->vgabase, VGA_MIS_W, misc | 1);
+
+	/* blank screen */
+	seq1 = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE);
+	vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
+	vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, seq1 | 1 << 5);
+	vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x3);
+
+	if (state->depth == 4) {
+		vga_wgfx(state->vgabase, VGA_GFX_DATA_ROTATE, 0x0);
+		vga_wgfx(state->vgabase, VGA_GFX_BIT_MASK, 0xff);
+		vga_wgfx(state->vgabase, VGA_GFX_SR_ENABLE, 0x00);
+	}
+	
+	/* restore font at plane 2 */
+	if (state->flags & VGA_SAVE_FONT0) {
+		vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x4);
+		vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6);
+		vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x2);
+		vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
+		vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
+		for (i = 0; i < 4 * 8192; i++) 
+			vga_w(fbbase, i, saved->vga_font0[i]);
+	}
+
+	/* restore font at plane 3 */
+	if (state->flags & VGA_SAVE_FONT1) {
+		vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x8);
+		vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6);
+		vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x3);
+		vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
+		vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
+		for (i = 0; i < 4 * 8192; i++) 
+			vga_w(fbbase, i, saved->vga_font1[i]);
+	}
+	
+	/* restore font at plane 0/1 */
+	if (state->flags & VGA_SAVE_TEXT) {
+		vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x1);
+		vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6);
+		vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x0);
+		vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
+		vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
+		for (i = 0; i < 8192; i++) 
+			vga_w(fbbase, i, saved->vga_text[i]);
+		
+		vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x2);
+		vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x6);
+		vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x1);
+		vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x0);
+		vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x5);
+		for (i = 0; i < 8192; i++) 
+			vga_w(fbbase + 2 * 8192, i, 
+			      saved->vga_text[i]);
+	}
+
+	/* unblank screen */
+	vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
+	vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, seq1 & ~(1 << 5));
+	vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x3);
+
+	/* restore regs */
+	vga_w(state->vgabase, VGA_MIS_W, misc);
+
+	vga_wgfx(state->vgabase, VGA_GFX_SR_ENABLE, gr1);
+	vga_wgfx(state->vgabase, VGA_GFX_DATA_ROTATE, gr3);
+	vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, gr4);
+	vga_wgfx(state->vgabase, VGA_GFX_MODE, gr5);
+	vga_wgfx(state->vgabase, VGA_GFX_MISC, gr6);
+	vga_wgfx(state->vgabase, VGA_GFX_BIT_MASK, gr8);
+
+	vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, seq1);
+	vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, seq2);
+	vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, seq4);
+}
+			      
+static void save_vga_mode(struct vgastate *state)
+{
+	struct regstate *saved = (struct regstate *) state->vidstate;
+	unsigned short iobase;
+	int i;
+
+	saved->misc = vga_r(state->vgabase, VGA_MIS_R);
+	if (saved->misc & 1)
+		iobase = 0x3d0;
+	else
+		iobase = 0x3b0;
+
+	for (i = 0; i < state->num_crtc; i++) 
+		saved->crtc[i] = vga_rcrtcs(state->vgabase, iobase, i);
+	
+	vga_r(state->vgabase, iobase + 0xa); 
+	vga_w(state->vgabase, VGA_ATT_W, 0x00);
+	for (i = 0; i < state->num_attr; i++) {
+		vga_r(state->vgabase, iobase + 0xa);
+		saved->attr[i] = vga_rattr(state->vgabase, i);
+	}
+	vga_r(state->vgabase, iobase + 0xa);
+	vga_w(state->vgabase, VGA_ATT_W, 0x20);
+
+	for (i = 0; i < state->num_gfx; i++) 
+		saved->gfx[i] = vga_rgfx(state->vgabase, i);
+
+	for (i = 0; i < state->num_seq; i++) 
+		saved->seq[i] = vga_rseq(state->vgabase, i);
+}
+
+static void restore_vga_mode(struct vgastate *state)
+{
+	struct regstate *saved = (struct regstate *) state->vidstate;
+	unsigned short iobase;
+	int i;
+
+	vga_w(state->vgabase, VGA_MIS_W, saved->misc);
+
+	if (saved->misc & 1)
+		iobase = 0x3d0;
+	else
+		iobase = 0x3b0;
+
+	/* turn off display */
+	vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, 
+		 saved->seq[VGA_SEQ_CLOCK_MODE] | 0x20);
+
+	/* disable sequencer */
+	vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x01);
+	
+	/* enable palette addressing */
+	vga_r(state->vgabase, iobase + 0xa);
+	vga_w(state->vgabase, VGA_ATT_W, 0x00);
+
+	for (i = 2; i < state->num_seq; i++) 
+		vga_wseq(state->vgabase, i, saved->seq[i]);
+
+
+	/* unprotect vga regs */
+	vga_wcrtcs(state->vgabase, iobase, 17, saved->crtc[17] & ~0x80);
+	for (i = 0; i < state->num_crtc; i++) 
+		vga_wcrtcs(state->vgabase, iobase, i, saved->crtc[i]);
+	
+	for (i = 0; i < state->num_gfx; i++) 
+		vga_wgfx(state->vgabase, i, saved->gfx[i]);
+
+	for (i = 0; i < state->num_attr; i++) {
+		vga_r(state->vgabase, iobase + 0xa);
+		vga_wattr(state->vgabase, i, saved->attr[i]);
+	}
+
+	/* reenable sequencer */
+	vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x03);
+	/* turn display on */
+	vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, 
+		 saved->seq[VGA_SEQ_CLOCK_MODE] & ~(1 << 5));
+
+	/* disable video/palette source */
+	vga_r(state->vgabase, iobase + 0xa);
+	vga_w(state->vgabase, VGA_ATT_W, 0x20);
+}
+
+static void save_vga_cmap(struct vgastate *state)
+{
+	struct regstate *saved = (struct regstate *) state->vidstate;
+	int i;
+
+	vga_w(state->vgabase, VGA_PEL_MSK, 0xff);
+	
+	/* assumes DAC is readable and writable */
+	vga_w(state->vgabase, VGA_PEL_IR, 0x00);
+	for (i = 0; i < 768; i++)
+		saved->vga_cmap[i] = vga_r(state->vgabase, VGA_PEL_D);
+}
+
+static void restore_vga_cmap(struct vgastate *state)
+{
+	struct regstate *saved = (struct regstate *) state->vidstate;
+	int i;
+
+	vga_w(state->vgabase, VGA_PEL_MSK, 0xff);
+
+	/* assumes DAC is readable and writable */
+	vga_w(state->vgabase, VGA_PEL_IW, 0x00);
+	for (i = 0; i < 768; i++)
+		vga_w(state->vgabase, VGA_PEL_D, saved->vga_cmap[i]);
+}
+
+static void vga_cleanup(struct vgastate *state)
+{
+	if (state->vidstate != NULL) {
+		struct regstate *saved = (struct regstate *) state->vidstate;
+
+		if (saved->vga_font0) 
+			vfree(saved->vga_font0);
+		if (saved->vga_font1) 
+			vfree(saved->vga_font1);
+		if (saved->vga_text)
+			vfree(saved->vga_text);
+		if (saved->vga_cmap)
+			vfree(saved->vga_cmap);
+		if (saved->attr)
+			vfree(saved->attr);
+		kfree(saved);
+		state->vidstate = NULL;
+	}
+}
+		
+int save_vga(struct vgastate *state)
+{
+	struct regstate *saved;
+
+	saved = kmalloc(sizeof(struct regstate), GFP_KERNEL);
+	if (saved == NULL)
+		return 1;
+	memset (saved, 0, sizeof(struct regstate));
+	(struct regstate *) state->vidstate = saved;
+		
+	if (state->flags & VGA_SAVE_CMAP) {
+		saved->vga_cmap = vmalloc(768);
+		if (!saved->vga_cmap) {
+			vga_cleanup(state);
+			return 1;
+		}
+		save_vga_cmap(state);
+	}
+
+	if (state->flags & VGA_SAVE_MODE) {
+		int total;
+
+		if (state->num_attr < 21)
+			state->num_attr = 21;
+		if (state->num_crtc < 25)
+			state->num_crtc = 25;
+		if (state->num_gfx < 9)
+			state->num_gfx = 9;
+		if (state->num_seq < 5)
+			state->num_seq = 5;
+		total = state->num_attr + state->num_crtc +
+			state->num_gfx + state->num_seq;
+
+		saved->attr = vmalloc(total);
+		if (!saved->attr) {
+			vga_cleanup(state);
+			return 1;
+		}
+		saved->crtc = saved->attr + state->num_attr;
+		saved->gfx = saved->crtc + state->num_crtc;
+		saved->seq = saved->gfx + state->num_gfx;
+
+		save_vga_mode(state);
+	}
+
+	if (state->flags & VGA_SAVE_FONTS) {
+		caddr_t fbbase;
+
+		/* exit if window is less than 32K */
+		if (state->memsize && state->memsize < 4 * 8192) {
+			vga_cleanup(state);
+			return 1;
+		}
+		if (!state->memsize)
+			state->memsize = 8 * 8192;
+		
+		if (!state->membase)
+			state->membase = 0xA0000;
+
+		fbbase = ioremap(state->membase, state->memsize);
+
+		if (!fbbase) {
+			vga_cleanup(state);
+			iounmap(fbbase);
+			return 1;
+	}
+
+		/* 
+		 * save only first 32K used by vgacon
+		 */
+		if (state->flags & VGA_SAVE_FONT0) {
+			saved->vga_font0 = vmalloc(4 * 8192);
+			if (!saved->vga_font0) {
+			vga_cleanup(state);
+			return 1;
+		}
+	}
+		/* 
+		 * largely unused, but if required by the caller
+		 * we'll just save everything.
+		 */
+		if (state->flags & VGA_SAVE_FONT1) {
+			saved->vga_font1 = vmalloc(state->memsize);
+			if (!saved->vga_font1) {
+			vga_cleanup(state);
+			return 1;
+		}
+	}
+		/*
+		 * Save 8K at plane0[0], and 8K at plane1[16K]
+		 */
+		if (state->flags & VGA_SAVE_TEXT) {
+			saved->vga_text = vmalloc(8192 * 2);
+			if (!saved->vga_text) {
+			vga_cleanup(state);
+			return 1;
+		}
+		}
+		
+		save_vga_text(state, fbbase);
+		iounmap(fbbase);
+	}
+	return 0;
+}
+
+int restore_vga (struct vgastate *state)
+{
+	if (state->vidstate == NULL)
+		return 1;
+
+	if (state->flags & VGA_SAVE_MODE)
+		restore_vga_mode(state);
+
+	if (state->flags & VGA_SAVE_FONTS) {
+		caddr_t fbbase = ioremap(state->membase, state->memsize);
+
+		if (!fbbase) {
+			vga_cleanup(state);
+			iounmap(fbbase);
+			return 1;
+		}
+		restore_vga_text(state, fbbase);
+		iounmap(fbbase);
+	}
+
+	if (state->flags & VGA_SAVE_CMAP)
+		restore_vga_cmap(state);
+
+	vga_cleanup(state);
+	return 0;
+}
+
+#ifdef MODULE
+int init_module(void) { return 0; };
+void cleanup_module(void) {};
+#endif
+
+EXPORT_SYMBOL(save_vga);
+EXPORT_SYMBOL(restore_vga);
+
+MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
+MODULE_DESCRIPTION("VGA State Save/Restore");
+MODULE_LICENSE("GPL");
+
diff -Nru a/drivers/video/virgefb.c b/drivers/video/virgefb.c
--- a/drivers/video/virgefb.c	Mon Dec  9 18:46:35 2002
+++ b/drivers/video/virgefb.c	Mon Dec  9 18:46:35 2002
@@ -1806,7 +1806,7 @@
 	}
 
 	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);
+	       minor(fb_info.node), fb_info.modename, v_ram_size>>10);
 
 	/* TODO: This driver cannot be unloaded yet */
 
diff -Nru a/fs/affs/file.c b/fs/affs/file.c
--- a/fs/affs/file.c	Mon Dec  9 18:46:37 2002
+++ b/fs/affs/file.c	Mon Dec  9 18:46:37 2002
@@ -391,9 +391,6 @@
 	affs_unlock_ext(inode);
 	return 0;
 
-err_small:
-	affs_error(inode->i_sb,"get_block","Block < 0");
-	return -EIO;
 err_big:
 	affs_error(inode->i_sb,"get_block","strange block request %d", block);
 	return -EIO;
diff -Nru a/fs/attr.c b/fs/attr.c
--- a/fs/attr.c	Mon Dec  9 18:46:34 2002
+++ b/fs/attr.c	Mon Dec  9 18:46:34 2002
@@ -66,14 +66,21 @@
 {
 	unsigned int ia_valid = attr->ia_valid;
 	int error = 0;
-	
-	lock_kernel();
+
 	if (ia_valid & ATTR_SIZE) {
-		error = vmtruncate(inode, attr->ia_size);
-		if (error)
-			goto out;
+		if (attr->ia_size == inode->i_size) {
+			if (ia_valid == ATTR_SIZE)
+				goto out;	/* we can skip lock_kernel() */
+		} else {
+			lock_kernel();
+			error = vmtruncate(inode, attr->ia_size);
+			unlock_kernel();
+			if (error)
+				goto out;
+		}
 	}
 
+	lock_kernel();
 	if (ia_valid & ATTR_UID)
 		inode->i_uid = attr->ia_uid;
 	if (ia_valid & ATTR_GID)
@@ -90,8 +97,8 @@
 			inode->i_mode &= ~S_ISGID;
 	}
 	mark_inode_dirty(inode);
-out:
 	unlock_kernel();
+out:
 	return error;
 }
 
@@ -157,7 +164,8 @@
 		return 0;
 
 	if (inode->i_op && inode->i_op->setattr) {
-		if (!(error = security_inode_setattr(dentry, attr)))
+		error = security_inode_setattr(dentry, attr);
+		if (!error)
 			error = inode->i_op->setattr(dentry, attr);
 	} else {
 		error = inode_change_ok(inode, attr);
diff -Nru a/fs/autofs/autofs_i.h b/fs/autofs/autofs_i.h
--- a/fs/autofs/autofs_i.h	Mon Dec  9 18:46:50 2002
+++ b/fs/autofs/autofs_i.h	Mon Dec  9 18:46:50 2002
@@ -26,6 +26,9 @@
 #include <linux/dcache.h>
 #include <linux/namei.h>
 #include <linux/mount.h>
+#include <linux/sched.h>
+
+#include <asm/current.h>
 #include <asm/uaccess.h>
 
 #ifdef DEBUG
diff -Nru a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
--- a/fs/autofs4/autofs_i.h	Mon Dec  9 18:46:50 2002
+++ b/fs/autofs4/autofs_i.h	Mon Dec  9 18:46:50 2002
@@ -24,6 +24,8 @@
 #include <linux/time.h>
 #include <linux/string.h>
 #include <linux/wait.h>
+#include <linux/sched.h>
+#include <asm/current.h>
 #include <asm/uaccess.h>
 
 /* #define DEBUG */
diff -Nru a/fs/bad_inode.c b/fs/bad_inode.c
--- a/fs/bad_inode.c	Mon Dec  9 18:46:35 2002
+++ b/fs/bad_inode.c	Mon Dec  9 18:46:35 2002
@@ -84,6 +84,8 @@
  
 void make_bad_inode(struct inode * inode) 
 {
+	remove_inode_hash(inode);
+
 	inode->i_mode = S_IFREG;
 	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 	inode->i_op = &bad_inode_ops;	
diff -Nru a/fs/buffer.c b/fs/buffer.c
--- a/fs/buffer.c	Mon Dec  9 18:46:38 2002
+++ b/fs/buffer.c	Mon Dec  9 18:46:38 2002
@@ -63,7 +63,9 @@
 		return;
 	enough++;
 	printk("buffer layer error at %s:%d\n", file, line);
+#ifndef CONFIG_KALLSYMS
 	printk("Pass this trace through ksymoops for reporting\n");
+#endif
 	dump_stack();
 }
 EXPORT_SYMBOL(__buffer_error);
@@ -2292,7 +2294,7 @@
 			bh->b_page = page;
 			bh->b_blocknr = map_bh.b_blocknr;
 			bh->b_size = blocksize;
-			bh->b_data = (char *)block_start;
+			bh->b_data = (char *)(long)block_start;
 			bh->b_bdev = map_bh.b_bdev;
 			bh->b_private = NULL;
 			read_bh[nr_reads++] = bh;
@@ -2633,7 +2635,7 @@
  */
 static void check_ttfb_buffer(struct page *page, struct buffer_head *bh)
 {
-	if (!buffer_uptodate(bh)) {
+	if (!buffer_uptodate(bh) && !buffer_req(bh)) {
 		if (PageUptodate(page) && page->mapping
 			&& buffer_mapped(bh)	/* discard_buffer */
 			&& S_ISBLK(page->mapping->host->i_mode))
@@ -2681,7 +2683,7 @@
 		check_ttfb_buffer(page, bh);
 		if (buffer_busy(bh))
 			goto failed;
-		if (!buffer_uptodate(bh))
+		if (!buffer_uptodate(bh) && !buffer_req(bh))
 			was_uptodate = 0;
 		bh = bh->b_this_page;
 	} while (bh != head);
diff -Nru a/fs/coda/psdev.c b/fs/coda/psdev.c
--- a/fs/coda/psdev.c	Mon Dec  9 18:46:49 2002
+++ b/fs/coda/psdev.c	Mon Dec  9 18:46:49 2002
@@ -362,21 +362,24 @@
 	.release	= coda_psdev_release,
 };
 
-static devfs_handle_t devfs_handle;
-
 static int init_coda_psdev(void)
 {
-	if(register_chrdev(CODA_PSDEV_MAJOR,"coda_psdev",
+	int i;
+	if (register_chrdev(CODA_PSDEV_MAJOR,"coda_psdev",
 				 &coda_psdev_fops)) {
               printk(KERN_ERR "coda_psdev: unable to get major %d\n", 
 		     CODA_PSDEV_MAJOR);
               return -EIO;
 	}
-	devfs_handle = devfs_mk_dir (NULL, "coda", NULL);
-	devfs_register_series (devfs_handle, "%u", MAX_CODADEVS, DEVFS_FL_NONE,
-			       CODA_PSDEV_MAJOR, 0,
+	devfs_mk_dir (NULL, "coda", NULL);
+	for (i = 0; i < MAX_CODADEVS; i++) {
+		char name[16];
+		sprintf(name, "coda/%d", i);
+		devfs_register(NULL, name, DEVFS_FL_NONE,
+			       CODA_PSDEV_MAJOR, i,
 			       S_IFCHR | S_IRUSR | S_IWUSR,
 			       &coda_psdev_fops, NULL);
+	}
 
 	coda_sysctl_init();
 
@@ -392,6 +395,7 @@
 static int __init init_coda(void)
 {
 	int status;
+	int i;
 	printk(KERN_INFO "Coda Kernel/Venus communications, v5.3.15, coda@cs.cmu.edu\n");
 
 	status = coda_init_inodecache();
@@ -410,7 +414,9 @@
 	}
 	return 0;
 out:
-	devfs_unregister(devfs_handle);
+	for (i = 0; i < MAX_CODADEVS; i++)
+		devfs_remove("coda/%d", i);
+	devfs_remove("coda");
 	unregister_chrdev(CODA_PSDEV_MAJOR,"coda_psdev");
 	coda_sysctl_clean();
 out1:
@@ -421,13 +427,15 @@
 
 static void __exit exit_coda(void)
 {
-        int err;
+        int err, i;
 
 	err = unregister_filesystem(&coda_fs_type);
         if ( err != 0 ) {
                 printk("coda: failed to unregister filesystem\n");
         }
-	devfs_unregister(devfs_handle);
+	for (i = 0; i < MAX_CODADEVS; i++)
+		devfs_remove("coda/%d", i);
+	devfs_remove("coda");
 	unregister_chrdev(CODA_PSDEV_MAJOR, "coda_psdev");
 	coda_sysctl_clean();
 	coda_destroy_inodecache();
diff -Nru a/fs/devfs/base.c b/fs/devfs/base.c
--- a/fs/devfs/base.c	Mon Dec  9 18:46:35 2002
+++ b/fs/devfs/base.c	Mon Dec  9 18:46:35 2002
@@ -703,8 +703,6 @@
 
 #define MODE_DIR (S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO)
 
-#define IS_HIDDEN(de) ( (de)->hide && !is_devfsd_or_child(fs_info) )
-
 #define DEBUG_NONE         0x0000000
 #define DEBUG_MODULE_LOAD  0x0000001
 #define DEBUG_REGISTER     0x0000002
@@ -765,29 +763,23 @@
 
 struct file_type
 {
+    struct file_operations *ops;
     unsigned long size;
 };
 
-struct device_type
+struct bdev_type
 {
-    unsigned short major;
-    unsigned short minor;
+    struct block_device_operations *ops;
+    dev_t dev;
+    unsigned char autogen:1;
+    unsigned char removable:1;
 };
 
-struct fcb_type  /*  File, char, block type  */
+struct cdev_type
 {
-    void *ops;
-    union 
-    {
-	struct file_type file;
-	struct device_type device;
-    }
-    u;
-    spinlock_t lock;            /*  Lock for changes                         */
-    unsigned char aopen_notify:1;
-    unsigned char removable:1;  /*  Belongs in device_type, but save space   */
-    unsigned char open:1;       /*  Not entirely correct                     */
-    unsigned char autogen:1;    /*  Belongs in device_type, but save space   */
+    struct file_operations *ops;
+    dev_t dev;
+    unsigned char autogen:1;
 };
 
 struct symlink_type
@@ -817,7 +809,9 @@
     union 
     {
 	struct directory_type dir;
-	struct fcb_type fcb;
+	struct file_type file;
+	struct bdev_type bdev;
+	struct cdev_type cdev;
 	struct symlink_type symlink;
 	const char *name;        /*  Only used for (mode == 0)               */
     }
@@ -825,11 +819,9 @@
     struct devfs_entry *prev;    /*  Previous entry in the parent directory  */
     struct devfs_entry *next;    /*  Next entry in the parent directory      */
     struct devfs_entry *parent;  /*  The parent directory                    */
-    struct devfs_entry *slave;   /*  Another entry to unregister             */
     struct devfs_inode inode;
     umode_t mode;
     unsigned short namelen;      /*  I think 64k+ filenames are a way off... */
-    unsigned char hide:1;
     unsigned char vfs_deletable:1;/*  Whether the VFS may delete the entry   */
     char name[1];                /*  This is just a dummy: the allocated array
 				     is bigger. This is NULL-terminated      */
@@ -942,13 +934,10 @@
 	     de->name, de, de->parent,
 	     de->parent ? de->parent->name : "no parent");
     if ( S_ISLNK (de->mode) ) kfree (de->u.symlink.linkname);
-    if ( ( S_ISCHR (de->mode) || S_ISBLK (de->mode) ) && de->u.fcb.autogen )
-    {
-	devfs_dealloc_devnum ( S_ISCHR (de->mode) ? DEVFS_SPECIAL_CHR :
-			       DEVFS_SPECIAL_BLK,
-			       mk_kdev (de->u.fcb.u.device.major,
-					de->u.fcb.u.device.minor) );
-    }
+    if ( S_ISCHR (de->mode) && de->u.cdev.autogen )
+	devfs_dealloc_devnum (DEVFS_SPECIAL_CHR, de->u.cdev.dev);
+    if ( S_ISBLK (de->mode) && de->u.bdev.autogen )
+	devfs_dealloc_devnum(DEVFS_SPECIAL_BLK, de->u.bdev.dev);
     WRITE_ENTRY_MAGIC (de, 0);
 #ifdef CONFIG_DEVFS_DEBUG
     spin_lock (&stat_lock);
@@ -1016,8 +1005,6 @@
     memset (new, 0, sizeof *new + namelen);  /*  Will set '\0' on name  */
     new->mode = mode;
     if ( S_ISDIR (mode) ) rwlock_init (&new->u.dir.lock);
-    else if ( S_ISREG (mode) || S_ISCHR (mode) || S_ISBLK (mode) )
-	spin_lock_init (&new->u.fcb.lock);
     atomic_set (&new->refcount, 1);
     spin_lock (&counter_lock);
     new->inode.ino = inode_counter++;
@@ -1097,7 +1084,6 @@
 
 static struct devfs_entry *_devfs_get_root_entry (void)
 {
-    kdev_t devnum;
     struct devfs_entry *new;
     static spinlock_t root_lock = SPIN_LOCK_UNLOCKED;
 
@@ -1116,18 +1102,14 @@
     /*  And create the entry for ".devfsd"  */
     if ( ( new = _devfs_alloc_entry (".devfsd", 0, S_IFCHR |S_IRUSR |S_IWUSR) )
 	 == NULL ) return NULL;
-    devnum = devfs_alloc_devnum (DEVFS_SPECIAL_CHR);
-    new->u.fcb.u.device.major = major (devnum);
-    new->u.fcb.u.device.minor = minor (devnum);
-    new->u.fcb.ops = &devfsd_fops;
+    new->u.cdev.dev = devfs_alloc_devnum (DEVFS_SPECIAL_CHR);
+    new->u.cdev.ops = &devfsd_fops;
     _devfs_append_entry (root_entry, new, FALSE, NULL);
 #ifdef CONFIG_DEVFS_DEBUG
     if ( ( new = _devfs_alloc_entry (".stat", 0, S_IFCHR | S_IRUGO | S_IWUGO) )
 	 == NULL ) return NULL;
-    devnum = devfs_alloc_devnum (DEVFS_SPECIAL_CHR);
-    new->u.fcb.u.device.major = major (devnum);
-    new->u.fcb.u.device.minor = minor (devnum);
-    new->u.fcb.ops = &stat_fops;
+    new->u.cdev.dev = devfs_alloc_devnum (DEVFS_SPECIAL_CHR);
+    new->u.cdev.ops = &stat_fops;
     _devfs_append_entry (root_entry, new, FALSE, NULL);
 #endif
     return root_entry;
@@ -1278,79 +1260,11 @@
     return dir;
 }   /*  End Function _devfs_walk_path  */
 
-
-/**
- *	_devfs_find_by_dev - Find a devfs entry in a directory.
- *	@dir: The directory where to search
- *	@major: The major number to search for.
- *	@minor: The minor number to search for.
- *	@type: The type of special file to search for. This may be either
- *		%DEVFS_SPECIAL_CHR or %DEVFS_SPECIAL_BLK.
- *
- *	Returns the devfs_entry pointer on success, else %NULL. An implicit
- *	devfs_get() is performed.
- */
-
-static struct devfs_entry *_devfs_find_by_dev (struct devfs_entry *dir,
-					       unsigned int major,
-					       unsigned int minor, char type)
-{
-    struct devfs_entry *entry, *de;
-
-    devfs_get (dir);
-    if (dir == NULL) return NULL;
-    if ( !S_ISDIR (dir->mode) )
-    {
-	PRINTK ("(%p): not a directory\n", dir);
-	devfs_put (dir);
-	return NULL;
-    }
-    /*  First search files in this directory  */
-    read_lock (&dir->u.dir.lock);
-    for (entry = dir->u.dir.first; entry != NULL; entry = entry->next)
-    {
-	if ( !S_ISCHR (entry->mode) && !S_ISBLK (entry->mode) ) continue;
-	if ( S_ISCHR (entry->mode) && (type != DEVFS_SPECIAL_CHR) ) continue;
-	if ( S_ISBLK (entry->mode) && (type != DEVFS_SPECIAL_BLK) ) continue;
-	if ( (entry->u.fcb.u.device.major == major) &&
-	     (entry->u.fcb.u.device.minor == minor) )
-	{
-	    devfs_get (entry);
-	    read_unlock (&dir->u.dir.lock);
-	    devfs_put (dir);
-	    return entry;
-	}
-	/*  Not found: try the next one  */
-    }
-    /*  Now recursively search the subdirectories: this is a stack chomper  */
-    for (entry = dir->u.dir.first; entry != NULL; entry = entry->next)
-    {
-	if ( !S_ISDIR (entry->mode) ) continue;
-	de = _devfs_find_by_dev (entry, major, minor, type);
-	if (de)
-	{
-	    read_unlock (&dir->u.dir.lock);
-	    devfs_put (dir);
-	    return de;
-	}
-    }
-    read_unlock (&dir->u.dir.lock);
-    devfs_put (dir);
-    return NULL;
-}   /*  End Function _devfs_find_by_dev  */
-
-
 /**
  *	_devfs_find_entry - Find a devfs entry.
  *	@dir: The handle to the parent devfs directory entry. If this is %NULL the
  *		name is relative to the root of the devfs.
  *	@name: The name of the entry. This may be %NULL.
- *	@major: The major number. This is used if lookup by @name fails.
- *	@minor: The minor number. This is used if lookup by @name fails.
- *		NOTE: If @major and @minor are both 0, searching by major and minor
- *		numbers is disabled.
- *	@type: The type of special file to search for. This may be either
- *		%DEVFS_SPECIAL_CHR or %DEVFS_SPECIAL_BLK.
  *	@traverse_symlink: If %TRUE then symbolic links are traversed.
  *
  *	Returns the devfs_entry pointer on success, else %NULL. An implicit
@@ -1359,40 +1273,29 @@
 
 static struct devfs_entry *_devfs_find_entry (devfs_handle_t dir,
 					      const char *name,
-					      unsigned int major,
-					      unsigned int minor,
-					      char type, int traverse_symlink)
+					      int traverse_symlink)
 {
-    struct devfs_entry *entry;
+    unsigned int namelen = strlen (name);
 
-    if (name != NULL)
+    if (name[0] == '/')
     {
-	unsigned int namelen = strlen (name);
-
-	if (name[0] == '/')
+	/*  Skip leading pathname component  */
+	if (namelen < 2)
 	{
-	    /*  Skip leading pathname component  */
-	    if (namelen < 2)
-	    {
-		PRINTK ("(%s): too short\n", name);
-		return NULL;
-	    }
-	    for (++name, --namelen; (*name != '/') && (namelen > 0);
-		 ++name, --namelen);
-	    if (namelen < 2)
-	    {
-		PRINTK ("(%s): too short\n", name);
-		return NULL;
-	    }
-	    ++name;
-	    --namelen;
+	    PRINTK ("(%s): too short\n", name);
+	    return NULL;
 	}
-	entry = _devfs_walk_path (dir, name, namelen, traverse_symlink);
-	if (entry != NULL) return entry;
+	for (++name, --namelen; (*name != '/') && (namelen > 0);
+	     ++name, --namelen);
+	if (namelen < 2)
+	{
+	    PRINTK ("(%s): too short\n", name);
+	    return NULL;
+	}
+	++name;
+	--namelen;
     }
-    /*  Have to search by major and minor: slow  */
-    if ( (major == 0) && (minor == 0) ) return NULL;
-    return _devfs_find_by_dev (root_entry, major, minor, type);
+    return _devfs_walk_path (dir, name, namelen, traverse_symlink);
 }   /*  End Function _devfs_find_entry  */
 
 static struct devfs_entry *get_devfs_entry_from_vfs_inode (struct inode *inode)
@@ -1568,7 +1471,7 @@
 {
     char devtype = S_ISCHR (mode) ? DEVFS_SPECIAL_CHR : DEVFS_SPECIAL_BLK;
     int err;
-    kdev_t devnum = NODEV;
+    dev_t devnum = 0, dev = MKDEV(major, minor);
     struct devfs_entry *de;
 
     if (name == NULL)
@@ -1594,29 +1497,32 @@
     if ( ( S_ISCHR (mode) || S_ISBLK (mode) ) &&
 	 (flags & DEVFS_FL_AUTO_DEVNUM) )
     {
-	if ( kdev_none ( devnum = devfs_alloc_devnum (devtype) ) )
-	{
+	devnum = devfs_alloc_devnum (devtype);
+	if (!devnum) {
 	    PRINTK ("(%s): exhausted %s device numbers\n",
 		    name, S_ISCHR (mode) ? "char" : "block");
 	    return NULL;
 	}
-	major = major (devnum);
-	minor = minor (devnum);
+	dev = devnum;
     }
     if ( ( de = _devfs_prepare_leaf (&dir, name, mode) ) == NULL )
     {
 	PRINTK ("(%s): could not prepare leaf\n", name);
-	if ( !kdev_none (devnum) ) devfs_dealloc_devnum (devtype, devnum);
+	if (devnum) devfs_dealloc_devnum (devtype, devnum);
 	return NULL;
     }
-    if ( S_ISCHR (mode) || S_ISBLK (mode) )
-    {
-	de->u.fcb.u.device.major = major;
-	de->u.fcb.u.device.minor = minor;
-	de->u.fcb.autogen = kdev_none (devnum) ? FALSE : TRUE;
-    }
-    else if ( !S_ISREG (mode) )
-    {
+    if (S_ISCHR (mode)) {
+	de->u.cdev.dev = dev;
+	de->u.cdev.autogen = devnum != 0;
+	de->u.cdev.ops = ops;
+    } else if (S_ISBLK (mode)) {
+	de->u.bdev.dev = dev;
+	de->u.cdev.autogen = devnum != 0;
+	de->u.bdev.ops = ops;
+	if (flags & DEVFS_FL_REMOVABLE) de->u.bdev.removable = TRUE;
+    } else if ( S_ISREG (mode) ) {
+	de->u.file.ops = ops;
+    } else {
 	PRINTK ("(%s): illegal mode: %x\n", name, mode);
 	devfs_put (de);
 	devfs_put (dir);
@@ -1633,16 +1539,12 @@
 	de->inode.uid = 0;
 	de->inode.gid = 0;
     }
-    de->u.fcb.ops = ops;
-    de->u.fcb.aopen_notify = (flags & DEVFS_FL_AOPEN_NOTIFY) ? TRUE : FALSE;
-    de->hide = (flags & DEVFS_FL_HIDE) ? TRUE : FALSE;
-    if (flags & DEVFS_FL_REMOVABLE) de->u.fcb.removable = TRUE;
-    if ( ( err = _devfs_append_entry (dir, de, de->u.fcb.removable, NULL) )
-	 != 0 )
+    err = _devfs_append_entry(dir, de, flags & DEVFS_FL_REMOVABLE, NULL);
+    if (err)
     {
 	PRINTK ("(%s): could not append to parent, err: %d\n", name, err);
 	devfs_put (dir);
-	if ( !kdev_none (devnum) ) devfs_dealloc_devnum (devtype, devnum);
+	if (devnum) devfs_dealloc_devnum (devtype, devnum);
 	return NULL;
     }
     DPRINTK (DEBUG_REGISTER, "(%s): de: %p dir: %p \"%s\"  pp: %p\n",
@@ -1674,8 +1576,7 @@
     else de->next->prev = de->prev;
     de->prev = de;          /*  Indicate we're unhooked                      */
     de->next = NULL;        /*  Force early termination for <devfs_readdir>  */
-    if ( ( S_ISREG (de->mode) || S_ISCHR (de->mode) || S_ISBLK (de->mode) ) &&
-	 de->u.fcb.removable )
+    if (S_ISBLK (de->mode) && de->u.bdev.removable )
 	--parent->u.dir.num_removable;
     return TRUE;
 }   /*  End Function _devfs_unhook  */
@@ -1697,7 +1598,6 @@
     write_unlock (&dir->u.dir.lock);
     if (!unhooked) return;
     devfs_get (dir);
-    devfs_unregister (de->slave);  /*  Let it handle the locking  */
     devfsd_notify (de, DEVFSD_NOTIFY_UNREGISTERED, 0);
     free_dentry (de);
     devfs_put (dir);
@@ -1769,7 +1669,6 @@
 	return -ENOTDIR;
     }
     de->info = info;
-    de->hide = (flags & DEVFS_FL_HIDE) ? TRUE : FALSE;
     de->u.symlink.linkname = newlink;
     de->u.symlink.length = linklength;
     if ( ( err = _devfs_append_entry (dir, de, FALSE, NULL) ) != 0 )
@@ -1870,10 +1769,6 @@
  *	@dir: The handle to the parent devfs directory entry. If this is %NULL the
  *		name is relative to the root of the devfs.
  *	@name: The name of the entry.
- *	@major: The major number. This is used if @name is %NULL.
- *	@minor: The minor number. This is used if @name is %NULL.
- *	@type: The type of special file to search for. This may be either
- *		%DEVFS_SPECIAL_CHR or %DEVFS_SPECIAL_BLK.
  *	@traverse_symlinks: If %TRUE then symlink entries in the devfs namespace are
  *		traversed. Symlinks pointing out of the devfs namespace will cause a
  *		failure. Symlink traversal consumes stack space.
@@ -1885,23 +1780,13 @@
  */
 
 devfs_handle_t devfs_get_handle (devfs_handle_t dir, const char *name,
-				 unsigned int major, unsigned int minor,
-				 char type, int traverse_symlinks)
+				 int traverse_symlinks)
 {
-    if ( (name != NULL) && (name[0] == '\0') ) name = NULL;
-    return _devfs_find_entry (dir, name, major, minor, type,traverse_symlinks);
+    if (!name || !name[0])
+	return NULL;
+    return _devfs_find_entry (dir, name, traverse_symlinks);
 }   /*  End Function devfs_get_handle  */
 
-void devfs_find_and_unregister (devfs_handle_t dir, const char *name,
-				unsigned int major, unsigned int minor,
-				char type, int traverse_symlinks)
-{
-    devfs_handle_t de = devfs_get_handle (dir, name, major, minor,
-					  type, traverse_symlinks);
-    devfs_unregister (de);
-    devfs_put (de);
-}   /*  End Function devfs_find_and_unregister  */
-
 void devfs_remove(const char *fmt, ...)
 {
 	char buf[64];
@@ -1911,84 +1796,13 @@
 	va_start(args, fmt);
 	n = vsnprintf(buf, 64, fmt, args);
 	if (n < 64) {
-		devfs_handle_t de = devfs_get_handle(NULL, buf, 0, 0, 0, 0);
+		devfs_handle_t de = devfs_get_handle(NULL, buf, 0);
 		devfs_unregister(de);
 		devfs_put(de);
 	}
 }
 
 /**
- *	devfs_get_flags - Get the flags for a devfs entry.
- *	@de: The handle to the device entry.
- *	@flags: The flags are written here.
- *
- *	Returns 0 on success, else a negative error code.
- */
-
-int devfs_get_flags (devfs_handle_t de, unsigned int *flags)
-{
-    unsigned int fl = 0;
-
-    if (de == NULL) return -EINVAL;
-    VERIFY_ENTRY (de);
-    if (de->hide) fl |= DEVFS_FL_HIDE;
-    if ( S_ISCHR (de->mode) || S_ISBLK (de->mode) || S_ISREG (de->mode) )
-    {
-	if (de->u.fcb.aopen_notify) fl |= DEVFS_FL_AOPEN_NOTIFY;
-	if (de->u.fcb.removable) fl |= DEVFS_FL_REMOVABLE;
-    }
-    *flags = fl;
-    return 0;
-}   /*  End Function devfs_get_flags  */
-
-
-/*
- *	devfs_set_flags - Set the flags for a devfs entry.
- *	@de: The handle to the device entry.
- *	@flags: The flags to set. Unset flags are cleared.
- *
- *	Returns 0 on success, else a negative error code.
- */
-
-int devfs_set_flags (devfs_handle_t de, unsigned int flags)
-{
-    if (de == NULL) return -EINVAL;
-    VERIFY_ENTRY (de);
-    DPRINTK (DEBUG_SET_FLAGS, "(%s): flags: %x\n", de->name, flags);
-    de->hide = (flags & DEVFS_FL_HIDE) ? TRUE : FALSE;
-    if ( S_ISCHR (de->mode) || S_ISBLK (de->mode) || S_ISREG (de->mode) )
-    {
-	spin_lock (&de->u.fcb.lock);
-	de->u.fcb.aopen_notify = (flags & DEVFS_FL_AOPEN_NOTIFY) ? TRUE:FALSE;
-	spin_unlock (&de->u.fcb.lock);
-    }
-    return 0;
-}   /*  End Function devfs_set_flags  */
-
-
-/**
- *	devfs_get_maj_min - Get the major and minor numbers for a devfs entry.
- *	@de: The handle to the device entry.
- *	@major: The major number is written here. This may be %NULL.
- *	@minor: The minor number is written here. This may be %NULL.
- *
- *	Returns 0 on success, else a negative error code.
- */
-
-int devfs_get_maj_min (devfs_handle_t de, unsigned int *major,
-		       unsigned int *minor)
-{
-    if (de == NULL) return -EINVAL;
-    VERIFY_ENTRY (de);
-    if ( S_ISDIR (de->mode) ) return -EISDIR;
-    if ( !S_ISCHR (de->mode) && !S_ISBLK (de->mode) ) return -EINVAL;
-    if (major != NULL) *major = de->u.fcb.u.device.major;
-    if (minor != NULL) *minor = de->u.fcb.u.device.minor;
-    return 0;
-}   /*  End Function devfs_get_maj_min  */
-
-
-/**
  *	devfs_get_handle_from_inode - Get the devfs handle for a VFS inode.
  *	@inode: The VFS inode.
  *
@@ -2045,53 +1859,30 @@
  *	The use count for the module owning the operations will be incremented.
  */
 
-void *devfs_get_ops (devfs_handle_t de)
+static struct file_operations *devfs_get_ops (devfs_handle_t de)
 {
     struct module *owner;
+    struct file_operations *ops;
 
     if (de == NULL) return NULL;
     VERIFY_ENTRY (de);
-    if ( !S_ISCHR (de->mode) && !S_ISBLK (de->mode) && !S_ISREG (de->mode) )
+    if (S_ISCHR (de->mode))
+	ops = de->u.cdev.ops;
+    else
+	ops = de->u.file.ops;
+    if (!ops)
 	return NULL;
-    if (de->u.fcb.ops == NULL) return NULL;
+    owner = ops->owner;
     read_lock (&de->parent->u.dir.lock);  /*  Prevent module from unloading  */
-    if (de->next == de) owner = NULL;     /*  Ops pointer is already stale   */
-    else if ( S_ISCHR (de->mode) || S_ISREG (de->mode) )
-	owner = ( (struct file_operations *) de->u.fcb.ops )->owner;
-    else owner = ( (struct block_device_operations *) de->u.fcb.ops )->owner;
     if ( (de->next == de) || !try_inc_mod_count (owner) )
     {   /*  Entry is already unhooked or module is unloading  */
 	read_unlock (&de->parent->u.dir.lock);
 	return NULL;
     }
     read_unlock (&de->parent->u.dir.lock);  /*  Module can continue unloading*/
-    return de->u.fcb.ops;
+    return ops;
 }   /*  End Function devfs_get_ops  */
 
-
-/**
- *	devfs_put_ops - Put the device operations for a devfs entry.
- *	@de: The handle to the device entry.
- *
- *	The use count for the module owning the operations will be decremented.
- */
-
-void devfs_put_ops (devfs_handle_t de)
-{
-    struct module *owner;
-
-    if (de == NULL) return;
-    VERIFY_ENTRY (de);
-    if ( !S_ISCHR (de->mode) && !S_ISBLK (de->mode) && !S_ISREG (de->mode) )
-	return;
-    if (de->u.fcb.ops == NULL) return;
-    if ( S_ISCHR (de->mode) || S_ISREG (de->mode) )
-	owner = ( (struct file_operations *) de->u.fcb.ops )->owner;
-    else owner = ( (struct block_device_operations *) de->u.fcb.ops )->owner;
-    if (owner) __MOD_DEC_USE_COUNT (owner);
-}   /*  End Function devfs_put_ops  */
-
-
 /**
  *	devfs_set_file_size - Set the file size for a devfs regular file.
  *	@de: The handle to the device entry.
@@ -2105,8 +1896,8 @@
     if (de == NULL) return -EINVAL;
     VERIFY_ENTRY (de);
     if ( !S_ISREG (de->mode) ) return -EINVAL;
-    if (de->u.fcb.u.file.size == size) return 0;
-    de->u.fcb.u.file.size = size;
+    if (de->u.file.size == size) return 0;
+    de->u.file.size = size;
     if (de->inode.dentry == NULL) return 0;
     if (de->inode.dentry->d_inode == NULL) return 0;
     de->inode.dentry->d_inode->i_size = size;
@@ -2188,47 +1979,6 @@
     return de->next;
 }   /*  End Function devfs_get_next_sibling  */
 
-
-/**
- *	devfs_auto_unregister - Configure a devfs entry to be automatically unregistered.
- *	@master: The master devfs entry. Only one slave may be registered.
- *	@slave: The devfs entry which will be automatically unregistered when the
- *		master entry is unregistered. It is illegal to call devfs_unregister()
- *		on this entry.
- */
-
-void devfs_auto_unregister (devfs_handle_t master, devfs_handle_t slave)
-{
-    if (master == NULL) return;
-    VERIFY_ENTRY (master);
-    VERIFY_ENTRY (slave);
-    if (master->slave != NULL)
-    {
-	/*  Because of the dumbness of the layers above, ignore duplicates  */
-	if (master->slave == slave) return;
-	PRINTK ("(%s): only one slave allowed\n", master->name);
-	OOPS ("():  old slave: \"%s\"  new slave: \"%s\"\n",
-	      master->slave->name, slave->name);
-    }
-    master->slave = slave;
-}   /*  End Function devfs_auto_unregister  */
-
-
-/**
- *	devfs_get_unregister_slave - Get the slave entry which will be automatically unregistered.
- *	@master: The master devfs entry.
- *
- *	Returns the slave which will be unregistered when @master is unregistered.
- */
-
-devfs_handle_t devfs_get_unregister_slave (devfs_handle_t master)
-{
-    if (master == NULL) return NULL;
-    VERIFY_ENTRY (master);
-    return master->slave;
-}   /*  End Function devfs_get_unregister_slave  */
-
-
 /**
  *	devfs_get_name - Get the name for a device entry in its parent directory.
  *	@de: The handle to the device entry.
@@ -2330,22 +2080,15 @@
 EXPORT_SYMBOL(devfs_mk_symlink);
 EXPORT_SYMBOL(devfs_mk_dir);
 EXPORT_SYMBOL(devfs_get_handle);
-EXPORT_SYMBOL(devfs_find_and_unregister);
 EXPORT_SYMBOL(devfs_remove);
-EXPORT_SYMBOL(devfs_get_flags);
-EXPORT_SYMBOL(devfs_set_flags);
-EXPORT_SYMBOL(devfs_get_maj_min);
 EXPORT_SYMBOL(devfs_get_handle_from_inode);
 EXPORT_SYMBOL(devfs_generate_path);
-EXPORT_SYMBOL(devfs_get_ops);
 EXPORT_SYMBOL(devfs_set_file_size);
 EXPORT_SYMBOL(devfs_get_info);
 EXPORT_SYMBOL(devfs_set_info);
 EXPORT_SYMBOL(devfs_get_parent);
 EXPORT_SYMBOL(devfs_get_first_child);
 EXPORT_SYMBOL(devfs_get_next_sibling);
-EXPORT_SYMBOL(devfs_auto_unregister);
-EXPORT_SYMBOL(devfs_get_unregister_slave);
 EXPORT_SYMBOL(devfs_get_name);
 EXPORT_SYMBOL(devfs_only);
 
@@ -2397,7 +2140,7 @@
 {
 	int tmp;
 	int retval = 0;
-	dev_t dev = MKDEV(de->u.fcb.u.device.major, de->u.fcb.u.device.minor);
+	dev_t dev = de->u.bdev.dev;
 	extern int warn_no_part;
 
 	if (!S_ISBLK(de->mode))
@@ -2429,7 +2172,7 @@
     {
 	for (de = dir->u.dir.first; de != NULL; de = de->next)
 	{
-	    if (S_ISBLK (de->mode) && de->u.fcb.removable) break;
+	    if (S_ISBLK (de->mode) && de->u.bdev.removable) break;
 	}
 	devfs_get (de);
     }
@@ -2464,7 +2207,7 @@
     }
     for (de = dir->u.dir.first; de != NULL; de = de->next)
     {
-	if (!S_ISBLK (de->mode) || !de->u.fcb.removable) continue;
+	if (!S_ISBLK (de->mode) || !de->u.bdev.removable) continue;
 	if (strcmp (de->name, "disc") == 0) break;
 	/*  Support for names where the partition is appended to the disc name
 	 */
@@ -2546,7 +2289,6 @@
 					   struct devfs_entry *de,
 					   struct dentry *dentry)
 {
-    int is_fcb = FALSE;
     struct inode *inode;
 
     if (de->prev == de) return NULL;  /*  Quick check to see if unhooked  */
@@ -2578,24 +2320,19 @@
     inode->i_rdev = NODEV;
     if ( S_ISCHR (de->mode) )
     {
-	inode->i_rdev = mk_kdev (de->u.fcb.u.device.major,
-				 de->u.fcb.u.device.minor);
-	inode->i_cdev = cdget ( kdev_t_to_nr (inode->i_rdev) );
-	is_fcb = TRUE;
+	inode->i_rdev = to_kdev_t(de->u.cdev.dev);
+	inode->i_cdev = cdget(de->u.cdev.dev);
     }
     else if ( S_ISBLK (de->mode) )
     {
-	inode->i_rdev = mk_kdev (de->u.fcb.u.device.major,
-				 de->u.fcb.u.device.minor);
+	inode->i_rdev = to_kdev_t(de->u.bdev.dev);
 	if (bd_acquire (inode) != 0)
 		PRINTK ("(%d): no block device from bdget()\n",(int)inode->i_ino);
-	is_fcb = TRUE;
     }
     else if ( S_ISFIFO (de->mode) ) inode->i_fop = &def_fifo_fops;
     else if ( S_ISREG (de->mode) )
     {
-	inode->i_size = de->u.fcb.u.file.size;
-	is_fcb = TRUE;
+	inode->i_size = de->u.file.size;
     }
     else if ( S_ISDIR (de->mode) )
     {
@@ -2657,23 +2394,19 @@
 	count = file->f_pos - 2;
 	read_lock (&parent->u.dir.lock);
 	for (de = parent->u.dir.first; de && (count > 0); de = de->next)
-	    if ( !IS_HIDDEN (de) ) --count;
+	    --count;
 	devfs_get (de);
 	read_unlock (&parent->u.dir.lock);
 	/*  Now add all remaining entries  */
 	while (de)
 	{
-	    if ( IS_HIDDEN (de) ) err = 0;
+	    err = (*filldir) (dirent, de->name, de->namelen,
+				file->f_pos, de->inode.ino, de->mode >> 12);
+	    if (err < 0) devfs_put (de);
 	    else
 	    {
-		err = (*filldir) (dirent, de->name, de->namelen,
-				  file->f_pos, de->inode.ino, de->mode >> 12);
-		if (err < 0) devfs_put (de);
-		else
-		{
-		    file->f_pos++;
-		    ++stored;
-		}
+	        file->f_pos++;
+	        ++stored;
 	    }
 	    if (err == -EINVAL) break;
 	    if (err < 0) return err;
@@ -2690,25 +2423,20 @@
 
 static int devfs_open (struct inode *inode, struct file *file)
 {
-    int err;
-    struct fcb_type *df;
+    int err = -ENODEV;
     struct devfs_entry *de;
-    struct fs_info *fs_info = inode->i_sb->s_fs_info;
-    void *ops;
+    struct file_operations *ops;
 
     de = get_devfs_entry_from_vfs_inode (inode);
     if (de == NULL) return -ENODEV;
     if ( S_ISDIR (de->mode) ) return 0;
-    df = &de->u.fcb;
     file->private_data = de->info;
-    ops = devfs_get_ops (de);  /*  Now have module refcount  */
     if ( S_ISBLK (inode->i_mode) )
     {
 	file->f_op = &def_blk_fops;
 	err = def_blk_fops.open (inode, file); /* Module refcount unchanged */
-    }
-    else
-    {
+    } else if (S_ISCHR(inode->i_mode)) {
+	ops = devfs_get_ops (de);  /*  Now have module refcount  */
 	file->f_op = ops;
 	if (file->f_op)
 	{
@@ -2717,22 +2445,18 @@
 	    unlock_kernel ();
 	}
 	else
-	{   /*  Fallback to legacy scheme (I don't have a module refcount)  */
-	    if ( S_ISCHR (inode->i_mode) ) err = chrdev_open (inode, file);
-	    else err = -ENODEV;
+	    err = chrdev_open (inode, file);
+    } else if (S_ISREG(inode->i_mode)) {
+	ops = devfs_get_ops (de);  /*  Now have module refcount  */
+	file->f_op = ops;
+	if (file->f_op)
+	{
+	    lock_kernel ();
+	    err = file->f_op->open ? (*file->f_op->open) (inode, file) : 0;
+	    unlock_kernel ();
 	}
     }
-    if (err < 0) return err;
-    /*  Open was successful  */
-    spin_lock (&df->lock);
-    err = df->open;
-    if (!err) df->open = TRUE;  /*  Was not already open    */
-    spin_unlock (&df->lock);
-    if (err) return 0;          /*  Was already open        */
-    if ( df->aopen_notify && !is_devfsd_or_child (fs_info) )
-	devfsd_notify_de (de, DEVFSD_NOTIFY_ASYNC_OPEN, inode->i_mode,
-			  current->euid, current->egid, fs_info, 0);
-    return 0;
+    return err;
 }   /*  End Function devfs_open  */
 
 static struct file_operations devfs_fops =
@@ -2808,10 +2532,7 @@
 
 static int devfs_d_delete (struct dentry *dentry)
 {
-    int was_open;
     struct inode *inode = dentry->d_inode;
-    struct devfs_entry *de;
-    struct fs_info *fs_info;
 
     if (dentry->d_op == &devfs_wait_dops) dentry->d_op = &devfs_dops;
     /*  Unhash dentry if negative (has no inode)  */
@@ -2820,21 +2541,6 @@
 	DPRINTK (DEBUG_D_DELETE, "(%p): dropping negative dentry\n", dentry);
 	return 1;
     }
-    fs_info = inode->i_sb->s_fs_info;
-    de = get_devfs_entry_from_vfs_inode (inode);
-    DPRINTK (DEBUG_D_DELETE, "(%p): inode: %p  devfs_entry: %p\n",
-	     dentry, inode, de);
-    if (de == NULL) return 0;
-    if ( !S_ISCHR (de->mode) && !S_ISBLK (de->mode) && !S_ISREG (de->mode) )
-	return 0;
-    spin_lock (&de->u.fcb.lock);
-    was_open = de->u.fcb.open;
-    if (was_open) de->u.fcb.open = FALSE;
-    spin_unlock (&de->u.fcb.lock);
-    if (!was_open) return 0;
-    if (de->u.fcb.aopen_notify)
-	devfsd_notify_de (de, DEVFSD_NOTIFY_CLOSE, inode->i_mode,
-			  current->euid, current->egid, fs_info, 1);
     return 0;
 }   /*  End Function devfs_d_delete  */
 
@@ -3117,11 +2823,10 @@
     de = _devfs_alloc_entry (dentry->d_name.name, dentry->d_name.len, mode);
     if (!de) return -ENOMEM;
     de->vfs_deletable = TRUE;
-    if ( S_ISBLK (mode) || S_ISCHR (mode) )
-    {
-	de->u.fcb.u.device.major = MAJOR (rdev);
-	de->u.fcb.u.device.minor = MINOR (rdev);
-    }
+    if (S_ISCHR (mode))
+	de->u.cdev.dev = rdev;
+    else if (S_ISBLK (mode))
+	de->u.bdev.dev = rdev;
     if ( ( err = _devfs_append_entry (parent, de, FALSE, NULL) ) != 0 )
 	return err;
     de->inode.uid = current->euid;
@@ -3273,10 +2978,12 @@
     info->uid = entry->uid;
     info->gid = entry->gid;
     de = entry->de;
-    if ( S_ISCHR (de->mode) || S_ISBLK (de->mode) )
-    {
-	info->major = de->u.fcb.u.device.major;
-	info->minor = de->u.fcb.u.device.minor;
+    if (S_ISCHR(de->mode)) {
+	info->major = MAJOR(de->u.cdev.dev);
+	info->minor = MINOR(de->u.cdev.dev);
+    } else if (S_ISBLK (de->mode)) {
+	info->major = MAJOR(de->u.bdev.dev);
+	info->minor = MINOR(de->u.bdev.dev);
     }
     pos = devfs_generate_path (de, info->devname, DEVFS_PATHLEN);
     if (pos < 0) return pos;
diff -Nru a/fs/devfs/util.c b/fs/devfs/util.c
--- a/fs/devfs/util.c	Mon Dec  9 18:46:38 2002
+++ b/fs/devfs/util.c	Mon Dec  9 18:46:38 2002
@@ -105,42 +105,6 @@
 
 EXPORT_SYMBOL(devfs_unregister_tape);
 
-/**
- *	devfs_register_series - Register a sequence of device entries.
- *	@dir: The handle to the parent devfs directory entry. If this is %NULL
- *		the new names are relative to the root of the devfs.
- *	@format: The printf-style format string. A single "\%u" is allowed.
- *	@num_entries: The number of entries to register.
- *	@flags: A set of bitwise-ORed flags (DEVFS_FL_*).
- *	@major: The major number. Not needed for regular files.
- *	@minor_start: The starting minor number. Not needed for regular files.
- *	@mode: The default file mode.
- *	@ops: The &file_operations or &block_device_operations structure.
- *		This must not be externally deallocated.
- *	@info: An arbitrary pointer which will be written to the private_data
- *		field of the &file structure passed to the device driver. You
- *		can set this to whatever you like, and change it once the file
- *		is opened (the next file opened will not see this change).
- */
-
-void devfs_register_series (devfs_handle_t dir, const char *format,
-			    unsigned int num_entries, unsigned int flags,
-			    unsigned int major, unsigned int minor_start,
-			    umode_t mode, void *ops, void *info)
-{
-    unsigned int count;
-    char devname[128];
-
-    for (count = 0; count < num_entries; ++count)
-    {
-	sprintf (devname, format, count);
-	devfs_register (dir, devname, flags, major, minor_start + count,
-			mode, ops, info);
-    }
-}   /*  End Function devfs_register_series  */
-EXPORT_SYMBOL(devfs_register_series);
-
-
 struct major_list
 {
     spinlock_t lock;
@@ -253,7 +217,7 @@
  *	This routine is thread safe and may block.
  */
 
-kdev_t devfs_alloc_devnum (char type)
+dev_t devfs_alloc_devnum (char type)
 {
     int minor;
     struct semaphore *semaphore;
@@ -270,12 +234,12 @@
 	semaphore = &block_semaphore;
 	list = &block_list;
     }
-    if (list->none_free) return NODEV;  /*  Fast test  */
+    if (list->none_free) return 0;  /*  Fast test  */
     down (semaphore);
     if (list->none_free)
     {
 	up (semaphore);
-	return NODEV;
+	return 0;
     }
     for (entry = list->first; entry != NULL; entry = entry->next)
     {
@@ -283,14 +247,14 @@
 	if (minor >= 256) continue;
 	__set_bit (minor, entry->bits);
 	up (semaphore);
-	return mk_kdev (entry->major, minor);
+	return MKDEV(entry->major, minor);
     }
     /*  Need to allocate a new major  */
     if ( ( entry = kmalloc (sizeof *entry, GFP_KERNEL) ) == NULL )
     {
 	list->none_free = 1;
 	up (semaphore);
-	return NODEV;
+	return 0;
     }
     memset (entry, 0, sizeof *entry);
     if ( ( entry->major = devfs_alloc_major (type) ) < 0 )
@@ -298,14 +262,14 @@
 	list->none_free = 1;
 	up (semaphore);
 	kfree (entry);
-	return NODEV;
+	return 0;
     }
     __set_bit (0, entry->bits);
     if (list->first == NULL) list->first = entry;
     else list->last->next = entry;
     list->last = entry;
     up (semaphore);
-    return mk_kdev (entry->major, 0);
+    return MKDEV(entry->major, 0);
 }   /*  End Function devfs_alloc_devnum  */
 EXPORT_SYMBOL(devfs_alloc_devnum);
 
@@ -318,14 +282,14 @@
  *	This routine is thread safe and may block.
  */
 
-void devfs_dealloc_devnum (char type, kdev_t devnum)
+void devfs_dealloc_devnum (char type, dev_t devnum)
 {
     int major, minor;
     struct semaphore *semaphore;
     struct device_list *list;
     struct minor_list *entry;
 
-    if ( kdev_none (devnum) ) return;
+    if (!devnum) return;
     if (type == DEVFS_SPECIAL_CHR)
     {
 	semaphore = &char_semaphore;
@@ -336,8 +300,8 @@
 	semaphore = &block_semaphore;
 	list = &block_list;
     }
-    major = major (devnum);
-    minor = minor (devnum);
+    major = MAJOR (devnum);
+    minor = MINOR (devnum);
     down (semaphore);
     for (entry = list->first; entry != NULL; entry = entry->next)
     {
@@ -348,12 +312,12 @@
 	if (was_set) list->none_free = 0;
 	up (semaphore);
 	if (!was_set)
-	    PRINTK ( "(): device %s was already free\n", kdevname (devnum) );
+	    PRINTK ( "(): device %s was already free\n", kdevname (to_kdev_t(devnum)) );
 	return;
     }
     up (semaphore);
     PRINTK ( "(): major for %s not previously allocated\n",
-	     kdevname (devnum) );
+	     kdevname (to_kdev_t(devnum)) );
 }   /*  End Function devfs_dealloc_devnum  */
 EXPORT_SYMBOL(devfs_dealloc_devnum);
 
diff -Nru a/fs/dquot.c b/fs/dquot.c
--- a/fs/dquot.c	Mon Dec  9 18:46:50 2002
+++ b/fs/dquot.c	Mon Dec  9 18:46:50 2002
@@ -1307,7 +1307,8 @@
 	error = -EIO;
 	if (!f->f_op || !f->f_op->read || !f->f_op->write)
 		goto out_f;
-	if ((error = security_quota_on(f)))
+	error = security_quota_on(f);
+	if (error)
 		goto out_f;
 	inode = f->f_dentry->d_inode;
 	error = -EACCES;
diff -Nru a/fs/eventpoll.c b/fs/eventpoll.c
--- a/fs/eventpoll.c	Mon Dec  9 18:46:36 2002
+++ b/fs/eventpoll.c	Mon Dec  9 18:46:36 2002
@@ -52,15 +52,18 @@
 #define DNPRINTK(n, x) (void) 0
 #endif /* #if DEBUG_EPOLL > 0 */
 
-#define DEBUG_DPI 0
+#define DEBUG_EPI 0
 
-#if DEBUG_DPI != 0
-#define DPI_SLAB_DEBUG (SLAB_DEBUG_FREE | SLAB_RED_ZONE /* | SLAB_POISON */)
-#else /* #if DEBUG_DPI != 0 */
-#define DPI_SLAB_DEBUG 0
-#endif /* #if DEBUG_DPI != 0 */
+#if DEBUG_EPI != 0
+#define EPI_SLAB_DEBUG (SLAB_DEBUG_FREE | SLAB_RED_ZONE /* | SLAB_POISON */)
+#else /* #if DEBUG_EPI != 0 */
+#define EPI_SLAB_DEBUG 0
+#endif /* #if DEBUG_EPI != 0 */
 
 
+/* Maximum number of poll wake up nests we are allowing */
+#define EP_MAX_POLLWAKE_NESTS 4
+
 /* Maximum size of the hash in bits ( 2^N ) */
 #define EP_MAX_HASH_BITS 17
 
@@ -78,10 +81,10 @@
 				     ((1 << (hbits)) % EP_HENTRY_X_PAGE ? 1: 0)))
 
 /* Macro to allocate a "struct epitem" from the slab cache */
-#define DPI_MEM_ALLOC()	(struct epitem *) kmem_cache_alloc(dpi_cache, SLAB_KERNEL)
+#define EPI_MEM_ALLOC()	(struct epitem *) kmem_cache_alloc(epi_cache, SLAB_KERNEL)
 
 /* Macro to free a "struct epitem" to the slab cache */
-#define DPI_MEM_FREE(p) kmem_cache_free(dpi_cache, p)
+#define EPI_MEM_FREE(p) kmem_cache_free(epi_cache, p)
 
 /* Macro to allocate a "struct eppoll_entry" from the slab cache */
 #define PWQ_MEM_ALLOC()	(struct eppoll_entry *) kmem_cache_alloc(pwq_cache, SLAB_KERNEL)
@@ -106,7 +109,7 @@
 #define EP_ITEM_FROM_WAIT(p) ((struct epitem *) container_of(p, struct eppoll_entry, wait)->base)
 
 /* Get the "struct epitem" from an epoll queue wrapper */
-#define EP_ITEM_FROM_EPQUEUE(p) (container_of(p, struct ep_pqueue, pt)->dpi)
+#define EP_ITEM_FROM_EPQUEUE(p) (container_of(p, struct ep_pqueue, pt)->epi)
 
 /*
  * This is used to optimize the event transfer to userspace. Since this
@@ -121,6 +124,27 @@
 #define EP_MAX_COLLECT_ITEMS 64
 
 
+/*
+ * Node that is linked into the "wake_task_list" member of the "struct poll_safewake".
+ * It is used to keep track on all tasks that are currently inside the wake_up() code
+ * to 1) short-circuit the one coming from the same task and same wait queue head
+ * ( loop ) 2) allow a maximum number of epoll descriptors inclusion nesting
+ * 3) let go the ones coming from other tasks.
+ */
+struct wake_task_node {
+	struct list_head llink;
+	task_t *task;
+	wait_queue_head_t *wq;
+};
+
+/*
+ * This is used to implement the safe poll wake up avoiding to reenter
+ * the poll callback from inside wake_up().
+ */
+struct poll_safewake {
+	struct list_head wake_task_list;
+	spinlock_t lock;
+};
 
 /*
  * This structure is stored inside the "private_data" member of the file
@@ -189,7 +213,7 @@
 	struct file *file;
 
 	/* The structure that describe the interested events and the source fd */
-	struct pollfd pfd;
+	struct epoll_event event;
 
 	/*
 	 * Used to keep track of the usage count of the structure. This avoids
@@ -204,11 +228,13 @@
 /* Wrapper struct used by poll queueing */
 struct ep_pqueue {
 	poll_table pt;
-	struct epitem *dpi;
+	struct epitem *epi;
 };
 
 
 
+static void ep_poll_safewake_init(struct poll_safewake *psw);
+static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq);
 static unsigned int ep_get_hash_bits(unsigned int hintsize);
 static int ep_getfd(int *efd, struct inode **einode, struct file **efile);
 static int ep_alloc_pages(char **pages, int numpages);
@@ -219,22 +245,22 @@
 static int ep_init(struct eventpoll *ep, unsigned int hashbits);
 static void ep_free(struct eventpoll *ep);
 static struct epitem *ep_find(struct eventpoll *ep, struct file *file);
-static void ep_use_epitem(struct epitem *dpi);
-static void ep_release_epitem(struct epitem *dpi);
+static void ep_use_epitem(struct epitem *epi);
+static void ep_release_epitem(struct epitem *epi);
 static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead, poll_table *pt);
-static int ep_insert(struct eventpoll *ep, struct pollfd *pfd, struct file *tfile);
-static int ep_modify(struct eventpoll *ep, struct epitem *dpi, unsigned int events);
-static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *dpi);
-static int ep_unlink(struct eventpoll *ep, struct epitem *dpi);
-static int ep_remove(struct eventpoll *ep, struct epitem *dpi);
+static int ep_insert(struct eventpoll *ep, struct epoll_event *event, struct file *tfile);
+static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_event *event);
+static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi);
+static int ep_unlink(struct eventpoll *ep, struct epitem *epi);
+static int ep_remove(struct eventpoll *ep, struct epitem *epi);
 static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync);
 static int ep_eventpoll_close(struct inode *inode, struct file *file);
 static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait);
-static int ep_collect_ready_items(struct eventpoll *ep, struct epitem **adpi, int maxdpi);
-static int ep_send_events(struct eventpoll *ep, struct epitem **adpi, int ndpi,
-			  struct pollfd *events);
-static int ep_events_transfer(struct eventpoll *ep, struct pollfd *events, int maxevents);
-static int ep_poll(struct eventpoll *ep, struct pollfd *events, int maxevents,
+static int ep_collect_ready_items(struct eventpoll *ep, struct epitem **aepi, int maxepi);
+static int ep_send_events(struct eventpoll *ep, struct epitem **aepi, int nepi,
+			  struct epoll_event *events);
+static int ep_events_transfer(struct eventpoll *ep, struct epoll_event *events, int maxevents);
+static int ep_poll(struct eventpoll *ep, struct epoll_event *events, int maxevents,
 		   int timeout);
 static int eventpollfs_delete_dentry(struct dentry *dentry);
 static struct inode *ep_eventpoll_inode(void);
@@ -242,6 +268,9 @@
 					      int flags, char *dev_name, void *data);
 
 
+/* Safe wake up implementation */
+static struct poll_safewake psw;
+
 /*
  * This semaphore is used to ensure that files are not removed
  * while epoll is using them. Namely the f_op->poll(), since
@@ -250,10 +279,10 @@
  * and it is write-held during the file cleanup path and the epoll
  * file exit code.
  */
-struct rw_semaphore epsem;
+static struct rw_semaphore epsem;
 
 /* Slab cache used to allocate "struct epitem" */
-static kmem_cache_t *dpi_cache;
+static kmem_cache_t *epi_cache;
 
 /* Slab cache used to allocate "struct eppoll_entry" */
 static kmem_cache_t *pwq_cache;
@@ -284,6 +313,70 @@
 
 
 
+/* Initialize the poll safe wake up structure */
+static void ep_poll_safewake_init(struct poll_safewake *psw)
+{
+
+	INIT_LIST_HEAD(&psw->wake_task_list);
+	spin_lock_init(&psw->lock);
+}
+
+
+/*
+ * Perform a safe wake up of the poll wait list. The problem is that
+ * with the new callback'd wake up system, it is possible that the
+ * poll callback is reentered from inside the call to wake_up() done
+ * on the poll wait queue head. The rule is that we cannot reenter the
+ * wake up code from the same task more than EP_MAX_POLLWAKE_NESTS times,
+ * and we cannot reenter the same wait queue head at all. This will
+ * enable to have a hierarchy of epoll file descriptor of no more than
+ * EP_MAX_POLLWAKE_NESTS deep. We need the irq version of the spin lock
+ * because this one gets called by the poll callback, that in turn is called
+ * from inside a wake_up(), that might be called from irq context.
+ */
+static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq)
+{
+	int wake_nests = 0;
+	unsigned long flags;
+	task_t *this_task = current;
+	struct list_head *lsthead = &psw->wake_task_list, *lnk;
+	struct wake_task_node tnode;
+
+	spin_lock_irqsave(&psw->lock, flags);
+
+	/* Try to see if the current task is already inside this wakeup call */
+	list_for_each(lnk, lsthead) {
+		struct wake_task_node *tncur = list_entry(lnk, struct wake_task_node, llink);
+
+		if (tncur->task == this_task) {
+			if (tncur->wq == wq || ++wake_nests > EP_MAX_POLLWAKE_NESTS) {
+				/*
+				 * Ops ... loop detected or maximum nest level reached.
+				 * We abort this wake by breaking the cycle itself.
+				 */
+				spin_unlock_irqrestore(&psw->lock, flags);
+				return;
+			}
+		}
+	}
+
+	/* Add the current task to the list */
+	tnode.task = this_task;
+	tnode.wq = wq;
+	list_add(&tnode.llink, lsthead);
+
+	spin_unlock_irqrestore(&psw->lock, flags);
+
+	/* Do really wake up now */
+	wake_up(wq);
+
+	/* Remove the current task from the list */
+	spin_lock_irqsave(&psw->lock, flags);
+	list_del(&tnode.llink);
+	spin_unlock_irqrestore(&psw->lock, flags);
+}
+
+
 /*
  * Calculate the size of the hash in bits. The returned size will be
  * bounded between EP_MIN_HASH_BITS and EP_MAX_HASH_BITS.
@@ -315,7 +408,7 @@
 void eventpoll_release(struct file *file)
 {
 	struct list_head *lsthead = &file->f_ep_links;
-	struct epitem *dpi;
+	struct epitem *epi;
 
 	/*
 	 * Fast check to avoid the get/release of the semaphore. Since
@@ -337,10 +430,10 @@
 	 */
 	down_write(&epsem);
 	while (!list_empty(lsthead)) {
-		dpi = list_entry(lsthead->next, struct epitem, fllink);
+		epi = list_entry(lsthead->next, struct epitem, fllink);
 
-		EP_LIST_DEL(&dpi->fllink);
-		ep_remove(dpi->ep, dpi);
+		EP_LIST_DEL(&epi->fllink);
+		ep_remove(epi->ep, epi);
 	}
 	up_write(&epsem);
 }
@@ -399,16 +492,20 @@
  * file that enable the insertion/removal/change of file descriptors inside
  * the interest set. It rapresents the kernel part of the user spcae epoll_ctl(2).
  */
-asmlinkage int sys_epoll_ctl(int epfd, int op, int fd, unsigned int events)
+asmlinkage int sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
 {
 	int error;
 	struct file *file, *tfile;
 	struct eventpoll *ep;
-	struct epitem *dpi;
-	struct pollfd pfd;
+	struct epitem *epi;
+	struct epoll_event epds;
 
 	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %u)\n",
-		     current, epfd, op, fd, events));
+		     current, epfd, op, fd, event->events));
+
+	error = -EFAULT;
+	if (copy_from_user(&epds, event, sizeof(struct epoll_event)))
+		goto eexit_1;
 
 	/* Get the "struct file *" for the eventpoll file */
 	error = -EBADF;
@@ -428,10 +525,11 @@
 
 	/*
 	 * We have to check that the file structure underneath the file descriptor
-	 * the user passed to us _is_ an eventpoll file.
+	 * the user passed to us _is_ an eventpoll file. And also we do not permit
+	 * adding an epoll file descriptor inside itself.
 	 */
 	error = -EINVAL;
-	if (!IS_FILE_EPOLL(file))
+	if (file == tfile || !IS_FILE_EPOLL(file))
 		goto eexit_3;
 
 	/*
@@ -448,30 +546,29 @@
 	 * This does not rapresent a problem though and we don't really want
 	 * to put an extra syncronization object to deal with this harmless condition.
 	 */
-	dpi = ep_find(ep, tfile);
+	epi = ep_find(ep, tfile);
 
 	error = -EINVAL;
 	switch (op) {
-	case EP_CTL_ADD:
-		if (!dpi) {
-			pfd.fd = fd;
-			pfd.events = events | POLLERR | POLLHUP;
-			pfd.revents = 0;
+	case EPOLL_CTL_ADD:
+		if (!epi) {
+			epds.events |= POLLERR | POLLHUP;
 
-			error = ep_insert(ep, &pfd, tfile);
+			error = ep_insert(ep, &epds, tfile);
 		} else
 			error = -EEXIST;
 		break;
-	case EP_CTL_DEL:
-		if (dpi)
-			error = ep_remove(ep, dpi);
+	case EPOLL_CTL_DEL:
+		if (epi)
+			error = ep_remove(ep, epi);
 		else
 			error = -ENOENT;
 		break;
-	case EP_CTL_MOD:
-		if (dpi)
-			error = ep_modify(ep, dpi, events | POLLERR | POLLHUP);
-		else
+	case EPOLL_CTL_MOD:
+		if (epi) {
+			epds.events |= POLLERR | POLLHUP;
+			error = ep_modify(ep, epi, &epds);
+		} else
 			error = -ENOENT;
 		break;
 	}
@@ -480,8 +577,8 @@
 	 * The function ep_find() increments the usage count of the structure
 	 * so, if this is not NULL, we need to release it.
 	 */
-	if (dpi)
-		ep_release_epitem(dpi);
+	if (epi)
+		ep_release_epitem(epi);
 
 eexit_3:
 	fput(tfile);
@@ -489,7 +586,7 @@
 	fput(file);
 eexit_1:
 	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %u) = %d\n",
-		     current, epfd, op, fd, events, error));
+		     current, epfd, op, fd, event->events, error));
 
 	return error;
 }
@@ -499,7 +596,7 @@
  * Implement the event wait interface for the eventpoll file. It is the kernel
  * part of the user space epoll_wait(2).
  */
-asmlinkage int sys_epoll_wait(int epfd, struct pollfd *events, int maxevents,
+asmlinkage int sys_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
 			      int timeout)
 {
 	int error;
@@ -514,7 +611,7 @@
 		return -EINVAL;
 
 	/* Verify that the area passed by the user is writeable */
-	if ((error = verify_area(VERIFY_WRITE, events, maxevents * sizeof(struct pollfd))))
+	if ((error = verify_area(VERIFY_WRITE, events, maxevents * sizeof(struct epoll_event))))
 		goto eexit_1;
 
 	/* Get the "struct file *" for the eventpoll file */
@@ -747,9 +844,9 @@
 		lsthead = ep_hash_entry(ep, i);
 
 		list_for_each(lnk, lsthead) {
-			struct epitem *dpi = list_entry(lnk, struct epitem, llink);
+			struct epitem *epi = list_entry(lnk, struct epitem, llink);
 
-			ep_unregister_pollwait(ep, dpi);
+			ep_unregister_pollwait(ep, epi);
 		}
 	}
 
@@ -763,9 +860,9 @@
 		lsthead = ep_hash_entry(ep, i);
 
 		while (!list_empty(lsthead)) {
-			struct epitem *dpi = list_entry(lsthead->next, struct epitem, llink);
+			struct epitem *epi = list_entry(lsthead->next, struct epitem, llink);
 
-			ep_remove(ep, dpi);
+			ep_remove(ep, epi);
 		}
 	}
 
@@ -785,27 +882,27 @@
 {
 	unsigned long flags;
 	struct list_head *lsthead, *lnk;
-	struct epitem *dpi = NULL;
+	struct epitem *epi = NULL;
 
 	read_lock_irqsave(&ep->lock, flags);
 
 	lsthead = ep_hash_entry(ep, ep_hash_index(ep, file));
 	list_for_each(lnk, lsthead) {
-		dpi = list_entry(lnk, struct epitem, llink);
+		epi = list_entry(lnk, struct epitem, llink);
 
-		if (dpi->file == file) {
-			ep_use_epitem(dpi);
+		if (epi->file == file) {
+			ep_use_epitem(epi);
 			break;
 		}
-		dpi = NULL;
+		epi = NULL;
 	}
 
 	read_unlock_irqrestore(&ep->lock, flags);
 
 	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_find(%p) -> %p\n",
-		     current, file, dpi));
+		     current, file, epi));
 
-	return dpi;
+	return epi;
 }
 
 
@@ -813,10 +910,10 @@
  * Increment the usage count of the "struct epitem" making it sure
  * that the user will have a valid pointer to reference.
  */
-static void ep_use_epitem(struct epitem *dpi)
+static void ep_use_epitem(struct epitem *epi)
 {
 
-	atomic_inc(&dpi->usecnt);
+	atomic_inc(&epi->usecnt);
 }
 
 
@@ -825,11 +922,11 @@
  * has finished using the structure. It might lead to freeing the
  * structure itself if the count goes to zero.
  */
-static void ep_release_epitem(struct epitem *dpi)
+static void ep_release_epitem(struct epitem *epi)
 {
 
-	if (atomic_dec_and_test(&dpi->usecnt))
-		DPI_MEM_FREE(dpi);
+	if (atomic_dec_and_test(&epi->usecnt))
+		EPI_MEM_FREE(epi);
 }
 
 
@@ -839,50 +936,50 @@
  */
 static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead, poll_table *pt)
 {
-	struct epitem *dpi = EP_ITEM_FROM_EPQUEUE(pt);
+	struct epitem *epi = EP_ITEM_FROM_EPQUEUE(pt);
 	struct eppoll_entry *pwq;
 
-	if (dpi->nwait >= 0 && (pwq = PWQ_MEM_ALLOC()))
+	if (epi->nwait >= 0 && (pwq = PWQ_MEM_ALLOC()))
 	{
 		init_waitqueue_func_entry(&pwq->wait, ep_poll_callback);
 		pwq->whead = whead;
-		pwq->base = dpi;
+		pwq->base = epi;
 		add_wait_queue(whead, &pwq->wait);
-		list_add_tail(&pwq->llink, &dpi->pwqlist);
-		dpi->nwait++;
+		list_add_tail(&pwq->llink, &epi->pwqlist);
+		epi->nwait++;
 	}
 	else
 	{
 		/* We have to signal that an error occured */
-		dpi->nwait = -1;
+		epi->nwait = -1;
 	}
 }
 
 
-static int ep_insert(struct eventpoll *ep, struct pollfd *pfd, struct file *tfile)
+static int ep_insert(struct eventpoll *ep, struct epoll_event *event, struct file *tfile)
 {
-	int error, revents;
+	int error, revents, pwake = 0;
 	unsigned long flags;
-	struct epitem *dpi;
+	struct epitem *epi;
 	struct ep_pqueue epq;
 
 	error = -ENOMEM;
-	if (!(dpi = DPI_MEM_ALLOC()))
+	if (!(epi = EPI_MEM_ALLOC()))
 		goto eexit_1;
 
 	/* Item initialization follow here ... */
-	INIT_LIST_HEAD(&dpi->llink);
-	INIT_LIST_HEAD(&dpi->rdllink);
-	INIT_LIST_HEAD(&dpi->fllink);
-	INIT_LIST_HEAD(&dpi->pwqlist);
-	dpi->ep = ep;
-	dpi->file = tfile;
-	dpi->pfd = *pfd;
-	atomic_set(&dpi->usecnt, 1);
-	dpi->nwait = 0;
+	INIT_LIST_HEAD(&epi->llink);
+	INIT_LIST_HEAD(&epi->rdllink);
+	INIT_LIST_HEAD(&epi->fllink);
+	INIT_LIST_HEAD(&epi->pwqlist);
+	epi->ep = ep;
+	epi->file = tfile;
+	epi->event = *event;
+	atomic_set(&epi->usecnt, 1);
+	epi->nwait = 0;
 
 	/* Initialize the poll table using the queue callback */
-	epq.dpi = dpi;
+	epq.epi = epi;
 	init_poll_funcptr(&epq.pt, ep_ptable_queue_proc);
 
 	/*
@@ -897,51 +994,55 @@
 	 * install process. Namely an allocation for a wait queue failed due
 	 * high memory pressure.
 	 */
-	if (dpi->nwait < 0)
+	if (epi->nwait < 0)
 		goto eexit_2;
 
+	/* Add the current item to the list of active epoll hook for this file */
+	spin_lock(&tfile->f_ep_lock);
+	list_add_tail(&epi->fllink, &tfile->f_ep_links);
+	spin_unlock(&tfile->f_ep_lock);
+
 	/* We have to drop the new item inside our item list to keep track of it */
 	write_lock_irqsave(&ep->lock, flags);
 
 	/* Add the current item to the hash table */
-	list_add(&dpi->llink, ep_hash_entry(ep, ep_hash_index(ep, tfile)));
+	list_add(&epi->llink, ep_hash_entry(ep, ep_hash_index(ep, tfile)));
 
 	/* If the file is already "ready" we drop it inside the ready list */
-	if ((revents & pfd->events) && !EP_IS_LINKED(&dpi->rdllink)) {
-		list_add_tail(&dpi->rdllink, &ep->rdllist);
+	if ((revents & event->events) && !EP_IS_LINKED(&epi->rdllink)) {
+		list_add_tail(&epi->rdllink, &ep->rdllist);
 
 		/* Notify waiting tasks that events are available */
 		if (waitqueue_active(&ep->wq))
 			wake_up(&ep->wq);
 		if (waitqueue_active(&ep->poll_wait))
-			wake_up(&ep->poll_wait);
+			pwake++;
 	}
 
 	write_unlock_irqrestore(&ep->lock, flags);
 
-	/* Add the current item to the list of active epoll hook for this file */
-	spin_lock(&tfile->f_ep_lock);
-	list_add_tail(&dpi->fllink, &tfile->f_ep_links);
-	spin_unlock(&tfile->f_ep_lock);
+	/* We have to call this outside the lock */
+	if (pwake)
+		ep_poll_safewake(&psw, &ep->poll_wait);
 
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_insert(%p, %d)\n",
-		     current, ep, pfd->fd));
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_insert(%p, %p)\n",
+		     current, ep, tfile));
 
 	return 0;
 
 eexit_2:
-	ep_unregister_pollwait(ep, dpi);
+	ep_unregister_pollwait(ep, epi);
 
 	/*
 	 * We need to do this because an event could have been arrived on some
 	 * allocated wait queue.
 	 */
 	write_lock_irqsave(&ep->lock, flags);
-	if (EP_IS_LINKED(&dpi->rdllink))
-		EP_LIST_DEL(&dpi->rdllink);
+	if (EP_IS_LINKED(&epi->rdllink))
+		EP_LIST_DEL(&epi->rdllink);
 	write_unlock_irqrestore(&ep->lock, flags);
 
-	DPI_MEM_FREE(dpi);
+	EPI_MEM_FREE(epi);
 eexit_1:
 	return error;
 }
@@ -951,8 +1052,9 @@
  * Modify the interest event mask by dropping an event if the new mask
  * has a match in the current file status.
  */
-static int ep_modify(struct eventpoll *ep, struct epitem *dpi, unsigned int events)
+static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_event *event)
 {
+	int pwake = 0;
 	unsigned int revents;
 	unsigned long flags;
 
@@ -962,30 +1064,37 @@
 	 * the lock, an event might happen between the f_op->poll() call and the
 	 * new event set registering.
 	 */
-	dpi->pfd.events = events;
+	epi->event.events = event->events;
 
 	/*
 	 * Get current event bits. We can safely use the file* here because
 	 * its usage count has been increased by the caller of this function.
 	 */
-	revents = dpi->file->f_op->poll(dpi->file, NULL);
+	revents = epi->file->f_op->poll(epi->file, NULL);
 
 	write_lock_irqsave(&ep->lock, flags);
 
+	/* Copy the data member from inside the lock */
+	epi->event.data = event->data;
+
 	/* If the file is already "ready" we drop it inside the ready list */
-	if ((revents & events) && EP_IS_LINKED(&dpi->llink) &&
-	    !EP_IS_LINKED(&dpi->rdllink)) {
-		list_add_tail(&dpi->rdllink, &ep->rdllist);
+	if ((revents & event->events) && EP_IS_LINKED(&epi->llink) &&
+	    !EP_IS_LINKED(&epi->rdllink)) {
+		list_add_tail(&epi->rdllink, &ep->rdllist);
 
 		/* Notify waiting tasks that events are available */
 		if (waitqueue_active(&ep->wq))
 			wake_up(&ep->wq);
 		if (waitqueue_active(&ep->poll_wait))
-			wake_up(&ep->poll_wait);
+			pwake++;
 	}
 
 	write_unlock_irqrestore(&ep->lock, flags);
 
+	/* We have to call this outside the lock */
+	if (pwake)
+		ep_poll_safewake(&psw, &ep->poll_wait);
+
 	return 0;
 }
 
@@ -995,14 +1104,14 @@
  * Since this must be called without holding "ep->lock" the atomic exchange trick
  * will protect us from multiple unregister.
  */
-static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *dpi)
+static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi)
 {
 	int nwait;
-	struct list_head *lsthead = &dpi->pwqlist;
+	struct list_head *lsthead = &epi->pwqlist;
 	struct eppoll_entry *pwq;
 
 	/* This is called without locks, so we need the atomic exchange */
-	nwait = xchg(&dpi->nwait, 0);
+	nwait = xchg(&epi->nwait, 0);
 
 	if (nwait)
 	{
@@ -1021,7 +1130,7 @@
  * Unlink the "struct epitem" from all places it might have been hooked up.
  * This function must be called with write IRQ lock on "ep->lock".
  */
-static int ep_unlink(struct eventpoll *ep, struct epitem *dpi)
+static int ep_unlink(struct eventpoll *ep, struct epitem *epi)
 {
 	int error;
 
@@ -1030,7 +1139,7 @@
 	 * The check protect us from doing a double unlink ( crash ).
 	 */
 	error = -ENOENT;
-	if (!EP_IS_LINKED(&dpi->llink))
+	if (!EP_IS_LINKED(&epi->llink))
 		goto eexit_1;
 
 	/*
@@ -1038,20 +1147,20 @@
 	 * This operation togheter with the above check closes the door to
 	 * double unlinks.
 	 */
-	EP_LIST_DEL(&dpi->llink);
+	EP_LIST_DEL(&epi->llink);
 
 	/*
 	 * If the item we are going to remove is inside the ready file descriptors
 	 * we want to remove it from this list to avoid stale events.
 	 */
-	if (EP_IS_LINKED(&dpi->rdllink))
-		EP_LIST_DEL(&dpi->rdllink);
+	if (EP_IS_LINKED(&epi->rdllink))
+		EP_LIST_DEL(&epi->rdllink);
 
 	error = 0;
 eexit_1:
 
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_unlink(%p, %d) = %d\n",
-		     current, ep, dpi->pfd.fd, error));
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_unlink(%p, %p) = %d\n",
+		     current, ep, epi->file, error));
 
 	return error;
 }
@@ -1061,7 +1170,7 @@
  * Removes a "struct epitem" from the eventpoll hash and deallocates
  * all the associated resources.
  */
-static int ep_remove(struct eventpoll *ep, struct epitem *dpi)
+static int ep_remove(struct eventpoll *ep, struct epitem *epi)
 {
 	int error;
 	unsigned long flags;
@@ -1074,19 +1183,19 @@
 	 * will run by holding the wait queue head lock and will call our callback
 	 * that will try to get "ep->lock".
 	 */
-	ep_unregister_pollwait(ep, dpi);
+	ep_unregister_pollwait(ep, epi);
 
 	/* Remove the current item from the list of epoll hooks */
-	spin_lock(&dpi->file->f_ep_lock);
-	if (EP_IS_LINKED(&dpi->fllink))
-		EP_LIST_DEL(&dpi->fllink);
-	spin_unlock(&dpi->file->f_ep_lock);
+	spin_lock(&epi->file->f_ep_lock);
+	if (EP_IS_LINKED(&epi->fllink))
+		EP_LIST_DEL(&epi->fllink);
+	spin_unlock(&epi->file->f_ep_lock);
 
 	/* We need to acquire the write IRQ lock before calling ep_unlink() */
 	write_lock_irqsave(&ep->lock, flags);
 
 	/* Really unlink the item from the hash */
-	error = ep_unlink(ep, dpi);
+	error = ep_unlink(ep, epi);
 
 	write_unlock_irqrestore(&ep->lock, flags);
 
@@ -1094,12 +1203,12 @@
 		goto eexit_1;
 
 	/* At this point it is safe to free the eventpoll item */
-	ep_release_epitem(dpi);
+	ep_release_epitem(epi);
 
 	error = 0;
 eexit_1:
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_remove(%p, %d) = %d\n",
-		     current, ep, dpi->pfd.fd, error));
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_remove(%p, %p) = %d\n",
+		     current, ep, epi->file, error));
 
 	return error;
 }
@@ -1112,20 +1221,21 @@
  */
 static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync)
 {
+	int pwake = 0;
 	unsigned long flags;
-	struct epitem *dpi = EP_ITEM_FROM_WAIT(wait);
-	struct eventpoll *ep = dpi->ep;
+	struct epitem *epi = EP_ITEM_FROM_WAIT(wait);
+	struct eventpoll *ep = epi->ep;
 
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: poll_callback(%p) dpi=%p ep=%p\n",
-		     current, dpi->file, dpi, ep));
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: poll_callback(%p) epi=%p ep=%p\n",
+		     current, epi->file, epi, ep));
 
 	write_lock_irqsave(&ep->lock, flags);
 
 	/* If this file is already in the ready list we exit soon */
-	if (EP_IS_LINKED(&dpi->rdllink))
+	if (EP_IS_LINKED(&epi->rdllink))
 		goto is_linked;
 
-	list_add_tail(&dpi->rdllink, &ep->rdllist);
+	list_add_tail(&epi->rdllink, &ep->rdllist);
 
 is_linked:
 	/*
@@ -1135,9 +1245,14 @@
 	if (waitqueue_active(&ep->wq))
 		wake_up(&ep->wq);
 	if (waitqueue_active(&ep->poll_wait))
-		wake_up(&ep->poll_wait);
+		pwake++;
 
 	write_unlock_irqrestore(&ep->lock, flags);
+
+	/* We have to call this outside the lock */
+	if (pwake)
+		ep_poll_safewake(&psw, &ep->poll_wait);
+
 	return 1;
 }
 
@@ -1180,33 +1295,33 @@
  * during the f_op->poll() call, we try to collect the maximum number of items
  * by reducing the irqlock/irqunlock switching rate.
  */
-static int ep_collect_ready_items(struct eventpoll *ep, struct epitem **adpi, int maxdpi)
+static int ep_collect_ready_items(struct eventpoll *ep, struct epitem **aepi, int maxepi)
 {
-	int ndpi;
+	int nepi;
 	unsigned long flags;
 	struct list_head *lsthead = &ep->rdllist;
 
 	write_lock_irqsave(&ep->lock, flags);
 
-	for (ndpi = 0; ndpi < maxdpi && !list_empty(lsthead);) {
-		struct epitem *dpi = list_entry(lsthead->next, struct epitem, rdllink);
+	for (nepi = 0; nepi < maxepi && !list_empty(lsthead);) {
+		struct epitem *epi = list_entry(lsthead->next, struct epitem, rdllink);
 
 		/* Remove the item from the ready list */
-		EP_LIST_DEL(&dpi->rdllink);
+		EP_LIST_DEL(&epi->rdllink);
 
 		/*
 		 * We need to increase the usage count of the "struct epitem" because
-		 * another thread might call EP_CTL_DEL on this target and make the
+		 * another thread might call EPOLL_CTL_DEL on this target and make the
 		 * object to vanish underneath our nose.
 		 */
-		ep_use_epitem(dpi);
+		ep_use_epitem(epi);
 
-		adpi[ndpi++] = dpi;
+		aepi[nepi++] = epi;
 	}
 
 	write_unlock_irqrestore(&ep->lock, flags);
 
-	return ndpi;
+	return nepi;
 }
 
 
@@ -1215,28 +1330,28 @@
  * __copy_to_user() might sleep, and also f_op->poll() might reenable the IRQ
  * because of the way poll() is traditionally implemented in Linux.
  */
-static int ep_send_events(struct eventpoll *ep, struct epitem **adpi, int ndpi,
-			  struct pollfd *events)
+static int ep_send_events(struct eventpoll *ep, struct epitem **aepi, int nepi,
+			  struct epoll_event *events)
 {
 	int i, eventcnt, eventbuf, revents;
-	struct epitem *dpi;
-	struct pollfd pfd[EP_MAX_BUF_EVENTS];
+	struct epitem *epi;
+	struct epoll_event event[EP_MAX_BUF_EVENTS];
 
-	for (i = 0, eventcnt = 0, eventbuf = 0; i < ndpi; i++, adpi++) {
-		dpi = *adpi;
+	for (i = 0, eventcnt = 0, eventbuf = 0; i < nepi; i++, aepi++) {
+		epi = *aepi;
 
 		/* Get the ready file event set */
-		revents = dpi->file->f_op->poll(dpi->file, NULL);
+		revents = epi->file->f_op->poll(epi->file, NULL);
 
-		if (revents & dpi->pfd.events) {
-			pfd[eventbuf] = dpi->pfd;
-			pfd[eventbuf].revents = revents & pfd[eventbuf].events;
+		if (revents & epi->event.events) {
+			event[eventbuf] = epi->event;
+			event[eventbuf].events &= revents;
 			eventbuf++;
 			if (eventbuf == EP_MAX_BUF_EVENTS) {
-				if (__copy_to_user(&events[eventcnt], pfd,
-						   eventbuf * sizeof(struct pollfd))) {
-					for (; i < ndpi; i++, adpi++)
-						ep_release_epitem(*adpi);
+				if (__copy_to_user(&events[eventcnt], event,
+						   eventbuf * sizeof(struct epoll_event))) {
+					for (; i < nepi; i++, aepi++)
+						ep_release_epitem(*aepi);
 					return -EFAULT;
 				}
 				eventcnt += eventbuf;
@@ -1244,12 +1359,12 @@
 			}
 		}
 
-		ep_release_epitem(dpi);
+		ep_release_epitem(epi);
 	}
 
 	if (eventbuf) {
-		if (__copy_to_user(&events[eventcnt], pfd,
-				   eventbuf * sizeof(struct pollfd)))
+		if (__copy_to_user(&events[eventcnt], event,
+				   eventbuf * sizeof(struct epoll_event)))
 			return -EFAULT;
 		eventcnt += eventbuf;
 	}
@@ -1261,10 +1376,10 @@
 /*
  * Perform the transfer of events to user space.
  */
-static int ep_events_transfer(struct eventpoll *ep, struct pollfd *events, int maxevents)
+static int ep_events_transfer(struct eventpoll *ep, struct epoll_event *events, int maxevents)
 {
-	int eventcnt, ndpi, sdpi, maxdpi;
-	struct epitem *adpi[EP_MAX_COLLECT_ITEMS];
+	int eventcnt, nepi, sepi, maxepi;
+	struct epitem *aepi[EP_MAX_COLLECT_ITEMS];
 
 	/*
 	 * We need to lock this because we could be hit by
@@ -1279,22 +1394,22 @@
 
 	for (eventcnt = 0; eventcnt < maxevents;) {
 		/* Maximum items we can extract this time */
-		maxdpi = min(EP_MAX_COLLECT_ITEMS, maxevents - eventcnt);
+		maxepi = min(EP_MAX_COLLECT_ITEMS, maxevents - eventcnt);
 
 		/* Collect/extract ready items */
-		ndpi = ep_collect_ready_items(ep, adpi, maxdpi);
+		nepi = ep_collect_ready_items(ep, aepi, maxepi);
 
-		if (ndpi) {
+		if (nepi) {
 			/* Send events to userspace */
-			sdpi = ep_send_events(ep, adpi, ndpi, &events[eventcnt]);
-			if (sdpi < 0) {
+			sepi = ep_send_events(ep, aepi, nepi, &events[eventcnt]);
+			if (sepi < 0) {
 				up_read(&epsem);
-				return sdpi;
+				return sepi;
 			}
-			eventcnt += sdpi;
+			eventcnt += sepi;
 		}
 
-		if (ndpi < maxdpi)
+		if (nepi < maxepi)
 			break;
 	}
 
@@ -1304,7 +1419,7 @@
 }
 
 
-static int ep_poll(struct eventpoll *ep, struct pollfd *events, int maxevents,
+static int ep_poll(struct eventpoll *ep, struct epoll_event *events, int maxevents,
 		   int timeout)
 {
 	int res, eavail;
@@ -1423,13 +1538,16 @@
 	/* Initialize the semaphore used to syncronize the file cleanup code */
 	init_rwsem(&epsem);
 
+	/* Initialize the structure used to perform safe poll wait head wake ups */
+	ep_poll_safewake_init(&psw);
+
 	/* Allocates slab cache used to allocate "struct epitem" items */
 	error = -ENOMEM;
-	dpi_cache = kmem_cache_create("eventpoll dpi",
+	epi_cache = kmem_cache_create("eventpoll epi",
 				      sizeof(struct epitem),
 				      0,
-				      SLAB_HWCACHE_ALIGN | DPI_SLAB_DEBUG, NULL, NULL);
-	if (!dpi_cache)
+				      SLAB_HWCACHE_ALIGN | EPI_SLAB_DEBUG, NULL, NULL);
+	if (!epi_cache)
 		goto eexit_1;
 
 	/* Allocates slab cache used to allocate "struct eppoll_entry" */
@@ -1437,7 +1555,7 @@
 	pwq_cache = kmem_cache_create("eventpoll pwq",
 				      sizeof(struct eppoll_entry),
 				      0,
-				      DPI_SLAB_DEBUG, NULL, NULL);
+				      EPI_SLAB_DEBUG, NULL, NULL);
 	if (!pwq_cache)
 		goto eexit_2;
 
@@ -1464,7 +1582,7 @@
 eexit_3:
 	kmem_cache_destroy(pwq_cache);
 eexit_2:
-	kmem_cache_destroy(dpi_cache);
+	kmem_cache_destroy(epi_cache);
 eexit_1:
 
 	return error;
@@ -1477,7 +1595,7 @@
 	unregister_filesystem(&eventpoll_fs_type);
 	mntput(eventpoll_mnt);
 	kmem_cache_destroy(pwq_cache);
-	kmem_cache_destroy(dpi_cache);
+	kmem_cache_destroy(epi_cache);
 }
 
 module_init(eventpoll_init);
diff -Nru a/fs/exec.c b/fs/exec.c
--- a/fs/exec.c	Mon Dec  9 18:46:36 2002
+++ b/fs/exec.c	Mon Dec  9 18:46:36 2002
@@ -358,11 +358,11 @@
 		memmove(to, to + offset, PAGE_SIZE - offset);
 		from = kmap(bprm->page[j]);
 		memcpy(to + PAGE_SIZE - offset, from, offset);
-		kunmap(bprm[j - 1]);
+		kunmap(bprm->page[j - 1]);
 		to = from;
 	}
 	memmove(to, to + offset, PAGE_SIZE - offset);
-	kunmap(bprm[j - 1]);
+	kunmap(bprm->page[j - 1]);
 
 	/* Adjust bprm->p to point to the end of the strings. */
 	bprm->p = PAGE_SIZE * i - offset;
@@ -841,7 +841,8 @@
 	}
 
 	/* fill in binprm security blob */
-	if ((retval = security_bprm_set(bprm)))
+	retval = security_bprm_set(bprm);
+	if (retval)
 		return retval;
 
 	memset(bprm->buf,0,BINPRM_BUF_SIZE);
@@ -958,7 +959,8 @@
 	    }
 	}
 #endif
-	if ((retval = security_bprm_check(bprm)))
+	retval = security_bprm_check(bprm);
+	if (retval)
 		return retval;
 
 	/* kernel module loader fixup */
@@ -1054,7 +1056,8 @@
 	if ((retval = bprm.envc) < 0)
 		goto out_mm;
 
-	if ((retval = security_bprm_alloc(&bprm)))
+	retval = security_bprm_alloc(&bprm);
+	if (retval)
 		goto out;
 
 	retval = prepare_binprm(&bprm);
@@ -1235,49 +1238,58 @@
 {
 	struct task_struct *g, *p;
 
-	/* give other threads a chance to run: */
-	yield();
-
 	read_lock(&tasklist_lock);
 	do_each_thread(g,p)
-		if (mm == p->mm && !p->core_waiter)
+		if (mm == p->mm && p != current) {
 			force_sig_specific(SIGKILL, p);
+			mm->core_waiters++;
+		}
 	while_each_thread(g,p);
+
 	read_unlock(&tasklist_lock);
 }
 
 static void coredump_wait(struct mm_struct *mm)
 {
-	DECLARE_WAITQUEUE(wait, current);
+	DECLARE_COMPLETION(startup_done);
+
+	mm->core_waiters++; /* let other threads block */
+	mm->core_startup_done = &startup_done;
+
+	/* give other threads a chance to run: */
+	yield();
 
-	atomic_inc(&mm->core_waiters);
-	add_wait_queue(&mm->core_wait, &wait);
 	zap_threads(mm);
-	current->state = TASK_UNINTERRUPTIBLE;
-	if (atomic_read(&mm->core_waiters) != atomic_read(&mm->mm_users))
-		schedule();
-	else
-		current->state = TASK_RUNNING;
+	if (--mm->core_waiters) {
+		up_write(&mm->mmap_sem);
+		wait_for_completion(&startup_done);
+	} else
+		up_write(&mm->mmap_sem);
+	BUG_ON(mm->core_waiters);
 }
 
 int do_coredump(long signr, struct pt_regs * regs)
 {
-	struct linux_binfmt * binfmt;
 	char corename[CORENAME_MAX_SIZE + 1];
-	struct file * file;
+	struct mm_struct *mm = current->mm;
+	struct linux_binfmt * binfmt;
 	struct inode * inode;
+	struct file * file;
 	int retval = 0;
 
 	lock_kernel();
 	binfmt = current->binfmt;
 	if (!binfmt || !binfmt->core_dump)
 		goto fail;
-	if (!current->mm->dumpable)
+	down_write(&mm->mmap_sem);
+	if (!mm->dumpable) {
+		up_write(&mm->mmap_sem);
 		goto fail;
-	current->mm->dumpable = 0;
-	if (down_trylock(&current->mm->core_sem))
-		BUG();
-	coredump_wait(current->mm);
+	}
+	mm->dumpable = 0;
+	init_completion(&mm->core_done);
+	coredump_wait(mm);
+
 	if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
 		goto fail_unlock;
 
@@ -1305,7 +1317,7 @@
 close_fail:
 	filp_close(file, NULL);
 fail_unlock:
-	up(&current->mm->core_sem);
+	complete_all(&mm->core_done);
 fail:
 	unlock_kernel();
 	return retval;
diff -Nru a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c
--- a/fs/ext2/ioctl.c	Mon Dec  9 18:46:52 2002
+++ b/fs/ext2/ioctl.c	Mon Dec  9 18:46:52 2002
@@ -9,6 +9,8 @@
 
 #include "ext2.h"
 #include <linux/time.h>
+#include <linux/sched.h>
+#include <asm/current.h>
 #include <asm/uaccess.h>
 
 
diff -Nru a/fs/ext3/inode.c b/fs/ext3/inode.c
--- a/fs/ext3/inode.c	Mon Dec  9 18:46:50 2002
+++ b/fs/ext3/inode.c	Mon Dec  9 18:46:50 2002
@@ -2413,7 +2413,7 @@
 			}
 		}
 	}
-	raw_inode->i_generation = le32_to_cpu(inode->i_generation);
+	raw_inode->i_generation = cpu_to_le32(inode->i_generation);
 	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
 		raw_inode->i_block[0] =
 			cpu_to_le32(kdev_t_to_nr(inode->i_rdev));
diff -Nru a/fs/ext3/namei.c b/fs/ext3/namei.c
--- a/fs/ext3/namei.c	Mon Dec  9 18:46:38 2002
+++ b/fs/ext3/namei.c	Mon Dec  9 18:46:38 2002
@@ -992,13 +992,13 @@
 
 #define S_SHIFT 12
 static unsigned char ext3_type_by_mode[S_IFMT >> S_SHIFT] = {
-	[S_IFREG >> S_SHIFT]	EXT3_FT_REG_FILE,
-	[S_IFDIR >> S_SHIFT]	EXT3_FT_DIR,
-	[S_IFCHR >> S_SHIFT]	EXT3_FT_CHRDEV,
-	[S_IFBLK >> S_SHIFT]	EXT3_FT_BLKDEV,
-	[S_IFIFO >> S_SHIFT]	EXT3_FT_FIFO,
-	[S_IFSOCK >> S_SHIFT]	EXT3_FT_SOCK,
-	[S_IFLNK >> S_SHIFT]	EXT3_FT_SYMLINK,
+	[S_IFREG >> S_SHIFT]	= EXT3_FT_REG_FILE,
+	[S_IFDIR >> S_SHIFT]	= EXT3_FT_DIR,
+	[S_IFCHR >> S_SHIFT]	= EXT3_FT_CHRDEV,
+	[S_IFBLK >> S_SHIFT]	= EXT3_FT_BLKDEV,
+	[S_IFIFO >> S_SHIFT]	= EXT3_FT_FIFO,
+	[S_IFSOCK >> S_SHIFT]	= EXT3_FT_SOCK,
+	[S_IFLNK >> S_SHIFT]	= EXT3_FT_SYMLINK,
 };
 
 static inline void ext3_set_de_type(struct super_block *sb,
diff -Nru a/fs/ext3/super.c b/fs/ext3/super.c
--- a/fs/ext3/super.c	Mon Dec  9 18:46:51 2002
+++ b/fs/ext3/super.c	Mon Dec  9 18:46:51 2002
@@ -662,6 +662,10 @@
 				return 0;
 			sbi->s_resuid = v;
 		}
+		else if (!strcmp (this_char, "oldalloc"))
+			set_opt (sbi->s_mount_opt, OLDALLOC);
+		else if (!strcmp (this_char, "orlov"))
+			clear_opt (sbi->s_mount_opt, OLDALLOC);
 #ifdef CONFIG_JBD_DEBUG
 		else if (!strcmp (this_char, "ro-after")) {
 			unsigned long v;
diff -Nru a/fs/fat/inode.c b/fs/fat/inode.c
--- a/fs/fat/inode.c	Mon Dec  9 18:46:36 2002
+++ b/fs/fat/inode.c	Mon Dec  9 18:46:36 2002
@@ -205,7 +205,7 @@
 		seq_printf(m, ",uid=%d", opts->fs_uid);
 	if (opts->fs_gid != 0)
 		seq_printf(m, ",gid=%d", opts->fs_gid);
-	seq_printf(m, ",umask=%04o", opts->fs_umask);
+	seq_printf(m, ",fmask=%04o", opts->fs_fmask);
 	seq_printf(m, ",dmask=%04o", opts->fs_dmask);
 	if (sbi->nls_disk)
 		seq_printf(m, ",codepage=%s", sbi->nls_disk->charset);
@@ -267,7 +267,7 @@
 
 	opts->fs_uid = current->uid;
 	opts->fs_gid = current->gid;
-	opts->fs_umask = opts->fs_dmask = current->fs->umask;
+	opts->fs_fmask = opts->fs_dmask = current->fs->umask;
 	opts->codepage = 0;
 	opts->iocharset = NULL;
 	if (is_vfat)
@@ -333,7 +333,15 @@
 		else if (!strcmp(this_char,"umask")) {
 			if (!value || !*value) ret = 0;
 			else {
-				opts->fs_umask = simple_strtoul(value,&value,8);
+				opts->fs_fmask = opts->fs_dmask =
+					simple_strtoul(value,&value,8);
+				if (*value) ret = 0;
+			}
+		}
+		else if (!strcmp(this_char,"fmask")) {
+			if (!value || !*value) ret = 0;
+			else {
+				opts->fs_fmask = simple_strtoul(value,&value,8);
 				if (*value) ret = 0;
 			}
 		}
@@ -1119,7 +1127,7 @@
 		    ((sbi->options.showexec &&
 		       !is_exec(de->ext))
 		    	? S_IRUGO|S_IWUGO : S_IRWXUGO)
-		    & ~sbi->options.fs_umask) | S_IFREG;
+		    & ~sbi->options.fs_fmask) | S_IFREG;
 		MSDOS_I(inode)->i_start = CF_LE_W(de->start);
 		if (sbi->fat_bits == 32) {
 			MSDOS_I(inode)->i_start |=
@@ -1253,7 +1261,7 @@
 	if (S_ISDIR(inode->i_mode))
 		mask = sbi->options.fs_dmask;
 	else
-		mask = sbi->options.fs_umask;
+		mask = sbi->options.fs_fmask;
 	inode->i_mode &= S_IFMT | (S_IRWXUGO & ~mask);
 out:
 	unlock_kernel();
diff -Nru a/fs/fcntl.c b/fs/fcntl.c
--- a/fs/fcntl.c	Mon Dec  9 18:46:34 2002
+++ b/fs/fcntl.c	Mon Dec  9 18:46:34 2002
@@ -75,8 +75,8 @@
 
 /*
  * locate_fd finds a free file descriptor in the open_fds fdset,
- * expanding the fd arrays if necessary.  The files write lock will be
- * held on exit to ensure that the fd can be entered atomically.
+ * expanding the fd arrays if necessary.  Must be called with the
+ * file_lock held for write.
  */
 
 static int locate_fd(struct files_struct *files, 
@@ -86,8 +86,6 @@
 	int error;
 	int start;
 
-	write_lock(&files->file_lock);
-	
 	error = -EINVAL;
 	if (orig_start >= current->rlim[RLIMIT_NOFILE].rlim_cur)
 		goto out;
@@ -131,30 +129,24 @@
 	return error;
 }
 
-static inline void allocate_fd(struct files_struct *files, 
-					struct file *file, int fd)
-{
-	FD_SET(fd, files->open_fds);
-	FD_CLR(fd, files->close_on_exec);
-	write_unlock(&files->file_lock);
-	fd_install(fd, file);
-}
-
 static int dupfd(struct file *file, int start)
 {
 	struct files_struct * files = current->files;
-	int ret;
+	int fd;
 
-	ret = locate_fd(files, file, start);
-	if (ret < 0) 
-		goto out_putf;
-	allocate_fd(files, file, ret);
-	return ret;
+	write_lock(&files->file_lock);
+	fd = locate_fd(files, file, start);
+	if (fd >= 0) {
+		FD_SET(fd, files->open_fds);
+		FD_CLR(fd, files->close_on_exec);
+		write_unlock(&files->file_lock);
+		fd_install(fd, file);
+	} else {
+		write_unlock(&files->file_lock);
+		fput(file);
+	}
 
-out_putf:
-	write_unlock(&files->file_lock);
-	fput(file);
-	return ret;
+	return fd;
 }
 
 asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
@@ -274,7 +266,8 @@
 {
 	int err;
 	
-	if ((err = security_file_set_fowner(filp)))
+	err = security_file_set_fowner(filp);
+	if (err)
 		return err;
 
 	f_modown(filp, arg, current->uid, current->euid, force);
@@ -367,7 +360,8 @@
 	if (!filp)
 		goto out;
 
-	if ((err = security_file_fcntl(filp, cmd, arg))) {
+	err = security_file_fcntl(filp, cmd, arg);
+	if (err) {
 		fput(filp);
 		return err;
 	}
@@ -390,7 +384,8 @@
 	if (!filp)
 		goto out;
 
-	if ((err = security_file_fcntl(filp, cmd, arg))) {
+	err = security_file_fcntl(filp, cmd, arg);
+	if (err) {
 		fput(filp);
 		return err;
 	}
diff -Nru a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
--- a/fs/hugetlbfs/inode.c	Mon Dec  9 18:46:51 2002
+++ b/fs/hugetlbfs/inode.c	Mon Dec  9 18:46:51 2002
@@ -23,6 +23,7 @@
 #include <linux/pagevec.h>
 #include <linux/quotaops.h>
 #include <linux/dnotify.h>
+#include <linux/security.h>
 
 #include <asm/uaccess.h>
 
@@ -209,7 +210,7 @@
 	if (inode->i_data.nrpages)
 		truncate_hugepages(&inode->i_data, 0);
 
-	security_ops->inode_delete(inode);
+	security_inode_delete(inode);
 
 	clear_inode(inode);
 	destroy_inode(inode);
@@ -333,7 +334,7 @@
 	if (error)
 		goto out;
 
-	error = security_ops->inode_setattr(dentry, attr);
+	error = security_inode_setattr(dentry, attr);
 	if (error)
 		goto out;
 
diff -Nru a/fs/ioctl.c b/fs/ioctl.c
--- a/fs/ioctl.c	Mon Dec  9 18:46:35 2002
+++ b/fs/ioctl.c	Mon Dec  9 18:46:35 2002
@@ -59,7 +59,8 @@
 		goto out;
 	error = 0;
 
-	if ((error = security_file_ioctl(filp, cmd, arg))) {
+	error = security_file_ioctl(filp, cmd, arg);
+	if (error) {
                 fput(filp);
                 goto out;
         }
diff -Nru a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
--- a/fs/jffs/inode-v23.c	Mon Dec  9 18:46:38 2002
+++ b/fs/jffs/inode-v23.c	Mon Dec  9 18:46:38 2002
@@ -48,7 +48,6 @@
 #include <linux/blkdev.h>
 #include <linux/quotaops.h>
 #include <linux/highmem.h>
-#include <linux/smp_lock.h>
 #include <asm/semaphore.h>
 #include <asm/byteorder.h>
 #include <asm/uaccess.h>
diff -Nru a/fs/locks.c b/fs/locks.c
--- a/fs/locks.c	Mon Dec  9 18:46:51 2002
+++ b/fs/locks.c	Mon Dec  9 18:46:51 2002
@@ -1185,7 +1185,8 @@
 		return -EACCES;
 	if (!S_ISREG(inode->i_mode))
 		return -EINVAL;
-	if ((error = security_file_lock(filp, arg)))
+	error = security_file_lock(filp, arg);
+	if (error)
 		return error;
 
 	lock_kernel();
@@ -1298,7 +1299,8 @@
 	if (error)
 		goto out_putf;
 
-	if ((error = security_file_lock(filp, cmd)))
+	error = security_file_lock(filp, cmd);
+	if (error)
 		goto out_free;
 
 	for (;;) {
@@ -1410,7 +1412,6 @@
 
 	inode = filp->f_dentry->d_inode;
 
-#ifdef CONFIG_MMU
 	/* Don't allow mandatory locks on files that may be memory mapped
 	 * and shared.
 	 */
@@ -1423,7 +1424,6 @@
 			goto out;
 		}
 	}
-#endif
 
 	error = flock_to_posix_lock(filp, file_lock, &flock);
 	if (error)
@@ -1449,7 +1449,8 @@
 		goto out;
 	}
 
-	if ((error = security_file_lock(filp, file_lock->fl_type)))
+	error = security_file_lock(filp, file_lock->fl_type);
+	if (error)
 		goto out;
 
 	if (filp->f_op && filp->f_op->lock != NULL) {
@@ -1588,7 +1589,8 @@
 		goto out;
 	}
 
-	if ((error = security_file_lock(filp, file_lock->fl_type)))
+	error = security_file_lock(filp, file_lock->fl_type);
+	if (error)
 		goto out;
 
 	if (filp->f_op && filp->f_op->lock != NULL) {
diff -Nru a/fs/namei.c b/fs/namei.c
--- a/fs/namei.c	Mon Dec  9 18:46:35 2002
+++ b/fs/namei.c	Mon Dec  9 18:46:36 2002
@@ -413,7 +413,8 @@
 		current->state = TASK_RUNNING;
 		schedule();
 	}
-	if ((err = security_inode_follow_link(dentry, nd)))
+	err = security_inode_follow_link(dentry, nd);
+	if (err)
 		goto loop;
 	current->link_count++;
 	current->total_link_count++;
@@ -862,9 +863,9 @@
 			read_unlock(&current->fs->lock);
 			if (__emul_lookup_dentry(name,nd))
 				return 0;
-			read_lock(&current->fs->lock);
+		} else {
+			read_unlock(&current->fs->lock);
 		}
-		read_unlock(&current->fs->lock);
 		spin_lock(&dcache_lock);
 		nd->mnt = current->fs->rootmnt;
 		nd->dentry = current->fs->root;
@@ -1124,7 +1125,8 @@
 		return -EACCES;	/* shouldn't it be ENOSYS? */
 	mode &= S_IALLUGO;
 	mode |= S_IFREG;
-	if ((error = security_inode_create(dir, dentry, mode)))
+	error = security_inode_create(dir, dentry, mode);
+	if (error)
 		return error;
 	DQUOT_INIT(dir);
 	error = dir->i_op->create(dir, dentry, mode);
@@ -1343,7 +1345,8 @@
 	 * stored in nd->last.name and we will have to putname() it when we
 	 * are done. Procfs-like symlinks just set LAST_BIND.
 	 */
-	if ((error = security_inode_follow_link(dentry, nd)))
+	error = security_inode_follow_link(dentry, nd);
+	if (error)
 		goto exit_dput;
 	UPDATE_ATIME(dentry->d_inode);
 	error = dentry->d_inode->i_op->follow_link(dentry, nd);
@@ -1408,7 +1411,8 @@
 	if (!dir->i_op || !dir->i_op->mknod)
 		return -EPERM;
 
-	if ((error = security_inode_mknod(dir, dentry, mode, dev)))
+	error = security_inode_mknod(dir, dentry, mode, dev);
+	if (error)
 		return error;
 
 	DQUOT_INIT(dir);
@@ -1476,7 +1480,8 @@
 		return -EPERM;
 
 	mode &= (S_IRWXUGO|S_ISVTX);
-	if ((error = security_inode_mkdir(dir, dentry, mode)))
+	error = security_inode_mkdir(dir, dentry, mode);
+	if (error)
 		return error;
 
 	DQUOT_INIT(dir);
@@ -1568,7 +1573,8 @@
 	if (d_mountpoint(dentry))
 		error = -EBUSY;
 	else {
-		if (!(error = security_inode_rmdir(dir, dentry))) {
+		error = security_inode_rmdir(dir, dentry);
+		if (!error) {
 			error = dir->i_op->rmdir(dir, dentry);
 			if (!error)
 				dentry->d_inode->i_flags |= S_DEAD;
@@ -1641,7 +1647,8 @@
 	if (d_mountpoint(dentry))
 		error = -EBUSY;
 	else {
-		if (!(error = security_inode_unlink(dir, dentry)))
+		error = security_inode_unlink(dir, dentry);
+		if (!error)
 			error = dir->i_op->unlink(dir, dentry);
 	}
 	up(&dentry->d_inode->i_sem);
@@ -1704,7 +1711,8 @@
 	if (!dir->i_op || !dir->i_op->symlink)
 		return -EPERM;
 
-	if ((error = security_inode_symlink(dir, dentry, oldname)))
+	error = security_inode_symlink(dir, dentry, oldname);
+	if (error)
 		return error;
 
 	DQUOT_INIT(dir);
@@ -1774,7 +1782,8 @@
 	if (S_ISDIR(old_dentry->d_inode->i_mode))
 		return -EPERM;
 
-	if ((error = security_inode_link(old_dentry, dir, new_dentry)))
+	error = security_inode_link(old_dentry, dir, new_dentry);
+	if (error)
 		return error;
 
 	down(&old_dentry->d_inode->i_sem);
@@ -1882,7 +1891,8 @@
 			return error;
 	}
 
-	if ((error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry)))
+	error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry);
+	if (error)
 		return error;
 
 	target = new_dentry->d_inode;
@@ -1916,7 +1926,8 @@
 	struct inode *target;
 	int error;
 
-	if ((error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry)))
+	error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry);
+	if (error)
 		return error;
 
 	dget(new_dentry);
diff -Nru a/fs/namespace.c b/fs/namespace.c
--- a/fs/namespace.c	Mon Dec  9 18:46:50 2002
+++ b/fs/namespace.c	Mon Dec  9 18:46:50 2002
@@ -289,7 +289,8 @@
 	struct super_block * sb = mnt->mnt_sb;
 	int retval = 0;
 
-	if ((retval = security_sb_umount(mnt, flags)))
+	retval = security_sb_umount(mnt, flags);
+	if (retval)
 		return retval;
 
 	/*
@@ -470,7 +471,8 @@
 	if (IS_DEADDIR(nd->dentry->d_inode))
 		goto out_unlock;
 
-	if ((err = security_sb_check_sb(mnt, nd)))
+	err = security_sb_check_sb(mnt, nd);
+	if (err)
 		goto out_unlock;
 
 	spin_lock(&dcache_lock);
@@ -740,7 +742,8 @@
 	if (retval)
 		return retval;
 
-	if ((retval = security_sb_mount(dev_name, &nd, type_page, flags, data_page)))
+	retval = security_sb_mount(dev_name, &nd, type_page, flags, data_page);
+	if (retval)
 		goto dput_out;
 
 	if (flags & MS_REMOUNT)
@@ -985,7 +988,8 @@
 	if (error)
 		goto out1;
 
-	if ((error = security_sb_pivotroot(&old_nd, &new_nd))) {
+	error = security_sb_pivotroot(&old_nd, &new_nd);
+	if (error) {
 		path_release(&old_nd);
 		goto out1;
 	}
diff -Nru a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c
--- a/fs/nfsd/nfscache.c	Mon Dec  9 18:46:52 2002
+++ b/fs/nfsd/nfscache.c	Mon Dec  9 18:46:52 2002
@@ -363,7 +363,7 @@
 	struct iovec	*vec = &rqstp->rq_res.head[0];
 
 	if (vec->iov_len + data->iov_len > PAGE_SIZE) {
-		printk(KERN_WARNING "nfsd: cached reply too large (%d).\n",
+		printk(KERN_WARNING "nfsd: cached reply too large (%Zd).\n",
 				data->iov_len);
 		return 0;
 	}
diff -Nru a/fs/open.c b/fs/open.c
--- a/fs/open.c	Mon Dec  9 18:46:34 2002
+++ b/fs/open.c	Mon Dec  9 18:46:34 2002
@@ -31,7 +31,8 @@
 		retval = -ENOSYS;
 		if (sb->s_op && sb->s_op->statfs) {
 			memset(buf, 0, sizeof(struct statfs));
-			if ((retval = security_sb_statfs(sb)))
+			retval = security_sb_statfs(sb);
+			if (retval)
 				return retval;
 			retval = sb->s_op->statfs(sb, buf);
 		}
@@ -279,7 +280,7 @@
  * must be owner or have write permission.
  * Else, update from *times, must be owner or super user.
  */
-asmlinkage long sys_utimes(char * filename, struct timeval * utimes)
+long do_utimes(char * filename, struct timeval * times)
 {
 	int error;
 	struct nameidata nd;
@@ -298,11 +299,7 @@
 
 	/* Don't worry, the checks are done in inode_change_ok() */
 	newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
-	if (utimes) {
-		struct timeval times[2];
-		error = -EFAULT;
-		if (copy_from_user(&times, utimes, sizeof(times)))
-			goto dput_and_out;
+	if (times) {
 		newattrs.ia_atime.tv_sec = times[0].tv_sec;
 		newattrs.ia_atime.tv_nsec = times[0].tv_usec * 1000;
 		newattrs.ia_mtime.tv_sec = times[1].tv_sec;
@@ -321,6 +318,16 @@
 out:
 	return error;
 }
+
+asmlinkage long sys_utimes(char * filename, struct timeval * utimes)
+{
+	struct timeval times[2];
+
+	if (utimes && copy_from_user(&times, utimes, sizeof(times)))
+		return -EFAULT;
+	return do_utimes(filename, utimes ? times : NULL);
+}
+
 
 /*
  * access() needs to use the real uid/gid, not the effective uid/gid.
diff -Nru a/fs/partitions/check.c b/fs/partitions/check.c
--- a/fs/partitions/check.c	Mon Dec  9 18:46:51 2002
+++ b/fs/partitions/check.c	Mon Dec  9 18:46:51 2002
@@ -315,8 +315,8 @@
 			      char *page, size_t count, loff_t off)
 {
 	return off ? 0 : sprintf(page, "%8u %8llu %8u %8llu\n",
-				p->reads, (u64)p->read_sectors,
-				p->writes, (u64)p->write_sectors);
+				p->reads, (unsigned long long)p->read_sectors,
+				p->writes, (unsigned long long)p->write_sectors);
 }
 static struct part_attribute part_attr_dev = {
 	.attr = {.name = "dev", .mode = S_IRUGO },
@@ -377,7 +377,6 @@
 	p->start_sect = start;
 	p->nr_sects = len;
 	devfs_register_partition(disk, part);
-	kobject_init(&p->kobj);
 	snprintf(p->kobj.name,KOBJ_NAME_LEN,"%s%d",disk->kobj.name,part);
 	p->kobj.parent = &disk->kobj;
 	p->kobj.subsys = &part_subsys;
@@ -406,7 +405,7 @@
 	s = strchr(disk->kobj.name, '/');
 	if (s)
 		*s = '!';
-	kobject_register(&disk->kobj);
+	kobject_add(&disk->kobj);
 	disk_sysfs_symlinks(disk);
 
 	if (disk->flags & GENHD_FL_CD)
@@ -529,8 +528,7 @@
 		sysfs_remove_link(&disk->driverfs_dev->kobj, "block");
 		put_device(disk->driverfs_dev);
 	}
-	kobject_get(&disk->kobj);	/* kobject model is fucked in head */
-	kobject_unregister(&disk->kobj);
+	kobject_del(&disk->kobj);
 }
 
 struct dev_name {
diff -Nru a/fs/proc/generic.c b/fs/proc/generic.c
--- a/fs/proc/generic.c	Mon Dec  9 18:46:52 2002
+++ b/fs/proc/generic.c	Mon Dec  9 18:46:52 2002
@@ -488,7 +488,11 @@
 		ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL);
 		if (ent->data) {
 			strcpy((char*)ent->data,dest);
-			proc_register(parent, ent);
+			if (proc_register(parent, ent) < 0) {
+				kfree(ent->data);
+				kfree(ent);
+				ent = NULL;
+			}
 		} else {
 			kfree(ent);
 			ent = NULL;
@@ -505,7 +509,10 @@
 	ent = proc_create(&parent,name,mode,1);
 	if (ent) {
 		ent->rdev = rdev;
-		proc_register(parent, ent);
+		if (proc_register(parent, ent) < 0) {
+			kfree(ent);
+			ent = NULL;
+		}
 	}
 	return ent;
 }
@@ -520,7 +527,10 @@
 		ent->proc_fops = &proc_dir_operations;
 		ent->proc_iops = &proc_dir_inode_operations;
 
-		proc_register(parent, ent);
+		if (proc_register(parent, ent) < 0) {
+			kfree(ent);
+			ent = NULL;
+		}
 	}
 	return ent;
 }
@@ -549,7 +559,10 @@
 			ent->proc_fops = &proc_dir_operations;
 			ent->proc_iops = &proc_dir_inode_operations;
 		}
-		proc_register(parent, ent);
+		if (proc_register(parent, ent) < 0) {
+			kfree(ent);
+			ent = NULL;
+		}
 	}
 	return ent;
 }
diff -Nru a/fs/read_write.c b/fs/read_write.c
--- a/fs/read_write.c	Mon Dec  9 18:46:49 2002
+++ b/fs/read_write.c	Mon Dec  9 18:46:49 2002
@@ -193,7 +193,8 @@
 
 	ret = locks_verify_area(FLOCK_VERIFY_READ, inode, file, *pos, count);
 	if (!ret) {
-		if (!(ret = security_file_permission (file, MAY_READ))) {
+		ret = security_file_permission (file, MAY_READ);
+		if (!ret) {
 			if (file->f_op->read)
 				ret = file->f_op->read(file, buf, count, pos);
 			else
@@ -232,7 +233,8 @@
 
 	ret = locks_verify_area(FLOCK_VERIFY_WRITE, inode, file, *pos, count);
 	if (!ret) {
-		if (!(ret = security_file_permission (file, MAY_WRITE))) {
+		ret = security_file_permission (file, MAY_WRITE);
+		if (!ret) {
 			if (file->f_op->write)
 				ret = file->f_op->write(file, buf, count, pos);
 			else
@@ -445,7 +447,7 @@
 		kfree(iov);
 	if ((ret + (type == READ)) > 0)
 		dnotify_parent(file->f_dentry,
-				(type == READ) ? DN_MODIFY : DN_ACCESS);
+				(type == READ) ? DN_ACCESS : DN_MODIFY);
 	return ret;
 }
 
diff -Nru a/fs/readdir.c b/fs/readdir.c
--- a/fs/readdir.c	Mon Dec  9 18:46:37 2002
+++ b/fs/readdir.c	Mon Dec  9 18:46:37 2002
@@ -22,7 +22,8 @@
 	if (!file->f_op || !file->f_op->readdir)
 		goto out;
 
-	if ((res = security_file_permission(file, MAY_READ)))
+	res = security_file_permission(file, MAY_READ);
+	if (res)
 		goto out;
 
 	down(&inode->i_sem);
@@ -133,13 +134,13 @@
 		return -EINVAL;
 	dirent = buf->previous;
 	if (dirent)
-		put_user(offset, &dirent->d_off);
+		__put_user(offset, &dirent->d_off);
 	dirent = buf->current_dir;
 	buf->previous = dirent;
-	put_user(ino, &dirent->d_ino);
-	put_user(reclen, &dirent->d_reclen);
+	__put_user(ino, &dirent->d_ino);
+	__put_user(reclen, &dirent->d_reclen);
 	copy_to_user(dirent->d_name, name, namlen);
-	put_user(0, dirent->d_name + namlen);
+	__put_user(0, dirent->d_name + namlen);
 	((char *) dirent) += reclen;
 	buf->current_dir = dirent;
 	buf->count -= reclen;
@@ -153,6 +154,10 @@
 	struct getdents_callback buf;
 	int error;
 
+	error = -EFAULT;
+	if (!access_ok(VERIFY_WRITE, dirent, count))
+		goto out;
+
 	error = -EBADF;
 	file = fget(fd);
 	if (!file)
@@ -202,7 +207,7 @@
 static int filldir64(void * __buf, const char * name, int namlen, loff_t offset,
 		     ino_t ino, unsigned int d_type)
 {
-	struct linux_dirent64 * dirent, d;
+	struct linux_dirent64 *dirent;
 	struct getdents_callback64 * buf = (struct getdents_callback64 *) __buf;
 	int reclen = ROUND_UP64(NAME_OFFSET(dirent) + namlen + 1);
 
@@ -211,22 +216,29 @@
 		return -EINVAL;
 	dirent = buf->previous;
 	if (dirent) {
-		d.d_off = offset;
-		copy_to_user(&dirent->d_off, &d.d_off, sizeof(d.d_off));
+		if (__put_user(offset, &dirent->d_off))
+			goto efault;
 	}
 	dirent = buf->current_dir;
 	buf->previous = dirent;
-	memset(&d, 0, NAME_OFFSET(&d));
-	d.d_ino = ino;
-	d.d_reclen = reclen;
-	d.d_type = d_type;
-	copy_to_user(dirent, &d, NAME_OFFSET(&d));
-	copy_to_user(dirent->d_name, name, namlen);
-	put_user(0, dirent->d_name + namlen);
+	if (__put_user(ino, &dirent->d_ino))
+		goto efault;
+	if (__put_user(0, &dirent->d_off))
+		goto efault;
+	if (__put_user(reclen, &dirent->d_reclen))
+		goto efault;
+	if (__put_user(d_type, &dirent->d_type))
+		goto efault;
+	if (copy_to_user(dirent->d_name, name, namlen))
+		goto efault;
+	if (__put_user(0, dirent->d_name + namlen))
+		goto efault;
 	((char *) dirent) += reclen;
 	buf->current_dir = dirent;
 	buf->count -= reclen;
 	return 0;
+efault:
+	return -EFAULT;
 }
 
 asmlinkage long sys_getdents64(unsigned int fd, void * dirent, unsigned int count)
@@ -236,6 +248,10 @@
 	struct getdents_callback64 buf;
 	int error;
 
+	error = -EFAULT;
+	if (!access_ok(VERIFY_WRITE, dirent, count))
+		goto out;
+
 	error = -EBADF;
 	file = fget(fd);
 	if (!file)
@@ -254,7 +270,7 @@
 	if (lastdirent) {
 		struct linux_dirent64 d;
 		d.d_off = file->f_pos;
-		copy_to_user(&lastdirent->d_off, &d.d_off, sizeof(d.d_off));
+		__put_user(d.d_off, &lastdirent->d_off);
 		error = count - buf.count;
 	}
 
diff -Nru a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c
--- a/fs/reiserfs/bitmap.c	Mon Dec  9 18:46:50 2002
+++ b/fs/reiserfs/bitmap.c	Mon Dec  9 18:46:50 2002
@@ -9,7 +9,6 @@
 #include <linux/errno.h>
 #include <linux/buffer_head.h>
 #include <linux/kernel.h>
-#include <linux/reiserfs_fs.h>
 #include <linux/reiserfs_fs_sb.h>
 #include <linux/reiserfs_fs_i.h>
 
diff -Nru a/fs/stat.c b/fs/stat.c
--- a/fs/stat.c	Mon Dec  9 18:46:35 2002
+++ b/fs/stat.c	Mon Dec  9 18:46:35 2002
@@ -38,7 +38,8 @@
 	struct inode *inode = dentry->d_inode;
 	int retval;
 
-	if ((retval = security_inode_getattr(mnt, dentry)))
+	retval = security_inode_getattr(mnt, dentry);
+	if (retval)
 		return retval;
 
 	if (inode->i_op->getattr)
@@ -241,7 +242,8 @@
 
 		error = -EINVAL;
 		if (inode->i_op && inode->i_op->readlink) {
-			if (!(error = security_inode_readlink(nd.dentry))) {
+			error = security_inode_readlink(nd.dentry);
+			if (!error) {
 				UPDATE_ATIME(inode);
 				error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
 			}
diff -Nru a/fs/sysfs/inode.c b/fs/sysfs/inode.c
--- a/fs/sysfs/inode.c	Mon Dec  9 18:46:50 2002
+++ b/fs/sysfs/inode.c	Mon Dec  9 18:46:50 2002
@@ -96,9 +96,10 @@
 
 	if (!dentry->d_inode) {
 		inode = sysfs_get_inode(dir->i_sb, mode, dev);
-		if (inode)
+		if (inode) {
 			d_instantiate(dentry, inode);
-		else
+			dget(dentry);
+		} else
 			error = -ENOSPC;
 	} else
 		error = -EEXIST;
@@ -135,14 +136,52 @@
 	if (inode) {
 		int l = strlen(symname)+1;
 		error = page_symlink(inode, symname, l);
-		if (!error)
+		if (!error) {
 			d_instantiate(dentry, inode);
-		else
+			dget(dentry);
+		} else
 			iput(inode);
 	}
 	return error;
 }
 
+#define to_subsys(k) container_of(k,struct subsystem,kobj)
+#define to_sattr(a) container_of(a,struct subsys_attribute,attr)
+
+/**
+ * Subsystem file operations.
+ * These operations allow subsystems to have files that can be 
+ * read/written. 
+ */
+ssize_t subsys_attr_show(struct kobject * kobj, struct attribute * attr, 
+			 char * page, size_t count, loff_t off)
+{
+	struct subsystem * s = to_subsys(kobj);
+	struct subsys_attribute * sattr = to_sattr(attr);
+	ssize_t ret = 0;
+
+	if (sattr->show)
+		ret = sattr->show(s,page,count,off);
+	return ret;
+}
+
+ssize_t subsys_attr_store(struct kobject * kobj, struct attribute * attr,
+			  const char * page, size_t count, loff_t off)
+{
+	struct subsystem * s = to_subsys(kobj);
+	struct subsys_attribute * sattr = to_sattr(attr);
+	ssize_t ret = 0;
+
+	if (sattr->store)
+		ret = sattr->store(s,page,count,off);
+	return ret;
+}
+
+static struct sysfs_ops subsys_sysfs_ops = {
+	.show	= subsys_attr_show,
+	.store	= subsys_attr_store,
+};
+
 /**
  *	sysfs_read_file - read an attribute. 
  *	@file:	file pointer.
@@ -263,9 +302,14 @@
 
 	if (!kobj || !attr)
 		goto Einval;
-	
+
+	/* if the kobject has no subsystem, then it is a subsystem itself,
+	 * so give it the subsys_sysfs_ops.
+	 */
 	if (kobj->subsys)
 		ops = kobj->subsys->sysfs_ops;
+	else
+		ops = &subsys_sysfs_ops;
 
 	/* No sysfs operations, either from having no subsystem,
 	 * or the subsystem have no operations.
@@ -571,8 +615,8 @@
 		/* make sure dentry is really there */
 		if (victim->d_inode && 
 		    (victim->d_parent->d_inode == dir->d_inode)) {
-			d_invalidate(victim);
 			simple_unlink(dir->d_inode,victim);
+			d_delete(victim);
 		}
 	}
 	up(&dir->d_inode->i_sem);
@@ -631,15 +675,15 @@
 		struct dentry * d = list_entry(node,struct dentry,d_child);
 		/* make sure dentry is still there */
 		if (d->d_inode) {
-			d_invalidate(d);
 			simple_unlink(dentry->d_inode,d);
+			d_delete(dentry);
 		}
 	}
 
 	up(&dentry->d_inode->i_sem);
 	d_invalidate(dentry);
 	simple_rmdir(parent->d_inode,dentry);
-
+	d_delete(dentry);
 	up(&parent->d_inode->i_sem);
 	dput(parent);
 }
diff -Nru a/fs/umsdos/ioctl.c b/fs/umsdos/ioctl.c
--- a/fs/umsdos/ioctl.c	Mon Dec  9 18:46:34 2002
+++ b/fs/umsdos/ioctl.c	Mon Dec  9 18:46:34 2002
@@ -430,7 +430,9 @@
 		 */
 		dir->i_sb->u.msdos_sb.options.fs_uid = data.umsdos_dirent.uid;
 		dir->i_sb->u.msdos_sb.options.fs_gid = data.umsdos_dirent.gid;
-		dir->i_sb->u.msdos_sb.options.fs_umask = data.umsdos_dirent.mode;
+		dir->i_sb->u.msdos_sb.options.fs_fmask =
+			dir->i_sb->u.msdos_sb.options.fs_dmask =
+				data.umsdos_dirent.mode;
 		ret = 0;
 	}
 out:
diff -Nru a/fs/xattr.c b/fs/xattr.c
--- a/fs/xattr.c	Mon Dec  9 18:46:36 2002
+++ b/fs/xattr.c	Mon Dec  9 18:46:36 2002
@@ -8,7 +8,6 @@
  */
 #include <linux/fs.h>
 #include <linux/slab.h>
-#include <linux/vmalloc.h>
 #include <linux/smp_lock.h>
 #include <linux/file.h>
 #include <linux/xattr.h>
@@ -19,7 +18,7 @@
 /*
  * Extended attribute memory allocation wrappers, originally
  * based on the Intermezzo PRESTO_ALLOC/PRESTO_FREE macros.
- * The vmalloc use here is very uncommon - extended attributes
+ * Values larger than a page are uncommon - extended attributes
  * are supposed to be small chunks of metadata, and it is quite
  * unusual to have very many extended attributes, so lists tend
  * to be quite short as well.  The 64K upper limit is derived
@@ -36,10 +35,8 @@
 
 	if (!size)	/* size request, no buffer is needed */
 		return NULL;
-	else if (size <= PAGE_SIZE)
-		ptr = kmalloc((unsigned long) size, GFP_KERNEL);
-	else
-		ptr = vmalloc((unsigned long) size);
+
+	ptr = kmalloc((unsigned long) size, GFP_KERNEL);
 	if (!ptr)
 		return ERR_PTR(-ENOMEM);
 	return ptr;
@@ -48,12 +45,8 @@
 static void
 xattr_free(void *ptr, size_t size)
 {
-	if (!size)	/* size request, no buffer was needed */
-		return;
-	else if (size <= PAGE_SIZE)
+	if (size)	/* for a size request, no buffer was needed */
 		kfree(ptr);
-	else
-		vfree(ptr);
 }
 
 /*
@@ -86,7 +79,8 @@
 
 	error = -EOPNOTSUPP;
 	if (d->d_inode->i_op && d->d_inode->i_op->setxattr) {
-		if ((error = security_inode_setxattr(d, kname, kvalue, size, flags)))
+		error = security_inode_setxattr(d, kname, kvalue, size, flags);
+		if (error)
 			goto out;
 		down(&d->d_inode->i_sem);
 		error = d->d_inode->i_op->setxattr(d, kname, kvalue, size, flags);
@@ -162,7 +156,8 @@
 
 	error = -EOPNOTSUPP;
 	if (d->d_inode->i_op && d->d_inode->i_op->getxattr) {
-		if ((error = security_inode_getxattr(d, kname)))
+		error = security_inode_getxattr(d, kname);
+		if (error)
 			goto out;
 		down(&d->d_inode->i_sem);
 		error = d->d_inode->i_op->getxattr(d, kname, kvalue, size);
@@ -234,7 +229,8 @@
 
 	error = -EOPNOTSUPP;
 	if (d->d_inode->i_op && d->d_inode->i_op->listxattr) {
-		if ((error = security_inode_listxattr(d)))
+		error = security_inode_listxattr(d);
+		if (error)
 			goto out;
 		down(&d->d_inode->i_sem);
 		error = d->d_inode->i_op->listxattr(d, klist, size);
@@ -308,7 +304,8 @@
 
 	error = -EOPNOTSUPP;
 	if (d->d_inode->i_op && d->d_inode->i_op->removexattr) {
-		if ((error = security_inode_removexattr(d, kname)))
+		error = security_inode_removexattr(d, kname);
+		if (error)
 			goto out;
 		down(&d->d_inode->i_sem);
 		error = d->d_inode->i_op->removexattr(d, kname);
diff -Nru a/fs/xfs/linux/xfs_aops.c b/fs/xfs/linux/xfs_aops.c
--- a/fs/xfs/linux/xfs_aops.c	Mon Dec  9 18:46:51 2002
+++ b/fs/xfs/linux/xfs_aops.c	Mon Dec  9 18:46:51 2002
@@ -101,7 +101,6 @@
 
 	ASSERT(!(mp->pbm_flags & PBMF_HOLE));
 	ASSERT(!(mp->pbm_flags & PBMF_DELAY));
-	ASSERT(!(mp->pbm_flags & PBMF_UNWRITTEN));
 	ASSERT(mp->pbm_bn != PAGE_BUF_DADDR_NULL);
 
 	delta = page->index;
@@ -135,17 +134,14 @@
 	struct page		*page;
 	int			ret = 0;
 
-	page = find_get_page(mapping, index);
+	page = find_trylock_page(mapping, index);
 	if (!page)
 		return 0;
-	if (PageWriteback(page) || TestSetPageLocked(page)) {
-		page_cache_release(page);
-		return 0;
-	}
+	if (PageWriteback(page))
+		goto out;
+
 	if (page->mapping && PageDirty(page)) {
-		if (!page_has_buffers(page)) {
-			ret = PAGE_CACHE_SIZE;
-		} else {
+		if (page_has_buffers(page)) {
 			struct buffer_head	*bh, *head;
 			bh = head = page_buffers(page);
 			do {
@@ -156,11 +152,12 @@
 				if (ret >= pg_offset)
 					break;
 			} while ((bh = bh->b_this_page) != head);
-		}
+		} else
+			ret = PAGE_CACHE_SIZE;
 	}
 
+out:
 	unlock_page(page);
-	page_cache_release(page);
 	return ret;
 }
 
@@ -214,13 +211,12 @@
 {
 	struct page		*page;
 
-	page = find_get_page(inode->i_mapping, index);
+	page = find_trylock_page(inode->i_mapping, index);
 	if (!page)
 		return NULL;
-	if (PageWriteback(page) || TestSetPageLocked(page)) {
-		page_cache_release(page);
-		return NULL;
-	}
+	if (PageWriteback(page))
+		goto out;
+
 	if (page->mapping && page_has_buffers(page)) {
 		struct buffer_head	*bh, *head;
 
@@ -230,8 +226,9 @@
 				return page;
 		} while ((bh = bh->b_this_page) != head);
 	}
+
+out:
 	unlock_page(page);
-	page_cache_release(page);
 	return NULL;
 }
 
@@ -319,8 +316,6 @@
 	} else {
 		unlock_page(page);
 	}
-
-	page_cache_release(page);
 }
 
 /*
@@ -352,15 +347,15 @@
  * page ready for freeing it's buffers.  When called with startio set then
  * we are coming from writepage. 
  *
- * When called with startio e.g. from
- * write page it is important that we write WHOLE page if possible. The
- * bh->b_state's can not know of any of the blocks or which block for
- * that matter are dirty due to map writes, and therefore bh uptodate is
- * only vaild if the pagei itself isn't completely uptodate. Some layers
- * may clear the page dirty flag prior to calling write page under the
- * assumption the entire page will be written out, by not writing out the
- * whole page the page can be reused before all vaild dirty data is
- * written out. Note: in the case of a page that has been dirty'd by
+ * When called with startio set it is important that we write the WHOLE
+ * page if possible.
+ * The bh->b_state's cannot know if any of the blocks or which block for
+ * that matter are dirty due to mmap writes, and therefore bh uptodate is
+ * only vaild if the page itself isn't completely uptodate.  Some layers
+ * may clear the page dirty flag prior to calling write page, under the
+ * assumption the entire page will be written out; by not writing out the
+ * whole page the page can be reused before all valid dirty data is
+ * written out.  Note: in the case of a page that has been dirty'd by
  * mapwrite and but partially setup by block_prepare_write the
  * bh->b_states's will not agree and only ones setup by BPW/BCW will have
  * valid state, thus the whole page must be written out thing.
@@ -392,7 +387,7 @@
 	end_offset = offset + PAGE_CACHE_SIZE;
 	if (end_offset > inode->i_size)
 		end_offset = inode->i_size;
-	
+
 	if (startio && !page_has_buffers(page))
 		create_empty_buffers(page, 1 << inode->i_blkbits, 0);
 
diff -Nru a/fs/xfs/linux/xfs_file.c b/fs/xfs/linux/xfs_file.c
--- a/fs/xfs/linux/xfs_file.c	Mon Dec  9 18:46:38 2002
+++ b/fs/xfs/linux/xfs_file.c	Mon Dec  9 18:46:38 2002
@@ -138,6 +138,22 @@
 	return linvfs_writev(iocb->ki_filp, &iov, 1, &iocb->ki_pos);
 }
 
+STATIC ssize_t
+linvfs_sendfile(
+	struct file		*filp,
+	loff_t			*ppos,
+	size_t			count,
+	read_actor_t		actor,
+	void			*target)
+{
+	vnode_t			*vp = LINVFS_GET_VP(filp->f_dentry->d_inode);
+	int			error;
+
+	VOP_SENDFILE(vp, filp, ppos, count, actor, target, NULL, error);
+
+	return error;
+}
+
 
 STATIC int
 linvfs_open(
@@ -186,7 +202,7 @@
 
 	ASSERT(vp);
 
-	VOP_FSYNC(vp, flags, NULL, (off_t)0, (off_t)-1, error);
+	VOP_FSYNC(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1, error);
 
 	return -error;
 }
@@ -212,7 +228,7 @@
 	caddr_t		read_buf;
 	int		namelen, size = 0;
 	size_t		rlen = PAGE_CACHE_SIZE << 2;
-	off_t		start_offset;
+	xfs_off_t	start_offset;
 	xfs_dirent_t	*dbp = NULL;
 
 	vp = LINVFS_GET_VP(filp->f_dentry->d_inode);
@@ -280,7 +296,7 @@
 {
 	struct inode	*ip = filp->f_dentry->d_inode;
 	vnode_t		*vp = LINVFS_GET_VP(ip);
-	vattr_t		va = { .va_mask = AT_UPDATIME };
+	vattr_t		va = { .va_mask = XFS_AT_UPDATIME };
 	int		error;
 
 	if ((vp->v_type == VREG) && (vp->v_vfsp->vfs_flag & VFS_DMI)) {
@@ -291,7 +307,7 @@
 
 	vma->vm_ops = &linvfs_file_vm_ops;
 
-	VOP_SETATTR(vp, &va, AT_UPDATIME, NULL, error);
+	VOP_SETATTR(vp, &va, XFS_AT_UPDATIME, NULL, error);
 	UPDATE_ATIME(ip);
 	return 0;
 }
@@ -348,6 +364,7 @@
 	.writev		= linvfs_writev,
 	.aio_read	= linvfs_aio_read,
 	.aio_write	= linvfs_aio_write,
+	.sendfile	= linvfs_sendfile,
 	.ioctl		= linvfs_ioctl,
 	.mmap		= linvfs_file_mmap,
 	.open		= linvfs_open,
diff -Nru a/fs/xfs/linux/xfs_globals.c b/fs/xfs/linux/xfs_globals.c
--- a/fs/xfs/linux/xfs_globals.c	Mon Dec  9 18:46:49 2002
+++ b/fs/xfs/linux/xfs_globals.c	Mon Dec  9 18:46:49 2002
@@ -37,7 +37,6 @@
 
 #include <xfs.h>
 
-uint64_t	xfs_panic_mask;		/* set to cause more panics */
 unsigned long	xfs_physmem;
 
 /*
diff -Nru a/fs/xfs/linux/xfs_ioctl.c b/fs/xfs/linux/xfs_ioctl.c
--- a/fs/xfs/linux/xfs_ioctl.c	Mon Dec  9 18:46:50 2002
+++ b/fs/xfs/linux/xfs_ioctl.c	Mon Dec  9 18:46:50 2002
@@ -34,8 +34,9 @@
 #include <xfs_fsops.h>
 #include <xfs_dfrag.h>
 #include <linux/dcache.h>
-#include <linux/namei.h>
 #include <linux/mount.h>
+#include <linux/namei.h>
+#include <linux/pagemap.h>
 
 
 extern int xfs_change_file_space(bhv_desc_t *, int,
@@ -74,17 +75,9 @@
 	case XFS_IOC_PATH_TO_FSHANDLE:
 	case XFS_IOC_PATH_TO_HANDLE: {
 		struct nameidata	nd;
-		char			*path;
 		int			error;
 
-		/* we need the path */
-		path = getname(hreq.path);
-		if (IS_ERR(path))
-			return PTR_ERR(path);
-
-		/* traverse the path */
-		error = path_lookup(path, 0, &nd);
-		putname(path);
+		error = user_path_walk_link(hreq.path, &nd);
 		if (error)
 			return error;
 
@@ -106,7 +99,6 @@
 		ASSERT(file->f_dentry->d_inode);
 		inode = igrab(file->f_dentry->d_inode);
 		fput(file);
-
 		break;
 	}
 
@@ -520,39 +512,46 @@
  * their own functions.  Functions are defined after their use
  * so gcc doesn't get fancy and inline them with -03 */
 
-int xfs_ioc_space(
+STATIC int
+xfs_ioc_space(
 	bhv_desc_t		*bdp,
 	vnode_t			*vp,
 	struct file		*filp,
 	unsigned int		cmd,
 	unsigned long		arg);
 
-int xfs_ioc_bulkstat(
+STATIC int
+xfs_ioc_bulkstat(
 	xfs_mount_t		*mp,
 	unsigned int		cmd,
 	unsigned long		arg);
 
-int xfs_ioc_fsgeometry_v1(
+STATIC int
+xfs_ioc_fsgeometry_v1(
 	xfs_mount_t		*mp,
 	unsigned long		arg);
 
-int xfs_ioc_fsgeometry(
+STATIC int
+xfs_ioc_fsgeometry(
 	xfs_mount_t		*mp,
 	unsigned long		arg);
 
-int xfs_ioc_xattr(
+STATIC int
+xfs_ioc_xattr(
 	vnode_t			*vp,
 	struct file		*filp,
 	unsigned int		cmd,
 	unsigned long		arg);
 
-int xfs_ioc_getbmap(
+STATIC int
+xfs_ioc_getbmap(
 	bhv_desc_t		*bdp,
 	struct file		*filp,
 	unsigned int		cmd,
 	unsigned long		arg);
 
-int xfs_ioc_getbmapx(
+STATIC int
+xfs_ioc_getbmapx(
 	bhv_desc_t		*bdp,
 	unsigned long		arg);
 
@@ -591,17 +590,16 @@
 	case XFS_IOC_DIOINFO: {
 		struct dioattr	da;
 
-		da.d_miniosz = mp->m_sb.sb_blocksize;
-		da.d_mem = mp->m_sb.sb_blocksize;
 
 		/*
 		 * this only really needs to be BBSIZE.
 		 * it is set to the file system block size to
 		 * avoid having to do block zeroing on short writes.
 		 */
-#define KIO_MAX_ATOMIC_IO 512	/* FIXME: what do we really want here? */
-		da.d_maxiosz = XFS_FSB_TO_B(mp,
-				XFS_B_TO_FSBT(mp, KIO_MAX_ATOMIC_IO << 10));
+		da.d_miniosz = mp->m_sb.sb_blocksize;
+		da.d_mem = mp->m_sb.sb_blocksize;
+		/* The size dio will do in one go */
+		da.d_maxiosz = 64 * PAGE_CACHE_SIZE;
 
 		if (copy_to_user((struct dioattr *)arg, &da, sizeof(da)))
 			return -XFS_ERROR(EFAULT);
@@ -800,16 +798,17 @@
 	}
 }
 
-int xfs_ioc_space(
+STATIC int
+xfs_ioc_space(
 	bhv_desc_t		*bdp,
 	vnode_t			*vp,
 	struct file		*filp,
 	unsigned int		cmd,
 	unsigned long		arg)
 {
-	xfs_flock64_t	bf;
-	int		attr_flags = 0;
-	int		error;
+	xfs_flock64_t		bf;
+	int			attr_flags = 0;
+	int			error;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -XFS_ERROR(EPERM);
@@ -833,16 +832,18 @@
 	return -error;
 }
 
-int xfs_ioc_bulkstat(
+STATIC int
+xfs_ioc_bulkstat(
 	xfs_mount_t		*mp,
 	unsigned int		cmd,
 	unsigned long		arg)
 {
-	xfs_fsop_bulkreq_t bulkreq;
-	int		count;		/* # of records returned */
-	xfs_ino_t	inlast;		/* last inode number */
-	int		done;
-	int		error;
+	xfs_fsop_bulkreq_t	bulkreq;
+	int			count;	/* # of records returned */
+	xfs_ino_t		inlast;	/* last inode number */
+	int			done;
+	int			error;
+
 	/* done = 1 if there are more stats to get and if bulkstat */
 	/* should be called again (unused here, but used in dmapi) */
 
@@ -901,7 +902,8 @@
 	return 0;
 }
 
-int xfs_ioc_fsgeometry_v1(
+STATIC int
+xfs_ioc_fsgeometry_v1(
 	xfs_mount_t		*mp,
 	unsigned long		arg)
 {
@@ -917,12 +919,13 @@
 	return 0;
 }
 
-int xfs_ioc_fsgeometry(
+STATIC int
+xfs_ioc_fsgeometry(
 	xfs_mount_t		*mp,
 	unsigned long		arg)
 {
-	xfs_fsop_geom_t fsgeo;
-	int		error;
+	xfs_fsop_geom_t		fsgeo;
+	int			error;
 
 	error = xfs_fs_geometry(mp, &fsgeo, 4);
 	if (error)
@@ -933,19 +936,20 @@
 	return 0;
 }
 
-int xfs_ioc_xattr(
+STATIC int
+xfs_ioc_xattr(
 	vnode_t			*vp,
 	struct file		*filp,
 	unsigned int		cmd,
 	unsigned long		arg)
 {
-	struct fsxattr	fa;
-	vattr_t		va;
-	int		error;
+	struct fsxattr		fa;
+	vattr_t			va;
+	int			error;
 
 	switch (cmd) {
 	case XFS_IOC_FSGETXATTR: {
-		va.va_mask = AT_XFLAGS|AT_EXTSIZE|AT_NEXTENTS;
+		va.va_mask = XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_NEXTENTS;
 		VOP_GETATTR(vp, &va, 0, NULL, error);
 		if (error)
 			return -error;
@@ -965,7 +969,7 @@
 		if (copy_from_user(&fa, (struct fsxattr *)arg, sizeof(fa)))
 			return -XFS_ERROR(EFAULT);
 
-		va.va_mask = AT_XFLAGS | AT_EXTSIZE;
+		va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE;
 		va.va_xflags  = fa.fsx_xflags;
 		va.va_extsize = fa.fsx_extsize;
 
@@ -978,7 +982,7 @@
 
 	case XFS_IOC_FSGETXATTRA: {
 
-		va.va_mask = AT_XFLAGS|AT_EXTSIZE|AT_ANEXTENTS;
+		va.va_mask = XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_ANEXTENTS;
 		VOP_GETATTR(vp, &va, 0, NULL, error);
 		if (error)
 			return -error;
@@ -998,15 +1002,16 @@
 	}
 }
 
-int xfs_ioc_getbmap(
+STATIC int
+xfs_ioc_getbmap(
 	bhv_desc_t		*bdp,
 	struct file		*filp,
 	unsigned int		cmd,
 	unsigned long		arg)
 {
-	struct getbmap	bm;
-	int		iflags;
-	int		error;
+	struct getbmap		bm;
+	int			iflags;
+	int			error;
 
 	if (copy_from_user(&bm, (struct getbmap *)arg, sizeof(bm)))
 		return -XFS_ERROR(EFAULT);
@@ -1027,14 +1032,15 @@
 	return 0;
 }
 
-int xfs_ioc_getbmapx(
+STATIC int
+xfs_ioc_getbmapx(
 	bhv_desc_t		*bdp,
 	unsigned long		arg)
 {
-	struct getbmapx bmx;
-	struct getbmap	bm;
-	int		iflags;
-	int		error;
+	struct getbmapx		bmx;
+	struct getbmap		bm;
+	int			iflags;
+	int			error;
 
 	if (copy_from_user(&bmx, (struct getbmapx *)arg, sizeof(bmx)))
 		return -XFS_ERROR(EFAULT);
diff -Nru a/fs/xfs/linux/xfs_iomap.c b/fs/xfs/linux/xfs_iomap.c
--- a/fs/xfs/linux/xfs_iomap.c	Mon Dec  9 18:46:38 2002
+++ b/fs/xfs/linux/xfs_iomap.c	Mon Dec  9 18:46:38 2002
@@ -56,7 +56,8 @@
 
 
 int
-xfs_strategy(xfs_inode_t *ip,
+xfs_strategy(
+	xfs_inode_t	*ip,
 	xfs_off_t	offset,
 	ssize_t		count,
 	int		flags,
@@ -74,13 +75,13 @@
 	xfs_bmap_free_t free_list;
 	xfs_filblks_t	count_fsb;
 	int		committed, i, loops, nimaps;
-	int		is_xfs = 1; /* This will be a variable at some point */
+	int		is_xfs;
 	xfs_bmbt_irec_t imap[XFS_MAX_RW_NBMAPS];
 	xfs_trans_t	*tp;
 
-	io = &ip->i_iocore;
 	mp = ip->i_mount;
-	/* is_xfs = IO_IS_XFS(io); */
+	io = &ip->i_iocore;
+	is_xfs = IO_IS_XFS(io);
 	ASSERT((ip->i_d.di_mode & IFMT) == IFREG);
 	ASSERT(((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) != 0) ==
 	       ((io->io_flags & XFS_IOCORE_RT) != 0));
@@ -238,14 +239,19 @@
 		 */
 
 		offset_fsb = XFS_B_TO_FSBT(mp, offset);
-		for(i = 0; i < nimaps; i++) {
-			int maps;
-			if (offset_fsb >= imap[i].br_startoff &&
-				(offset_fsb < (imap[i].br_startoff + imap[i].br_blockcount))) {
-				XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL | XFS_EXTSIZE_WR);
+		for (i = 0; i < nimaps; i++) {
+			int	maps;
+
+			if ((offset_fsb >= imap[i].br_startoff) &&
+			    (offset_fsb <
+			     (imap[i].br_startoff + imap[i].br_blockcount))) {
+
+				XFS_IUNLOCK(mp, io,
+						XFS_ILOCK_EXCL|XFS_EXTSIZE_WR);
 				maps = min(nimaps, *npbmaps);
-				*npbmaps = _xfs_imap_to_bmap(io, offset, &imap[i],
-					pbmapp, maps, *npbmaps);
+				*npbmaps = _xfs_imap_to_bmap(io, offset,
+							     &imap[i], pbmapp,
+							     maps, *npbmaps);
 				XFS_STATS_INC(xfsstats.xs_xstrat_quick);
 				return 0;
 			}
@@ -260,9 +266,11 @@
 
 		nimaps--; /* Index of last entry  */
 		ASSERT(nimaps >= 0);
-		ASSERT(offset_fsb >= imap[nimaps].br_startoff + imap[nimaps].br_blockcount);
+		ASSERT(offset_fsb >=
+			imap[nimaps].br_startoff + imap[nimaps].br_blockcount);
 		ASSERT(count_fsb);
-		offset_fsb = imap[nimaps].br_startoff + imap[nimaps].br_blockcount;
+		offset_fsb =
+			imap[nimaps].br_startoff + imap[nimaps].br_blockcount;
 		map_start_fsb = offset_fsb;
 		XFS_STATS_INC(xfsstats.xs_xstrat_split);
 		XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_WR);
@@ -397,10 +405,9 @@
 	if (io->io_new_size > nisize)
 		nisize = io->io_new_size;
 
-	for (im=0, pbm=0; im < imaps && pbm < pbmaps; im++,pbmapp++,imap++,pbm++) {
+	for (im=pbm=0; im < imaps && pbm < pbmaps; im++,pbmapp++,imap++,pbm++) {
 		pbmapp->pbm_target = io->io_flags & XFS_IOCORE_RT ?
-			mp->m_rtdev_targp :
-			mp->m_ddev_targp;
+			mp->m_rtdev_targp : mp->m_ddev_targp;
 		pbmapp->pbm_offset = XFS_FSB_TO_B(mp, imap->br_startoff);
 		pbmapp->pbm_delta = offset - pbmapp->pbm_offset;
 		pbmapp->pbm_bsize = XFS_FSB_TO_B(mp, imap->br_blockcount);
@@ -415,8 +422,9 @@
 			pbmapp->pbm_flags = PBMF_DELAY;
 		} else {
 			pbmapp->pbm_bn = XFS_FSB_TO_DB_IO(io, start_block);
-			if (imap->br_state == XFS_EXT_UNWRITTEN)
+			if (ISUNWRITTEN(imap)) {
 				pbmapp->pbm_flags |= PBMF_UNWRITTEN;
+			}
 		}
 
 		if ((pbmapp->pbm_offset + pbmapp->pbm_bsize) >= nisize) {
@@ -425,7 +433,7 @@
 
 		offset += pbmapp->pbm_bsize - pbmapp->pbm_delta;
 	}
-	return(pbm);	/* Return the number filled */
+	return pbm;	/* Return the number filled */
 }
 
 STATIC int
@@ -475,7 +483,7 @@
  *	2 must allocate.
  *	There are 3 cases when we allocate:
  *		delay allocation (doesn't really allocate or use transactions)
- *		direct allocation (no previous delay allocation
+ *		direct allocation (no previous delay allocation)
  *		convert delay to real allocations
  */
 
@@ -716,17 +724,14 @@
 	if (io->io_new_size > isize)
 		isize = io->io_new_size;
 
-	if ((offset + count) > isize) {
-		aeof = 1;
-	} else {
-		aeof = 0;
-	}
+	aeof = ((offset + count) > isize) ? 1 : 0;
 
 	offset_fsb = XFS_B_TO_FSBT(mp, offset);
 	last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count)));
 	count_fsb = last_fsb - offset_fsb;
 	if (found && (pbmapp->pbm_flags & PBMF_HOLE)) {
 		xfs_fileoff_t	map_last_fsb;
+
 		map_last_fsb = XFS_B_TO_FSB(mp,
 			(pbmapp->pbm_bsize + pbmapp->pbm_offset));
 
@@ -742,15 +747,15 @@
 	 * is greater that 512K and we are allocating past the allocation eof
 	 */
 	if (!found && mp->m_dalign && (isize >= 524288) && aeof) {
-		int eof;
-		xfs_fileoff_t new_last_fsb;
+		int		eof;
+		xfs_fileoff_t	new_last_fsb;
+
 		new_last_fsb = roundup_64(last_fsb, mp->m_dalign);
 		printk("xfs_iomap_write_direct: about to XFS_BMAP_EOF %Ld\n",
 			new_last_fsb);
 		error = XFS_BMAP_EOF(mp, io, new_last_fsb, XFS_DATA_FORK, &eof);
-		if (error) {
+		if (error)
 			goto error_out;
-		}
 		if (eof)
 			last_fsb = new_last_fsb;
 	}
@@ -867,13 +872,14 @@
 	maps = min(nimaps, maps);
 	*npbmaps = _xfs_imap_to_bmap(io, offset, &imap[0], pbmapp, maps,
 								*npbmaps);
-	if(*npbmaps) {
+	if (*npbmaps) {
 		/*
 		 * this is new since xfs_iomap_read
 		 * didn't find it.
 		 */
 		if (*npbmaps != 1) {
-			printk("NEED MORE WORK FOR MULTIPLE BMAPS (which are new)\n");
+			/* NEED MORE WORK FOR MULTIPLE BMAPS (which are new) */
+			BUG();
 		}
 	}
 	goto out;
@@ -889,4 +895,3 @@
 out:	/* Just return error and any tracing at end of routine */
 	return XFS_ERROR(error);
 }
-
diff -Nru a/fs/xfs/linux/xfs_iops.c b/fs/xfs/linux/xfs_iops.c
--- a/fs/xfs/linux/xfs_iops.c	Mon Dec  9 18:46:35 2002
+++ b/fs/xfs/linux/xfs_iops.c	Mon Dec  9 18:46:35 2002
@@ -45,7 +45,7 @@
 	vattr_t		va;
 	int		error;
 
-	va.va_mask = AT_NLINK|AT_SIZE;
+	va.va_mask = XFS_AT_NLINK|XFS_AT_SIZE;
 	VOP_GETATTR(vp, &va, ATTR_LAZY, NULL, error);
 	ip->i_nlink = va.va_nlink;
 	ip->i_size = va.va_size;
@@ -85,14 +85,14 @@
 		mode &= ~current->fs->umask;
 
 	memset(&va, 0, sizeof(va));
-	va.va_mask = AT_TYPE|AT_MODE;
+	va.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
 	va.va_type = IFTOVT(mode);
 	va.va_mode = mode;
 
 	switch (mode & S_IFMT) {
 	case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK:
 		va.va_rdev = XFS_MKDEV(MAJOR(rdev), MINOR(rdev));
-		va.va_mask |= AT_RDEV;
+		va.va_mask |= XFS_AT_RDEV;
 		/*FALLTHROUGH*/
 	case S_IFREG:
 		VOP_CREATE(dvp, dentry, &va, &vp, NULL, error);
@@ -255,7 +255,7 @@
 	memset(&va, 0, sizeof(va));
 	va.va_type = VLNK;
 	va.va_mode = irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO;
-	va.va_mask = AT_TYPE|AT_MODE;
+	va.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
 
 	error = 0;
 	VOP_SYMLINK(dvp, dentry, &va, (char *)symname, &cvp, NULL, error);
@@ -462,31 +462,31 @@
 
 	memset(&vattr, 0, sizeof(vattr_t));
 	if (ia_valid & ATTR_UID) {
-		vattr.va_mask |= AT_UID;
+		vattr.va_mask |= XFS_AT_UID;
 		vattr.va_uid = attr->ia_uid;
 	}
 	if (ia_valid & ATTR_GID) {
-		vattr.va_mask |= AT_GID;
+		vattr.va_mask |= XFS_AT_GID;
 		vattr.va_gid = attr->ia_gid;
 	}
 	if (ia_valid & ATTR_SIZE) {
-		vattr.va_mask |= AT_SIZE;
+		vattr.va_mask |= XFS_AT_SIZE;
 		vattr.va_size = attr->ia_size;
 	}
 	if (ia_valid & ATTR_ATIME) {
-		vattr.va_mask |= AT_ATIME;
+		vattr.va_mask |= XFS_AT_ATIME;
 		vattr.va_atime = attr->ia_atime;
 	}
 	if (ia_valid & ATTR_MTIME) {
-		vattr.va_mask |= AT_MTIME;
+		vattr.va_mask |= XFS_AT_MTIME;
 		vattr.va_mtime = attr->ia_mtime;
 	}
 	if (ia_valid & ATTR_CTIME) {
-		vattr.va_mask |= AT_CTIME;
+		vattr.va_mask |= XFS_AT_CTIME;
 		vattr.va_ctime = attr->ia_ctime;
 	}
 	if (ia_valid & ATTR_MODE) {
-		vattr.va_mask |= AT_MODE;
+		vattr.va_mask |= XFS_AT_MODE;
 		vattr.va_mode = attr->ia_mode;
 		if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
 			inode->i_mode &= ~S_ISGID;
diff -Nru a/fs/xfs/linux/xfs_linux.h b/fs/xfs/linux/xfs_linux.h
--- a/fs/xfs/linux/xfs_linux.h	Mon Dec  9 18:46:34 2002
+++ b/fs/xfs/linux/xfs_linux.h	Mon Dec  9 18:46:34 2002
@@ -71,6 +71,7 @@
 #define restricted_chown	xfs_params.restrict_chown
 #define irix_sgid_inherit	xfs_params.sgid_inherit
 #define irix_symlink_mode	xfs_params.symlink_mode
+#define xfs_panic_mask		xfs_params.panic_mask
 
 typedef struct xfs_dirent {		/* data from readdir() */
 	xfs_ino_t	d_ino;		/* inode number of entry */
@@ -153,7 +154,6 @@
 #define EFSCORRUPTED	990		/* Filesystem is corrupted */
 
 #define SYNCHRONIZE()	barrier()
-#define rootdev		ROOT_DEV
 #define __return_address __builtin_return_address(0)
 
 /* IRIX uses a dynamic sizing algorithm (ndquot = 200 + numprocs*2) */
diff -Nru a/fs/xfs/linux/xfs_lrw.c b/fs/xfs/linux/xfs_lrw.c
--- a/fs/xfs/linux/xfs_lrw.c	Mon Dec  9 18:46:34 2002
+++ b/fs/xfs/linux/xfs_lrw.c	Mon Dec  9 18:46:34 2002
@@ -205,6 +205,67 @@
 	return ret;
 }
 
+ssize_t
+xfs_sendfile(
+	bhv_desc_t		*bdp,
+	struct file		*filp,
+	loff_t			*offp,
+	size_t			count,
+	read_actor_t		actor,
+	void			*target,
+	cred_t			*credp)
+{
+	size_t			size = 0;
+	ssize_t			ret;
+	xfs_fsize_t		n;
+	xfs_inode_t		*ip;
+	xfs_mount_t		*mp;
+	vnode_t			*vp;
+
+	ip = XFS_BHVTOI(bdp);
+	vp = BHV_TO_VNODE(bdp);
+	mp = ip->i_mount;
+	vn_trace_entry(vp, "xfs_sendfile", (inst_t *)__return_address);
+
+	XFS_STATS_INC(xfsstats.xs_read_calls);
+
+	n = XFS_MAX_FILE_OFFSET - *offp;
+	if ((n <= 0) || (size == 0))
+		return 0;
+
+	if (n < size)
+		size = n;
+
+	if (XFS_FORCED_SHUTDOWN(mp)) {
+		return -EIO;
+	}
+
+	xfs_ilock(ip, XFS_IOLOCK_SHARED);
+
+	if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) &&
+	    !(filp->f_mode & FINVIS)) {
+		int error;
+		vrwlock_t locktype = VRWLOCK_READ;
+
+		error = xfs_dm_send_data_event(DM_EVENT_READ, bdp, *offp,
+				size, FILP_DELAY_FLAG(filp), &locktype);
+		if (error) {
+			xfs_iunlock(ip, XFS_IOLOCK_SHARED);
+			return -error;
+		}
+	}
+
+	ret = generic_file_sendfile(filp, offp, count, actor, target);
+	xfs_iunlock(ip, XFS_IOLOCK_SHARED);
+
+	XFS_STATS_ADD(xfsstats.xs_read_bytes, ret);
+
+	if (!(filp->f_mode & FINVIS))
+		xfs_ichgtime(ip, XFS_ICHGTIME_ACC);
+
+	return ret;
+}
+
 /*
  * This routine is called to handle zeroing any space in the last
  * block of the file that is beyond the EOF.  We do this since the
@@ -260,10 +321,9 @@
 		return 0;
 	}
 	/*
-	 * Get a pagebuf for the last block, zero the part beyond the
-	 * EOF, and write it out sync.	We need to drop the ilock
-	 * while we do this so we don't deadlock when the buffer cache
-	 * calls back to us.
+	 * Zero the part of the last block beyond the EOF, and write it
+	 * out sync.  We need to drop the ilock while we do this so we
+	 * don't deadlock when the buffer cache calls back to us.
 	 */
 	XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL| XFS_EXTSIZE_RD);
 	loff = XFS_FSB_TO_B(mp, last_fsb);
@@ -340,7 +400,6 @@
 	last_fsb = isize ? XFS_B_TO_FSBT(mp, isize - 1) : (xfs_fileoff_t)-1;
 	start_zero_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)isize);
 	end_zero_fsb = XFS_B_TO_FSBT(mp, offset - 1);
-
 	ASSERT((xfs_sfiloff_t)last_fsb < (xfs_sfiloff_t)start_zero_fsb);
 	if (last_fsb == end_zero_fsb) {
 		/*
@@ -353,10 +412,6 @@
 	ASSERT(start_zero_fsb <= end_zero_fsb);
 	prev_zero_fsb = NULLFILEOFF;
 	prev_zero_count = 0;
-	/*
-	 * Maybe change this loop to do the bmapi call and
-	 * loop while we split the mappings into pagebufs?
-	 */
 	while (start_zero_fsb <= end_zero_fsb) {
 		nimaps = 1;
 		zero_count_fsb = end_zero_fsb - start_zero_fsb + 1;
@@ -731,7 +786,6 @@
 	return(ret);
 }
 
-
 /*
  * All xfs metadata buffers except log state machine buffers
  * get this attached as their b_bdstrat callback function.
@@ -761,6 +815,7 @@
 			return (xfs_bioerror(bp));
 	}
 }
+
 /*
  * Wrapper around bdstrat so that we can stop data
  * from going to disk in case we are shutting down the filesystem.
diff -Nru a/fs/xfs/linux/xfs_stats.c b/fs/xfs/linux/xfs_stats.c
--- a/fs/xfs/linux/xfs_stats.c	Mon Dec  9 18:46:51 2002
+++ b/fs/xfs/linux/xfs_stats.c	Mon Dec  9 18:46:51 2002
@@ -33,11 +33,18 @@
 #include <xfs.h>
 #include <linux/proc_fs.h>
 
-static int
-xfs_read_xfsstats(char *buffer, char **start, off_t offset,
-			int count, int *eof, void *data)
+struct xfsstats xfsstats;
+
+STATIC int
+xfs_read_xfsstats(
+	char		*buffer,
+	char		**start,
+	off_t		offset,
+	int		count,
+	int		*eof,
+	void		*data)
 {
-	int	i, j, len;
+	int		i, j, len;
 	static struct xstats_entry {
 		char	*desc;
 		int	endpoint;
@@ -88,11 +95,16 @@
 	return len;
 }
 
-static int
-xfs_read_xfsquota(char *buffer, char **start, off_t offset,
-			int count, int *eof, void *data)
+STATIC int
+xfs_read_xfsquota(
+	char		*buffer,
+	char		**start,
+	off_t		offset,
+	int		count,
+	int		*eof,
+	void		*data)
 {
-	int	len;
+	int		len;
 
 	/* maximum; incore; ratio free to inuse; freelist */
 	len = sprintf(buffer, "%d\t%d\t%d\t%u\n",
diff -Nru a/fs/xfs/linux/xfs_stats.h b/fs/xfs/linux/xfs_stats.h
--- a/fs/xfs/linux/xfs_stats.h	Mon Dec  9 18:46:35 2002
+++ b/fs/xfs/linux/xfs_stats.h	Mon Dec  9 18:46:35 2002
@@ -32,15 +32,128 @@
 #ifndef __XFS_STATS_H__
 #define __XFS_STATS_H__
 
+
+#if defined(CONFIG_PROC_FS) && !defined(XFS_STATS_OFF)
+
 /*
- * procfs interface
+ * XFS global statistics
  */
-#ifdef CONFIG_PROC_FS
+struct xfsstats {
+# define XFSSTAT_END_EXTENT_ALLOC	4
+	__uint32_t		xs_allocx;
+	__uint32_t		xs_allocb;
+	__uint32_t		xs_freex;
+	__uint32_t		xs_freeb;
+# define XFSSTAT_END_ALLOC_BTREE	(XFSSTAT_END_EXTENT_ALLOC+4)
+	__uint32_t		xs_abt_lookup;
+	__uint32_t		xs_abt_compare;
+	__uint32_t		xs_abt_insrec;
+	__uint32_t		xs_abt_delrec;
+# define XFSSTAT_END_BLOCK_MAPPING	(XFSSTAT_END_ALLOC_BTREE+7)
+	__uint32_t		xs_blk_mapr;
+	__uint32_t		xs_blk_mapw;
+	__uint32_t		xs_blk_unmap;
+	__uint32_t		xs_add_exlist;
+	__uint32_t		xs_del_exlist;
+	__uint32_t		xs_look_exlist;
+	__uint32_t		xs_cmp_exlist;
+# define XFSSTAT_END_BLOCK_MAP_BTREE	(XFSSTAT_END_BLOCK_MAPPING+4)
+	__uint32_t		xs_bmbt_lookup;
+	__uint32_t		xs_bmbt_compare;
+	__uint32_t		xs_bmbt_insrec;
+	__uint32_t		xs_bmbt_delrec;
+# define XFSSTAT_END_DIRECTORY_OPS	(XFSSTAT_END_BLOCK_MAP_BTREE+4)
+	__uint32_t		xs_dir_lookup;
+	__uint32_t		xs_dir_create;
+	__uint32_t		xs_dir_remove;
+	__uint32_t		xs_dir_getdents;
+# define XFSSTAT_END_TRANSACTIONS	(XFSSTAT_END_DIRECTORY_OPS+3)
+	__uint32_t		xs_trans_sync;
+	__uint32_t		xs_trans_async;
+	__uint32_t		xs_trans_empty;
+# define XFSSTAT_END_INODE_OPS		(XFSSTAT_END_TRANSACTIONS+7)
+	__uint32_t		xs_ig_attempts;
+	__uint32_t		xs_ig_found;
+	__uint32_t		xs_ig_frecycle;
+	__uint32_t		xs_ig_missed;
+	__uint32_t		xs_ig_dup;
+	__uint32_t		xs_ig_reclaims;
+	__uint32_t		xs_ig_attrchg;
+# define XFSSTAT_END_LOG_OPS		(XFSSTAT_END_INODE_OPS+5)
+	__uint32_t		xs_log_writes;
+	__uint32_t		xs_log_blocks;
+	__uint32_t		xs_log_noiclogs;
+	__uint32_t		xs_log_force;
+	__uint32_t		xs_log_force_sleep;
+# define XFSSTAT_END_TAIL_PUSHING	(XFSSTAT_END_LOG_OPS+10)
+	__uint32_t		xs_try_logspace;
+	__uint32_t		xs_sleep_logspace;
+	__uint32_t		xs_push_ail;
+	__uint32_t		xs_push_ail_success;
+	__uint32_t		xs_push_ail_pushbuf;
+	__uint32_t		xs_push_ail_pinned;
+	__uint32_t		xs_push_ail_locked;
+	__uint32_t		xs_push_ail_flushing;
+	__uint32_t		xs_push_ail_restarts;
+	__uint32_t		xs_push_ail_flush;
+# define XFSSTAT_END_WRITE_CONVERT	(XFSSTAT_END_TAIL_PUSHING+2)
+	__uint32_t		xs_xstrat_quick;
+	__uint32_t		xs_xstrat_split;
+# define XFSSTAT_END_READ_WRITE_OPS	(XFSSTAT_END_WRITE_CONVERT+2)
+	__uint32_t		xs_write_calls;
+	__uint32_t		xs_read_calls;
+# define XFSSTAT_END_ATTRIBUTE_OPS	(XFSSTAT_END_READ_WRITE_OPS+4)
+	__uint32_t		xs_attr_get;
+	__uint32_t		xs_attr_set;
+	__uint32_t		xs_attr_remove;
+	__uint32_t		xs_attr_list;
+# define XFSSTAT_END_QUOTA_OPS		(XFSSTAT_END_ATTRIBUTE_OPS+8)
+	__uint32_t		xs_qm_dqreclaims;
+	__uint32_t		xs_qm_dqreclaim_misses;
+	__uint32_t		xs_qm_dquot_dups;
+	__uint32_t		xs_qm_dqcachemisses;
+	__uint32_t		xs_qm_dqcachehits;
+	__uint32_t		xs_qm_dqwants;
+	__uint32_t		xs_qm_dqshake_reclaims;
+	__uint32_t		xs_qm_dqinact_reclaims;
+# define XFSSTAT_END_INODE_CLUSTER	(XFSSTAT_END_QUOTA_OPS+3)
+	__uint32_t		xs_iflush_count;
+	__uint32_t		xs_icluster_flushcnt;
+	__uint32_t		xs_icluster_flushinode;
+# define XFSSTAT_END_VNODE_OPS		(XFSSTAT_END_INODE_CLUSTER+8)
+	__uint32_t		vn_active;	/* # vnodes not on free lists */
+	__uint32_t		vn_alloc;	/* # times vn_alloc called */
+	__uint32_t		vn_get;		/* # times vn_get called */
+	__uint32_t		vn_hold;	/* # times vn_hold called */
+	__uint32_t		vn_rele;	/* # times vn_rele called */
+	__uint32_t		vn_reclaim;	/* # times vn_reclaim called */
+	__uint32_t		vn_remove;	/* # times vn_remove called */
+	__uint32_t		vn_free;	/* # times vn_free called */
+/* Extra precision counters */
+	__uint64_t		xs_xstrat_bytes;
+	__uint64_t		xs_write_bytes;
+	__uint64_t		xs_read_bytes;
+};
+
+extern struct xfsstats xfsstats;
+
+# define XFS_STATS_INC(count)		( (count)++ )
+# define XFS_STATS_DEC(count)		( (count)-- )
+# define XFS_STATS_ADD(count, inc)	( (count) += (inc) )
+
 extern void xfs_init_procfs(void);
 extern void xfs_cleanup_procfs(void);
-#else
+
+
+#else	/* !CONFIG_PROC_FS */
+
+# define XFS_STATS_INC(count)
+# define XFS_STATS_DEC(count)
+# define XFS_STATS_ADD(count, inc)
+
 static __inline void xfs_init_procfs(void) { };
 static __inline void xfs_cleanup_procfs(void) { };
-#endif
+
+#endif	/* !CONFIG_PROC_FS */
 
 #endif /* __XFS_STATS_H__ */
diff -Nru a/fs/xfs/linux/xfs_super.c b/fs/xfs/linux/xfs_super.c
--- a/fs/xfs/linux/xfs_super.c	Mon Dec  9 18:46:51 2002
+++ b/fs/xfs/linux/xfs_super.c	Mon Dec  9 18:46:51 2002
@@ -46,10 +46,6 @@
 extern int  xfs_init(void);
 extern void xfs_cleanup(void);
 
-#ifndef EVMS_MAJOR
-# define EVMS_MAJOR		117
-#endif
-
 /* For kernels which have the s_maxbytes field - set it */
 #ifdef MAX_NON_LFS
 # define set_max_bytes(sb)	((sb)->s_maxbytes = XFS_MAX_FILE_OFFSET)
@@ -101,7 +97,6 @@
 #define MNTOPT_NORECOVERY "norecovery"	/* don't run XFS recovery */
 #define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */
 #define MNTOPT_QUOTA	"quota"		/* disk quotas */
-#define MNTOPT_MRQUOTA	"mrquota"	/* don't turnoff if SB has quotas on */
 #define MNTOPT_NOQUOTA	"noquota"	/* no quotas */
 #define MNTOPT_UQUOTA	"usrquota"	/* user quota enabled */
 #define MNTOPT_GQUOTA	"grpquota"	/* group quota enabled */
@@ -513,6 +508,31 @@
 	kfree(btp);
 }
 
+void
+xfs_relse_buftarg(
+	xfs_buftarg_t		*btp)
+{
+	invalidate_bdev(btp->pbr_bdev, 1);
+	truncate_inode_pages(btp->pbr_mapping, 0LL);
+}
+
+void
+xfs_size_buftarg(
+	xfs_buftarg_t		*btp,
+	unsigned int		blocksize,
+	unsigned int		sectorsize)
+{
+	btp->pbr_bsize = blocksize;
+	btp->pbr_sshift = ffs(sectorsize) - 1;
+	btp->pbr_smask = sectorsize - 1;
+
+	if (set_blocksize(btp->pbr_bdev, sectorsize)) {
+		printk(KERN_WARNING
+			"XFS: Cannot set_blocksize to %u on device 0x%x\n",
+			sectorsize, btp->pbr_dev);
+	}
+}
+
 xfs_buftarg_t *
 xfs_alloc_buftarg(
 	struct block_device	*bdev)
@@ -524,14 +544,7 @@
 	btp->pbr_dev =  bdev->bd_dev;
 	btp->pbr_bdev = bdev;
 	btp->pbr_mapping = bdev->bd_inode->i_mapping;
-	btp->pbr_blocksize = PAGE_CACHE_SIZE;
-
-	switch (MAJOR(btp->pbr_dev)) {
-	case MD_MAJOR:
-	case EVMS_MAJOR:
-		btp->pbr_flags = PBR_ALIGNED_ONLY;
-		break;
-	}
+	xfs_size_buftarg(btp, PAGE_CACHE_SIZE, bdev_hardsect_size(bdev));
 
 	return btp;
 }
@@ -614,7 +627,7 @@
 
 	args = kmalloc(sizeof(struct xfs_mount_args), GFP_KERNEL);
 	if (!args)
-		return	-EINVAL;
+		return  -EINVAL;
 	memset(args, 0, sizeof(struct xfs_mount_args));
 	args->slcount = args->stimeout = args->ctimeout = -1;
 	strncpy(args->fsname, sb->s_id, MAXNAMELEN);
@@ -635,12 +648,13 @@
 		vfsp->vfs_flag |= VFS_RDONLY;
 
 	vfsp->vfs_super = sb;
-	set_blocksize(sb->s_bdev, BBSIZE);
 	set_max_bytes(sb);
 	set_quota_ops(sb);
 	sb->s_op = &linvfs_sops;
 	sb->s_export_op = &linvfs_export_ops;
 
+	sb_min_blocksize(sb, BBSIZE);
+
 	LINVFS_SET_VFS(sb, vfsp);
 
 	VFSOPS_MOUNT(vfsops, vfsp, args, NULL, error);
@@ -762,8 +776,8 @@
 linvfs_put_super(
 	struct super_block	*sb)
 {
-	int			error;
 	vfs_t			*vfsp = LINVFS_GET_VFS(sb);
+	int			error;
 
 	VFS_DOUNMOUNT(vfsp, 0, NULL, NULL, error);
 	if (error) {
diff -Nru a/fs/xfs/linux/xfs_super.h b/fs/xfs/linux/xfs_super.h
--- a/fs/xfs/linux/xfs_super.h	Mon Dec  9 18:46:35 2002
+++ b/fs/xfs/linux/xfs_super.h	Mon Dec  9 18:46:35 2002
@@ -87,6 +87,8 @@
 extern void xfs_blkdev_put (struct block_device *);
 
 extern struct pb_target *xfs_alloc_buftarg (struct block_device *);
+extern void xfs_size_buftarg (struct pb_target *, unsigned int, unsigned int);
+extern void xfs_relse_buftarg (struct pb_target *);
 extern void xfs_free_buftarg (struct pb_target *);
 
 #endif	/* __XFS_SUPER_H__ */
diff -Nru a/fs/xfs/linux/xfs_sysctl.c b/fs/xfs/linux/xfs_sysctl.c
--- a/fs/xfs/linux/xfs_sysctl.c	Mon Dec  9 18:46:52 2002
+++ b/fs/xfs/linux/xfs_sysctl.c	Mon Dec  9 18:46:52 2002
@@ -40,10 +40,10 @@
 
 extern struct xfsstats xfsstats;
 
-STATIC ulong xfs_min[XFS_PARAM] = { 0, 0, 0, 0 };
-STATIC ulong xfs_max[XFS_PARAM] = { 1, 1, 1, 1 };
+STATIC ulong xfs_min[XFS_PARAM] = { 0, 0, 0, 0, 0 };
+STATIC ulong xfs_max[XFS_PARAM] = { 1, 1, 1, 1, 127 };
 
-xfs_param_t xfs_params = { 0, 1, 0, 0 };
+xfs_param_t xfs_params = { 0, 1, 0, 0, 0 };
 
 static struct ctl_table_header *xfs_table_header;
 
@@ -89,6 +89,10 @@
 	{XFS_SYMLINK_MODE, "irix_symlink_mode", &xfs_params.symlink_mode,
 	sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
 	&sysctl_intvec, NULL, &xfs_min[5], &xfs_max[5]},
+
+	{XFS_PANIC_MASK, "panic_mask", &xfs_params.panic_mask,
+	sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
+	&sysctl_intvec, NULL, &xfs_min[6], &xfs_max[6]},
 
 	{0}
 };
diff -Nru a/fs/xfs/linux/xfs_sysctl.h b/fs/xfs/linux/xfs_sysctl.h
--- a/fs/xfs/linux/xfs_sysctl.h	Mon Dec  9 18:46:34 2002
+++ b/fs/xfs/linux/xfs_sysctl.h	Mon Dec  9 18:46:34 2002
@@ -47,6 +47,7 @@
 	ulong	sgid_inherit;	/* Inherit ISGID bit if process' GID is  */
 				/*  not a member of the parent dir GID.  */
 	ulong	symlink_mode;	/* Symlink creat mode affected by umask. */
+	ulong	panic_mask;	/* bitmask to specify panics on errors.  */
 } xfs_param_t;
 
 enum {
@@ -54,6 +55,7 @@
 	XFS_RESTRICT_CHOWN = 2,
 	XFS_SGID_INHERIT = 3,
 	XFS_SYMLINK_MODE = 4,
+	XFS_PANIC_MASK = 5,
 };
 
 extern xfs_param_t	xfs_params;
diff -Nru a/fs/xfs/linux/xfs_version.h b/fs/xfs/linux/xfs_version.h
--- a/fs/xfs/linux/xfs_version.h	Mon Dec  9 18:46:51 2002
+++ b/fs/xfs/linux/xfs_version.h	Mon Dec  9 18:46:51 2002
@@ -39,6 +39,8 @@
 #ifndef __XFS_VERSION_H__
 #define __XFS_VERSION_H__
 
-#define XFS_VERSION_STRING "CVS-09/15/02:17"
+#include <linux/version.h>
+
+#define XFS_VERSION_STRING "for Linux " UTS_RELEASE
 
 #endif /* __XFS_VERSION_H__ */
diff -Nru a/fs/xfs/linux/xfs_vnode.c b/fs/xfs/linux/xfs_vnode.c
--- a/fs/xfs/linux/xfs_vnode.c	Mon Dec  9 18:46:35 2002
+++ b/fs/xfs/linux/xfs_vnode.c	Mon Dec  9 18:46:35 2002
@@ -35,8 +35,7 @@
 
 
 uint64_t vn_generation;		/* vnode generation number */
-
-spinlock_t	vnumber_lock = SPIN_LOCK_UNLOCKED;
+spinlock_t vnumber_lock = SPIN_LOCK_UNLOCKED;
 
 /*
  * Dedicated vnode inactive/reclaim sync semaphores.
@@ -59,9 +58,6 @@
 	0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK, S_IFIFO, 0, S_IFSOCK
 };
 
-#define VN_LOCK(vp)		spin_lock(&(vp)->v_lock)
-#define VN_UNLOCK(vp)		spin_unlock(&(vp)->v_lock)
-
 
 void
 vn_init(void)
@@ -73,14 +69,13 @@
 		init_sv(svp, SV_DEFAULT, "vsy", i);
 }
 
-
 /*
  * Clean a vnode of filesystem-specific data and prepare it for reuse.
  */
 STATIC int
 vn_reclaim(struct vnode *vp)
 {
-	int error;
+	int	error;
 
 	XFS_STATS_INC(xfsstats.vn_reclaim);
 
@@ -98,9 +93,8 @@
 	ASSERT(vp->v_fbhv == NULL);
 
 	VN_LOCK(vp);
-
 	vp->v_flag &= (VRECLM|VWAIT);
-	VN_UNLOCK(vp);
+	VN_UNLOCK(vp, 0);
 
 	vp->v_type = VNON;
 	vp->v_fbhv = NULL;
@@ -121,7 +115,7 @@
 		sv_broadcast(vptosync(vp));
 	}
 	vp->v_flag &= ~(VRECLM|VWAIT|VMODIFIED);
-	VN_UNLOCK(vp);
+	VN_UNLOCK(vp, 0);
 }
 
 int
@@ -133,7 +127,7 @@
 		sv_wait(vptosync(vp), PINOD, &vp->v_lock, 0);
 		return 1;
 	}
-	VN_UNLOCK(vp);
+	VN_UNLOCK(vp, 0);
 	return 0;
 }
 
@@ -189,7 +183,7 @@
 }
 
 /*
- * "revalidate" the linux inode.
+ * Revalidate the Linux inode from the vnode.
  */
 int
 vn_revalidate(struct vnode *vp)
@@ -199,17 +193,12 @@
 	vattr_t		va;
 
 	vn_trace_entry(vp, "vn_revalidate", (inst_t *)__return_address);
+	ASSERT(vp->v_fbhv != NULL);
 
-	va.va_mask = AT_STAT|AT_GENCOUNT;
-
-	ASSERT(vp->v_bh.bh_first != NULL);
-
+	va.va_mask = XFS_AT_STAT|XFS_AT_GENCOUNT;
 	VOP_GETATTR(vp, &va, 0, NULL, error);
-
-	if (! error) {
+	if (!error) {
 		inode = LINVFS_GET_IP(vp);
-		ASSERT(inode);
-
 		inode->i_mode	    = VTTOIF(va.va_type) | va.va_mode;
 		inode->i_nlink	    = va.va_nlink;
 		inode->i_uid	    = va.va_uid;
@@ -224,11 +213,9 @@
 		inode->i_atime.tv_nsec	    = va.va_atime.tv_nsec;
 		VUNMODIFY(vp);
 	}
-
 	return -error;
 }
 
-
 /*
  * purge a vnode from the cache
  * At this point the vnode is guaranteed to have no references (vn_count == 0)
@@ -248,7 +235,7 @@
 	 */
 	VN_LOCK(vp);
 	if (vp->v_number != vmap->v_number) {
-		VN_UNLOCK(vp);
+		VN_UNLOCK(vp, 0);
 		return;
 	}
 
@@ -269,13 +256,13 @@
 	 * Another process could have raced in and gotten this vnode...
 	 */
 	if (vn_count(vp) > 0) {
-		VN_UNLOCK(vp);
+		VN_UNLOCK(vp, 0);
 		return;
 	}
 
 	XFS_STATS_DEC(xfsstats.vn_active);
 	vp->v_flag |= VRECLM;
-	VN_UNLOCK(vp);
+	VN_UNLOCK(vp, 0);
 
 	/*
 	 * Call VOP_RECLAIM and clean vp. The FSYNC_INVAL flag tells
@@ -305,7 +292,7 @@
 	VN_LOCK(vp);
 	inode = igrab(LINVFS_GET_IP(vp));
 	ASSERT(inode);
-	VN_UNLOCK(vp);
+	VN_UNLOCK(vp, 0);
 
 	return vp;
 }
@@ -317,12 +304,10 @@
 vn_rele(struct vnode *vp)
 {
 	int	vcnt;
-	/* REFERENCED */
-	int cache;
+	int	cache;
 
 	XFS_STATS_INC(xfsstats.vn_rele);
 
-
 	VN_LOCK(vp);
 
 	vn_trace_entry(vp, "vn_rele", (inst_t *)__return_address);
@@ -339,7 +324,7 @@
 		 * until we turn off VINACT or VRECLM
 		 */
 		vp->v_flag |= VINACT;
-		VN_UNLOCK(vp);
+		VN_UNLOCK(vp, 0);
 
 		/*
 		 * Do not make the VOP_INACTIVE call if there
@@ -360,11 +345,10 @@
 
 	}
 
-	VN_UNLOCK(vp);
+	VN_UNLOCK(vp, 0);
 
 	vn_trace_exit(vp, "vn_rele", (inst_t *)__return_address);
 }
-
 
 /*
  * Finish the removal of a vnode.
diff -Nru a/fs/xfs/linux/xfs_vnode.h b/fs/xfs/linux/xfs_vnode.h
--- a/fs/xfs/linux/xfs_vnode.h	Mon Dec  9 18:46:52 2002
+++ b/fs/xfs/linux/xfs_vnode.h	Mon Dec  9 18:46:52 2002
@@ -32,6 +32,12 @@
 #ifndef __XFS_VNODE_H__
 #define __XFS_VNODE_H__
 
+struct uio;
+struct file;
+struct vattr;
+struct page_buf_bmap_s;
+struct attrlist_cursor_kern;
+
 /*
  * Vnode types (unrelated to on-disk inodes).  VNON means no type.
  */
@@ -47,12 +53,9 @@
 	VSOCK	= 8
 } vtype_t;
 
-typedef __u64	vnumber_t;
-
-/*
- * Define the type of behavior head used by vnodes.
- */
-#define vn_bhv_head_t	bhv_head_t
+typedef xfs_ino_t vnumber_t;
+typedef struct dentry vname_t;
+typedef bhv_head_t vn_bhv_head_t;
 
 /*
  * MP locking protocols:
@@ -61,18 +64,50 @@
  */
 typedef struct vnode {
 	__u32		v_flag;			/* vnode flags (see below) */
-	enum vtype	v_type;			/* vnode type		*/
-	struct vfs	*v_vfsp;		/* ptr to containing VFS*/
+	enum vtype	v_type;			/* vnode type */
+	struct vfs	*v_vfsp;		/* ptr to containing VFS */
 	vnumber_t	v_number;		/* in-core vnode number */
 	vn_bhv_head_t	v_bh;			/* behavior head */
-
-	spinlock_t	v_lock;			/* don't use VLOCK on Linux */
-	struct inode	v_inode;		/* linux inode */
+	spinlock_t	v_lock;			/* VN_LOCK/VN_UNLOCK */
+	struct inode	v_inode;		/* Linux inode */
 #ifdef CONFIG_XFS_VNODE_TRACING
 	struct ktrace	*v_trace;		/* trace header structure    */
 #endif
 } vnode_t;
 
+#define v_fbhv			v_bh.bh_first	       /* first behavior */
+#define v_fops			v_bh.bh_first->bd_ops  /* first behavior ops */
+
+#define VNODE_POSITION_BASE	BHV_POSITION_BASE	/* chain bottom */
+#define VNODE_POSITION_TOP	BHV_POSITION_TOP	/* chain top */
+#define VNODE_POSITION_INVALID	BHV_POSITION_INVALID	/* invalid pos. num */
+
+typedef enum {
+	VN_BHV_UNKNOWN,		/* not specified */
+	VN_BHV_XFS,		/* xfs */
+	VN_BHV_END		/* housekeeping end-of-range */
+} vn_bhv_t;
+
+#define VNODE_POSITION_XFS	(VNODE_POSITION_BASE)
+
+/*
+ * Macros for dealing with the behavior descriptor inside of the vnode.
+ */
+#define BHV_TO_VNODE(bdp)	((vnode_t *)BHV_VOBJ(bdp))
+#define BHV_TO_VNODE_NULL(bdp)	((vnode_t *)BHV_VOBJNULL(bdp))
+
+#define VNODE_TO_FIRST_BHV(vp)		(BHV_HEAD_FIRST(&(vp)->v_bh))
+#define VN_BHV_HEAD(vp)			((bhv_head_t *)(&((vp)->v_bh)))
+#define VN_BHV_READ_LOCK(bhp)		BHV_READ_LOCK(bhp)
+#define VN_BHV_READ_UNLOCK(bhp)		BHV_READ_UNLOCK(bhp)
+#define VN_BHV_WRITE_LOCK(bhp)		BHV_WRITE_LOCK(bhp)
+#define VN_BHV_NOT_READ_LOCKED(bhp)	BHV_NOT_READ_LOCKED(bhp)
+#define VN_BHV_NOT_WRITE_LOCKED(bhp)	BHV_NOT_WRITE_LOCKED(bhp)
+#define vn_bhv_head_init(bhp,name)	bhv_head_init(bhp,name)
+#define vn_bhv_remove(bhp,bdp)		bhv_remove(bhp,bdp)
+#define vn_bhv_lookup(bhp,ops)		bhv_lookup(bhp,ops)
+#define vn_bhv_lookup_unlocked(bhp,ops) bhv_lookup_unlocked(bhp,ops)
+
 /*
  * Vnode to Linux inode mapping.
  */
@@ -91,23 +126,12 @@
 
 /*
  * Vnode flags.
- *
- * The vnode flags fall into two categories:
- * 1) Local only -
- *    Flags that are relevant only to a particular cell
- * 2) Single system image -
- *    Flags that must be maintained coherent across all cells
  */
- /* Local only flags */
 #define VINACT		       0x1	/* vnode is being inactivated	*/
 #define VRECLM		       0x2	/* vnode is being reclaimed	*/
-#define VWAIT		       0x4	/* waiting for VINACT
-					   or VRECLM to finish */
-#define VMODIFIED	       0x8	/* xfs inode state possibly different
-					 * from linux inode state.
-					 */
-
-/* Single system image flags */
+#define VWAIT		       0x4	/* waiting for VINACT/VRECLM to end */
+#define VMODIFIED	       0x8	/* XFS inode state possibly differs */
+					/* to the Linux inode state.	*/
 #define VROOT		  0x100000	/* root of its file system	*/
 #define VNOSWAP		  0x200000	/* cannot be used as virt swap device */
 #define VISSWAP		  0x400000	/* vnode is part of virt swap device */
@@ -115,7 +139,6 @@
 #define VNONREPLICABLE	 0x1000000	/* Vnode has writers. Don't replicate */
 #define VDOCMP		 0x2000000	/* Vnode has special VOP_CMP impl. */
 #define VSHARE		 0x4000000	/* vnode part of global cache	*/
-					/* VSHARE applies to local cell only */
 #define VFRLOCKS	 0x8000000	/* vnode has FR locks applied	*/
 #define VENF_LOCKING	0x10000000	/* enf. mode FR locking in effect */
 #define VOPLOCK		0x20000000	/* oplock set on the vnode	*/
@@ -143,35 +166,6 @@
 	VCHANGE_FLAGS_IOEXCL_COUNT	= 4
 } vchange_t;
 
-/*
- * Macros for dealing with the behavior descriptor inside of the vnode.
- */
-#define BHV_TO_VNODE(bdp)	((vnode_t *)BHV_VOBJ(bdp))
-#define BHV_TO_VNODE_NULL(bdp)	((vnode_t *)BHV_VOBJNULL(bdp))
-
-#define VNODE_TO_FIRST_BHV(vp)		(BHV_HEAD_FIRST(&(vp)->v_bh))
-#define VN_BHV_HEAD(vp)			((vn_bhv_head_t *)(&((vp)->v_bh)))
-#define VN_BHV_READ_LOCK(bhp)		BHV_READ_LOCK(bhp)
-#define VN_BHV_READ_UNLOCK(bhp)		BHV_READ_UNLOCK(bhp)
-#define VN_BHV_WRITE_LOCK(bhp)		BHV_WRITE_LOCK(bhp)
-#define VN_BHV_NOT_READ_LOCKED(bhp)	BHV_NOT_READ_LOCKED(bhp)
-#define VN_BHV_NOT_WRITE_LOCKED(bhp)	BHV_NOT_WRITE_LOCKED(bhp)
-#define vn_bhv_head_init(bhp,name)	bhv_head_init(bhp,name)
-#define vn_bhv_head_reinit(bhp)		bhv_head_reinit(bhp)
-#define vn_bhv_insert_initial(bhp,bdp)	bhv_insert_initial(bhp,bdp)
-#define vn_bhv_remove(bhp,bdp)		bhv_remove(bhp,bdp)
-#define vn_bhv_lookup(bhp,ops)		bhv_lookup(bhp,ops)
-#define vn_bhv_lookup_unlocked(bhp,ops) bhv_lookup_unlocked(bhp,ops)
-
-#define v_fbhv		v_bh.bh_first	       /* first behavior */
-#define v_fops		v_bh.bh_first->bd_ops  /* ops for first behavior */
-
-
-struct uio;
-struct file;
-struct vattr;
-struct page_buf_bmap_s;
-struct attrlist_cursor_kern;
 
 typedef int	(*vop_open_t)(bhv_desc_t *, struct cred *);
 typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct file *,
@@ -180,37 +174,42 @@
 typedef ssize_t (*vop_write_t)(bhv_desc_t *, struct file *,
 				const struct iovec *, unsigned long,
 				loff_t *, struct cred *);
-typedef int	(*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *, unsigned int, unsigned long);
+typedef ssize_t (*vop_sendfile_t)(bhv_desc_t *, struct file *,
+				loff_t *, size_t, read_actor_t,
+				void *, struct cred *);
+typedef int	(*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *,
+				unsigned int, unsigned long);
 typedef int	(*vop_getattr_t)(bhv_desc_t *, struct vattr *, int,
 				struct cred *);
 typedef int	(*vop_setattr_t)(bhv_desc_t *, struct vattr *, int,
 				struct cred *);
 typedef int	(*vop_access_t)(bhv_desc_t *, int, struct cred *);
-typedef int	(*vop_lookup_t)(bhv_desc_t *, struct dentry *, vnode_t **,
+typedef int	(*vop_lookup_t)(bhv_desc_t *, vname_t *, vnode_t **,
 				int, vnode_t *, struct cred *);
-typedef int	(*vop_create_t)(bhv_desc_t *, struct dentry *, struct vattr *,
+typedef int	(*vop_create_t)(bhv_desc_t *, vname_t *, struct vattr *,
 				vnode_t **, struct cred *);
-typedef int	(*vop_remove_t)(bhv_desc_t *, struct dentry *, struct cred *);
-typedef int	(*vop_link_t)(bhv_desc_t *, vnode_t *, struct dentry *,
+typedef int	(*vop_remove_t)(bhv_desc_t *, vname_t *, struct cred *);
+typedef int	(*vop_link_t)(bhv_desc_t *, vnode_t *, vname_t *,
+				struct cred *);
+typedef int	(*vop_rename_t)(bhv_desc_t *, vname_t *, vnode_t *, vname_t *,
 				struct cred *);
-typedef int	(*vop_rename_t)(bhv_desc_t *, struct dentry *, vnode_t *,
-				struct dentry *, struct cred *);
-typedef int	(*vop_mkdir_t)(bhv_desc_t *, struct dentry *, struct vattr *,
+typedef int	(*vop_mkdir_t)(bhv_desc_t *, vname_t *, struct vattr *,
 				vnode_t **, struct cred *);
-typedef	int	(*vop_rmdir_t)(bhv_desc_t *, struct dentry *, struct cred *);
+typedef int	(*vop_rmdir_t)(bhv_desc_t *, vname_t *, struct cred *);
 typedef int	(*vop_readdir_t)(bhv_desc_t *, struct uio *, struct cred *,
 				int *);
-typedef int	(*vop_symlink_t)(bhv_desc_t *, struct dentry *,
-				struct vattr *, char *,
-				vnode_t **, struct cred *);
+typedef int	(*vop_symlink_t)(bhv_desc_t *, vname_t *, struct vattr *,
+				char *, vnode_t **, struct cred *);
 typedef int	(*vop_readlink_t)(bhv_desc_t *, struct uio *, struct cred *);
-typedef int	(*vop_fsync_t)(bhv_desc_t *, int, struct cred *, xfs_off_t, xfs_off_t);
+typedef int	(*vop_fsync_t)(bhv_desc_t *, int, struct cred *,
+				xfs_off_t, xfs_off_t);
 typedef int	(*vop_inactive_t)(bhv_desc_t *, struct cred *);
 typedef int	(*vop_fid2_t)(bhv_desc_t *, struct fid *);
 typedef int	(*vop_release_t)(bhv_desc_t *);
 typedef int	(*vop_rwlock_t)(bhv_desc_t *, vrwlock_t);
 typedef void	(*vop_rwunlock_t)(bhv_desc_t *, vrwlock_t);
-typedef int	(*vop_bmap_t)(bhv_desc_t *, xfs_off_t, ssize_t, int, struct page_buf_bmap_s *, int *);
+typedef int	(*vop_bmap_t)(bhv_desc_t *, xfs_off_t, ssize_t, int,
+				struct page_buf_bmap_s *, int *);
 typedef int	(*vop_reclaim_t)(bhv_desc_t *);
 typedef int	(*vop_attr_get_t)(bhv_desc_t *, char *, char *, int *, int,
 				struct cred *);
@@ -223,7 +222,8 @@
 typedef void	(*vop_vnode_change_t)(bhv_desc_t *, vchange_t, __psint_t);
 typedef void	(*vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
 typedef void	(*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
-typedef int	(*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, uint64_t, int);
+typedef int	(*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t,
+				uint64_t, int);
 typedef int	(*vop_iflush_t)(bhv_desc_t *, int);
 
 
@@ -232,6 +232,7 @@
 	vop_open_t		vop_open;
 	vop_read_t		vop_read;
 	vop_write_t		vop_write;
+	vop_sendfile_t		vop_sendfile;
 	vop_ioctl_t		vop_ioctl;
 	vop_getattr_t		vop_getattr;
 	vop_setattr_t		vop_setattr;
@@ -283,6 +284,12 @@
 	rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,cr);\
 	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
+#define VOP_SENDFILE(vp,f,of,cnt,act,targ,cr,rv)			\
+{									\
+	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
+	rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,of,cnt,act,targ,cr);\
+	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
+}
 #define VOP_BMAP(vp,of,sz,rw,b,n,rv)					\
 {									\
 	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
@@ -541,53 +548,55 @@
 /*
  * setattr or getattr attributes
  */
-#define AT_TYPE		0x00000001
-#define AT_MODE		0x00000002
-#define AT_UID		0x00000004
-#define AT_GID		0x00000008
-#define AT_FSID		0x00000010
-#define AT_NODEID	0x00000020
-#define AT_NLINK	0x00000040
-#define AT_SIZE		0x00000080
-#define AT_ATIME	0x00000100
-#define AT_MTIME	0x00000200
-#define AT_CTIME	0x00000400
-#define AT_RDEV		0x00000800
-#define AT_BLKSIZE	0x00001000
-#define AT_NBLOCKS	0x00002000
-#define AT_VCODE	0x00004000
-#define AT_MAC		0x00008000
-#define AT_UPDATIME	0x00010000
-#define AT_UPDMTIME	0x00020000
-#define AT_UPDCTIME	0x00040000
-#define AT_ACL		0x00080000
-#define AT_CAP		0x00100000
-#define AT_INF		0x00200000
-#define AT_XFLAGS	0x00400000
-#define AT_EXTSIZE	0x00800000
-#define AT_NEXTENTS	0x01000000
-#define AT_ANEXTENTS	0x02000000
-#define AT_PROJID	0x04000000
-#define AT_SIZE_NOPERM	0x08000000
-#define AT_GENCOUNT	0x10000000
-
-#define AT_ALL	(AT_TYPE|AT_MODE|AT_UID|AT_GID|AT_FSID|AT_NODEID|\
-		AT_NLINK|AT_SIZE|AT_ATIME|AT_MTIME|AT_CTIME|AT_RDEV|\
-		AT_BLKSIZE|AT_NBLOCKS|AT_VCODE|AT_MAC|AT_ACL|AT_CAP|\
-		AT_INF|AT_XFLAGS|AT_EXTSIZE|AT_NEXTENTS|AT_ANEXTENTS|\
-		AT_PROJID|AT_GENCOUNT)
-
-#define AT_STAT (AT_TYPE|AT_MODE|AT_UID|AT_GID|AT_FSID|AT_NODEID|AT_NLINK|\
-		AT_SIZE|AT_ATIME|AT_MTIME|AT_CTIME|AT_RDEV|AT_BLKSIZE|\
-		AT_NBLOCKS|AT_PROJID)
-
-#define AT_TIMES (AT_ATIME|AT_MTIME|AT_CTIME)
-
-#define AT_UPDTIMES (AT_UPDATIME|AT_UPDMTIME|AT_UPDCTIME)
-
-#define AT_NOSET (AT_NLINK|AT_RDEV|AT_FSID|AT_NODEID|AT_TYPE|\
-		 AT_BLKSIZE|AT_NBLOCKS|AT_VCODE|AT_NEXTENTS|AT_ANEXTENTS|\
-		 AT_GENCOUNT)
+#define XFS_AT_TYPE		0x00000001
+#define XFS_AT_MODE		0x00000002
+#define XFS_AT_UID		0x00000004
+#define XFS_AT_GID		0x00000008
+#define XFS_AT_FSID		0x00000010
+#define XFS_AT_NODEID		0x00000020
+#define XFS_AT_NLINK		0x00000040
+#define XFS_AT_SIZE		0x00000080
+#define XFS_AT_ATIME		0x00000100
+#define XFS_AT_MTIME		0x00000200
+#define XFS_AT_CTIME		0x00000400
+#define XFS_AT_RDEV		0x00000800
+#define XFS_AT_BLKSIZE		0x00001000
+#define XFS_AT_NBLOCKS		0x00002000
+#define XFS_AT_VCODE		0x00004000
+#define XFS_AT_MAC		0x00008000
+#define XFS_AT_UPDATIME		0x00010000
+#define XFS_AT_UPDMTIME		0x00020000
+#define XFS_AT_UPDCTIME		0x00040000
+#define XFS_AT_ACL		0x00080000
+#define XFS_AT_CAP		0x00100000
+#define XFS_AT_INF		0x00200000
+#define XFS_AT_XFLAGS		0x00400000
+#define XFS_AT_EXTSIZE		0x00800000
+#define XFS_AT_NEXTENTS		0x01000000
+#define XFS_AT_ANEXTENTS	0x02000000
+#define XFS_AT_PROJID		0x04000000
+#define XFS_AT_SIZE_NOPERM	0x08000000
+#define XFS_AT_GENCOUNT		0x10000000
+
+#define XFS_AT_ALL	(XFS_AT_TYPE|XFS_AT_MODE|XFS_AT_UID|XFS_AT_GID|\
+		XFS_AT_FSID|XFS_AT_NODEID|XFS_AT_NLINK|XFS_AT_SIZE|\
+		XFS_AT_ATIME|XFS_AT_MTIME|XFS_AT_CTIME|XFS_AT_RDEV|\
+		XFS_AT_BLKSIZE|XFS_AT_NBLOCKS|XFS_AT_VCODE|XFS_AT_MAC|\
+		XFS_AT_ACL|XFS_AT_CAP|XFS_AT_INF|XFS_AT_XFLAGS|XFS_AT_EXTSIZE|\
+		XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_PROJID|XFS_AT_GENCOUNT)
+
+#define XFS_AT_STAT	(XFS_AT_TYPE|XFS_AT_MODE|XFS_AT_UID|XFS_AT_GID|\
+		XFS_AT_FSID|XFS_AT_NODEID|XFS_AT_NLINK|XFS_AT_SIZE|\
+		XFS_AT_ATIME|XFS_AT_MTIME|XFS_AT_CTIME|XFS_AT_RDEV|\
+		XFS_AT_BLKSIZE|XFS_AT_NBLOCKS|XFS_AT_PROJID)
+
+#define XFS_AT_TIMES	(XFS_AT_ATIME|XFS_AT_MTIME|XFS_AT_CTIME)
+
+#define XFS_AT_UPDTIMES	(XFS_AT_UPDATIME|XFS_AT_UPDMTIME|XFS_AT_UPDCTIME)
+
+#define XFS_AT_NOSET	(XFS_AT_NLINK|XFS_AT_RDEV|XFS_AT_FSID|XFS_AT_NODEID|\
+		XFS_AT_TYPE|XFS_AT_BLKSIZE|XFS_AT_NBLOCKS|XFS_AT_VCODE|\
+		XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_GENCOUNT)
 
 #define VREAD		00400
 #define VWRITE		00200
@@ -665,8 +674,16 @@
 #endif	/* ! (defined(CONFIG_XFS_VNODE_TRACING) */
 
 /*
+ * Vname handling macros.
+ */
+#define VNAME(dentry)		((char *) (dentry)->d_name.name)
+#define VNAMELEN(dentry)	((dentry)->d_name.len)
+
+/*
  * Vnode spinlock manipulation.
  */
+#define VN_LOCK(vp)		mutex_spinlock(&(vp)->v_lock)
+#define VN_UNLOCK(vp, s)	mutex_spinunlock(&(vp)->v_lock, s)
 #define VN_FLAGSET(vp,b)	vn_flagset(vp,b)
 #define VN_FLAGCLR(vp,b)	vn_flagclr(vp,b)
 
diff -Nru a/fs/xfs/pagebuf/page_buf.c b/fs/xfs/pagebuf/page_buf.c
--- a/fs/xfs/pagebuf/page_buf.c	Mon Dec  9 18:46:34 2002
+++ b/fs/xfs/pagebuf/page_buf.c	Mon Dec  9 18:46:34 2002
@@ -46,7 +46,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/compiler.h>
 #include <linux/stddef.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
@@ -57,16 +56,15 @@
 #include <linux/bio.h>
 #include <linux/sysctl.h>
 #include <linux/proc_fs.h>
+#include <linux/workqueue.h>
 
 #include <support/debug.h>
 #include <support/kmem.h>
 
 #include "page_buf_internal.h"
 
-#define SECTOR_SHIFT	9
-#define SECTOR_SIZE	(1<<SECTOR_SHIFT)
-#define SECTOR_MASK	(SECTOR_SIZE - 1)
-#define BN_ALIGN_MASK	((1 << (PAGE_CACHE_SHIFT - SECTOR_SHIFT)) - 1)
+#define BBSHIFT		9
+#define BN_ALIGN_MASK	((1 << (PAGE_CACHE_SHIFT - BBSHIFT)) - 1)
 
 #ifndef GFP_READAHEAD
 #define GFP_READAHEAD	0
@@ -115,45 +113,6 @@
 }
 #endif	/* PAGEBUF_TRACE */
 
-#ifdef PAGEBUF_TRACKING
-#define MAX_PB	10000
-page_buf_t	*pb_array[MAX_PB];
-EXPORT_SYMBOL(pb_array);
-
-void
-pb_tracking_get(
-	page_buf_t	*pb)
-{
-	int		i;
-
-	for (i = 0; (pb_array[i] != 0) && (i < MAX_PB); i++) { }
-	if (i == MAX_PB)
-		printk("pb 0x%p not recorded in pb_array\n", pb);
-	else {
-		//printk("pb_get 0x%p in pb_array[%d]\n", pb, i);
-		pb_array[i] = pb;
-	}
-}
-
-void
-pb_tracking_free(
-	page_buf_t	*pb)
-{
-	int		i;
-
-	for (i = 0; (pb_array[i] != pb) && (i < MAX_PB); i++) { }
-	if (i < MAX_PB) {
-		//printk("pb_free 0x%p from pb_array[%d]\n", pb, i);
-		pb_array[i] = NULL;
-	}
-	else
-		printk("Freed unmonitored pagebuf 0x%p\n", pb);
-}
-#else
-#define pb_tracking_get(pb)	do { } while (0)
-#define pb_tracking_free(pb)	do { } while (0)
-#endif	/* PAGEBUF_TRACKING */
-
 /*
  *	File wide globals
  */
@@ -161,6 +120,8 @@
 STATIC kmem_cache_t *pagebuf_cache;
 STATIC pagebuf_daemon_t *pb_daemon;
 STATIC void pagebuf_daemon_wakeup(int);
+STATIC struct workqueue_struct *pagebuf_workqueue;
+
 
 /*
  * Pagebuf module configuration parameters, exported via
@@ -179,11 +140,6 @@
 struct pbstats pbstats;
 
 /*
- * Queue for delayed I/O completion.
- */
-struct workqueue_struct *pagebuf_workqueue;
-
-/*
  * Pagebuf allocation / freeing.
  */
 
@@ -245,19 +201,27 @@
 STATIC	a_list_t	*as_free_head;
 STATIC	int		as_list_len;
 
+
+/*
+ * Try to batch vunmaps because they are costly.
+ */
 STATIC void
 free_address(
 	void		*addr)
 {
 	a_list_t	*aentry;
 
-	spin_lock(&as_lock);
 	aentry = kmalloc(sizeof(a_list_t), GFP_ATOMIC);
-	aentry->next = as_free_head;
-	aentry->vm_addr = addr;
-	as_free_head = aentry;
-	as_list_len++;
-	spin_unlock(&as_lock);
+	if (aentry) {
+		spin_lock(&as_lock);
+		aentry->next = as_free_head;
+		aentry->vm_addr = addr;
+		as_free_head = aentry;
+		as_list_len++;
+		spin_unlock(&as_lock);
+	} else {
+		vunmap(addr);
+	}
 }
 
 STATIC void
@@ -265,7 +229,8 @@
 {
 	a_list_t	*aentry, *old;
 
-	if (as_free_head == NULL) return;
+	if (as_free_head == NULL)
+		return;
 
 	spin_lock(&as_lock);
 	aentry = as_free_head;
@@ -307,8 +272,6 @@
 	 */
 	flags &= ~(PBF_LOCK|PBF_MAPPED|PBF_DONT_BLOCK|PBF_READ_AHEAD);
 
-	pb_tracking_get(pb);
-
 	memset(pb, 0, sizeof(page_buf_private_t));
 	atomic_set(&pb->pb_hold, 1);
 	init_MUTEX_LOCKED(&pb->pb_iodonesema);
@@ -437,7 +400,6 @@
 		}
 	}
 
-	pb_tracking_free(pb);
 	pagebuf_deallocate(pb);
 }
 
@@ -462,7 +424,8 @@
 	struct page		*page;
 	int			gfp_mask, retry_count = 5, rval = 0;
 	int			all_mapped, good_pages, nbytes;
-	size_t			blocksize, size, offset;
+	unsigned int		blocksize, sectorshift;
+	size_t			size, offset;
 
 
 	/* For pagebufs where we want to map an address, do not use
@@ -508,7 +471,8 @@
 		return rval;
 
 	rval = pi = 0;
-	blocksize = pb->pb_target->pbr_blocksize;
+	blocksize = pb->pb_target->pbr_bsize;
+	sectorshift = pb->pb_target->pbr_sshift;
 	size = pb->pb_count_desired;
 	offset = pb->pb_offset;
 
@@ -549,15 +513,15 @@
 					pb->pb_locked = 1;
 				good_pages--;
 			} else if (!PagePrivate(page)) {
-				unsigned long i, range = (offset + nbytes) >> SECTOR_SHIFT;
+				unsigned long	i, range;
 
-				ASSERT(blocksize < PAGE_CACHE_SIZE);
-				ASSERT(!(pb->pb_flags & _PBF_PRIVATE_BH));
 				/*
 				 * In this case page->private holds a bitmap
-				 * of uptodate sectors (512) within the page
+				 * of uptodate sectors within the page
 				 */
-				for (i = offset >> SECTOR_SHIFT; i < range; i++)
+				ASSERT(blocksize < PAGE_CACHE_SIZE);
+				range = (offset + nbytes) >> sectorshift;
+				for (i = offset >> sectorshift; i < range; i++)
 					if (!test_bit(i, &page->private))
 						break;
 				if (i != range)
@@ -611,7 +575,6 @@
 	return rval;
 }
 
-
 /*
  *	Finding and Reading Buffers
  */
@@ -642,8 +605,14 @@
 	page_buf_t		*pb;
 	int			not_locked;
 
-	range_base = (ioff << SECTOR_SHIFT);
-	range_length = (isize << SECTOR_SHIFT);
+	range_base = (ioff << BBSHIFT);
+	range_length = (isize << BBSHIFT);
+
+	/* Ensure we never do IOs smaller than the sector size */
+	BUG_ON(range_length < (1 << target->pbr_sshift));
+
+	/* Ensure we never do IOs that are not sector aligned */
+	BUG_ON(range_base & (loff_t)target->pbr_smask);
 
 	hval = _bhash(target->pbr_bdev->bd_dev, range_base);
 	h = &pbhash[hval];
@@ -851,8 +820,20 @@
 	size_t			isize,
 	page_buf_flags_t	flags)
 {
+	struct backing_dev_info *bdi;
+
+	bdi = target->pbr_mapping->backing_dev_info;
+	if (bdi_read_congested(bdi))
+		return;
+	if (bdi_write_congested(bdi))
+		return;
+
 	flags |= (PBF_TRYLOCK|PBF_READ|PBF_ASYNC|PBF_MAPPABLE|PBF_READ_AHEAD);
+
+	/* don't complain on allocation failure, it's fine with us */
+	current->flags |= PF_NOWARN;
 	pagebuf_get(target, ioff, isize, flags);
+	current->flags &= ~PF_NOWARN;
 }
 
 page_buf_t *
@@ -956,18 +937,12 @@
 		} else {
 			kfree(rmem); /* free the mem from the previous try */
 			tlen <<= 1; /* double the size and try again */
-			/*
-			printk(
-			"pb_get_no_daddr NOT block 0x%p mask 0x%p len %d\n",
-				rmem, ((size_t)rmem & (size_t)~SECTOR_MASK),
-				len);
-			*/
 		}
 		if ((rmem = kmalloc(tlen, GFP_KERNEL)) == 0) {
 			pagebuf_free(pb);
 			return NULL;
 		}
-	} while ((size_t)rmem != ((size_t)rmem & (size_t)~SECTOR_MASK));
+	} while ((size_t)rmem != ((size_t)rmem & ~target->pbr_smask));
 
 	if ((rval = pagebuf_associate_memory(pb, rmem, len)) != 0) {
 		kfree(rmem);
@@ -1145,7 +1120,7 @@
 		if (atomic_read(&PBP(pb)->pb_pin_count) == 0) {
 			break;
 		}
-		blk_run_queues();
+		pagebuf_run_queues(pb);
 		schedule();
 	}
 	remove_wait_queue(&PBP(pb)->pb_waiters, &wait);
@@ -1183,7 +1158,8 @@
 
 void
 pagebuf_iodone(
-	page_buf_t		*pb)
+	page_buf_t		*pb,
+	int			schedule)
 {
 	pb->pb_flags &= ~(PBF_READ | PBF_WRITE);
 	if (pb->pb_error == 0) {
@@ -1193,8 +1169,12 @@
 	PB_TRACE(pb, PB_TRACE_REC(done), pb->pb_iodone);
 
 	if ((pb->pb_iodone) || (pb->pb_flags & PBF_ASYNC)) {
-		INIT_WORK(&pb->pb_iodone_work, pagebuf_iodone_work, pb);
-		queue_work(pagebuf_workqueue, &pb->pb_iodone_work);
+		if (schedule) {
+			INIT_WORK(&pb->pb_iodone_work, pagebuf_iodone_work, pb);
+			queue_work(pagebuf_workqueue, &pb->pb_iodone_work);
+		} else {
+			pagebuf_iodone_work(pb);
+		}
 	} else {
 		up(&pb->pb_iodonesema);
 	}
@@ -1248,9 +1228,7 @@
 	pb->pb_flags &= ~(PBF_READ|PBF_WRITE|PBF_ASYNC|PBF_DELWRI|PBF_READ_AHEAD);
 	pb->pb_flags |= flags & (PBF_READ|PBF_WRITE|PBF_ASYNC|PBF_SYNC|PBF_READ_AHEAD);
 
-	if (pb->pb_bn == PAGE_BUF_DADDR_NULL) {
-		BUG();
-	}
+	BUG_ON(pb->pb_bn == PAGE_BUF_DADDR_NULL);
 
 	/* For writes call internal function which checks for
 	 * filesystem specific callout function and execute it.
@@ -1279,7 +1257,8 @@
 	int			error)
 {
 	page_buf_t		*pb = (page_buf_t *)bio->bi_private;
-	unsigned int		i, blocksize = pb->pb_target->pbr_blocksize;
+	unsigned int		i, blocksize = pb->pb_target->pbr_bsize;
+	unsigned int		sectorshift = pb->pb_target->pbr_sshift;
 	struct bio_vec		*bvec = bio->bi_io_vec;
 
 	if (bio->bi_size)
@@ -1299,10 +1278,8 @@
 			unsigned int	j, range;
 
 			ASSERT(blocksize < PAGE_CACHE_SIZE);
-			ASSERT(!(pb->pb_flags & _PBF_PRIVATE_BH));
-
-			range = (bvec->bv_offset + bvec->bv_len)>>SECTOR_SHIFT;
-			for (j = bvec->bv_offset>>SECTOR_SHIFT; j < range; j++)
+			range = (bvec->bv_offset + bvec->bv_len) >> sectorshift;
+			for (j = bvec->bv_offset >> sectorshift; j < range; j++)
 				set_bit(j, &page->private);
 			if (page->private == (unsigned long)(PAGE_CACHE_SIZE-1))
 				SetPageUptodate(page);
@@ -1315,9 +1292,9 @@
 		}
 	}
 
-	if (atomic_dec_and_test(&PBP(pb)->pb_io_remaining)) {
+	if (atomic_dec_and_test(&pb->pb_io_remaining) == 1) {
 		pb->pb_locked = 0;
-		pagebuf_iodone(pb);
+		pagebuf_iodone(pb, 1);
 	}
 
 	bio_put(bio);
@@ -1353,7 +1330,7 @@
 	int			offset = pb->pb_offset;
 	int			size = pb->pb_count_desired;
 	sector_t		sector = pb->pb_bn;
-	size_t			blocksize = pb->pb_target->pbr_blocksize;
+	unsigned int		blocksize = pb->pb_target->pbr_bsize;
 	int			locking;
 
 	locking = (pb->pb_flags & _PBF_LOCKABLE) == 0 && (pb->pb_locked == 0);
@@ -1369,7 +1346,7 @@
 	 * completion callout which happens before we have started
 	 * all the I/O from calling iodone too early
 	 */
-	atomic_set(&PBP(pb)->pb_io_remaining, 1);
+	atomic_set(&pb->pb_io_remaining, 1);
 
 	/* Special code path for reading a sub page size pagebuf in --
 	 * we populate up the whole page, and hence the other metadata
@@ -1382,7 +1359,7 @@
 		bio = bio_alloc(GFP_NOIO, 1);
 
 		bio->bi_bdev = pb->pb_target->pbr_bdev;
-		bio->bi_sector = sector - (offset >> SECTOR_SHIFT);
+		bio->bi_sector = sector - (offset >> BBSHIFT);
 		bio->bi_end_io = bio_end_io_pagebuf;
 		bio->bi_private = pb;
 		bio->bi_vcnt++;
@@ -1393,7 +1370,7 @@
 		bvec->bv_len = PAGE_CACHE_SIZE;
 		bvec->bv_offset = 0;
 
-		atomic_inc(&PBP(pb)->pb_io_remaining);
+		atomic_inc(&pb->pb_io_remaining);
 		submit_bio(READ, bio);
 
 		goto io_submitted;
@@ -1426,8 +1403,8 @@
 	map_i = 0;
 
 next_chunk:
-	atomic_inc(&PBP(pb)->pb_io_remaining);
-	nr_pages = BIO_MAX_SECTORS >> (PAGE_SHIFT - SECTOR_SHIFT);
+	atomic_inc(&pb->pb_io_remaining);
+	nr_pages = BIO_MAX_SECTORS >> (PAGE_SHIFT - BBSHIFT);
 	if (nr_pages > total_nr_pages)
 		nr_pages = total_nr_pages;
 
@@ -1452,7 +1429,7 @@
 
 		offset = 0;
 
-		sector += nbytes >> SECTOR_SHIFT;
+		sector += nbytes >> BBSHIFT;
 		size -= nbytes;
 		total_nr_pages--;
 	}
@@ -1468,10 +1445,8 @@
 
 io_submitted:
 
-	if (atomic_dec_and_test(&PBP(pb)->pb_io_remaining) == 1) {
-		pagebuf_iodone(pb);
-	} else if ((pb->pb_flags & (PBF_SYNC|PBF_ASYNC)) == PBF_SYNC)  {
-		blk_run_queues();
+	if (atomic_dec_and_test(&pb->pb_io_remaining) == 1) {
+		pagebuf_iodone(pb, 0);
 	}
 
 	return status < 0 ? status : 0;
@@ -1489,7 +1464,7 @@
 	page_buf_t		*pb)
 {
 	PB_TRACE(pb, PB_TRACE_REC(iowait), 0);
-	blk_run_queues();
+	pagebuf_run_queues(pb);
 	down(&pb->pb_iodonesema);
 	PB_TRACE(pb, PB_TRACE_REC(iowaited), (int)pb->pb_error);
 	return pb->pb_error;
@@ -1622,9 +1597,8 @@
 			atomic_dec(&pb->pb_hold);
 		}
 		list_del(&pb->pb_list);
-	} else {
-		pb_daemon->pb_delwri_cnt++;
 	}
+
 	list_add_tail(&pb->pb_list, &pb_daemon->pb_delwrite_l);
 	PBP(pb)->pb_flushtime = jiffies + pb_params.p_un.age_buffer;
 	spin_unlock(&pb_daemon->pb_delwrite_lock);
@@ -1642,7 +1616,6 @@
 	spin_lock(&pb_daemon->pb_delwrite_lock);
 	list_del_init(&pb->pb_list);
 	pb->pb_flags &= ~PBF_DELWRI;
-	pb_daemon->pb_delwri_cnt--;
 	spin_unlock(&pb_daemon->pb_delwrite_lock);
 }
 
@@ -1725,8 +1698,7 @@
 
 		spin_unlock(&pb_daemon->pb_delwrite_lock);
 		while (!list_empty(&tmp)) {
-			pb = list_entry(tmp.next,
-							page_buf_t, pb_list);
+			pb = list_entry(tmp.next, page_buf_t, pb_list);
 			list_del_init(&pb->pb_list);
 			pb->pb_flags &= ~PBF_DELWRI;
 			pb->pb_flags |= PBF_WRITE;
@@ -1734,10 +1706,10 @@
 			__pagebuf_iorequest(pb);
 		}
 
-		if (count)
-			blk_run_queues();
 		if (as_list_len > 0)
 			purge_addresses();
+		if (count)
+			pagebuf_run_queues(NULL);
 
 		force_flush = 0;
 	} while (pb_daemon->active == 1);
@@ -1808,7 +1780,7 @@
 
 	spin_unlock(&pb_daemon->pb_delwrite_lock);
 
-	blk_run_queues();
+	pagebuf_run_queues(NULL);
 
 	if (pinptr)
 		*pinptr = pincount;
@@ -1838,8 +1810,6 @@
 		}
 
 		pb_daemon->active = 1;
-		pb_daemon->io_active = 1;
-		pb_daemon->pb_delwri_cnt = 0;
 		pb_daemon->pb_delwrite_lock = SPIN_LOCK_UNLOCKED;
 
 		INIT_LIST_HEAD(&pb_daemon->pb_delwrite_l);
@@ -1866,7 +1836,6 @@
 		destroy_workqueue(pagebuf_workqueue);
 
 		pb_daemon->active = 0;
-		pb_daemon->io_active = 0;
 
 		wake_up_interruptible(&pbd_waitq);
 		while (pb_daemon->active == 0) {
@@ -2011,14 +1980,8 @@
 	}
 
 #ifdef PAGEBUF_TRACE
-# if 1
 	pb_trace.buf = (pagebuf_trace_t *)kmalloc(
 			PB_TRACE_BUFSIZE * sizeof(pagebuf_trace_t), GFP_KERNEL);
-# else
-	/* Alternatively, for really really long trace bufs */
-	pb_trace.buf = (pagebuf_trace_t *)vmalloc(
-			PB_TRACE_BUFSIZE * sizeof(pagebuf_trace_t));
-# endif
 	memset(pb_trace.buf, 0, PB_TRACE_BUFSIZE * sizeof(pagebuf_trace_t));
 	pb_trace.start = 0;
 	pb_trace.end = PB_TRACE_BUFSIZE - 1;
diff -Nru a/fs/xfs/pagebuf/page_buf.h b/fs/xfs/pagebuf/page_buf.h
--- a/fs/xfs/pagebuf/page_buf.h	Mon Dec  9 18:46:38 2002
+++ b/fs/xfs/pagebuf/page_buf.h	Mon Dec  9 18:46:38 2002
@@ -47,7 +47,6 @@
 #include <linux/fs.h>
 #include <linux/buffer_head.h>
 #include <linux/uio.h>
-#include <linux/workqueue.h>
 
 enum xfs_buffer_state { BH_Delay = BH_PrivateStart };
 BUFFER_FNS(Delay, delay);
@@ -132,11 +131,12 @@
 #define PBR_ALIGNED_ONLY 2	/* only use aligned I/O */
 
 typedef struct pb_target {
-	int			pbr_flags;
 	dev_t			pbr_dev;
 	struct block_device	*pbr_bdev;
 	struct address_space	*pbr_mapping;
-	unsigned int		pbr_blocksize;
+	unsigned int		pbr_bsize;
+	unsigned int		pbr_sshift;
+	size_t			pbr_smask;
 } pb_target_t;
 
 /*
@@ -175,7 +175,7 @@
  * This buffer structure is used by the page cache buffer management routines
  * to refer to an assembly of pages forming a logical buffer.  The actual
  * I/O is performed with buffer_head or bio structures, as required by drivers,
- * for drivers which do not understand this structure.  The buffer structure is
+ * for drivers which do not understand this structure. The buffer structure is
  * used on temporary basis only, and discarded when released.  
  *
  * The real data storage is recorded in the page cache.	 Metadata is
@@ -206,6 +206,7 @@
 	size_t			pb_count_desired; /* desired transfer size */
 	void			*pb_addr;	/* virtual address of buffer */
 	struct work_struct	pb_iodone_work;
+	atomic_t		pb_io_remaining;/* #outstanding I/O requests */
 	page_buf_iodone_t	pb_iodone;	/* I/O completion function */
 	page_buf_relse_t	pb_relse;	/* releasing function */
 	page_buf_bdstrat_t	pb_strat;	/* pre-write function */
@@ -295,8 +296,6 @@
 extern int pagebuf_lock(		/* lock buffer			*/
 		page_buf_t *);		/* buffer to lock		*/
 
-extern void pagebuf_target_clear(struct pb_target *);
-
 extern void pagebuf_unlock(		/* unlock buffer		*/
 		page_buf_t *);		/* buffer to unlock		*/
 
@@ -307,7 +306,9 @@
 }
 
 extern void pagebuf_iodone(		/* mark buffer I/O complete	*/
-		page_buf_t *);		/* buffer to mark		*/
+		page_buf_t *,		/* buffer to mark		*/
+		int);			/* run completion locally, or in
+					 * a helper thread. 		*/
 
 extern void pagebuf_ioerror(		/* mark buffer in error (or not) */
 		page_buf_t *,		/* buffer to mark		*/
@@ -376,6 +377,10 @@
 	return pagebuf_iorequest(pb);
 }
 
-extern struct workqueue_struct *pagebuf_workqueue;
+static __inline__ void pagebuf_run_queues(page_buf_t *pb)
+{
+	if (!pb || atomic_read(&pb->pb_io_remaining))
+		blk_run_queues();
+}
 
 #endif /* __PAGE_BUF_H__ */
diff -Nru a/fs/xfs/pagebuf/page_buf_internal.h b/fs/xfs/pagebuf/page_buf_internal.h
--- a/fs/xfs/pagebuf/page_buf_internal.h	Mon Dec  9 18:46:37 2002
+++ b/fs/xfs/pagebuf/page_buf_internal.h	Mon Dec  9 18:46:37 2002
@@ -52,7 +52,6 @@
 	page_buf_t		pb_common;	/* public part of structure */
 	struct semaphore	pb_sema;	/* semaphore for lockables  */
 	unsigned long		pb_flushtime;	/* time to flush pagebuf    */
-	atomic_t		pb_io_remaining;/* #outstanding I/O requests */
 	atomic_t		pb_pin_count;	/* pin count		    */
 	wait_queue_head_t	pb_waiters;	/* unpin waiters	    */
 #ifdef PAGEBUF_LOCK_TRACKING
@@ -98,10 +97,8 @@
 
 typedef struct pagebuf_daemon {
 	int			active;
-	int			io_active;
 	spinlock_t		pb_delwrite_lock;
 	struct list_head	pb_delwrite_l;
-	int			pb_delwri_cnt;
 } pagebuf_daemon_t;
 
 /*
diff -Nru a/fs/xfs/pagebuf/page_buf_locking.c b/fs/xfs/pagebuf/page_buf_locking.c
--- a/fs/xfs/pagebuf/page_buf_locking.c	Mon Dec  9 18:46:38 2002
+++ b/fs/xfs/pagebuf/page_buf_locking.c	Mon Dec  9 18:46:38 2002
@@ -113,20 +113,11 @@
 	ASSERT(pb->pb_flags & _PBF_LOCKABLE);
 
 	PB_TRACE(pb, PB_TRACE_REC(lock), 0);
-	if (atomic_read(&PBP(pb)->pb_io_remaining))
-		blk_run_queues();
+	pagebuf_run_queues(pb);
 	down(&PBP(pb)->pb_sema);
 	PB_SET_OWNER(pb);
 	PB_TRACE(pb, PB_TRACE_REC(locked), 0);
 	return 0;
-}
-
-void
-pagebuf_target_clear(
-	pb_target_t		*target)
-{
-	invalidate_bdev(target->pbr_bdev, 1);
-	truncate_inode_pages(target->pbr_mapping, 0LL);
 }
 
 /*
diff -Nru a/fs/xfs/support/move.c b/fs/xfs/support/move.c
--- a/fs/xfs/support/move.c	Mon Dec  9 18:46:38 2002
+++ b/fs/xfs/support/move.c	Mon Dec  9 18:46:38 2002
@@ -30,6 +30,7 @@
  * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
  */
 
+#include <linux/errno.h>
 #include <asm/uaccess.h>
 
 #include <xfs_types.h>
diff -Nru a/fs/xfs/support/mrlock.c b/fs/xfs/support/mrlock.c
--- a/fs/xfs/support/mrlock.c	Mon Dec  9 18:46:34 2002
+++ b/fs/xfs/support/mrlock.c	Mon Dec  9 18:46:34 2002
@@ -87,7 +87,7 @@
 {
 	DECLARE_WAITQUEUE( wait, current );
 
-	set_current_state(TASK_UNINTERRUPTIBLE);
+	__set_current_state(TASK_UNINTERRUPTIBLE);
 
 	spin_lock(&q->lock);
 	if (rw) {
@@ -100,8 +100,6 @@
 	spin_unlock(lock);
 
 	schedule();
-
-	set_current_state(TASK_RUNNING);
 
 	spin_lock(&q->lock);
 	__remove_wait_queue(q, &wait);
diff -Nru a/fs/xfs/support/sv.h b/fs/xfs/support/sv.h
--- a/fs/xfs/support/sv.h	Mon Dec  9 18:46:35 2002
+++ b/fs/xfs/support/sv.h	Mon Dec  9 18:46:35 2002
@@ -60,12 +60,11 @@
 	DECLARE_WAITQUEUE(wait, current);
 
 	add_wait_queue_exclusive(&sv->waiters, &wait);
-	set_current_state(state);
+	__set_current_state(state);
 	spin_unlock(lock);
 
 	schedule_timeout(timeout);
 
-	set_current_state(TASK_RUNNING);
 	remove_wait_queue(&sv->waiters, &wait);
 }
 
diff -Nru a/fs/xfs/xfs.h b/fs/xfs/xfs.h
--- a/fs/xfs/xfs.h	Mon Dec  9 18:46:35 2002
+++ b/fs/xfs/xfs.h	Mon Dec  9 18:46:35 2002
@@ -33,6 +33,7 @@
 #define __XFS_H__
 
 #include <linux/config.h>
+#include <linux/types.h>
 
 #include <xfs_types.h>
 #include <xfs_arch.h>
diff -Nru a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
--- a/fs/xfs/xfs_acl.c	Mon Dec  9 18:46:36 2002
+++ b/fs/xfs/xfs_acl.c	Mon Dec  9 18:46:36 2002
@@ -235,7 +235,7 @@
 		if (kind == _ACL_TYPE_ACCESS) {
 			vattr_t va;
 
-			va.va_mask = AT_MODE;
+			va.va_mask = XFS_AT_MODE;
 			VOP_GETATTR(vp, &va, 0, sys_cred, error);
 			if (error)
 				goto out;
@@ -372,7 +372,7 @@
 		return EROFS;
 	if ((error = _MAC_VACCESS(vp, NULL, VWRITE)))
 		return error;
-	va.va_mask = AT_UID;
+	va.va_mask = XFS_AT_UID;
 	VOP_GETATTR(vp, &va, 0, NULL, error);
 	if (error)
 		return error;
@@ -702,7 +702,7 @@
 		xfs_acl_get_attr(vp, access_acl, _ACL_TYPE_ACCESS, 0, &error);
 		if (!error) {
 			/* Got the ACL, need the mode... */
-			va.va_mask = AT_MODE;
+			va.va_mask = XFS_AT_MODE;
 			VOP_GETATTR(vp, &va, 0, sys_cred, error);
 		}
 
@@ -800,12 +800,12 @@
 	 * Copy the u::, g::, o::, and m:: bits from the ACL into the
 	 * mode.  The m:: bits take precedence over the g:: bits.
 	 */
-	va.va_mask = AT_MODE;
+	va.va_mask = XFS_AT_MODE;
 	VOP_GETATTR(vp, &va, 0, sys_cred, error);
 	if (error)
 		return error;
 
-	va.va_mask = AT_MODE;
+	va.va_mask = XFS_AT_MODE;
 	va.va_mode &= ~(S_IRWXU|S_IRWXG|S_IRWXO);
 	ap = acl->acl_entry;
 	for (i = 0; i < acl->acl_cnt; ++i) {
diff -Nru a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h
--- a/fs/xfs/xfs_ag.h	Mon Dec  9 18:46:50 2002
+++ b/fs/xfs/xfs_ag.h	Mon Dec  9 18:46:50 2002
@@ -109,12 +109,12 @@
 #define XFS_AGF_ALL_BITS	((1 << XFS_AGF_NUM_BITS) - 1)
 
 /* disk block (xfs_daddr_t) in the AG */
-#define XFS_AGF_DADDR		((xfs_daddr_t)1)
+#define XFS_AGF_DADDR(mp)	((xfs_daddr_t)(1 << (mp)->m_sectbb_log))
 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_AGF_BLOCK)
 xfs_agblock_t xfs_agf_block(struct xfs_mount *mp);
 #define XFS_AGF_BLOCK(mp)	xfs_agf_block(mp)
 #else
-#define XFS_AGF_BLOCK(mp)	XFS_HDR_BLOCK(mp, XFS_AGF_DADDR)
+#define XFS_AGF_BLOCK(mp)	XFS_HDR_BLOCK(mp, XFS_AGF_DADDR(mp))
 #endif
 
 /*
@@ -164,29 +164,30 @@
 #define XFS_AGI_ALL_BITS	((1 << XFS_AGI_NUM_BITS) - 1)
 
 /* disk block (xfs_daddr_t) in the AG */
-#define XFS_AGI_DADDR		((xfs_daddr_t)2)
+#define XFS_AGI_DADDR(mp)	((xfs_daddr_t)(2 << (mp)->m_sectbb_log))
 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_AGI_BLOCK)
 xfs_agblock_t xfs_agi_block(struct xfs_mount *mp);
 #define XFS_AGI_BLOCK(mp)	xfs_agi_block(mp)
 #else
-#define XFS_AGI_BLOCK(mp)	XFS_HDR_BLOCK(mp, XFS_AGI_DADDR)
+#define XFS_AGI_BLOCK(mp)	XFS_HDR_BLOCK(mp, XFS_AGI_DADDR(mp))
 #endif
 
 /*
  * The third a.g. block contains the a.g. freelist, an array
  * of block pointers to blocks owned by the allocation btree code.
  */
-#define XFS_AGFL_DADDR		((xfs_daddr_t)3)
+#define XFS_AGFL_DADDR(mp)	((xfs_daddr_t)(3 << (mp)->m_sectbb_log))
 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_AGFL_BLOCK)
 xfs_agblock_t xfs_agfl_block(struct xfs_mount *mp);
 #define XFS_AGFL_BLOCK(mp)	xfs_agfl_block(mp)
 #else
-#define XFS_AGFL_BLOCK(mp)	XFS_HDR_BLOCK(mp, XFS_AGFL_DADDR)
+#define XFS_AGFL_BLOCK(mp)	XFS_HDR_BLOCK(mp, XFS_AGFL_DADDR(mp))
 #endif
-#define XFS_AGFL_SIZE		(BBSIZE / sizeof(xfs_agblock_t))
-typedef struct xfs_agfl
-{
-	xfs_agblock_t	agfl_bno[XFS_AGFL_SIZE];
+#define XFS_AGFL_SIZE(mp)	((mp)->m_sb.sb_sectsize / sizeof(xfs_agblock_t))
+
+/* -- nathans TODO ... use of BBSIZE here - should be sector size -- */
+typedef struct xfs_agfl {
+	xfs_agblock_t	agfl_bno[BBSIZE/sizeof(xfs_agblock_t)];
 } xfs_agfl_t;
 
 /*
@@ -244,15 +245,15 @@
 xfs_extlen_t xfs_ag_best_blocks(int bl, xfs_drfsbno_t blks);
 #define XFS_AG_BEST_BLOCKS(bl,blks)	xfs_ag_best_blocks(bl,blks)
 #else
-/*--#define	XFS_AG_BEST_BLOCKS(bl)	((xfs_extlen_t)(XFS_AG_BEST_BYTES >> bl))*/
+/*--#define XFS_AG_BEST_BLOCKS(bl) ((xfs_extlen_t)(XFS_AG_BEST_BYTES >> bl))*/
 /*
  * Best is XFS_AG_BEST_BLOCKS at and below 64 Gigabyte filesystems, and
  * XFS_AG_MAX_BLOCKS above 64 Gigabytes.
  */
-#define XFS_AG_BEST_BLOCKS(bl,blks)	((xfs_extlen_t)((1LL << (36 - bl)) >= \
-							blks) ? \
-							((xfs_extlen_t)(XFS_AG_BEST_BYTES >> bl)) : \
-							XFS_AG_MAX_BLOCKS(bl))
+#define XFS_AG_BEST_BLOCKS(bl,blks)	\
+	((xfs_extlen_t)((1LL << (36 - bl)) >= blks) ? \
+		((xfs_extlen_t)(XFS_AG_BEST_BYTES >> bl)) : \
+		XFS_AG_MAX_BLOCKS(bl))
 #endif
 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_AG_MAX_BLOCKS)
 xfs_extlen_t xfs_ag_max_blocks(int bl);
@@ -320,7 +321,7 @@
 
 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_AGB_TO_DADDR)
 xfs_daddr_t xfs_agb_to_daddr(struct xfs_mount *mp, xfs_agnumber_t agno,
-			 xfs_agblock_t agbno);
+				xfs_agblock_t agbno);
 #define XFS_AGB_TO_DADDR(mp,agno,agbno) xfs_agb_to_daddr(mp,agno,agbno)
 #else
 #define XFS_AGB_TO_DADDR(mp,agno,agbno) \
@@ -333,7 +334,8 @@
  */
 
 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_AG_DADDR)
-xfs_daddr_t xfs_ag_daddr(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_daddr_t d);
+xfs_daddr_t xfs_ag_daddr(struct xfs_mount *mp, xfs_agnumber_t agno,
+				xfs_daddr_t d);
 #define XFS_AG_DADDR(mp,agno,d)		xfs_ag_daddr(mp,agno,d)
 #else
 #define XFS_AG_DADDR(mp,agno,d) (XFS_AGB_TO_DADDR(mp, agno, 0) + (d))
diff -Nru a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
--- a/fs/xfs/xfs_alloc.c	Mon Dec  9 18:46:35 2002
+++ b/fs/xfs/xfs_alloc.c	Mon Dec  9 18:46:35 2002
@@ -399,12 +399,14 @@
 	xfs_buf_t	**bpp)		/* buffer for the ag free block array */
 {
 	xfs_buf_t	*bp;		/* return value */
-	xfs_daddr_t	d;		/* disk block address */
 	int		error;
 
 	ASSERT(agno != NULLAGNUMBER);
-	d = XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR);
-	if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d, 1, 0, &bp)))
+	error = xfs_trans_read_buf(
+			mp, tp, mp->m_ddev_targp,
+			XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)),
+			XFS_FSS_TO_BB(mp, 1), 0, &bp);
+	if (error)
 		return error;
 	ASSERT(bp);
 	ASSERT(!XFS_BUF_GETERROR(bp));
@@ -1821,9 +1823,8 @@
 /*
  * Decide whether to use this allocation group for this allocation.
  * If so, fix up the btree freelist's size.
- * This is external so mkfs can call it, too.
  */
-int				/* error */
+STATIC int			/* error */
 xfs_alloc_fix_freelist(
 	xfs_alloc_arg_t *args,	/* allocation argument structure */
 	int		flags)	/* XFS_ALLOC_FLAG_... */
@@ -2020,7 +2021,7 @@
 	bno = INT_GET(agfl->agfl_bno[INT_GET(agf->agf_flfirst, ARCH_CONVERT)], ARCH_CONVERT);
 	INT_MOD(agf->agf_flfirst, ARCH_CONVERT, 1);
 	xfs_trans_brelse(tp, agflbp);
-	if (INT_GET(agf->agf_flfirst, ARCH_CONVERT) == XFS_AGFL_SIZE)
+	if (INT_GET(agf->agf_flfirst, ARCH_CONVERT) == XFS_AGFL_SIZE(mp))
 		INT_ZERO(agf->agf_flfirst, ARCH_CONVERT);
 	pag = &mp->m_perag[INT_GET(agf->agf_seqno, ARCH_CONVERT)];
 	INT_MOD(agf->agf_flcount, ARCH_CONVERT, -1);
@@ -2120,13 +2121,13 @@
 		return error;
 	agfl = XFS_BUF_TO_AGFL(agflbp);
 	INT_MOD(agf->agf_fllast, ARCH_CONVERT, 1);
-	if (INT_GET(agf->agf_fllast, ARCH_CONVERT) == XFS_AGFL_SIZE)
+	if (INT_GET(agf->agf_fllast, ARCH_CONVERT) == XFS_AGFL_SIZE(mp))
 		INT_ZERO(agf->agf_fllast, ARCH_CONVERT);
 	pag = &mp->m_perag[INT_GET(agf->agf_seqno, ARCH_CONVERT)];
 	INT_MOD(agf->agf_flcount, ARCH_CONVERT, 1);
 	xfs_trans_agflist_delta(tp, 1);
 	pag->pagf_flcount++;
-	ASSERT(INT_GET(agf->agf_flcount, ARCH_CONVERT) <= XFS_AGFL_SIZE);
+	ASSERT(INT_GET(agf->agf_flcount, ARCH_CONVERT) <= XFS_AGFL_SIZE(mp));
 	blockp = &agfl->agfl_bno[INT_GET(agf->agf_fllast, ARCH_CONVERT)];
 	INT_SET(*blockp, ARCH_CONVERT, bno);
 	TRACE_MODAGF(NULL, agf, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT);
@@ -2152,15 +2153,17 @@
 	xfs_agf_t	*agf;		/* ag freelist header */
 	int		agf_ok;		/* set if agf is consistent */
 	xfs_buf_t	*bp;		/* return value */
-	xfs_daddr_t	d;		/* disk block address */
-	int		error;
 	xfs_perag_t	*pag;		/* per allocation group data */
+	int		error;
 
 	ASSERT(agno != NULLAGNUMBER);
-	d = XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR);
-	if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d, 1,
+	error = xfs_trans_read_buf(
+			mp, tp, mp->m_ddev_targp,
+			XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
+			XFS_FSS_TO_BB(mp, 1),
 			(flags & XFS_ALLOC_FLAG_TRYLOCK) ? XFS_BUF_TRYLOCK : 0U,
-			&bp)))
+			&bp);
+	if (error)
 		return error;
 	ASSERT(!bp || !XFS_BUF_GETERROR(bp));
 	if (!bp) {
@@ -2173,12 +2176,13 @@
 	agf = XFS_BUF_TO_AGF(bp);
 	agf_ok =
 		INT_GET(agf->agf_magicnum, ARCH_CONVERT) == XFS_AGF_MAGIC &&
-		XFS_AGF_GOOD_VERSION(INT_GET(agf->agf_versionnum, ARCH_CONVERT)) &&
+		XFS_AGF_GOOD_VERSION(
+			INT_GET(agf->agf_versionnum, ARCH_CONVERT)) &&
 		INT_GET(agf->agf_freeblks, ARCH_CONVERT) <=
 				INT_GET(agf->agf_length, ARCH_CONVERT) &&
-		INT_GET(agf->agf_flfirst, ARCH_CONVERT) < XFS_AGFL_SIZE &&
-		INT_GET(agf->agf_fllast,  ARCH_CONVERT) < XFS_AGFL_SIZE &&
-		INT_GET(agf->agf_flcount, ARCH_CONVERT) <= XFS_AGFL_SIZE;
+		INT_GET(agf->agf_flfirst, ARCH_CONVERT) < XFS_AGFL_SIZE(mp) &&
+		INT_GET(agf->agf_fllast,  ARCH_CONVERT) < XFS_AGFL_SIZE(mp) &&
+		INT_GET(agf->agf_flcount, ARCH_CONVERT) <= XFS_AGFL_SIZE(mp);
 	if (XFS_TEST_ERROR(!agf_ok, mp, XFS_ERRTAG_ALLOC_READ_AGF,
 			XFS_RANDOM_ALLOC_READ_AGF)) {
 		xfs_trans_brelse(tp, bp);
@@ -2197,13 +2201,13 @@
 			cmn_err(CE_NOTE, "Bad freeblks %d %d",
 				INT_GET(agf->agf_freeblks, ARCH_CONVERT),
 				INT_GET(agf->agf_length, ARCH_CONVERT));
-		if (!(INT_GET(agf->agf_flfirst, ARCH_CONVERT) < XFS_AGFL_SIZE))
+		if (!(INT_GET(agf->agf_flfirst, ARCH_CONVERT) < XFS_AGFL_SIZE(mp)))
 			cmn_err(CE_NOTE, "Bad flfirst %d",
 				INT_GET(agf->agf_flfirst, ARCH_CONVERT));
-		if (!(INT_GET(agf->agf_fllast, ARCH_CONVERT) < XFS_AGFL_SIZE))
+		if (!(INT_GET(agf->agf_fllast, ARCH_CONVERT) < XFS_AGFL_SIZE(mp)))
 			cmn_err(CE_NOTE, "Bad fllast %d",
 				INT_GET(agf->agf_fllast, ARCH_CONVERT));
-		if (!(INT_GET(agf->agf_flcount, ARCH_CONVERT) <= XFS_AGFL_SIZE))
+		if (!(INT_GET(agf->agf_flcount, ARCH_CONVERT) <= XFS_AGFL_SIZE(mp)))
 			cmn_err(CE_NOTE, "Bad flcount %d",
 				INT_GET(agf->agf_flcount, ARCH_CONVERT));
 #endif
diff -Nru a/fs/xfs/xfs_alloc.h b/fs/xfs/xfs_alloc.h
--- a/fs/xfs/xfs_alloc.h	Mon Dec  9 18:46:36 2002
+++ b/fs/xfs/xfs_alloc.h	Mon Dec  9 18:46:36 2002
@@ -131,16 +131,6 @@
 	struct xfs_mount	*mp);	/* file system mount structure */
 
 /*
- * Decide whether to use this allocation group for this allocation.
- * If so, fix up the btree freelist's size.
- * This is external so mkfs can call it, too.
- */
-int				/* error */
-xfs_alloc_fix_freelist(
-	xfs_alloc_arg_t *args,	/* allocation argument structure */
-	int		flags); /* XFS_ALLOC_FLAG_... */
-
-/*
  * Get a block from the freelist.
  * Returns with the buffer for the block gotten.
  */
diff -Nru a/fs/xfs/xfs_alloc_btree.h b/fs/xfs/xfs_alloc_btree.h
--- a/fs/xfs/xfs_alloc_btree.h	Mon Dec  9 18:46:51 2002
+++ b/fs/xfs/xfs_alloc_btree.h	Mon Dec  9 18:46:51 2002
@@ -96,16 +96,22 @@
 #endif
 
 /*
- * Minimum and maximum blocksize.
+ * Minimum and maximum blocksize and sectorsize.
  * The blocksize upper limit is pretty much arbitrary.
+ * The sectorsize upper limit is due to sizeof(sb_sectsize).
  */
 #define XFS_MIN_BLOCKSIZE_LOG	9	/* i.e. 512 bytes */
 #define XFS_MAX_BLOCKSIZE_LOG	16	/* i.e. 65536 bytes */
 #define XFS_MIN_BLOCKSIZE	(1 << XFS_MIN_BLOCKSIZE_LOG)
 #define XFS_MAX_BLOCKSIZE	(1 << XFS_MAX_BLOCKSIZE_LOG)
+#define XFS_MIN_SECTORSIZE_LOG	9       /* i.e. 512 bytes */
+#define XFS_MAX_SECTORSIZE_LOG	15      /* i.e. 32768 bytes */
+#define XFS_MIN_SECTORSIZE	(1 << XFS_MIN_SECTORSIZE_LOG)
+#define XFS_MAX_SECTORSIZE	(1 << XFS_MAX_SECTORSIZE_LOG)
 
 /*
- * block numbers in the AG; SB is BB 0, AGF is BB 1, AGI is BB 2, AGFL is BB 3
+ * Block numbers in the AG:
+ * SB is sector 0, AGF is sector 1, AGI is sector 2, AGFL is sector 3.
  */
 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BNO_BLOCK)
 xfs_agblock_t xfs_bno_block(struct xfs_mount *mp);
diff -Nru a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
--- a/fs/xfs/xfs_attr_leaf.c	Mon Dec  9 18:46:37 2002
+++ b/fs/xfs/xfs_attr_leaf.c	Mon Dec  9 18:46:37 2002
@@ -2897,7 +2897,7 @@
 						map.br_blockcount);
 			bp = xfs_trans_get_buf(*trans,
 					dp->i_mount->m_ddev_targp,
-					dblkno, dblkcnt, 0);
+					dblkno, dblkcnt, XFS_BUF_LOCK);
 			xfs_trans_binval(*trans, bp);
 			/*
 			 * Roll to next transaction.
diff -Nru a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
--- a/fs/xfs/xfs_bmap.c	Mon Dec  9 18:46:51 2002
+++ b/fs/xfs/xfs_bmap.c	Mon Dec  9 18:46:51 2002
@@ -5526,14 +5526,13 @@
 	int			bmapi_flags;	/* flags for xfs_bmapi */
 	__int32_t		oflags;		/* getbmapx bmv_oflags field */
 
-	ip = XFS_BHVTOI(bdp);
 	vp = BHV_TO_VNODE(bdp);
+	ip = XFS_BHVTOI(bdp);
+	mp = ip->i_mount;
 
-	whichfork = interface & BMV_IF_ATTRFORK ?
-				XFS_ATTR_FORK : XFS_DATA_FORK;
+	whichfork = interface & BMV_IF_ATTRFORK ? XFS_ATTR_FORK : XFS_DATA_FORK;
 	sh_unwritten = (interface & BMV_IF_PREALLOC) != 0;
 
-
 	/*	If the BMV_IF_NO_DMAPI_READ interface bit specified, do not
 	 *	generate a DMAPI read event.  Otherwise, if the DM_EVENT_READ
 	 *	bit is set for the file, generate a read event in order
@@ -5575,8 +5574,6 @@
 		   ip->i_d.di_format != XFS_DINODE_FMT_LOCAL)
 		return XFS_ERROR(EINVAL);
 
-	mp = ip->i_mount;
-
 	if (whichfork == XFS_DATA_FORK) {
 		if (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC) {
 			prealloced = 1;
@@ -5600,18 +5597,15 @@
 		bmv->bmv_entries = 0;
 		return 0;
 	}
-
 	nex = bmv->bmv_count - 1;
-
 	if (nex <= 0)
 		return XFS_ERROR(EINVAL);
-
 	bmvend = bmv->bmv_offset + bmv->bmv_length;
 
 	xfs_ilock(ip, XFS_IOLOCK_SHARED);
 
 	if (whichfork == XFS_DATA_FORK && ip->i_delayed_blks) {
-
+		/* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */
 		VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 0, FI_REMAPF, error);
 	}
 
@@ -5629,11 +5623,10 @@
 	bmapi_flags = XFS_BMAPI_AFLAG(whichfork) |
 			((sh_unwritten) ? 0 : XFS_BMAPI_IGSTATE);
 
-	subnex = 16;	/* XXXjtk - need a #define?	*/
-
 	/*
 	 * Allocate enough space to handle "subnex" maps at a time.
 	 */
+	subnex = 16;
 	map = kmem_alloc(subnex * sizeof(*map), KM_SLEEP);
 
 	bmv->bmv_entries = 0;
@@ -5646,77 +5639,63 @@
 	nexleft = nex;
 
 	do {
-	    if (nexleft > subnex)
-		    nmap = subnex;
-	    else
-		    nmap = nexleft;
-
-	    error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset),
-					XFS_BB_TO_FSB(mp, bmv->bmv_length),
-					bmapi_flags, NULL, 0,
-					map, &nmap, NULL);
-	    ASSERT(nmap <= subnex);
-
-	    if (error)
-		    goto unlock_and_return;
-
-	    for (error = i = 0; i < nmap && nexleft && bmv->bmv_length; i++) {
-		nexleft--;
-
-		oflags = 0;
-
-		out.bmv_offset = XFS_FSB_TO_BB(mp, map[i].br_startoff);
-		out.bmv_length = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
-
-		ASSERT(map[i].br_startblock != DELAYSTARTBLOCK);
-
-		if (   prealloced
-		    && map[i].br_startblock == HOLESTARTBLOCK
-		    && out.bmv_offset + out.bmv_length == bmvend) {
-			/*
-			 * came to hole at end of file
-			 */
+		nmap = (nexleft > subnex) ? subnex : nexleft;
+		error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset),
+				  XFS_BB_TO_FSB(mp, bmv->bmv_length),
+				  bmapi_flags, NULL, 0, map, &nmap, NULL);
+		if (error)
 			goto unlock_and_return;
-		} else {
-			if (map[i].br_startblock == HOLESTARTBLOCK)
-				out.bmv_block = -1;
-			else
-				out.bmv_block =
-					XFS_FSB_TO_DB(ip, map[i].br_startblock);
-
-			/* return either a getbmap or a getbmapx structure. */
-
-			if (interface & BMV_IF_EXTENDED) {
-				struct	getbmapx	outx;
-
-				GETBMAP_CONVERT(out,outx);
+		ASSERT(nmap <= subnex);
 
-				outx.bmv_oflags = oflags;
-				outx.bmv_unused1 = outx.bmv_unused2 = 0;
-
-				if (copy_to_user(ap, &outx, sizeof(outx))) {
-					error = XFS_ERROR(EFAULT);
-					goto unlock_and_return;
-				}
+		for (i = 0; i < nmap && nexleft && bmv->bmv_length; i++) {
+			nexleft--;
+			oflags = (map[i].br_state == XFS_EXT_UNWRITTEN) ?
+					BMV_OF_PREALLOC : 0;
+			out.bmv_offset = XFS_FSB_TO_BB(mp, map[i].br_startoff);
+			out.bmv_length = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
+			ASSERT(map[i].br_startblock != DELAYSTARTBLOCK);
+			if (prealloced &&
+			    map[i].br_startblock == HOLESTARTBLOCK &&
+			    out.bmv_offset + out.bmv_length == bmvend) {
+				/*
+				 * came to hole at end of file
+				 */
+				goto unlock_and_return;
 			} else {
-				if (copy_to_user(ap, &out, sizeof(out))) {
-					error = XFS_ERROR(EFAULT);
-					goto unlock_and_return;
+				out.bmv_block = 
+				    (map[i].br_startblock == HOLESTARTBLOCK) ?
+					-1 :
+					XFS_FSB_TO_DB(ip, map[i].br_startblock);
+
+				/* return either getbmap/getbmapx structure. */
+				if (interface & BMV_IF_EXTENDED) {
+					struct	getbmapx	outx;
+
+					GETBMAP_CONVERT(out,outx);
+					outx.bmv_oflags = oflags;
+					outx.bmv_unused1 = outx.bmv_unused2 = 0;
+					if (copy_to_user(ap, &outx,
+							sizeof(outx))) {
+						error = XFS_ERROR(EFAULT);
+						goto unlock_and_return;
+					}
+				} else {
+					if (copy_to_user(ap, &out,
+							sizeof(out))) {
+						error = XFS_ERROR(EFAULT);
+						goto unlock_and_return;
+					}
 				}
+				bmv->bmv_offset =
+					out.bmv_offset + out.bmv_length;
+				bmv->bmv_length = MAX((__int64_t)0,
+					(__int64_t)(bmvend - bmv->bmv_offset));
+				bmv->bmv_entries++;
+				ap = (interface & BMV_IF_EXTENDED) ?
+					(void *)((struct getbmapx *)ap + 1) :
+					(void *)((struct getbmap *)ap + 1);
 			}
-
-			bmv->bmv_offset = out.bmv_offset + out.bmv_length;
-			bmv->bmv_length = MAX( (__int64_t)0,
-					(__int64_t)(bmvend - bmv->bmv_offset) );
-
-			bmv->bmv_entries++;
-
-			if (interface & BMV_IF_EXTENDED)
-				ap = (void *)((struct getbmapx *)ap + 1);
-			else
-				ap = (void *)((struct getbmap *)ap + 1);
 		}
-	    }
 	} while (nmap && nexleft && bmv->bmv_length);
 
 unlock_and_return:
diff -Nru a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h
--- a/fs/xfs/xfs_bmap_btree.h	Mon Dec  9 18:46:37 2002
+++ b/fs/xfs/xfs_bmap_btree.h	Mon Dec  9 18:46:37 2002
@@ -167,7 +167,7 @@
   (XFS_SB_VERSION_HASEXTFLGBIT(&((x)->i_mount->m_sb)) ? \
 	XFS_EXTFMT_HASSTATE : XFS_EXTFMT_NOSTATE)
 #endif
-#define ISUNWRITTEN(x)		((x) == XFS_EXT_UNWRITTEN)
+#define ISUNWRITTEN(x)	((x)->br_state == XFS_EXT_UNWRITTEN)
 
 /*
  * Incore version of above.
diff -Nru a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
--- a/fs/xfs/xfs_buf.h	Mon Dec  9 18:46:51 2002
+++ b/fs/xfs/xfs_buf.h	Mon Dec  9 18:46:51 2002
@@ -107,8 +107,8 @@
 #define XFS_BUF_UNWRITE(x)	((x)->pb_flags &= ~PBF_WRITE)
 #define XFS_BUF_ISWRITE(x)	((x)->pb_flags & PBF_WRITE)
 
-#define XFS_BUF_ISUNINITIAL(x)	 ((x)->pb_flags & PBF_UNINITIAL)
-#define XFS_BUF_UNUNINITIAL(x)	 ((x)->pb_flags &= ~PBF_UNINITIAL)
+#define XFS_BUF_ISUNINITIAL(x)	 (0)
+#define XFS_BUF_UNUNINITIAL(x)	 (0)
 
 #define XFS_BUF_BP_ISMAPPED(bp)	 1
 
@@ -182,6 +182,7 @@
 #define XFS_BUF_SET_TARGET(bp, target)	\
 	(bp)->pb_target = (target)
 
+#define XFS_BUF_TARGET(bp)	((bp)->pb_target)
 #define XFS_BUF_TARGET_DEV(bp)	((bp)->pb_target->pbr_dev)
 #define XFS_BUF_SET_VTYPE_REF(bp, type, ref)
 #define XFS_BUF_SET_VTYPE(bp, type)
@@ -209,7 +210,7 @@
 	bp->pb_strat = xfs_bdstrat_cb;
 	xfs_buf_undelay(bp);
 	if ((ret = pagebuf_iostart(bp, PBF_WRITE | PBF_ASYNC)) == 0)
-		blk_run_queues();
+		pagebuf_run_queues(bp);
 	return ret;
 }
 
@@ -235,7 +236,7 @@
 
 
 #define xfs_biodone(pb)		    \
-	    pagebuf_iodone(pb)
+	    pagebuf_iodone(pb, 0)
 
 #define xfs_incore(buftarg,blkno,len,lockit) \
 	    pagebuf_find(buftarg, blkno ,len, lockit)
@@ -264,7 +265,7 @@
 		error = pagebuf_iowait(pb);
 		xfs_buf_relse(pb);
 	} else {
-		blk_run_queues();
+		pagebuf_run_queues(pb);
 		error = 0;
 	}
 
@@ -299,8 +300,7 @@
 #define xfs_binval(buftarg) XFS_bflush(buftarg)
 
 #define xfs_incore_relse(buftarg,delwri_only,wait)	\
-       pagebuf_target_clear(buftarg)
-
+	xfs_relse_buftarg(buftarg)
 
 #define xfs_baread(target, rablkno, ralen)  \
 	pagebuf_readahead((target), (rablkno), \
diff -Nru a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
--- a/fs/xfs/xfs_buf_item.c	Mon Dec  9 18:46:34 2002
+++ b/fs/xfs/xfs_buf_item.c	Mon Dec  9 18:46:34 2002
@@ -902,9 +902,7 @@
 	XFS_BUF_SET_FSPRIVATE(bp, bip->bli_item.li_bio_list);
 	if ((XFS_BUF_FSPRIVATE(bp, void *) == NULL) &&
 	    (XFS_BUF_IODONE_FUNC(bp) != NULL)) {
-/**
 		ASSERT((XFS_BUF_ISUNINITIAL(bp)) == 0);
-***/
 		XFS_BUF_CLR_IODONE_FUNC(bp);
 	}
 
@@ -1005,7 +1003,7 @@
 		 */
 		mp = lip->li_mountp;
 		if (XFS_FORCED_SHUTDOWN(mp)) {
-			ASSERT(XFS_BUF_TARGET_DEV(bp) == mp->m_dev);
+			ASSERT(XFS_BUF_TARGET(bp) == mp->m_ddev_targp);
 			XFS_BUF_SUPER_STALE(bp);
 			xfs_buftrace("BUF_IODONE_CB", bp);
 			xfs_buf_do_callbacks(bp, lip);
@@ -1102,7 +1100,7 @@
 
 	lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *);
 	mp = (xfs_mount_t *)lip->li_mountp;
-	ASSERT(XFS_BUF_TARGET_DEV(bp) == mp->m_dev);
+	ASSERT(XFS_BUF_TARGET(bp) == mp->m_ddev_targp);
 
 	XFS_BUF_STALE(bp);
 	XFS_BUF_DONE(bp);
diff -Nru a/fs/xfs/xfs_cap.c b/fs/xfs/xfs_cap.c
--- a/fs/xfs/xfs_cap.c	Mon Dec  9 18:46:36 2002
+++ b/fs/xfs/xfs_cap.c	Mon Dec  9 18:46:36 2002
@@ -192,7 +192,7 @@
 		return EROFS;
 	if ((error = _MAC_VACCESS(vp, NULL, VWRITE)))
 		return error;
-	va.va_mask = AT_UID;
+	va.va_mask = XFS_AT_UID;
 	VOP_GETATTR(vp, &va, 0, NULL, error);
 	if (error)
 		return error;
diff -Nru a/fs/xfs/xfs_dir2.h b/fs/xfs/xfs_dir2.h
--- a/fs/xfs/xfs_dir2.h	Mon Dec  9 18:46:50 2002
+++ b/fs/xfs/xfs_dir2.h	Mon Dec  9 18:46:50 2002
@@ -32,7 +32,6 @@
 #ifndef __XFS_DIR2_H__
 #define __XFS_DIR2_H__
 
-struct dirent;
 struct uio;
 struct xfs_dabuf;
 struct xfs_da_args;
diff -Nru a/fs/xfs/xfs_dir2_block.h b/fs/xfs/xfs_dir2_block.h
--- a/fs/xfs/xfs_dir2_block.h	Mon Dec  9 18:46:51 2002
+++ b/fs/xfs/xfs_dir2_block.h	Mon Dec  9 18:46:51 2002
@@ -37,7 +37,6 @@
  * Directory version 2, single block format structures
  */
 
-struct dirent;
 struct uio;
 struct xfs_dabuf;
 struct xfs_da_args;
diff -Nru a/fs/xfs/xfs_dir2_leaf.h b/fs/xfs/xfs_dir2_leaf.h
--- a/fs/xfs/xfs_dir2_leaf.h	Mon Dec  9 18:46:34 2002
+++ b/fs/xfs/xfs_dir2_leaf.h	Mon Dec  9 18:46:34 2002
@@ -36,7 +36,6 @@
  * Directory version 2, leaf block structures.
  */
 
-struct dirent;
 struct uio;
 struct xfs_dabuf;
 struct xfs_da_args;
diff -Nru a/fs/xfs/xfs_dir2_node.h b/fs/xfs/xfs_dir2_node.h
--- a/fs/xfs/xfs_dir2_node.h	Mon Dec  9 18:46:51 2002
+++ b/fs/xfs/xfs_dir2_node.h	Mon Dec  9 18:46:51 2002
@@ -36,7 +36,6 @@
  * Directory version 2, btree node format structures
  */
 
-struct dirent;
 struct uio;
 struct xfs_dabuf;
 struct xfs_da_args;
diff -Nru a/fs/xfs/xfs_dir2_sf.h b/fs/xfs/xfs_dir2_sf.h
--- a/fs/xfs/xfs_dir2_sf.h	Mon Dec  9 18:46:35 2002
+++ b/fs/xfs/xfs_dir2_sf.h	Mon Dec  9 18:46:35 2002
@@ -39,7 +39,6 @@
  * fit into the literal area of the inode.
  */
 
-struct dirent;
 struct uio;
 struct xfs_dabuf;
 struct xfs_da_args;
diff -Nru a/fs/xfs/xfs_dir_leaf.h b/fs/xfs/xfs_dir_leaf.h
--- a/fs/xfs/xfs_dir_leaf.h	Mon Dec  9 18:46:35 2002
+++ b/fs/xfs/xfs_dir_leaf.h	Mon Dec  9 18:46:35 2002
@@ -42,7 +42,6 @@
  * internal links in the Btree are logical block offsets into the file.
  */
 
-struct dirent;
 struct uio;
 struct xfs_bmap_free;
 struct xfs_dabuf;
diff -Nru a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c
--- a/fs/xfs/xfs_error.c	Mon Dec  9 18:46:51 2002
+++ b/fs/xfs/xfs_error.c	Mon Dec  9 18:46:51 2002
@@ -224,11 +224,15 @@
 {
 	va_list ap;
 
+#ifdef DEBUG
+	xfs_panic_mask |= XFS_PTAG_SHUTDOWN_CORRUPT;
+#endif
+
 	if (xfs_panic_mask && (xfs_panic_mask & panic_tag)
 	    && (level & CE_ALERT)) {
 		level &= ~CE_ALERT;
 		level |= CE_PANIC;
-		cmn_err(CE_ALERT, "Transforming an alert into a panic.");
+		cmn_err(CE_ALERT, "XFS: Transforming an alert into a BUG.");
 	}
 	va_start(ap, fmt);
 	xfs_fs_vcmn_err(level, mp, fmt, ap);
diff -Nru a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h
--- a/fs/xfs/xfs_error.h	Mon Dec  9 18:46:50 2002
+++ b/fs/xfs/xfs_error.h	Mon Dec  9 18:46:50 2002
@@ -138,13 +138,18 @@
 
 /*
  * XFS panic tags -- allow a call to xfs_cmn_err() be turned into
- *			a panic by setting xfs_panic_mask in the
- *			stune file.
+ *			a panic by setting xfs_panic_mask in a
+ *			sysctl.  update xfs_max[XFS_PARAM] if
+ *			more are added.
  */
 #define		XFS_NO_PTAG			0LL
 #define		XFS_PTAG_IFLUSH			0x0000000000000001LL
 #define		XFS_PTAG_LOGRES			0x0000000000000002LL
 #define		XFS_PTAG_AILDELETE		0x0000000000000004LL
+#define		XFS_PTAG_AVAILABLE		0x0000000000000008LL
+#define		XFS_PTAG_SHUTDOWN_CORRUPT	0x0000000000000010LL
+#define		XFS_PTAG_SHUTDOWN_IOERROR	0x0000000000000020LL
+#define		XFS_PTAG_SHUTDOWN_LOGERROR	0x0000000000000040LL
 
 struct xfs_mount;
 /* PRINTFLIKE4 */
diff -Nru a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
--- a/fs/xfs/xfs_fs.h	Mon Dec  9 18:46:35 2002
+++ b/fs/xfs/xfs_fs.h	Mon Dec  9 18:46:35 2002
@@ -30,12 +30,8 @@
  *
  * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
  */
-#ifndef _LINUX_XFS_FS_H
-#define _LINUX_XFS_FS_H
-
-#include <linux/types.h>
-#include <asm/ioctl.h>
-
+#ifndef __XFS_FS_H__
+#define __XFS_FS_H__
 
 /*
  * SGI's XFS filesystem's major stuff (constants, structures)
@@ -229,15 +225,16 @@
 
 #define XFS_FSOP_GEOM_VERSION	0
 
-#define XFS_FSOP_GEOM_FLAGS_ATTR	0x01	/* attributes in use	*/
-#define XFS_FSOP_GEOM_FLAGS_NLINK	0x02	/* 32-bit nlink values	*/
-#define XFS_FSOP_GEOM_FLAGS_QUOTA	0x04	/* quotas enabled	*/
-#define XFS_FSOP_GEOM_FLAGS_IALIGN	0x08	/* inode alignment	*/
-#define XFS_FSOP_GEOM_FLAGS_DALIGN	0x10	/* large data alignment */
-#define XFS_FSOP_GEOM_FLAGS_SHARED	0x20	/* read-only shared	*/
-#define XFS_FSOP_GEOM_FLAGS_EXTFLG	0x40	/* special extent flag	*/
-#define XFS_FSOP_GEOM_FLAGS_DIRV2	0x80	/* directory version 2	*/
-#define XFS_FSOP_GEOM_FLAGS_LOGV2      0x100	/* log format version 2 */
+#define XFS_FSOP_GEOM_FLAGS_ATTR	0x0001	/* attributes in use	*/
+#define XFS_FSOP_GEOM_FLAGS_NLINK	0x0002	/* 32-bit nlink values	*/
+#define XFS_FSOP_GEOM_FLAGS_QUOTA	0x0004	/* quotas enabled	*/
+#define XFS_FSOP_GEOM_FLAGS_IALIGN	0x0008	/* inode alignment	*/
+#define XFS_FSOP_GEOM_FLAGS_DALIGN	0x0010	/* large data alignment */
+#define XFS_FSOP_GEOM_FLAGS_SHARED	0x0020	/* read-only shared	*/
+#define XFS_FSOP_GEOM_FLAGS_EXTFLG	0x0040	/* special extent flag	*/
+#define XFS_FSOP_GEOM_FLAGS_DIRV2	0x0080	/* directory version 2	*/
+#define XFS_FSOP_GEOM_FLAGS_LOGV2	0x0100	/* log format version 2	*/
+#define XFS_FSOP_GEOM_FLAGS_SECTOR	0x0200	/* sector sizes >1BB	*/
 
 
 /*
@@ -394,11 +391,13 @@
  * This is typically called by a stateless file server in order to generate
  * "file handles".
  */
+#ifndef MAXFIDSZ
 #define MAXFIDSZ	46
 typedef struct fid {
 	__u16		fid_len;		/* length of data in bytes */
 	unsigned char	fid_data[MAXFIDSZ];	/* data (variable length)  */
 } fid_t;
+#endif
 
 typedef struct xfs_fid {
 	__u16	xfs_fid_len;		/* length of remainder	*/
@@ -499,4 +498,4 @@
 #define BTOBBT(bytes)	((__u64)(bytes) >> BBSHIFT)
 #define BBTOB(bbs)	((bbs) << BBSHIFT)
 
-#endif	/* _LINUX_XFS_FS_H */
+#endif	/* __XFS_FS_H__ */
diff -Nru a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
--- a/fs/xfs/xfs_fsops.c	Mon Dec  9 18:46:51 2002
+++ b/fs/xfs/xfs_fsops.c	Mon Dec  9 18:46:51 2002
@@ -78,9 +78,12 @@
 			(XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb) ?
 				XFS_FSOP_GEOM_FLAGS_EXTFLG : 0) |
 			(XFS_SB_VERSION_HASDIRV2(&mp->m_sb) ?
-				XFS_FSOP_GEOM_FLAGS_DIRV2 : 0);
-		geo->logsectsize = mp->m_sb.sb_sectsize;	/* XXX */
-		geo->rtsectsize = mp->m_sb.sb_sectsize;		/* XXX */
+				XFS_FSOP_GEOM_FLAGS_DIRV2 : 0) |
+			(XFS_SB_VERSION_HASSECTOR(&mp->m_sb) ?
+				XFS_FSOP_GEOM_FLAGS_SECTOR : 0);
+		geo->logsectsize = XFS_SB_VERSION_HASSECTOR(&mp->m_sb) ?
+				mp->m_sb.sb_logsectsize : BBSIZE;
+		geo->rtsectsize = mp->m_sb.sb_blocksize;
 		geo->dirblocksize = mp->m_dirblksize;
 	}
 	if (new_version >= 4) {
@@ -105,9 +108,7 @@
 	xfs_alloc_rec_t		*arec;
 	xfs_btree_sblock_t	*block;
 	xfs_buf_t		*bp;
-	int			bsize;
 	int			bucket;
-	xfs_daddr_t		disk_addr;
 	int			dpct;
 	int			error;
 	xfs_agnumber_t		nagcount;
@@ -117,7 +118,6 @@
 	xfs_agnumber_t		oagcount;
 	int			pct;
 	xfs_sb_t		*sbp;
-	int			sectbb;
 	xfs_trans_t		*tp;
 
 	nb = in->newblocks;
@@ -125,8 +125,9 @@
 	if (nb < mp->m_sb.sb_dblocks || pct < 0 || pct > 100)
 		return XFS_ERROR(EINVAL);
 	dpct = pct - mp->m_sb.sb_imax_pct;
-	error = xfs_read_buf(mp, mp->m_ddev_targp, XFS_FSB_TO_BB(mp, nb) - 1, 1,
-		0, &bp);
+	error = xfs_read_buf(mp, mp->m_ddev_targp,
+			XFS_FSB_TO_BB(mp, nb) - XFS_FSS_TO_BB(mp, 1),
+			XFS_FSS_TO_BB(mp, 1), 0, &bp);
 	if (error)
 		return error;
 	ASSERT(bp);
@@ -161,19 +162,15 @@
 		xfs_trans_cancel(tp, 0);
 		return error;
 	}
-	/* new ag's */
-	sectbb = BTOBB(mp->m_sb.sb_sectsize);
-	bsize = mp->m_sb.sb_blocksize;
 
 	nfree = 0;
 	for (agno = nagcount - 1; agno >= oagcount; agno--, new -= agsize) {
 		/*
 		 * AG freelist header block
 		 */
-		disk_addr = XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR);
 		bp = xfs_buf_get(mp->m_ddev_targp,
-				  disk_addr,
-				  sectbb, 0);
+				  XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
+				  XFS_FSS_TO_BB(mp, 1), 0);
 		agf = XFS_BUF_TO_AGF(bp);
 		memset(agf, 0, mp->m_sb.sb_sectsize);
 		INT_SET(agf->agf_magicnum, ARCH_CONVERT, XFS_AGF_MAGIC);
@@ -186,12 +183,14 @@
 		else
 			agsize = mp->m_sb.sb_agblocks;
 		INT_SET(agf->agf_length, ARCH_CONVERT, agsize);
-		INT_SET(agf->agf_roots[XFS_BTNUM_BNOi], ARCH_CONVERT, XFS_BNO_BLOCK(mp));
-		INT_SET(agf->agf_roots[XFS_BTNUM_CNTi], ARCH_CONVERT, XFS_CNT_BLOCK(mp));
+		INT_SET(agf->agf_roots[XFS_BTNUM_BNOi], ARCH_CONVERT,
+			XFS_BNO_BLOCK(mp));
+		INT_SET(agf->agf_roots[XFS_BTNUM_CNTi], ARCH_CONVERT,
+			XFS_CNT_BLOCK(mp));
 		INT_SET(agf->agf_levels[XFS_BTNUM_BNOi], ARCH_CONVERT, 1);
 		INT_SET(agf->agf_levels[XFS_BTNUM_CNTi], ARCH_CONVERT, 1);
 		INT_ZERO(agf->agf_flfirst, ARCH_CONVERT);
-		INT_SET(agf->agf_fllast, ARCH_CONVERT, XFS_AGFL_SIZE - 1);
+		INT_SET(agf->agf_fllast, ARCH_CONVERT, XFS_AGFL_SIZE(mp) - 1);
 		INT_ZERO(agf->agf_flcount, ARCH_CONVERT);
 		tmpsize = agsize - XFS_PREALLOC_BLOCKS(mp);
 		INT_SET(agf->agf_freeblks, ARCH_CONVERT, tmpsize);
@@ -203,10 +202,9 @@
 		/*
 		 * AG inode header block
 		 */
-		disk_addr = XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR);
 		bp = xfs_buf_get(mp->m_ddev_targp,
-				  disk_addr,
-				  sectbb, 0);
+				  XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
+				  XFS_FSS_TO_BB(mp, 1), 0);
 		agi = XFS_BUF_TO_AGI(bp);
 		memset(agi, 0, mp->m_sb.sb_sectsize);
 		INT_SET(agi->agi_magicnum, ARCH_CONVERT, XFS_AGI_MAGIC);
@@ -220,7 +218,8 @@
 		INT_SET(agi->agi_newino, ARCH_CONVERT, NULLAGINO);
 		INT_SET(agi->agi_dirino, ARCH_CONVERT, NULLAGINO);
 		for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++)
-			INT_SET(agi->agi_unlinked[bucket], ARCH_CONVERT, NULLAGINO);
+			INT_SET(agi->agi_unlinked[bucket], ARCH_CONVERT,
+				NULLAGINO);
 		error = xfs_bwrite(mp, bp);
 		if (error) {
 			goto error0;
@@ -228,21 +227,22 @@
 		/*
 		 * BNO btree root block
 		 */
-		disk_addr = XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp));
 		bp = xfs_buf_get(mp->m_ddev_targp,
-			disk_addr,
-			BTOBB(bsize), 0);
+			XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp)),
+			BTOBB(mp->m_sb.sb_blocksize), 0);
 		block = XFS_BUF_TO_SBLOCK(bp);
-		memset(block, 0, bsize);
+		memset(block, 0, mp->m_sb.sb_blocksize);
 		INT_SET(block->bb_magic, ARCH_CONVERT, XFS_ABTB_MAGIC);
 		INT_ZERO(block->bb_level, ARCH_CONVERT);
 		INT_SET(block->bb_numrecs, ARCH_CONVERT, 1);
 		INT_SET(block->bb_leftsib, ARCH_CONVERT, NULLAGBLOCK);
 		INT_SET(block->bb_rightsib, ARCH_CONVERT, NULLAGBLOCK);
-		arec = XFS_BTREE_REC_ADDR(bsize, xfs_alloc, block, 1,
-			mp->m_alloc_mxr[0]);
-		INT_SET(arec->ar_startblock, ARCH_CONVERT, XFS_PREALLOC_BLOCKS(mp));
-		INT_SET(arec->ar_blockcount, ARCH_CONVERT, agsize - INT_GET(arec->ar_startblock, ARCH_CONVERT));
+		arec = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_alloc,
+			block, 1, mp->m_alloc_mxr[0]);
+		INT_SET(arec->ar_startblock, ARCH_CONVERT,
+			XFS_PREALLOC_BLOCKS(mp));
+		INT_SET(arec->ar_blockcount, ARCH_CONVERT,
+			agsize - INT_GET(arec->ar_startblock, ARCH_CONVERT));
 		error = xfs_bwrite(mp, bp);
 		if (error) {
 			goto error0;
@@ -250,21 +250,22 @@
 		/*
 		 * CNT btree root block
 		 */
-		disk_addr = XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp));
 		bp = xfs_buf_get(mp->m_ddev_targp,
-			disk_addr,
-			BTOBB(bsize), 0);
+			XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp)),
+			BTOBB(mp->m_sb.sb_blocksize), 0);
 		block = XFS_BUF_TO_SBLOCK(bp);
-		memset(block, 0, bsize);
+		memset(block, 0, mp->m_sb.sb_blocksize);
 		INT_SET(block->bb_magic, ARCH_CONVERT, XFS_ABTC_MAGIC);
 		INT_ZERO(block->bb_level, ARCH_CONVERT);
 		INT_SET(block->bb_numrecs, ARCH_CONVERT, 1);
 		INT_SET(block->bb_leftsib, ARCH_CONVERT, NULLAGBLOCK);
 		INT_SET(block->bb_rightsib, ARCH_CONVERT, NULLAGBLOCK);
-		arec = XFS_BTREE_REC_ADDR(bsize, xfs_alloc, block, 1,
-			mp->m_alloc_mxr[0]);
-		INT_SET(arec->ar_startblock, ARCH_CONVERT, XFS_PREALLOC_BLOCKS(mp));
-		INT_SET(arec->ar_blockcount, ARCH_CONVERT, agsize - INT_GET(arec->ar_startblock, ARCH_CONVERT));
+		arec = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize, xfs_alloc,
+			block, 1, mp->m_alloc_mxr[0]);
+		INT_SET(arec->ar_startblock, ARCH_CONVERT,
+			XFS_PREALLOC_BLOCKS(mp));
+		INT_SET(arec->ar_blockcount, ARCH_CONVERT,
+			agsize - INT_GET(arec->ar_startblock, ARCH_CONVERT));
 		nfree += INT_GET(arec->ar_blockcount, ARCH_CONVERT);
 		error = xfs_bwrite(mp, bp);
 		if (error) {
@@ -273,12 +274,11 @@
 		/*
 		 * INO btree root block
 		 */
-		disk_addr = XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp));
 		bp = xfs_buf_get(mp->m_ddev_targp,
-			disk_addr,
-			BTOBB(bsize), 0);
+			XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp)),
+			BTOBB(mp->m_sb.sb_blocksize), 0);
 		block = XFS_BUF_TO_SBLOCK(bp);
-		memset(block, 0, bsize);
+		memset(block, 0, mp->m_sb.sb_blocksize);
 		INT_SET(block->bb_magic, ARCH_CONVERT, XFS_IBT_MAGIC);
 		INT_ZERO(block->bb_level, ARCH_CONVERT);
 		INT_ZERO(block->bb_numrecs, ARCH_CONVERT);
@@ -304,8 +304,9 @@
 		ASSERT(bp);
 		agi = XFS_BUF_TO_AGI(bp);
 		INT_MOD(agi->agi_length, ARCH_CONVERT, new);
-		ASSERT(nagcount == oagcount
-		       || INT_GET(agi->agi_length, ARCH_CONVERT) == mp->m_sb.sb_agblocks);
+		ASSERT(nagcount == oagcount ||
+		       INT_GET(agi->agi_length, ARCH_CONVERT) ==
+				mp->m_sb.sb_agblocks);
 		xfs_ialloc_log_agi(tp, bp, XFS_AGI_LENGTH);
 		/*
 		 * Change agf length.
@@ -323,7 +324,7 @@
 		 * Free the new space.
 		 */
 		error = xfs_free_extent(tp, XFS_AGB_TO_FSB(mp, agno,
-				INT_GET(agf->agf_length, ARCH_CONVERT) - new), new);
+			INT_GET(agf->agf_length, ARCH_CONVERT) - new), new);
 		if (error) {
 			goto error0;
 		}
@@ -350,7 +351,7 @@
 	for (agno = 1; agno < nagcount; agno++) {
 		error = xfs_read_buf(mp, mp->m_ddev_targp,
 				  XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)),
-				  sectbb, 0, &bp);
+				  XFS_FSS_TO_BB(mp, 1), 0, &bp);
 		if (error) {
 			xfs_fs_cmn_err(CE_WARN, mp,
 			"error %d reading secondary superblock for ag %d",
@@ -584,7 +585,6 @@
 
 	return 0;
 }
-
 
 int
 xfs_fs_thaw(
diff -Nru a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
--- a/fs/xfs/xfs_ialloc.c	Mon Dec  9 18:46:38 2002
+++ b/fs/xfs/xfs_ialloc.c	Mon Dec  9 18:46:38 2002
@@ -1258,8 +1258,7 @@
 	xfs_agi_t		*agi;	/* allocation group header */
 
 	agi = XFS_BUF_TO_AGI(bp);
-	ASSERT(INT_GET(agi->agi_magicnum, ARCH_CONVERT) ==
-		XFS_AGI_MAGIC);
+	ASSERT(INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC);
 #endif
 	/*
 	 * Compute byte offsets for the first and last fields.
@@ -1284,26 +1283,26 @@
 	xfs_agi_t	*agi;		/* allocation group header */
 	int		agi_ok;		/* agi is consistent */
 	xfs_buf_t	*bp;		/* allocation group hdr buf */
-    xfs_daddr_t		d;		/* disk block address */
-	int		error;
-#ifdef DEBUG
-	int		i;
-#endif
 	xfs_perag_t	*pag;		/* per allocation group data */
-
+	int		error;
 
 	ASSERT(agno != NULLAGNUMBER);
-	d = XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR);
-	if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d, 1, 0, &bp)))
+	error = xfs_trans_read_buf(
+			mp, tp, mp->m_ddev_targp,
+			XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
+			XFS_FSS_TO_BB(mp, 1), 0, &bp);
+	if (error)
 		return error;
 	ASSERT(bp && !XFS_BUF_GETERROR(bp));
+
 	/*
 	 * Validate the magic number of the agi block.
 	 */
 	agi = XFS_BUF_TO_AGI(bp);
 	agi_ok =
 		INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC &&
-		XFS_AGI_GOOD_VERSION(INT_GET(agi->agi_versionnum, ARCH_CONVERT));
+		XFS_AGI_GOOD_VERSION(
+			INT_GET(agi->agi_versionnum, ARCH_CONVERT));
 	if (XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI,
 			XFS_RANDOM_IALLOC_READ_AGI)) {
 		xfs_trans_brelse(tp, bp);
@@ -1323,13 +1322,20 @@
 		 * It's possible for these to be out of sync if
 		 * we are in the middle of a forced shutdown.
 		 */
-		ASSERT(pag->pagi_freecount == INT_GET(agi->agi_freecount, ARCH_CONVERT)
+		ASSERT(pag->pagi_freecount ==
+				INT_GET(agi->agi_freecount, ARCH_CONVERT)
 			|| XFS_FORCED_SHUTDOWN(mp));
 	}
+
 #ifdef DEBUG
-	for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++)
-		ASSERT(!INT_ISZERO(agi->agi_unlinked[i], ARCH_CONVERT));
+	{
+		int	i;
+
+		for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++)
+			ASSERT(!INT_ISZERO(agi->agi_unlinked[i], ARCH_CONVERT));
+	}
 #endif
+
 	XFS_BUF_SET_VTYPE_REF(bp, B_FS_AGI, XFS_AGI_REF);
 	*bpp = bp;
 	return 0;
diff -Nru a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c
--- a/fs/xfs/xfs_ialloc_btree.c	Mon Dec  9 18:46:36 2002
+++ b/fs/xfs/xfs_ialloc_btree.c	Mon Dec  9 18:46:36 2002
@@ -213,10 +213,10 @@
 			 */
 			agfbno = XFS_AG_DADDR(cur->bc_mp,
 					      cur->bc_private.i.agno,
-					      XFS_AGF_DADDR);
+					      XFS_AGF_DADDR(mp));
 			if (error = xfs_trans_read_buf(cur->bc_mp, cur->bc_tp,
-					cur->bc_mp->m_ddev_targp, agfbno, 1, 0,
-					&agfbp))
+					cur->bc_mp->m_ddev_targp, agfbno,
+					XFS_FSS_TO_BB(mp, 1), 0, &agfbp))
 				return error;
 			ASSERT(!XFS_BUF_GETERROR(agfbp));
 			xfs_trans_bhold_until_committed(cur->bc_tp, agfbp);
@@ -506,9 +506,10 @@
 	 * transaction record makes it to the on-disk log.
 	 */
 	agfbno = XFS_AG_DADDR(cur->bc_mp, cur->bc_private.i.agno,
-			      XFS_AGF_DADDR);
+			      XFS_AGF_DADDR(mp));
 	if (error = xfs_trans_read_buf(cur->bc_mp, cur->bc_tp,
-			cur->bc_mp->m_ddev_targp, agfbno, 1, 0, &agfbp))
+			cur->bc_mp->m_ddev_targp, agfbno,
+			XFS_FSS_TO_BB(mp, 1), 0, &agfbp))
 		return error;
 	ASSERT(!XFS_BUF_GETERROR(agfbp));
 	xfs_trans_bhold_until_committed(cur->bc_tp, agfbp);
diff -Nru a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
--- a/fs/xfs/xfs_inode.c	Mon Dec  9 18:46:51 2002
+++ b/fs/xfs/xfs_inode.c	Mon Dec  9 18:46:51 2002
@@ -1799,14 +1799,14 @@
 	mp = tp->t_mountp;
 
 	agno = XFS_INO_TO_AGNO(mp, ip->i_ino);
-	agdaddr = XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR);
+	agdaddr = XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp));
 
 	/*
 	 * Get the agi buffer first.  It ensures lock ordering
 	 * on the list.
 	 */
 	error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, agdaddr,
-				   1, 0, &agibp);
+				   XFS_FSS_TO_BB(mp, 1), 0, &agibp);
 	if (error) {
 		return error;
 	}
@@ -1898,15 +1898,15 @@
 	mp = tp->t_mountp;
 
 	agno = XFS_INO_TO_AGNO(mp, ip->i_ino);
-	agdaddr = XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR);
+	agdaddr = XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp));
 
 	/*
 	 * Get the agi buffer first.  It ensures lock ordering
 	 * on the list.
 	 */
 	error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, agdaddr,
-				   1, 0, &agibp);
-	if (error != 0) {
+				   XFS_FSS_TO_BB(mp, 1), 0, &agibp);
+	if (error) {
 		cmn_err(CE_WARN,
 			"xfs_iunlink_remove: xfs_trans_read_buf()  returned an error %d on %s.	Returning error.",
 			error, mp->m_fsname);
diff -Nru a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
--- a/fs/xfs/xfs_inode_item.c	Mon Dec  9 18:46:50 2002
+++ b/fs/xfs/xfs_inode_item.c	Mon Dec  9 18:46:50 2002
@@ -433,7 +433,6 @@
 		ASSERT(!(iip->ili_format.ilf_fields &
 			 (XFS_ILOG_ADATA | XFS_ILOG_ABROOT)));
 		if (iip->ili_format.ilf_fields & XFS_ILOG_AEXT) {
-			ASSERT(!(iip->ili_format.ilf_fields & XFS_ILOG_DEXT));
 			ASSERT(ip->i_afp->if_bytes > 0);
 			ASSERT(ip->i_afp->if_u1.if_extents != NULL);
 			ASSERT(ip->i_d.di_anextents > 0);
@@ -455,7 +454,7 @@
 			/*
 			 * Need to endian flip before logging
 			 */
-			ext_buffer = kmem_alloc(ip->i_df.if_bytes,
+			ext_buffer = kmem_alloc(ip->i_afp->if_bytes,
 				KM_SLEEP);
 			iip->ili_aextents_buf = ext_buffer;
 			vecp->i_addr = (xfs_caddr_t)ext_buffer;
diff -Nru a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
--- a/fs/xfs/xfs_log.c	Mon Dec  9 18:46:52 2002
+++ b/fs/xfs/xfs_log.c	Mon Dec  9 18:46:52 2002
@@ -51,7 +51,7 @@
 				xfs_daddr_t	blk_offset,
 				int		num_bblks);
 STATIC int	 xlog_space_left(xlog_t *log, int cycle, int bytes);
-STATIC int	 xlog_sync(xlog_t *log, xlog_in_core_t *iclog, uint flags);
+STATIC int	 xlog_sync(xlog_t *log, xlog_in_core_t *iclog);
 STATIC void	 xlog_unalloc_log(xlog_t *log);
 STATIC int	 xlog_write(xfs_mount_t *mp, xfs_log_iovec_t region[],
 			    int nentries, xfs_log_ticket_t tic,
@@ -965,12 +965,12 @@
 		aborted = XFS_LI_ABORTED;
 	}
 	xlog_state_done_syncing(iclog, aborted);
-	if ( !(XFS_BUF_ISASYNC(bp)) ) {
+	if (!(XFS_BUF_ISASYNC(bp))) {
 		/*
 		 * Corresponding psema() will be done in bwrite().  If we don't
 		 * vsema() here, panic.
 		 */
-	  XFS_BUF_V_IODONESEMA(bp);
+		XFS_BUF_V_IODONESEMA(bp);
 	}
 }	/* xlog_iodone */
 
@@ -1241,6 +1241,7 @@
 		ASSERT(XFS_BUF_ISBUSY(iclog->ic_bp));
 		ASSERT(XFS_BUF_VALUSEMA(iclog->ic_bp) <= 0);
 		sv_init(&iclog->ic_forcesema, SV_DEFAULT, "iclog-force");
+		sv_init(&iclog->ic_writesema, SV_DEFAULT, "iclog-write");
 
 		iclogp = &iclog->ic_next;
 	}
@@ -1368,8 +1369,7 @@
 
 int
 xlog_sync(xlog_t		*log,
-	  xlog_in_core_t	*iclog,
-	  uint			flags)
+	  xlog_in_core_t	*iclog)
 {
 	xfs_caddr_t	dptr;		/* pointer to byte sized element */
 	xfs_buf_t	*bp;
@@ -1382,11 +1382,6 @@
 	XFS_STATS_INC(xfsstats.xs_log_writes);
 	ASSERT(iclog->ic_refcnt == 0);
 
-#ifdef DEBUG
-	if (flags != 0 && (flags & XFS_LOG_SYNC) )
-		xlog_panic("xlog_sync: illegal flag");
-#endif
-
 	/* Round out the log write size */
 	if (iclog->ic_offset & BBMASK) {
 		/* count of 0 is already accounted for up in
@@ -1440,13 +1435,8 @@
 	}
 	XFS_BUF_SET_PTR(bp, (xfs_caddr_t) &(iclog->ic_header), count);
 	XFS_BUF_SET_FSPRIVATE(bp, iclog);	/* save for later */
-	if (flags & XFS_LOG_SYNC){
-		XFS_BUF_BUSY(bp);
-		XFS_BUF_HOLD(bp);
-	} else {
-		XFS_BUF_BUSY(bp);
-		XFS_BUF_ASYNC(bp);
-	}
+	XFS_BUF_BUSY(bp);
+	XFS_BUF_ASYNC(bp);
 	/*
 	 * Do a disk write cache flush for the log block.
 	 * This is a bit of a sledgehammer, it would be better
@@ -1532,6 +1522,7 @@
 	iclog = log->l_iclog;
 	for (i=0; i<log->l_iclog_bufs; i++) {
 		sv_destroy(&iclog->ic_forcesema);
+		sv_destroy(&iclog->ic_writesema);
 		XFS_freerbuf(iclog->ic_bp);
 #ifdef DEBUG
 		if (iclog->ic_trace != NULL) {
@@ -1832,15 +1823,19 @@
 			 * If the number of ops in this iclog indicate it just
 			 * contains the dummy transaction, we can
 			 * change state into IDLE (the second time around).
-			 * Otherwise we should change the state into NEED a dummy.
+			 * Otherwise we should change the state into
+			 * NEED a dummy.
 			 * We don't need to cover the dummy.
 			 */
 			if (!changed &&
 			   (INT_GET(iclog->ic_header.h_num_logops, ARCH_CONVERT) == XLOG_COVER_OPS)) {
 				changed = 1;
-			} else {	/* we have two dirty iclogs so start over */
-					/* This could also be num of ops indicates
-						this is not the dummy going out. */
+			} else {
+				/*
+				 * We have two dirty iclogs so start over
+				 * This could also be num of ops indicates
+				 * this is not the dummy going out.
+				 */
 				changed = 2;
 			}
 			INT_ZERO(iclog->ic_header.h_num_logops, ARCH_CONVERT);
@@ -2163,6 +2158,12 @@
 		iclog->ic_state = XLOG_STATE_DONE_SYNC;
 	}
 
+	/*
+	 * Someone could be sleeping prior to writing out the next
+	 * iclog buffer, we wake them all, one will get to do the
+	 * I/O, the others get to wait for the result.
+	 */
+	sv_broadcast(&iclog->ic_writesema);
 	LOG_UNLOCK(log, s);
 	xlog_state_do_callback(log, aborted, iclog);	/* also cleans log */
 }	/* xlog_state_done_syncing */
@@ -2226,8 +2227,6 @@
 	xlog_in_core_t	  *iclog;
 	int		  error;
 
-	xlog_state_do_callback(log, 0, NULL);	/* also cleans log */
-
 restart:
 	s = LOG_LOCK(log);
 	if (XLOG_FORCED_SHUTDOWN(log)) {
@@ -2715,17 +2714,6 @@
 	LOG_UNLOCK(log, s);
 }	/* xlog_state_put_ticket */
 
-void xlog_sync_work(
-	void	*v)
-{
-	xlog_in_core_t	*iclog = (xlog_in_core_t *)v;
-	xlog_t		*log  = iclog->ic_log;
-
-	xlog_sync(log, iclog, 0);
-}
-
-int xlog_mode = 1;
-
 /*
  * Flush iclog to disk if this is the last reference to the given iclog and
  * the WANT_SYNC bit is set.
@@ -2774,13 +2762,7 @@
 	 * flags after this point.
 	 */
 	if (sync) {
-		INIT_WORK(&iclog->ic_write_work, xlog_sync_work, iclog);
-		switch (xlog_mode) {
-		case 0:
-			return xlog_sync(log, iclog, 0);
-		case 1:
-		        queue_work(pagebuf_workqueue, &iclog->ic_write_work);
-		}
+		return xlog_sync(log, iclog);
 	}
 	return (0);
 
@@ -2985,9 +2967,11 @@
 		uint	  flags)
 {
     xlog_in_core_t	*iclog;
+    int			already_slept = 0;
     SPLDECL(s);
 
 
+try_again:
     s = LOG_LOCK(log);
     iclog = log->l_iclog;
 
@@ -3008,12 +2992,40 @@
 	}
 
 	if (iclog->ic_state == XLOG_STATE_ACTIVE) {
-		iclog->ic_refcnt++;
-		xlog_state_switch_iclogs(log, iclog, 0);
-		LOG_UNLOCK(log, s);
-		if (xlog_state_release_iclog(log, iclog))
-			return XFS_ERROR(EIO);
-		s = LOG_LOCK(log);
+		/*
+		 * We sleep here if we haven't already slept (e.g.
+		 * this is the first time we've looked at the correct
+		 * iclog buf) and the buffer before us is going to
+		 * be sync'ed. The reason for this is that if we
+		 * are doing sync transactions here, by waiting for
+		 * the previous I/O to complete, we can allow a few
+		 * more transactions into this iclog before we close
+		 * it down.
+		 *
+		 * Otherwise, we mark the buffer WANT_SYNC, and bump
+		 * up the refcnt so we can release the log (which drops
+		 * the ref count).  The state switch keeps new transaction
+		 * commits from using this buffer.  When the current commits
+		 * finish writing into the buffer, the refcount will drop to
+		 * zero and the buffer will go out then.
+		 */
+		if (!already_slept &&
+		    (iclog->ic_prev->ic_state & (XLOG_STATE_WANT_SYNC |
+						 XLOG_STATE_SYNCING))) {
+			ASSERT(!(iclog->ic_state & XLOG_STATE_IOERROR));
+			XFS_STATS_INC(xfsstats.xs_log_force_sleep);
+			sv_wait(&iclog->ic_prev->ic_writesema, PSWP,
+				&log->l_icloglock, s);
+			already_slept = 1;
+			goto try_again;
+		} else {
+			iclog->ic_refcnt++;
+			xlog_state_switch_iclogs(log, iclog, 0);
+			LOG_UNLOCK(log, s);
+			if (xlog_state_release_iclog(log, iclog))
+				return XFS_ERROR(EIO);
+			s = LOG_LOCK(log);
+		}
 	}
 
 	if ((flags & XFS_LOG_SYNC) && /* sleep */
diff -Nru a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
--- a/fs/xfs/xfs_log_priv.h	Mon Dec  9 18:46:34 2002
+++ b/fs/xfs/xfs_log_priv.h	Mon Dec  9 18:46:34 2002
@@ -422,6 +422,7 @@
  */
 typedef struct xlog_iclog_fields {
 	sv_t			ic_forcesema;
+	sv_t			ic_writesema;
 	struct xlog_in_core	*ic_next;
 	struct xlog_in_core	*ic_prev;
 	struct xfs_buf		*ic_bp;
@@ -438,7 +439,6 @@
 	int			ic_bwritecnt;
 	ushort_t		ic_state;
 	char			*ic_datap;	/* pointer to iclog data */
-	struct work_struct	ic_write_work;
 } xlog_iclog_fields_t;
 
 typedef struct xlog_in_core2 {
@@ -458,7 +458,7 @@
  * Defines to save our code from this glop.
  */
 #define ic_forcesema	hic_fields.ic_forcesema
-#define ic_write_work	hic_fields.ic_write_work
+#define ic_writesema	hic_fields.ic_writesema
 #define ic_next		hic_fields.ic_next
 #define ic_prev		hic_fields.ic_prev
 #define ic_bp		hic_fields.ic_bp
diff -Nru a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
--- a/fs/xfs/xfs_log_recover.c	Mon Dec  9 18:46:38 2002
+++ b/fs/xfs/xfs_log_recover.c	Mon Dec  9 18:46:38 2002
@@ -50,7 +50,7 @@
 
 
 xfs_buf_t *
-xlog_get_bp(int num_bblks,xfs_mount_t *mp)
+xlog_get_bp(int num_bblks, xfs_mount_t *mp)
 {
 	xfs_buf_t   *bp;
 
@@ -242,15 +242,15 @@
  * necessarily be perfect.
  */
 int
-xlog_find_cycle_start(xlog_t	*log,
-		      xfs_buf_t *bp,
+xlog_find_cycle_start(xlog_t		*log,
+		      xfs_buf_t		*bp,
 		      xfs_daddr_t	first_blk,
 		      xfs_daddr_t	*last_blk,
-		      uint	cycle)
+		      uint		cycle)
 {
-	xfs_daddr_t mid_blk;
-	uint	mid_cycle;
-	int	error;
+	xfs_daddr_t	mid_blk;
+	uint		mid_cycle;
+	int		error;
 
 	mid_blk = BLK_AVG(first_blk, *last_blk);
 	while (mid_blk != first_blk && mid_blk != *last_blk) {
@@ -307,9 +307,10 @@
 			return ENOMEM;
 	}
 
+	for (i = start_blk; i < start_blk + nbblks; i += bufblks) {
+		int	bcount;
 
-	for (i = start_blk; i < start_blk + nbblks; i += bufblks)  {
-		int bcount = min(bufblks, (start_blk + nbblks - i));
+		bcount = min(bufblks, (start_blk + nbblks - i));
 
 		if ((error = xlog_bread(log, i, bcount, bp)))
 			goto out;
@@ -373,11 +374,10 @@
     } else {
 	if ((error = xlog_bread(log, start_blk, num_blks, bp)))
 	    goto out;
-	buf = XFS_BUF_PTR(bp) + (num_blks - 1) * BBSIZE;
+	buf = XFS_BUF_PTR(bp) + ((num_blks - 1) << BBSHIFT);
     }
 
-
-    for (i=(*last_blk)-1; i>=0; i--) {
+    for (i = (*last_blk) - 1; i >= 0; i--) {
 	if (i < start_blk) {
 	    /* legal log record not found */
 	    xlog_warn("XFS: Log inconsistent (didn't find previous header)");
@@ -422,7 +422,8 @@
      * record do we update last_blk.
      */
     if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
-	int h_size = INT_GET(head->h_size, ARCH_CONVERT);
+	uint	h_size = INT_GET(head->h_size, ARCH_CONVERT);
+
 	xhdrs = h_size / XLOG_HEADER_CYCLE_SIZE;
 	if (h_size % XLOG_HEADER_CYCLE_SIZE)
 		xhdrs++;
@@ -715,10 +716,10 @@
  * available.
  */
 int
-xlog_find_tail(xlog_t  *log,
-	       xfs_daddr_t *head_blk,
-	       xfs_daddr_t *tail_blk,
-	       int readonly)
+xlog_find_tail(xlog_t		*log,
+	       xfs_daddr_t	*head_blk,
+	       xfs_daddr_t	*tail_blk,
+	       int		readonly)
 {
 	xlog_rec_header_t	*rhead;
 	xlog_op_header_t	*op_head;
@@ -925,7 +926,6 @@
 	xfs_daddr_t	num_scan_bblks;
 	int		error, log_bbnum = log->l_logBBsize;
 
-	error = 0;
 	/* check totally zeroed log */
 	bp = xlog_get_bp(1,log->l_mp);
 	if (!bp)
@@ -1088,14 +1088,11 @@
 	xlog_t		*log,
 	xfs_lsn_t	tail_lsn)
 {
-	int			tail_cycle;
-	int			head_cycle;
-	int			tail_block;
-	int			head_block;
-	int			tail_distance;
-	int			max_distance;
-	int			distance;
-	int			error;
+	int		tail_cycle, head_cycle;
+	int		tail_block, head_block;
+	int		tail_distance, max_distance;
+	int		distance;
+	int		error;
 
 	tail_cycle = CYCLE_LSN(tail_lsn, ARCH_NOCONVERT);
 	tail_block = BLOCK_LSN(tail_lsn, ARCH_NOCONVERT);
@@ -1118,8 +1115,7 @@
 		 */
 		if (head_block < tail_block || head_block >= log->l_logBBsize)
 			return XFS_ERROR(EFSCORRUPTED);
-		tail_distance = tail_block +
-				(log->l_logBBsize - head_block);
+		tail_distance = tail_block + (log->l_logBBsize - head_block);
 	} else {
 		/*
 		 * The head is behind the tail in the physical log,
@@ -1839,10 +1835,9 @@
 	uint type;
 
 	/*
-	 * Non-root filesystems are required to send in quota flags
-	 * at mount time.
+	 * Filesystems are required to send in quota flags at mount time.
 	 */
-	if (mp->m_qflags == 0 && mp->m_dev != rootdev) {
+	if (mp->m_qflags == 0) {
 		return;
 	}
 	
@@ -1981,13 +1976,12 @@
 	 * the buffer out of the buffer cache so that the buffer won't
 	 * overlap with future reads of those inodes.
 	 */
-	error = 0;
-
-	if ((INT_GET(*((__uint16_t *)(xfs_buf_offset(bp, 0))), ARCH_CONVERT) == XFS_DINODE_MAGIC) &&
+	if (XFS_DINODE_MAGIC ==
+	    INT_GET(*((__uint16_t *)(xfs_buf_offset(bp, 0))), ARCH_CONVERT) &&
 	    (XFS_BUF_COUNT(bp) != MAX(log->l_mp->m_sb.sb_blocksize,
 			(__uint32_t)XFS_INODE_CLUSTER_SIZE(log->l_mp)))) {
-	  XFS_BUF_STALE(bp);
-	  error = xfs_bwrite(mp, bp);
+		XFS_BUF_STALE(bp);
+		error = xfs_bwrite(mp, bp);
 	} else {
 		ASSERT(XFS_BUF_FSPRIVATE(bp, void *) == NULL ||
 		       XFS_BUF_FSPRIVATE(bp, xfs_mount_t *) == mp);
@@ -2043,6 +2037,7 @@
 		imap.im_blkno = 0;
 		xfs_imap(log->l_mp, 0, ino, &imap, 0);
 	}
+
 	bp = xfs_buf_read_flags(mp->m_ddev_targp, imap.im_blkno, imap.im_len,
 								XFS_BUF_LOCK);
 	if (XFS_BUF_ISERROR(bp)) {
@@ -2171,8 +2166,6 @@
 		break;
 	}
 
-
-
 	/*
 	 * If we logged any attribute data, recover it.	 There may or
 	 * may not have been any other non-core data logged in this
@@ -2289,30 +2282,28 @@
 	mp = log->l_mp;
 
 	/*
-	 * Non-root filesystems are required to send in quota flags
-	 * at mount time.
+	 * Filesystems are required to send in quota flags at mount time.
 	 */
-	if (mp->m_qflags == 0 && mp->m_dev != rootdev) {
+	if (mp->m_qflags == 0)
 		return (0);
-	}
 
 	recddq = (xfs_disk_dquot_t *)item->ri_buf[1].i_addr;
 	ASSERT(recddq);
 	/*
 	 * This type of quotas was turned off, so ignore this record.
 	 */
-	type = INT_GET(recddq->d_flags, ARCH_CONVERT)&(XFS_DQ_USER|XFS_DQ_GROUP);
+	type = INT_GET(recddq->d_flags, ARCH_CONVERT) &
+			(XFS_DQ_USER | XFS_DQ_GROUP);
 	ASSERT(type);
 	if (log->l_quotaoffs_flag & type)
 		return (0);
 
 	/*
-	 * At this point we know that if we are recovering a root filesystem
-	 * then quota was _not_ turned off. Since there is no other flag
-	 * indicate to us otherwise, this must mean that quota's on,
-	 * and the dquot needs to be replayed. Remember that we may not have
-	 * fully recovered the superblock yet, so we can't do the usual trick
-	 * of looking at the SB quota bits.
+	 * At this point we know that quota was _not_ turned off.
+	 * Since the mount flags are not indicating to us otherwise, this
+	 * must mean that quota is on, and the dquot needs to be replayed.
+	 * Remember that we may not have fully recovered the superblock yet,
+	 * so we can't do the usual trick of looking at the SB quota bits.
 	 *
 	 * The other possibility, of course, is that the quota subsystem was
 	 * removed since the last mount - ENOSYS.
@@ -2323,7 +2314,7 @@
 			   dq_f->qlf_id,
 			   0, XFS_QMOPT_DOWARN,
 			   "xlog_recover_do_dquot_trans (log copy)"))) {
-	  if (error == ENOSYS)
+		if (error == ENOSYS)
 			return (0);
 		return XFS_ERROR(EIO);
 	}
@@ -2847,7 +2838,6 @@
 {
 	xfs_trans_t	*tp;
 	xfs_agi_t	*agi;
-	xfs_daddr_t	agidaddr;
 	xfs_buf_t	*agibp;
 	int		offset;
 	int		error;
@@ -2855,9 +2845,9 @@
 	tp = xfs_trans_alloc(mp, XFS_TRANS_CLEAR_AGI_BUCKET);
 	xfs_trans_reserve(tp, 0, XFS_CLEAR_AGI_BUCKET_LOG_RES(mp), 0, 0, 0);
 
-	agidaddr = XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR);
-	error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, agidaddr,
-				   1, 0, &agibp);
+	error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
+				   XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
+				   XFS_FSS_TO_BB(mp, 1), 0, &agibp);
 	if (error) {
 		xfs_trans_cancel(tp, XFS_TRANS_ABORT);
 		return;
@@ -2898,7 +2888,6 @@
 	xfs_mount_t	*mp;
 	xfs_agnumber_t	agno;
 	xfs_agi_t	*agi;
-	xfs_daddr_t	agidaddr;
 	xfs_buf_t	*agibp;
 	xfs_buf_t	*ibp;
 	xfs_dinode_t	*dip;
@@ -2923,14 +2912,17 @@
 		/*
 		 * Find the agi for this ag.
 		 */
-		agidaddr = XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR);
-		agibp = xfs_buf_read(mp->m_ddev_targp, agidaddr, 1, 0);
+		agibp = xfs_buf_read(mp->m_ddev_targp,
+				XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
+				XFS_FSS_TO_BB(mp, 1), 0);
 		if (XFS_BUF_ISERROR(agibp)) {
-			xfs_ioerror_alert("xlog_recover_process_iunlinks(agi#1)",
-					  log->l_mp, agibp, agidaddr);
+			xfs_ioerror_alert("xlog_recover_process_iunlinks(#1)",
+				log->l_mp, agibp,
+				XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)));
 		}
 		agi = XFS_BUF_TO_AGI(agibp);
-		ASSERT(INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC);
+		ASSERT(XFS_AGI_MAGIC ==
+			INT_GET(agi->agi_magicnum, ARCH_CONVERT));
 
 		for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++) {
 
@@ -3009,15 +3001,20 @@
 				 * Reacquire the agibuffer and continue around
 				 * the loop.
 				 */
-				agidaddr = XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR);
 				agibp = xfs_buf_read(mp->m_ddev_targp,
-						 agidaddr, 1, 0);
+						XFS_AG_DADDR(mp, agno,
+							XFS_AGI_DADDR(mp)),
+						XFS_FSS_TO_BB(mp, 1), 0);
 				if (XFS_BUF_ISERROR(agibp)) {
-					xfs_ioerror_alert("xlog_recover_process_iunlinks(agi#2)",
-							  log->l_mp, agibp, agidaddr);
+					xfs_ioerror_alert(
+				"xlog_recover_process_iunlinks(#2)",
+						log->l_mp, agibp,
+						XFS_AG_DADDR(mp, agno,
+							XFS_AGI_DADDR(mp)));
 				}
 				agi = XFS_BUF_TO_AGI(agibp);
-				ASSERT(INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC);
+				ASSERT(XFS_AGI_MAGIC == INT_GET(
+					agi->agi_magicnum, ARCH_CONVERT));
 			}
 		}
 
@@ -3488,9 +3485,8 @@
 		return error;
 	}
 
-	/* convert superblock from on-disk format */
-
-	sbp=&log->l_mp->m_sb;
+	/* Convert superblock from on-disk format */
+	sbp = &log->l_mp->m_sb;
 	xfs_xlatesb(XFS_BUF_TO_SBP(bp), sbp, 1, ARCH_CONVERT, XFS_SB_ALL_BITS);
 	ASSERT(sbp->sb_magicnum == XFS_SB_MAGIC);
 	ASSERT(XFS_SB_GOOD_VERSION(sbp));
@@ -3656,30 +3652,36 @@
 	itotal = 0LL;
 	ifree = 0LL;
 	for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
-		agfdaddr = XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR);
-		agfbp = xfs_buf_read(mp->m_ddev_targp, agfdaddr, 1, 0);
+		agfdaddr = XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp));
+		agfbp = xfs_buf_read(mp->m_ddev_targp, agfdaddr,
+				XFS_FSS_TO_BB(mp, 1), 0);
 		if (XFS_BUF_ISERROR(agfbp)) {
 			xfs_ioerror_alert("xlog_recover_check_summary(agf)",
-					  log->l_mp, agfbp, agfdaddr);
+						mp, agfbp, agfdaddr);
 		}
 		agfp = XFS_BUF_TO_AGF(agfbp);
-		ASSERT(INT_GET(agfp->agf_magicnum, ARCH_CONVERT) == XFS_AGF_MAGIC);
-		ASSERT(XFS_AGF_GOOD_VERSION(INT_GET(agfp->agf_versionnum, ARCH_CONVERT)));
+		ASSERT(XFS_AGF_MAGIC ==
+			INT_GET(agfp->agf_magicnum, ARCH_CONVERT));
+		ASSERT(XFS_AGF_GOOD_VERSION(
+			INT_GET(agfp->agf_versionnum, ARCH_CONVERT)));
 		ASSERT(INT_GET(agfp->agf_seqno, ARCH_CONVERT) == agno);
 
 		freeblks += INT_GET(agfp->agf_freeblks, ARCH_CONVERT) +
 			    INT_GET(agfp->agf_flcount, ARCH_CONVERT);
 		xfs_buf_relse(agfbp);
 
-		agidaddr = XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR);
-		agibp = xfs_buf_read(mp->m_ddev_targp, agidaddr, 1, 0);
+		agidaddr = XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp));
+		agibp = xfs_buf_read(mp->m_ddev_targp, agidaddr,
+				XFS_FSS_TO_BB(mp, 1), 0);
 		if (XFS_BUF_ISERROR(agibp)) {
 			xfs_ioerror_alert("xlog_recover_check_summary(agi)",
 					  log->l_mp, agibp, agidaddr);
 		}
 		agip = XFS_BUF_TO_AGI(agibp);
-		ASSERT(INT_GET(agip->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC);
-		ASSERT(XFS_AGI_GOOD_VERSION(INT_GET(agip->agi_versionnum, ARCH_CONVERT)));
+		ASSERT(XFS_AGI_MAGIC ==
+			INT_GET(agip->agi_magicnum, ARCH_CONVERT));
+		ASSERT(XFS_AGI_GOOD_VERSION(
+			INT_GET(agip->agi_versionnum, ARCH_CONVERT)));
 		ASSERT(INT_GET(agip->agi_seqno, ARCH_CONVERT) == agno);
 
 		itotal += INT_GET(agip->agi_count, ARCH_CONVERT);
diff -Nru a/fs/xfs/xfs_macros.c b/fs/xfs/xfs_macros.c
--- a/fs/xfs/xfs_macros.c	Mon Dec  9 18:46:35 2002
+++ b/fs/xfs/xfs_macros.c	Mon Dec  9 18:46:35 2002
@@ -2179,6 +2179,14 @@
 }
 #endif
 
+#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_HASSECTOR)
+int
+xfs_sb_version_hassector(xfs_sb_t *sbp)
+{
+	return XFS_SB_VERSION_HASSECTOR(sbp);
+}
+#endif
+
 #if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_TONEW)
 unsigned
 xfs_sb_version_tonew(unsigned v)
diff -Nru a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
--- a/fs/xfs/xfs_mount.c	Mon Dec  9 18:46:36 2002
+++ b/fs/xfs/xfs_mount.c	Mon Dec  9 18:46:36 2002
@@ -91,7 +91,8 @@
     { offsetof(xfs_sb_t, sb_unit),	 0 },
     { offsetof(xfs_sb_t, sb_width),	 0 },
     { offsetof(xfs_sb_t, sb_dirblklog),	 0 },
-    { offsetof(xfs_sb_t, sb_dummy),	 1 },
+    { offsetof(xfs_sb_t, sb_logsectlog), 0 },
+    { offsetof(xfs_sb_t, sb_logsectsize),0 },
     { offsetof(xfs_sb_t, sb_logsunit),	 0 },
     { sizeof(xfs_sb_t),			 0 }
 };
@@ -119,6 +120,7 @@
 	spinlock_init(&mp->m_freeze_lock, "xfs_freeze");
 	init_sv(&mp->m_wait_unfreeze, SV_DEFAULT, "xfs_freeze", 0);
 	atomic_set(&mp->m_active_trans, 0);
+	mp->m_cxfstype = XFS_CXFS_NOT;
 
 	return mp;
 }	/* xfs_mount_init */
@@ -217,9 +219,13 @@
 	 * More sanity checking. These were stolen directly from
 	 * xfs_repair.
 	 */
-	if (sbp->sb_blocksize <= 0					||
-	    sbp->sb_agcount <= 0					||
-	    sbp->sb_sectsize <= 0					||
+	if (sbp->sb_agcount <= 0					||
+	    sbp->sb_sectsize < XFS_MIN_SECTORSIZE			||
+	    sbp->sb_sectsize > XFS_MAX_SECTORSIZE			||
+	    sbp->sb_sectlog < XFS_MIN_SECTORSIZE_LOG			||
+	    sbp->sb_sectlog > XFS_MAX_SECTORSIZE_LOG			||
+	    sbp->sb_blocksize < XFS_MIN_BLOCKSIZE			||
+	    sbp->sb_blocksize > XFS_MAX_BLOCKSIZE			||
 	    sbp->sb_blocklog < XFS_MIN_BLOCKSIZE_LOG			||
 	    sbp->sb_blocklog > XFS_MAX_BLOCKSIZE_LOG			||
 	    sbp->sb_inodesize < XFS_DINODE_MIN_SIZE			||
@@ -232,7 +238,7 @@
 	}
 
 	/*
-	 * sanity check ag count, size fields against data size field
+	 * Sanity check AG count, size fields against data size field
 	 */
 	if (sbp->sb_dblocks == 0 ||
 	    sbp->sb_dblocks >
@@ -261,14 +267,15 @@
 	 */
 	if (sbp->sb_blocksize > PAGE_SIZE) {
 		cmn_err(CE_WARN,
-		"XFS: Trying to mount file system with blocksize %d bytes",
+		"XFS: Attempted to mount file system with blocksize %d bytes",
 			sbp->sb_blocksize);
 		cmn_err(CE_WARN,
-		"XFS: Only page-sized (%d bytes) or less blocksizes currently work.",
+		"XFS: Only page-sized (%d) or less blocksizes currently work.",
 			PAGE_SIZE);
 		return XFS_ERROR(EWRONGFS);
 	}
-	return (0);
+
+	return 0;
 }
 
 void
@@ -467,6 +474,7 @@
 	mp->m_maxagi = mp->m_sb.sb_agcount;
 	mp->m_blkbit_log = sbp->sb_blocklog + XFS_NBBYLOG;
 	mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
+	mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
 	mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1;
 	mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog;
 	mp->m_litino = sbp->sb_inodesize -
@@ -560,7 +568,7 @@
 	xfs_daddr_t	d;
 	extern xfs_ioops_t xfs_iocore_xfs;	/* from xfs_iocore.c */
 	__uint64_t	ret64;
-	uint		quotaflags, quotaondisk, rootqcheck, needquotacheck;
+	uint		quotaflags, quotaondisk;
 	uint		uquotaondisk = 0, gquotaondisk = 0;
 	boolean_t	needquotamount;
 	__int64_t	update_flags;
@@ -755,7 +763,9 @@
 		goto error1;
 	}
 	if (!noio) {
-		error = xfs_read_buf(mp, mp->m_ddev_targp, d - 1, 1, 0, &bp);
+		error = xfs_read_buf(mp, mp->m_ddev_targp,
+				     d - XFS_FSS_TO_BB(mp, 1),
+				     XFS_FSS_TO_BB(mp, 1), 0, &bp);
 		if (!error) {
 			xfs_buf_relse(bp);
 		} else {
@@ -775,7 +785,9 @@
 			error = XFS_ERROR(E2BIG);
 			goto error1;
 		}
-		error = xfs_read_buf(mp, mp->m_logdev_targp, d - 1, 1, 0, &bp);
+		error = xfs_read_buf(mp, mp->m_logdev_targp,
+				     d - XFS_FSB_TO_BB(mp, 1),
+				     XFS_FSB_TO_BB(mp, 1), 0, &bp);
 		if (!error) {
 			xfs_buf_relse(bp);
 		} else {
@@ -967,21 +979,13 @@
 
 	/*
 	 * Figure out if we'll need to do a quotacheck.
-	 * The requirements are a little different depending on whether
-	 * this fs is root or not.
 	 */
-	rootqcheck = (mp->m_dev == rootdev && quotaondisk && 
-		      ((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT &&
-			(mp->m_sb.sb_qflags & XFS_UQUOTA_CHKD) == 0) ||
-		       (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT &&
-			(mp->m_sb.sb_qflags & XFS_GQUOTA_CHKD) == 0)));
-	needquotacheck = rootqcheck ||	XFS_QM_NEED_QUOTACHECK(mp);
 	if (XFS_IS_QUOTA_ON(mp) || quotaondisk) {
 		/*
 		 * Call mount_quotas at this point only if we won't have to do
 		 * a quotacheck.
 		 */
-		if (quotaondisk && !needquotacheck) {
+		if (quotaondisk && !XFS_QM_NEED_QUOTACHECK(mp)) {
 			/*
 			 * If the xfs quota code isn't installed,
 			 * we have to reset the quotachk'd bit.
@@ -1020,10 +1024,6 @@
 	if (needquotamount) {
 		ASSERT(mp->m_qflags == 0);
 		mp->m_qflags = quotaflags;
-		rootqcheck = (mp->m_dev == rootdev && needquotacheck);
-		if (rootqcheck && (error = xfs_dev_is_read_only(mp,
-					"quotacheck")))
-			goto error2;
 		if (xfs_qm_mount_quotas(mp))
 			xfs_mount_reset_sbqflags(mp);
 	}
@@ -1190,7 +1190,7 @@
 		XFS_BUF_UNDELAYWRITE(sbp);
 		XFS_BUF_WRITE(sbp);
 		XFS_BUF_UNASYNC(sbp);
-		ASSERT(XFS_BUF_TARGET_DEV(sbp) == mp->m_dev);
+		ASSERT(XFS_BUF_TARGET(sbp) == mp->m_ddev_targp);
 		xfsbdstrat(mp, sbp);
 		/* Nevermind errors we might get here. */
 		error = xfs_iowait(sbp);
diff -Nru a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
--- a/fs/xfs/xfs_mount.h	Mon Dec  9 18:46:34 2002
+++ b/fs/xfs/xfs_mount.h	Mon Dec  9 18:46:34 2002
@@ -232,6 +232,7 @@
 	__uint8_t		m_mk_sharedro;	/* mark shared ro on unmount */
 	__uint8_t		m_inode_quiesce;/* call quiesce on new inodes.
 						   field governed by m_ilock */
+	__uint8_t		m_sectbb_log;	/* sectlog - BBSHIFT */
 	__uint8_t		m_dirversion;	/* 1 or 2 */
 	xfs_dirops_t		m_dirops;	/* table of dir funcs */
 	int			m_dirblksize;	/* directory block sz--bytes */
@@ -265,7 +266,7 @@
 #if XFS_BIG_FILESYSTEMS
 #define XFS_MOUNT_INO64		0x00000002
 #endif
-#define XFS_MOUNT_ROOTQCHECK	0x00000004
+			     /* 0x00000004	-- currently unused */
 			     /* 0x00000008	-- currently unused */
 #define XFS_MOUNT_FS_SHUTDOWN	0x00000010	/* atomic stop of all filesystem
 						   operations, typically for
diff -Nru a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
--- a/fs/xfs/xfs_qm.c	Mon Dec  9 18:46:34 2002
+++ b/fs/xfs/xfs_qm.c	Mon Dec  9 18:46:34 2002
@@ -301,27 +301,24 @@
 
 /*
  * This is called from xfs_mountfs to start quotas and initialize all
- * necessary data structures like quotainfo, and in the rootfs's case
- * xfs_Gqm. This is also responsible for running a quotacheck as necessary.
- * We are guaranteed that the superblock is consistently read in at this
- * point.
+ * necessary data structures like quotainfo.  This is also responsible for
+ * running a quotacheck as necessary.  We are guaranteed that the superblock
+ * is consistently read in at this point.
  */
 int
 xfs_qm_mount_quotas(
 	xfs_mount_t	*mp)
 {
-	unsigned long		s;
-	int		error;
+	unsigned long	s;
+	int		error = 0;
 	uint		sbf;
 
-	error = 0;
 	/*
-	 * If a non-root file system had quotas running earlier, but decided
-	 * to mount without -o quota/pquota options, revoke the quotachecked
-	 * license, and bail out.
+	 * If a file system had quotas running earlier, but decided to
+	 * mount without -o quota/uquota/gquota options, revoke the
+	 * quotachecked license, and bail out.
 	 */
 	if (! XFS_IS_QUOTA_ON(mp) &&
-	    (mp->m_dev != rootdev) &&
 	    (mp->m_sb.sb_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT))) {
 		mp->m_qflags = 0;
 		goto write_changes;
@@ -342,32 +339,6 @@
 #if defined(DEBUG) && defined(XFS_LOUD_RECOVERY)
 	cmn_err(CE_NOTE, "Attempting to turn on disk quotas.");
 #endif
-	/*
-	 * If this is the root file system, mark flags in mount struct first.
-	 * We couldn't do this earlier because we didn't have the superblock
-	 * read in.
-	 */
-	if (mp->m_dev == rootdev) {
-		ASSERT(XFS_SB_VERSION_HASQUOTA(&mp->m_sb));
-		ASSERT(mp->m_sb.sb_qflags &
-		       (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT));
-		if (xfs_Gqm == NULL) {
-			if ((xfs_Gqm = xfs_qm_init()) == NULL) {
-				mp->m_qflags = 0;
-				error = EINVAL;
-				goto write_changes;
-			}
-		}
-		mp->m_qflags = mp->m_sb.sb_qflags;
-		if (mp->m_qflags & XFS_UQUOTA_ACCT)
-			mp->m_qflags |= XFS_UQUOTA_ACTIVE;
-		if (mp->m_qflags & XFS_GQUOTA_ACCT)
-			mp->m_qflags |= XFS_GQUOTA_ACTIVE;
-		/*
-		 * The quotainode of the root file system may or may not
-		 * exist at this point.
-		 */
-	}
 
 	ASSERT(XFS_IS_QUOTA_RUNNING(mp));
 	/*
@@ -545,20 +516,6 @@
 		if (error)
 			return (error);
 
-		/*
-		 * If this is the root filesystem doing a quotacheck,
-		 * we should do periodic bflushes. This is because there's
-		 * no bflushd at this point.
-		 */
-		if (mp->m_flags & XFS_MOUNT_ROOTQCHECK) {
-			if (++niters == XFS_QM_MAX_DQCLUSTER_LOGSZ) {
-				xfs_log_force(mp, (xfs_lsn_t)0,
-					      XFS_LOG_FORCE | XFS_LOG_SYNC);
-				XFS_bflush(mp->m_ddev_targp);
-				niters = 0;
-			}
-		}
-
 		xfs_qm_mplist_lock(mp);
 		if (recl != XFS_QI_MPLRECLAIMS(mp)) {
 			xfs_qm_mplist_unlock(mp);
@@ -1569,22 +1526,6 @@
 					     XFS_DQ_USER : XFS_DQ_GROUP);
 		xfs_bdwrite(mp, bp);
 		/*
-		 * When quotachecking the root filesystem,
-		 * we may not have bdflush, and we may fill
-		 * up all available freebufs.
-		 * The workaround here is to push on the
-		 * log and do a bflush on the rootdev
-		 * periodically.
-		 */
-		if (mp->m_flags & XFS_MOUNT_ROOTQCHECK) {
-			if (++notcommitted == incr) {
-				xfs_log_force(mp, (xfs_lsn_t)0,
-					      XFS_LOG_FORCE | XFS_LOG_SYNC);
-				XFS_bflush(mp->m_ddev_targp);
-				notcommitted = 0;
-			}
-		}
-		/*
 		 * goto the next block.
 		 */
 		bno++;
@@ -1982,7 +1923,6 @@
 
  error_return:
 	cmn_err(CE_NOTE, "XFS quotacheck %s: Done.", mp->m_fsname);
-	mp->m_flags &= ~(XFS_MOUNT_ROOTQCHECK);
 	return (error);
 }
 
@@ -2034,9 +1974,9 @@
 	/*
 	 * Create the two inodes, if they don't exist already. The changes
 	 * made above will get added to a transaction and logged in one of
-	 * the qino_alloc calls below.
+	 * the qino_alloc calls below.  If the device is readonly,
+	 * temporarily switch to read-write to do this.
 	 */
-
 	if (XFS_IS_UQUOTA_ON(mp) && uip == NULL) {
 		if ((error = xfs_qm_qino_alloc(mp, &uip,
 					      sbflags | XFS_SB_UQUOTINO,
@@ -2146,20 +2086,6 @@
 		if (XFS_DQ_IS_DIRTY(dqp)) {
 			xfs_dqtrace_entry(dqp, "DQSHAKE: DQDIRTY");
 			/*
-			 * We'll be doing a dqflush, and it is
-			 * possible to fill up the entire buffer cache
-			 * with dirty delayed write buffers when doing
-			 * this on a root filesystem, if bdflush isn't
-			 * running. So, do a flush periodically.
-			 */
-			if (dqp->q_mount->m_flags & XFS_MOUNT_ROOTQCHECK) {
-				if (!(++nflushes % XFS_QM_MAX_DQCLUSTER_LOGSZ)){
-					xfs_log_force(dqp->q_mount, (xfs_lsn_t)0,
-						 XFS_LOG_FORCE | XFS_LOG_SYNC);
-					XFS_bflush(dqp->q_mount->m_ddev_targp);
-				}
-			}
-			/*
 			 * We flush it delayed write, so don't bother
 			 * releasing the mplock.
 			 */
@@ -2329,21 +2255,6 @@
 		 */
 		if (XFS_DQ_IS_DIRTY(dqp)) {
 			xfs_dqtrace_entry(dqp, "DQRECLAIM: DQDIRTY");
-			/*
-			 * We'll be doing a dqflush, and it is
-			 * possible to fill up the entire buffer cache
-			 * with dirty delayed write buffers when doing
-			 * this on a root filesystem, if bdflush isn't
-			 * running. So, do a flush periodically.
-			 */
-			if (dqp->q_mount->m_flags & XFS_MOUNT_ROOTQCHECK) {
-				if (!(++nflushes % XFS_QM_MAX_DQCLUSTER_LOGSZ)) {
-					xfs_log_force(dqp->q_mount, (xfs_lsn_t)0,
-						XFS_LOG_FORCE | XFS_LOG_SYNC);
-					XFS_bflush(dqp->q_mount->m_ddev_targp);
-				}
-			}
-
 			/*
 			 * We flush it delayed write, so don't bother
 			 * releasing the freelist lock.
diff -Nru a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
--- a/fs/xfs/xfs_qm_syscalls.c	Mon Dec  9 18:46:50 2002
+++ b/fs/xfs/xfs_qm_syscalls.c	Mon Dec  9 18:46:50 2002
@@ -99,8 +99,6 @@
 		return -xfs_qm_scall_quotaon(mp, qflags);
 	case Q_XQUOTAOFF:
 		qflags = xfs_qm_import_flags(flags);
-		if (mp->m_dev == rootdev)
-			return -xfs_qm_scall_quotaoff(mp, qflags, B_FALSE);
 		if (!XFS_IS_QUOTA_ON(mp))
 			return -ESRCH;
 		return -xfs_qm_scall_quotaoff(mp, qflags, B_FALSE);
@@ -169,17 +167,16 @@
 	int			error;
 	uint			inactivate_flags;
 	xfs_qoff_logitem_t	*qoffstart;
-	uint			sbflags, newflags;
 	int			nculprits;
 
 	if (!force && !capable(CAP_SYS_ADMIN))
 		return XFS_ERROR(EPERM);
 	/*
-	 * Only root file system can have quotas enabled on disk but not
-	 * in core. Note that quota utilities (like quotaoff) _expect_
+	 * No file system can have quotas enabled on disk but not in core.
+	 * Note that quota utilities (like quotaoff) _expect_
 	 * errno == EEXIST here.
 	 */
-	if (mp->m_dev != rootdev && (mp->m_qflags & flags) == 0)
+	if ((mp->m_qflags & flags) == 0)
 		return XFS_ERROR(EEXIST);
 	error = 0;
 
@@ -191,54 +188,14 @@
 	 * critical thing.
 	 * If quotaoff, then we must be dealing with the root filesystem.
 	 */
-	ASSERT(mp->m_quotainfo || mp->m_dev == rootdev);
+	ASSERT(mp->m_quotainfo);
 	if (mp->m_quotainfo)
 		mutex_lock(&(XFS_QI_QOFFLOCK(mp)), PINOD);
 
-	/*
-	 * Root file system may or may not have quotas on in core.
-	 * We have to perform the quotaoff accordingly.
-	 */
-	if (mp->m_dev == rootdev) {
-		s = XFS_SB_LOCK(mp);
-		sbflags = mp->m_sb.sb_qflags;
-		if ((mp->m_qflags & flags) == 0) {
-			mp->m_sb.sb_qflags &= ~(flags);
-			newflags = mp->m_sb.sb_qflags;
-			XFS_SB_UNLOCK(mp, s);
-			if (mp->m_quotainfo)
-				mutex_unlock(&(XFS_QI_QOFFLOCK(mp)));
-			if (sbflags != newflags)
-			      error = xfs_qm_write_sb_changes(mp, XFS_SB_QFLAGS);
-			return (error);
-		}
-		XFS_SB_UNLOCK(mp, s);
-
-		if ((sbflags & flags) != (mp->m_qflags & flags)) {
-			/*
-			 * This can happen only with grp+usr quota
-			 * combination. Note: 1) accounting cannot be turned
-			 * off without enforcement also getting turned off.
-			 * 2) Every flag that exists in mpqflags MUST exist
-			 * in sbqflags (but not vice versa).
-			 * which means at this point sbqflags = UQ+GQ+..,
-			 * and mpqflags = UQ or GQ.
-			 */
-			ASSERT(sbflags & XFS_GQUOTA_ACCT);
-			ASSERT((sbflags & XFS_ALL_QUOTA_ACCT) !=
-			       (mp->m_qflags & XFS_ALL_QUOTA_ACCT));
-
-			qdprintk("quotaoff, sbflags=%x flags=%x m_qflags=%x\n",
-				sbflags, flags, mp->m_qflags);
-			/* XXX TBD Finish this for group quota support */
-			/* We need to update the SB and mp separately */
-			return XFS_ERROR(EINVAL);
-		}
-	}
 	ASSERT(mp->m_quotainfo);
 
 	/*
-	 * if we're just turning off quota enforcement, change mp and go.
+	 * If we're just turning off quota enforcement, change mp and go.
 	 */
 	if ((flags & XFS_ALL_QUOTA_ACCT) == 0) {
 		mp->m_qflags &= ~(flags);
@@ -272,8 +229,8 @@
 	}
 
 	/*
-	 * Nothing to do? Don't complain.
-	 * This happens when we're just turning off quota enforcement.
+	 * Nothing to do?  Don't complain. This happens when we're just
+	 * turning off quota enforcement.
 	 */
 	if ((mp->m_qflags & flags) == 0) {
 		mutex_unlock(&(XFS_QI_QOFFLOCK(mp)));
@@ -326,9 +283,8 @@
 	 * So, if we couldn't purge all the dquots from the filesystem,
 	 * we can't get rid of the incore data structures.
 	 */
-	while ((nculprits = xfs_qm_dqpurge_all(mp, dqtype|XFS_QMOPT_QUOTAOFF))) {
+	while ((nculprits = xfs_qm_dqpurge_all(mp, dqtype|XFS_QMOPT_QUOTAOFF)))
 		delay(10 * nculprits);
-	}
 
 	/*
 	 * Transactions that had started before ACTIVE state bit was cleared
@@ -406,11 +362,9 @@
 
 
 /*
- * This does two separate functions:
- * Switch on quotas for the root file system. This will take effect only
- * on reboot.
- * Switch on (a given) quota enforcement for both root and non-root filesystems.
- * This takes effect immediately.
+ * Switch on (a given) quota enforcement for a filesystem.  This takes
+ * effect immediately.
+ * (Switching on quota accounting must be done at mount time.)
  */
 STATIC int
 xfs_qm_scall_quotaon(
@@ -422,37 +376,26 @@
 	uint		qf;
 	uint		accflags;
 	__int64_t	sbflags;
-	boolean_t	rootfs;
-	boolean_t	delay;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return XFS_ERROR(EPERM);
 
-	rootfs = (boolean_t) (mp->m_dev == rootdev);
-
 	flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD);
 	/*
-	 * If caller wants to turn on accounting on /, but accounting
-	 * is already turned on, ignore ACCTing flags.
-	 * Switching on quota accounting for non-root filesystems
-	 * must be done at mount time.
+	 * Switching on quota accounting must be done at mount time.
 	 */
 	accflags = flags & XFS_ALL_QUOTA_ACCT;
-	if (!rootfs ||
-	    (accflags && rootfs && ((mp->m_qflags & accflags) == accflags))) {
-		flags &= ~(XFS_ALL_QUOTA_ACCT);
-	}
+	flags &= ~(XFS_ALL_QUOTA_ACCT);
 
 	sbflags = 0;
-	delay = (boolean_t) ((flags & XFS_ALL_QUOTA_ACCT) != 0);
 
 	if (flags == 0) {
 		qdprintk("quotaon: zero flags, m_qflags=%x\n", mp->m_qflags);
 		return XFS_ERROR(EINVAL);
 	}
 
-	/* Only rootfs can turn on quotas with a delayed effect */
-	ASSERT(!delay || rootfs);
+	/* No fs can turn on quotas with a delayed effect */
+	ASSERT((flags & XFS_ALL_QUOTA_ACCT) == 0);
 
 	/*
 	 * Can't enforce without accounting. We check the superblock
@@ -477,22 +420,6 @@
 		return XFS_ERROR(EEXIST);
 
 	/*
-	 * Change superblock version (if needed) for the root filesystem
-	 */
-	if (rootfs && !XFS_SB_VERSION_HASQUOTA(&mp->m_sb)) {
-		qdprintk("Old superblock version %x\n", mp->m_sb.sb_versionnum);
-		s = XFS_SB_LOCK(mp);
-		XFS_SB_VERSION_ADDQUOTA(&mp->m_sb);
-		mp->m_sb.sb_uquotino = NULLFSINO;
-		mp->m_sb.sb_gquotino = NULLFSINO;
-		mp->m_sb.sb_qflags = 0;
-		XFS_SB_UNLOCK(mp, s);
-		qdprintk("Converted to version %x\n", mp->m_sb.sb_versionnum);
-		sbflags |= (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO |
-			    XFS_SB_GQUOTINO | XFS_SB_QFLAGS);
-	}
-
-	/*
 	 * Change sb_qflags on disk but not incore mp->qflags
 	 * if this is the root filesystem.
 	 */
@@ -511,11 +438,9 @@
 	if ((error = xfs_qm_write_sb_changes(mp, sbflags)))
 		return (error);
 	/*
-	 * If we had just turned on quotas (ondisk) for rootfs, or if we aren't
-	 * trying to switch on quota enforcement, we are done.
+	 * If we aren't trying to switch on quota enforcement, we are done.
 	 */
-	if (delay ||
-	    ((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) !=
+	if  (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) !=
 	     (mp->m_qflags & XFS_UQUOTA_ACCT)) ||
 	    (flags & XFS_ALL_QUOTA_ENFD) == 0)
 		return (0);
@@ -524,8 +449,7 @@
 		return XFS_ERROR(ESRCH);
 
 	/*
-	 * Switch on quota enforcement in core. This applies to both root
-	 * and non-root file systems.
+	 * Switch on quota enforcement in core.
 	 */
 	mutex_lock(&(XFS_QI_QOFFLOCK(mp)), PINOD);
 	mp->m_qflags |= (flags & XFS_ALL_QUOTA_ENFD);
@@ -546,7 +470,6 @@
 {
 	xfs_inode_t	*uip, *gip;
 	boolean_t	tempuqip, tempgqip;
-	__uint16_t	sbflags;
 
 	uip = gip = NULL;
 	tempuqip = tempgqip = B_FALSE;
@@ -561,20 +484,6 @@
 	out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags &
 							(XFS_ALL_QUOTA_ACCT|
 							 XFS_ALL_QUOTA_ENFD));
-	/*
-	 * If the qflags are different on disk, as can be the case when
-	 * root filesystem's quotas are being turned on, return them in the
-	 * HI 8 bits.
-	 */
-	if (mp->m_dev == rootdev) {
-		sbflags = (__uint16_t) xfs_qm_export_flags(mp->m_sb.sb_qflags &
-							   (XFS_ALL_QUOTA_ACCT|
-							    XFS_ALL_QUOTA_ENFD));
-		ASSERT((out->qs_flags & 0xff00) == 0);
-		if (sbflags != out->qs_flags)
-			out->qs_flags |= ((sbflags & 0x00ff) << 8);
-	}
-
 	out->qs_pad = 0;
 	out->qs_uquota.qfs_ino = mp->m_sb.sb_uquotino;
 	out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino;
diff -Nru a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
--- a/fs/xfs/xfs_rename.c	Mon Dec  9 18:46:37 2002
+++ b/fs/xfs/xfs_rename.c	Mon Dec  9 18:46:37 2002
@@ -78,8 +78,8 @@
 xfs_lock_for_rename(
 	xfs_inode_t	*dp1,	/* old (source) directory inode */
 	xfs_inode_t	*dp2,	/* new (target) directory inode */
-	struct dentry	*dentry1, /* old entry name */
-	struct dentry	*dentry2, /* new entry name */
+	vname_t		*dentry1, /* old entry name */
+	vname_t		*dentry2, /* new entry name */
 	xfs_inode_t	**ipp1, /* inode of old entry */
 	xfs_inode_t	**ipp2, /* inode of new entry, if it
 				   already exists, NULL otherwise. */
@@ -224,9 +224,9 @@
 int
 xfs_rename(
 	bhv_desc_t	*src_dir_bdp,
-	struct dentry	*src_dentry,
+	vname_t		*src_dentry,
 	vnode_t		*target_dir_vp,
-	struct dentry	*target_dentry,
+	vname_t		*target_dentry,
 	cred_t		*credp)
 {
 	xfs_trans_t	*tp;
@@ -246,8 +246,8 @@
 	int		spaceres;
 	int		target_link_zero = 0;
 	int		num_inodes;
-	char		*src_name = (char *)src_dentry->d_name.name;
-	char		*target_name = (char *)target_dentry->d_name.name;
+	char		*src_name = VNAME(src_dentry);
+	char		*target_name = VNAME(target_dentry);
 	int		src_namelen;
 	int		target_namelen;
 #ifdef DEBUG
@@ -268,10 +268,10 @@
 	if (target_dir_bdp == NULL) {
 		return XFS_ERROR(EXDEV);
 	}
-	src_namelen = src_dentry->d_name.len;
+	src_namelen = VNAMELEN(src_dentry);
 	if (src_namelen >= MAXNAMELEN)
 		return XFS_ERROR(ENAMETOOLONG);
-	target_namelen = target_dentry->d_name.len;
+	target_namelen = VNAMELEN(target_dentry);
 	if (target_namelen >= MAXNAMELEN)
 		return XFS_ERROR(ENAMETOOLONG);
 	src_dp = XFS_BHVTOI(src_dir_bdp);
diff -Nru a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
--- a/fs/xfs/xfs_rtalloc.c	Mon Dec  9 18:46:35 2002
+++ b/fs/xfs/xfs_rtalloc.c	Mon Dec  9 18:46:35 2002
@@ -1925,7 +1925,8 @@
 	 * Read in the last block of the device, make sure it exists.
 	 */
 	error = xfs_read_buf(mp, mp->m_rtdev_targp,
-		XFS_FSB_TO_BB(mp, in->newblocks) - 1, 1, 0, &bp);
+			XFS_FSB_TO_BB(mp, in->newblocks - 1),
+			XFS_FSB_TO_BB(mp, 1), 0, &bp);
 	if (error)
 		return error;
 	ASSERT(bp);
@@ -2285,7 +2286,9 @@
 			(unsigned long long) mp->m_sb.sb_rblocks);
 		return XFS_ERROR(E2BIG);
 	}
-	error = xfs_read_buf(mp, mp->m_rtdev_targp, d - 1, 1, 0, &bp);
+	error = xfs_read_buf(mp, mp->m_rtdev_targp,
+				XFS_FSB_TO_BB(mp, d - 1),
+				XFS_FSB_TO_BB(mp, 1), 0, &bp);
 	if (error) {
 		cmn_err(CE_WARN,
 	"XFS: realtime mount -- xfs_read_buf failed, returned %d", error);
diff -Nru a/fs/xfs/xfs_rw.c b/fs/xfs/xfs_rw.c
--- a/fs/xfs/xfs_rw.c	Mon Dec  9 18:46:51 2002
+++ b/fs/xfs/xfs_rw.c	Mon Dec  9 18:46:51 2002
@@ -116,16 +116,16 @@
 		return;
 
 	if (flags & XFS_CORRUPT_INCORE) {
-		cmn_err(CE_ALERT,
+		xfs_cmn_err(XFS_PTAG_SHUTDOWN_CORRUPT, CE_ALERT, mp,
     "Corruption of in-memory data detected.  Shutting down filesystem: %s",
 			mp->m_fsname);
 	} else if (!(flags & XFS_FORCE_UMOUNT)) {
 		if (logerror) {
-			cmn_err(CE_ALERT,
+			xfs_cmn_err(XFS_PTAG_SHUTDOWN_LOGERROR, CE_ALERT, mp,
 			"Log I/O Error Detected.  Shutting down filesystem: %s",
 				mp->m_fsname);
 		} else if (!(flags & XFS_SHUTDOWN_REMOTE_REQ)) {
-			cmn_err(CE_ALERT,
+			xfs_cmn_err(XFS_PTAG_SHUTDOWN_IOERROR, CE_ALERT, mp,
 				"I/O Error Detected.  Shutting down filesystem: %s",
 				mp->m_fsname);
 		}
diff -Nru a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h
--- a/fs/xfs/xfs_sb.h	Mon Dec  9 18:46:36 2002
+++ b/fs/xfs/xfs_sb.h	Mon Dec  9 18:46:36 2002
@@ -34,7 +34,7 @@
 
 /*
  * Super block
- * Fits into a 512-byte buffer at daddr_t 0 of each allocation group.
+ * Fits into a sector-sized buffer at address 0 of each allocation group.
  * Only the first of these is ever updated except during growfs.
  */
 
@@ -57,6 +57,7 @@
 #define XFS_SB_VERSION_DALIGNBIT	0x0100
 #define XFS_SB_VERSION_SHAREDBIT	0x0200
 #define XFS_SB_VERSION_LOGV2BIT		0x0400
+#define XFS_SB_VERSION_SECTORBIT	0x0800
 #define XFS_SB_VERSION_EXTFLGBIT	0x1000
 #define XFS_SB_VERSION_DIRV2BIT		0x2000
 #define XFS_SB_VERSION_OKSASHFBITS	\
@@ -69,7 +70,8 @@
 	 XFS_SB_VERSION_ALIGNBIT | \
 	 XFS_SB_VERSION_DALIGNBIT | \
 	 XFS_SB_VERSION_SHAREDBIT | \
-	 XFS_SB_VERSION_LOGV2BIT)
+	 XFS_SB_VERSION_LOGV2BIT | \
+	 XFS_SB_VERSION_SECTORBIT)
 #define XFS_SB_VERSION_OKSASHBITS	\
 	(XFS_SB_VERSION_NUMBITS | \
 	 XFS_SB_VERSION_REALFBITS | \
@@ -78,14 +80,15 @@
 	(XFS_SB_VERSION_NUMBITS | \
 	 XFS_SB_VERSION_OKREALFBITS | \
 	 XFS_SB_VERSION_OKSASHFBITS)
-#define XFS_SB_VERSION_MKFS(ia,dia,extflag,dirv2,na)	\
+#define XFS_SB_VERSION_MKFS(ia,dia,extflag,dirv2,na,sflag)	\
 	(((ia) || (dia) || (extflag) || (dirv2) || (na)) ? \
 		(XFS_SB_VERSION_4 | \
 		 ((ia) ? XFS_SB_VERSION_ALIGNBIT : 0) | \
 		 ((dia) ? XFS_SB_VERSION_DALIGNBIT : 0) | \
 		 ((extflag) ? XFS_SB_VERSION_EXTFLGBIT : 0) | \
 		 ((dirv2) ? XFS_SB_VERSION_DIRV2BIT : 0) | \
-		 ((na) ? XFS_SB_VERSION_LOGV2BIT : 0)) : \
+		 ((na) ? XFS_SB_VERSION_LOGV2BIT : 0) | \
+		 ((sflag) ? XFS_SB_VERSION_SECTORBIT : 0)) : \
 		XFS_SB_VERSION_1)
 
 typedef struct xfs_sb
@@ -140,7 +143,8 @@
 	__uint32_t	sb_unit;	/* stripe or raid unit */
 	__uint32_t	sb_width;	/* stripe or raid width */
 	__uint8_t	sb_dirblklog;	/* log2 of dir block size (fsbs) */
-	__uint8_t	sb_dummy[3];	/* padding */
+	__uint8_t	sb_logsectlog;	/* log2 of the log sector size */
+	__uint16_t	sb_logsectsize;	/* sector size for the log, bytes */
 	__uint32_t	sb_logsunit;	/* stripe unit size for the log */
 } xfs_sb_t;
 
@@ -159,7 +163,7 @@
 	XFS_SBS_IFREE, XFS_SBS_FDBLOCKS, XFS_SBS_FREXTENTS, XFS_SBS_UQUOTINO,
 	XFS_SBS_GQUOTINO, XFS_SBS_QFLAGS, XFS_SBS_FLAGS, XFS_SBS_SHARED_VN,
 	XFS_SBS_INOALIGNMT, XFS_SBS_UNIT, XFS_SBS_WIDTH, XFS_SBS_DIRBLKLOG,
-	XFS_SBS_DUMMY, XFS_SBS_LOGSUNIT,
+	XFS_SBS_LOGSECTLOG, XFS_SBS_LOGSECTSIZE, XFS_SBS_LOGSUNIT,
 	XFS_SBS_FIELDCOUNT
 } xfs_sb_field_t;
 
@@ -440,11 +444,20 @@
 		((sbp)->sb_versionnum & ~XFS_SB_VERSION_EXTFLGBIT))
 #endif
 
+#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_HASSECTOR)
+int xfs_sb_version_hassector(xfs_sb_t *sbp);
+#define XFS_SB_VERSION_HASSECTOR(sbp)   xfs_sb_version_hassector(sbp)
+#else
+#define XFS_SB_VERSION_HASSECTOR(sbp)   \
+	((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
+	((sbp)->sb_versionnum & XFS_SB_VERSION_SECTORBIT))
+#endif
+
 /*
  * end of superblock version macros
  */
 
-#define XFS_SB_DADDR	((xfs_daddr_t)0)		/* daddr in filesystem/ag */
+#define XFS_SB_DADDR	((xfs_daddr_t)0)	/* daddr in filesystem/ag */
 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_BLOCK)
 xfs_agblock_t xfs_sb_block(struct xfs_mount *mp);
 #define XFS_SB_BLOCK(mp)	xfs_sb_block(mp)
@@ -474,6 +487,27 @@
 			 XFS_FSB_TO_AGBNO(mp,fsbno))
 #endif
 
+#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BUF_TO_SBP)
+xfs_sb_t *xfs_buf_to_sbp(struct xfs_buf *bp);
+#define XFS_BUF_TO_SBP(bp)	xfs_buf_to_sbp(bp)
+#else
+#define XFS_BUF_TO_SBP(bp)	((xfs_sb_t *)XFS_BUF_PTR(bp))
+#endif
+
+/*
+ * File system sector to basic block conversions.
+ */
+#define XFS_FSS_TO_BB(mp,sec)	((sec) << (mp)->m_sectbb_log)
+#define XFS_BB_TO_FSS(mp,bb)	\
+	(((bb) + (XFS_FSS_TO_BB(mp,1) - 1)) >> (mp)->m_sectbb_log)
+#define XFS_BB_TO_FSST(mp,bb)	((bb) >> (mp)->m_sectbb_log)
+
+/*
+ * File system sector to byte conversions.
+ */
+#define XFS_FSS_TO_B(mp,sectno)	((xfs_fsize_t)(sectno) << (mp)->m_sb.sb_sectlog)
+#define XFS_B_TO_FSST(mp,b)	(((__uint64_t)(b)) >> (mp)->m_sb.sb_sectlog)
+
 /*
  * File system block to basic block conversions.
  */
@@ -486,18 +520,10 @@
 /*
  * File system block to byte conversions.
  */
-#define XFS_FSB_TO_B(mp,fsbno)	((xfs_fsize_t)(fsbno) << \
-				 (mp)->m_sb.sb_blocklog)
+#define XFS_FSB_TO_B(mp,fsbno)	((xfs_fsize_t)(fsbno) << (mp)->m_sb.sb_blocklog)
 #define XFS_B_TO_FSB(mp,b)	\
 	((((__uint64_t)(b)) + (mp)->m_blockmask) >> (mp)->m_sb.sb_blocklog)
 #define XFS_B_TO_FSBT(mp,b)	(((__uint64_t)(b)) >> (mp)->m_sb.sb_blocklog)
 #define XFS_B_FSB_OFFSET(mp,b)	((b) & (mp)->m_blockmask)
-
-#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_BUF_TO_SBP)
-xfs_sb_t *xfs_buf_to_sbp(struct xfs_buf *bp);
-#define XFS_BUF_TO_SBP(bp)	xfs_buf_to_sbp(bp)
-#else
-#define XFS_BUF_TO_SBP(bp)	((xfs_sb_t *)XFS_BUF_PTR(bp))
-#endif
 
 #endif	/* __XFS_SB_H__ */
diff -Nru a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
--- a/fs/xfs/xfs_trans.h	Mon Dec  9 18:46:50 2002
+++ b/fs/xfs/xfs_trans.h	Mon Dec  9 18:46:50 2002
@@ -1027,11 +1027,6 @@
 					xfs_agnumber_t ag,
 					xfs_extlen_t idx);
 
-/*
- * Not necessarily exported, but used outside a single file.
- */
-int		xfs_trans_lsn_danger(struct xfs_mount *, xfs_lsn_t);
-
 #endif	/* __KERNEL__ */
 
 #endif	/* __XFS_TRANS_H__ */
diff -Nru a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
--- a/fs/xfs/xfs_trans_buf.c	Mon Dec  9 18:46:34 2002
+++ b/fs/xfs/xfs_trans_buf.c	Mon Dec  9 18:46:34 2002
@@ -1013,7 +1013,7 @@
 			}
 
 			bp = blip->bli_buf;
-			if ((XFS_BUF_TARGET_DEV(bp) == target->pbr_dev) &&
+			if ((XFS_BUF_TARGET(bp) == target) &&
 			    (XFS_BUF_ADDR(bp) == blkno) &&
 			    (XFS_BUF_COUNT(bp) == len)) {
 				/*
@@ -1070,7 +1070,7 @@
 			}
 
 			bp = blip->bli_buf;
-			if ((XFS_BUF_TARGET_DEV(bp) == target->pbr_dev) &&
+			if ((XFS_BUF_TARGET(bp) == target) &&
 			    (XFS_BUF_ADDR(bp) == blkno) &&
 			    (XFS_BUF_COUNT(bp) == len)) {
 				/*
diff -Nru a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h
--- a/fs/xfs/xfs_types.h	Mon Dec  9 18:46:35 2002
+++ b/fs/xfs/xfs_types.h	Mon Dec  9 18:46:35 2002
@@ -151,7 +151,7 @@
 typedef __int64_t	xfs_sfiloff_t;	/* signed block number in a file */
 typedef __uint64_t	xfs_filblks_t;	/* number of blocks in a file */
 
-typedef __uint8_t	xfs_arch_t;	/* architecutre of an xfs fs */
+typedef __uint8_t	xfs_arch_t;	/* architecture of an xfs fs */
 
 /*
  * Null values for the types.
@@ -193,119 +193,6 @@
 	XFS_BTNUM_BNOi, XFS_BTNUM_CNTi, XFS_BTNUM_BMAPi, XFS_BTNUM_INOi,
 	XFS_BTNUM_MAX
 } xfs_btnum_t;
-
-
-#if defined(CONFIG_PROC_FS) && defined(__KERNEL__) && !defined(XFS_STATS_OFF)
-/*
- * XFS global statistics
- */
-struct xfsstats {
-# define XFSSTAT_END_EXTENT_ALLOC	4
-	__uint32_t		xs_allocx;
-	__uint32_t		xs_allocb;
-	__uint32_t		xs_freex;
-	__uint32_t		xs_freeb;
-# define XFSSTAT_END_ALLOC_BTREE	(XFSSTAT_END_EXTENT_ALLOC+4)
-	__uint32_t		xs_abt_lookup;
-	__uint32_t		xs_abt_compare;
-	__uint32_t		xs_abt_insrec;
-	__uint32_t		xs_abt_delrec;
-# define XFSSTAT_END_BLOCK_MAPPING	(XFSSTAT_END_ALLOC_BTREE+7)
-	__uint32_t		xs_blk_mapr;
-	__uint32_t		xs_blk_mapw;
-	__uint32_t		xs_blk_unmap;
-	__uint32_t		xs_add_exlist;
-	__uint32_t		xs_del_exlist;
-	__uint32_t		xs_look_exlist;
-	__uint32_t		xs_cmp_exlist;
-# define XFSSTAT_END_BLOCK_MAP_BTREE	(XFSSTAT_END_BLOCK_MAPPING+4)
-	__uint32_t		xs_bmbt_lookup;
-	__uint32_t		xs_bmbt_compare;
-	__uint32_t		xs_bmbt_insrec;
-	__uint32_t		xs_bmbt_delrec;
-# define XFSSTAT_END_DIRECTORY_OPS	(XFSSTAT_END_BLOCK_MAP_BTREE+4)
-	__uint32_t		xs_dir_lookup;
-	__uint32_t		xs_dir_create;
-	__uint32_t		xs_dir_remove;
-	__uint32_t		xs_dir_getdents;
-# define XFSSTAT_END_TRANSACTIONS	(XFSSTAT_END_DIRECTORY_OPS+3)
-	__uint32_t		xs_trans_sync;
-	__uint32_t		xs_trans_async;
-	__uint32_t		xs_trans_empty;
-# define XFSSTAT_END_INODE_OPS		(XFSSTAT_END_TRANSACTIONS+7)
-	__uint32_t		xs_ig_attempts;
-	__uint32_t		xs_ig_found;
-	__uint32_t		xs_ig_frecycle;
-	__uint32_t		xs_ig_missed;
-	__uint32_t		xs_ig_dup;
-	__uint32_t		xs_ig_reclaims;
-	__uint32_t		xs_ig_attrchg;
-# define XFSSTAT_END_LOG_OPS		(XFSSTAT_END_INODE_OPS+5)
-	__uint32_t		xs_log_writes;
-	__uint32_t		xs_log_blocks;
-	__uint32_t		xs_log_noiclogs;
-	__uint32_t		xs_log_force;
-	__uint32_t		xs_log_force_sleep;
-# define XFSSTAT_END_TAIL_PUSHING	(XFSSTAT_END_LOG_OPS+10)
-	__uint32_t		xs_try_logspace;
-	__uint32_t		xs_sleep_logspace;
-	__uint32_t		xs_push_ail;
-	__uint32_t		xs_push_ail_success;
-	__uint32_t		xs_push_ail_pushbuf;
-	__uint32_t		xs_push_ail_pinned;
-	__uint32_t		xs_push_ail_locked;
-	__uint32_t		xs_push_ail_flushing;
-	__uint32_t		xs_push_ail_restarts;
-	__uint32_t		xs_push_ail_flush;
-# define XFSSTAT_END_WRITE_CONVERT	(XFSSTAT_END_TAIL_PUSHING+2)
-	__uint32_t		xs_xstrat_quick;
-	__uint32_t		xs_xstrat_split;
-# define XFSSTAT_END_READ_WRITE_OPS	(XFSSTAT_END_WRITE_CONVERT+2)
-	__uint32_t		xs_write_calls;
-	__uint32_t		xs_read_calls;
-# define XFSSTAT_END_ATTRIBUTE_OPS	(XFSSTAT_END_READ_WRITE_OPS+4)
-	__uint32_t		xs_attr_get;
-	__uint32_t		xs_attr_set;
-	__uint32_t		xs_attr_remove;
-	__uint32_t		xs_attr_list;
-# define XFSSTAT_END_QUOTA_OPS		(XFSSTAT_END_ATTRIBUTE_OPS+8)
-	__uint32_t		xs_qm_dqreclaims;
-	__uint32_t		xs_qm_dqreclaim_misses;
-	__uint32_t		xs_qm_dquot_dups;
-	__uint32_t		xs_qm_dqcachemisses;
-	__uint32_t		xs_qm_dqcachehits;
-	__uint32_t		xs_qm_dqwants;
-	__uint32_t		xs_qm_dqshake_reclaims;
-	__uint32_t		xs_qm_dqinact_reclaims;
-# define XFSSTAT_END_INODE_CLUSTER	(XFSSTAT_END_QUOTA_OPS+3)
-	__uint32_t		xs_iflush_count;
-	__uint32_t		xs_icluster_flushcnt;
-	__uint32_t		xs_icluster_flushinode;
-# define XFSSTAT_END_VNODE_OPS		(XFSSTAT_END_INODE_CLUSTER+8)
-	__uint32_t		vn_active;	/* # vnodes not on free lists */
-	__uint32_t		vn_alloc;	/* # times vn_alloc called */
-	__uint32_t		vn_get;		/* # times vn_get called */
-	__uint32_t		vn_hold;	/* # times vn_hold called */
-	__uint32_t		vn_rele;	/* # times vn_rele called */
-	__uint32_t		vn_reclaim;	/* # times vn_reclaim called */
-	__uint32_t		vn_remove;	/* # times vn_remove called */
-	__uint32_t		vn_free;	/* # times vn_free called */
-/* Extra precision counters */
-	__uint64_t		xs_xstrat_bytes;
-	__uint64_t		xs_write_bytes;
-	__uint64_t		xs_read_bytes;
-};
-
-extern struct xfsstats xfsstats;
-
-# define XFS_STATS_INC(count)		( (count)++ )
-# define XFS_STATS_DEC(count)		( (count)-- )
-# define XFS_STATS_ADD(count, inc)	( (count) += (inc) )
-#else	/* !CONFIG_PROC_FS */
-# define XFS_STATS_INC(count)
-# define XFS_STATS_DEC(count)
-# define XFS_STATS_ADD(count, inc)
-#endif	/* !CONFIG_PROC_FS */
 
 
 /*
diff -Nru a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
--- a/fs/xfs/xfs_utils.c	Mon Dec  9 18:46:52 2002
+++ b/fs/xfs/xfs_utils.c	Mon Dec  9 18:46:52 2002
@@ -32,10 +32,6 @@
 
 #include <xfs.h>
 
-#ifdef CONFIG_PROC_FS
-struct xfsstats xfsstats;
-#endif
-
 /*
  * xfs_get_dir_entry is used to get a reference to an inode given
  * its parent directory inode and the name of the file.	 It does
@@ -45,11 +41,11 @@
  */
 int
 xfs_get_dir_entry(
-	struct dentry		*dentry,
-	xfs_inode_t		**ipp)
+	vname_t		*dentry,
+	xfs_inode_t	**ipp)
 {
-	vnode_t			*vp;
-	bhv_desc_t		*bdp;
+	vnode_t		*vp;
+	bhv_desc_t	*bdp;
 
 	ASSERT(dentry->d_inode);
 
@@ -66,24 +62,23 @@
 
 int
 xfs_dir_lookup_int(
-	bhv_desc_t		*dir_bdp,
-	uint			lock_mode,
-	struct dentry		*dentry,
-	xfs_ino_t		*inum,
-	xfs_inode_t		**ipp)
+	bhv_desc_t	*dir_bdp,
+	uint		lock_mode,
+	vname_t		*dentry,
+	xfs_ino_t	*inum,
+	xfs_inode_t	**ipp)
 {
 	vnode_t		*dir_vp;
 	xfs_inode_t	*dp;
 	int		error;
 
 	dir_vp = BHV_TO_VNODE(dir_bdp);
-	vn_trace_entry(dir_vp, "xfs_dir_lookup_int",
-		       (inst_t *)__return_address);
+	vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
 
 	dp = XFS_BHVTOI(dir_bdp);
 
 	error = XFS_DIR_LOOKUP(dp->i_mount, NULL, dp,
-			(char *)dentry->d_name.name, dentry->d_name.len, inum);
+				VNAME(dentry), VNAMELEN(dentry), inum);
 	if (!error) {
 		/*
 		 * Unlock the directory. We do this because we can't
diff -Nru a/fs/xfs/xfs_utils.h b/fs/xfs/xfs_utils.h
--- a/fs/xfs/xfs_utils.h	Mon Dec  9 18:46:52 2002
+++ b/fs/xfs/xfs_utils.h	Mon Dec  9 18:46:52 2002
@@ -37,66 +37,16 @@
 #define ITRACE(ip)	vn_trace_ref(XFS_ITOV(ip), __FILE__, __LINE__, \
 				(inst_t *)__return_address)
 
-struct bhv_desc;
-struct cred;
-struct vnode;
-struct xfs_inode;
-struct xfs_mount;
-struct xfs_trans;
-
-extern int
-xfs_rename(
-	struct bhv_desc *src_dir_bdp,
-	struct dentry	*src_dentry,
-	struct vnode	*target_dir_vp,
-	struct dentry	*target_dentry,
-	struct cred	*credp);
-
-extern int
-xfs_get_dir_entry(
-	struct dentry		*dentry,
-	xfs_inode_t		**ipp);
-
-extern int
-xfs_dir_lookup_int(
-	struct bhv_desc		*dir_bdp,
-	uint			lock_mode,
-	struct dentry		*dentry,
-	xfs_ino_t		*inum,
-	struct xfs_inode	**ipp);
-
-extern int
-xfs_truncate_file(
-	struct xfs_mount	*mp,
-	struct xfs_inode	*ip);
-
-extern int
-xfs_dir_ialloc(
-	struct xfs_trans	**tpp,
-	struct xfs_inode	*dp,
-	mode_t			mode,
-	nlink_t			nlink,
-	xfs_dev_t		rdev,
-	struct cred		*credp,
-	prid_t			prid,
-	int			okalloc,
-	struct xfs_inode	**ipp,
-	int			*committed);
-
-extern int
-xfs_droplink(
-	struct xfs_trans	*tp,
-	struct xfs_inode	*ip);
-
-extern int
-xfs_bumplink(
-	struct xfs_trans	*tp,
-	struct xfs_inode	*ip);
-
-extern void
-xfs_bump_ino_vers2(
-	struct xfs_trans	*tp,
-	struct xfs_inode	*ip);
-
-#endif /* XFS_UTILS_H */
+extern int xfs_rename (bhv_desc_t *, vname_t *, vnode_t *, vname_t *, cred_t *);
+extern int xfs_get_dir_entry (vname_t *, xfs_inode_t **);
+extern int xfs_dir_lookup_int (bhv_desc_t *, uint, vname_t *, xfs_ino_t *,
+				xfs_inode_t **);
+extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *);
+extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, nlink_t,
+				xfs_dev_t, cred_t *, prid_t, int,
+				xfs_inode_t **, int *);
+extern int xfs_droplink (xfs_trans_t *, xfs_inode_t *);
+extern int xfs_bumplink (xfs_trans_t *, xfs_inode_t *);
+extern void xfs_bump_ino_vers2 (xfs_trans_t *, xfs_inode_t *);
 
+#endif	/* __XFS_UTILS_H__ */
diff -Nru a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
--- a/fs/xfs/xfs_vfsops.c	Mon Dec  9 18:46:35 2002
+++ b/fs/xfs/xfs_vfsops.c	Mon Dec  9 18:46:35 2002
@@ -393,7 +393,7 @@
 	xfs_mount_t		*mp;
 	struct block_device	*ddev, *logdev, *rtdev;
 	int			ronly = (vfsp->vfs_flag & VFS_RDONLY);
-	int			error = 0;
+	int			flags = 0, error;
 
 	ddev = vfsp->vfs_super->s_bdev;
 	logdev = rtdev = NULL;
@@ -430,17 +430,11 @@
 	vfs_insertbhv(vfsp, &mp->m_bhv, &xfs_vfsops, mp);
 
 	mp->m_ddev_targp = xfs_alloc_buftarg(ddev);
-	if (rtdev != NULL) {
+	if (rtdev)
 		mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev);
-		set_blocksize(rtdev, 512);
-	}
-	if (logdev != NULL && logdev != ddev) {
-		mp->m_logdev_targp = xfs_alloc_buftarg(logdev);
-		set_blocksize(logdev, 512);
-	} else {
-		mp->m_logdev_targp = mp->m_ddev_targp;
-	}
-	
+	mp->m_logdev_targp = (logdev && logdev != ddev) ?
+				xfs_alloc_buftarg(logdev) : mp->m_ddev_targp;
+
 	error = xfs_start_flags(args, mp, ronly);
 	if (error)
 		goto error;
@@ -455,16 +449,20 @@
 		goto error;
 	}
 
-	mp->m_ddev_targp->pbr_blocksize = mp->m_sb.sb_blocksize;
-	if (logdev != 0 && logdev != ddev) {
-		mp->m_logdev_targp->pbr_blocksize = mp->m_sb.sb_blocksize;
-	}
-	if (rtdev != 0) {
-		mp->m_rtdev_targp->pbr_blocksize = mp->m_sb.sb_blocksize;
-	}
+	xfs_size_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize,
+			 mp->m_sb.sb_sectsize);
+	if (logdev && logdev != ddev) {
+		unsigned int	ss = BBSIZE;
+
+		if (XFS_SB_VERSION_HASSECTOR(&mp->m_sb))
+			ss = mp->m_sb.sb_logsectsize;
+		xfs_size_buftarg(mp->m_logdev_targp, mp->m_sb.sb_blocksize, ss);
+	}
+	if (rtdev)
+		xfs_size_buftarg(mp->m_logdev_targp, mp->m_sb.sb_blocksize,
+				 mp->m_sb.sb_blocksize);
 
-	mp->m_cxfstype = XFS_CXFS_NOT;
-	error = xfs_mountfs(vfsp, mp, ddev->bd_dev, 0);
+	error = xfs_mountfs(vfsp, mp, ddev->bd_dev, flags);
 	if (error)
 		goto error;
 	return 0;
diff -Nru a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
--- a/fs/xfs/xfs_vnodeops.c	Mon Dec  9 18:46:52 2002
+++ b/fs/xfs/xfs_vnodeops.c	Mon Dec  9 18:46:52 2002
@@ -31,7 +31,6 @@
  */
 
 #include <xfs.h>
-#include <asm/fcntl.h>
 
 
 /*
@@ -61,7 +60,6 @@
  * fifo vnodes are "wrapped" by specfs and fifofs vnodes, respectively,
  * when a new vnode is first looked up or created.
  */
-/*ARGSUSED*/
 STATIC int
 xfs_open(
 	bhv_desc_t	*bdp,
@@ -93,7 +91,6 @@
 /*
  * xfs_getattr
  */
-/*ARGSUSED*/
 int
 xfs_getattr(
 	bhv_desc_t	*bdp,
@@ -106,8 +103,7 @@
 	vnode_t		*vp;
 
 	vp  = BHV_TO_VNODE(bdp);
-
-	vn_trace_entry(vp, "xfs_getattr", (inst_t *)__return_address);
+	vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
 
 	ip = XFS_BHVTOI(bdp);
 	mp = ip->i_mount;
@@ -119,7 +115,7 @@
 		xfs_ilock(ip, XFS_ILOCK_SHARED);
 
 	vap->va_size = ip->i_d.di_size;
-	if (vap->va_mask == AT_SIZE) {
+	if (vap->va_mask == XFS_AT_SIZE) {
 		if (!(flags & ATTR_LAZY))
 			xfs_iunlock(ip, XFS_ILOCK_SHARED);
 		return 0;
@@ -137,7 +133,8 @@
 	/*
 	 * Quick exit for non-stat callers
 	 */
-	if ((vap->va_mask & ~(AT_SIZE|AT_FSID|AT_NODEID|AT_NLINK)) == 0) {
+	if ((vap->va_mask &
+	    ~(XFS_AT_SIZE|XFS_AT_FSID|XFS_AT_NODEID|XFS_AT_NLINK)) == 0) {
 		if (!(flags & ATTR_LAZY))
 			xfs_iunlock(ip, XFS_ILOCK_SHARED);
 		return 0;
@@ -224,8 +221,8 @@
 	 * to be filled in are needed.
 	 */
 	if ((vap->va_mask &
-	     (AT_XFLAGS|AT_EXTSIZE|AT_NEXTENTS|AT_ANEXTENTS|
-	      AT_GENCOUNT|AT_VCODE)) == 0) {
+	     (XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|
+	      XFS_AT_GENCOUNT|XFS_AT_VCODE)) == 0) {
 		if (!(flags & ATTR_LAZY))
 			xfs_iunlock(ip, XFS_ILOCK_SHARED);
 		return 0;
@@ -284,17 +281,17 @@
 	int		privileged;
 	int		mandlock_before, mandlock_after;
 	uint		qflags;
-	struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2;
+	xfs_dquot_t	*udqp, *gdqp, *olddquot1, *olddquot2;
 	int		file_owner;
 
 	vp = BHV_TO_VNODE(bdp);
+	vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
 
-	vn_trace_entry(vp, "xfs_setattr", (inst_t *)__return_address);
 	/*
 	 * Cannot set certain attributes.
 	 */
 	mask = vap->va_mask;
-	if (mask & AT_NOSET) {
+	if (mask & XFS_AT_NOSET) {
 		return XFS_ERROR(EINVAL);
 	}
 
@@ -308,11 +305,11 @@
 	 * Timestamps do not need to be logged and hence do not
 	 * need to be done within a transaction.
 	 */
-	if (mask & AT_UPDTIMES) {
-		ASSERT((mask & ~AT_UPDTIMES) == 0);
-		timeflags = ((mask & AT_UPDATIME) ? XFS_ICHGTIME_ACC : 0) |
-			    ((mask & AT_UPDCTIME) ? XFS_ICHGTIME_CHG : 0) |
-			    ((mask & AT_UPDMTIME) ? XFS_ICHGTIME_MOD : 0);
+	if (mask & XFS_AT_UPDTIMES) {
+		ASSERT((mask & ~XFS_AT_UPDTIMES) == 0);
+		timeflags = ((mask & XFS_AT_UPDATIME) ? XFS_ICHGTIME_ACC : 0) |
+			    ((mask & XFS_AT_UPDCTIME) ? XFS_ICHGTIME_CHG : 0) |
+			    ((mask & XFS_AT_UPDMTIME) ? XFS_ICHGTIME_MOD : 0);
 		xfs_ichgtime(ip, timeflags);
 		return 0;
 	}
@@ -328,15 +325,15 @@
 	 * If the IDs do change before we take the ilock, we're covered
 	 * because the i_*dquot fields will get updated anyway.
 	 */
-	if (XFS_IS_QUOTA_ON(mp) && (mask & (AT_UID|AT_GID))) {
+	if (XFS_IS_QUOTA_ON(mp) && (mask & (XFS_AT_UID|XFS_AT_GID))) {
 		qflags = 0;
-		if (mask & AT_UID) {
+		if (mask & XFS_AT_UID) {
 			uid = vap->va_uid;
 			qflags |= XFS_QMOPT_UQUOTA;
 		} else {
 			uid = ip->i_d.di_uid;
 		}
-		if (mask & AT_GID) {
+		if (mask & XFS_AT_GID) {
 			gid = vap->va_gid;
 			qflags |= XFS_QMOPT_GQUOTA;
 		}  else {
@@ -360,8 +357,8 @@
 	 */
 	tp = NULL;
 	lock_flags = XFS_ILOCK_EXCL;
-	if (!(mask & AT_SIZE)) {
-		if ((mask != (AT_CTIME|AT_ATIME|AT_MTIME)) ||
+	if (!(mask & XFS_AT_SIZE)) {
+		if ((mask != (XFS_AT_CTIME|XFS_AT_ATIME|XFS_AT_MTIME)) ||
 		    (mp->m_flags & XFS_MOUNT_WSYNC)) {
 			tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE);
 			commit_flags = 0;
@@ -400,7 +397,9 @@
 	 * Only the owner or users with CAP_FOWNER
 	 * capability may do these things.
 	 */
-	if (mask & (AT_MODE|AT_XFLAGS|AT_EXTSIZE|AT_UID|AT_GID|AT_PROJID)) {
+	if (mask &
+	    (XFS_AT_MODE|XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_UID|
+	     XFS_AT_GID|XFS_AT_PROJID)) {
 		/*
 		 * CAP_FOWNER overrides the following restrictions:
 		 *
@@ -424,7 +423,7 @@
 		 * IDs of the calling process shall match the group owner of
 		 * the file when setting the set-group-ID bit on that file
 		 */
-		if (mask & AT_MODE) {
+		if (mask & XFS_AT_MODE) {
 			mode_t m = 0;
 
 			if ((vap->va_mode & ISUID) && !file_owner)
@@ -449,7 +448,7 @@
 	 * and can change the group id only to a group of which he
 	 * or she is a member.
 	 */
-	if (mask & (AT_UID|AT_GID|AT_PROJID)) {
+	if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID)) {
 		/*
 		 * These IDs could have changed since we last looked at them.
 		 * But, we're assured that if the ownership did change
@@ -459,9 +458,9 @@
 		iuid = ip->i_d.di_uid;
 		iprojid = ip->i_d.di_projid;
 		igid = ip->i_d.di_gid;
-		gid = (mask & AT_GID) ? vap->va_gid : igid;
-		uid = (mask & AT_UID) ? vap->va_uid : iuid;
-		projid = (mask & AT_PROJID) ? (xfs_prid_t)vap->va_projid :
+		gid = (mask & XFS_AT_GID) ? vap->va_gid : igid;
+		uid = (mask & XFS_AT_UID) ? vap->va_uid : iuid;
+		projid = (mask & XFS_AT_PROJID) ? (xfs_prid_t)vap->va_projid :
 			 iprojid;
 
 		/*
@@ -506,13 +505,13 @@
 	/*
 	 * Truncate file.  Must have write permission and not be a directory.
 	 */
-	if (mask & AT_SIZE) {
+	if (mask & XFS_AT_SIZE) {
 		/* Short circuit the truncate case for zero length files */
 		if ((vap->va_size == 0) &&
 		   (ip->i_d.di_size == 0) && (ip->i_d.di_nextents == 0)) {
 			xfs_iunlock(ip, XFS_ILOCK_EXCL);
 			lock_flags &= ~XFS_ILOCK_EXCL;
-			if (mask & AT_CTIME)
+			if (mask & XFS_AT_CTIME)
 				xfs_ichgtime(ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
 			code = 0;
 			goto error_return;
@@ -537,7 +536,7 @@
 	/*
 	 * Change file access or modified times.
 	 */
-	if (mask & (AT_ATIME|AT_MTIME)) {
+	if (mask & (XFS_AT_ATIME|XFS_AT_MTIME)) {
 		if (!file_owner) {
 			if ((flags & ATTR_UTIME) &&
 			    !capable(CAP_FOWNER)) {
@@ -550,11 +549,11 @@
 	/*
 	 * Change extent size or realtime flag.
 	 */
-	if (mask & (AT_EXTSIZE|AT_XFLAGS)) {
+	if (mask & (XFS_AT_EXTSIZE|XFS_AT_XFLAGS)) {
 		/*
 		 * Can't change extent size if any extents are allocated.
 		 */
-		if (ip->i_d.di_nextents && (mask & AT_EXTSIZE) &&
+		if (ip->i_d.di_nextents && (mask & XFS_AT_EXTSIZE) &&
 		    ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) !=
 		     vap->va_extsize) ) {
 			code = XFS_ERROR(EINVAL);	/* EFBIG? */
@@ -569,11 +568,11 @@
 		 * with buffered data writes is implemented.
 		 *
 		 */
-		if ((mask & AT_EXTSIZE)				&&
+		if ((mask & XFS_AT_EXTSIZE)			&&
 		    ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) !=
 		     vap->va_extsize) &&
 		    (!((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ||
-		       ((mask & AT_XFLAGS) &&
+		       ((mask & XFS_AT_XFLAGS) &&
 			(vap->va_xflags & XFS_XFLAG_REALTIME))))) {
 			code = XFS_ERROR(EINVAL);
 			goto error_return;
@@ -582,7 +581,7 @@
 		/*
 		 * Can't change realtime flag if any extents are allocated.
 		 */
-		if (ip->i_d.di_nextents && (mask & AT_XFLAGS) &&
+		if (ip->i_d.di_nextents && (mask & XFS_AT_XFLAGS) &&
 		    (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) !=
 		    (vap->va_xflags & XFS_XFLAG_REALTIME)) {
 			code = XFS_ERROR(EINVAL);	/* EFBIG? */
@@ -592,11 +591,11 @@
 		 * Extent size must be a multiple of the appropriate block
 		 * size, if set at all.
 		 */
-		if ((mask & AT_EXTSIZE) && vap->va_extsize != 0) {
+		if ((mask & XFS_AT_EXTSIZE) && vap->va_extsize != 0) {
 			xfs_extlen_t	size;
 
 			if ((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ||
-			    ((mask & AT_XFLAGS) &&
+			    ((mask & XFS_AT_XFLAGS) &&
 			    (vap->va_xflags & XFS_XFLAG_REALTIME))) {
 				size = mp->m_sb.sb_rextsize <<
 				       mp->m_sb.sb_blocklog;
@@ -611,7 +610,7 @@
 		/*
 		 * If realtime flag is set then must have realtime data.
 		 */
-		if ((mask & AT_XFLAGS) &&
+		if ((mask & XFS_AT_XFLAGS) &&
 		    (vap->va_xflags & XFS_XFLAG_REALTIME)) {
 			if ((mp->m_sb.sb_rblocks == 0) ||
 			    (mp->m_sb.sb_rextsize == 0) ||
@@ -624,13 +623,13 @@
 
 	/*
 	 * Now we can make the changes.	 Before we join the inode
-	 * to the transaction, if AT_SIZE is set then take care of
+	 * to the transaction, if XFS_AT_SIZE is set then take care of
 	 * the part of the truncation that must be done without the
 	 * inode lock.	This needs to be done before joining the inode
 	 * to the transaction, because the inode cannot be unlocked
 	 * once it is a part of the transaction.
 	 */
-	if (mask & AT_SIZE) {
+	if (mask & XFS_AT_SIZE) {
 		if (vap->va_size > ip->i_d.di_size) {
 			code = xfs_igrow_start(ip, vap->va_size, credp);
 			xfs_iunlock(ip, XFS_ILOCK_EXCL);
@@ -673,7 +672,7 @@
 	/*
 	 * Truncate file.  Must have write permission and not be a directory.
 	 */
-	if (mask & AT_SIZE) {
+	if (mask & XFS_AT_SIZE) {
 		if (vap->va_size > ip->i_d.di_size) {
 			xfs_igrow_finish(tp, ip, vap->va_size,
 			    !(flags & ATTR_DMI));
@@ -703,7 +702,7 @@
 	/*
 	 * Change file access modes.
 	 */
-	if (mask & AT_MODE) {
+	if (mask & XFS_AT_MODE) {
 		ip->i_d.di_mode &= IFMT;
 		ip->i_d.di_mode |= vap->va_mode & ~IFMT;
 
@@ -718,7 +717,7 @@
 	 * and can change the group id only to a group of which he
 	 * or she is a member.
 	 */
-	if (mask & (AT_UID|AT_GID|AT_PROJID)) {
+	if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID)) {
 		/*
 		 * CAP_FSETID overrides the following restrictions:
 		 *
@@ -736,7 +735,7 @@
 		 */
 		if (iuid != uid) {
 			if (XFS_IS_UQUOTA_ON(mp)) {
-				ASSERT(mask & AT_UID);
+				ASSERT(mask & XFS_AT_UID);
 				ASSERT(udqp);
 				ASSERT(xfs_qm_dqid(udqp) == (xfs_dqid_t)uid);
 				olddquot1 = xfs_qm_vop_chown(tp, ip,
@@ -750,7 +749,7 @@
 		}
 		if (igid != gid) {
 			if (XFS_IS_GQUOTA_ON(mp)) {
-				ASSERT(mask & AT_GID);
+				ASSERT(mask & XFS_AT_GID);
 				ASSERT(gdqp);
 				ASSERT(xfs_qm_dqid(gdqp) == gid);
 				olddquot2 = xfs_qm_vop_chown(tp, ip,
@@ -778,14 +777,14 @@
 	/*
 	 * Change file access or modified times.
 	 */
-	if (mask & (AT_ATIME|AT_MTIME)) {
-		if (mask & AT_ATIME) {
+	if (mask & (XFS_AT_ATIME|XFS_AT_MTIME)) {
+		if (mask & XFS_AT_ATIME) {
 			ip->i_d.di_atime.t_sec = vap->va_atime.tv_sec;
 			ip->i_d.di_atime.t_nsec = vap->va_atime.tv_nsec;
 			ip->i_update_core = 1;
 			timeflags &= ~XFS_ICHGTIME_ACC;
 		}
-		if (mask & AT_MTIME) {
+		if (mask & XFS_AT_MTIME) {
 			ip->i_d.di_mtime.t_sec = vap->va_mtime.tv_sec;
 			ip->i_d.di_mtime.t_nsec = vap->va_mtime.tv_nsec;
 			timeflags &= ~XFS_ICHGTIME_MOD;
@@ -798,15 +797,15 @@
 	/*
 	 * Change XFS-added attributes.
 	 */
-	if (mask & (AT_EXTSIZE|AT_XFLAGS)) {
-		if (mask & AT_EXTSIZE) {
+	if (mask & (XFS_AT_EXTSIZE|XFS_AT_XFLAGS)) {
+		if (mask & XFS_AT_EXTSIZE) {
 			/*
 			 * Converting bytes to fs blocks.
 			 */
 			ip->i_d.di_extsize = vap->va_extsize >>
 				mp->m_sb.sb_blocklog;
 		}
-		if (mask & AT_XFLAGS) {
+		if (mask & XFS_AT_XFLAGS) {
 			ip->i_d.di_flags = 0;
 			if (vap->va_xflags & XFS_XFLAG_REALTIME) {
 				ip->i_d.di_flags |= XFS_DIFLAG_REALTIME;
@@ -822,11 +821,11 @@
 	}
 
 	/*
-	 * Change file inode change time only if AT_CTIME set
+	 * Change file inode change time only if XFS_AT_CTIME set
 	 * AND we have been called by a DMI function.
 	 */
 
-	if ( (flags & ATTR_DMI) && (mask & AT_CTIME) ) {
+	if ( (flags & ATTR_DMI) && (mask & XFS_AT_CTIME) ) {
 		ip->i_d.di_ctime.t_sec = vap->va_ctime.tv_sec;
 		ip->i_d.di_ctime.t_nsec = vap->va_ctime.tv_nsec;
 		ip->i_update_core = 1;
@@ -912,14 +911,13 @@
 		xfs_iunlock(ip, lock_flags);
 	}
 	return code;
-} /* xfs_setattr */
+}
 
 
 /*
  * xfs_access
  * Null conversion from vnode mode bits to inode mode bits, as in efs.
  */
-/*ARGSUSED*/
 STATIC int
 xfs_access(
 	bhv_desc_t	*bdp,
@@ -929,7 +927,7 @@
 	xfs_inode_t	*ip;
 	int		error;
 
-	vn_trace_entry(BHV_TO_VNODE(bdp), "xfs_access",
+	vn_trace_entry(BHV_TO_VNODE(bdp), __FUNCTION__,
 					       (inst_t *)__return_address);
 
 	ip = XFS_BHVTOI(bdp);
@@ -944,7 +942,6 @@
  * xfs_readlink
  *
  */
-/*ARGSUSED*/
 STATIC int
 xfs_readlink(
 	bhv_desc_t	*bdp,
@@ -966,8 +963,7 @@
 	xfs_buf_t	*bp;
 
 	vp = BHV_TO_VNODE(bdp);
-
-	vn_trace_entry(vp, "xfs_readlink", (inst_t *)__return_address);
+	vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
 
 	ip = XFS_BHVTOI(bdp);
 	mp = ip->i_mount;
@@ -1047,6 +1043,7 @@
 	return error;
 }
 
+
 /*
  * xfs_fsync
  *
@@ -1056,7 +1053,6 @@
  * be held while flushing the data, so acquire after we're done
  * with that.
  */
-/*ARGSUSED*/
 STATIC int
 xfs_fsync(
 	bhv_desc_t	*bdp,
@@ -1067,16 +1063,13 @@
 {
 	xfs_inode_t	*ip;
 	int		error;
-	/* REFERENCED */
 	int		error2;
-					/* REFERENCED */
 	int		syncall;
 	vnode_t		*vp;
 	xfs_trans_t	*tp;
 
 	vp = BHV_TO_VNODE(bdp);
-
-	vn_trace_entry(vp, "xfs_fsync", (inst_t *)__return_address);
+	vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
 
 	ip = XFS_BHVTOI(bdp);
 
@@ -1526,6 +1519,7 @@
 	xfs_trans_t	**tpp)
 {
 	int		error;
+
 	ASSERT(ip->i_d.di_size <= XFS_IFORK_DSIZE(ip));
 	/*
 	 * We're freeing a symlink which fit into
@@ -1608,7 +1602,6 @@
 	return (0);
 }
 
-/*ARGSUSED*/
 STATIC int
 xfs_release(
 	bhv_desc_t	*bdp)
@@ -1655,14 +1648,12 @@
  * now be truncated.  Also, we clear all of the read-ahead state
  * kept for the inode here since the file is now closed.
  */
-/*ARGSUSED*/
 STATIC int
 xfs_inactive(
 	bhv_desc_t	*bdp,
 	cred_t		*credp)
 {
 	xfs_inode_t	*ip;
-			/* REFERENCED */
 	vnode_t		*vp;
 	xfs_trans_t	*tp;
 	xfs_mount_t	*mp;
@@ -1671,8 +1662,7 @@
 	int		truncate;
 
 	vp = BHV_TO_VNODE(bdp);
-
-	vn_trace_entry(vp, "xfs_inactive", (inst_t *)__return_address);
+	vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
 
 	ip = XFS_BHVTOI(bdp);
 
@@ -1880,15 +1870,14 @@
 /*
  * xfs_lookup
  */
-/*ARGSUSED*/
 STATIC int
 xfs_lookup(
-	bhv_desc_t	*dir_bdp,
-	struct dentry	*dentry,
-	vnode_t		**vpp,
-	int		flags,
-	vnode_t		*rdir,
-	cred_t		*credp)
+	bhv_desc_t		*dir_bdp,
+	vname_t			*dentry,
+	vnode_t			**vpp,
+	int			flags,
+	vnode_t			*rdir,
+	cred_t			*credp)
 {
 	xfs_inode_t		*dp, *ip;
 	struct vnode		*vp;
@@ -1898,8 +1887,7 @@
 	vnode_t			*dir_vp;
 
 	dir_vp = BHV_TO_VNODE(dir_bdp);
-
-	vn_trace_entry(dir_vp, "xfs_lookup", (inst_t *)__return_address);
+	vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
 
 	dp = XFS_BHVTOI(dir_bdp);
 
@@ -1963,13 +1951,13 @@
  */
 STATIC int
 xfs_create(
-	bhv_desc_t	*dir_bdp,
-	struct dentry	*dentry,
-	vattr_t		*vap,
-	vnode_t		**vpp,
-	cred_t		*credp)
+	bhv_desc_t		*dir_bdp,
+	vname_t			*dentry,
+	vattr_t			*vap,
+	vnode_t			**vpp,
+	cred_t			*credp)
 {
-	char			*name = (char *)dentry->d_name.name;
+	char			*name = VNAME(dentry);
 	vnode_t			*dir_vp;
 	xfs_inode_t		*dp, *ip;
 	vnode_t			*vp=NULL;
@@ -1984,19 +1972,19 @@
 	uint			cancel_flags;
 	int			committed;
 	xfs_prid_t		prid;
-	struct xfs_dquot	*udqp, *gdqp;
+	xfs_dquot_t		*udqp, *gdqp;
 	uint			resblks;
 	int			dm_di_mode;
 	int			namelen;
 
 	ASSERT(!*vpp);
 	dir_vp = BHV_TO_VNODE(dir_bdp);
-	dp = XFS_BHVTOI(dir_bdp);
+	vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
 
-	vn_trace_entry(dir_vp, "xfs_create", (inst_t *)__return_address);
+	dp = XFS_BHVTOI(dir_bdp);
 
 	dm_di_mode = vap->va_mode|VTTOIF(vap->va_type);
-	namelen = dentry->d_name.len;
+	namelen = VNAMELEN(dentry);
 	if (namelen >= MAXNAMELEN)
 		return XFS_ERROR(ENAMETOOLONG);
 
@@ -2015,7 +2003,7 @@
 		return XFS_ERROR(EIO);
 
 	udqp = gdqp = NULL;
-	if (vap->va_mask & AT_PROJID)
+	if (vap->va_mask & XFS_AT_PROJID)
 		prid = (xfs_prid_t)vap->va_projid;
 	else
 		prid = (xfs_prid_t)dfltprid;
@@ -2076,7 +2064,7 @@
 	if (resblks == 0 &&
 	    (error = XFS_DIR_CANENTER(mp, tp, dp, name, namelen)))
 		goto error_return;
-	rdev = (vap->va_mask & AT_RDEV) ? vap->va_rdev : 0;
+	rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0;
 	error = xfs_dir_ialloc(&tp, dp,
 			MAKEIMODE(vap->va_type,vap->va_mode), 1,
 			rdev, credp, prid, resblks > 0,
@@ -2220,7 +2208,6 @@
 }
 
 #ifdef DEBUG
-
 /*
  * Some counters to see if (and how often) we are hitting some deadlock
  * prevention code paths.
@@ -2261,14 +2248,14 @@
 STATIC int
 xfs_lock_dir_and_entry(
 	xfs_inode_t	*dp,
-	struct dentry	*dentry,
+	vname_t		*dentry,
 	xfs_inode_t	*ip,	/* inode of entry 'name' */
 	int		*entry_changed)
 {
-	int			attempts;
-	xfs_ino_t		e_inum;
-	xfs_inode_t		*ips[2];
-	xfs_log_item_t		*lp;
+	int		attempts;
+	xfs_ino_t	e_inum;
+	xfs_inode_t	*ips[2];
+	xfs_log_item_t	*lp;
 
 #ifdef DEBUG
 	xfs_rm_locks++;
@@ -2357,12 +2344,13 @@
  * in the log.
  */
 void
-xfs_lock_inodes (xfs_inode_t **ips,
-	int inodes,
-	int first_locked,
-	uint lock_mode)
+xfs_lock_inodes(
+	xfs_inode_t	**ips,
+	int		inodes,
+	int		first_locked,
+	uint		lock_mode)
 {
-	int attempts = 0, i, j, try_lock;
+	int		attempts = 0, i, j, try_lock;
 	xfs_log_item_t	*lp;
 
 	ASSERT(ips && (inodes >= 2)); /* we need at least two */
@@ -2468,18 +2456,19 @@
 #define REMOVE_DEBUG_TRACE(x)
 #endif	/* ! DEBUG */
 
+
 /*
  * xfs_remove
  *
  */
 STATIC int
 xfs_remove(
-	bhv_desc_t	*dir_bdp,
-	struct dentry	*dentry,
-	cred_t		*credp)
+	bhv_desc_t		*dir_bdp,
+	vname_t			*dentry,
+	cred_t			*credp)
 {
 	vnode_t			*dir_vp;
-	char			*name = (char *) dentry->d_name.name;
+	char			*name = VNAME(dentry);
 	xfs_inode_t		*dp, *ip;
 	xfs_trans_t		*tp = NULL;
 	xfs_mount_t		*mp;
@@ -2493,11 +2482,9 @@
 	int			link_zero;
 	uint			resblks;
 	int			namelen;
-/*	bhv_desc_t		*bdp; */
 
 	dir_vp = BHV_TO_VNODE(dir_bdp);
-
-	vn_trace_entry(dir_vp, "xfs_remove", (inst_t *)__return_address);
+	vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
 
 	dp = XFS_BHVTOI(dir_bdp);
 	mp = dp->i_mount;
@@ -2505,7 +2492,7 @@
 	if (XFS_FORCED_SHUTDOWN(mp))
 		return XFS_ERROR(EIO);
 
-	namelen = dentry->d_name.len;
+	namelen = VNAMELEN(dentry);
 	if (namelen >= MAXNAMELEN)
 		return XFS_ERROR(ENAMETOOLONG);
 	if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
@@ -2540,7 +2527,7 @@
 
 	dm_di_mode = ip->i_d.di_mode;
 
-	vn_trace_entry(XFS_ITOV(ip), "xfs_remove", (inst_t *)__return_address);
+	vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address);
 
 	ITRACE(ip);
 
@@ -2699,8 +2686,7 @@
 		goto std_return;
 	}
 
-	vn_trace_exit(XFS_ITOV(ip), "xfs_remove",
-						(inst_t *)__return_address);
+	vn_trace_exit(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address);
 
 	/*
 	 * Let interposed file systems know about removed links.
@@ -2752,10 +2738,10 @@
  */
 STATIC int
 xfs_link(
-	bhv_desc_t	*target_dir_bdp,
-	vnode_t		*src_vp,
-	struct dentry	*dentry,
-	cred_t		*credp)
+	bhv_desc_t		*target_dir_bdp,
+	vnode_t			*src_vp,
+	vname_t			*dentry,
+	cred_t			*credp)
 {
 	xfs_inode_t		*tdp, *sip;
 	xfs_trans_t		*tp;
@@ -2769,18 +2755,18 @@
 	vnode_t			*target_dir_vp;
 	bhv_desc_t		*src_bdp;
 	int			resblks;
-	char			*target_name = (char *)dentry->d_name.name;
+	char			*target_name = VNAME(dentry);
 	int			target_namelen;
 
 	target_dir_vp = BHV_TO_VNODE(target_dir_bdp);
+	vn_trace_entry(target_dir_vp, __FUNCTION__, (inst_t *)__return_address);
+	vn_trace_entry(src_vp, __FUNCTION__, (inst_t *)__return_address);
 
-	vn_trace_entry(target_dir_vp, "xfs_link", (inst_t *)__return_address);
-
-	target_namelen = dentry->d_name.len;
+	target_namelen = VNAMELEN(dentry);
 	if (target_namelen >= MAXNAMELEN)
 		return XFS_ERROR(ENAMETOOLONG);
-
-	vn_trace_entry(src_vp, "xfs_link", (inst_t *)__return_address);
+	if (src_vp->v_type == VDIR)
+		return XFS_ERROR(EPERM);
 
 	/*
 	 * For now, manually find the XFS behavior descriptor for
@@ -2925,21 +2911,19 @@
 }
 
 
-
-
 /*
  * xfs_mkdir
  *
  */
 STATIC int
 xfs_mkdir(
-	bhv_desc_t	*dir_bdp,
-	struct dentry	*dentry,
-	vattr_t		*vap,
-	vnode_t		**vpp,
-	cred_t		*credp)
+	bhv_desc_t		*dir_bdp,
+	vname_t			*dentry,
+	vattr_t			*vap,
+	vnode_t			**vpp,
+	cred_t			*credp)
 {
-	char			*dir_name = (char *)dentry->d_name.name;
+	char			*dir_name = VNAME(dentry);
 	xfs_inode_t		*dp;
 	xfs_inode_t		*cdp;	/* inode of created dir */
 	vnode_t			*cvp;	/* vnode of created dir */
@@ -2956,7 +2940,7 @@
 	boolean_t		created = B_FALSE;
 	int			dm_event_sent = 0;
 	xfs_prid_t		prid;
-	struct xfs_dquot	*udqp, *gdqp;
+	xfs_dquot_t		*udqp, *gdqp;
 	uint			resblks;
 	int			dm_di_mode;
 	int			dir_namelen;
@@ -2968,7 +2952,7 @@
 	if (XFS_FORCED_SHUTDOWN(mp))
 		return XFS_ERROR(EIO);
 
-	dir_namelen = dentry->d_name.len;
+	dir_namelen = VNAMELEN(dentry);
 	if (dir_namelen >= MAXNAMELEN)
 		return XFS_ERROR(ENAMETOOLONG);
 
@@ -2985,11 +2969,11 @@
 
 	/* Return through std_return after this point. */
 
-	vn_trace_entry(dir_vp, "xfs_mkdir", (inst_t *)__return_address);
+	vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
 
 	mp = dp->i_mount;
 	udqp = gdqp = NULL;
-	if (vap->va_mask & AT_PROJID)
+	if (vap->va_mask & XFS_AT_PROJID)
 		prid = (xfs_prid_t)vap->va_projid;
 	else
 		prid = (xfs_prid_t)dfltprid;
@@ -3049,7 +3033,7 @@
 	/*
 	 * create the directory inode.
 	 */
-	rdev = (vap->va_mask & AT_RDEV) ? vap->va_rdev : 0;
+	rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0;
 	error = xfs_dir_ialloc(&tp, dp, 
 			MAKEIMODE(vap->va_type,vap->va_mode), 2,
 			rdev, credp, prid, resblks > 0,
@@ -3182,16 +3166,15 @@
  */
 STATIC int
 xfs_rmdir(
-	bhv_desc_t	*dir_bdp,
-	struct dentry	*dentry,
-	cred_t		*credp)
+	bhv_desc_t		*dir_bdp,
+	vname_t			*dentry,
+	cred_t			*credp)
 {
-	char			*name = (char *)dentry->d_name.name;
+	char			*name = VNAME(dentry);
 	xfs_inode_t		*dp;
 	xfs_inode_t		*cdp;	/* child directory */
 	xfs_trans_t		*tp;
 	xfs_mount_t		*mp;
-/*	bhv_desc_t		*bdp;*/
 	int			error;
 	xfs_bmap_free_t		free_list;
 	xfs_fsblock_t		first_block;
@@ -3207,11 +3190,11 @@
 	dir_vp = BHV_TO_VNODE(dir_bdp);
 	dp = XFS_BHVTOI(dir_bdp);
 
-	vn_trace_entry(dir_vp, "xfs_rmdir", (inst_t *)__return_address);
+	vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
 
 	if (XFS_FORCED_SHUTDOWN(XFS_BHVTOI(dir_bdp)->i_mount))
 		return XFS_ERROR(EIO);
-	namelen = dentry->d_name.len;
+	namelen = VNAMELEN(dentry);
 	if (namelen >= MAXNAMELEN)
 		return XFS_ERROR(ENAMETOOLONG);
 
@@ -3444,14 +3427,12 @@
 }
 
 
-
 /*
  * xfs_readdir
  *
  * Read dp's entries starting at uiop->uio_offset and translate them into
  * bufsize bytes worth of struct dirents starting at bufbase.
  */
-/*ARGSUSED*/
 STATIC int
 xfs_readdir(
 	bhv_desc_t	*dir_bdp,
@@ -3459,13 +3440,13 @@
 	cred_t		*credp,
 	int		*eofp)
 {
-	xfs_inode_t		*dp;
-	xfs_trans_t		*tp = NULL;
-	int			error = 0;
-	uint			lock_mode;
-	xfs_off_t		start_offset;
+	xfs_inode_t	*dp;
+	xfs_trans_t	*tp = NULL;
+	int		error = 0;
+	uint		lock_mode;
+	xfs_off_t	start_offset;
 
-	vn_trace_entry(BHV_TO_VNODE(dir_bdp), "xfs_readdir",
+	vn_trace_entry(BHV_TO_VNODE(dir_bdp), __FUNCTION__,
 					       (inst_t *)__return_address);
 	dp = XFS_BHVTOI(dir_bdp);
 
@@ -3491,18 +3472,19 @@
 	return error;
 }
 
+
 /*
  * xfs_symlink
  *
  */
 STATIC int
 xfs_symlink(
-	bhv_desc_t	*dir_bdp,
-	struct dentry	*dentry,
-	vattr_t		*vap,
-	char		*target_path,
-	vnode_t		**vpp,
-	cred_t		*credp)
+	bhv_desc_t		*dir_bdp,
+	vname_t			*dentry,
+	vattr_t			*vap,
+	char			*target_path,
+	vnode_t			**vpp,
+	cred_t			*credp)
 {
 	xfs_trans_t		*tp;
 	xfs_mount_t		*mp;
@@ -3527,9 +3509,9 @@
 	int			n;
 	xfs_buf_t		*bp;
 	xfs_prid_t		prid;
-	struct xfs_dquot	*udqp, *gdqp;
+	xfs_dquot_t		*udqp, *gdqp;
 	uint			resblks;
-	char			*link_name = (char *)dentry->d_name.name;
+	char			*link_name = VNAME(dentry);
 	int			link_namelen;
 
 	*vpp = NULL;
@@ -3540,14 +3522,14 @@
 	ip = NULL;
 	tp = NULL;
 
-	vn_trace_entry(dir_vp, "xfs_symlink", (inst_t *)__return_address);
+	vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
 
 	mp = dp->i_mount;
 
 	if (XFS_FORCED_SHUTDOWN(mp))
 		return XFS_ERROR(EIO);
 
-	link_namelen = dentry->d_name.len;
+	link_namelen = VNAMELEN(dentry);
 	if (link_namelen >= MAXNAMELEN)
 		return XFS_ERROR(ENAMETOOLONG);
 	/*
@@ -3594,7 +3576,7 @@
 	/* Return through std_return after this point. */
 
 	udqp = gdqp = NULL;
-	if (vap->va_mask & AT_PROJID)
+	if (vap->va_mask & XFS_AT_PROJID)
 		prid = (xfs_prid_t)vap->va_projid;
 	else
 		prid = (xfs_prid_t)dfltprid;
@@ -3662,7 +3644,7 @@
 	/*
 	 * Allocate an inode for the symlink.
 	 */
-	rdev = (vap->va_mask & AT_RDEV) ? vap->va_rdev : 0;
+	rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0;
 
 	error = xfs_dir_ialloc(&tp, dp, IFLNK | (vap->va_mode&~IFMT),
 			       1, rdev, credp, prid, resblks > 0, &ip, NULL);
@@ -3839,8 +3821,8 @@
 	xfs_inode_t	*ip;
 	xfs_fid2_t	*xfid;
 
-	vn_trace_entry(BHV_TO_VNODE(bdp), "xfs_fid2",
-		       (inst_t *)__return_address);
+	vn_trace_entry(BHV_TO_VNODE(bdp), __FUNCTION__,
+				       (inst_t *)__return_address);
 	ASSERT(sizeof(fid_t) >= sizeof(xfs_fid2_t));
 
 	xfid = (xfs_fid2_t *)fidp;
@@ -3915,8 +3897,9 @@
 }
 
 STATIC int
-xfs_inode_flush(bhv_desc_t	*bdp,
-		int		flags)
+xfs_inode_flush(
+	bhv_desc_t	*bdp,
+	int		flags)
 {
 	xfs_inode_t	*ip;
 	xfs_dinode_t	*dip;
@@ -4061,7 +4044,7 @@
 
 	vp = BHV_TO_VNODE(bdp);
 
-	vn_trace_entry(vp, "xfs_reclaim", (inst_t *)__return_address);
+	vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
 
 	ASSERT(!VN_MAPPED(vp));
 	ip = XFS_BHVTOI(bdp);
@@ -4249,8 +4232,7 @@
 	xfs_trans_t		*tp;
 	int			xfs_bmapi_flags;
 
-	vn_trace_entry(XFS_ITOV(ip), "xfs_alloc_file_space",
-					       (inst_t *)__return_address);
+	vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address);
 	mp = ip->i_mount;
 
 	if (XFS_FORCED_SHUTDOWN(mp))
@@ -4408,7 +4390,7 @@
 				NULL, NULL, 0, 0, 0); /* Delay flag intentionally unused */
 		if (error == 0)
 			goto retry;	/* Maybe DMAPI app. has made space */
-		/* else fall through with error = xfs_dm_send_data_event result. */
+		/* else fall through with error from xfs_dm_send_data_event */
 	}
 
 	return error;
@@ -4532,8 +4514,7 @@
 	xfs_fileoff_t		startoffset_fsb;
 	xfs_trans_t		*tp;
 
-	vn_trace_entry(XFS_ITOV(ip), "xfs_free_file_space",
-					       (inst_t *)__return_address);
+	vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address);
 	mp = ip->i_mount;
 
 	if (XFS_IS_QUOTA_ON(mp)) {
@@ -4736,9 +4717,8 @@
 	vnode_t		*vp;
 
 	vp = BHV_TO_VNODE(bdp);
+	vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
 
-	vn_trace_entry(vp, "xfs_change_file_space",
-						(inst_t *)__return_address);
 	ip = XFS_BHVTOI(bdp);
 	mp = ip->i_mount;
 
@@ -4824,7 +4804,7 @@
 				break;
 		}
 
-		va.va_mask = AT_SIZE;
+		va.va_mask = XFS_AT_SIZE;
 		va.va_size = startoffset;
 
 		error = xfs_setattr(bdp, &va, attr_flags, credp);
@@ -4887,6 +4867,7 @@
 }
 
 vnodeops_t xfs_vnodeops = {
+	BHV_IDENTITY_INIT(VN_BHV_XFS,VNODE_POSITION_XFS),
 	.vop_open		= xfs_open,
 	.vop_read		= xfs_read,
 	.vop_write		= xfs_write,
diff -Nru a/fs/xfs/xfsidbg.c b/fs/xfs/xfsidbg.c
--- a/fs/xfs/xfsidbg.c	Mon Dec  9 18:46:50 2002
+++ b/fs/xfs/xfsidbg.c	Mon Dec  9 18:46:50 2002
@@ -1824,7 +1824,8 @@
 		   bp.pb_common.pb_bn,
 		   (unsigned long) bp.pb_common.pb_count_desired);
 	kdb_printf("  pb_io_remaining %d pb_error %u\n",
-		   bp.pb_io_remaining.counter, bp.pb_common.pb_error);
+		   bp.pb_common.pb_io_remaining.counter,
+		   bp.pb_common.pb_error);
 	kdb_printf("  pb_page_count %u pb_offset 0x%x pb_pages 0x%p\n",
 		bp.pb_common.pb_page_count, bp.pb_common.pb_offset,
 		bp.pb_common.pb_pages);
@@ -4207,8 +4208,9 @@
 	};
 
 	kdb_printf("xlog at 0x%p\n", log);
-	kdb_printf("&flushsm: 0x%p  tic_cnt: %d	 tic_tcnt: %d  \n",
-		&log->l_flushsema, log->l_ticket_cnt, log->l_ticket_tcnt);
+	kdb_printf("&flushsm: 0x%p  flushcnt: %d tic_cnt: %d	 tic_tcnt: %d  \n",
+		&log->l_flushsema, log->l_flushcnt,
+		log->l_ticket_cnt, log->l_ticket_tcnt);
 	kdb_printf("freelist: 0x%p  tail: 0x%p	ICLOG: 0x%p  \n",
 		log->l_freelist, log->l_tail, log->l_iclog);
 	kdb_printf("&icloglock: 0x%p  tail_lsn: %s  last_sync_lsn: %s \n",
@@ -4660,9 +4662,10 @@
 	kdb_printf("dalign %d swidth %d sinoalign %d attr_magicpct %d dir_magicpct %d\n",
 		mp->m_dalign, mp->m_swidth, mp->m_sinoalign,
 		mp->m_attr_magicpct, mp->m_dir_magicpct);
-	kdb_printf("mk_sharedro %d dirversion %d dirblkfsbs %d &dirops 0x%p\n",
-		mp->m_mk_sharedro, mp->m_dirversion, mp->m_dirblkfsbs,
-		&mp->m_dirops);
+	kdb_printf("mk_sharedro %d inode_quiesce %d sectbb_log %d\n",
+		mp->m_mk_sharedro, mp->m_inode_quiesce, mp->m_sectbb_log);
+	kdb_printf("dirversion %d dirblkfsbs %d &dirops 0x%p\n",
+		mp->m_dirversion, mp->m_dirblkfsbs, &mp->m_dirops);
 	kdb_printf("dirblksize %d dirdatablk 0x%Lx dirleafblk 0x%Lx dirfreeblk 0x%Lx\n",
 		mp->m_dirblksize,
 		(xfs_dfiloff_t)mp->m_dirdatablk,
diff -Nru a/include/asm-alpha/core_cia.h b/include/asm-alpha/core_cia.h
--- a/include/asm-alpha/core_cia.h	Mon Dec  9 18:46:38 2002
+++ b/include/asm-alpha/core_cia.h	Mon Dec  9 18:46:38 2002
@@ -202,6 +202,10 @@
 #define CIA_IOC_PCI_W3_MASK		(IDENT_ADDR + 0x8760000740UL)
 #define CIA_IOC_PCI_T3_BASE		(IDENT_ADDR + 0x8760000780UL)
 
+#define CIA_IOC_PCI_Wn_BASE(N)	(IDENT_ADDR + 0x8760000400UL + (N)*0x100) 
+#define CIA_IOC_PCI_Wn_MASK(N)	(IDENT_ADDR + 0x8760000440UL + (N)*0x100) 
+#define CIA_IOC_PCI_Tn_BASE(N)	(IDENT_ADDR + 0x8760000480UL + (N)*0x100) 
+
 #define CIA_IOC_PCI_W_DAC		(IDENT_ADDR + 0x87600007C0UL)
 
 /*
diff -Nru a/include/asm-alpha/current.h b/include/asm-alpha/current.h
--- a/include/asm-alpha/current.h	Mon Dec  9 18:46:52 2002
+++ b/include/asm-alpha/current.h	Mon Dec  9 18:46:52 2002
@@ -1,7 +1,7 @@
 #ifndef _ALPHA_CURRENT_H
 #define _ALPHA_CURRENT_H
 
-#include <asm/thread_info.h>
+#include <linux/thread_info.h>
 
 #define get_current()	(current_thread_info()->task + 0)
 #define current		get_current()
diff -Nru a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h
--- a/include/asm-alpha/pci.h	Mon Dec  9 18:46:34 2002
+++ b/include/asm-alpha/pci.h	Mon Dec  9 18:46:34 2002
@@ -6,6 +6,8 @@
 #include <linux/spinlock.h>
 #include <asm/scatterlist.h>
 #include <asm/machvec.h>
+#include <asm/io.h>
+
 
 /*
  * The following structure is used to manage multiple PCI busses.
diff -Nru a/include/asm-alpha/thread_info.h b/include/asm-alpha/thread_info.h
--- a/include/asm-alpha/thread_info.h	Mon Dec  9 18:46:51 2002
+++ b/include/asm-alpha/thread_info.h	Mon Dec  9 18:46:51 2002
@@ -25,6 +25,8 @@
 	int bpt_nsaved;
 	unsigned long bpt_addr[2];		/* breakpoint handling  */
 	unsigned int bpt_insn[2];
+
+	struct restart_block	restart_block;
 };
 
 /*
@@ -35,6 +37,9 @@
 	task:		&tsk,			\
 	exec_domain:	&default_exec_domain,	\
 	addr_limit:	KERNEL_DS,		\
+	.restart_block = {			\
+		.fn = do_no_restart_syscall,	\
+	},					\
 }
 
 #define init_thread_info	(init_thread_union.thread_info)
diff -Nru a/include/asm-alpha/topology.h b/include/asm-alpha/topology.h
--- a/include/asm-alpha/topology.h	Mon Dec  9 18:46:35 2002
+++ b/include/asm-alpha/topology.h	Mon Dec  9 18:46:35 2002
@@ -1,20 +1,15 @@
 #ifndef _ASM_ALPHA_TOPOLOGY_H
 #define _ASM_ALPHA_TOPOLOGY_H
 
-#ifdef CONFIG_NUMA
-#ifdef CONFIG_ALPHA_WILDFIRE
+#if defined(CONFIG_NUMA) && defined(CONFIG_ALPHA_WILDFIRE)
+
 /* With wildfire assume 4 CPUs per node */
 #define __cpu_to_node(cpu)		((cpu) >> 2)
-#endif /* CONFIG_ALPHA_WILDFIRE */
-#endif /* CONFIG_NUMA */
 
-#if !defined(CONFIG_NUMA) || !defined(CONFIG_ALPHA_WILDFIRE)
-#define __cpu_to_node(cpu)		(0)
-#define __memblk_to_node(memblk)	(0)
-#define __parent_node(nid)		(0)
-#define __node_to_first_cpu(node)	(0)
-#define __node_to_cpu_mask(node)	(cpu_online_map)
-#define __node_to_memblk(node)		(0)
-#endif /* !CONFIG_NUMA || !CONFIG_ALPHA_WILDFIRE */
+#else /* !CONFIG_NUMA || !CONFIG_ALPHA_WILDFIRE */
+
+#include <asm-generic/topology.h>
+
+#endif /* CONFIG_NUMA && CONFIG_ALPHA_WILDFIRE */
 
 #endif /* _ASM_ALPHA_TOPOLOGY_H */
diff -Nru a/include/asm-alpha/unistd.h b/include/asm-alpha/unistd.h
--- a/include/asm-alpha/unistd.h	Mon Dec  9 18:46:36 2002
+++ b/include/asm-alpha/unistd.h	Mon Dec  9 18:46:36 2002
@@ -349,7 +349,8 @@
 #define __NR_sys_epoll_wait		409
 #define __NR_remap_file_pages		410
 #define __NR_set_tid_address		411
-#define NR_SYSCALLS			412
+#define __NR_restart_syscall		412
+#define NR_SYSCALLS			413
 
 #if defined(__GNUC__)
 
diff -Nru a/include/asm-arm/signal.h b/include/asm-arm/signal.h
--- a/include/asm-arm/signal.h	Mon Dec  9 18:46:37 2002
+++ b/include/asm-arm/signal.h	Mon Dec  9 18:46:37 2002
@@ -185,8 +185,6 @@
 #ifdef __KERNEL__
 #include <asm/sigcontext.h>
 
-#define sigmask(sig)	(1UL << ((sig) - 1))
-
 #define HAVE_ARCH_GET_SIGNAL_TO_DELIVER
 
 #endif
diff -Nru a/include/asm-i386/bitops.h b/include/asm-i386/bitops.h
--- a/include/asm-i386/bitops.h	Mon Dec  9 18:46:50 2002
+++ b/include/asm-i386/bitops.h	Mon Dec  9 18:46:50 2002
@@ -260,6 +260,8 @@
  constant_test_bit((nr),(addr)) : \
  variable_test_bit((nr),(addr)))
 
+#undef ADDR
+
 /**
  * find_first_zero_bit - find the first zero bit in a memory region
  * @addr: The address to start the search at
diff -Nru a/include/asm-i386/current.h b/include/asm-i386/current.h
--- a/include/asm-i386/current.h	Mon Dec  9 18:46:36 2002
+++ b/include/asm-i386/current.h	Mon Dec  9 18:46:36 2002
@@ -1,7 +1,7 @@
 #ifndef _I386_CURRENT_H
 #define _I386_CURRENT_H
 
-#include <asm/thread_info.h>
+#include <linux/thread_info.h>
 
 struct task_struct;
 
diff -Nru a/include/asm-i386/desc.h b/include/asm-i386/desc.h
--- a/include/asm-i386/desc.h	Mon Dec  9 18:46:34 2002
+++ b/include/asm-i386/desc.h	Mon Dec  9 18:46:34 2002
@@ -6,6 +6,9 @@
 
 #ifndef __ASSEMBLY__
 
+#include <linux/preempt.h>
+#include <linux/smp.h>
+
 #include <asm/mmu.h>
 
 extern struct desc_struct cpu_gdt_table[NR_CPUS][GDT_ENTRIES];
diff -Nru a/include/asm-i386/mca.h b/include/asm-i386/mca.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-i386/mca.h	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,46 @@
+/* -*- mode: c; c-basic-offset: 8 -*- */
+
+/* Platform specific MCA defines */
+#ifndef _ASM_MCA_H
+#define _ASM_MCA_H
+
+/* Maximal number of MCA slots - actually, some machines have less, but
+ * they all have sufficient number of POS registers to cover 8.
+ */
+#define MCA_MAX_SLOT_NR  8
+
+/* Most machines have only one MCA bus.  The only multiple bus machines
+ * I know have at most two */
+#define MAX_MCA_BUSSES 2
+
+#define MCA_PRIMARY_BUS		0
+#define MCA_SECONDARY_BUS	1
+
+/* Dummy slot numbers on primary MCA for integrated functions */
+#define MCA_INTEGSCSI	(MCA_MAX_SLOT_NR)
+#define MCA_INTEGVIDEO	(MCA_MAX_SLOT_NR+1)
+#define MCA_MOTHERBOARD (MCA_MAX_SLOT_NR+2)
+
+/* Dummy POS values for integrated functions */
+#define MCA_DUMMY_POS_START	0x10000
+#define MCA_INTEGSCSI_POS	(MCA_DUMMY_POS_START+1)
+#define MCA_INTEGVIDEO_POS	(MCA_DUMMY_POS_START+2)
+#define MCA_MOTHERBOARD_POS	(MCA_DUMMY_POS_START+3)
+
+/* MCA registers */
+
+#define MCA_MOTHERBOARD_SETUP_REG	0x94
+#define MCA_ADAPTER_SETUP_REG		0x96
+#define MCA_POS_REG(n)			(0x100+(n))
+
+#define MCA_ENABLED	0x01	/* POS 2, set if adapter enabled */
+
+/* Max number of adapters, including both slots and various integrated
+ * things.
+ */
+#define MCA_NUMADAPTERS (MCA_MAX_SLOT_NR+3)
+
+/* lock to protect access to the MCA registers */
+extern spinlock_t mca_lock;
+
+#endif
diff -Nru a/include/asm-i386/mmu.h b/include/asm-i386/mmu.h
--- a/include/asm-i386/mmu.h	Mon Dec  9 18:46:38 2002
+++ b/include/asm-i386/mmu.h	Mon Dec  9 18:46:38 2002
@@ -1,6 +1,7 @@
 #ifndef __i386_MMU_H
 #define __i386_MMU_H
 
+#include <asm/semaphore.h>
 /*
  * The i386 doesn't have a mmu context, but
  * we put the segment information here.
diff -Nru a/include/asm-i386/mpspec.h b/include/asm-i386/mpspec.h
--- a/include/asm-i386/mpspec.h	Mon Dec  9 18:46:34 2002
+++ b/include/asm-i386/mpspec.h	Mon Dec  9 18:46:34 2002
@@ -105,6 +105,7 @@
 #define BUSTYPE_TC	"TC"
 #define BUSTYPE_VME	"VME"
 #define BUSTYPE_XPRESS	"XPRESS"
+#define BUSTYPE_NEC98	"NEC98"
 
 struct mpc_config_ioapic
 {
@@ -195,7 +196,8 @@
 	MP_BUS_ISA = 1,
 	MP_BUS_EISA,
 	MP_BUS_PCI,
-	MP_BUS_MCA
+	MP_BUS_MCA,
+	MP_BUS_NEC98
 };
 extern int mp_bus_id_to_type [MAX_MP_BUSSES];
 extern int mp_bus_id_to_node [MAX_MP_BUSSES];
diff -Nru a/include/asm-i386/signal.h b/include/asm-i386/signal.h
--- a/include/asm-i386/signal.h	Mon Dec  9 18:46:35 2002
+++ b/include/asm-i386/signal.h	Mon Dec  9 18:46:35 2002
@@ -209,8 +209,6 @@
 	 __const_sigismember((set),(sig)) :	\
 	 __gen_sigismember((set),(sig)))
 
-#define sigmask(sig)	(1UL << ((sig) - 1))
-
 static __inline__ int sigfindinword(unsigned long word)
 {
 	__asm__("bsfl %1,%0" : "=r"(word) : "rm"(word) : "cc");
diff -Nru a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h
--- a/include/asm-i386/thread_info.h	Mon Dec  9 18:46:35 2002
+++ b/include/asm-i386/thread_info.h	Mon Dec  9 18:46:35 2002
@@ -20,6 +20,7 @@
  * - if the contents of this structure are changed, the assembly constants must also be changed
  */
 #ifndef __ASSEMBLY__
+
 struct thread_info {
 	struct task_struct	*task;		/* main task structure */
 	struct exec_domain	*exec_domain;	/* execution domain */
@@ -31,6 +32,7 @@
 					 	   0-0xBFFFFFFF for user-thead
 						   0-0xFFFFFFFF for kernel-thread
 						*/
+	struct restart_block    restart_block;
 
 	__u8			supervisor_stack[0];
 };
@@ -44,6 +46,7 @@
 #define TI_CPU		0x0000000C
 #define TI_PRE_COUNT	0x00000010
 #define TI_ADDR_LIMIT	0x00000014
+#define TI_RESTART_BLOCK 0x0000018
 
 #endif
 
@@ -55,6 +58,7 @@
  * preempt_count needs to be 1 initially, until the scheduler is functional.
  */
 #ifndef __ASSEMBLY__
+
 #define INIT_THREAD_INFO(tsk)			\
 {						\
 	.task		= &tsk,			\
@@ -63,6 +67,9 @@
 	.cpu		= 0,			\
 	.preempt_count	= 1,			\
 	.addr_limit	= KERNEL_DS,		\
+	.restart_block = {			\
+		.fn = do_no_restart_syscall,	\
+	},					\
 }
 
 #define init_thread_info	(init_thread_union.thread_info)
diff -Nru a/include/asm-i386/uaccess.h b/include/asm-i386/uaccess.h
--- a/include/asm-i386/uaccess.h	Mon Dec  9 18:46:35 2002
+++ b/include/asm-i386/uaccess.h	Mon Dec  9 18:46:35 2002
@@ -6,7 +6,7 @@
  */
 #include <linux/config.h>
 #include <linux/errno.h>
-#include <linux/sched.h>
+#include <linux/thread_info.h>
 #include <linux/prefetch.h>
 #include <asm/page.h>
 
diff -Nru a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
--- a/include/asm-i386/unistd.h	Mon Dec  9 18:46:50 2002
+++ b/include/asm-i386/unistd.h	Mon Dec  9 18:46:50 2002
@@ -5,6 +5,7 @@
  * This file contains the system call numbers.
  */
 
+#define __NR_restart_syscall      0
 #define __NR_exit		  1
 #define __NR_fork		  2
 #define __NR_read		  3
@@ -258,9 +259,9 @@
 #define __NR_free_hugepages	251
 #define __NR_exit_group		252
 #define __NR_lookup_dcookie	253
-#define __NR_sys_epoll_create	254
-#define __NR_sys_epoll_ctl	255
-#define __NR_sys_epoll_wait	256
+#define __NR_epoll_create	254
+#define __NR_epoll_ctl		255
+#define __NR_epoll_wait		256
 #define __NR_remap_file_pages	257
 #define __NR_set_tid_address	258
 
diff -Nru a/include/asm-m68k/signal.h b/include/asm-m68k/signal.h
--- a/include/asm-m68k/signal.h	Mon Dec  9 18:46:35 2002
+++ b/include/asm-m68k/signal.h	Mon Dec  9 18:46:35 2002
@@ -207,8 +207,6 @@
 	 __const_sigismember(set,sig) :		\
 	 __gen_sigismember(set,sig))
 
-#define sigmask(sig)	(1UL << ((sig) - 1))
-
 extern __inline__ int sigfindinword(unsigned long word)
 {
 	__asm__("bfffo %1{#0,#0},%0" : "=d"(word) : "d"(word & -word) : "cc");
diff -Nru a/include/asm-ppc/cputable.h b/include/asm-ppc/cputable.h
--- a/include/asm-ppc/cputable.h	Mon Dec  9 18:46:36 2002
+++ b/include/asm-ppc/cputable.h	Mon Dec  9 18:46:36 2002
@@ -66,6 +66,7 @@
 #define CPU_FTR_HPTE_TABLE		0x00000200
 #define CPU_FTR_CAN_NAP			0x00000400
 #define CPU_FTR_L3CR			0x00000800
+#define CPU_FTR_NO_DPM			0x00008000
 
 #ifdef __ASSEMBLY__
 
diff -Nru a/include/asm-ppc/errno.h b/include/asm-ppc/errno.h
--- a/include/asm-ppc/errno.h	Mon Dec  9 18:46:35 2002
+++ b/include/asm-ppc/errno.h	Mon Dec  9 18:46:35 2002
@@ -6,12 +6,6 @@
 #undef	EDEADLOCK
 #define	EDEADLOCK	58	/* File locking deadlock error */
 
-/* Should never be seen by user programs */
-#define ERESTARTSYS	512
-#define ERESTARTNOINTR	513
-#define ERESTARTNOHAND	514	/* restart if no handler.. */
-#define ENOIOCTLCMD	515	/* No ioctl command */
-
-#define _LAST_ERRNO	515
+#define _LAST_ERRNO	516
 
 #endif
diff -Nru a/include/asm-ppc/hardirq.h b/include/asm-ppc/hardirq.h
--- a/include/asm-ppc/hardirq.h	Mon Dec  9 18:46:34 2002
+++ b/include/asm-ppc/hardirq.h	Mon Dec  9 18:46:34 2002
@@ -4,6 +4,7 @@
 
 #include <linux/config.h>
 #include <linux/cache.h>
+#include <linux/smp_lock.h>
 
 /* The __last_jiffy_stamp field is needed to ensure that no decrementer 
  * interrupt is lost on SMP machines. Since on most CPUs it is in the same 
diff -Nru a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h
--- a/include/asm-ppc/processor.h	Mon Dec  9 18:46:34 2002
+++ b/include/asm-ppc/processor.h	Mon Dec  9 18:46:34 2002
@@ -635,9 +635,7 @@
  * Bus types
  */
 #define EISA_bus 0
-#define EISA_bus__is_a_macro /* for versions in ksyms.c */
 #define MCA_bus 0
-#define MCA_bus__is_a_macro /* for versions in ksyms.c */
 
 /* Lazy FPU handling on uni-processor */
 extern struct task_struct *last_task_used_math;
diff -Nru a/include/asm-ppc/thread_info.h b/include/asm-ppc/thread_info.h
--- a/include/asm-ppc/thread_info.h	Mon Dec  9 18:46:35 2002
+++ b/include/asm-ppc/thread_info.h	Mon Dec  9 18:46:35 2002
@@ -23,6 +23,7 @@
 	unsigned long		flags;		/* low level flags */
 	int			cpu;		/* cpu we're on */
 	int			preempt_count;
+	struct restart_block	restart_block;
 };
 
 #define INIT_THREAD_INFO(tsk)			\
@@ -31,7 +32,10 @@
 	.exec_domain =	&default_exec_domain,	\
 	.flags =	0,			\
 	.cpu =		0,			\
-	.preempt_count = 1			\
+	.preempt_count = 1,			\
+	.restart_block = {			\
+		.fn = do_no_restart_syscall,	\
+	},					\
 }
 
 #define init_thread_info	(init_thread_union.thread_info)
@@ -70,8 +74,6 @@
 #define TI_FLAGS	8
 #define TI_CPU		12
 #define TI_PREEMPT	16
-#define TI_SOFTIRQ	20
-#define TI_HARDIRQ	24
 
 #define PREEMPT_ACTIVE		0x4000000
 
diff -Nru a/include/asm-ppc/unistd.h b/include/asm-ppc/unistd.h
--- a/include/asm-ppc/unistd.h	Mon Dec  9 18:46:35 2002
+++ b/include/asm-ppc/unistd.h	Mon Dec  9 18:46:35 2002
@@ -4,7 +4,7 @@
 /*
  * This file contains the system call numbers.
  */
-
+#define __NR_restart_syscall	  0
 #define __NR_exit		  1
 #define __NR_fork		  2
 #define __NR_read		  3
@@ -240,9 +240,9 @@
 #define __NR_free_hugepages	233
 #define __NR_exit_group		234
 #define __NR_lookup_dcookie	235
-#define __NR_sys_epoll_create	236
-#define __NR_sys_epoll_ctl	237
-#define __NR_sys_epoll_wait	238
+#define __NR_epoll_create	236
+#define __NR_epoll_ctl		237
+#define __NR_epoll_wait		238
 #define __NR_remap_file_pages	239
 
 #define __NR(n)	#n
diff -Nru a/include/asm-ppc64/compat.h b/include/asm-ppc64/compat.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-ppc64/compat.h	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,22 @@
+#ifndef _ASM_PPC64_COMPAT_H
+#define _ASM_PPC64_COMPAT_H
+/*
+ * Architecture specific compatibility types
+ */
+#include <linux/types.h>
+
+typedef u32		compat_size_t;
+typedef s32		compat_ssize_t;
+typedef s32		compat_time_t;
+
+struct compat_timespec {
+	compat_time_t	tv_sec;
+	s32		tv_nsec;
+};
+
+struct compat_timeval {
+	compat_time_t	tv_sec;
+	s32		tv_usec;
+};
+
+#endif /* _ASM_PPC64_COMPAT_H */
diff -Nru a/include/asm-ppc64/eeh.h b/include/asm-ppc64/eeh.h
--- a/include/asm-ppc64/eeh.h	Mon Dec  9 18:46:51 2002
+++ b/include/asm-ppc64/eeh.h	Mon Dec  9 18:46:51 2002
@@ -27,25 +27,26 @@
 
 struct pci_dev;
 
-#define IO_UNMAPPED_REGION_ID 0xaUL
-
-#define IO_TOKEN_TO_ADDR(token) ((((unsigned long)(token)) & 0xFFFFFFFF) | (0xEUL << 60))
-/* Flag bits encoded in the 3 unused function bits of devfn */
-#define EEH_TOKEN_DISABLED (1UL << 34UL)	/* eeh is disabled for this token */
-#define IS_EEH_TOKEN_DISABLED(token) ((unsigned long)(token) & EEH_TOKEN_DISABLED)
-
-#define EEH_STATE_OVERRIDE 1   /* IOA does not require eeh traps */
-#define EEH_STATE_FAILURE  16  /* */
+/* I/O addresses are converted to EEH "tokens" such that a driver will cause
+ * a bad page fault if the address is used directly (i.e. these addresses are
+ * never actually mapped.  Translation between IO <-> EEH region is 1 to 1.
+ */
+#define IO_TOKEN_TO_ADDR(token) (((unsigned long)(token) & ~(0xfUL << REGION_SHIFT)) | \
+				(IO_REGION_ID << REGION_SHIFT))
+#define IO_ADDR_TO_TOKEN(addr) (((unsigned long)(addr) & ~(0xfUL << REGION_SHIFT)) | \
+				(EEH_REGION_ID << REGION_SHIFT))
+
+/* Values for eeh_mode bits in device_node */
+#define EEH_MODE_SUPPORTED	(1<<0)
+#define EEH_MODE_NOCHECK	(1<<1)
 
 /* This is for profiling only */
 extern unsigned long eeh_total_mmio_ffs;
 
-extern int eeh_implemented;
-
 void eeh_init(void);
-static inline int is_eeh_implemented(void) { return eeh_implemented; }
 int eeh_get_state(unsigned long ea);
 unsigned long eeh_check_failure(void *token, unsigned long val);
+void *eeh_ioremap(unsigned long addr, void *vaddr);
 
 #define EEH_DISABLE		0
 #define EEH_ENABLE		1
@@ -58,15 +59,11 @@
  */
 int is_eeh_configured(struct pci_dev *dev);
 
-/* Generate an EEH token.
- * The high nibble of the offset is cleared, otherwise bounds checking is performed.
- * Use IO_TOKEN_TO_ADDR(token) to translate this token back to a mapped virtual addr.
- * Do NOT do this to perform IO -- use the read/write macros!
- */
-unsigned long eeh_token(unsigned long phb,
-			unsigned long bus,
-			unsigned long devfn,
-			unsigned long offset);
+/* Translate a (possible) eeh token to a physical addr.
+ * If "token" is not an eeh token it is simply returned under
+ * the assumption that it is already a physical addr.
+ */
+unsigned long eeh_token_to_phys(unsigned long token);
 
 extern void *memcpy(void *, const void *, unsigned long);
 extern void *memset(void *,int, unsigned long);
@@ -77,15 +74,16 @@
  * If EEH is off for a device and it is a memory BAR, ioremap will
  * map it to the IOREGION.  In this case addr == vaddr and since these
  * should be in registers we compare them first.  Next we check for
- * all ones which is perhaps fastest as ~val.  Finally we weed out
- * EEH disabled IO BARs.
+ * ff's which indicates a (very) possible failure.
  *
  * If this macro yields TRUE, the caller relays to eeh_check_failure()
  * which does further tests out of line.
  */
-/* #define EEH_POSSIBLE_ERROR(addr, vaddr, val) ((vaddr) != (addr) && ~(val) == 0 && !IS_EEH_TOKEN_DISABLED(addr)) */
+/* #define EEH_POSSIBLE_IO_ERROR(val) (~(val) == 0) */
+/* #define EEH_POSSIBLE_ERROR(addr, vaddr, val) ((vaddr) != (addr) && EEH_POSSIBLE_IO_ERROR(val) */
 /* This version is rearranged to collect some profiling data */
-#define EEH_POSSIBLE_ERROR(addr, vaddr, val) (~(val) == 0 && (++eeh_total_mmio_ffs, (vaddr) != (addr) && !IS_EEH_TOKEN_DISABLED(addr)))
+#define EEH_POSSIBLE_IO_ERROR(val) (~(val) == 0 && ++eeh_total_mmio_ffs)
+#define EEH_POSSIBLE_ERROR(addr, vaddr, val) (EEH_POSSIBLE_IO_ERROR(val) && (vaddr) != (addr))
 
 /* 
  * MMIO read/write operations with EEH support.
@@ -149,38 +147,56 @@
 	memcpy(vdest, src, n);
 }
 
-static inline void eeh_insb(volatile u8 *addr, void *buf, int n) {
-	volatile u8 *vaddr = (volatile u8 *)IO_TOKEN_TO_ADDR(addr);
-	_insb(vaddr, buf, n);
-	/* ToDo: look for ff's in buf[n] */
-}
+/* The I/O macros must handle ISA ports as well as PCI I/O bars.
+ * ISA does not implement EEH and ISA may not exist in the system.
+ * For PCI we check for EEH failures.
+ */
+#define _IO_IS_ISA(port) ((port) < 0x10000)
+#define _IO_HAS_ISA_BUS	(isa_io_base != 0)
 
-static inline void eeh_outsb(volatile u8 *addr, const void *buf, int n) {
-	volatile u8 *vaddr = (volatile u8 *)IO_TOKEN_TO_ADDR(addr);
-	_outsb(vaddr, buf, n);
+static inline u8 eeh_inb(unsigned long port) {
+	u8 val;
+	if (_IO_IS_ISA(port) && !_IO_HAS_ISA_BUS)
+		return ~0;
+	val = in_8((u8 *)(port+pci_io_base));
+	if (!_IO_IS_ISA(port) && EEH_POSSIBLE_IO_ERROR(val))
+		return eeh_check_failure((void*)(port+pci_io_base), val);
+	return val;
 }
 
-static inline void eeh_insw_ns(volatile u16 *addr, void *buf, int n) {
-	volatile u16 *vaddr = (volatile u16 *)IO_TOKEN_TO_ADDR(addr);
-	_insw_ns(vaddr, buf, n);
-	/* ToDo: look for ffff's in buf[n] */
+static inline void eeh_outb(u8 val, unsigned long port) {
+	if (!_IO_IS_ISA(port) || _IO_HAS_ISA_BUS)
+		return out_8((u8 *)(port+pci_io_base), val);
 }
 
-static inline void eeh_outsw_ns(volatile u16 *addr, const void *buf, int n) {
-	volatile u16 *vaddr = (volatile u16 *)IO_TOKEN_TO_ADDR(addr);
-	_outsw_ns(vaddr, buf, n);
+static inline u16 eeh_inw(unsigned long port) {
+	u16 val;
+	if (_IO_IS_ISA(port) && !_IO_HAS_ISA_BUS)
+		return ~0;
+	val = in_le16((u16 *)(port+pci_io_base));
+	if (!_IO_IS_ISA(port) && EEH_POSSIBLE_IO_ERROR(val))
+		return eeh_check_failure((void*)(port+pci_io_base), val);
+	return val;
 }
 
-static inline void eeh_insl_ns(volatile u32 *addr, void *buf, int n) {
-	volatile u32 *vaddr = (volatile u32 *)IO_TOKEN_TO_ADDR(addr);
-	_insl_ns(vaddr, buf, n);
-	/* ToDo: look for ffffffff's in buf[n] */
+static inline void eeh_outw(u16 val, unsigned long port) {
+	if (!_IO_IS_ISA(port) || _IO_HAS_ISA_BUS)
+		return out_le16((u16 *)(port+pci_io_base), val);
 }
 
-static inline void eeh_outsl_ns(volatile u32 *addr, const void *buf, int n) {
-	volatile u32 *vaddr = (volatile u32 *)IO_TOKEN_TO_ADDR(addr);
-	_outsl_ns(vaddr, buf, n);
+static inline u32 eeh_inl(unsigned long port) {
+	u32 val;
+	if (_IO_IS_ISA(port) && !_IO_HAS_ISA_BUS)
+		return ~0;
+	val = in_le32((u32 *)(port+pci_io_base));
+	if (!_IO_IS_ISA(port) && EEH_POSSIBLE_IO_ERROR(val))
+		return eeh_check_failure((void*)(port+pci_io_base), val);
+	return val;
 }
 
+static inline void eeh_outl(u32 val, unsigned long port) {
+	if (!_IO_IS_ISA(port) || _IO_HAS_ISA_BUS)
+		return out_le32((u32 *)(port+pci_io_base), val);
+}
 
 #endif /* _EEH_H */
diff -Nru a/include/asm-ppc64/errno.h b/include/asm-ppc64/errno.h
--- a/include/asm-ppc64/errno.h	Mon Dec  9 18:46:34 2002
+++ b/include/asm-ppc64/errno.h	Mon Dec  9 18:46:34 2002
@@ -13,12 +13,6 @@
 #undef	EDEADLOCK
 #define	EDEADLOCK	58	/* File locking deadlock error */
 
-/* Should never be seen by user programs */
-#define ERESTARTSYS	512
-#define ERESTARTNOINTR	513
-#define ERESTARTNOHAND	514	/* restart if no handler.. */
-#define ENOIOCTLCMD	515	/* No ioctl command */
-
-#define _LAST_ERRNO	515
+#define _LAST_ERRNO	516
 
 #endif
diff -Nru a/include/asm-ppc64/hardirq.h b/include/asm-ppc64/hardirq.h
--- a/include/asm-ppc64/hardirq.h	Mon Dec  9 18:46:35 2002
+++ b/include/asm-ppc64/hardirq.h	Mon Dec  9 18:46:35 2002
@@ -10,6 +10,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/cache.h>
 #include <linux/preempt.h>
 
 typedef struct {
@@ -104,12 +105,4 @@
 
 #endif /* __KERNEL__ */
 	
-#define show_stack(SP)				\
-do {						\
-	if (SP)					\
-		print_backtrace(SP);		\
-	else					\
-		print_backtrace(_get_SP());	\
-} while (0)
-
 #endif /* __ASM_HARDIRQ_H */
diff -Nru a/include/asm-ppc64/hvcall.h b/include/asm-ppc64/hvcall.h
--- a/include/asm-ppc64/hvcall.h	Mon Dec  9 18:46:34 2002
+++ b/include/asm-ppc64/hvcall.h	Mon Dec  9 18:46:34 2002
@@ -57,6 +57,7 @@
 #define H_IPI			0x6c
 #define H_IPOLL			0x70
 #define H_XIRR			0x74
+#define H_PERFMON		0x7c
 
 #define HSC			".long 0x44000022\n"
 #define H_ENTER_r3		"li	3, 0x08\n"
diff -Nru a/include/asm-ppc64/hw_irq.h b/include/asm-ppc64/hw_irq.h
--- a/include/asm-ppc64/hw_irq.h	Mon Dec  9 18:46:51 2002
+++ b/include/asm-ppc64/hw_irq.h	Mon Dec  9 18:46:51 2002
@@ -13,6 +13,7 @@
 #define _PPC64_HW_IRQ_H
 
 #include <linux/config.h>
+#include <linux/errno.h>
 #include <asm/irq.h>
 
 int timer_interrupt(struct pt_regs *);
@@ -79,6 +80,27 @@
  */
 struct hw_interrupt_type;
 static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
+ 
+struct notifier_block;
+ 
+#ifdef CONFIG_PROFILING
+ 
+int register_profile_notifier(struct notifier_block * nb);
+int unregister_profile_notifier(struct notifier_block * nb);
 
+#else
+
+static inline int register_profile_notifier(struct notifier_block * nb)
+{
+	return -ENOSYS;
+}
+
+static inline int unregister_profile_notifier(struct notifier_block * nb)
+{
+	return -ENOSYS;
+}
+
+#endif /* CONFIG_PROFILING */
+ 
 #endif /* _PPC64_HW_IRQ_H */
 #endif /* __KERNEL__ */
diff -Nru a/include/asm-ppc64/iSeries/HvCall.h b/include/asm-ppc64/iSeries/HvCall.h
--- a/include/asm-ppc64/iSeries/HvCall.h	Mon Dec  9 18:46:35 2002
+++ b/include/asm-ppc64/iSeries/HvCall.h	Mon Dec  9 18:46:35 2002
@@ -130,6 +130,7 @@
 #define HvCallBaseRouter28				HvCallBase + 28
 #define HvCallBaseRouter29				HvCallBase + 29
 #define HvCallBaseRouter30				HvCallBase + 30
+#define HvCallBaseSetDebugBus 				HvCallBase + 31
 
 #define HvCallCcSetDABR  				HvCallCc + 7
 
@@ -203,6 +204,11 @@
 static inline void HvCall_setDABR(unsigned long val)
 {
 	HvCall1(HvCallCcSetDABR, val);
+}
+
+static inline void HvCall_setDebugBus(unsigned long val)
+{
+	HvCall1(HvCallBaseSetDebugBus, val);
 }
 
 #endif // _HVCALL_H
diff -Nru a/include/asm-ppc64/io.h b/include/asm-ppc64/io.h
--- a/include/asm-ppc64/io.h	Mon Dec  9 18:46:51 2002
+++ b/include/asm-ppc64/io.h	Mon Dec  9 18:46:51 2002
@@ -25,13 +25,7 @@
 #undef __IO_DEBUG
 
 extern unsigned long isa_io_base;
-extern unsigned long isa_mem_base;
 extern unsigned long pci_io_base;
-extern unsigned long pci_dram_offset;
-extern int have_print;
-#define _IO_BASE	isa_io_base
-#define _ISA_MEM_BASE	isa_mem_base
-#define PCI_DRAM_OFFSET	pci_dram_offset
 
 #ifdef CONFIG_PPC_ISERIES
 #define readb(addr)		iSeries_Read_Byte((void*)(addr))  
@@ -50,36 +44,45 @@
 #define outw(data,addr)		writew(data,((unsigned long)(addr)))  
 #define outl(data,addr)		writel(data,((unsigned long)(addr)))
 #else
-#define IS_MAPPED_VADDR(port)	((unsigned long)(port) >> 60UL)
 #define readb(addr)		eeh_readb((void*)(addr))  
 #define readw(addr)		eeh_readw((void*)(addr))  
 #define readl(addr)		eeh_readl((void*)(addr))
 #define writeb(data, addr)	eeh_writeb((data), ((void*)(addr)))
 #define writew(data, addr)	eeh_writew((data), ((void*)(addr)))
 #define writel(data, addr)	eeh_writel((data), ((void*)(addr)))
-#define memset_io(a,b,c)	eeh_memset((void *)(a),(b),(c))
+#define memset_io(a,b,c)	eeh_memset_io((void *)(a),(b),(c))
 #define memcpy_fromio(a,b,c)	eeh_memcpy_fromio((a),(void *)(b),(c))
 #define memcpy_toio(a,b,c)	eeh_memcpy_toio((void *)(a),(b),(c))
-#define inb(port)		_inb((unsigned long)port)
-#define outb(val, port)		_outb(val, (unsigned long)port)
-#define inw(port)		_inw((unsigned long)port)
-#define outw(val, port)		_outw(val, (unsigned long)port)
-#define inl(port)		_inl((unsigned long)port)
-#define outl(val, port)		_outl(val, (unsigned long)port)
+#define inb(port)		eeh_inb((unsigned long)port)
+#define outb(val, port)		eeh_outb(val, (unsigned long)port)
+#define inw(port)		eeh_inw((unsigned long)port)
+#define outw(val, port)		eeh_outw(val, (unsigned long)port)
+#define inl(port)		eeh_inl((unsigned long)port)
+#define outl(val, port)		eeh_outl(val, (unsigned long)port)
 
 /*
  * The insw/outsw/insl/outsl macros don't do byte-swapping.
  * They are only used in practice for transferring buffers which
  * are arrays of bytes, and byte-swapping is not appropriate in
  * that case.  - paulus */
-#define insb(port, buf, ns)	eeh_insb((u8 *)(port), (buf), (ns))
-#define outsb(port, buf, ns)	eeh_outsb((u8 *)(port), (buf), (ns))
-#define insw(port, buf, ns)	eeh_insw_ns((u16 *)(port), (buf), (ns))
-#define outsw(port, buf, ns)	eeh_outsw_ns((u16 *)(port), (buf), (ns))
-#define insl(port, buf, nl)	eeh_insl_ns((u32 *)(port), (buf), (nl))
-#define outsl(port, buf, nl)	eeh_outsl_ns((u32 *)(port), (buf), (nl))
+#define insb(port, buf, ns)	_insb((u8 *)((port)+pci_io_base), (buf), (ns))
+#define outsb(port, buf, ns)	_outsb((u8 *)((port)+pci_io_base), (buf), (ns))
+#define insw(port, buf, ns)	_insw_ns((u16 *)((port)+pci_io_base), (buf), (ns))
+#define outsw(port, buf, ns)	_outsw_ns((u16 *)((port)+pci_io_base), (buf), (ns))
+#define insl(port, buf, nl)	_insl_ns((u32 *)((port)+pci_io_base), (buf), (nl))
+#define outsl(port, buf, nl)	_outsl_ns((u32 *)((port)+pci_io_base), (buf), (nl))
 #endif
 
+extern void _insb(volatile u8 *port, void *buf, int ns);
+extern void _outsb(volatile u8 *port, const void *buf, int ns);
+extern void _insw(volatile u16 *port, void *buf, int ns);
+extern void _outsw(volatile u16 *port, const void *buf, int ns);
+extern void _insl(volatile u32 *port, void *buf, int nl);
+extern void _outsl(volatile u32 *port, const void *buf, int nl);
+extern void _insw_ns(volatile u16 *port, void *buf, int ns);
+extern void _outsw_ns(volatile u16 *port, const void *buf, int ns);
+extern void _insl_ns(volatile u32 *port, void *buf, int nl);
+extern void _outsl_ns(volatile u32 *port, const void *buf, int nl);
 
 /*
  * output pause versions need a delay at least for the
@@ -92,27 +95,15 @@
 #define inl_p(port)             inl(port)
 #define outl_p(val, port)       (udelay(1), outl((val, (port)))
 
-
-extern void _insb(volatile u8 *port, void *buf, int ns);
-extern void _outsb(volatile u8 *port, const void *buf, int ns);
-extern void _insw(volatile u16 *port, void *buf, int ns);
-extern void _outsw(volatile u16 *port, const void *buf, int ns);
-extern void _insl(volatile u32 *port, void *buf, int nl);
-extern void _outsl(volatile u32 *port, const void *buf, int nl);
-extern void _insw_ns(volatile u16 *port, void *buf, int ns);
-extern void _outsw_ns(volatile u16 *port, const void *buf, int ns);
-extern void _insl_ns(volatile u32 *port, void *buf, int nl);
-extern void _outsl_ns(volatile u32 *port, const void *buf, int nl);
-
 /*
  * The *_ns versions below don't do byte-swapping.
  * Neither do the standard versions now, these are just here
  * for older code.
  */
-#define insw_ns(port, buf, ns)	insw(port, buf, ns)
-#define outsw_ns(port, buf, ns)	outsw(port, buf, ns)
-#define insl_ns(port, buf, nl)	insl(port, buf, nl)
-#define outsl_ns(port, buf, nl)	outsl(port, buf, nl)
+#define insw_ns(port, buf, ns)	_insw_ns((u16 *)((port)+pci_io_base), (buf), (ns))
+#define outsw_ns(port, buf, ns)	_outsw_ns((u16 *)((port)+pci_io_base), (buf), (ns))
+#define insl_ns(port, buf, nl)	_insl_ns((u32 *)((port)+pci_io_base), (buf), (nl))
+#define outsl_ns(port, buf, nl)	_outsl_ns((u32 *)((port)+pci_io_base), (buf), (nl))
 
 
 #define IO_SPACE_LIMIT ~(0UL)
@@ -249,49 +240,6 @@
 
 #ifndef CONFIG_PPC_ISERIES 
 #include <asm/eeh.h>
-
-static inline u8 _inb(unsigned long port) {
-	if (IS_MAPPED_VADDR(port))
-		return readb((void *)port);
-	else if (_IO_BASE)
-		return in_8((u8 *)((port)+_IO_BASE));
-	else
-		return 0xff;
-}
-static inline void _outb(u8 val, unsigned long port) {
-	if (IS_MAPPED_VADDR(port))
-		return writeb(val, (void *)port);
-	else if (_IO_BASE)
-		out_8((u8 *)((port)+_IO_BASE), val);
-}
-static inline u16 _inw(unsigned long port) {
-	if (IS_MAPPED_VADDR(port))
-		return readw((void *)port);
-	else if (_IO_BASE)
-		return in_le16((u16 *)((port)+_IO_BASE));
-	else
-		return 0xffff;
-}
-static inline void _outw(u16 val, unsigned long port) {
-	if (IS_MAPPED_VADDR(port))
-		return writew(val, (void *)port);
-	else if (_IO_BASE)
-		out_le16((u16 *)((port)+_IO_BASE), val);
-}
-static inline u32 _inl(unsigned long port) {
-	if (IS_MAPPED_VADDR(port))
-		return readl((void *)port);
-	else if (_IO_BASE)
-		return in_le32((u32 *)((port)+_IO_BASE));
-	else
-		return 0xffffffff;
-}
-static inline void _outl(u32 val, unsigned long port) {
-	if (IS_MAPPED_VADDR(port))
-		return writel(val, (void *)port);
-	else if (_IO_BASE)
-		out_le32((u32 *)((port)+_IO_BASE), val);
-}
 #endif
 
 #ifdef __KERNEL__
diff -Nru a/include/asm-ppc64/page.h b/include/asm-ppc64/page.h
--- a/include/asm-ppc64/page.h	Mon Dec  9 18:46:34 2002
+++ b/include/asm-ppc64/page.h	Mon Dec  9 18:46:34 2002
@@ -168,8 +168,10 @@
 #define KERNELBASE      PAGE_OFFSET
 #define VMALLOCBASE     0xD000000000000000
 #define IOREGIONBASE    0xE000000000000000
+#define EEHREGIONBASE   0xA000000000000000
 
 #define IO_REGION_ID       (IOREGIONBASE>>REGION_SHIFT)
+#define EEH_REGION_ID      (EEHREGIONBASE>>REGION_SHIFT)
 #define VMALLOC_REGION_ID  (VMALLOCBASE>>REGION_SHIFT)
 #define KERNEL_REGION_ID   (KERNELBASE>>REGION_SHIFT)
 #define USER_REGION_ID     (0UL)
diff -Nru a/include/asm-ppc64/pci-bridge.h b/include/asm-ppc64/pci-bridge.h
--- a/include/asm-ppc64/pci-bridge.h	Mon Dec  9 18:46:34 2002
+++ b/include/asm-ppc64/pci-bridge.h	Mon Dec  9 18:46:34 2002
@@ -12,17 +12,6 @@
 struct device_node;
 struct pci_controller;
 
-/*
- * pci_io_base returns the memory address at which you can access
- * the I/O space for PCI bus number `bus' (or NULL on error).
- */
-extern void *pci_bus_io_base(unsigned int bus);
-extern unsigned long pci_bus_io_base_phys(unsigned int bus);
-extern unsigned long pci_bus_mem_base_phys(unsigned int bus);
-
-/* Get the PCI host controller for a bus */
-extern struct pci_controller* pci_bus_to_hose(int bus);
-
 /* Get the PCI host controller for an OF device */
 extern struct pci_controller*
 pci_find_hose_for_OF_device(struct device_node* node);
@@ -92,6 +81,7 @@
 	else
 		return fetch_dev_dn(dev);
 }
+
 /* Use this macro after the PCI bus walk for max performance when it
  * is known that sysdata is correct.
  */
diff -Nru a/include/asm-ppc64/pci.h b/include/asm-ppc64/pci.h
--- a/include/asm-ppc64/pci.h	Mon Dec  9 18:46:36 2002
+++ b/include/asm-ppc64/pci.h	Mon Dec  9 18:46:36 2002
@@ -9,18 +9,17 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-/* Values for the `which' argument to sys_pciconfig_iobase syscall.  */
-#define IOBASE_BRIDGE_NUMBER	0
-#define IOBASE_MEMORY		1
-#define IOBASE_IO		2
-#define IOBASE_ISA_IO           3
-#define IOBASE_ISA_MEM          4
-
-/* Can be used to override the logic in pci_scan_bus for skipping
- * already-configured bus numbers - to be used for buggy BIOSes
- * or architectures with incomplete PCI setup by the loader.
- */
-extern int pcibios_assign_all_busses(void);
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <asm/scatterlist.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+
+static inline int pcibios_assign_all_busses(void)
+{
+	return 0;
+}
 
 #define PCIBIOS_MIN_IO		0x1000
 #define PCIBIOS_MIN_MEM		0x10000000
@@ -35,31 +34,8 @@
 	/* We don't do dynamic PCI IRQ allocation */
 }
 
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <asm/scatterlist.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-
 struct pci_dev;
-#define REG_SAVE_SIZE 64
-/************************************************************************
- * Structure to hold the data for PCI Register Save/Restore functions.  *
- ************************************************************************/
-struct pci_config_reg_save_area {
-	struct pci_dev* PciDev;	    /* Pointer to device(Sanity Check)     */ 
-	int    Flags;               /* Control & Info Flags                */
-	int    RCode;               /* Return Code on Save/Restore         */
-	int    Register;            /* Pointer to current register.        */
-	u8     Regs[REG_SAVE_SIZE]; /* Save Area                           */ 
-};
-/************************************************************************
- * Functions to support device reset                                    *
- ************************************************************************/
-extern int   pci_reset_device(struct pci_dev*, int, int);
-extern int   pci_save_config_regs(struct pci_dev*,struct pci_config_reg_save_area*);
-extern int   pci_restore_config_regs(struct pci_dev*,struct pci_config_reg_save_area*);
+
 extern char* pci_card_location(struct pci_dev*);
 
 extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
@@ -68,7 +44,7 @@
 				void *vaddr, dma_addr_t dma_handle);
 
 extern dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
-					size_t size, int direction);
+				 size_t size, int direction);
 extern void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
                              size_t size, int direction);
 extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
diff -Nru a/include/asm-ppc64/ppc32.h b/include/asm-ppc64/ppc32.h
--- a/include/asm-ppc64/ppc32.h	Mon Dec  9 18:46:36 2002
+++ b/include/asm-ppc64/ppc32.h	Mon Dec  9 18:46:36 2002
@@ -1,6 +1,7 @@
 #ifndef _PPC64_PPC32_H
 #define _PPC64_PPC32_H
 
+#include <linux/compat.h>
 #include <asm/siginfo.h>
 #include <asm/signal.h>
 
@@ -43,10 +44,7 @@
 })
 
 /* These are here to support 32-bit syscalls on a 64-bit kernel. */
-typedef unsigned int	__kernel_size_t32;
-typedef int		__kernel_ssize_t32;
 typedef int		__kernel_ptrdiff_t32;
-typedef int		__kernel_time_t32;
 typedef int		__kernel_clock_t32;
 typedef int		__kernel_pid_t32;
 typedef unsigned short	__kernel_ipc_pid_t32;
@@ -160,7 +158,7 @@
 typedef struct sigaltstack_32 {
 	unsigned int ss_sp;
 	int ss_flags;
-	__kernel_size_t32 ss_size;
+	compat_size_t ss_size;
 } stack_32_t;
 
 struct flock32 {
@@ -174,39 +172,22 @@
 
 struct stat32 {
 	__kernel_dev_t32   st_dev; /* 2 */
-	/* __kernel_dev_t32 __pad1; */ /* 2 */
 	__kernel_ino_t32   st_ino; /* 4  */
 	__kernel_mode_t32  st_mode; /* 2  */
 	short   	   st_nlink; /* 2 */
 	__kernel_uid_t32   st_uid; /* 2 */
 	__kernel_gid_t32   st_gid; /* 2 */
 	__kernel_dev_t32   st_rdev; /* 2 */
-	/* __kernel_dev_t32 __pad2; */ /* 2 */
 	__kernel_off_t32   st_size; /* 4 */
 	__kernel_off_t32   st_blksize; /* 4 */
 	__kernel_off_t32   st_blocks; /* 4 */
-	__kernel_time_t32  st_atime; /* 4 */
+	compat_time_t    st_atime; /* 4 */
 	unsigned int       __unused1; /* 4 */
-	__kernel_time_t32  st_mtime; /* 4 */
+	compat_time_t    st_mtime; /* 4 */
 	unsigned int       __unused2; /* 4 */
-	__kernel_time_t32  st_ctime; /* 4 */
+	compat_time_t    st_ctime; /* 4 */
 	unsigned int       __unused3; /* 4 */
 	unsigned int  __unused4[2]; /* 2*4 */
-};
-
-struct __old_kernel_stat32
-{
-	unsigned short st_dev;
-	unsigned short st_ino;
-	unsigned short st_mode;
-	unsigned short st_nlink;
-	unsigned short st_uid;
-	unsigned short st_gid;
-	unsigned short st_rdev;
-	unsigned int   st_size;
-	unsigned int   st_atime;
-	unsigned int   st_mtime;
-	unsigned int   st_ctime;
 };
 
 struct sigcontext32 {
diff -Nru a/include/asm-ppc64/prom.h b/include/asm-ppc64/prom.h
--- a/include/asm-ppc64/prom.h	Mon Dec  9 18:46:52 2002
+++ b/include/asm-ppc64/prom.h	Mon Dec  9 18:46:52 2002
@@ -125,12 +125,18 @@
 	int	n_intrs;
 	struct	interrupt_info *intrs;
 	char	*full_name;
+
+	/* PCI stuff probably doesn't belong here */
 	int	busno;			/* for pci devices */
 	int	bussubno;		/* for pci devices */
 	int	devfn;			/* for pci devices */
+#define DN_STATUS_BIST_FAILED (1<<0)
+	int	status;			/* Current device status (non-zero is bad) */
+	int	eeh_mode;		/* See eeh.h for possible EEH_MODEs */
+	int	eeh_config_addr;
 	struct  pci_controller *phb;	/* for pci devices */
 	struct	TceTable *tce_table;	/* for phb's or bridges */
-#define DN_STATUS_BIST_FAILED (1<<0)
+
 	struct	property *properties;
 	struct	device_node *parent;
 	struct	device_node *child;
diff -Nru a/include/asm-ppc64/stat.h b/include/asm-ppc64/stat.h
--- a/include/asm-ppc64/stat.h	Mon Dec  9 18:46:52 2002
+++ b/include/asm-ppc64/stat.h	Mon Dec  9 18:46:52 2002
@@ -10,20 +10,6 @@
 
 #include <linux/types.h>
 
-struct __old_kernel_stat {
-	unsigned short st_dev;
-	unsigned short st_ino;
-	unsigned short st_mode;
-	unsigned short st_nlink;
-	unsigned short st_uid;
-	unsigned short st_gid;
-	unsigned short st_rdev;
-	unsigned long  st_size;
-	unsigned long  st_atime;
-	unsigned long  st_mtime;
-	unsigned long  st_ctime;
-};
-
 struct stat {
 	dev_t		st_dev;
 	ino_t		st_ino;
@@ -48,7 +34,7 @@
 
 #define STAT_HAVE_NSEC 1
 
-/* This matches struct stat64 in glibc2.1. */
+/* This matches struct stat64 in glibc2.1. Only used for 32 bit. */
 struct stat64 {
 	unsigned long st_dev; 		/* Device.  */
 	unsigned long st_ino;		/* File serial number.  */
diff -Nru a/include/asm-ppc64/system.h b/include/asm-ppc64/system.h
--- a/include/asm-ppc64/system.h	Mon Dec  9 18:46:52 2002
+++ b/include/asm-ppc64/system.h	Mon Dec  9 18:46:52 2002
@@ -79,7 +79,6 @@
 extern void (*xmon_fault_handler)(struct pt_regs *regs);
 #endif
 
-extern void print_backtrace(unsigned long *);
 extern void show_regs(struct pt_regs * regs);
 extern void flush_instruction_cache(void);
 extern int _get_PVR(void);
diff -Nru a/include/asm-ppc64/thread_info.h b/include/asm-ppc64/thread_info.h
--- a/include/asm-ppc64/thread_info.h	Mon Dec  9 18:46:34 2002
+++ b/include/asm-ppc64/thread_info.h	Mon Dec  9 18:46:34 2002
@@ -23,6 +23,7 @@
 	unsigned long	flags;			/* low level flags */
 	int		cpu;			/* cpu we're on */
 	int		preempt_count;		/* not used at present */
+	struct restart_block restart_block;
 };
 
 /*
@@ -37,6 +38,9 @@
 	.flags =	0,			\
 	.cpu =		0,			\
 	.preempt_count = 1,			\
+	.restart_block = {			\
+		.fn = do_no_restart_syscall,	\
+	},					\
 }
 
 #define init_thread_info	(init_thread_union.thread_info)
diff -Nru a/include/asm-ppc64/unistd.h b/include/asm-ppc64/unistd.h
--- a/include/asm-ppc64/unistd.h	Mon Dec  9 18:46:34 2002
+++ b/include/asm-ppc64/unistd.h	Mon Dec  9 18:46:34 2002
@@ -10,6 +10,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#define __NR_restart_syscall	  0
 #define __NR_exit		  1
 #define __NR_fork		  2
 #define __NR_read		  3
@@ -231,7 +232,7 @@
 #define __NR_lremovexattr	219
 #define __NR_fremovexattr	220
 #define __NR_futex		221
-#define __NR_sched_setaffinity	222     
+#define __NR_sched_setaffinity	222
 #define __NR_sched_getaffinity	223
 /* 224 currently unused */
 #define __NR_tuxcall		225
@@ -244,6 +245,11 @@
 #define __NR_alloc_hugepages	232
 #define __NR_free_hugepages	233
 #define __NR_exit_group		234
+#define __NR_lookup_dcookie	235
+#define __NR_sys_epoll_create	236
+#define __NR_sys_epoll_ctl	237
+#define __NR_sys_epoll_wait	238
+#define __NR_remap_file_pages	239
 
 #define __NR(n)	#n
 
diff -Nru a/include/asm-s390/ccwdev.h b/include/asm-s390/ccwdev.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-s390/ccwdev.h	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,185 @@
+/*
+ *  include/asm-s390/ccwdev.h
+ *  include/asm-s390x/ccwdev.h
+ *
+ *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Author(s): Arnd Bergmann <arndb@de.ibm.com>
+ *
+ *  Interface for CCW device drivers
+ */
+#ifndef _S390_CCWDEV_H_
+#define _S390_CCWDEV_H_
+
+#include <linux/device.h>
+
+/* structs from asm/cio.h */
+struct irb;
+struct ccw1;
+
+/* the id is used to identify what hardware a device driver supports. It 
+ * is used both by the ccw subsystem driver for probing and from
+ * user space for automatic module loading.
+ *
+ * References:
+ *   - struct usb_device_id (include/linux/usb.h)
+ *   - devreg_hc_t (include/linux/s390dyn.h)
+ *   - chandev_model_info (drivers/s390/misc/chandev.c)
+ */
+struct ccw_device_id {
+	__u16	match_flags;	/* which fields to match against */
+
+	__u16	cu_type;	/* control unit type     */
+	__u16	dev_type;	/* device type           */
+	__u8	cu_model;	/* control unit model    */
+	__u8	dev_model;	/* device model          */
+
+	unsigned long driver_info;
+};
+
+enum match_flag {
+	CCW_DEVICE_ID_MATCH_CU_TYPE      = 0x01,
+	CCW_DEVICE_ID_MATCH_CU_MODEL     = 0x02,
+	CCW_DEVICE_ID_MATCH_DEVICE_TYPE  = 0x04,
+	CCW_DEVICE_ID_MATCH_DEVICE_MODEL = 0x08,
+	/* CCW_DEVICE_ID_MATCH_ANY	     = 0x10, */
+};
+
+/* simplified initializers for struct ccw_device:
+ * CCW_DEVICE and CCW_DEVICE_DEVTYPE initialize one
+ * entry in your MODULE_DEVICE_TABLE and set the match_flag correctly */
+#define CCW_DEVICE(cu, cum) 						\
+	.cu_type=(cu), .cu_model=(cum),					\
+	.match_flags=(CCW_DEVICE_ID_MATCH_CU_TYPE			\
+		   | (cum ? CCW_DEVICE_ID_MATCH_CU_MODEL : 0))
+
+#define CCW_DEVICE_DEVTYPE(cu, cum, dev, devm)				\
+	.cu_type=(cu), .cu_model=(cum), .dev_type=(dev), .dev_model=(devm),\
+	.match_flags=CCW_DEVICE_ID_MATCH_CU_TYPE			\
+		   | ((cum) ? CCW_DEVICE_ID_MATCH_CU_MODEL : 0) 	\
+		   | CCW_DEVICE_ID_MATCH_DEVICE_TYPE			\
+		   | ((devm) ? CCW_DEVICE_ID_MATCH_DEVICE_MODEL : 0)
+
+/* scan through an array of device ids and return the first
+ * entry that matches the device.
+ *
+ * the array must end with an entry containing zero match_flags
+ */
+static inline const struct ccw_device_id *
+ccw_device_id_match(const struct ccw_device_id *array,
+			const struct ccw_device_id *match)
+{
+	const struct ccw_device_id *id = array;
+
+	for (id = array; id->match_flags; id++) {
+		if ((id->match_flags & CCW_DEVICE_ID_MATCH_CU_TYPE)
+		    && (id->cu_type != match->cu_type))
+			continue;
+
+		if ((id->match_flags & CCW_DEVICE_ID_MATCH_CU_MODEL)
+		    && (id->cu_model != match->cu_model))
+			continue;
+
+		if ((id->match_flags & CCW_DEVICE_ID_MATCH_DEVICE_TYPE)
+		    && (id->dev_type != match->dev_type))
+			continue;
+
+		if ((id->match_flags & CCW_DEVICE_ID_MATCH_DEVICE_MODEL)
+		    && (id->dev_model != match->dev_model))
+			continue;
+
+		return id;
+	}
+
+	return 0;
+}
+
+/* The struct ccw device is our replacement for the globally accessible
+ * ioinfo array. ioinfo will mutate into a subchannel device later.
+ *
+ * Reference: Documentation/driver-model.txt */
+struct ccw_device {
+	spinlock_t *ccwlock;
+	struct ccw_device_private *private;	/* cio private information */
+	struct ccw_device_id id;	/* id of this device, driver_info is
+					   set by ccw_find_driver */
+	struct ccw_driver *drv;		/* */
+	struct device dev;		/* */
+	int online;
+	/* This is sick, but a driver can have different interrupt handlers 
+	   for different ccw_devices (multi-subchannel drivers)... */
+	void (*handler) (struct ccw_device *, unsigned long, struct irb *);
+};
+
+
+/* Each ccw driver registers with the ccw root bus */
+struct ccw_driver {
+	struct module *owner;		/* for automatic MOD_INC_USE_COUNT   */
+	struct ccw_device_id *ids;	/* probe driver with these devs      */
+	int (*probe) (struct ccw_device *); /* ask driver to probe dev 	     */
+	int (*remove) (struct ccw_device *);
+					/* device is no longer available     */
+	int (*set_online) (struct ccw_device *);
+	int (*set_offline) (struct ccw_device *);
+	struct device_driver driver;	/* higher level structure, dont init
+					   this from your driver	     */
+	char *name;
+};
+
+extern struct ccw_device *get_ccwdev_by_busid(struct ccw_driver *cdrv,
+					      const char *bus_id);
+
+/* devices drivers call these during module load and unload.
+ * When a driver is registered, its probe method is called
+ * when new devices for its type pop up */
+extern int  ccw_driver_register   (struct ccw_driver *driver);
+extern void ccw_driver_unregister (struct ccw_driver *driver);
+
+struct ccw1;
+
+extern int ccw_device_set_options(struct ccw_device *, unsigned long);
+
+/* Allow for i/o completion notification after primary interrupt status. */
+#define CCWDEV_EARLY_NOTIFICATION	0x0001
+/* Report all interrupt conditions. */
+#define CCWDEV_REPORT_ALL	 	0x0002
+
+/*
+ * ccw_device_start()
+ *
+ *  Start a S/390 channel program. When the interrupt arrives, the
+ *  IRQ handler is called, either immediately, delayed (dev-end missing,
+ *  or sense required) or never (no IRQ handler registered).
+ *  Depending on the action taken, ccw_device_start() returns:  
+ *                           0	     - Success
+ *			     -EBUSY  - Device busy, or status pending
+ *			     -ENODEV - Device not operational
+ *                           -EINVAL - Device invalid for operation
+ */
+extern int ccw_device_start(struct ccw_device *, struct ccw1 *,
+			    unsigned long, __u8, unsigned long);
+extern int ccw_device_resume(struct ccw_device *);
+extern int ccw_device_halt(struct ccw_device *, unsigned long);
+extern int ccw_device_clear(struct ccw_device *, unsigned long);
+
+extern int read_dev_chars(struct ccw_device *cdev, void **buffer, int length);
+extern int read_conf_data(struct ccw_device *cdev, void **buffer, int *length);
+
+extern void ccw_device_set_online(struct ccw_device *cdev);
+extern void ccw_device_set_offline(struct ccw_device *cdev);
+
+
+extern struct ciw *ccw_device_get_ciw(struct ccw_device *, __u32 cmd);
+extern __u8 ccw_device_get_path_mask(struct ccw_device *);
+
+#define get_ccwdev_lock(x) (x)->ccwlock
+
+#define to_ccwdev(n) container_of(n, struct ccw_device, dev)
+#define to_ccwdrv(n) container_of(n, struct ccw_driver, driver)
+
+extern struct ccw_device *ccw_device_probe_console(void);
+
+// FIXME: these have to go
+extern int _ccw_device_get_device_number(struct ccw_device *);
+extern int _ccw_device_get_subchannel_number(struct ccw_device *);
+
+#endif /* _S390_CCWDEV_H_ */
diff -Nru a/include/asm-s390/ccwgroup.h b/include/asm-s390/ccwgroup.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-s390/ccwgroup.h	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,44 @@
+#ifndef S390_CCWGROUP_H
+#define S390_CCWGROUP_H
+
+struct ccw_device;
+struct ccw_driver;
+
+struct ccwgroup_device {
+	unsigned long creator_id;	/* unique number of the driver */
+	enum {
+		CCWGROUP_OFFLINE,
+		CCWGROUP_ONLINE,
+	} state;
+	unsigned int count;		/* number of attached slave devices */
+	struct device	dev;		/* master device		    */
+	struct ccw_device *cdev[0];	/* variable number, allocate as needed */
+};
+
+struct ccwgroup_driver {
+	char *name;
+	int max_slaves;
+	unsigned long driver_id;
+
+	int (*probe) (struct ccwgroup_device *);
+	int (*remove) (struct ccwgroup_device *);
+	int (*release) (struct ccwgroup_driver *);
+	int (*set_online) (struct ccwgroup_device *);
+	int (*set_offline) (struct ccwgroup_device *);
+
+	struct device_driver driver;		/* this driver */
+};
+
+extern int  ccwgroup_driver_register   (struct ccwgroup_driver *cdriver);
+extern void ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver);
+extern int ccwgroup_create (struct device *root,
+			    unsigned int creator_id,
+			    struct ccw_driver *gdrv,
+			    int argc, char *argv[]);
+
+extern int ccwgroup_probe_ccwdev(struct ccw_device *cdev);
+extern int ccwgroup_remove_ccwdev(struct ccw_device *cdev);
+
+#define to_ccwgroupdev(x) container_of((x), struct ccwgroup_device, dev)
+#define to_ccwgroupdrv(x) container_of((x), struct ccwgroup_driver, driver)
+#endif
diff -Nru a/include/asm-s390/chandev.h b/include/asm-s390/chandev.h
--- a/include/asm-s390/chandev.h	Mon Dec  9 18:46:36 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,237 +0,0 @@
-/*
- *  include/asm-s390/chandev.h
- *
- *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
- * 
- *  Generic channel device initialisation support. 
- */
-#ifndef __S390_CHANDEV_H
-#define __S390_CHANDEV_H
-#include <linux/version.h>
-#include <asm/types.h>
-#include <linux/netdevice.h>
-
-
-/* Setting this flag to true causes a device name to be built based on the read_devno of the device */
-/* this is exported so external code can look at this flags setting */
-extern int chandev_use_devno_names;
-
-
-/* chandev_type is a bitmask for registering & describing device types. */
-typedef enum
-{
-	chandev_type_none=0x0,
-	chandev_type_ctc=0x1,
-	chandev_type_escon=0x2,
-	chandev_type_lcs=0x4,
-	chandev_type_osad=0x8,
-	chandev_type_qeth=0x10,
-	chandev_type_claw=0x20,
-} chandev_type;
-
-typedef enum
-{
-	chandev_category_none,
-	chandev_category_network_device,
-	chandev_category_serial_device,
-} chandev_category;
-
-
-
-typedef struct
-{
-	int     irq;
-	u16     devno;
-	u16     cu_type;      /* control unit type */
-	u8      cu_model;     /* control unit model */
-	u16     dev_type;     /* device type */
-	u8      dev_model;    /* device model */
-	u8      pim;          /* path installed mask */
-	u8      chpid[8];     /* CHPID 0-7 (if available) */
-} chandev_subchannel_info;
-
-#define CLAW_NAMELEN 9
-/* CLAW specific parameters other drivers should ignore these fields */
-typedef struct
-{
-	
-	char	 host_name[CLAW_NAMELEN];    /* local host name */
-	char	 adapter_name[CLAW_NAMELEN]; /* workstation adapter name */
-	char	 api_type[CLAW_NAMELEN];     /* API type either TCPIP or API */
-} chandev_claw_info;
-
-/*
- * The chandev_probeinfo structure is passed to the device driver with configuration
- * info for which irq's & ports to use when attempting to probe the device.
- */
-typedef struct
-{
-	chandev_subchannel_info read;
-	chandev_subchannel_info write;
-	chandev_subchannel_info data;
-	/* memory_usage_in_k is the suggested memory the driver should attempt to use for io */
-	/* buffers -1 means use the driver default the driver should set this field to the */
-	/* amount of memory it actually uses when returning this probeinfo to the channel */
-	/* device layer with chandev_initdevice */
-	s32     memory_usage_in_k;
-	chandev_claw_info       claw;
-	u8      data_exists; /* whether this device has a data channel */
-	u8      cu_dev_info_inconsistent; /* either ctc or we possibly had a bad sense_id */
-	u8      chpid_info_inconsistent;  /* either ctc or schib info bad */
-        s16     port_protocol_no; /* 0 by default, set specifically when forcing */
-	u8      hint_port_no;   /* lcs specific */
-	u8      max_port_no;    /* lcs/qeth specific */
-	chandev_type chan_type;
-	u8      checksum_received_ip_pkts;
-	u8      use_hw_stats; /* where available e.g. lcs */
-	u8      device_forced; /* indicates the device hasn't been autodetected */
-	char    *parmstr;       /* driver specific parameters added by add_parms keyword */
-	/* newdevice used internally by chandev.c */
-	struct  chandev_activelist *newdevice; 
-	s32     devif_num; 
-/* devif_num=-1 implies don't care,0 implies tr0, info used by chandev_initnetdevice */
-} chandev_probeinfo;
-
-/*
- * This is a wrapper to the machine check handler & should be used
- * instead of reqest_irq or s390_request_irq_special for anything
- * using the channel device layer.
- */
-int chandev_request_irq(unsigned int   irq,
-                      void           (*handler)(int, void *, struct pt_regs *),
-                      unsigned long  irqflags,
-                      const char    *devname,
-                      void          *dev_id);
-/*
- * I originally believed this function wouldn't be necessary
- * I subsequently found that reprobing failed in certain cases :-(,
- * It is just a wrapper for free irq.
- */
-void chandev_free_irq(unsigned int irq, void *dev_id);
-
-typedef enum
-{
-	chandev_status_good,
-	chandev_status_not_oper,
-	chandev_status_first_msck=chandev_status_not_oper,
-	chandev_status_no_path,
-	chandev_status_revalidate,
-	chandev_status_gone,
-	chandev_status_last_msck,
-	chandev_status_all_chans_good /* pseudo machine check to indicate all channels are healthy */
-} chandev_msck_status;
-
-typedef int (*chandev_probefunc)(chandev_probeinfo *probeinfo);
-typedef int (*chandev_shutdownfunc)(void *device);
-typedef void (*chandev_unregfunc)(void *device);
-typedef void (*chandev_msck_notification_func)(void *device,int msck_irq,
-chandev_msck_status prevstatus,chandev_msck_status newstatus);
-
-
-
-/* A driver should call chandev_register_and_probe when ready to be probed,
- * after registeration the drivers probefunction will be called asynchronously
- * when more devices become available at normal task time.
- * The shutdownfunc parameter is used so that the channel layer
- * can request a driver to close unregister itself & release its interrupts.
- * repoper func is used when a device becomes operational again after being temporarily
- * not operational the previous status is sent in the prevstatus variable.
- * This can be used in cases when the default handling isn't quite adequete
- * e.g. if a ssch is needed to reinitialize long running channel programs.
- *
- * This returns the number of devices found or -ENOMEM if the code didn't
- * have enough memory to allocate the chandev control block
- * or -EPERM if a duplicate entry is found.
- */
-int chandev_register_and_probe(chandev_probefunc probefunc,
-			       chandev_shutdownfunc shutdownfunc,
-			       chandev_msck_notification_func msck_notfunc,
-			       chandev_type chan_type);
-
-/* The chandev_unregister function is typically called when a module is being removed 
- * from the system. The shutdown parameter if TRUE calls shutdownfunc for each 
- * device instance so the driver writer doesn't have to.
- */
-void chandev_unregister(chandev_probefunc probefunc,int call_shutdown);
-
-/* chandev_initdevice should be called immeadiately before returning after */
-/* a successful probe. */
-int chandev_initdevice(chandev_probeinfo *probeinfo,void *dev_ptr,u8 port_no,char *devname,
-chandev_category category,chandev_unregfunc unreg_dev);
-
-/* This function builds a device name & copies it into destnamebuff suitable for calling 
-   init_trdev or whatever & it honours the use_devno_names flag, it is used by chandev_initnetdevice 
-   setting the buildfullname flag to TRUE will cause it to always build a full unique name based 
-   on basename either honouring the chandev_use_devno_names flag if set or starting at index 
-   0 & checking the namespace of the channel device layer itself for a free index, this
-   may be useful when one doesn't have control of the name an upper layer may choose.
-   It returns NULL on error.
-*/
-char *chandev_build_device_name(chandev_probeinfo *probeinfo,char *destnamebuff,char *basename,int buildfullname);
-
-
-
-
-/* chandev_init_netdev registers with the normal network device layer */
-/* it doesn't update any of the chandev internal structures. */
-/* i.e. it is optional */
-/* it was part of chandev_initnetdevice but I separated it as */
-/* chandev_initnetdevice may make too many assumptions for some users */
-/* chandev_initnetdevice = chandev_initdevice followed by chandev_init_netdev */
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-struct net_device *chandev_init_netdev(chandev_probeinfo *probeinfo,char *basename,
-struct net_device *dev, int sizeof_priv,struct net_device *(*init_netdevfunc)(struct net_device *dev, int sizeof_priv));
-#else
-struct device *chandev_init_netdev(chandev_probeinfo *probeinfo,char *basename,
-struct device *dev, int sizeof_priv,struct device *(*init_netdevfunc)(struct device *dev, int sizeof_priv));
-#endif
-
-/* chandev_initnetdevice registers a network device with the channel layer. 
- * It returns the device structure if successful,if dev=NULL it kmallocs it, 
- * On device initialisation failure it will kfree it under ALL curcumstances
- * i.e. if dev is not NULL on entering this routine it MUST be malloced with kmalloc. 
- * The base name is tr ( e.g. tr0 without the 0 ), for token ring eth for ethernet,
- *  ctc or escon for ctc device drivers.
- * If valid function pointers are given they will be called to setup,
- * register & unregister the device. 
- * An example of setup is eth_setup in drivers/net/net_init.c.
- * An example of init_dev is init_trdev(struct net_device *dev)
- * & an example of unregister is unregister_trdev, 
- * unregister_netdev should be used for escon & ctc
- * as there is no network unregister_ctcdev in the kernel.
-*/
-
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-struct net_device *chandev_initnetdevice(chandev_probeinfo *probeinfo,u8 port_no,
-					 struct net_device *dev,int sizeof_priv, 
-					 char *basename, 
-					 struct net_device *(*init_netdevfunc)
-					 (struct net_device *dev, int sizeof_priv),
-					 void (*unreg_netdevfunc)(struct net_device *dev));
-#else
-struct device *chandev_initnetdevice(chandev_probeinfo *probeinfo,u8 port_no,
-				     struct device *dev,int sizeof_priv,
-				     char *basename, 
-				     struct device *(*init_netdevfunc)
-				     (struct device *dev, int sizeof_priv),
-				     void (*unreg_netdevfunc)(struct device *dev));
-#endif
-
-/* chandev_add & delete model shouldn't normally be needed by drivers except if */
-/* someone is developing a driver which the channel device layer doesn't know about */
-void chandev_add_model(chandev_type chan_type,s32 cu_type,s16 cu_model,
-		       s32 dev_type,s16 dev_model,u8 max_port_no,int auto_msck_recovery,
-		        u8 default_checksum_received_ip_pkts,u8 default_use_hw_stats);
-void chandev_del_model(s32 cu_type,s16 cu_model,s32 dev_type,s16 dev_model);
-
-/* modules should use chandev_persist to see if they should stay loaded */
-/* this is useful for debugging purposes where you may wish to examine */
-/* /proc/s390dbf/ entries */
-int chandev_persist(chandev_type chan_type);
-#endif /* __S390_CHANDEV_H */
-
-
-
-
-
diff -Nru a/include/asm-s390/cio.h b/include/asm-s390/cio.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-s390/cio.h	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,271 @@
+/*
+ *  include/asm-s390/cio.h
+ *  include/asm-s390x/cio.h
+ *
+ * Common interface for I/O on S/390
+ */
+#ifndef _ASM_S390_CIO_H_
+#define _ASM_S390_CIO_H_
+
+#include <linux/spinlock.h>
+#include <asm/types.h>
+
+#ifdef __KERNEL__
+
+#define LPM_ANYPATH 0xff
+
+/*
+ * subchannel status word
+ */
+struct scsw {
+	__u32 key  : 4;		/* subchannel key */
+	__u32 sctl : 1; 	/* suspend control */
+	__u32 eswf : 1; 	/* ESW format */
+	__u32 cc   : 2; 	/* deferred condition code */
+	__u32 fmt  : 1; 	/* format */
+	__u32 pfch : 1; 	/* prefetch */
+	__u32 isic : 1; 	/* initial-status interruption control */
+	__u32 alcc : 1; 	/* address-limit checking control */
+	__u32 ssi  : 1; 	/* supress-suspended interruption */
+	__u32 zcc  : 1; 	/* zero condition code */
+	__u32 ectl : 1; 	/* extended control */
+	__u32 pno  : 1;	    	/* path not operational */
+	__u32 res  : 1;	    	/* reserved */
+	__u32 fctl : 3;	    	/* function control */
+	__u32 actl : 7;	    	/* activity control */
+	__u32 stctl : 5;    	/* status control */
+	__u32 cpa;	    	/* channel program address */
+	__u32 dstat : 8;    	/* device status */
+	__u32 cstat : 8;    	/* subchannel status */
+	__u32 count : 16;   	/* residual count */
+} __attribute__ ((packed));
+
+#define SCSW_FCTL_CLEAR_FUNC	 0x1
+#define SCSW_FCTL_HALT_FUNC	 0x2
+#define SCSW_FCTL_START_FUNC	 0x4
+
+#define SCSW_ACTL_SUSPENDED	 0x1
+#define SCSW_ACTL_DEVACT	 0x2
+#define SCSW_ACTL_SCHACT	 0x4
+#define SCSW_ACTL_CLEAR_PEND	 0x8
+#define SCSW_ACTL_HALT_PEND	 0x10
+#define SCSW_ACTL_START_PEND	 0x20
+#define SCSW_ACTL_RESUME_PEND	 0x40
+
+#define SCSW_STCTL_STATUS_PEND	 0x1
+#define SCSW_STCTL_SEC_STATUS	 0x2
+#define SCSW_STCTL_PRIM_STATUS	 0x4
+#define SCSW_STCTL_INTER_STATUS	 0x8
+#define SCSW_STCTL_ALERT_STATUS	 0x10
+
+#define DEV_STAT_ATTENTION	 0x80
+#define DEV_STAT_STAT_MOD	 0x40
+#define DEV_STAT_CU_END		 0x20
+#define DEV_STAT_BUSY		 0x10
+#define DEV_STAT_CHN_END	 0x08
+#define DEV_STAT_DEV_END	 0x04
+#define DEV_STAT_UNIT_CHECK	 0x02
+#define DEV_STAT_UNIT_EXCEP	 0x01
+
+#define SCHN_STAT_PCI		 0x80
+#define SCHN_STAT_INCORR_LEN	 0x40
+#define SCHN_STAT_PROG_CHECK	 0x20
+#define SCHN_STAT_PROT_CHECK	 0x10
+#define SCHN_STAT_CHN_DATA_CHK	 0x08
+#define SCHN_STAT_CHN_CTRL_CHK	 0x04
+#define SCHN_STAT_INTF_CTRL_CHK	 0x02
+#define SCHN_STAT_CHAIN_CHECK	 0x01
+
+/*
+ * architectured values for first sense byte
+ */
+#define SNS0_CMD_REJECT		0x80
+#define SNS_CMD_REJECT		SNS0_CMD_REJEC
+#define SNS0_INTERVENTION_REQ	0x40
+#define SNS0_BUS_OUT_CHECK	0x20
+#define SNS0_EQUIPMENT_CHECK	0x10
+#define SNS0_DATA_CHECK		0x08
+#define SNS0_OVERRUN		0x04
+#define SNS0_INCOMPL_DOMAIN	0x01
+
+/*
+ * architectured values for second sense byte
+ */
+#define SNS1_PERM_ERR		0x80
+#define SNS1_INV_TRACK_FORMAT	0x40
+#define SNS1_EOC		0x20
+#define SNS1_MESSAGE_TO_OPER	0x10
+#define SNS1_NO_REC_FOUND	0x08
+#define SNS1_FILE_PROTECTED	0x04
+#define SNS1_WRITE_INHIBITED	0x02
+#define SNS1_INPRECISE_END	0x01
+
+/*
+ * architectured values for third sense byte
+ */
+#define SNS2_REQ_INH_WRITE	0x80
+#define SNS2_CORRECTABLE	0x40
+#define SNS2_FIRST_LOG_ERR	0x20
+#define SNS2_ENV_DATA_PRESENT	0x10
+#define SNS2_INPRECISE_END	0x04
+
+struct ccw1 {
+	__u8  cmd_code;		/* command code */
+	__u8  flags;   		/* flags, like IDA adressing, etc. */
+	__u16 count;   		/* byte count */
+	__u32 cda;     		/* data address */
+} __attribute__ ((packed,aligned(8)));
+
+#define CCW_FLAG_DC		0x80
+#define CCW_FLAG_CC		0x40
+#define CCW_FLAG_SLI		0x20
+#define CCW_FLAG_SKIP		0x10
+#define CCW_FLAG_PCI		0x08
+#define CCW_FLAG_IDA		0x04
+#define CCW_FLAG_SUSPEND	0x02
+
+#define CCW_CMD_READ_IPL	0x02
+#define CCW_CMD_NOOP		0x03
+#define CCW_CMD_BASIC_SENSE	0x04
+#define CCW_CMD_TIC		0x08
+#define CCW_CMD_SENSE_PGID	0x34
+#define CCW_CMD_SUSPEND_RECONN	0x5B
+#define CCW_CMD_RDC		0x64
+#define CCW_CMD_SET_PGID	0xAF
+#define CCW_CMD_SENSE_ID	0xE4
+#define CCW_CMD_DCTL		0xF3
+
+#define SENSE_MAX_COUNT		0x20
+
+struct erw {
+	__u32 res0  : 3;  	/* reserved */
+	__u32 auth  : 1;	/* Authorization check */
+	__u32 pvrf  : 1;  	/* path-verification-required flag */
+	__u32 cpt   : 1;  	/* channel-path timeout */
+	__u32 fsavf : 1;  	/* Failing storage address validity flag */
+	__u32 cons  : 1;  	/* concurrent-sense */
+	__u32 scavf : 1;	/* Secondary ccw address validity flag */
+	__u32 fsaf  : 1;	/* Failing storage address format */
+	__u32 scnt  : 6;  	/* sense count if cons == 1 */
+	__u32 res16 : 16; 	/* reserved */
+} __attribute__ ((packed));
+
+/*
+ * subchannel logout area
+ */
+struct sublog {
+	__u32 res0  : 1;  	/* reserved */
+	__u32 esf   : 7;  	/* extended status flags */
+	__u32 lpum  : 8;  	/* last path used mask */
+	__u32 arep  : 1;  	/* ancillary report */
+	__u32 fvf   : 5;  	/* field-validity flags */
+	__u32 sacc  : 2;  	/* storage access code */
+	__u32 termc : 2;  	/* termination code */
+	__u32 devsc : 1;  	/* device-status check */
+	__u32 serr  : 1;  	/* secondary error */
+	__u32 ioerr : 1;  	/* i/o-error alert */
+	__u32 seqc  : 3;  	/* sequence code */
+} __attribute__ ((packed));
+
+/*
+ * Format 0 Extended Status Word (ESW)
+ */
+struct esw0 {
+	struct sublog sublog;	/* subchannel logout */
+	struct erw erw;	    	/* extended report word */
+	__u32  faddr[2];    	/* failing storage address */
+	__u32  saddr;  		/* secondary ccw address */
+} __attribute__ ((packed));
+
+/*
+ * Format 1 Extended Status Word (ESW)
+ */
+struct esw1 {
+	__u8  zero0;		/* reserved zeros */
+	__u8  lpum;		/* last path used mask */
+	__u16 zero16;		/* reserved zeros */
+	struct erw erw;		/* extended report word */
+	__u32 zeros[3]; 	/* 2 fullwords of zeros */
+} __attribute__ ((packed));
+
+/*
+ * Format 2 Extended Status Word (ESW)
+ */
+struct esw2 {
+	__u8  zero0;		/* reserved zeros */
+	__u8  lpum;		/* last path used mask */
+	__u16 dcti;		/* device-connect-time interval */
+	struct erw erw;		/* extended report word */
+	__u32 zeros[3]; 	/* 2 fullwords of zeros */
+} __attribute__ ((packed));
+
+/*
+ * Format 3 Extended Status Word (ESW)
+ */
+struct esw3 {
+	__u8  zero0;		/* reserved zeros */
+	__u8  lpum;		/* last path used mask */
+	__u16 res;		/* reserved */
+	struct erw erw;		/* extended report word */
+	__u32 zeros[3]; 	/* 2 fullwords of zeros */
+} __attribute__ ((packed));
+
+/*
+ * interruption response block
+ */
+struct irb {
+	struct scsw scsw;	/* subchannel status word */
+	union {			/* extended status word, 4 formats */
+		struct esw0 esw0;
+		struct esw1 esw1;
+		struct esw2 esw2;
+		struct esw3 esw3;
+	} esw;
+	__u8   ecw[32];		/* extended control word */
+} __attribute__ ((packed,aligned(4)));
+
+/*
+ * command information word  (CIW) layout
+ */
+struct ciw {
+	__u32 et       :  2; 	/* entry type */
+	__u32 reserved :  2; 	/* reserved */
+	__u32 ct       :  4; 	/* command type */
+	__u32 cmd      :  8; 	/* command */
+	__u32 count    : 16; 	/* coun */
+} __attribute__ ((packed));
+
+#define CIW_TYPE_RCD	0x0    	/* read configuration data */
+#define CIW_TYPE_SII	0x1    	/* set interface identifier */
+#define CIW_TYPE_RNI	0x2    	/* read node identifier */
+
+/*
+ * Flags used as input parameters for do_IO()
+ */
+#define DOIO_ALLOW_SUSPEND	 0x0001 /* allow for channel prog. suspend */
+#define DOIO_DENY_PREFETCH	 0x0002 /* don't allow for CCW prefetch */
+#define DOIO_SUPPRESS_INTER	 0x0004 /* suppress intermediate inter. */
+					/* ... for suspended CCWs */
+
+struct diag210 {
+	__u16 vrdcdvno : 16;   /* device number (input) */
+	__u16 vrdclen  : 16;   /* data block length (input) */
+	__u32 vrdcvcla : 8;    /* virtual device class (output) */
+	__u32 vrdcvtyp : 8;    /* virtual device type (output) */
+	__u32 vrdcvsta : 8;    /* virtual device status (output) */
+	__u32 vrdcvfla : 8;    /* virtual device flags (output) */
+	__u32 vrdcrccl : 8;    /* real device class (output) */
+	__u32 vrdccrty : 8;    /* real device type (output) */
+	__u32 vrdccrmd : 8;    /* real device model (output) */
+	__u32 vrdccrft : 8;    /* real device feature (output) */
+} __attribute__ ((packed,aligned(4)));
+
+extern int diag210(struct diag210 *addr);
+
+extern int chsc(void *data);
+
+extern void wait_cons_dev(void);
+
+#endif
+
+#endif
diff -Nru a/include/asm-s390/dasd.h b/include/asm-s390/dasd.h
--- a/include/asm-s390/dasd.h	Mon Dec  9 18:46:35 2002
+++ b/include/asm-s390/dasd.h	Mon Dec  9 18:46:35 2002
@@ -8,6 +8,8 @@
  * any future changes wrt the API will result in a change of the APIVERSION reported
  * to userspace by the DASDAPIVER-ioctl
  *
+ * $Revision: 1.3 $
+ *
  * History of changes (starts July 2000)
  * 05/04/01 created by moving the kernel interface to drivers/s390/block/dasd_int.h
  * 12/06/01 DASD_API_VERSION 2 - binary compatible to 0 (new BIODASDINFO2)
@@ -224,8 +226,6 @@
 #define BIODASDSLCK    _IO(DASD_IOCTL_LETTER,4) /* steal lock */
 /* reset profiling information of a device */
 #define BIODASDPRRST   _IO(DASD_IOCTL_LETTER,5)
-/* enable PAV */
-#define BIODASDENAPAV  _IO(DASD_IOCTL_LETTER,6)
 
 
 /* retrieve API version number */
diff -Nru a/include/asm-s390/idals.h b/include/asm-s390/idals.h
--- a/include/asm-s390/idals.h	Mon Dec  9 18:46:34 2002
+++ b/include/asm-s390/idals.h	Mon Dec  9 18:46:34 2002
@@ -15,9 +15,17 @@
 
 #include <linux/config.h>
 #include <linux/errno.h>
-#include <asm/irq.h>
+#include <linux/err.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/cio.h>
+#include <asm/uaccess.h>
 
+#ifdef CONFIG_ARCH_S390X
+#define IDA_SIZE_LOG 12 /* 11 for 2k , 12 for 4k */
+#else
 #define IDA_SIZE_LOG 11 /* 11 for 2k , 12 for 4k */
+#endif
 #define IDA_BLOCK_SIZE (1L<<IDA_SIZE_LOG)
 
 /*
@@ -76,7 +84,7 @@
  * If necessary it allocates an IDAL and sets the appropriate flags.
  */
 static inline int
-set_normalized_cda(ccw1_t * ccw, void *vaddr)
+set_normalized_cda(struct ccw1 * ccw, void *vaddr)
 {
 #if defined (CONFIG_ARCH_S390X)
 	unsigned int nridaws;
@@ -103,7 +111,7 @@
  * Releases any allocated IDAL related to the CCW.
  */
 static inline void
-clear_normalized_cda(ccw1_t * ccw)
+clear_normalized_cda(struct ccw1 * ccw)
 {
 #if defined(CONFIG_ARCH_S390X)
 	if (ccw->flags & CCW_FLAG_IDA) {
@@ -112,6 +120,140 @@
 	}
 #endif
 	ccw->cda = 0;
+}
+
+/*
+ * Idal buffer extension
+ */
+struct idal_buffer {
+	size_t size;
+	size_t page_order;
+	void *data[0];
+};
+
+/*
+ * Allocate an idal buffer
+ */
+static inline struct idal_buffer *
+idal_buffer_alloc(size_t size, int page_order)
+{
+	struct idal_buffer *ib;
+	int nr_chunks, nr_ptrs, i;
+
+	nr_ptrs = (size + IDA_BLOCK_SIZE - 1) >> IDA_SIZE_LOG;
+	nr_chunks = (4096 << page_order) >> IDA_SIZE_LOG;
+	ib = kmalloc(sizeof(struct idal_buffer) + nr_ptrs*sizeof(void *),
+		     GFP_DMA | GFP_KERNEL);
+	if (ib == NULL)
+		return ERR_PTR(-ENOMEM);
+	ib->size = size;
+	ib->page_order = page_order;
+	for (i = 0; i < nr_ptrs; i++) {
+		if ((i & (nr_chunks - 1)) != 0) {
+			ib->data[i] = ib->data[i-1] + IDA_BLOCK_SIZE;
+			continue;
+		}
+		ib->data[i] = (void *)
+			__get_free_pages(GFP_KERNEL, page_order);
+		if (ib->data[i] != NULL)
+			continue;
+		// Not enough memory
+		while (i >= nr_chunks) {
+			i -= nr_chunks;
+			free_pages((unsigned long) ib->data[i],
+				   ib->page_order);
+		}
+		kfree(ib);
+		return ERR_PTR(-ENOMEM);
+	}
+	return ib;
+}
+
+/*
+ * Free an idal buffer.
+ */
+static inline void
+idal_buffer_free(struct idal_buffer *ib)
+{
+	int nr_chunks, nr_ptrs, i;
+
+	nr_ptrs = (ib->size + IDA_BLOCK_SIZE - 1) >> IDA_SIZE_LOG;
+	nr_chunks = (4096 << ib->page_order) >> IDA_SIZE_LOG;
+	for (i = 0; i < nr_ptrs; i += nr_chunks)
+		free_pages((unsigned long) ib->data[i], ib->page_order);
+	kfree(ib);
+}
+
+/*
+ * Test if a idal list is really needed.
+ */
+static inline int
+__idal_buffer_is_needed(struct idal_buffer *ib)
+{
+#ifdef CONFIG_ARCH_S390X
+	return ib->size > (4096 << ib->page_order) ||
+		idal_is_needed(ib->data[0], ib->size);
+#else
+	return ib->size > (4096 << ib->page_order);
+#endif
+}
+
+/*
+ * Set channel data address to idal buffer.
+ */
+static inline void
+idal_buffer_set_cda(struct idal_buffer *ib, struct ccw1 *ccw)
+{
+	if (__idal_buffer_is_needed(ib)) {
+		// setup idals;
+		ccw->cda = (u32)(addr_t) ib->data;
+		ccw->flags |= CCW_FLAG_IDA;
+	} else
+		// we do not need idals - use direct addressing
+		ccw->cda = (u32)(addr_t) ib->data[0];
+	ccw->count = ib->size;
+}
+
+/*
+ * Copy count bytes from an idal buffer to user memory
+ */
+static inline size_t
+idal_buffer_to_user(struct idal_buffer *ib, void *to, size_t count)
+{
+	size_t left;
+	int i;
+
+	if (count > ib->size)
+		BUG();
+	for (i = 0; count > IDA_BLOCK_SIZE; i++) {
+		left = copy_to_user(to, ib->data[i], IDA_BLOCK_SIZE);
+		if (left)
+			return left + count - IDA_BLOCK_SIZE;
+		(addr_t) to += IDA_BLOCK_SIZE;
+		count -= IDA_BLOCK_SIZE;
+	}
+	return copy_to_user(to, ib->data[i], count);
+}
+
+/*
+ * Copy count bytes from user memory to an idal buffer
+ */
+static inline size_t
+idal_buffer_from_user(struct idal_buffer *ib, const void *from, size_t count)
+{
+	size_t left;
+	int i;
+
+	if (count > ib->size)
+		BUG();
+	for (i = 0; count > IDA_BLOCK_SIZE; i++) {
+		left = copy_from_user(ib->data[i], from, IDA_BLOCK_SIZE);
+		if (left)
+			return left + count - IDA_BLOCK_SIZE;
+		(addr_t) from += IDA_BLOCK_SIZE;
+		count -= IDA_BLOCK_SIZE;
+	}
+	return copy_from_user(ib->data[i], from, count);
 }
 
 #endif
diff -Nru a/include/asm-s390/irq.h b/include/asm-s390/irq.h
--- a/include/asm-s390/irq.h	Mon Dec  9 18:46:51 2002
+++ b/include/asm-s390/irq.h	Mon Dec  9 18:46:51 2002
@@ -1,903 +1,26 @@
 #ifndef _ASM_IRQ_H
 #define _ASM_IRQ_H
 
-#include <linux/config.h>
 #ifdef __KERNEL__
 #include <asm/hardirq.h>
 
 /*
- * How many IRQ's for S390 ?!?
- */
-#define __MAX_SUBCHANNELS 65536
-#define NR_IRQS           __MAX_SUBCHANNELS
-#define NR_CHPIDS 256
-
-#define LPM_ANYPATH 0xff /* doesn't really belong here, Ingo? */
-
-#define INVALID_STORAGE_AREA ((void *)(-1 - 0x3FFF ))
-
-/*
- * path management control word
- */
-typedef struct {
-      __u32 intparm;      /* interruption parameter */
-      __u32 qf   : 1;     /* qdio facility */
-      __u32 res0 : 1;     /* reserved zeros */
-      __u32 isc  : 3;     /* interruption sublass */
-      __u32 res5 : 3;     /* reserved zeros */
-      __u32 ena  : 1;     /* enabled */
-      __u32 lm   : 2;     /* limit mode */
-      __u32 mme  : 2;     /* measurement-mode enable */
-      __u32 mp   : 1;     /* multipath mode */
-      __u32 tf   : 1;     /* timing facility */
-      __u32 dnv  : 1;     /* device number valid */
-      __u32 dev  : 16;    /* device number */
-      __u8  lpm;          /* logical path mask */
-      __u8  pnom;         /* path not operational mask */
-      __u8  lpum;         /* last path used mask */
-      __u8  pim;          /* path installed mask */
-      __u16 mbi;          /* measurement-block index */
-      __u8  pom;          /* path operational mask */
-      __u8  pam;          /* path available mask */
-      __u8  chpid[8];     /* CHPID 0-7 (if available) */
-      __u32 unused1 : 8;  /* reserved zeros */
-      __u32 st      : 3;  /* subchannel type */
-      __u32 unused2 : 20; /* reserved zeros */
-      __u32 csense  : 1;  /* concurrent sense; can be enabled ...*/
-                          /*  ... per MSCH, however, if facility */
-                          /*  ... is not installed, this results */
-                          /*  ... in an operand exception.       */
-   } __attribute__ ((packed)) pmcw_t;
-
-#endif /* __KERNEL__ */
-/*
- * subchannel status word
- */
-typedef struct {
-      __u32 key  : 4; /* subchannel key */
-      __u32 sctl : 1; /* suspend control */
-      __u32 eswf : 1; /* ESW format */
-      __u32 cc   : 2; /* deferred condition code */
-      __u32 fmt  : 1; /* format */
-      __u32 pfch : 1; /* prefetch */
-      __u32 isic : 1; /* initial-status interruption control */
-      __u32 alcc : 1; /* address-limit checking control */
-      __u32 ssi  : 1; /* supress-suspended interruption */
-      __u32 zcc  : 1; /* zero condition code */
-      __u32 ectl : 1; /* extended control */
-      __u32 pno  : 1;     /* path not operational */
-      __u32 res  : 1;     /* reserved */
-      __u32 fctl : 3;     /* function control */
-      __u32 actl : 7;     /* activity control */
-      __u32 stctl : 5;    /* status control */
-      __u32 cpa;          /* channel program address */
-      __u32 dstat : 8;    /* device status */
-      __u32 cstat : 8;    /* subchannel status */
-      __u32 count : 16;   /* residual count */
-   } __attribute__ ((packed)) scsw_t;
-
-#define SCSW_FCTL_CLEAR_FUNC     0x1
-#define SCSW_FCTL_HALT_FUNC      0x2
-#define SCSW_FCTL_START_FUNC     0x4
-
-#define SCSW_ACTL_SUSPENDED      0x1
-#define SCSW_ACTL_DEVACT         0x2
-#define SCSW_ACTL_SCHACT         0x4
-#define SCSW_ACTL_CLEAR_PEND     0x8
-#define SCSW_ACTL_HALT_PEND      0x10
-#define SCSW_ACTL_START_PEND     0x20
-#define SCSW_ACTL_RESUME_PEND    0x40
-
-#define SCSW_STCTL_STATUS_PEND   0x1
-#define SCSW_STCTL_SEC_STATUS    0x2
-#define SCSW_STCTL_PRIM_STATUS   0x4
-#define SCSW_STCTL_INTER_STATUS  0x8
-#define SCSW_STCTL_ALERT_STATUS  0x10
-
-#define DEV_STAT_ATTENTION       0x80
-#define DEV_STAT_STAT_MOD        0x40
-#define DEV_STAT_CU_END          0x20
-#define DEV_STAT_BUSY            0x10
-#define DEV_STAT_CHN_END         0x08
-#define DEV_STAT_DEV_END         0x04
-#define DEV_STAT_UNIT_CHECK      0x02
-#define DEV_STAT_UNIT_EXCEP      0x01
-
-#define SCHN_STAT_PCI            0x80
-#define SCHN_STAT_INCORR_LEN     0x40
-#define SCHN_STAT_PROG_CHECK     0x20
-#define SCHN_STAT_PROT_CHECK     0x10
-#define SCHN_STAT_CHN_DATA_CHK   0x08
-#define SCHN_STAT_CHN_CTRL_CHK   0x04
-#define SCHN_STAT_INTF_CTRL_CHK  0x02
-#define SCHN_STAT_CHAIN_CHECK    0x01
-
-/*
- * architectured values for first sense byte
- */
-#define SNS0_CMD_REJECT         0x80
-#define SNS_CMD_REJECT          SNS0_CMD_REJECT
-#define SNS0_INTERVENTION_REQ   0x40
-#define SNS0_BUS_OUT_CHECK      0x20
-#define SNS0_EQUIPMENT_CHECK    0x10
-#define SNS0_DATA_CHECK         0x08
-#define SNS0_OVERRUN            0x04
-/*                              0x02 reserved */
-#define SNS0_INCOMPL_DOMAIN     0x01
-
-/*
- * architectured values for second sense byte
- */
-#define SNS1_PERM_ERR           0x80
-#define SNS1_INV_TRACK_FORMAT   0x40
-#define SNS1_EOC                0x20
-#define SNS1_MESSAGE_TO_OPER    0x10
-#define SNS1_NO_REC_FOUND       0x08
-#define SNS1_FILE_PROTECTED     0x04
-#define SNS1_WRITE_INHIBITED    0x02
-#define SNS1_INPRECISE_END      0x01
-
-/*
- * architectured values for third sense byte
- */
-#define SNS2_REQ_INH_WRITE      0x80
-#define SNS2_CORRECTABLE        0x40
-#define SNS2_FIRST_LOG_ERR      0x20
-#define SNS2_ENV_DATA_PRESENT   0x10
-/*                              0x08 reserved */
-#define SNS2_INPRECISE_END      0x04
-/*                              0x02 reserved */
-/*                              0x01 reserved */
-
-#ifdef __KERNEL__
-/*
- * subchannel information block
- */
-typedef struct {
-      pmcw_t pmcw;             /* path management control word */
-      scsw_t scsw;             /* subchannel status word */
-      __u8 mda[12];            /* model dependent area */
-   } __attribute__ ((packed,aligned(4))) schib_t;
-#endif /* __KERNEL__ */
-
-typedef struct {
-      __u8  cmd_code;/* command code */
-      __u8  flags;   /* flags, like IDA adressing, etc. */
-      __u16 count;   /* byte count */
-      __u32 cda;     /* data address */
-   } __attribute__ ((packed,aligned(8))) ccw1_t;
-
-#define CCW_FLAG_DC             0x80
-#define CCW_FLAG_CC             0x40
-#define CCW_FLAG_SLI            0x20
-#define CCW_FLAG_SKIP           0x10
-#define CCW_FLAG_PCI            0x08
-#define CCW_FLAG_IDA            0x04
-#define CCW_FLAG_SUSPEND        0x02
-
-#define CCW_CMD_READ_IPL        0x02
-#define CCW_CMD_NOOP            0x03
-#define CCW_CMD_BASIC_SENSE     0x04
-#define CCW_CMD_TIC             0x08
-#define CCW_CMD_SENSE_PGID      0x34
-#define CCW_CMD_SUSPEND_RECONN  0x5B
-#define CCW_CMD_RDC             0x64
-#define CCW_CMD_SET_PGID        0xAF
-#define CCW_CMD_SENSE_ID        0xE4
-#define CCW_CMD_DCTL            0xF3
-
-#ifdef __KERNEL__
-#define SENSE_MAX_COUNT         0x20
-
-/*
- * architectured values for first sense byte
- */
-#define SNS0_CMD_REJECT         0x80
-#define SNS_CMD_REJECT          SNS0_CMD_REJECT
-#define SNS0_INTERVENTION_REQ   0x40
-#define SNS0_BUS_OUT_CHECK      0x20
-#define SNS0_EQUIPMENT_CHECK    0x10
-#define SNS0_DATA_CHECK         0x08
-#define SNS0_OVERRUN            0x04
-
-/*
- * operation request block
- */
-typedef struct {
-      __u32 intparm;  /* interruption parameter */
-      __u32 key  : 4; /* flags, like key, suspend control, etc. */
-      __u32 spnd : 1; /* suspend control */
-      __u32 res1 : 1; /* reserved */
-      __u32 mod  : 1; /* modification control */
-      __u32 sync : 1; /* synchronize control */
-      __u32 fmt  : 1; /* format control */
-      __u32 pfch : 1; /* prefetch control */
-      __u32 isic : 1; /* initial-status-interruption control */
-      __u32 alcc : 1; /* address-limit-checking control */
-      __u32 ssic : 1; /* suppress-suspended-interr. control */
-      __u32 res2 : 1; /* reserved */
-      __u32 c64  : 1; /* IDAW/QDIO 64 bit control  */
-      __u32 i2k  : 1; /* IDAW 2/4kB block size control */
-      __u32 lpm  : 8; /* logical path mask */
-      __u32 ils  : 1; /* incorrect length */
-      __u32 zero : 6; /* reserved zeros */
-      __u32 orbx : 1; /* ORB extension control */
-      __u32 cpa;      /* channel program address */
-   }  __attribute__ ((packed,aligned(4))) orb_t;
-
-#endif /* __KERNEL__ */
-typedef struct {
-      __u32 res0  : 4;  /* reserved */
-      __u32 pvrf  : 1;  /* path-verification-required flag */
-      __u32 cpt   : 1;  /* channel-path timeout */
-      __u32 fsavf : 1;  /* Failing storage address validity flag */
-      __u32 cons  : 1;  /* concurrent-sense */
-      __u32 res8  : 2;  /* reserved */
-      __u32 scnt  : 6;  /* sense count if cons == 1 */
-      __u32 res16 : 16; /* reserved */
-   } __attribute__ ((packed)) erw_t;
-
-/*
- * subchannel logout area
- */
-typedef struct {
-      __u32 res0  : 1;  /* reserved */
-      __u32 esf   : 7;  /* extended status flags */
-      __u32 lpum  : 8;  /* last path used mask */
-      __u32 res16 : 1;  /* reserved */
-      __u32 fvf   : 5;  /* field-validity flags */
-      __u32 sacc  : 2;  /* storage access code */
-      __u32 termc : 2;  /* termination code */
-      __u32 devsc : 1;  /* device-status check */
-      __u32 serr  : 1;  /* secondary error */
-      __u32 ioerr : 1;  /* i/o-error alert */
-      __u32 seqc  : 3;  /* sequence code */
-   } __attribute__ ((packed)) sublog_t ;
-
-/*
- * Format 0 Extended Status Word (ESW)
- */
-typedef struct {
-      sublog_t sublog;    /* subchannel logout */
-      erw_t    erw;       /* extended report word */
-      __u32    faddr;     /* failing address */
-      __u32    zeros[2];  /* 2 fullwords of zeros */
-   } __attribute__ ((packed)) esw0_t;
-
-/*
- * Format 1 Extended Status Word (ESW)
- */
-typedef struct {
-      __u8  zero0;    /* reserved zeros */
-      __u8  lpum;     /* last path used mask */
-      __u16 zero16;   /* reserved zeros */
-      erw_t erw;      /* extended report word */
-      __u32 zeros[3]; /* 2 fullwords of zeros */
-   } __attribute__ ((packed)) esw1_t;
-
-/*
- * Format 2 Extended Status Word (ESW)
- */
-typedef struct {
-      __u8  zero0;    /* reserved zeros */
-      __u8  lpum;     /* last path used mask */
-      __u16 dcti;     /* device-connect-time interval */
-      erw_t erw;      /* extended report word */
-      __u32 zeros[3]; /* 2 fullwords of zeros */
-   } __attribute__ ((packed)) esw2_t;
-
-/*
- * Format 3 Extended Status Word (ESW)
- */
-typedef struct {
-      __u8  zero0;    /* reserved zeros */
-      __u8  lpum;     /* last path used mask */
-      __u16 res;      /* reserved */
-      erw_t erw;      /* extended report word */
-      __u32 zeros[3]; /* 2 fullwords of zeros */
-   } __attribute__ ((packed)) esw3_t;
-
-typedef union {
-      esw0_t esw0;
-      esw1_t esw1;
-      esw2_t esw2;
-      esw3_t esw3;
-   } __attribute__ ((packed)) esw_t;
-
-/*
- * interruption response block
- */
-typedef struct {
-      scsw_t scsw;             /* subchannel status word */
-      esw_t  esw;              /* extended status word */
-      __u8   ecw[32];          /* extended control word */
-   } __attribute__ ((packed,aligned(4))) irb_t;
-#ifdef __KERNEL__
-
-/*
- * TPI info structure
- */
-typedef struct {
-	__u32 reserved1  : 16;   /* reserved 0x00000001 */
-	__u32 irq        : 16;   /* aka. subchannel number */
-	__u32 intparm;           /* interruption parameter */
-	__u32 adapter_IO : 1;
-	__u32 reserved2  : 1;
-	__u32 isc        : 3;
-	__u32 reserved3  : 12;
-	__u32 int_type   : 3;
-	__u32 reserved4  : 12;
-   } __attribute__ ((packed)) tpi_info_t;
-
-
-//
-// command information word  (CIW) layout
-//
-typedef struct _ciw {
-   __u32        et       :  2; // entry type
-   __u32        reserved :  2; // reserved
-   __u32        ct       :  4; // command type
-   __u32        cmd      :  8; // command
-   __u32        count    : 16; // count
-   } __attribute__ ((packed)) ciw_t;
-
-#define CIW_TYPE_RCD    0x0    // read configuration data
-#define CIW_TYPE_SII    0x1    // set interface identifier
-#define CIW_TYPE_RNI    0x2    // read node identifier
-
-#define MAX_CIWS 8
-//
-// sense-id response buffer layout
-//
-typedef struct {
-  /* common part */
-      __u8           reserved;     /* always 0x'FF' */
-      __u16          cu_type;      /* control unit type */
-      __u8           cu_model;     /* control unit model */
-      __u16          dev_type;     /* device type */
-      __u8           dev_model;    /* device model */
-      __u8           unused;       /* padding byte */
-  /* extended part */
-      ciw_t    ciw[MAX_CIWS];      /* variable # of CIWs */
-   }  __attribute__ ((packed,aligned(4))) senseid_t;
-/*
- * where we put the ssd info
- */
-typedef struct _ssd_info {
-	__u8   valid:1;
-	__u8   type:7;          /* subchannel type */
-	__u8   chpid[8];        /* chpids */
-	__u16  fla[8];          /* full link addresses */
-} __attribute__ ((packed)) ssd_info_t;
-
-/*
- * area for store event information
- */
-typedef struct chsc_area_t {
-	struct {
-		/* word 0 */
-		__u16 command_code1;
-		__u16 command_code2;
-		union {
-			struct {
-				/* word 1 */
-				__u32 reserved1;
-				/* word 2 */
-				__u32 reserved2;
-			} __attribute__ ((packed,aligned(8))) sei_req;
-			struct {
-				/* word 1 */
-				__u16 reserved1;
-				__u16 f_sch;     /* first subchannel */
-				/* word 2 */
-				__u16 reserved2;
-				__u16 l_sch;    /* last subchannel */
-			} __attribute__ ((packed,aligned(8))) ssd_req;
-		} request_block_data;
-		/* word 3 */
-		__u32 reserved3;
-	} __attribute__ ((packed,aligned(8))) request_block;
-	struct {
-		/* word 0 */
-		__u16 length;
-		__u16 response_code;
-		/* word 1 */
-		__u32 reserved1;
-		union {
-			struct {
-				/* word 2 */
-				__u8  flags;
-				__u8  vf;         /* validity flags */
-				__u8  rs;         /* reporting source */
-				__u8  cc;         /* content code */
-				/* word 3 */
-				__u16 fla;        /* full link address */
-				__u16 rsid;       /* reporting source id */
-				/* word 4 */
-				__u32 reserved2;
-				/* word 5 */
-				__u32 reserved3;
-				/* word 6 */
-				__u32 ccdf;       /* content-code dependent field */
-				/* word 7 */
-				__u32 reserved4;
-				/* word 8 */
-				__u32 reserved5;
-				/* word 9 */
-				__u32 reserved6;
-			} __attribute__ ((packed,aligned(8))) sei_res;
-			struct {
-				/* word 2 */
-				__u8 sch_valid : 1;
-				__u8 dev_valid : 1;
-				__u8 st        : 3; /* subchannel type */
-				__u8 zeroes    : 3;
-				__u8  unit_addr;  /* unit address */
-				__u16 devno;      /* device number */
-				/* word 3 */
-				__u8 path_mask;  
-				__u8 fla_valid_mask;
-				__u16 sch;        /* subchannel */
-				/* words 4-5 */
-				__u8 chpid[8];    /* chpids 0-7 */
-				/* words 6-9 */
-				__u16 fla[8];     /* full link addresses 0-7 */
-			} __attribute__ ((packed,aligned(8))) ssd_res;
-		} response_block_data;
-	} __attribute__ ((packed,aligned(8))) response_block;
-} __attribute__ ((packed,aligned(PAGE_SIZE))) chsc_area_t;
-
-#endif /* __KERNEL__ */
-/*
- * sense data
- */
-typedef struct {
-      __u8          res[32];   /* reserved   */
-      __u8          data[32];  /* sense data */
-   } __attribute__ ((packed)) sense_t;
-
-/*
- * device status area, to be provided by the device driver
- *  when calling request_irq() as parameter "dev_id", later
- *  tied to the "action" control block.
- *
- * Note : No data area must be added after union ii or the
- *         effective devstat size calculation will fail !
- */
-typedef struct {
-     __u16         devno;    /* device number, aka. "cuu" from irb */
-     unsigned long intparm;  /* interrupt parameter */
-     __u8          cstat;    /* channel status - accumulated */
-     __u8          dstat;    /* device status - accumulated */
-     __u8          lpum;     /* last path used mask from irb */
-     __u8          unused;   /* not used - reserved */
-     unsigned int  flag;     /* flag : see below */
-     __u32         cpa;      /* CCW address from irb at primary status */
-     __u32         rescnt;   /* res. count from irb at primary status */
-     __u32         scnt;     /* sense count, if DEVSTAT_FLAG_SENSE_AVAIL */
-     union {
-        irb_t   irb;         /* interruption response block */
-        sense_t sense;       /* sense information */
-        } ii;                /* interrupt information */
-  } devstat_t;
-
-#define DEVSTAT_FLAG_SENSE_AVAIL   0x00000001
-#define DEVSTAT_NOT_OPER           0x00000002
-#define DEVSTAT_START_FUNCTION     0x00000004
-#define DEVSTAT_HALT_FUNCTION      0x00000008
-#define DEVSTAT_STATUS_PENDING     0x00000010
-#define DEVSTAT_REVALIDATE         0x00000020
-#define DEVSTAT_DEVICE_GONE        0x00000040
-#define DEVSTAT_DEVICE_OWNED       0x00000080
-#define DEVSTAT_CLEAR_FUNCTION     0x00000100
-#define DEVSTAT_PCI                0x00000200
-#define DEVSTAT_SUSPENDED          0x00000400
-#define DEVSTAT_UNKNOWN_DEV        0x00000800
-#define DEVSTAT_FINAL_STATUS       0x80000000
-
-#define DEVINFO_NOT_OPER           DEVSTAT_NOT_OPER
-#define DEVINFO_UNKNOWN_DEV        DEVSTAT_UNKNOWN_DEV
-#define DEVINFO_DEVICE_OWNED       DEVSTAT_DEVICE_OWNED
-#define DEVINFO_QDIO_CAPABLE       0x40000000
-
-#define INTPARM_STATUS_PENDING     0xFFFFFFFF
-#ifdef __KERNEL__
-
-#define IO_INTERRUPT_TYPE          0 /* I/O interrupt type */
-
-typedef  void (* io_handler_func1_t) ( int             irq,
-                                       devstat_t      *devstat,
-                                       struct pt_regs *rgs);
-
-typedef  void (* io_handler_func_t) ( int             irq,
-                                      void           *devstat,
-                                      struct pt_regs *rgs);
-
-typedef  void ( * not_oper_handler_func_t)( int irq,
-                                            int status );
-
-typedef  int  (* adapter_int_handler_t)( __u32 intparm );
-
-typedef struct {
-	io_handler_func_t         handler;  /* interrupt handler routine */
-	const char               *name;     /* device name */
-	devstat_t                *dev_id;   /* device status block */
-   } irq_desc_t;
-
-typedef struct {
-	__u8  state1    :  2;   /* path state value 1 */
-	__u8  state2    :  2;   /* path state value 2 */
-	__u8  state3    :  1;   /* path state value 3 */
-	__u8  resvd     :  3;   /* reserved */
-	} __attribute__ ((packed)) path_state_t;
-
-typedef struct {
-   union {
-		__u8         fc;   /* SPID function code */
-		path_state_t ps;   /* SNID path state */
-	} inf;
-	__u32 cpu_addr  : 16;   /* CPU address */
-	__u32 cpu_id    : 24;   /* CPU identification */
-	__u32 cpu_model : 16;   /* CPU model */
-	__u32 tod_high;         /* high word TOD clock */
-	} __attribute__ ((packed)) pgid_t;
-
-#define SPID_FUNC_SINGLE_PATH      0x00
-#define SPID_FUNC_MULTI_PATH       0x80
-#define SPID_FUNC_ESTABLISH        0x00
-#define SPID_FUNC_RESIGN           0x40
-#define SPID_FUNC_DISBAND          0x20
-
-#define SNID_STATE1_RESET          0
-#define SNID_STATE1_UNGROUPED      2
-#define SNID_STATE1_GROUPED        3
-
-#define SNID_STATE2_NOT_RESVD      0
-#define SNID_STATE2_RESVD_ELSE     2
-#define SNID_STATE2_RESVD_SELF     3
-
-#define SNID_STATE3_MULTI_PATH     1
-#define SNID_STATE3_SINGLE_PATH    0
-
-/*
- * Flags used as input parameters for do_IO()
- */
-#define DOIO_EARLY_NOTIFICATION  0x0001 /* allow for I/O completion ... */
-                                        /* ... notification after ... */
-                                        /* ... primary interrupt status */
-#define DOIO_RETURN_CHAN_END     DOIO_EARLY_NOTIFICATION
-#define DOIO_VALID_LPM           0x0002 /* LPM input parameter is valid */
-#define DOIO_WAIT_FOR_INTERRUPT  0x0004 /* wait synchronously for interrupt */
-#define DOIO_REPORT_ALL          0x0008 /* report all interrupt conditions */
-#define DOIO_ALLOW_SUSPEND       0x0010 /* allow for channel prog. suspend */
-#define DOIO_DENY_PREFETCH       0x0020 /* don't allow for CCW prefetch */
-#define DOIO_SUPPRESS_INTER      0x0040 /* suppress intermediate inter. */
-                                        /* ... for suspended CCWs */
-#define DOIO_TIMEOUT             0x0080 /* 3 secs. timeout for sync. I/O */
-#define DOIO_DONT_CALL_INTHDLR   0x0100 /* don't call interrupt handler */
-#define DOIO_CANCEL_ON_TIMEOUT   0x0200 /* cancel I/O if it timed out */
-
-/*
- * do_IO()
- *
- *  Start a S/390 channel program. When the interrupt arrives, the
- *  IRQ handler is called, either immediately, delayed (dev-end missing,
- *  or sense required) or never (no IRQ handler registered -
- *  should never occur, as the IRQ (subchannel ID) should be
- *  disabled if no handler is present. Depending on the action
- *  taken, do_IO() returns :  0      - Success
- *                           -EIO    - Status pending
- *                                        see : action->dev_id->cstat
- *                                              action->dev_id->dstat
- *                           -EBUSY  - Device busy
- *                           -ENODEV - Device not operational
- */
-int do_IO( int            irq,          /* IRQ aka. subchannel number */
-           ccw1_t        *cpa,          /* logical channel program address */
-           unsigned long  intparm,      /* interruption parameter */
-           __u8           lpm,          /* logical path mask */
-           unsigned long  flag);        /* flags : see above */
-
-
-void do_crw_pending( void  );	         /* CRW handler */
-
-int resume_IO( int irq);               /* IRQ aka. subchannel number */
-
-int halt_IO( int           irq,         /* IRQ aka. subchannel number */
-             unsigned long intparm,     /* dummy intparm */
-             unsigned long flag);       /* possible DOIO_WAIT_FOR_INTERRUPT */
-
-int clear_IO( int           irq,         /* IRQ aka. subchannel number */
-              unsigned long intparm,     /* dummy intparm */
-              unsigned long flag);       /* possible DOIO_WAIT_FOR_INTERRUPT */
-
-typedef struct {
-     int          irq;                  /* irq, aka. subchannel */
-     __u16        devno;                /* device number */
-     unsigned int status;               /* device status */
-     senseid_t    sid_data;             /* senseID data */
-     } s390_dev_info_t;
-
-int get_dev_info_by_irq  ( int irq, s390_dev_info_t *pdi);
-int get_dev_info_by_devno( __u16 devno, s390_dev_info_t *pdi);
-
-int          get_irq_by_devno( __u16 devno );
-unsigned int get_devno_by_irq( int irq );
-
-int get_irq_first( void );
-int get_irq_next ( int irq );
-
-int read_dev_chars( int irq, void **buffer, int length );
-int read_conf_data( int irq, void **buffer, int *length, __u8 lpm );
-
-int s390_request_irq_special( int                      irq,
-                              io_handler_func_t        io_handler,
-                              not_oper_handler_func_t  not_oper_handler,
-                              unsigned long            irqflags,
-                              const char              *devname,
-                              void                    *dev_id);
-
-extern int s390_request_console_irq (int irq,
-			  void (*handler) (int, void *, struct pt_regs *),
-			  unsigned long irqflags,
-			  const char *devname,
-			  void *dev_id);
-
-extern int set_cons_dev(int irq);
-extern int wait_cons_dev(int irq);
-extern schib_t *s390_get_schib( int irq );
-
-extern int s390_register_adapter_interrupt(adapter_int_handler_t handler);
-extern int s390_unregister_adapter_interrupt(adapter_int_handler_t handler);
-
-/*
- * Some S390 specific IO instructions as inline
- */
-
-extern __inline__ int stsch(int irq, volatile schib_t *addr)
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "   lr    1,%1\n"
-                "   stsch 0(%2)\n"
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode)
-		: "d" (irq | 0x10000), "a" (addr)
-		: "cc", "1" );
-        return ccode;
-}
-
-extern __inline__ int msch(int irq, volatile schib_t *addr)
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "   lr    1,%1\n"
-                "   msch  0(%2)\n"
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode)
-		: "d" (irq | 0x10000L), "a" (addr)
-                : "cc", "1" );
-        return ccode;
-}
-
-extern __inline__ int msch_err(int irq, volatile schib_t *addr)
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "    lr   1,%1\n"
-                "    msch 0(%2)\n"
-                "0:  ipm  %0\n"
-                "    srl  %0,28\n"
-                "1:\n"
-#ifdef CONFIG_ARCH_S390X
-                ".section .fixup,\"ax\"\n"
-                "2:  l    %0,%3\n"
-                "    jg   1b\n"
-                ".previous\n"
-                ".section __ex_table,\"a\"\n"
-                "   .align 8\n"
-                "   .quad 0b,2b\n"
-                ".previous"
-#else
-                ".section .fixup,\"ax\"\n"
-                "2:  l    %0,%3\n"
-                "    bras 1,3f\n"
-                "    .long 1b\n"
-                "3:  l    1,0(1)\n"
-                "    br   1\n"
-                ".previous\n"
-                ".section __ex_table,\"a\"\n"
-                "   .align 4\n"
-                "   .long 0b,2b\n"
-                ".previous"
-#endif
-                : "=d" (ccode)
-                : "d" (irq | 0x10000L), "a" (addr), "i" (__LC_PGM_ILC)
-                : "cc", "1" );
-        return ccode;
-}
-
-extern __inline__ int tsch(int irq, volatile irb_t *addr)
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "   lr    1,%1\n"
-                "   tsch  0(%2)\n"
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode) 
-		: "d" (irq | 0x10000L), "a" (addr)
-                : "cc", "1" );
-        return ccode;
-}
-
-extern __inline__ int tpi( volatile tpi_info_t *addr)
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "   tpi   0(%1)\n"
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode) 
-		: "a" (addr)
-                : "cc", "1" );
-        return ccode;
-}
-
-extern __inline__ int ssch(int irq, volatile orb_t *addr)
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "   lr    1,%1\n"
-                "   ssch  0(%2)\n"
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode) 
-		: "d" (irq | 0x10000L), "a" (addr)
-                : "cc", "1" );
-        return ccode;
-}
-
-extern __inline__ int rsch(int irq)
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "   lr    1,%1\n"
-                "   rsch\n"
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode) 
-		: "d" (irq | 0x10000L)
-                : "cc", "1" );
-        return ccode;
-}
-
-extern __inline__ int csch(int irq)
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "   lr    1,%1\n"
-                "   csch\n"
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode) 
-		: "d" (irq | 0x10000L)
-                : "cc", "1" );
-        return ccode;
-}
-
-extern __inline__ int hsch(int irq)
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "   lr    1,%1\n"
-                "   hsch\n"
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode) 
-		: "d" (irq | 0x10000L)
-                : "cc", "1" );
-        return ccode;
-}
-
-extern __inline__ int xsch(int irq)
-{
-	int ccode;
-	
-	__asm__ __volatile__(
-                "   lr    1,%1\n"
-                "   .insn rre,0xb2760000,%1,0\n"
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode) 
-		: "d" (irq | 0x10000L)
-                : "cc", "1" );
-	return ccode;
-}
-
-extern __inline__ int iac( void)
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "   iac   1\n"
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode) : : "cc", "1" );
-        return ccode;
-}
-
-extern __inline__ int rchp(int chpid)
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "   lr    1,%1\n"
-                "   rchp\n"
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode) 
-		: "d" (chpid)
-                : "cc", "1" );
-        return ccode;
-}
-
-typedef struct {
-     __u16 vrdcdvno : 16;   /* device number (input) */
-     __u16 vrdclen  : 16;   /* data block length (input) */
-     __u32 vrdcvcla : 8;    /* virtual device class (output) */
-     __u32 vrdcvtyp : 8;    /* virtual device type (output) */
-     __u32 vrdcvsta : 8;    /* virtual device status (output) */
-     __u32 vrdcvfla : 8;    /* virtual device flags (output) */
-     __u32 vrdcrccl : 8;    /* real device class (output) */
-     __u32 vrdccrty : 8;    /* real device type (output) */
-     __u32 vrdccrmd : 8;    /* real device model (output) */
-     __u32 vrdccrft : 8;    /* real device feature (output) */
-     } __attribute__ ((packed,aligned(4))) diag210_t;
-
-extern int diag210( diag210_t * addr);
-
-extern __inline__ int chsc( chsc_area_t * chsc_area)
-{
-	int cc;
-	
-	__asm__ __volatile__ (
-	        ".insn	rre,0xb25f0000,%1,0	\n\t"
-		"ipm	%0	\n\t"
-		"srl	%0,28	\n\t"
-		: "=d" (cc) 
-		: "d" (chsc_area) 
-		: "cc" );
-	
-	return cc;
-}
-
-#include <asm/s390io.h>
-
-#define get_irq_lock(irq) &ioinfo[irq]->irq_lock
-
-#define s390irq_spin_lock(irq) \
-        spin_lock(get_irq_lock(irq))
-
-#define s390irq_spin_unlock(irq) \
-        spin_unlock(get_irq_lock(irq))
-
-#define s390irq_spin_lock_irqsave(irq,flags) \
-        spin_lock_irqsave(get_irq_lock(irq), flags)
+ * the definition of irqs has changed in 2.5.46:
+ * NR_IRQS is no longer the number of i/o
+ * interrupts (65536), but rather the number
+ * of interrupt classes (6).
+ */
+
+enum interruption_class {
+	EXTERNAL_INTERRUPT,
+	IO_INTERRUPT,
+	MACHINE_CHECK_INTERRUPT,
+	PROGRAM_INTERRUPT,
+	RESTART_INTERRUPT,
+	SUPERVISOR_CALL,
 
-#define s390irq_spin_unlock_irqrestore(irq,flags) \
-        spin_unlock_irqrestore(get_irq_lock(irq), flags)
+	NR_IRQS,
+};
 
 #define touch_nmi_watchdog() do { } while(0)
 
diff -Nru a/include/asm-s390/lowcore.h b/include/asm-s390/lowcore.h
--- a/include/asm-s390/lowcore.h	Mon Dec  9 18:46:37 2002
+++ b/include/asm-s390/lowcore.h	Mon Dec  9 18:46:37 2002
@@ -35,9 +35,9 @@
 #define __LC_MCCK_CODE                  0x0E8
 #define __LC_AREGS_SAVE_AREA            0x120
 #define __LC_CREGS_SAVE_AREA            0x1C0
-#define __LC_RETURN_PSW                 0x200
 
-#define __LC_SYNC_IO_WORD               0x400
+#define __LC_RETURN_PSW                 0x200
+#define __LC_IRB			0x208
 
 #define __LC_SAVE_AREA                  0xC00
 #define __LC_KERNEL_STACK               0xC40
@@ -115,14 +115,11 @@
 	__u32        access_regs_save_area[16];/* 0x120 */
 	__u32        floating_pt_save_area[8]; /* 0x160 */
 	__u32        gpregs_save_area[16];     /* 0x180 */
-	__u32        cregs_save_area[16];      /* 0x240 */	
+	__u32        cregs_save_area[16];      /* 0x1c0 */	
 
         psw_t        return_psw;               /* 0x200 */
-	__u8         pad8[0x400-0x208];        /* 0x208 */
-
-	__u32        sync_io_word;	       /* 0x400 */
-
-        __u8         pad9[0xc00-0x404];        /* 0x404 */
+	__u8	     irb[64];		       /* 0x208 */
+	__u8         pad8[0xc00-0x248];        /* 0x248 */
 
         /* System info area */
 	__u32        save_area[16];            /* 0xc00 */
diff -Nru a/include/asm-s390/qdio.h b/include/asm-s390/qdio.h
--- a/include/asm-s390/qdio.h	Mon Dec  9 18:46:35 2002
+++ b/include/asm-s390/qdio.h	Mon Dec  9 18:46:35 2002
@@ -16,27 +16,14 @@
 /* note, that most of the typedef's are from ingo. */
 
 #include <linux/interrupt.h>
-
-//#define QDIO_DBF_LIKE_HELL
+#include <asm/cio.h>
 
 #define QDIO_NAME "qdio "
 
-#define QDIO_VERBOSE_LEVEL 9
-
 #ifndef CONFIG_ARCH_S390X
 #define QDIO_32_BIT
 #endif /* CONFIG_ARCH_S390X */
 
-#define QDIO_USE_PROCESSING_STATE
-
-#ifdef CONFIG_QDIO_PERF_STATS
-#define QDIO_PERFORMANCE_STATS
-#endif /* CONFIG_QDIO_PERF_STATS */
-
-#define QDIO_MINIMAL_BH_RELIEF_TIME 16
-#define QDIO_TIMER_POLL_VALUE 1
-#define IQDIO_TIMER_POLL_VALUE 1
-
 /**** CONSTANTS, that are relied on without using these symbols *****/
 #define QDIO_MAX_QUEUES_PER_IRQ 32 /* used in width of unsigned int */
 /************************ END of CONSTANTS **************************/
@@ -45,195 +32,22 @@
 #define QDIO_MAX_ELEMENTS_PER_BUFFER 16
 #define SBAL_SIZE 256
 
-#define IQDIO_FILL_LEVEL_TO_POLL (QDIO_MAX_BUFFERS_PER_Q*4/3)
-
-#define IQDIO_THININT_ISC 3
-#define IQDIO_DELAY_TARGET 0
-#define QDIO_BUSY_BIT_PATIENCE 2000 /* in microsecs */
-#define IQDIO_GLOBAL_LAPS 2 /* GLOBAL_LAPS are not used as we */
-#define IQDIO_GLOBAL_LAPS_INT 1 /* dont global summary */
-#define IQDIO_LOCAL_LAPS 4
-#define IQDIO_LOCAL_LAPS_INT 1
-#define IQDIO_GLOBAL_SUMMARY_CC_MASK 2
-/*#define IQDIO_IQDC_INT_PARM 0x1234*/
-
-#define QDIO_Q_LAPS 5
-
-#define QDIO_STORAGE_KEY 0
-
-#define L2_CACHELINE_SIZE 256
-#define INDICATORS_PER_CACHELINE (L2_CACHELINE_SIZE/sizeof(__u32))
-
-#define QDIO_PERF "qdio_perf"
-
-/* must be a power of 2 */
-/*#define QDIO_STATS_NUMBER 4
-
-#define QDIO_STATS_CLASSES 2
-#define QDIO_STATS_COUNT_NEEDED 2*/
-
-#define QDIO_NO_USE_COUNT_TIME 10
-#define QDIO_NO_USE_COUNT_TIMEOUT 1000 /* wait for 1 sec on each q before
-					  exiting without having use_count
-					  of the queue to 0 */
-
-#define QDIO_ESTABLISH_TIMEOUT 1000
-#define QDIO_ACTIVATE_TIMEOUT 100
-#define QDIO_CLEANUP_CLEAR_TIMEOUT 20000
-#define QDIO_CLEANUP_HALT_TIMEOUT 10000
-
-#define QDIO_IRQ_BUCKETS 256 /* heavy..., but does only use a few bytes, but
-			      be rather faster in cases of collisions
-			      (if there really is a collision, it is
-			      on every (traditional) interrupt and every
-			      do_QDIO, so we rather are generous */
 #define QDIO_QETH_QFMT 0
 #define QDIO_ZFCP_QFMT 1
 #define QDIO_IQDIO_QFMT 2
 
-#define QDIO_IRQ_STATE_FRESH 0 /* must be 0 -> memset has set it to 0 */
-#define QDIO_IRQ_STATE_INACTIVE 1
-#define QDIO_IRQ_STATE_ESTABLISHED 2
-#define QDIO_IRQ_STATE_ACTIVE 3
-#define QDIO_IRQ_STATE_STOPPED 4
-
-/* used as intparm in do_IO: */
-#define QDIO_DOING_SENSEID 0
-#define QDIO_DOING_ESTABLISH 1
-#define QDIO_DOING_ACTIVATE 2
-#define QDIO_DOING_CLEANUP 3
-
-/************************* DEBUG FACILITY STUFF *********************/
-/* #define QDIO_DBF_LIKE_HELL */
-
-#define QDIO_DBF_HEX(ex,name,level,addr,len) \
-	do { \
-	if (ex) \
-		debug_exception(qdio_dbf_##name,level,(void*)(addr),len); \
-	else \
-		debug_event(qdio_dbf_##name,level,(void*)(addr),len); \
-	} while (0)
-#define QDIO_DBF_TEXT(ex,name,level,text) \
-	do { \
-	if (ex) \
-		debug_text_exception(qdio_dbf_##name,level,text); \
-	else \
-		debug_text_event(qdio_dbf_##name,level,text); \
-	} while (0)
-
-#define QDIO_DBF_HEX0(ex,name,addr,len) QDIO_DBF_HEX(ex,name,0,addr,len)
-#define QDIO_DBF_HEX1(ex,name,addr,len) QDIO_DBF_HEX(ex,name,1,addr,len)
-#define QDIO_DBF_HEX2(ex,name,addr,len) QDIO_DBF_HEX(ex,name,2,addr,len)
-#define QDIO_DBF_HEX3(ex,name,addr,len) QDIO_DBF_HEX(ex,name,3,addr,len)
-#define QDIO_DBF_HEX4(ex,name,addr,len) QDIO_DBF_HEX(ex,name,4,addr,len)
-#define QDIO_DBF_HEX5(ex,name,addr,len) QDIO_DBF_HEX(ex,name,5,addr,len)
-#define QDIO_DBF_HEX6(ex,name,addr,len) QDIO_DBF_HEX(ex,name,6,addr,len)
-#ifdef QDIO_DBF_LIKE_HELL
-#endif /* QDIO_DBF_LIKE_HELL */
-#if 0
-#define QDIO_DBF_HEX0(ex,name,addr,len) do {} while (0)
-#define QDIO_DBF_HEX1(ex,name,addr,len) do {} while (0)
-#define QDIO_DBF_HEX2(ex,name,addr,len) do {} while (0)
-#ifndef QDIO_DBF_LIKE_HELL
-#define QDIO_DBF_HEX3(ex,name,addr,len) do {} while (0)
-#define QDIO_DBF_HEX4(ex,name,addr,len) do {} while (0)
-#define QDIO_DBF_HEX5(ex,name,addr,len) do {} while (0)
-#define QDIO_DBF_HEX6(ex,name,addr,len) do {} while (0)
-#endif /* QDIO_DBF_LIKE_HELL */
-#endif /* 0 */
-
-#define QDIO_DBF_TEXT0(ex,name,text) QDIO_DBF_TEXT(ex,name,0,text)
-#define QDIO_DBF_TEXT1(ex,name,text) QDIO_DBF_TEXT(ex,name,1,text)
-#define QDIO_DBF_TEXT2(ex,name,text) QDIO_DBF_TEXT(ex,name,2,text)
-#define QDIO_DBF_TEXT3(ex,name,text) QDIO_DBF_TEXT(ex,name,3,text)
-#define QDIO_DBF_TEXT4(ex,name,text) QDIO_DBF_TEXT(ex,name,4,text)
-#define QDIO_DBF_TEXT5(ex,name,text) QDIO_DBF_TEXT(ex,name,5,text)
-#define QDIO_DBF_TEXT6(ex,name,text) QDIO_DBF_TEXT(ex,name,6,text)
-#ifdef QDIO_DBF_LIKE_HELL
-#endif /* QDIO_DBF_LIKE_HELL */
-#if 0
-#define QDIO_DBF_TEXT0(ex,name,text) do {} while (0)
-#define QDIO_DBF_TEXT1(ex,name,text) do {} while (0)
-#define QDIO_DBF_TEXT2(ex,name,text) do {} while (0)
-#ifndef QDIO_DBF_LIKE_HELL
-#define QDIO_DBF_TEXT3(ex,name,text) do {} while (0)
-#define QDIO_DBF_TEXT4(ex,name,text) do {} while (0)
-#define QDIO_DBF_TEXT5(ex,name,text) do {} while (0)
-#define QDIO_DBF_TEXT6(ex,name,text) do {} while (0)
-#endif /* QDIO_DBF_LIKE_HELL */
-#endif /* 0 */
-
-#define QDIO_DBF_SETUP_NAME "qdio_setup"
-#define QDIO_DBF_SETUP_LEN 8
-#define QDIO_DBF_SETUP_INDEX 2
-#define QDIO_DBF_SETUP_NR_AREAS 1
-#ifdef QDIO_DBF_LIKE_HELL
-#define QDIO_DBF_SETUP_LEVEL 6
-#else /* QDIO_DBF_LIKE_HELL */
-#define QDIO_DBF_SETUP_LEVEL 2
-#endif /* QDIO_DBF_LIKE_HELL */
-
-#define QDIO_DBF_SBAL_NAME "qdio_labs" /* sbal */
-#define QDIO_DBF_SBAL_LEN 256
-#define QDIO_DBF_SBAL_INDEX 2
-#define QDIO_DBF_SBAL_NR_AREAS 2
-#ifdef QDIO_DBF_LIKE_HELL
-#define QDIO_DBF_SBAL_LEVEL 6
-#else /* QDIO_DBF_LIKE_HELL */
-#define QDIO_DBF_SBAL_LEVEL 2
-#endif /* QDIO_DBF_LIKE_HELL */
-
-#define QDIO_DBF_TRACE_NAME "qdio_trace"
-#define QDIO_DBF_TRACE_LEN 8
-#define QDIO_DBF_TRACE_NR_AREAS 2
-#ifdef QDIO_DBF_LIKE_HELL
-#define QDIO_DBF_TRACE_INDEX 4
-#define QDIO_DBF_TRACE_LEVEL 4 /* -------- could be even more verbose here */
-#else /* QDIO_DBF_LIKE_HELL */
-#define QDIO_DBF_TRACE_INDEX 2
-#define QDIO_DBF_TRACE_LEVEL 2
-#endif /* QDIO_DBF_LIKE_HELL */
-
-#define QDIO_DBF_SENSE_NAME "qdio_sense"
-#define QDIO_DBF_SENSE_LEN 64
-#define QDIO_DBF_SENSE_INDEX 1
-#define QDIO_DBF_SENSE_NR_AREAS 1
-#ifdef QDIO_DBF_LIKE_HELL
-#define QDIO_DBF_SENSE_LEVEL 6
-#else /* QDIO_DBF_LIKE_HELL */
-#define QDIO_DBF_SENSE_LEVEL 2
-#endif /* QDIO_DBF_LIKE_HELL */
-
-#ifdef QDIO_DBF_LIKE_HELL
-#define QDIO_TRACE_QTYPE QDIO_ZFCP_QFMT
-
-#define QDIO_DBF_SLSB_OUT_NAME "qdio_slsb_out"
-#define QDIO_DBF_SLSB_OUT_LEN QDIO_MAX_BUFFERS_PER_Q
-#define QDIO_DBF_SLSB_OUT_INDEX 8
-#define QDIO_DBF_SLSB_OUT_NR_AREAS 1
-#define QDIO_DBF_SLSB_OUT_LEVEL 6
-
-#define QDIO_DBF_SLSB_IN_NAME "qdio_slsb_in"
-#define QDIO_DBF_SLSB_IN_LEN QDIO_MAX_BUFFERS_PER_Q
-#define QDIO_DBF_SLSB_IN_INDEX 8
-#define QDIO_DBF_SLSB_IN_NR_AREAS 1
-#define QDIO_DBF_SLSB_IN_LEVEL 6
-#endif /* QDIO_DBF_LIKE_HELL */
-
-/****************** END OF DEBUG FACILITY STUFF *********************/
-
-typedef struct qdio_buffer_element_t {
+struct qdio_buffer_element{
 	unsigned int flags;
 	unsigned int length;
 #ifdef QDIO_32_BIT
 	void *reserved;
 #endif /* QDIO_32_BIT */
 	void *addr;
-} __attribute__ ((packed,aligned(16))) qdio_buffer_element_t;
+} __attribute__ ((packed,aligned(16)));
 
-typedef struct qdio_buffer_t {
-	volatile qdio_buffer_element_t element[16];
-} __attribute__ ((packed,aligned(256))) qdio_buffer_t;
+struct qdio_buffer{
+	volatile struct qdio_buffer_element element[16];
+} __attribute__ ((packed,aligned(256)));
 
 
 /* params are: irq, status, qdio_error, siga_error,
@@ -262,8 +76,8 @@
 #define QDIO_FLAG_CLEANUP_USING_CLEAR 0x01
 #define QDIO_FLAG_CLEANUP_USING_HALT 0x02
 
-typedef struct qdio_initialize_t {
-	int irq;
+struct qdio_initialize{
+	struct ccw_device *cdev;
 	unsigned char q_format;
 	unsigned char adapter_name[8];
        	unsigned int qib_param_field_format; /*adapter dependent*/
@@ -284,10 +98,10 @@
 	unsigned long flags;
 	void **input_sbal_addr_array; /* addr of n*128 void ptrs */
 	void **output_sbal_addr_array; /* addr of n*128 void ptrs */
-} qdio_initialize_t;
-extern int qdio_initialize(qdio_initialize_t *init_data);
+};
+extern int qdio_initialize(struct qdio_initialize *init_data);
 
-extern int qdio_activate(int irq,int flags);
+extern int qdio_activate(struct ccw_device *,int flags);
 
 #define QDIO_STATE_MUST_USE_OUTB_PCI	0x00000001
 #define QDIO_STATE_INACTIVE 		0x00000002 /* after qdio_cleanup */
@@ -304,47 +118,23 @@
 						     adapter interrupts */
 #define QDIO_FLAG_DONT_SIGA 0x10
 
-extern int do_QDIO(int irq,unsigned int flags, unsigned int queue_number,
+extern int do_QDIO(struct ccw_device*, unsigned int flags, 
+		   unsigned int queue_number,
 		   unsigned int qidx,unsigned int count,
-		   qdio_buffer_t *buffers);
+		   struct qdio_buffer *buffers);
 
-extern int qdio_synchronize(int irq,unsigned int flags,
+extern int qdio_synchronize(struct ccw_device*, unsigned int flags,
 			    unsigned int queue_number);
 
-extern int qdio_cleanup(int irq,int how);
+extern int qdio_cleanup(struct ccw_device*, int how);
 
-unsigned char qdio_get_slsb_state(int irq,unsigned int flag,
+unsigned char qdio_get_slsb_state(struct ccw_device*, unsigned int flag,
 				  unsigned int queue_number,
 				  unsigned int qidx);
 
 extern void qdio_init_scrubber(void);
-/*
- * QDIO device commands returned by extended Sense-ID
- */
-#define DEFAULT_ESTABLISH_QS_CMD 0x1b
-#define DEFAULT_ESTABLISH_QS_COUNT 0x1000
-#define DEFAULT_ACTIVATE_QS_CMD 0x1f
-#define DEFAULT_ACTIVATE_QS_COUNT 0
-typedef struct _qdio_cmds {
-	unsigned char rcd;            /* read configuration data */
-	unsigned short count_rcd;
-	unsigned char sii;            /* set interface identifier */
-	unsigned short count_sii;
-	unsigned char rni;            /* read node identifier */
-	unsigned short count_rni;
-	unsigned char eq;             /* establish QDIO queues */
-	unsigned short count_eq;
-	unsigned char aq;             /* activate QDIO queues */
-	unsigned short count_aq;
-} qdio_cmds_t;
 
-/*
- * additional CIWs returned by extended Sense-ID
- */
-#define CIW_TYPE_EQUEUE 0x3       /* establish QDIO queues */
-#define CIW_TYPE_AQUEUE 0x4       /* activate QDIO queues */
-
-typedef struct _qdesfmt0 {
+struct qdesfmt0 {
 #ifdef QDIO_32_BIT
 	unsigned long res1;             /* reserved */
 #endif /* QDIO_32_BIT */
@@ -364,12 +154,12 @@
 	unsigned int  ckey  :  4;       /* access key for SBALs */
 	unsigned int  dkey  :  4;       /* access key for SLSB */
 	unsigned int  res5  : 16;       /* reserved */
-} __attribute__ ((packed)) qdesfmt0_t;
+} __attribute__ ((packed));
 
 /*
  * Queue-Description record (QDR)
  */
-typedef struct _qdr {
+struct qdr {
 	unsigned int  qfmt    :  8;     /* queue format */
 	unsigned int  pfmt    :  8;     /* impl. dep. parameter format */
 	unsigned int  res1    :  8;     /* reserved */
@@ -391,9 +181,9 @@
 	unsigned int  qkey    :  4;     /* queue-informatio-block key */
 	unsigned int  res9    : 28;     /* reserved */
 /*	union _qd {*/ /* why this? */
-		qdesfmt0_t qdf0[126];
+		struct qdesfmt0 qdf0[126];
 /*	} qd;*/
-} __attribute__ ((packed,aligned(4096))) qdr_t;
+} __attribute__ ((packed,aligned(4096)));
 
 
 /*
@@ -401,7 +191,7 @@
  */
 #define QIB_AC_INBOUND_PCI_SUPPORTED 0x80
 #define QIB_AC_OUTBOUND_PCI_SUPPORTED 0x40
-typedef struct _qib {
+struct qib {
 	unsigned int  qfmt    :  8;     /* queue format */
 	unsigned int  pfmt    :  8;     /* impl. dep. parameter format */
 	unsigned int  res1    :  8;     /* reserved */
@@ -424,24 +214,24 @@
 	unsigned char parm[QDIO_MAX_BUFFERS_PER_Q];
 					/* implementation dependent
 					   parameters */
-} __attribute__ ((packed,aligned(256))) qib_t;
+} __attribute__ ((packed,aligned(256)));
 
 
 /*
  * storage-list-information block element (SLIBE)
  */
-typedef struct _slibe {
+struct slibe {
 #ifdef QDIO_32_BIT
 	unsigned long res;              /* reserved */
 #endif /* QDIO_32_BIT */
 	unsigned long parms;            /* implementation dependent
 					   parameters */
-} slibe_t;
+};
 
 /*
  * storage-list-information block (SLIB)
  */
-typedef struct _slib {
+struct slib {
 #ifdef QDIO_32_BIT
 	unsigned long res1;             /* reserved */
 #endif /* QDIO_32_BIT */
@@ -455,17 +245,17 @@
 #endif /* QDIO_32_BIT */
 	unsigned long slsba;            /* SLSB address */
 	unsigned char res4[1000];       /* reserved */
-	slibe_t       slibe[QDIO_MAX_BUFFERS_PER_Q];    /* SLIB elements */
-} __attribute__ ((packed,aligned(2048))) slib_t;
+	struct slibe slibe[QDIO_MAX_BUFFERS_PER_Q];    /* SLIB elements */
+} __attribute__ ((packed,aligned(2048)));
 
-typedef struct _sbal_flags {
+struct sbal_flags {
 	unsigned char res1  : 1;   /* reserved */
 	unsigned char last  : 1;   /* last entry */
 	unsigned char cont  : 1;   /* contiguous storage */
 	unsigned char res2  : 1;   /* reserved */
 	unsigned char frag  : 2;   /* fragmentation (s.below) */
 	unsigned char res3  : 2;   /* reserved */
-} __attribute__ ((packed)) sbal_flags_t;
+} __attribute__ ((packed));
 
 #define SBAL_FLAGS_FIRST_FRAG	     0x04000000UL
 #define SBAL_FLAGS_MIDDLE_FRAG	     0x08000000UL
@@ -489,92 +279,88 @@
 /* Naught of interest beyond this point */
 
 #define SBAL_FLAGS0_PCI		0x40
-typedef struct _sbal_sbalf_0 {
+struct sbal_sbalf_0 {
 	unsigned char res1  : 1;   /* reserved */
 	unsigned char pci   : 1;   /* PCI indicator */
 	unsigned char cont  : 1;   /* data continuation */
 	unsigned char sbtype: 2;   /* storage-block type (OpenFCP) */
 	unsigned char res2  : 3;   /* reserved */
-} __attribute__ ((packed)) sbal_sbalf_0_t;
+} __attribute__ ((packed));
 
-typedef struct _sbal_sbalf_1 {
+struct sbal_sbalf_1 {
 	unsigned char res1  : 4;   /* reserved */
 	unsigned char key   : 4;   /* storage key */
-} __attribute__ ((packed)) sbal_sbalf_1_t;
+} __attribute__ ((packed));
 
-typedef struct _sbal_sbalf_14 {
+struct sbal_sbalf_14 {
 	unsigned char res1   : 4;  /* reserved */
 	unsigned char erridx : 4;  /* error index */
-} __attribute__ ((packed)) sbal_sbalf_14_t;
+} __attribute__ ((packed));
 
-typedef struct _sbal_sbalf_15 {
+struct sbal_sbalf_15 {
 	unsigned char reason;      /* reserved */
-} __attribute__ ((packed)) sbal_sbalf_15_t;
+} __attribute__ ((packed));
 
-typedef union _sbal_sbalf {
-	sbal_sbalf_0_t  i0;
-	sbal_sbalf_1_t  i1;
-	sbal_sbalf_14_t i14;
-	sbal_sbalf_15_t i15;
+union sbal_sbalf {
+	struct sbal_sbalf_0  i0;
+	struct sbal_sbalf_1  i1;
+	struct sbal_sbalf_14 i14;
+	struct sbal_sbalf_15 i15;
 	unsigned char value;
-} sbal_sbalf_t;
+};
 
-typedef struct _sbale {
+struct sbal_element {
 	union {
-		sbal_flags_t  bits;       /* flags */
+		struct sbal_flags  bits;       /* flags */
 		unsigned char value;
 	} flags;
 	unsigned int  res1  : 16;   /* reserved */
-	sbal_sbalf_t  sbalf;       /* SBAL flags */
+	union sbal_sbalf  sbalf;       /* SBAL flags */
 	unsigned int  res2  : 16;  /* reserved */
 	unsigned int  count : 16;  /* data count */
 #ifdef QDIO_32_BIT
 	unsigned long res3;        /* reserved */
 #endif /* QDIO_32_BIT */
 	unsigned long addr;        /* absolute data address */
-} __attribute__ ((packed,aligned(16))) sbal_element_t;
+} __attribute__ ((packed,aligned(16)));
 
 /*
  * strorage-block access-list (SBAL)
  */
-typedef struct _sbal {
-	sbal_element_t element[QDIO_MAX_ELEMENTS_PER_BUFFER];
-} __attribute__ ((packed,aligned(256))) sbal_t;
+struct sbal {
+	struct sbal_element element[QDIO_MAX_ELEMENTS_PER_BUFFER];
+} __attribute__ ((packed,aligned(256)));
 
 /*
  * storage-list (SL)
  */
-typedef struct _sl_element {
+struct sl_element {
 #ifdef QDIO_32_BIT
         unsigned long res;     /* reserved */
 #endif /* QDIO_32_BIT */
         unsigned long sbal;    /* absolute SBAL address */
-} __attribute__ ((packed)) sl_element_t;
+} __attribute__ ((packed));
 
-typedef struct _sl {
-	sl_element_t element[QDIO_MAX_BUFFERS_PER_Q];
-} __attribute__ ((packed,aligned(1024))) sl_t;
+struct sl {
+	struct sl_element element[QDIO_MAX_BUFFERS_PER_Q];
+} __attribute__ ((packed,aligned(1024)));
 
 /*
  * storage-list-state block (SLSB)
  */
-/*typedef struct _slsb_val {*/
-/*	unsigned char value;       */ /* SLSB entry as a single byte value */
-/*} __attribute__ ((packed)) slsb_val_t;*/
-
-typedef struct _slsb_flags {
+struct slsb_flags {
 	unsigned char owner  : 2;   /* SBAL owner */
 	unsigned char type   : 1;   /* buffer type */
 	unsigned char state  : 5;   /* processing state */
-} __attribute__ ((packed)) slsb_flags_t;
+} __attribute__ ((packed));
 
 
-typedef struct _slsb {
-	union _acc {
+struct slsb {
+	union {
 		unsigned char val[QDIO_MAX_BUFFERS_PER_Q];
-		slsb_flags_t flags[QDIO_MAX_BUFFERS_PER_Q];
+		struct slsb_flags flags[QDIO_MAX_BUFFERS_PER_Q];
 	} acc;
-} __attribute__ ((packed,aligned(256))) slsb_t;
+} __attribute__ ((packed,aligned(256)));
 
 /*
  * SLSB values
@@ -605,327 +391,5 @@
 #define SLSB_P_OUTPUT_ERROR       0xAF
 
 #define SLSB_ERROR_DURING_LOOKUP  0xFF
-/*
- * path management control word (extended layout)
- */
-typedef struct {
-	unsigned long  intparm;      /* interruption parameter */
-	unsigned int   qf   : 1;     /* qdio facility */
-	unsigned int   res0 : 1;     /* reserved */
-	unsigned int   isc  : 3;     /* interruption sublass */
-	unsigned int   res5 : 3;     /* reserved zeros */
-	unsigned int   ena  : 1;     /* enabled */
-	unsigned int   lm   : 2;     /* limit mode */
-	unsigned int   mme  : 2;     /* measurement-mode enable */
-	unsigned int   mp   : 1;     /* multipath mode */
-	unsigned int   tf   : 1;     /* timing facility */
-	unsigned int   dnv  : 1;     /* device number valid */
-	unsigned int   dev  : 16;    /* device number */
-	unsigned char  lpm;          /* logical path mask */
-	unsigned char  pnom;         /* path not operational mask */
-	unsigned char  lpum;         /* last path used mask */
-	unsigned char  pim;          /* path installed mask */
-	unsigned short mbi;          /* measurement-block index */
-	unsigned char  pom;          /* path operational mask */
-	unsigned char  pam;          /* path available mask */
-	unsigned char  chpid[8];     /* CHPID 0-7 (if available) */
-	unsigned int   res1    : 8;  /* reserved */
-	unsigned int   st      : 3;  /* */
-	unsigned int   res2    : 20; /* reserved */
-	unsigned int   csense  : 1;  /* concurrent sense; can be enabled
-					per MSCH, however, if facility
-					is not installed, this results
-					in an operand exception. */
-} pmcw_e_t;
-
-/*
- * subchannel status word (extended layout)
- */
-typedef struct {
-	unsigned int   key  : 4;     /* subchannel key */
-	unsigned int   sctl : 1;     /* suspend control */
-	unsigned int   eswf : 1;     /* ESW format */
-	unsigned int   cc   : 2;     /* deferred condition code */
-	unsigned int   fmt  : 1;     /* format */
-	unsigned int   pfch : 1;     /* prefetch */
-	unsigned int   isic : 1;     /* initial-status interruption control */
-	unsigned int   alcc : 1;     /* address-limit checking control */
-	unsigned int   ssi  : 1;     /* supress-suspended interruption */
-	unsigned int   zcc  : 1;     /* zero condition code */
-	unsigned int   ectl : 1;     /* extended control */
-	unsigned int   pno  : 1;     /* path not operational */
-	unsigned int   qact : 1;     /* qdio active */
-	unsigned int   fctl : 3;     /* function control */
-	unsigned int   actl : 7;     /* activity control */
-	unsigned int   stctl : 5;    /* status control */
-	unsigned long  cpa;          /* channel program address */
-	unsigned int   dstat : 8;    /* device status */
-	unsigned int   cstat : 8;    /* subchannel status */
-	unsigned int   count : 16;   /* residual count */
-} scsw_e_t;
-
-typedef struct qdio_q_t {
-	volatile slsb_t slsb;
-
-	__u32 * volatile dev_st_chg_ind;
-
-	int is_input_q;
-	int is_0copy_sbals_q;
-	int irq;
-
-	unsigned int is_iqdio_q;
-
-	/* bit 0 means queue 0, bit 1 means queue 1, ... */
-	unsigned int mask;
-	unsigned int q_no;
-
-	qdio_handler_t (*handler);
-
-	/* points to the next buffer to be checked for having
-	 * been processed by the card (outbound)
-	 * or to the next buffer the program should check for (inbound) */
-	volatile int first_to_check;
-	/* and the last time it was: */
-	volatile int last_move_ftc;
-
-	atomic_t number_of_buffers_used;
-	atomic_t polling;
-
-	unsigned int siga_in;
-	unsigned int siga_out;
-	unsigned int siga_sync;
-	unsigned int siga_sync_done_on_thinints;
-	unsigned int hydra_gives_outbound_pcis;
-
-	/* used to save beginning position when calling dd_handlers */
-	int first_element_to_kick;
-
-	atomic_t use_count;
-	atomic_t is_in_shutdown;
-
-#ifdef QDIO_USE_TIMERS_FOR_POLLING
-	struct timer_list timer;
-	atomic_t timer_already_set;
-	spinlock_t timer_lock;
-#else /* QDIO_USE_TIMERS_FOR_POLLING */
-	struct tasklet_struct tasklet;
-#endif /* QDIO_USE_TIMERS_FOR_POLLING */
-
-	unsigned int state;
-
-	/* used to store the error condition during a data transfer */
-	unsigned int qdio_error;
-	unsigned int siga_error;
-	unsigned int error_status_flags;
-
-	/* list of interesting queues */
-	volatile struct qdio_q_t *list_next;
-	volatile struct qdio_q_t *list_prev;
-
-	slib_t *slib; /* a page is allocated under this pointer,
-			 sl points into this page, offset PAGE_SIZE/2
-			 (after slib) */
-	sl_t *sl;
-	volatile sbal_t *sbal[QDIO_MAX_BUFFERS_PER_Q];
-
-	qdio_buffer_t *qdio_buffers[QDIO_MAX_BUFFERS_PER_Q];
-
-	unsigned long int_parm;
-
-	/*struct {
-		int in_bh_check_limit;
-		int threshold;
-	} threshold_classes[QDIO_STATS_CLASSES];*/
-
-	struct {
-		/* inbound: the time to stop polling
-		   outbound: the time to kick peer */
-		int threshold; /* the real value */
-
-		/* outbound: last time of do_QDIO
-		   inbound: last time of noticing incoming data */
-		/*__u64 last_transfer_times[QDIO_STATS_NUMBER];
-		int last_transfer_index; */
-
-		__u64 last_transfer_time;
-	} timing;
-        unsigned int queue_type;
-} __attribute__ ((aligned(256))) qdio_q_t;
-
-typedef struct qdio_irq_t {
-	__u32 * volatile dev_st_chg_ind;
-
-	unsigned long int_parm;
-	int irq;
-
-	unsigned int is_iqdio_irq;
-	unsigned int hydra_gives_outbound_pcis;
-	unsigned int sync_done_on_outb_pcis;
-
-	unsigned int state;
-	spinlock_t setting_up_lock;
-
-	unsigned int no_input_qs;
-	unsigned int no_output_qs;
-
-	unsigned char qdioac;
-
-	qdio_q_t *input_qs[QDIO_MAX_QUEUES_PER_IRQ];
-	qdio_q_t *output_qs[QDIO_MAX_QUEUES_PER_IRQ];
-
-	ccw1_t ccw;
-	int io_result_cstat;
-	int io_result_dstat;
-	int io_result_flags;
-	atomic_t interrupt_has_arrived;
-	atomic_t interrupt_has_been_cleaned;
-	wait_queue_head_t wait_q;
-
-	qdr_t *qdr;
-
-	qdio_cmds_t commands;
-
-	qib_t qib;
-
-	io_handler_func_t original_int_handler;
-
-	struct qdio_irq_t *next;
-} qdio_irq_t;
-
-#define QDIO_CHSC_RESPONSE_CODE_OK 1
-/* flags for st qdio sch data */
-#define CHSC_FLAG_QDIO_CAPABILITY 0x80
-#define CHSC_FLAG_VALIDITY 0x40
-
-#define CHSC_FLAG_SIGA_INPUT_NECESSARY 0x40
-#define CHSC_FLAG_SIGA_OUTPUT_NECESSARY 0x20
-#define CHSC_FLAG_SIGA_SYNC_NECESSARY 0x10
-#define CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS 0x08
-#define CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS 0x04
-
-typedef struct qdio_chsc_area_t {
-	struct {
-		/* word 0 */
-		__u16 command_code1;
-		__u16 command_code2;
-		/* word 1 */
-		__u16 operation_code;
-		__u16 first_sch;
-		/* word 2 */
-		__u8 reserved1;
-		__u8 image_id;
-		__u16 last_sch;
-		/* word 3 */
-		__u32 reserved2;
-
-		/* word 4 */
-		union {
-			struct {
-				/* word 4&5 */
-				__u64 summary_indicator_addr;
-				/* word 6&7 */
-				__u64 subchannel_indicator_addr;
-				/* word 8 */
-				int ks:4;
-				int kc:4;
-				int reserved1:21;
-				int isc:3;
-				/* word 9&10 */
-				__u32 reserved2[2];
-				/* word 11 */
-				__u32 subsystem_id;
-				/* word 12-1015 */
-				__u32 reserved3[1004];
-			} __attribute__ ((packed,aligned(4))) set_chsc;
-			struct {
-				/* word 4&5 */
-				__u32 reserved1[2];	
-				/* word 6 */
-				__u32 delay_target;
-				/* word 7-1015 */
-				__u32 reserved4[1009];
-			} __attribute__ ((packed,aligned(4))) set_chsc_fast;
-			struct {
-				/* word 0 */
-				__u16 length;
-				__u16 response_code;
-				/* word 1 */
-				__u32 reserved1;
-				/* words 2 to 9 for st sch qdio data */
-				__u8 flags;
-				__u8 reserved2;
-				__u16 sch;
-				__u8 qfmt;
-				__u8 reserved3;
-				__u8 qdioac;
-				__u8 sch_class;
-				__u8 reserved4;
-				__u8 icnt;
-				__u8 reserved5;
-				__u8 ocnt;
-				/* plus 5 words of reserved fields */
-			} __attribute__ ((packed,aligned(8)))
-			store_qdio_data_response;
-		} operation_data_area;
-	} __attribute__ ((packed,aligned(8))) request_block;
-	struct {
-		/* word 0 */
-		__u16 length;
-		__u16 response_code;
-		/* word 1 */
-		__u32 reserved1;
-	} __attribute__ ((packed,aligned(8))) response_block;
-} __attribute__ ((packed,aligned(PAGE_SIZE))) qdio_chsc_area_t;
-
-
-#define QDIO_PRINTK_HEADER QDIO_NAME ": "
-
-#if QDIO_VERBOSE_LEVEL>8
-#define QDIO_PRINT_STUPID(x...) printk( KERN_DEBUG QDIO_PRINTK_HEADER x)
-#else
-#define QDIO_PRINT_STUPID(x...)
-#endif
-
-#if QDIO_VERBOSE_LEVEL>7
-#define QDIO_PRINT_ALL(x...) printk( QDIO_PRINTK_HEADER x)
-#else
-#define QDIO_PRINT_ALL(x...)
-#endif
-
-#if QDIO_VERBOSE_LEVEL>6
-#define QDIO_PRINT_INFO(x...) printk( QDIO_PRINTK_HEADER x)
-#else
-#define QDIO_PRINT_INFO(x...)
-#endif
-
-#if QDIO_VERBOSE_LEVEL>5
-#define QDIO_PRINT_WARN(x...) printk( QDIO_PRINTK_HEADER x)
-#else
-#define QDIO_PRINT_WARN(x...)
-#endif
-
-#if QDIO_VERBOSE_LEVEL>4
-#define QDIO_PRINT_ERR(x...) printk( QDIO_PRINTK_HEADER x)
-#else
-#define QDIO_PRINT_ERR(x...)
-#endif
-
-#if QDIO_VERBOSE_LEVEL>3
-#define QDIO_PRINT_CRIT(x...) printk( QDIO_PRINTK_HEADER x)
-#else
-#define QDIO_PRINT_CRIT(x...)
-#endif
-
-#if QDIO_VERBOSE_LEVEL>2
-#define QDIO_PRINT_ALERT(x...) printk( QDIO_PRINTK_HEADER x)
-#else
-#define QDIO_PRINT_ALERT(x...)
-#endif
-
-#if QDIO_VERBOSE_LEVEL>1
-#define QDIO_PRINT_EMERG(x...) printk( QDIO_PRINTK_HEADER x)
-#else
-#define QDIO_PRINT_EMERG(x...)
-#endif
 
 #endif /* __QDIO_H__ */
diff -Nru a/include/asm-s390/s390dyn.h b/include/asm-s390/s390dyn.h
--- a/include/asm-s390/s390dyn.h	Mon Dec  9 18:46:36 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,56 +0,0 @@
-/*
- *  arch/s390/kernel/s390dyn.h
- *   S/390 data definitions for dynamic device attachment
- *
- *  S390 version
- *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Ingo Adlung (adlung@de.ibm.com)
- */
-
-#ifndef __s390dyn_h
-#define __s390dyn_h
-
-#ifndef _LINUX_LIST_H
-#include <linux/list.h>
-#endif
-
-struct _devreg;
-
-typedef  int  (* oper_handler_func_t)( int             irq,
-                                       struct _devreg *dreg);
-
-typedef struct _devreg_hc_t {
-	__u16 ctype;
-	__u8  cmode;
-	__u16 dtype;
-	__u8  dmode;
-   }  __attribute__ ((packed)) devreg_hc_t;
-
-typedef struct _devreg {
-	struct list_head list;
-	union {
-		int devno;
-		devreg_hc_t hc;       /* has controller info */
-	} ci;
-
-	int                  flag;
-	oper_handler_func_t  oper_func;
-} devreg_t;
-
-#define DEVREG_MATCH_CU_TYPE    0x00000001
-#define DEVREG_MATCH_CU_MODEL   0x00000002
-#define DEVREG_MATCH_DEV_TYPE   0x00000004
-#define DEVREG_MATCH_DEV_MODEL  0x00000008
-
-#define DEVREG_EXACT_MATCH      (DEVREG_MATCH_CU_TYPE|DEVREG_MATCH_CU_MODEL|DEVREG_MATCH_DEV_TYPE|DEVREG_MATCH_DEV_MODEL)
-#define DEVREG_NO_CU_INFO       (DEVREG_MATCH_DEV_TYPE|DEVREG_MATCH_DEV_MODEL)
-#define DEVREG_NO_DEV_INFO      (DEVREG_MATCH_CU_TYPE|DEVREG_MATCH_CU_MODEL)
-
-#define DEVREG_TYPE_DEVNO       0x80000000
-#define DEVREG_TYPE_DEVCHARS    0x40000000
-
-int        s390_device_register  ( devreg_t *drinfo );
-int        s390_device_unregister( devreg_t *dreg );
-devreg_t * s390_search_devreg    ( ioinfo_t *ioinfo );
-
-#endif /* __s390dyn */
diff -Nru a/include/asm-s390/s390io.h b/include/asm-s390/s390io.h
--- a/include/asm-s390/s390io.h	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,124 +0,0 @@
-/*
- *  arch/s390/kernel/s390io.h
- *
- *  S390 version
- *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Ingo Adlung (adlung@de.ibm.com)
- */
-
-#ifndef __s390io_h
-#define __s390io_h
-
-#include <linux/device.h>
-
-/*
- * IRQ data structure used by I/O subroutines
- *
- * Note : If bit flags are added, the "unused" value must be
- *        decremented accordingly !
- */
-typedef struct subchannel {
-     unsigned int  irq;           /* aka. subchannel number */
-     spinlock_t    irq_lock;      /* irq lock */
-
-     __u8          st;            /* subchannel type */
-
-     void          *private_data; /* pointer to private data */
-
-     struct subchannel *prev;
-     struct subchannel *next;
-
-     union {
-        unsigned int info;
-        struct {
-           unsigned int  busy      : 1;  /* device currently in use */
-           unsigned int  oper      : 1;  /* device is operational */
-           unsigned int  fast      : 1;  /* post with "channel end", ...    */
-                                         /* ... don't wait for "device end" */
-                                         /* ... from do_IO() parameters     */
-           unsigned int  ready     : 1;  /* interrupt handler registered */
-           unsigned int  haltio    : 1;  /* halt_IO in process */
-           unsigned int  doio      : 1;  /* do_IO in process */
-           unsigned int  doio_q    : 1;  /* do_IO queued - only possible ... */
-                                         /* ... if 'fast' is set too */
-           unsigned int  w4final   : 1;  /* wait for final status, internally */
-                                         /* ... used with 'fast' setting only */
-           unsigned int  repall    : 1;  /* report every interrupt status */
-           unsigned int  unready   : 1;  /* deregister irq handler in process */
-           unsigned int  d_disable : 1;  /* delayed disabling required */
-           unsigned int  w4sense   : 1;  /* SENSE status pending */
-           unsigned int  syncio    : 1;  /* synchronous I/O requested */
-           unsigned int  consns    : 1;  /* concurrent sense is available */
-           unsigned int  delsense  : 1;  /* delayed SENSE required */
-           unsigned int  s_pend    : 1;  /* status pending condition */
-           unsigned int  pgid      : 1;  /* "path group ID" is valid */
-           unsigned int  pgid_supp : 1;  /* "path group ID" command is supported */
-           unsigned int  esid      : 1;  /* Ext. SenseID supported by HW */
-           unsigned int  rcd       : 1;  /* RCD supported by HW */
-           unsigned int  repnone   : 1;  /* don't call IRQ handler on interrupt */
-           unsigned int  dval      : 1;  /* device number valid */
-           unsigned int  unknown   : 1;  /* unknown device - if SenseID failed */
-           unsigned int  unused    : (sizeof(unsigned int)*8 - 23); /* unused */
-              } __attribute__ ((packed)) flags;
-        } ui;
-
-     unsigned long u_intparm;     /* user interruption parameter */
-     senseid_t     senseid;       /* SenseID info */
-     irq_desc_t    irq_desc;      /* irq descriptor */
-     not_oper_handler_func_t nopfunc; 	/* not oper handler */		
-     __u8          ulpm;          /* logical path mask used for I/O */
-     __u8          opm;           /* path mask of operational paths */
-     __u16         devno;         /* device number */
-     pgid_t        pgid;          /* path group ID */
-     schib_t       schib;         /* subchannel information block */
-     orb_t         orb;           /* operation request block */
-     devstat_t     devstat;       /* device status */
-     ccw1_t       *qcpa;          /* queued channel program */
-     ccw1_t        senseccw;      /* ccw for sense command */
-     __u8          sense_data[32];/* buffer for basic sense */
-     unsigned int  stctl;         /* accumulated status control from irb */
-     unsigned long qintparm;      /* queued interruption parameter  */
-     unsigned long qflag;         /* queued flags */
-     __u8          qlpm;          /* queued logical path mask */
-     ssd_info_t    ssd_info;      /* subchannel description */
-     struct device dev;		  /* entry in device tree */
-} __attribute__ ((aligned(8))) ioinfo_t;
-
-
-/*
- * There are four different subchannel types, but we are currently
- * only interested in I/O subchannels. This means there is only
- * one subchannel_driver, other subchannels belonging to css_bus_type
- * are simply ignored.
- */
-struct subchannel_driver {
-	enum {
-		SUBCHANNEL_TYPE_IO      = 0,
-		SUBCHANNEL_TYPE_CHSC    = 1,
-		SUBCHANNEL_TYPE_MESSAGE = 2,
-		SUBCHANNEL_TYPE_ADM     = 3,
-	} st;			  /* subchannel type */
-	struct device_driver drv; /* entry in driver tree */
-};
-extern struct bus_type css_bus_type;
-
-#define IOINFO_FLAGS_BUSY    0x80000000
-#define IOINFO_FLAGS_OPER    0x40000000
-#define IOINFO_FLAGS_FAST    0x20000000
-#define IOINFO_FLAGS_READY   0x10000000
-#define IOINFO_FLAGS_HALTIO  0x08000000
-#define IOINFO_FLAGS_DOIO    0x04000000
-#define IOINFO_FLAGS_DOIO_Q  0x02000000
-#define IOINFO_FLAGS_W4FINAL 0x01000000
-#define IOINFO_FLAGS_REPALL  0x00800000
-
-extern ioinfo_t *ioinfo[];
-int s390_set_private_data(int irq, void * data);
-void * s390_get_private_data(int irq);
-
-#define CHSC_SEI_ACC_CHPID        1
-#define CHSC_SEI_ACC_LINKADDR     2
-#define CHSC_SEI_ACC_FULLLINKADDR 3
-
-#endif  /* __s390io_h */
-
diff -Nru a/include/asm-s390/s390mach.h b/include/asm-s390/s390mach.h
--- a/include/asm-s390/s390mach.h	Mon Dec  9 18:46:35 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,119 +0,0 @@
-/*
- *  arch/s390/kernel/s390mach.h
- *   S/390 data definitions for machine check processing
- *
- *  S390 version
- *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Ingo Adlung (adlung@de.ibm.com)
- */
-
-#ifndef __s390mach_h
-#define __s390mach_h
-
-#include <asm/types.h>
-
-typedef struct _mci {
-	__u32   sd              :  1; /* 00 system damage */
-	__u32   pd              :  1; /* 01 instruction-processing damage */
-	__u32   sr              :  1; /* 02 system recovery */
-	__u32   to_be_defined_1 :  4; /* 03-06 */
-	__u32   dg              :  1; /* 07 degradation */
-	__u32   w               :  1; /* 08 warning pending */
-	__u32   cp              :  1; /* 09 channel-report pending */
-	__u32   to_be_defined_2 :  6; /* 10-15 */
-	__u32   se              :  1; /* 16 storage error uncorrected */
-	__u32   sc              :  1; /* 17 storage error corrected */
-	__u32   ke              :  1; /* 18 storage-key error uncorrected */
-	__u32   ds              :  1; /* 19 storage degradation */
-	__u32	to_be_defined_3 :  4; /* 20-23 */
-	__u32   fa              :  1; /* 24 failing storage address validity */
-	__u32   to_be_defined_4 :  7; /* 25-31 */
-	__u32   ie              :  1; /* 32 indirect storage error */
-	__u32	to_be_defined_5 : 31; /* 33-63 */
-	} mci_t;
-
-//
-// machine-check-interruption code
-//
-typedef struct _mcic {
-   union _mcc {
-      __u64 mcl;	/* machine check int. code - long info */	
-      mci_t mcd;  /* machine check int. code - details   */
-   } mcc;
-} __attribute__ ((packed)) mcic_t;
-
-//
-// Channel Report Word
-//
-typedef struct _crw {
-	__u32 res1    :  1;   /* reserved zero */
-	__u32 slct    :  1;   /* solicited */
-	__u32 oflw    :  1;   /* overflow */
-	__u32 chn     :  1;   /* chained */
-	__u32 rsc     :  4;   /* reporting source code */
-	__u32 anc     :  1;   /* ancillary report */
-	__u32 res2    :  1;   /* reserved zero */
-	__u32 erc     :  6;   /* error-recovery code */
-	__u32 rsid    : 16;   /* reporting-source ID */
-} __attribute__ ((packed)) crw_t;
-
-#define CRW_RSC_MONITOR  0x2  /* monitoring facility */
-#define CRW_RSC_SCH      0x3  /* subchannel */
-#define CRW_RSC_CPATH    0x4  /* channel path */
-#define CRW_RSC_CONFIG   0x9  /* configuration-alert facility */
-#define CRW_RSC_CSS      0xB  /* channel subsystem */
-
-#define CRW_ERC_EVENT    0x00 /* event information pending */
-#define CRW_ERC_AVAIL    0x01 /* available */
-#define CRW_ERC_INIT     0x02 /* initialized */
-#define CRW_ERC_TERROR   0x03 /* temporary error */
-#define CRW_ERC_IPARM    0x04 /* installed parm initialized */
-#define CRW_ERC_TERM     0x05 /* terminal */
-#define CRW_ERC_PERRN    0x06 /* perm. error, fac. not init */
-#define CRW_ERC_PERRI    0x07 /* perm. error, facility init */
-#define CRW_ERC_PMOD     0x08 /* installed parameters modified */
-
-#define MAX_CRW_PENDING  1024
-#define MAX_MACH_PENDING 1024
-
-//
-// CRW Entry
-//
-typedef struct _crwe {
-	crw_t   crw;
-	struct _crwe *crwe_next;
-} __attribute__ ((packed)) crwe_t;
-
-typedef struct _mache {
-	spinlock_t     lock;
-	unsigned int   status;
-	mcic_t         mcic;
-	union _mc {
-	   crwe_t     *crwe;		/* CRW if applicable */
-   } mc;
-	struct _mache *next;
-	struct _mache *prev;
-} mache_t;
-
-#define MCHCHK_STATUS_TO_PROCESS    0x00000001
-#define MCHCHK_STATUS_IN_PROGRESS   0x00000002
-#define MCHCHK_STATUS_WAITING       0x00000004
-
-void s390_init_machine_check( void );
-void s390_do_machine_check  ( void );
-void s390_do_crw_pending    ( crwe_t *pcrwe );
-
-extern __inline__ int stcrw( __u32 *pcrw )
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "STCRW 0(%1)\n\t"
-                "IPM %0\n\t"
-                "SRL %0,28\n\t"
-                : "=d" (ccode) : "a" (pcrw)
-                : "cc", "1" );
-        return ccode;
-}
-
-#endif /* __s390mach */
diff -Nru a/include/asm-s390/setup.h b/include/asm-s390/setup.h
--- a/include/asm-s390/setup.h	Mon Dec  9 18:46:51 2002
+++ b/include/asm-s390/setup.h	Mon Dec  9 18:46:51 2002
@@ -38,6 +38,7 @@
  */
 extern unsigned int console_mode;
 extern unsigned int console_device;
+extern unsigned int console_irq;
 
 #define CONSOLE_IS_UNDEFINED	(console_mode == 0)
 #define CONSOLE_IS_SCLP		(console_mode == 1)
diff -Nru a/include/asm-s390x/ccwdev.h b/include/asm-s390x/ccwdev.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-s390x/ccwdev.h	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,185 @@
+/*
+ *  include/asm-s390/ccwdev.h
+ *  include/asm-s390x/ccwdev.h
+ *
+ *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Author(s): Arnd Bergmann <arndb@de.ibm.com>
+ *
+ *  Interface for CCW device drivers
+ */
+#ifndef _S390_CCWDEV_H_
+#define _S390_CCWDEV_H_
+
+#include <linux/device.h>
+
+/* structs from asm/cio.h */
+struct irb;
+struct ccw1;
+
+/* the id is used to identify what hardware a device driver supports. It 
+ * is used both by the ccw subsystem driver for probing and from
+ * user space for automatic module loading.
+ *
+ * References:
+ *   - struct usb_device_id (include/linux/usb.h)
+ *   - devreg_hc_t (include/linux/s390dyn.h)
+ *   - chandev_model_info (drivers/s390/misc/chandev.c)
+ */
+struct ccw_device_id {
+	__u16	match_flags;	/* which fields to match against */
+
+	__u16	cu_type;	/* control unit type     */
+	__u16	dev_type;	/* device type           */
+	__u8	cu_model;	/* control unit model    */
+	__u8	dev_model;	/* device model          */
+
+	unsigned long driver_info;
+};
+
+enum match_flag {
+	CCW_DEVICE_ID_MATCH_CU_TYPE      = 0x01,
+	CCW_DEVICE_ID_MATCH_CU_MODEL     = 0x02,
+	CCW_DEVICE_ID_MATCH_DEVICE_TYPE  = 0x04,
+	CCW_DEVICE_ID_MATCH_DEVICE_MODEL = 0x08,
+	/* CCW_DEVICE_ID_MATCH_ANY	     = 0x10, */
+};
+
+/* simplified initializers for struct ccw_device:
+ * CCW_DEVICE and CCW_DEVICE_DEVTYPE initialize one
+ * entry in your MODULE_DEVICE_TABLE and set the match_flag correctly */
+#define CCW_DEVICE(cu, cum) 						\
+	.cu_type=(cu), .cu_model=(cum),					\
+	.match_flags=(CCW_DEVICE_ID_MATCH_CU_TYPE			\
+		   | (cum ? CCW_DEVICE_ID_MATCH_CU_MODEL : 0))
+
+#define CCW_DEVICE_DEVTYPE(cu, cum, dev, devm)				\
+	.cu_type=(cu), .cu_model=(cum), .dev_type=(dev), .dev_model=(devm),\
+	.match_flags=CCW_DEVICE_ID_MATCH_CU_TYPE			\
+		   | ((cum) ? CCW_DEVICE_ID_MATCH_CU_MODEL : 0) 	\
+		   | CCW_DEVICE_ID_MATCH_DEVICE_TYPE			\
+		   | ((devm) ? CCW_DEVICE_ID_MATCH_DEVICE_MODEL : 0)
+
+/* scan through an array of device ids and return the first
+ * entry that matches the device.
+ *
+ * the array must end with an entry containing zero match_flags
+ */
+static inline const struct ccw_device_id *
+ccw_device_id_match(const struct ccw_device_id *array,
+			const struct ccw_device_id *match)
+{
+	const struct ccw_device_id *id = array;
+
+	for (id = array; id->match_flags; id++) {
+		if ((id->match_flags & CCW_DEVICE_ID_MATCH_CU_TYPE)
+		    && (id->cu_type != match->cu_type))
+			continue;
+
+		if ((id->match_flags & CCW_DEVICE_ID_MATCH_CU_MODEL)
+		    && (id->cu_model != match->cu_model))
+			continue;
+
+		if ((id->match_flags & CCW_DEVICE_ID_MATCH_DEVICE_TYPE)
+		    && (id->dev_type != match->dev_type))
+			continue;
+
+		if ((id->match_flags & CCW_DEVICE_ID_MATCH_DEVICE_MODEL)
+		    && (id->dev_model != match->dev_model))
+			continue;
+
+		return id;
+	}
+
+	return 0;
+}
+
+/* The struct ccw device is our replacement for the globally accessible
+ * ioinfo array. ioinfo will mutate into a subchannel device later.
+ *
+ * Reference: Documentation/driver-model.txt */
+struct ccw_device {
+	spinlock_t *ccwlock;
+	struct ccw_device_private *private;	/* cio private information */
+	struct ccw_device_id id;	/* id of this device, driver_info is
+					   set by ccw_find_driver */
+	struct ccw_driver *drv;		/* */
+	struct device dev;		/* */
+	int online;
+	/* This is sick, but a driver can have different interrupt handlers 
+	   for different ccw_devices (multi-subchannel drivers)... */
+	void (*handler) (struct ccw_device *, unsigned long, struct irb *);
+};
+
+
+/* Each ccw driver registers with the ccw root bus */
+struct ccw_driver {
+	struct module *owner;		/* for automatic MOD_INC_USE_COUNT   */
+	struct ccw_device_id *ids;	/* probe driver with these devs      */
+	int (*probe) (struct ccw_device *); /* ask driver to probe dev 	     */
+	int (*remove) (struct ccw_device *);
+					/* device is no longer available     */
+	int (*set_online) (struct ccw_device *);
+	int (*set_offline) (struct ccw_device *);
+	struct device_driver driver;	/* higher level structure, dont init
+					   this from your driver	     */
+	char *name;
+};
+
+extern struct ccw_device *get_ccwdev_by_busid(struct ccw_driver *cdrv,
+					      const char *bus_id);
+
+/* devices drivers call these during module load and unload.
+ * When a driver is registered, its probe method is called
+ * when new devices for its type pop up */
+extern int  ccw_driver_register   (struct ccw_driver *driver);
+extern void ccw_driver_unregister (struct ccw_driver *driver);
+
+struct ccw1;
+
+extern int ccw_device_set_options(struct ccw_device *, unsigned long);
+
+/* Allow for i/o completion notification after primary interrupt status. */
+#define CCWDEV_EARLY_NOTIFICATION	0x0001
+/* Report all interrupt conditions. */
+#define CCWDEV_REPORT_ALL	 	0x0002
+
+/*
+ * ccw_device_start()
+ *
+ *  Start a S/390 channel program. When the interrupt arrives, the
+ *  IRQ handler is called, either immediately, delayed (dev-end missing,
+ *  or sense required) or never (no IRQ handler registered).
+ *  Depending on the action taken, ccw_device_start() returns:  
+ *                           0	     - Success
+ *			     -EBUSY  - Device busy, or status pending
+ *			     -ENODEV - Device not operational
+ *                           -EINVAL - Device invalid for operation
+ */
+extern int ccw_device_start(struct ccw_device *, struct ccw1 *,
+			    unsigned long, __u8, unsigned long);
+extern int ccw_device_resume(struct ccw_device *);
+extern int ccw_device_halt(struct ccw_device *, unsigned long);
+extern int ccw_device_clear(struct ccw_device *, unsigned long);
+
+extern int read_dev_chars(struct ccw_device *cdev, void **buffer, int length);
+extern int read_conf_data(struct ccw_device *cdev, void **buffer, int *length);
+
+extern void ccw_device_set_online(struct ccw_device *cdev);
+extern void ccw_device_set_offline(struct ccw_device *cdev);
+
+
+extern struct ciw *ccw_device_get_ciw(struct ccw_device *, __u32 cmd);
+extern __u8 ccw_device_get_path_mask(struct ccw_device *);
+
+#define get_ccwdev_lock(x) (x)->ccwlock
+
+#define to_ccwdev(n) container_of(n, struct ccw_device, dev)
+#define to_ccwdrv(n) container_of(n, struct ccw_driver, driver)
+
+extern struct ccw_device *ccw_device_probe_console(void);
+
+// FIXME: these have to go
+extern int _ccw_device_get_device_number(struct ccw_device *);
+extern int _ccw_device_get_subchannel_number(struct ccw_device *);
+
+#endif /* _S390_CCWDEV_H_ */
diff -Nru a/include/asm-s390x/ccwgroup.h b/include/asm-s390x/ccwgroup.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-s390x/ccwgroup.h	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,44 @@
+#ifndef S390_CCWGROUP_H
+#define S390_CCWGROUP_H
+
+struct ccw_device;
+struct ccw_driver;
+
+struct ccwgroup_device {
+	unsigned long creator_id;	/* unique number of the driver */
+	enum {
+		CCWGROUP_OFFLINE,
+		CCWGROUP_ONLINE,
+	} state;
+	unsigned int count;		/* number of attached slave devices */
+	struct device	dev;		/* master device		    */
+	struct ccw_device *cdev[0];	/* variable number, allocate as needed */
+};
+
+struct ccwgroup_driver {
+	char *name;
+	int max_slaves;
+	unsigned long driver_id;
+
+	int (*probe) (struct ccwgroup_device *);
+	int (*remove) (struct ccwgroup_device *);
+	int (*release) (struct ccwgroup_driver *);
+	int (*set_online) (struct ccwgroup_device *);
+	int (*set_offline) (struct ccwgroup_device *);
+
+	struct device_driver driver;		/* this driver */
+};
+
+extern int  ccwgroup_driver_register   (struct ccwgroup_driver *cdriver);
+extern void ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver);
+extern int ccwgroup_create_dev (struct device *root,
+				unsigned int creator_id,
+				struct ccw_driver *gdrv,
+				int argc, char *argv[]);
+
+extern int ccwgroup_probe_ccwdev(struct ccw_device *cdev);
+extern int ccwgroup_remove_ccwdev(struct ccw_device *cdev);
+
+#define to_ccwgroupdev(x) container_of((x), struct ccwgroup_device, dev)
+#define to_ccwgroupdrv(x) container_of((x), struct ccwgroup_driver, driver)
+#endif
diff -Nru a/include/asm-s390x/chandev.h b/include/asm-s390x/chandev.h
--- a/include/asm-s390x/chandev.h	Mon Dec  9 18:46:34 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,237 +0,0 @@
-/*
- *  include/asm-s390/chandev.h
- *
- *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
- * 
- *  Generic channel device initialisation support. 
- */
-#ifndef __S390_CHANDEV_H
-#define __S390_CHANDEV_H
-#include <linux/version.h>
-#include <asm/types.h>
-#include <linux/netdevice.h>
-
-
-/* Setting this flag to true causes a device name to be built based on the read_devno of the device */
-/* this is exported so external code can look at this flags setting */
-extern int chandev_use_devno_names;
-
-
-/* chandev_type is a bitmask for registering & describing device types. */
-typedef enum
-{
-	chandev_type_none=0x0,
-	chandev_type_ctc=0x1,
-	chandev_type_escon=0x2,
-	chandev_type_lcs=0x4,
-	chandev_type_osad=0x8,
-	chandev_type_qeth=0x10,
-	chandev_type_claw=0x20,
-} chandev_type;
-
-typedef enum
-{
-	chandev_category_none,
-	chandev_category_network_device,
-	chandev_category_serial_device,
-} chandev_category;
-
-
-
-typedef struct
-{
-	int     irq;
-	u16     devno;
-	u16     cu_type;      /* control unit type */
-	u8      cu_model;     /* control unit model */
-	u16     dev_type;     /* device type */
-	u8      dev_model;    /* device model */
-	u8      pim;          /* path installed mask */
-	u8      chpid[8];     /* CHPID 0-7 (if available) */
-} chandev_subchannel_info;
-
-#define CLAW_NAMELEN 9
-/* CLAW specific parameters other drivers should ignore these fields */
-typedef struct
-{
-	
-	char	 host_name[CLAW_NAMELEN];    /* local host name */
-	char	 adapter_name[CLAW_NAMELEN]; /* workstation adapter name */
-	char	 api_type[CLAW_NAMELEN];     /* API type either TCPIP or API */
-} chandev_claw_info;
-
-/*
- * The chandev_probeinfo structure is passed to the device driver with configuration
- * info for which irq's & ports to use when attempting to probe the device.
- */
-typedef struct
-{
-	chandev_subchannel_info read;
-	chandev_subchannel_info write;
-	chandev_subchannel_info data;
-	/* memory_usage_in_k is the suggested memory the driver should attempt to use for io */
-	/* buffers -1 means use the driver default the driver should set this field to the */
-	/* amount of memory it actually uses when returning this probeinfo to the channel */
-	/* device layer with chandev_initdevice */
-	s32     memory_usage_in_k;
-	chandev_claw_info       claw;
-	u8      data_exists; /* whether this device has a data channel */
-	u8      cu_dev_info_inconsistent; /* either ctc or we possibly had a bad sense_id */
-	u8      chpid_info_inconsistent;  /* either ctc or schib info bad */
-        s16     port_protocol_no; /* 0 by default, set specifically when forcing */
-	u8      hint_port_no;   /* lcs specific */
-	u8      max_port_no;    /* lcs/qeth specific */
-	chandev_type chan_type;
-	u8      checksum_received_ip_pkts;
-	u8      use_hw_stats; /* where available e.g. lcs */
-	u8      device_forced; /* indicates the device hasn't been autodetected */
-	char    *parmstr;       /* driver specific parameters added by add_parms keyword */
-	/* newdevice used internally by chandev.c */
-	struct  chandev_activelist *newdevice; 
-	s32     devif_num; 
-/* devif_num=-1 implies don't care,0 implies tr0, info used by chandev_initnetdevice */
-} chandev_probeinfo;
-
-/*
- * This is a wrapper to the machine check handler & should be used
- * instead of reqest_irq or s390_request_irq_special for anything
- * using the channel device layer.
- */
-int chandev_request_irq(unsigned int   irq,
-                      void           (*handler)(int, void *, struct pt_regs *),
-                      unsigned long  irqflags,
-                      const char    *devname,
-                      void          *dev_id);
-/*
- * I originally believed this function wouldn't be necessary
- * I subsequently found that reprobing failed in certain cases :-(,
- * It is just a wrapper for free irq.
- */
-void chandev_free_irq(unsigned int irq, void *dev_id);
-
-typedef enum
-{
-	chandev_status_good,
-	chandev_status_not_oper,
-	chandev_status_first_msck=chandev_status_not_oper,
-	chandev_status_no_path,
-	chandev_status_revalidate,
-	chandev_status_gone,
-	chandev_status_last_msck,
-	chandev_status_all_chans_good /* pseudo machine check to indicate all channels are healthy */
-} chandev_msck_status;
-
-typedef int (*chandev_probefunc)(chandev_probeinfo *probeinfo);
-typedef int (*chandev_shutdownfunc)(void *device);
-typedef void (*chandev_unregfunc)(void *device);
-typedef void (*chandev_msck_notification_func)(void *device,int msck_irq,
-chandev_msck_status prevstatus,chandev_msck_status newstatus);
-
-
-
-/* A driver should call chandev_register_and_probe when ready to be probed,
- * after registeration the drivers probefunction will be called asynchronously
- * when more devices become available at normal task time.
- * The shutdownfunc parameter is used so that the channel layer
- * can request a driver to close unregister itself & release its interrupts.
- * repoper func is used when a device becomes operational again after being temporarily
- * not operational the previous status is sent in the prevstatus variable.
- * This can be used in cases when the default handling isn't quite adequete
- * e.g. if a ssch is needed to reinitialize long running channel programs.
- *
- * This returns the number of devices found or -ENOMEM if the code didn't
- * have enough memory to allocate the chandev control block
- * or -EPERM if a duplicate entry is found.
- */
-int chandev_register_and_probe(chandev_probefunc probefunc,
-			       chandev_shutdownfunc shutdownfunc,
-			       chandev_msck_notification_func msck_notfunc,
-			       chandev_type chan_type);
-
-/* The chandev_unregister function is typically called when a module is being removed 
- * from the system. The shutdown parameter if TRUE calls shutdownfunc for each 
- * device instance so the driver writer doesn't have to.
- */
-void chandev_unregister(chandev_probefunc probefunc,int call_shutdown);
-
-/* chandev_initdevice should be called immeadiately before returning after */
-/* a successful probe. */
-int chandev_initdevice(chandev_probeinfo *probeinfo,void *dev_ptr,u8 port_no,char *devname,
-chandev_category category,chandev_unregfunc unreg_dev);
-
-/* This function builds a device name & copies it into destnamebuff suitable for calling 
-   init_trdev or whatever & it honours the use_devno_names flag, it is used by chandev_initnetdevice 
-   setting the buildfullname flag to TRUE will cause it to always build a full unique name based 
-   on basename either honouring the chandev_use_devno_names flag if set or starting at index 
-   0 & checking the namespace of the channel device layer itself for a free index, this
-   may be useful when one doesn't have control of the name an upper layer may choose.
-   It returns NULL on error.
-*/
-char *chandev_build_device_name(chandev_probeinfo *probeinfo,char *destnamebuff,char *basename,int buildfullname);
-
-
-
-
-/* chandev_init_netdev registers with the normal network device layer */
-/* it doesn't update any of the chandev internal structures. */
-/* i.e. it is optional */
-/* it was part of chandev_initnetdevice but I separated it as */
-/* chandev_initnetdevice may make too many assumptions for some users */
-/* chandev_initnetdevice = chandev_initdevice followed by chandev_init_netdev */
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-struct net_device *chandev_init_netdev(chandev_probeinfo *probeinfo,char *basename,
-struct net_device *dev, int sizeof_priv,struct net_device *(*init_netdevfunc)(struct net_device *dev, int sizeof_priv));
-#else
-struct device *chandev_init_netdev(chandev_probeinfo *probeinfo,char *basename,
-struct device *dev, int sizeof_priv,struct device *(*init_netdevfunc)(struct device *dev, int sizeof_priv));
-#endif
-
-/* chandev_initnetdevice registers a network device with the channel layer. 
- * It returns the device structure if successful,if dev=NULL it kmallocs it, 
- * On device initialisation failure it will kfree it under ALL curcumstances
- * i.e. if dev is not NULL on entering this routine it MUST be malloced with kmalloc. 
- * The base name is tr ( e.g. tr0 without the 0 ), for token ring eth for ethernet,
- *  ctc or escon for ctc device drivers.
- * If valid function pointers are given they will be called to setup,
- * register & unregister the device. 
- * An example of setup is eth_setup in drivers/net/net_init.c.
- * An example of init_dev is init_trdev(struct net_device *dev)
- * & an example of unregister is unregister_trdev, 
- * unregister_netdev should be used for escon & ctc
- * as there is no network unregister_ctcdev in the kernel.
-*/
-
-#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
-struct net_device *chandev_initnetdevice(chandev_probeinfo *probeinfo,u8 port_no,
-					 struct net_device *dev,int sizeof_priv, 
-					 char *basename, 
-					 struct net_device *(*init_netdevfunc)
-					 (struct net_device *dev, int sizeof_priv),
-					 void (*unreg_netdevfunc)(struct net_device *dev));
-#else
-struct device *chandev_initnetdevice(chandev_probeinfo *probeinfo,u8 port_no,
-				     struct device *dev,int sizeof_priv,
-				     char *basename, 
-				     struct device *(*init_netdevfunc)
-				     (struct device *dev, int sizeof_priv),
-				     void (*unreg_netdevfunc)(struct device *dev));
-#endif
-
-/* chandev_add & delete model shouldn't normally be needed by drivers except if */
-/* someone is developing a driver which the channel device layer doesn't know about */
-void chandev_add_model(chandev_type chan_type,s32 cu_type,s16 cu_model,
-		       s32 dev_type,s16 dev_model,u8 max_port_no,int auto_msck_recovery,
-		        u8 default_checksum_received_ip_pkts,u8 default_use_hw_stats);
-void chandev_del_model(s32 cu_type,s16 cu_model,s32 dev_type,s16 dev_model);
-
-/* modules should use chandev_persist to see if they should stay loaded */
-/* this is useful for debugging purposes where you may wish to examine */
-/* /proc/s390dbf/ entries */
-int chandev_persist(chandev_type chan_type);
-#endif /* __S390_CHANDEV_H */
-
-
-
-
-
diff -Nru a/include/asm-s390x/cio.h b/include/asm-s390x/cio.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-s390x/cio.h	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,271 @@
+/*
+ *  include/asm-s390/cio.h
+ *  include/asm-s390x/cio.h
+ *
+ * Common interface for I/O on S/390
+ */
+#ifndef _ASM_S390_CIO_H_
+#define _ASM_S390_CIO_H_
+
+#include <linux/spinlock.h>
+#include <asm/types.h>
+
+#ifdef __KERNEL__
+
+#define LPM_ANYPATH 0xff
+
+/*
+ * subchannel status word
+ */
+struct scsw {
+	__u32 key  : 4;		/* subchannel key */
+	__u32 sctl : 1; 	/* suspend control */
+	__u32 eswf : 1; 	/* ESW format */
+	__u32 cc   : 2; 	/* deferred condition code */
+	__u32 fmt  : 1; 	/* format */
+	__u32 pfch : 1; 	/* prefetch */
+	__u32 isic : 1; 	/* initial-status interruption control */
+	__u32 alcc : 1; 	/* address-limit checking control */
+	__u32 ssi  : 1; 	/* supress-suspended interruption */
+	__u32 zcc  : 1; 	/* zero condition code */
+	__u32 ectl : 1; 	/* extended control */
+	__u32 pno  : 1;	    	/* path not operational */
+	__u32 res  : 1;	    	/* reserved */
+	__u32 fctl : 3;	    	/* function control */
+	__u32 actl : 7;	    	/* activity control */
+	__u32 stctl : 5;    	/* status control */
+	__u32 cpa;	    	/* channel program address */
+	__u32 dstat : 8;    	/* device status */
+	__u32 cstat : 8;    	/* subchannel status */
+	__u32 count : 16;   	/* residual count */
+} __attribute__ ((packed));
+
+#define SCSW_FCTL_CLEAR_FUNC	 0x1
+#define SCSW_FCTL_HALT_FUNC	 0x2
+#define SCSW_FCTL_START_FUNC	 0x4
+
+#define SCSW_ACTL_SUSPENDED	 0x1
+#define SCSW_ACTL_DEVACT	 0x2
+#define SCSW_ACTL_SCHACT	 0x4
+#define SCSW_ACTL_CLEAR_PEND	 0x8
+#define SCSW_ACTL_HALT_PEND	 0x10
+#define SCSW_ACTL_START_PEND	 0x20
+#define SCSW_ACTL_RESUME_PEND	 0x40
+
+#define SCSW_STCTL_STATUS_PEND	 0x1
+#define SCSW_STCTL_SEC_STATUS	 0x2
+#define SCSW_STCTL_PRIM_STATUS	 0x4
+#define SCSW_STCTL_INTER_STATUS	 0x8
+#define SCSW_STCTL_ALERT_STATUS	 0x10
+
+#define DEV_STAT_ATTENTION	 0x80
+#define DEV_STAT_STAT_MOD	 0x40
+#define DEV_STAT_CU_END		 0x20
+#define DEV_STAT_BUSY		 0x10
+#define DEV_STAT_CHN_END	 0x08
+#define DEV_STAT_DEV_END	 0x04
+#define DEV_STAT_UNIT_CHECK	 0x02
+#define DEV_STAT_UNIT_EXCEP	 0x01
+
+#define SCHN_STAT_PCI		 0x80
+#define SCHN_STAT_INCORR_LEN	 0x40
+#define SCHN_STAT_PROG_CHECK	 0x20
+#define SCHN_STAT_PROT_CHECK	 0x10
+#define SCHN_STAT_CHN_DATA_CHK	 0x08
+#define SCHN_STAT_CHN_CTRL_CHK	 0x04
+#define SCHN_STAT_INTF_CTRL_CHK	 0x02
+#define SCHN_STAT_CHAIN_CHECK	 0x01
+
+/*
+ * architectured values for first sense byte
+ */
+#define SNS0_CMD_REJECT		0x80
+#define SNS_CMD_REJECT		SNS0_CMD_REJEC
+#define SNS0_INTERVENTION_REQ	0x40
+#define SNS0_BUS_OUT_CHECK	0x20
+#define SNS0_EQUIPMENT_CHECK	0x10
+#define SNS0_DATA_CHECK		0x08
+#define SNS0_OVERRUN		0x04
+#define SNS0_INCOMPL_DOMAIN	0x01
+
+/*
+ * architectured values for second sense byte
+ */
+#define SNS1_PERM_ERR		0x80
+#define SNS1_INV_TRACK_FORMAT	0x40
+#define SNS1_EOC		0x20
+#define SNS1_MESSAGE_TO_OPER	0x10
+#define SNS1_NO_REC_FOUND	0x08
+#define SNS1_FILE_PROTECTED	0x04
+#define SNS1_WRITE_INHIBITED	0x02
+#define SNS1_INPRECISE_END	0x01
+
+/*
+ * architectured values for third sense byte
+ */
+#define SNS2_REQ_INH_WRITE	0x80
+#define SNS2_CORRECTABLE	0x40
+#define SNS2_FIRST_LOG_ERR	0x20
+#define SNS2_ENV_DATA_PRESENT	0x10
+#define SNS2_INPRECISE_END	0x04
+
+struct ccw1 {
+	__u8  cmd_code;		/* command code */
+	__u8  flags;   		/* flags, like IDA adressing, etc. */
+	__u16 count;   		/* byte count */
+	__u32 cda;     		/* data address */
+} __attribute__ ((packed,aligned(8)));
+
+#define CCW_FLAG_DC		0x80
+#define CCW_FLAG_CC		0x40
+#define CCW_FLAG_SLI		0x20
+#define CCW_FLAG_SKIP		0x10
+#define CCW_FLAG_PCI		0x08
+#define CCW_FLAG_IDA		0x04
+#define CCW_FLAG_SUSPEND	0x02
+
+#define CCW_CMD_READ_IPL	0x02
+#define CCW_CMD_NOOP		0x03
+#define CCW_CMD_BASIC_SENSE	0x04
+#define CCW_CMD_TIC		0x08
+#define CCW_CMD_SENSE_PGID	0x34
+#define CCW_CMD_SUSPEND_RECONN	0x5B
+#define CCW_CMD_RDC		0x64
+#define CCW_CMD_SET_PGID	0xAF
+#define CCW_CMD_SENSE_ID	0xE4
+#define CCW_CMD_DCTL		0xF3
+
+#define SENSE_MAX_COUNT		0x20
+
+struct erw {
+	__u32 res0  : 3;  	/* reserved */
+	__u32 auth  : 1;	/* Authorization check */
+	__u32 pvrf  : 1;  	/* path-verification-required flag */
+	__u32 cpt   : 1;  	/* channel-path timeout */
+	__u32 fsavf : 1;  	/* Failing storage address validity flag */
+	__u32 cons  : 1;  	/* concurrent-sense */
+	__u32 scavf : 1;	/* Secondary ccw address validity flag */
+	__u32 fsaf  : 1;	/* Failing storage address format */
+	__u32 scnt  : 6;  	/* sense count if cons == 1 */
+	__u32 res16 : 16; 	/* reserved */
+} __attribute__ ((packed));
+
+/*
+ * subchannel logout area
+ */
+struct sublog {
+	__u32 res0  : 1;  	/* reserved */
+	__u32 esf   : 7;  	/* extended status flags */
+	__u32 lpum  : 8;  	/* last path used mask */
+	__u32 arep  : 1;  	/* ancillary report */
+	__u32 fvf   : 5;  	/* field-validity flags */
+	__u32 sacc  : 2;  	/* storage access code */
+	__u32 termc : 2;  	/* termination code */
+	__u32 devsc : 1;  	/* device-status check */
+	__u32 serr  : 1;  	/* secondary error */
+	__u32 ioerr : 1;  	/* i/o-error alert */
+	__u32 seqc  : 3;  	/* sequence code */
+} __attribute__ ((packed));
+
+/*
+ * Format 0 Extended Status Word (ESW)
+ */
+struct esw0 {
+	struct sublog sublog;	/* subchannel logout */
+	struct erw erw;	    	/* extended report word */
+	__u32  faddr[2];    	/* failing storage address */
+	__u32  saddr;  		/* secondary ccw address */
+} __attribute__ ((packed));
+
+/*
+ * Format 1 Extended Status Word (ESW)
+ */
+struct esw1 {
+	__u8  zero0;		/* reserved zeros */
+	__u8  lpum;		/* last path used mask */
+	__u16 zero16;		/* reserved zeros */
+	struct erw erw;		/* extended report word */
+	__u32 zeros[3]; 	/* 2 fullwords of zeros */
+} __attribute__ ((packed));
+
+/*
+ * Format 2 Extended Status Word (ESW)
+ */
+struct esw2 {
+	__u8  zero0;		/* reserved zeros */
+	__u8  lpum;		/* last path used mask */
+	__u16 dcti;		/* device-connect-time interval */
+	struct erw erw;		/* extended report word */
+	__u32 zeros[3]; 	/* 2 fullwords of zeros */
+} __attribute__ ((packed));
+
+/*
+ * Format 3 Extended Status Word (ESW)
+ */
+struct esw3 {
+	__u8  zero0;		/* reserved zeros */
+	__u8  lpum;		/* last path used mask */
+	__u16 res;		/* reserved */
+	struct erw erw;		/* extended report word */
+	__u32 zeros[3]; 	/* 2 fullwords of zeros */
+} __attribute__ ((packed));
+
+/*
+ * interruption response block
+ */
+struct irb {
+	struct scsw scsw;	/* subchannel status word */
+	union {			/* extended status word, 4 formats */
+		struct esw0 esw0;
+		struct esw1 esw1;
+		struct esw2 esw2;
+		struct esw3 esw3;
+	} esw;
+	__u8   ecw[32];		/* extended control word */
+} __attribute__ ((packed,aligned(4)));
+
+/*
+ * command information word  (CIW) layout
+ */
+struct ciw {
+	__u32 et       :  2; 	/* entry type */
+	__u32 reserved :  2; 	/* reserved */
+	__u32 ct       :  4; 	/* command type */
+	__u32 cmd      :  8; 	/* command */
+	__u32 count    : 16; 	/* coun */
+} __attribute__ ((packed));
+
+#define CIW_TYPE_RCD	0x0    	/* read configuration data */
+#define CIW_TYPE_SII	0x1    	/* set interface identifier */
+#define CIW_TYPE_RNI	0x2    	/* read node identifier */
+
+/*
+ * Flags used as input parameters for do_IO()
+ */
+#define DOIO_ALLOW_SUSPEND	 0x0001 /* allow for channel prog. suspend */
+#define DOIO_DENY_PREFETCH	 0x0002 /* don't allow for CCW prefetch */
+#define DOIO_SUPPRESS_INTER	 0x0004 /* suppress intermediate inter. */
+					/* ... for suspended CCWs */
+
+struct diag210 {
+	__u16 vrdcdvno : 16;   /* device number (input) */
+	__u16 vrdclen  : 16;   /* data block length (input) */
+	__u32 vrdcvcla : 8;    /* virtual device class (output) */
+	__u32 vrdcvtyp : 8;    /* virtual device type (output) */
+	__u32 vrdcvsta : 8;    /* virtual device status (output) */
+	__u32 vrdcvfla : 8;    /* virtual device flags (output) */
+	__u32 vrdcrccl : 8;    /* real device class (output) */
+	__u32 vrdccrty : 8;    /* real device type (output) */
+	__u32 vrdccrmd : 8;    /* real device model (output) */
+	__u32 vrdccrft : 8;    /* real device feature (output) */
+} __attribute__ ((packed,aligned(4)));
+
+extern int diag210(struct diag210 *addr);
+
+extern int chsc(void *data);
+
+extern void wait_cons_dev(void);
+
+#endif
+
+#endif
diff -Nru a/include/asm-s390x/dasd.h b/include/asm-s390x/dasd.h
--- a/include/asm-s390x/dasd.h	Mon Dec  9 18:46:35 2002
+++ b/include/asm-s390x/dasd.h	Mon Dec  9 18:46:35 2002
@@ -8,6 +8,8 @@
  * any future changes wrt the API will result in a change of the APIVERSION reported
  * to userspace by the DASDAPIVER-ioctl
  *
+ * $Revision: 1.3 $
+ *
  * History of changes (starts July 2000)
  * 05/04/01 created by moving the kernel interface to drivers/s390/block/dasd_int.h
  * 12/06/01 DASD_API_VERSION 2 - binary compatible to 0 (new BIODASDINFO2)
@@ -224,8 +226,6 @@
 #define BIODASDSLCK    _IO(DASD_IOCTL_LETTER,4) /* steal lock */
 /* reset profiling information of a device */
 #define BIODASDPRRST   _IO(DASD_IOCTL_LETTER,5)
-/* enable PAV */
-#define BIODASDENAPAV  _IO(DASD_IOCTL_LETTER,6)
 
 
 /* retrieve API version number */
diff -Nru a/include/asm-s390x/idals.h b/include/asm-s390x/idals.h
--- a/include/asm-s390x/idals.h	Mon Dec  9 18:46:50 2002
+++ b/include/asm-s390x/idals.h	Mon Dec  9 18:46:50 2002
@@ -15,9 +15,17 @@
 
 #include <linux/config.h>
 #include <linux/errno.h>
-#include <asm/irq.h>
+#include <linux/err.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/cio.h>
+#include <asm/uaccess.h>
 
+#ifdef CONFIG_ARCH_S390X
 #define IDA_SIZE_LOG 12 /* 11 for 2k , 12 for 4k */
+#else
+#define IDA_SIZE_LOG 11 /* 11 for 2k , 12 for 4k */
+#endif
 #define IDA_BLOCK_SIZE (1L<<IDA_SIZE_LOG)
 
 /*
@@ -76,7 +84,7 @@
  * If necessary it allocates an IDAL and sets the appropriate flags.
  */
 static inline int
-set_normalized_cda(ccw1_t * ccw, void *vaddr)
+set_normalized_cda(struct ccw1 * ccw, void *vaddr)
 {
 #if defined (CONFIG_ARCH_S390X)
 	unsigned int nridaws;
@@ -103,7 +111,7 @@
  * Releases any allocated IDAL related to the CCW.
  */
 static inline void
-clear_normalized_cda(ccw1_t * ccw)
+clear_normalized_cda(struct ccw1 * ccw)
 {
 #if defined(CONFIG_ARCH_S390X)
 	if (ccw->flags & CCW_FLAG_IDA) {
@@ -112,6 +120,140 @@
 	}
 #endif
 	ccw->cda = 0;
+}
+
+/*
+ * Idal buffer extension
+ */
+struct idal_buffer {
+	size_t size;
+	size_t page_order;
+	void *data[0];
+};
+
+/*
+ * Allocate an idal buffer
+ */
+static inline struct idal_buffer *
+idal_buffer_alloc(size_t size, int page_order)
+{
+	struct idal_buffer *ib;
+	int nr_chunks, nr_ptrs, i;
+
+	nr_ptrs = (size + IDA_BLOCK_SIZE - 1) >> IDA_SIZE_LOG;
+	nr_chunks = (4096 << page_order) >> IDA_SIZE_LOG;
+	ib = kmalloc(sizeof(struct idal_buffer) + nr_ptrs*sizeof(void *),
+		     GFP_DMA | GFP_KERNEL);
+	if (ib == NULL)
+		return ERR_PTR(-ENOMEM);
+	ib->size = size;
+	ib->page_order = page_order;
+	for (i = 0; i < nr_ptrs; i++) {
+		if ((i & (nr_chunks - 1)) != 0) {
+			ib->data[i] = ib->data[i-1] + IDA_BLOCK_SIZE;
+			continue;
+		}
+		ib->data[i] = (void *)
+			__get_free_pages(GFP_KERNEL, page_order);
+		if (ib->data[i] != NULL)
+			continue;
+		// Not enough memory
+		while (i >= nr_chunks) {
+			i -= nr_chunks;
+			free_pages((unsigned long) ib->data[i],
+				   ib->page_order);
+		}
+		kfree(ib);
+		return ERR_PTR(-ENOMEM);
+	}
+	return ib;
+}
+
+/*
+ * Free an idal buffer.
+ */
+static inline void
+idal_buffer_free(struct idal_buffer *ib)
+{
+	int nr_chunks, nr_ptrs, i;
+
+	nr_ptrs = (ib->size + IDA_BLOCK_SIZE - 1) >> IDA_SIZE_LOG;
+	nr_chunks = (4096 << ib->page_order) >> IDA_SIZE_LOG;
+	for (i = 0; i < nr_ptrs; i += nr_chunks)
+		free_pages((unsigned long) ib->data[i], ib->page_order);
+	kfree(ib);
+}
+
+/*
+ * Test if a idal list is really needed.
+ */
+static inline int
+__idal_buffer_is_needed(struct idal_buffer *ib)
+{
+#ifdef CONFIG_ARCH_S390X
+	return ib->size > (4096 << ib->page_order) ||
+		idal_is_needed(ib->data[0], ib->size);
+#else
+	return ib->size > (4096 << ib->page_order);
+#endif
+}
+
+/*
+ * Set channel data address to idal buffer.
+ */
+static inline void
+idal_buffer_set_cda(struct idal_buffer *ib, struct ccw1 *ccw)
+{
+	if (__idal_buffer_is_needed(ib)) {
+		// setup idals;
+		ccw->cda = (u32)(addr_t) ib->data;
+		ccw->flags |= CCW_FLAG_IDA;
+	} else
+		// we do not need idals - use direct addressing
+		ccw->cda = (u32)(addr_t) ib->data[0];
+	ccw->count = ib->size;
+}
+
+/*
+ * Copy count bytes from an idal buffer to user memory
+ */
+static inline size_t
+idal_buffer_to_user(struct idal_buffer *ib, void *to, size_t count)
+{
+	size_t left;
+	int i;
+
+	if (count > ib->size)
+		BUG();
+	for (i = 0; count > IDA_BLOCK_SIZE; i++) {
+		left = copy_to_user(to, ib->data[i], IDA_BLOCK_SIZE);
+		if (left)
+			return left + count - IDA_BLOCK_SIZE;
+		(addr_t) to += IDA_BLOCK_SIZE;
+		count -= IDA_BLOCK_SIZE;
+	}
+	return copy_to_user(to, ib->data[i], count);
+}
+
+/*
+ * Copy count bytes from user memory to an idal buffer
+ */
+static inline size_t
+idal_buffer_from_user(struct idal_buffer *ib, const void *from, size_t count)
+{
+	size_t left;
+	int i;
+
+	if (count > ib->size)
+		BUG();
+	for (i = 0; count > IDA_BLOCK_SIZE; i++) {
+		left = copy_from_user(ib->data[i], from, IDA_BLOCK_SIZE);
+		if (left)
+			return left + count - IDA_BLOCK_SIZE;
+		(addr_t) from += IDA_BLOCK_SIZE;
+		count -= IDA_BLOCK_SIZE;
+	}
+	return copy_from_user(ib->data[i], from, count);
 }
 
 #endif
diff -Nru a/include/asm-s390x/irq.h b/include/asm-s390x/irq.h
--- a/include/asm-s390x/irq.h	Mon Dec  9 18:46:51 2002
+++ b/include/asm-s390x/irq.h	Mon Dec  9 18:46:51 2002
@@ -1,903 +1,26 @@
 #ifndef _ASM_IRQ_H
 #define _ASM_IRQ_H
 
-#include <linux/config.h>
 #ifdef __KERNEL__
 #include <asm/hardirq.h>
 
 /*
- * How many IRQ's for S390 ?!?
- */
-#define __MAX_SUBCHANNELS 65536
-#define NR_IRQS           __MAX_SUBCHANNELS
-#define NR_CHPIDS 256
-
-#define LPM_ANYPATH 0xff /* doesn't really belong here, Ingo? */
-
-#define INVALID_STORAGE_AREA ((void *)(-1 - 0x3FFF ))
-
-/*
- * path management control word
- */
-typedef struct {
-      __u32 intparm;      /* interruption parameter */
-      __u32 qf   : 1;     /* qdio facility */
-      __u32 res0 : 1;     /* reserved zeros */
-      __u32 isc  : 3;     /* interruption sublass */
-      __u32 res5 : 3;     /* reserved zeros */
-      __u32 ena  : 1;     /* enabled */
-      __u32 lm   : 2;     /* limit mode */
-      __u32 mme  : 2;     /* measurement-mode enable */
-      __u32 mp   : 1;     /* multipath mode */
-      __u32 tf   : 1;     /* timing facility */
-      __u32 dnv  : 1;     /* device number valid */
-      __u32 dev  : 16;    /* device number */
-      __u8  lpm;          /* logical path mask */
-      __u8  pnom;         /* path not operational mask */
-      __u8  lpum;         /* last path used mask */
-      __u8  pim;          /* path installed mask */
-      __u16 mbi;          /* measurement-block index */
-      __u8  pom;          /* path operational mask */
-      __u8  pam;          /* path available mask */
-      __u8  chpid[8];     /* CHPID 0-7 (if available) */
-      __u32 unused1 : 8;  /* reserved zeros */
-      __u32 st      : 3;  /* subchannel type */
-      __u32 unused2 : 20; /* reserved zeros */
-      __u32 csense  : 1;  /* concurrent sense; can be enabled ...*/
-                          /*  ... per MSCH, however, if facility */
-                          /*  ... is not installed, this results */
-                          /*  ... in an operand exception.       */
-   } __attribute__ ((packed)) pmcw_t;
-
-#endif /* __KERNEL__ */
-/*
- * subchannel status word
- */
-typedef struct {
-      __u32 key  : 4; /* subchannel key */
-      __u32 sctl : 1; /* suspend control */
-      __u32 eswf : 1; /* ESW format */
-      __u32 cc   : 2; /* deferred condition code */
-      __u32 fmt  : 1; /* format */
-      __u32 pfch : 1; /* prefetch */
-      __u32 isic : 1; /* initial-status interruption control */
-      __u32 alcc : 1; /* address-limit checking control */
-      __u32 ssi  : 1; /* supress-suspended interruption */
-      __u32 zcc  : 1; /* zero condition code */
-      __u32 ectl : 1; /* extended control */
-      __u32 pno  : 1;     /* path not operational */
-      __u32 res  : 1;     /* reserved */
-      __u32 fctl : 3;     /* function control */
-      __u32 actl : 7;     /* activity control */
-      __u32 stctl : 5;    /* status control */
-      __u32 cpa;          /* channel program address */
-      __u32 dstat : 8;    /* device status */
-      __u32 cstat : 8;    /* subchannel status */
-      __u32 count : 16;   /* residual count */
-   } __attribute__ ((packed)) scsw_t;
-
-#define SCSW_FCTL_CLEAR_FUNC     0x1
-#define SCSW_FCTL_HALT_FUNC      0x2
-#define SCSW_FCTL_START_FUNC     0x4
-
-#define SCSW_ACTL_SUSPENDED      0x1
-#define SCSW_ACTL_DEVACT         0x2
-#define SCSW_ACTL_SCHACT         0x4
-#define SCSW_ACTL_CLEAR_PEND     0x8
-#define SCSW_ACTL_HALT_PEND      0x10
-#define SCSW_ACTL_START_PEND     0x20
-#define SCSW_ACTL_RESUME_PEND    0x40
-
-#define SCSW_STCTL_STATUS_PEND   0x1
-#define SCSW_STCTL_SEC_STATUS    0x2
-#define SCSW_STCTL_PRIM_STATUS   0x4
-#define SCSW_STCTL_INTER_STATUS  0x8
-#define SCSW_STCTL_ALERT_STATUS  0x10
-
-#define DEV_STAT_ATTENTION       0x80
-#define DEV_STAT_STAT_MOD        0x40
-#define DEV_STAT_CU_END          0x20
-#define DEV_STAT_BUSY            0x10
-#define DEV_STAT_CHN_END         0x08
-#define DEV_STAT_DEV_END         0x04
-#define DEV_STAT_UNIT_CHECK      0x02
-#define DEV_STAT_UNIT_EXCEP      0x01
-
-#define SCHN_STAT_PCI            0x80
-#define SCHN_STAT_INCORR_LEN     0x40
-#define SCHN_STAT_PROG_CHECK     0x20
-#define SCHN_STAT_PROT_CHECK     0x10
-#define SCHN_STAT_CHN_DATA_CHK   0x08
-#define SCHN_STAT_CHN_CTRL_CHK   0x04
-#define SCHN_STAT_INTF_CTRL_CHK  0x02
-#define SCHN_STAT_CHAIN_CHECK    0x01
-
-/*
- * architectured values for first sense byte
- */
-#define SNS0_CMD_REJECT         0x80
-#define SNS_CMD_REJECT          SNS0_CMD_REJECT
-#define SNS0_INTERVENTION_REQ   0x40
-#define SNS0_BUS_OUT_CHECK      0x20
-#define SNS0_EQUIPMENT_CHECK    0x10
-#define SNS0_DATA_CHECK         0x08
-#define SNS0_OVERRUN            0x04
-/*                              0x02 reserved */
-#define SNS0_INCOMPL_DOMAIN     0x01
-
-/*
- * architectured values for second sense byte
- */
-#define SNS1_PERM_ERR           0x80
-#define SNS1_INV_TRACK_FORMAT   0x40
-#define SNS1_EOC                0x20
-#define SNS1_MESSAGE_TO_OPER    0x10
-#define SNS1_NO_REC_FOUND       0x08
-#define SNS1_FILE_PROTECTED     0x04
-#define SNS1_WRITE_INHIBITED    0x02
-#define SNS1_INPRECISE_END      0x01
-
-/*
- * architectured values for third sense byte
- */
-#define SNS2_REQ_INH_WRITE      0x80
-#define SNS2_CORRECTABLE        0x40
-#define SNS2_FIRST_LOG_ERR      0x20
-#define SNS2_ENV_DATA_PRESENT   0x10
-/*                              0x08 reserved */
-#define SNS2_INPRECISE_END      0x04
-/*                              0x02 reserved */
-/*                              0x01 reserved */
-
-#ifdef __KERNEL__
-/*
- * subchannel information block
- */
-typedef struct {
-      pmcw_t pmcw;             /* path management control word */
-      scsw_t scsw;             /* subchannel status word */
-      __u8 mda[12];            /* model dependent area */
-   } __attribute__ ((packed,aligned(4))) schib_t;
-#endif /* __KERNEL__ */
-
-typedef struct {
-      __u8  cmd_code;/* command code */
-      __u8  flags;   /* flags, like IDA adressing, etc. */
-      __u16 count;   /* byte count */
-      __u32 cda;     /* data address */
-   } __attribute__ ((packed,aligned(8))) ccw1_t;
-
-#define CCW_FLAG_DC             0x80
-#define CCW_FLAG_CC             0x40
-#define CCW_FLAG_SLI            0x20
-#define CCW_FLAG_SKIP           0x10
-#define CCW_FLAG_PCI            0x08
-#define CCW_FLAG_IDA            0x04
-#define CCW_FLAG_SUSPEND        0x02
-
-#define CCW_CMD_READ_IPL        0x02
-#define CCW_CMD_NOOP            0x03
-#define CCW_CMD_BASIC_SENSE     0x04
-#define CCW_CMD_TIC             0x08
-#define CCW_CMD_SENSE_PGID      0x34
-#define CCW_CMD_SUSPEND_RECONN  0x5B
-#define CCW_CMD_RDC             0x64
-#define CCW_CMD_SET_PGID        0xAF
-#define CCW_CMD_SENSE_ID        0xE4
-#define CCW_CMD_DCTL            0xF3
-
-#ifdef __KERNEL__
-#define SENSE_MAX_COUNT         0x20
-
-/*
- * architectured values for first sense byte
- */
-#define SNS0_CMD_REJECT         0x80
-#define SNS_CMD_REJECT          SNS0_CMD_REJECT
-#define SNS0_INTERVENTION_REQ   0x40
-#define SNS0_BUS_OUT_CHECK      0x20
-#define SNS0_EQUIPMENT_CHECK    0x10
-#define SNS0_DATA_CHECK         0x08
-#define SNS0_OVERRUN            0x04
-
-/*
- * operation request block
- */
-typedef struct {
-      __u32 intparm;  /* interruption parameter */
-      __u32 key  : 4; /* flags, like key, suspend control, etc. */
-      __u32 spnd : 1; /* suspend control */
-      __u32 res1 : 1; /* reserved */
-      __u32 mod  : 1; /* modification control */
-      __u32 sync : 1; /* synchronize control */
-      __u32 fmt  : 1; /* format control */
-      __u32 pfch : 1; /* prefetch control */
-      __u32 isic : 1; /* initial-status-interruption control */
-      __u32 alcc : 1; /* address-limit-checking control */
-      __u32 ssic : 1; /* suppress-suspended-interr. control */
-      __u32 res2 : 1; /* reserved */
-      __u32 c64  : 1; /* IDAW/QDIO 64 bit control  */
-      __u32 i2k  : 1; /* IDAW 2/4kB block size control */
-      __u32 lpm  : 8; /* logical path mask */
-      __u32 ils  : 1; /* incorrect length */
-      __u32 zero : 6; /* reserved zeros */
-      __u32 orbx : 1; /* ORB extension control */
-      __u32 cpa;      /* channel program address */
-   }  __attribute__ ((packed,aligned(4))) orb_t;
-
-#endif /* __KERNEL__ */
-typedef struct {
-      __u32 res0  : 4;  /* reserved */
-      __u32 pvrf  : 1;  /* path-verification-required flag */
-      __u32 cpt   : 1;  /* channel-path timeout */
-      __u32 fsavf : 1;  /* Failing storage address validity flag */
-      __u32 cons  : 1;  /* concurrent-sense */
-      __u32 res8  : 2;  /* reserved */
-      __u32 scnt  : 6;  /* sense count if cons == 1 */
-      __u32 res16 : 16; /* reserved */
-   } __attribute__ ((packed)) erw_t;
-
-/*
- * subchannel logout area
- */
-typedef struct {
-      __u32 res0  : 1;  /* reserved */
-      __u32 esf   : 7;  /* extended status flags */
-      __u32 lpum  : 8;  /* last path used mask */
-      __u32 res16 : 1;  /* reserved */
-      __u32 fvf   : 5;  /* field-validity flags */
-      __u32 sacc  : 2;  /* storage access code */
-      __u32 termc : 2;  /* termination code */
-      __u32 devsc : 1;  /* device-status check */
-      __u32 serr  : 1;  /* secondary error */
-      __u32 ioerr : 1;  /* i/o-error alert */
-      __u32 seqc  : 3;  /* sequence code */
-   } __attribute__ ((packed)) sublog_t ;
-
-/*
- * Format 0 Extended Status Word (ESW)
- */
-typedef struct {
-      sublog_t sublog;    /* subchannel logout */
-      erw_t    erw;       /* extended report word */
-      __u32    faddr;     /* failing address */
-      __u32    zeros[2];  /* 2 fullwords of zeros */
-   } __attribute__ ((packed)) esw0_t;
-
-/*
- * Format 1 Extended Status Word (ESW)
- */
-typedef struct {
-      __u8  zero0;    /* reserved zeros */
-      __u8  lpum;     /* last path used mask */
-      __u16 zero16;   /* reserved zeros */
-      erw_t erw;      /* extended report word */
-      __u32 zeros[3]; /* 2 fullwords of zeros */
-   } __attribute__ ((packed)) esw1_t;
-
-/*
- * Format 2 Extended Status Word (ESW)
- */
-typedef struct {
-      __u8  zero0;    /* reserved zeros */
-      __u8  lpum;     /* last path used mask */
-      __u16 dcti;     /* device-connect-time interval */
-      erw_t erw;      /* extended report word */
-      __u32 zeros[3]; /* 2 fullwords of zeros */
-   } __attribute__ ((packed)) esw2_t;
-
-/*
- * Format 3 Extended Status Word (ESW)
- */
-typedef struct {
-      __u8  zero0;    /* reserved zeros */
-      __u8  lpum;     /* last path used mask */
-      __u16 res;      /* reserved */
-      erw_t erw;      /* extended report word */
-      __u32 zeros[3]; /* 2 fullwords of zeros */
-   } __attribute__ ((packed)) esw3_t;
-
-typedef union {
-      esw0_t esw0;
-      esw1_t esw1;
-      esw2_t esw2;
-      esw3_t esw3;
-   } __attribute__ ((packed)) esw_t;
-
-/*
- * interruption response block
- */
-typedef struct {
-      scsw_t scsw;             /* subchannel status word */
-      esw_t  esw;              /* extended status word */
-      __u8   ecw[32];          /* extended control word */
-   } __attribute__ ((packed,aligned(4))) irb_t;
-#ifdef __KERNEL__
-
-/*
- * TPI info structure
- */
-typedef struct {
-	__u32 reserved1  : 16;   /* reserved 0x00000001 */
-	__u32 irq        : 16;   /* aka. subchannel number */
-	__u32 intparm;           /* interruption parameter */
-	__u32 adapter_IO : 1;
-	__u32 reserved2  : 1;
-	__u32 isc        : 3;
-	__u32 reserved3  : 12;
-	__u32 int_type   : 3;
-	__u32 reserved4  : 12;
-   } __attribute__ ((packed)) tpi_info_t;
-
-
-//
-// command information word  (CIW) layout
-//
-typedef struct _ciw {
-   __u32        et       :  2; // entry type
-   __u32        reserved :  2; // reserved
-   __u32        ct       :  4; // command type
-   __u32        cmd      :  8; // command
-   __u32        count    : 16; // count
-   } __attribute__ ((packed)) ciw_t;
-
-#define CIW_TYPE_RCD    0x0    // read configuration data
-#define CIW_TYPE_SII    0x1    // set interface identifier
-#define CIW_TYPE_RNI    0x2    // read node identifier
-
-#define MAX_CIWS 8
-//
-// sense-id response buffer layout
-//
-typedef struct {
-  /* common part */
-      __u8           reserved;     /* always 0x'FF' */
-      __u16          cu_type;      /* control unit type */
-      __u8           cu_model;     /* control unit model */
-      __u16          dev_type;     /* device type */
-      __u8           dev_model;    /* device model */
-      __u8           unused;       /* padding byte */
-  /* extended part */
-      ciw_t    ciw[MAX_CIWS];      /* variable # of CIWs */
-   }  __attribute__ ((packed,aligned(4))) senseid_t;
-/*
- * where we put the ssd info
- */
-typedef struct _ssd_info {
-	__u8   valid:1;
-	__u8   type:7;          /* subchannel type */
-	__u8   chpid[8];        /* chpids */
-	__u16  fla[8];          /* full link addresses */
-} __attribute__ ((packed)) ssd_info_t;
-
-/*
- * area for store event information
- */
-typedef struct chsc_area_t {
-	struct {
-		/* word 0 */
-		__u16 command_code1;
-		__u16 command_code2;
-		union {
-			struct {
-				/* word 1 */
-				__u32 reserved1;
-				/* word 2 */
-				__u32 reserved2;
-			} __attribute__ ((packed,aligned(8))) sei_req;
-			struct {
-				/* word 1 */
-				__u16 reserved1;
-				__u16 f_sch;     /* first subchannel */
-				/* word 2 */
-				__u16 reserved2;
-				__u16 l_sch;    /* last subchannel */
-			} __attribute__ ((packed,aligned(8))) ssd_req;
-		} request_block_data;
-		/* word 3 */
-		__u32 reserved3;
-	} __attribute__ ((packed,aligned(8))) request_block;
-	struct {
-		/* word 0 */
-		__u16 length;
-		__u16 response_code;
-		/* word 1 */
-		__u32 reserved1;
-		union {
-			struct {
-				/* word 2 */
-				__u8  flags;
-				__u8  vf;         /* validity flags */
-				__u8  rs;         /* reporting source */
-				__u8  cc;         /* content code */
-				/* word 3 */
-				__u16 fla;        /* full link address */
-				__u16 rsid;       /* reporting source id */
-				/* word 4 */
-				__u32 reserved2;
-				/* word 5 */
-				__u32 reserved3;
-				/* word 6 */
-				__u32 ccdf;       /* content-code dependent field */
-				/* word 7 */
-				__u32 reserved4;
-				/* word 8 */
-				__u32 reserved5;
-				/* word 9 */
-				__u32 reserved6;
-			} __attribute__ ((packed,aligned(8))) sei_res;
-			struct {
-				/* word 2 */
-				__u8 sch_valid : 1;
-				__u8 dev_valid : 1;
-				__u8 st        : 3; /* subchannel type */
-				__u8 zeroes    : 3;
-				__u8  unit_addr;  /* unit address */
-				__u16 devno;      /* device number */
-				/* word 3 */
-				__u8 path_mask;  
-				__u8 fla_valid_mask;
-				__u16 sch;        /* subchannel */
-				/* words 4-5 */
-				__u8 chpid[8];    /* chpids 0-7 */
-				/* words 6-9 */
-				__u16 fla[8];     /* full link addresses 0-7 */
-			} __attribute__ ((packed,aligned(8))) ssd_res;
-		} response_block_data;
-	} __attribute__ ((packed,aligned(8))) response_block;
-} __attribute__ ((packed,aligned(PAGE_SIZE))) chsc_area_t;
-
-#endif /* __KERNEL__ */
-/*
- * sense data
- */
-typedef struct {
-      __u8          res[32];   /* reserved   */
-      __u8          data[32];  /* sense data */
-   } __attribute__ ((packed)) sense_t;
-
-/*
- * device status area, to be provided by the device driver
- *  when calling request_irq() as parameter "dev_id", later
- *  tied to the "action" control block.
- *
- * Note : No data area must be added after union ii or the
- *         effective devstat size calculation will fail !
- */
-typedef struct {
-     __u16         devno;    /* device number, aka. "cuu" from irb */
-     unsigned long intparm;  /* interrupt parameter */
-     __u8          cstat;    /* channel status - accumulated */
-     __u8          dstat;    /* device status - accumulated */
-     __u8          lpum;     /* last path used mask from irb */
-     __u8          unused;   /* not used - reserved */
-     unsigned int  flag;     /* flag : see below */
-     __u32         cpa;      /* CCW address from irb at primary status */
-     __u32         rescnt;   /* res. count from irb at primary status */
-     __u32         scnt;     /* sense count, if DEVSTAT_FLAG_SENSE_AVAIL */
-     union {
-        irb_t   irb;         /* interruption response block */
-        sense_t sense;       /* sense information */
-        } ii;                /* interrupt information */
-  } devstat_t;
-
-#define DEVSTAT_FLAG_SENSE_AVAIL   0x00000001
-#define DEVSTAT_NOT_OPER           0x00000002
-#define DEVSTAT_START_FUNCTION     0x00000004
-#define DEVSTAT_HALT_FUNCTION      0x00000008
-#define DEVSTAT_STATUS_PENDING     0x00000010
-#define DEVSTAT_REVALIDATE         0x00000020
-#define DEVSTAT_DEVICE_GONE        0x00000040
-#define DEVSTAT_DEVICE_OWNED       0x00000080
-#define DEVSTAT_CLEAR_FUNCTION     0x00000100
-#define DEVSTAT_PCI                0x00000200
-#define DEVSTAT_SUSPENDED          0x00000400
-#define DEVSTAT_UNKNOWN_DEV        0x00000800
-#define DEVSTAT_FINAL_STATUS       0x80000000
-
-#define DEVINFO_NOT_OPER           DEVSTAT_NOT_OPER
-#define DEVINFO_UNKNOWN_DEV        DEVSTAT_UNKNOWN_DEV
-#define DEVINFO_DEVICE_OWNED       DEVSTAT_DEVICE_OWNED
-#define DEVINFO_QDIO_CAPABLE       0x40000000
-
-#define INTPARM_STATUS_PENDING     0xFFFFFFFF
-#ifdef __KERNEL__
-
-#define IO_INTERRUPT_TYPE          0 /* I/O interrupt type */
-
-typedef  void (* io_handler_func1_t) ( int             irq,
-                                       devstat_t      *devstat,
-                                       struct pt_regs *rgs);
-
-typedef  void (* io_handler_func_t) ( int             irq,
-                                      void           *devstat,
-                                      struct pt_regs *rgs);
-
-typedef  void ( * not_oper_handler_func_t)( int irq,
-                                            int status );
-
-typedef  int  (* adapter_int_handler_t)( __u32 intparm );
-
-typedef struct {
-	io_handler_func_t         handler;  /* interrupt handler routine */
-	const char               *name;     /* device name */
-	devstat_t                *dev_id;   /* device status block */
-   } irq_desc_t;
-
-typedef struct {
-	__u8  state1    :  2;   /* path state value 1 */
-	__u8  state2    :  2;   /* path state value 2 */
-	__u8  state3    :  1;   /* path state value 3 */
-	__u8  resvd     :  3;   /* reserved */
-	} __attribute__ ((packed)) path_state_t;
-
-typedef struct {
-   union {
-		__u8         fc;   /* SPID function code */
-		path_state_t ps;   /* SNID path state */
-	} inf;
-	__u32 cpu_addr  : 16;   /* CPU address */
-	__u32 cpu_id    : 24;   /* CPU identification */
-	__u32 cpu_model : 16;   /* CPU model */
-	__u32 tod_high;         /* high word TOD clock */
-	} __attribute__ ((packed)) pgid_t;
-
-#define SPID_FUNC_SINGLE_PATH      0x00
-#define SPID_FUNC_MULTI_PATH       0x80
-#define SPID_FUNC_ESTABLISH        0x00
-#define SPID_FUNC_RESIGN           0x40
-#define SPID_FUNC_DISBAND          0x20
-
-#define SNID_STATE1_RESET          0
-#define SNID_STATE1_UNGROUPED      2
-#define SNID_STATE1_GROUPED        3
-
-#define SNID_STATE2_NOT_RESVD      0
-#define SNID_STATE2_RESVD_ELSE     2
-#define SNID_STATE2_RESVD_SELF     3
-
-#define SNID_STATE3_MULTI_PATH     1
-#define SNID_STATE3_SINGLE_PATH    0
-
-/*
- * Flags used as input parameters for do_IO()
- */
-#define DOIO_EARLY_NOTIFICATION  0x0001 /* allow for I/O completion ... */
-                                        /* ... notification after ... */
-                                        /* ... primary interrupt status */
-#define DOIO_RETURN_CHAN_END     DOIO_EARLY_NOTIFICATION
-#define DOIO_VALID_LPM           0x0002 /* LPM input parameter is valid */
-#define DOIO_WAIT_FOR_INTERRUPT  0x0004 /* wait synchronously for interrupt */
-#define DOIO_REPORT_ALL          0x0008 /* report all interrupt conditions */
-#define DOIO_ALLOW_SUSPEND       0x0010 /* allow for channel prog. suspend */
-#define DOIO_DENY_PREFETCH       0x0020 /* don't allow for CCW prefetch */
-#define DOIO_SUPPRESS_INTER      0x0040 /* suppress intermediate inter. */
-                                        /* ... for suspended CCWs */
-#define DOIO_TIMEOUT             0x0080 /* 3 secs. timeout for sync. I/O */
-#define DOIO_DONT_CALL_INTHDLR   0x0100 /* don't call interrupt handler */
-#define DOIO_CANCEL_ON_TIMEOUT   0x0200 /* cancel I/O if it timed out */
-
-/*
- * do_IO()
- *
- *  Start a S/390 channel program. When the interrupt arrives, the
- *  IRQ handler is called, either immediately, delayed (dev-end missing,
- *  or sense required) or never (no IRQ handler registered -
- *  should never occur, as the IRQ (subchannel ID) should be
- *  disabled if no handler is present. Depending on the action
- *  taken, do_IO() returns :  0      - Success
- *                           -EIO    - Status pending
- *                                        see : action->dev_id->cstat
- *                                              action->dev_id->dstat
- *                           -EBUSY  - Device busy
- *                           -ENODEV - Device not operational
- */
-int do_IO( int            irq,          /* IRQ aka. subchannel number */
-           ccw1_t        *cpa,          /* logical channel program address */
-           unsigned long  intparm,      /* interruption parameter */
-           __u8           lpm,          /* logical path mask */
-           unsigned long  flag);        /* flags : see above */
-
-
-void do_crw_pending( void  );	         /* CRW handler */
-
-int resume_IO( int irq);               /* IRQ aka. subchannel number */
-
-int halt_IO( int           irq,         /* IRQ aka. subchannel number */
-             unsigned long intparm,     /* dummy intparm */
-             unsigned long flag);       /* possible DOIO_WAIT_FOR_INTERRUPT */
-
-int clear_IO( int           irq,         /* IRQ aka. subchannel number */
-              unsigned long intparm,     /* dummy intparm */
-              unsigned long flag);       /* possible DOIO_WAIT_FOR_INTERRUPT */
-
-typedef struct {
-     int          irq;                  /* irq, aka. subchannel */
-     __u16        devno;                /* device number */
-     unsigned int status;               /* device status */
-     senseid_t    sid_data;             /* senseID data */
-     } s390_dev_info_t;
-
-int get_dev_info_by_irq  ( int irq, s390_dev_info_t *pdi);
-int get_dev_info_by_devno( __u16 devno, s390_dev_info_t *pdi);
-
-int          get_irq_by_devno( __u16 devno );
-unsigned int get_devno_by_irq( int irq );
-
-int get_irq_first( void );
-int get_irq_next ( int irq );
-
-int read_dev_chars( int irq, void **buffer, int length );
-int read_conf_data( int irq, void **buffer, int *length, __u8 lpm );
-
-int s390_request_irq_special( int                      irq,
-                              io_handler_func_t        io_handler,
-                              not_oper_handler_func_t  not_oper_handler,
-                              unsigned long            irqflags,
-                              const char              *devname,
-                              void                    *dev_id);
-
-extern int s390_request_console_irq (int irq,
-			  void (*handler) (int, void *, struct pt_regs *),
-			  unsigned long irqflags,
-			  const char *devname,
-			  void *dev_id);
-
-extern int set_cons_dev(int irq);
-extern int wait_cons_dev(int irq);
-extern schib_t *s390_get_schib( int irq );
-
-extern int s390_register_adapter_interrupt(adapter_int_handler_t handler);
-extern int s390_unregister_adapter_interrupt(adapter_int_handler_t handler);
-
-/*
- * Some S390 specific IO instructions as inline
- */
-
-extern __inline__ int stsch(int irq, volatile schib_t *addr)
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "   lr    1,%1\n"
-                "   stsch 0(%2)\n"
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode)
-		: "d" (irq | 0x10000), "a" (addr)
-		: "cc", "1" );
-        return ccode;
-}
-
-extern __inline__ int msch(int irq, volatile schib_t *addr)
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "   lr    1,%1\n"
-                "   msch  0(%2)\n"
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode)
-		: "d" (irq | 0x10000L), "a" (addr)
-                : "cc", "1" );
-        return ccode;
-}
-
-extern __inline__ int msch_err(int irq, volatile schib_t *addr)
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "    lr   1,%1\n"
-                "    msch 0(%2)\n"
-                "0:  ipm  %0\n"
-                "    srl  %0,28\n"
-                "1:\n"
-#ifdef CONFIG_ARCH_S390X
-                ".section .fixup,\"ax\"\n"
-                "2:  l    %0,%3\n"
-                "    jg   1b\n"
-                ".previous\n"
-                ".section __ex_table,\"a\"\n"
-                "   .align 8\n"
-                "   .quad 0b,2b\n"
-                ".previous"
-#else
-                ".section .fixup,\"ax\"\n"
-                "2:  l    %0,%3\n"
-                "    bras 1,3f\n"
-                "    .long 1b\n"
-                "3:  l    1,0(1)\n"
-                "    br   1\n"
-                ".previous\n"
-                ".section __ex_table,\"a\"\n"
-                "   .align 4\n"
-                "   .long 0b,2b\n"
-                ".previous"
-#endif
-                : "=d" (ccode)
-                : "d" (irq | 0x10000L), "a" (addr), "i" (__LC_PGM_ILC)
-                : "cc", "1" );
-        return ccode;
-}
-
-extern __inline__ int tsch(int irq, volatile irb_t *addr)
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "   lr    1,%1\n"
-                "   tsch  0(%2)\n"
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode) 
-		: "d" (irq | 0x10000L), "a" (addr)
-                : "cc", "1" );
-        return ccode;
-}
-
-extern __inline__ int tpi( volatile tpi_info_t *addr)
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "   tpi   0(%1)\n"
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode) 
-		: "a" (addr)
-                : "cc", "1" );
-        return ccode;
-}
-
-extern __inline__ int ssch(int irq, volatile orb_t *addr)
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "   lr    1,%1\n"
-                "   ssch  0(%2)\n"
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode) 
-		: "d" (irq | 0x10000L), "a" (addr)
-                : "cc", "1" );
-        return ccode;
-}
-
-extern __inline__ int rsch(int irq)
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "   lr    1,%1\n"
-                "   rsch\n"
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode) 
-		: "d" (irq | 0x10000L)
-                : "cc", "1" );
-        return ccode;
-}
-
-extern __inline__ int csch(int irq)
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "   lr    1,%1\n"
-                "   csch\n"
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode) 
-		: "d" (irq | 0x10000L)
-                : "cc", "1" );
-        return ccode;
-}
-
-extern __inline__ int hsch(int irq)
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "   lr    1,%1\n"
-                "   hsch\n"
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode) 
-		: "d" (irq | 0x10000L)
-                : "cc", "1" );
-        return ccode;
-}
-
-extern __inline__ int xsch(int irq)
-{
-	int ccode;
-	
-	__asm__ __volatile__(
-                "   lr    1,%1\n"
-                "   .insn rre,0xb2760000,%1,0\n"
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode) 
-		: "d" (irq | 0x10000L)
-                : "cc", "1" );
-	return ccode;
-}
-
-extern __inline__ int iac( void)
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "   iac   1\n"
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode) : : "cc", "1" );
-        return ccode;
-}
-
-extern __inline__ int rchp(int chpid)
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "   lr    1,%1\n"
-                "   rchp\n"
-                "   ipm   %0\n"
-                "   srl   %0,28"
-                : "=d" (ccode) 
-		: "d" (chpid)
-                : "cc", "1" );
-        return ccode;
-}
-
-typedef struct {
-     __u16 vrdcdvno : 16;   /* device number (input) */
-     __u16 vrdclen  : 16;   /* data block length (input) */
-     __u32 vrdcvcla : 8;    /* virtual device class (output) */
-     __u32 vrdcvtyp : 8;    /* virtual device type (output) */
-     __u32 vrdcvsta : 8;    /* virtual device status (output) */
-     __u32 vrdcvfla : 8;    /* virtual device flags (output) */
-     __u32 vrdcrccl : 8;    /* real device class (output) */
-     __u32 vrdccrty : 8;    /* real device type (output) */
-     __u32 vrdccrmd : 8;    /* real device model (output) */
-     __u32 vrdccrft : 8;    /* real device feature (output) */
-     } __attribute__ ((packed,aligned(4))) diag210_t;
-
-extern int diag210( diag210_t * addr);
-
-extern __inline__ int chsc( chsc_area_t * chsc_area)
-{
-	int cc;
-	
-	__asm__ __volatile__ (
-	        ".insn	rre,0xb25f0000,%1,0	\n\t"
-		"ipm	%0	\n\t"
-		"srl	%0,28	\n\t"
-		: "=d" (cc) 
-		: "d" (chsc_area) 
-		: "cc" );
-	
-	return cc;
-}
-
-#include <asm/s390io.h>
-
-#define get_irq_lock(irq) &ioinfo[irq]->irq_lock
-
-#define s390irq_spin_lock(irq) \
-        spin_lock(get_irq_lock(irq))
-
-#define s390irq_spin_unlock(irq) \
-        spin_unlock(get_irq_lock(irq))
-
-#define s390irq_spin_lock_irqsave(irq,flags) \
-        spin_lock_irqsave(get_irq_lock(irq), flags)
+ * the definition of irqs has changed in 2.5.46:
+ * NR_IRQS is no longer the number of i/o
+ * interrupts (65536), but rather the number
+ * of interrupt classes (6).
+ */
+
+enum interruption_class {
+	EXTERNAL_INTERRUPT,
+	IO_INTERRUPT,
+	MACHINE_CHECK_INTERRUPT,
+	PROGRAM_INTERRUPT,
+	RESTART_INTERRUPT,
+	SUPERVISOR_CALL,
 
-#define s390irq_spin_unlock_irqrestore(irq,flags) \
-        spin_unlock_irqrestore(get_irq_lock(irq), flags)
+	NR_IRQS,
+};
 
 #define touch_nmi_watchdog() do { } while(0)
 
diff -Nru a/include/asm-s390x/lowcore.h b/include/asm-s390x/lowcore.h
--- a/include/asm-s390x/lowcore.h	Mon Dec  9 18:46:50 2002
+++ b/include/asm-s390x/lowcore.h	Mon Dec  9 18:46:50 2002
@@ -22,8 +22,6 @@
 #define __LC_PGM_NEW_PSW                0x01d0
 #define __LC_MCK_NEW_PSW                0x01e0
 #define __LC_IO_NEW_PSW                 0x01f0
-#define __LC_RETURN_PSW                 0x0200
-#define __LC_SYNC_IO_WORD               0x0210
 #define __LC_EXT_PARAMS                 0x080
 #define __LC_CPU_ADDRESS                0x084
 #define __LC_EXT_INT_CODE               0x086
@@ -38,7 +36,9 @@
 #define __LC_IO_INT_WORD                0x0C0
 #define __LC_MCCK_CODE                  0x0E8
 
-#define __LC_DIAG44_OPCODE		0x214
+#define __LC_RETURN_PSW                 0x200
+#define __LC_IRB			0x210
+#define __LC_DIAG44_OPCODE		0x250
 
 #define __LC_SAVE_AREA                  0xC00
 #define __LC_KERNEL_STACK               0xD40
@@ -121,9 +121,9 @@
 	psw_t        mcck_new_psw;             /* 0x1e0 */
 	psw_t        io_new_psw;               /* 0x1f0 */
         psw_t        return_psw;               /* 0x200 */
-	__u32        sync_io_word;             /* 0x210 */
-	__u32        diag44_opcode;            /* 0x214 */
-        __u8         pad8[0xc00-0x218];        /* 0x218 */
+	__u8	     irb[64];		       /* 0x210 */
+	__u32        diag44_opcode;            /* 0x250 */
+        __u8         pad8[0xc00-0x254];        /* 0x254 */
         /* System info area */
 	__u64        save_area[16];            /* 0xc00 */
         __u8         pad9[0xd40-0xc80];        /* 0xc80 */
@@ -133,7 +133,7 @@
 	__u8         pad10[0xd80-0xd50];       /* 0xd64 */
 	struct       cpuinfo_S390 cpu_data;    /* 0xd80 */
 	__u32        ipl_device;               /* 0xdb8 */
-	__u32        pad11;                    /* 0xdbc was lsw word of ipl_device until a bug was found DJB */
+	__u32        pad11;                    /* 0xdbc */
 	/* entry.S sensitive area end */
 
         /* SMP info area: defined by DJB */
diff -Nru a/include/asm-s390x/qdio.h b/include/asm-s390x/qdio.h
--- a/include/asm-s390x/qdio.h	Mon Dec  9 18:46:37 2002
+++ b/include/asm-s390x/qdio.h	Mon Dec  9 18:46:37 2002
@@ -11,33 +11,19 @@
 #ifndef __QDIO_H__
 #define __QDIO_H__
 
-#define VERSION_QDIO_H "$Revision: 1.48 $"
+#define VERSION_QDIO_H "$Revision: 1.57 $"
 
 /* note, that most of the typedef's are from ingo. */
 
 #include <linux/interrupt.h>
-
-//#define QDIO_DBF_LIKE_HELL
+#include <asm/cio.h>
 
 #define QDIO_NAME "qdio "
 
-#define QDIO_VERBOSE_LEVEL 9
-
 #ifndef CONFIG_ARCH_S390X
 #define QDIO_32_BIT
 #endif /* CONFIG_ARCH_S390X */
 
-#define QDIO_USE_PROCESSING_STATE
-
-#ifdef CONFIG_QDIO_PERF_STATS
-#define QDIO_PERFORMANCE_STATS
-#endif /* CONFIG_QDIO_PERF_STATS */
-
-#define QDIO_MINIMAL_BH_RELIEF_TIME 16
-#define QDIO_TIMER_POLL_VALUE 1
-#define IQDIO_TIMER_POLL_VALUE 1
-
-
 /**** CONSTANTS, that are relied on without using these symbols *****/
 #define QDIO_MAX_QUEUES_PER_IRQ 32 /* used in width of unsigned int */
 /************************ END of CONSTANTS **************************/
@@ -46,195 +32,22 @@
 #define QDIO_MAX_ELEMENTS_PER_BUFFER 16
 #define SBAL_SIZE 256
 
-#define IQDIO_FILL_LEVEL_TO_POLL (QDIO_MAX_BUFFERS_PER_Q*4/3)
-
-#define IQDIO_THININT_ISC 3
-#define IQDIO_DELAY_TARGET 0
-#define QDIO_BUSY_BIT_PATIENCE 2000 /* in microsecs */
-#define IQDIO_GLOBAL_LAPS 2 /* GLOBAL_LAPS are not used as we */
-#define IQDIO_GLOBAL_LAPS_INT 1 /* dont global summary */
-#define IQDIO_LOCAL_LAPS 4
-#define IQDIO_LOCAL_LAPS_INT 1
-#define IQDIO_GLOBAL_SUMMARY_CC_MASK 2
-/*#define IQDIO_IQDC_INT_PARM 0x1234*/
-
-#define QDIO_Q_LAPS 5
-
-#define QDIO_STORAGE_KEY 0
-
-#define L2_CACHELINE_SIZE 256
-#define INDICATORS_PER_CACHELINE (L2_CACHELINE_SIZE/sizeof(__u32))
-
-#define QDIO_PERF "qdio_perf"
-
-/* must be a power of 2 */
-/*#define QDIO_STATS_NUMBER 4
-
-#define QDIO_STATS_CLASSES 2
-#define QDIO_STATS_COUNT_NEEDED 2*/
-
-#define QDIO_NO_USE_COUNT_TIME 10
-#define QDIO_NO_USE_COUNT_TIMEOUT 1000 /* wait for 1 sec on each q before
-					  exiting without having use_count
-					  of the queue to 0 */
-
-#define QDIO_ESTABLISH_TIMEOUT 1000
-#define QDIO_ACTIVATE_TIMEOUT 100
-#define QDIO_CLEANUP_CLEAR_TIMEOUT 20000
-#define QDIO_CLEANUP_HALT_TIMEOUT 10000
-
-#define QDIO_IRQ_BUCKETS 256 /* heavy..., but does only use a few bytes, but
-			      be rather faster in cases of collisions
-			      (if there really is a collision, it is
-			      on every (traditional) interrupt and every
-			      do_QDIO, so we rather are generous */
 #define QDIO_QETH_QFMT 0
 #define QDIO_ZFCP_QFMT 1
 #define QDIO_IQDIO_QFMT 2
 
-#define QDIO_IRQ_STATE_FRESH 0 /* must be 0 -> memset has set it to 0 */
-#define QDIO_IRQ_STATE_INACTIVE 1
-#define QDIO_IRQ_STATE_ESTABLISHED 2
-#define QDIO_IRQ_STATE_ACTIVE 3
-#define QDIO_IRQ_STATE_STOPPED 4
-
-/* used as intparm in do_IO: */
-#define QDIO_DOING_SENSEID 0
-#define QDIO_DOING_ESTABLISH 1
-#define QDIO_DOING_ACTIVATE 2
-#define QDIO_DOING_CLEANUP 3
-
-/************************* DEBUG FACILITY STUFF *********************/
-/* #define QDIO_DBF_LIKE_HELL */
-
-#define QDIO_DBF_HEX(ex,name,level,addr,len) \
-	do { \
-	if (ex) \
-		debug_exception(qdio_dbf_##name,level,(void*)(addr),len); \
-	else \
-		debug_event(qdio_dbf_##name,level,(void*)(addr),len); \
-	} while (0)
-#define QDIO_DBF_TEXT(ex,name,level,text) \
-	do { \
-	if (ex) \
-		debug_text_exception(qdio_dbf_##name,level,text); \
-	else \
-		debug_text_event(qdio_dbf_##name,level,text); \
-	} while (0)
-
-#define QDIO_DBF_HEX0(ex,name,addr,len) QDIO_DBF_HEX(ex,name,0,addr,len)
-#define QDIO_DBF_HEX1(ex,name,addr,len) QDIO_DBF_HEX(ex,name,1,addr,len)
-#define QDIO_DBF_HEX2(ex,name,addr,len) QDIO_DBF_HEX(ex,name,2,addr,len)
-#define QDIO_DBF_HEX3(ex,name,addr,len) QDIO_DBF_HEX(ex,name,3,addr,len)
-#define QDIO_DBF_HEX4(ex,name,addr,len) QDIO_DBF_HEX(ex,name,4,addr,len)
-#define QDIO_DBF_HEX5(ex,name,addr,len) QDIO_DBF_HEX(ex,name,5,addr,len)
-#define QDIO_DBF_HEX6(ex,name,addr,len) QDIO_DBF_HEX(ex,name,6,addr,len)
-#ifdef QDIO_DBF_LIKE_HELL
-#endif /* QDIO_DBF_LIKE_HELL */
-#if 0
-#define QDIO_DBF_HEX0(ex,name,addr,len) do {} while (0)
-#define QDIO_DBF_HEX1(ex,name,addr,len) do {} while (0)
-#define QDIO_DBF_HEX2(ex,name,addr,len) do {} while (0)
-#ifndef QDIO_DBF_LIKE_HELL
-#define QDIO_DBF_HEX3(ex,name,addr,len) do {} while (0)
-#define QDIO_DBF_HEX4(ex,name,addr,len) do {} while (0)
-#define QDIO_DBF_HEX5(ex,name,addr,len) do {} while (0)
-#define QDIO_DBF_HEX6(ex,name,addr,len) do {} while (0)
-#endif /* QDIO_DBF_LIKE_HELL */
-#endif /* 0 */
-
-#define QDIO_DBF_TEXT0(ex,name,text) QDIO_DBF_TEXT(ex,name,0,text)
-#define QDIO_DBF_TEXT1(ex,name,text) QDIO_DBF_TEXT(ex,name,1,text)
-#define QDIO_DBF_TEXT2(ex,name,text) QDIO_DBF_TEXT(ex,name,2,text)
-#define QDIO_DBF_TEXT3(ex,name,text) QDIO_DBF_TEXT(ex,name,3,text)
-#define QDIO_DBF_TEXT4(ex,name,text) QDIO_DBF_TEXT(ex,name,4,text)
-#define QDIO_DBF_TEXT5(ex,name,text) QDIO_DBF_TEXT(ex,name,5,text)
-#define QDIO_DBF_TEXT6(ex,name,text) QDIO_DBF_TEXT(ex,name,6,text)
-#ifdef QDIO_DBF_LIKE_HELL
-#endif /* QDIO_DBF_LIKE_HELL */
-#if 0
-#define QDIO_DBF_TEXT0(ex,name,text) do {} while (0)
-#define QDIO_DBF_TEXT1(ex,name,text) do {} while (0)
-#define QDIO_DBF_TEXT2(ex,name,text) do {} while (0)
-#ifndef QDIO_DBF_LIKE_HELL
-#define QDIO_DBF_TEXT3(ex,name,text) do {} while (0)
-#define QDIO_DBF_TEXT4(ex,name,text) do {} while (0)
-#define QDIO_DBF_TEXT5(ex,name,text) do {} while (0)
-#define QDIO_DBF_TEXT6(ex,name,text) do {} while (0)
-#endif /* QDIO_DBF_LIKE_HELL */
-#endif /* 0 */
-
-#define QDIO_DBF_SETUP_NAME "qdio_setup"
-#define QDIO_DBF_SETUP_LEN 8
-#define QDIO_DBF_SETUP_INDEX 2
-#define QDIO_DBF_SETUP_NR_AREAS 1
-#ifdef QDIO_DBF_LIKE_HELL
-#define QDIO_DBF_SETUP_LEVEL 6
-#else /* QDIO_DBF_LIKE_HELL */
-#define QDIO_DBF_SETUP_LEVEL 2
-#endif /* QDIO_DBF_LIKE_HELL */
-
-#define QDIO_DBF_SBAL_NAME "qdio_labs" /* sbal */
-#define QDIO_DBF_SBAL_LEN 256
-#define QDIO_DBF_SBAL_INDEX 2
-#define QDIO_DBF_SBAL_NR_AREAS 2
-#ifdef QDIO_DBF_LIKE_HELL
-#define QDIO_DBF_SBAL_LEVEL 6
-#else /* QDIO_DBF_LIKE_HELL */
-#define QDIO_DBF_SBAL_LEVEL 2
-#endif /* QDIO_DBF_LIKE_HELL */
-
-#define QDIO_DBF_TRACE_NAME "qdio_trace"
-#define QDIO_DBF_TRACE_LEN 8
-#define QDIO_DBF_TRACE_NR_AREAS 2
-#ifdef QDIO_DBF_LIKE_HELL
-#define QDIO_DBF_TRACE_INDEX 4
-#define QDIO_DBF_TRACE_LEVEL 4 /* -------- could be even more verbose here */
-#else /* QDIO_DBF_LIKE_HELL */
-#define QDIO_DBF_TRACE_INDEX 2
-#define QDIO_DBF_TRACE_LEVEL 2
-#endif /* QDIO_DBF_LIKE_HELL */
-
-#define QDIO_DBF_SENSE_NAME "qdio_sense"
-#define QDIO_DBF_SENSE_LEN 64
-#define QDIO_DBF_SENSE_INDEX 1
-#define QDIO_DBF_SENSE_NR_AREAS 1
-#ifdef QDIO_DBF_LIKE_HELL
-#define QDIO_DBF_SENSE_LEVEL 6
-#else /* QDIO_DBF_LIKE_HELL */
-#define QDIO_DBF_SENSE_LEVEL 2
-#endif /* QDIO_DBF_LIKE_HELL */
-
-#ifdef QDIO_DBF_LIKE_HELL
-#define QDIO_TRACE_QTYPE QDIO_ZFCP_QFMT
-
-#define QDIO_DBF_SLSB_OUT_NAME "qdio_slsb_out"
-#define QDIO_DBF_SLSB_OUT_LEN QDIO_MAX_BUFFERS_PER_Q
-#define QDIO_DBF_SLSB_OUT_INDEX 8
-#define QDIO_DBF_SLSB_OUT_NR_AREAS 1
-#define QDIO_DBF_SLSB_OUT_LEVEL 6
-
-#define QDIO_DBF_SLSB_IN_NAME "qdio_slsb_in"
-#define QDIO_DBF_SLSB_IN_LEN QDIO_MAX_BUFFERS_PER_Q
-#define QDIO_DBF_SLSB_IN_INDEX 8
-#define QDIO_DBF_SLSB_IN_NR_AREAS 1
-#define QDIO_DBF_SLSB_IN_LEVEL 6
-#endif /* QDIO_DBF_LIKE_HELL */
-
-/****************** END OF DEBUG FACILITY STUFF *********************/
-
-typedef struct qdio_buffer_element_t {
+struct qdio_buffer_element{
 	unsigned int flags;
 	unsigned int length;
 #ifdef QDIO_32_BIT
 	void *reserved;
 #endif /* QDIO_32_BIT */
 	void *addr;
-} __attribute__ ((packed,aligned(16))) qdio_buffer_element_t;
+} __attribute__ ((packed,aligned(16)));
 
-typedef struct qdio_buffer_t {
-	volatile qdio_buffer_element_t element[16];
-} __attribute__ ((packed,aligned(256))) qdio_buffer_t;
+struct qdio_buffer{
+	volatile struct qdio_buffer_element element[16];
+} __attribute__ ((packed,aligned(256)));
 
 
 /* params are: irq, status, qdio_error, siga_error,
@@ -263,8 +76,8 @@
 #define QDIO_FLAG_CLEANUP_USING_CLEAR 0x01
 #define QDIO_FLAG_CLEANUP_USING_HALT 0x02
 
-typedef struct qdio_initialize_t {
-	int irq;
+struct qdio_initialize{
+	struct ccw_device *cdev;
 	unsigned char q_format;
 	unsigned char adapter_name[8];
        	unsigned int qib_param_field_format; /*adapter dependent*/
@@ -285,10 +98,10 @@
 	unsigned long flags;
 	void **input_sbal_addr_array; /* addr of n*128 void ptrs */
 	void **output_sbal_addr_array; /* addr of n*128 void ptrs */
-} qdio_initialize_t;
-extern int qdio_initialize(qdio_initialize_t *init_data);
+};
+extern int qdio_initialize(struct qdio_initialize *init_data);
 
-extern int qdio_activate(int irq,int flags);
+extern int qdio_activate(struct ccw_device *,int flags);
 
 #define QDIO_STATE_MUST_USE_OUTB_PCI	0x00000001
 #define QDIO_STATE_INACTIVE 		0x00000002 /* after qdio_cleanup */
@@ -305,47 +118,23 @@
 						     adapter interrupts */
 #define QDIO_FLAG_DONT_SIGA 0x10
 
-extern int do_QDIO(int irq,unsigned int flags, unsigned int queue_number,
+extern int do_QDIO(struct ccw_device*, unsigned int flags, 
+		   unsigned int queue_number,
 		   unsigned int qidx,unsigned int count,
-		   qdio_buffer_t *buffers);
+		   struct qdio_buffer *buffers);
 
-extern int qdio_synchronize(int irq,unsigned int flags,
+extern int qdio_synchronize(struct ccw_device*, unsigned int flags,
 			    unsigned int queue_number);
 
-extern int qdio_cleanup(int irq,int how);
+extern int qdio_cleanup(struct ccw_device*, int how);
 
-unsigned char qdio_get_slsb_state(int irq,unsigned int flag,
+unsigned char qdio_get_slsb_state(struct ccw_device*, unsigned int flag,
 				  unsigned int queue_number,
 				  unsigned int qidx);
 
 extern void qdio_init_scrubber(void);
-/*
- * QDIO device commands returned by extended Sense-ID
- */
-#define DEFAULT_ESTABLISH_QS_CMD 0x1b
-#define DEFAULT_ESTABLISH_QS_COUNT 0x1000
-#define DEFAULT_ACTIVATE_QS_CMD 0x1f
-#define DEFAULT_ACTIVATE_QS_COUNT 0
-typedef struct _qdio_cmds {
-	unsigned char rcd;            /* read configuration data */
-	unsigned short count_rcd;
-	unsigned char sii;            /* set interface identifier */
-	unsigned short count_sii;
-	unsigned char rni;            /* read node identifier */
-	unsigned short count_rni;
-	unsigned char eq;             /* establish QDIO queues */
-	unsigned short count_eq;
-	unsigned char aq;             /* activate QDIO queues */
-	unsigned short count_aq;
-} qdio_cmds_t;
 
-/*
- * additional CIWs returned by extended Sense-ID
- */
-#define CIW_TYPE_EQUEUE 0x3       /* establish QDIO queues */
-#define CIW_TYPE_AQUEUE 0x4       /* activate QDIO queues */
-
-typedef struct _qdesfmt0 {
+struct qdesfmt0 {
 #ifdef QDIO_32_BIT
 	unsigned long res1;             /* reserved */
 #endif /* QDIO_32_BIT */
@@ -365,12 +154,12 @@
 	unsigned int  ckey  :  4;       /* access key for SBALs */
 	unsigned int  dkey  :  4;       /* access key for SLSB */
 	unsigned int  res5  : 16;       /* reserved */
-} __attribute__ ((packed)) qdesfmt0_t;
+} __attribute__ ((packed));
 
 /*
  * Queue-Description record (QDR)
  */
-typedef struct _qdr {
+struct qdr {
 	unsigned int  qfmt    :  8;     /* queue format */
 	unsigned int  pfmt    :  8;     /* impl. dep. parameter format */
 	unsigned int  res1    :  8;     /* reserved */
@@ -392,9 +181,9 @@
 	unsigned int  qkey    :  4;     /* queue-informatio-block key */
 	unsigned int  res9    : 28;     /* reserved */
 /*	union _qd {*/ /* why this? */
-		qdesfmt0_t qdf0[126];
+		struct qdesfmt0 qdf0[126];
 /*	} qd;*/
-} __attribute__ ((packed,aligned(4096))) qdr_t;
+} __attribute__ ((packed,aligned(4096)));
 
 
 /*
@@ -402,7 +191,7 @@
  */
 #define QIB_AC_INBOUND_PCI_SUPPORTED 0x80
 #define QIB_AC_OUTBOUND_PCI_SUPPORTED 0x40
-typedef struct _qib {
+struct qib {
 	unsigned int  qfmt    :  8;     /* queue format */
 	unsigned int  pfmt    :  8;     /* impl. dep. parameter format */
 	unsigned int  res1    :  8;     /* reserved */
@@ -425,24 +214,24 @@
 	unsigned char parm[QDIO_MAX_BUFFERS_PER_Q];
 					/* implementation dependent
 					   parameters */
-} __attribute__ ((packed,aligned(256))) qib_t;
+} __attribute__ ((packed,aligned(256)));
 
 
 /*
  * storage-list-information block element (SLIBE)
  */
-typedef struct _slibe {
+struct slibe {
 #ifdef QDIO_32_BIT
 	unsigned long res;              /* reserved */
 #endif /* QDIO_32_BIT */
 	unsigned long parms;            /* implementation dependent
 					   parameters */
-} slibe_t;
+};
 
 /*
  * storage-list-information block (SLIB)
  */
-typedef struct _slib {
+struct slib {
 #ifdef QDIO_32_BIT
 	unsigned long res1;             /* reserved */
 #endif /* QDIO_32_BIT */
@@ -456,17 +245,17 @@
 #endif /* QDIO_32_BIT */
 	unsigned long slsba;            /* SLSB address */
 	unsigned char res4[1000];       /* reserved */
-	slibe_t       slibe[QDIO_MAX_BUFFERS_PER_Q];    /* SLIB elements */
-} __attribute__ ((packed,aligned(2048))) slib_t;
+	struct slibe slibe[QDIO_MAX_BUFFERS_PER_Q];    /* SLIB elements */
+} __attribute__ ((packed,aligned(2048)));
 
-typedef struct _sbal_flags {
+struct sbal_flags {
 	unsigned char res1  : 1;   /* reserved */
 	unsigned char last  : 1;   /* last entry */
 	unsigned char cont  : 1;   /* contiguous storage */
 	unsigned char res2  : 1;   /* reserved */
 	unsigned char frag  : 2;   /* fragmentation (s.below) */
 	unsigned char res3  : 2;   /* reserved */
-} __attribute__ ((packed)) sbal_flags_t;
+} __attribute__ ((packed));
 
 #define SBAL_FLAGS_FIRST_FRAG	     0x04000000UL
 #define SBAL_FLAGS_MIDDLE_FRAG	     0x08000000UL
@@ -490,92 +279,88 @@
 /* Naught of interest beyond this point */
 
 #define SBAL_FLAGS0_PCI		0x40
-typedef struct _sbal_sbalf_0 {
+struct sbal_sbalf_0 {
 	unsigned char res1  : 1;   /* reserved */
 	unsigned char pci   : 1;   /* PCI indicator */
 	unsigned char cont  : 1;   /* data continuation */
 	unsigned char sbtype: 2;   /* storage-block type (OpenFCP) */
 	unsigned char res2  : 3;   /* reserved */
-} __attribute__ ((packed)) sbal_sbalf_0_t;
+} __attribute__ ((packed));
 
-typedef struct _sbal_sbalf_1 {
+struct sbal_sbalf_1 {
 	unsigned char res1  : 4;   /* reserved */
 	unsigned char key   : 4;   /* storage key */
-} __attribute__ ((packed)) sbal_sbalf_1_t;
+} __attribute__ ((packed));
 
-typedef struct _sbal_sbalf_14 {
+struct sbal_sbalf_14 {
 	unsigned char res1   : 4;  /* reserved */
 	unsigned char erridx : 4;  /* error index */
-} __attribute__ ((packed)) sbal_sbalf_14_t;
+} __attribute__ ((packed));
 
-typedef struct _sbal_sbalf_15 {
+struct sbal_sbalf_15 {
 	unsigned char reason;      /* reserved */
-} __attribute__ ((packed)) sbal_sbalf_15_t;
+} __attribute__ ((packed));
 
-typedef union _sbal_sbalf {
-	sbal_sbalf_0_t  i0;
-	sbal_sbalf_1_t  i1;
-	sbal_sbalf_14_t i14;
-	sbal_sbalf_15_t i15;
+union sbal_sbalf {
+	struct sbal_sbalf_0  i0;
+	struct sbal_sbalf_1  i1;
+	struct sbal_sbalf_14 i14;
+	struct sbal_sbalf_15 i15;
 	unsigned char value;
-} sbal_sbalf_t;
+};
 
-typedef struct _sbale {
+struct sbal_element {
 	union {
-		sbal_flags_t  bits;       /* flags */
+		struct sbal_flags  bits;       /* flags */
 		unsigned char value;
 	} flags;
 	unsigned int  res1  : 16;   /* reserved */
-	sbal_sbalf_t  sbalf;       /* SBAL flags */
+	union sbal_sbalf  sbalf;       /* SBAL flags */
 	unsigned int  res2  : 16;  /* reserved */
 	unsigned int  count : 16;  /* data count */
 #ifdef QDIO_32_BIT
 	unsigned long res3;        /* reserved */
 #endif /* QDIO_32_BIT */
 	unsigned long addr;        /* absolute data address */
-} __attribute__ ((packed,aligned(16))) sbal_element_t;
+} __attribute__ ((packed,aligned(16)));
 
 /*
  * strorage-block access-list (SBAL)
  */
-typedef struct _sbal {
-	sbal_element_t element[QDIO_MAX_ELEMENTS_PER_BUFFER];
-} __attribute__ ((packed,aligned(256))) sbal_t;
+struct sbal {
+	struct sbal_element element[QDIO_MAX_ELEMENTS_PER_BUFFER];
+} __attribute__ ((packed,aligned(256)));
 
 /*
  * storage-list (SL)
  */
-typedef struct _sl_element {
+struct sl_element {
 #ifdef QDIO_32_BIT
         unsigned long res;     /* reserved */
 #endif /* QDIO_32_BIT */
         unsigned long sbal;    /* absolute SBAL address */
-} __attribute__ ((packed)) sl_element_t;
+} __attribute__ ((packed));
 
-typedef struct _sl {
-	sl_element_t element[QDIO_MAX_BUFFERS_PER_Q];
-} __attribute__ ((packed,aligned(1024))) sl_t;
+struct sl {
+	struct sl_element element[QDIO_MAX_BUFFERS_PER_Q];
+} __attribute__ ((packed,aligned(1024)));
 
 /*
  * storage-list-state block (SLSB)
  */
-/*typedef struct _slsb_val {*/
-/*	unsigned char value;       */ /* SLSB entry as a single byte value */
-/*} __attribute__ ((packed)) slsb_val_t;*/
-
-typedef struct _slsb_flags {
+struct slsb_flags {
 	unsigned char owner  : 2;   /* SBAL owner */
 	unsigned char type   : 1;   /* buffer type */
 	unsigned char state  : 5;   /* processing state */
-} __attribute__ ((packed)) slsb_flags_t;
+} __attribute__ ((packed));
 
 
-typedef struct _slsb {
-	union _acc {
+struct slsb {
+	union {
 		unsigned char val[QDIO_MAX_BUFFERS_PER_Q];
-		slsb_flags_t flags[QDIO_MAX_BUFFERS_PER_Q];
+		struct slsb_flags flags[QDIO_MAX_BUFFERS_PER_Q];
 	} acc;
-} __attribute__ ((packed,aligned(256))) slsb_t;
+} __attribute__ ((packed,aligned(256)));
 
 /*
  * SLSB values
@@ -606,327 +391,5 @@
 #define SLSB_P_OUTPUT_ERROR       0xAF
 
 #define SLSB_ERROR_DURING_LOOKUP  0xFF
-/*
- * path management control word (extended layout)
- */
-typedef struct {
-	unsigned long  intparm;      /* interruption parameter */
-	unsigned int   qf   : 1;     /* qdio facility */
-	unsigned int   res0 : 1;     /* reserved */
-	unsigned int   isc  : 3;     /* interruption sublass */
-	unsigned int   res5 : 3;     /* reserved zeros */
-	unsigned int   ena  : 1;     /* enabled */
-	unsigned int   lm   : 2;     /* limit mode */
-	unsigned int   mme  : 2;     /* measurement-mode enable */
-	unsigned int   mp   : 1;     /* multipath mode */
-	unsigned int   tf   : 1;     /* timing facility */
-	unsigned int   dnv  : 1;     /* device number valid */
-	unsigned int   dev  : 16;    /* device number */
-	unsigned char  lpm;          /* logical path mask */
-	unsigned char  pnom;         /* path not operational mask */
-	unsigned char  lpum;         /* last path used mask */
-	unsigned char  pim;          /* path installed mask */
-	unsigned short mbi;          /* measurement-block index */
-	unsigned char  pom;          /* path operational mask */
-	unsigned char  pam;          /* path available mask */
-	unsigned char  chpid[8];     /* CHPID 0-7 (if available) */
-	unsigned int   res1    : 8;  /* reserved */
-	unsigned int   st      : 3;  /* */
-	unsigned int   res2    : 20; /* reserved */
-	unsigned int   csense  : 1;  /* concurrent sense; can be enabled
-					per MSCH, however, if facility
-					is not installed, this results
-					in an operand exception. */
-} pmcw_e_t;
-
-/*
- * subchannel status word (extended layout)
- */
-typedef struct {
-	unsigned int   key  : 4;     /* subchannel key */
-	unsigned int   sctl : 1;     /* suspend control */
-	unsigned int   eswf : 1;     /* ESW format */
-	unsigned int   cc   : 2;     /* deferred condition code */
-	unsigned int   fmt  : 1;     /* format */
-	unsigned int   pfch : 1;     /* prefetch */
-	unsigned int   isic : 1;     /* initial-status interruption control */
-	unsigned int   alcc : 1;     /* address-limit checking control */
-	unsigned int   ssi  : 1;     /* supress-suspended interruption */
-	unsigned int   zcc  : 1;     /* zero condition code */
-	unsigned int   ectl : 1;     /* extended control */
-	unsigned int   pno  : 1;     /* path not operational */
-	unsigned int   qact : 1;     /* qdio active */
-	unsigned int   fctl : 3;     /* function control */
-	unsigned int   actl : 7;     /* activity control */
-	unsigned int   stctl : 5;    /* status control */
-	unsigned long  cpa;          /* channel program address */
-	unsigned int   dstat : 8;    /* device status */
-	unsigned int   cstat : 8;    /* subchannel status */
-	unsigned int   count : 16;   /* residual count */
-} scsw_e_t;
-
-typedef struct qdio_q_t {
-	volatile slsb_t slsb;
-
-	__u32 * volatile dev_st_chg_ind;
-
-	int is_input_q;
-	int is_0copy_sbals_q;
-	int irq;
-
-	unsigned int is_iqdio_q;
-
-	/* bit 0 means queue 0, bit 1 means queue 1, ... */
-	unsigned int mask;
-	unsigned int q_no;
-
-	qdio_handler_t (*handler);
-
-	/* points to the next buffer to be checked for having
-	 * been processed by the card (outbound)
-	 * or to the next buffer the program should check for (inbound) */
-	volatile int first_to_check;
-	/* and the last time it was: */
-	volatile int last_move_ftc;
-
-	atomic_t number_of_buffers_used;
-	atomic_t polling;
-
-	unsigned int siga_in;
-	unsigned int siga_out;
-	unsigned int siga_sync;
-	unsigned int siga_sync_done_on_thinints;
-	unsigned int hydra_gives_outbound_pcis;
-
-	/* used to save beginning position when calling dd_handlers */
-	int first_element_to_kick;
-
-	atomic_t use_count;
-	atomic_t is_in_shutdown;
-
-#ifdef QDIO_USE_TIMERS_FOR_POLLING
-	struct timer_list timer;
-	atomic_t timer_already_set;
-	spinlock_t timer_lock;
-#else /* QDIO_USE_TIMERS_FOR_POLLING */
-	struct tasklet_struct tasklet;
-#endif /* QDIO_USE_TIMERS_FOR_POLLING */
-
-	unsigned int state;
-
-	/* used to store the error condition during a data transfer */
-	unsigned int qdio_error;
-	unsigned int siga_error;
-	unsigned int error_status_flags;
-
-	/* list of interesting queues */
-	volatile struct qdio_q_t *list_next;
-	volatile struct qdio_q_t *list_prev;
-
-	slib_t *slib; /* a page is allocated under this pointer,
-			 sl points into this page, offset PAGE_SIZE/2
-			 (after slib) */
-	sl_t *sl;
-	volatile sbal_t *sbal[QDIO_MAX_BUFFERS_PER_Q];
-
-	qdio_buffer_t *qdio_buffers[QDIO_MAX_BUFFERS_PER_Q];
-
-	unsigned long int_parm;
-
-	/*struct {
-		int in_bh_check_limit;
-		int threshold;
-	} threshold_classes[QDIO_STATS_CLASSES];*/
-
-	struct {
-		/* inbound: the time to stop polling
-		   outbound: the time to kick peer */
-		int threshold; /* the real value */
-
-		/* outbound: last time of do_QDIO
-		   inbound: last time of noticing incoming data */
-		/*__u64 last_transfer_times[QDIO_STATS_NUMBER];
-		int last_transfer_index; */
-
-		__u64 last_transfer_time;
-	} timing;
-        unsigned int queue_type;
-} __attribute__ ((aligned(256))) qdio_q_t;
-
-typedef struct qdio_irq_t {
-	__u32 * volatile dev_st_chg_ind;
-
-	unsigned long int_parm;
-	int irq;
-
-	unsigned int is_iqdio_irq;
-	unsigned int hydra_gives_outbound_pcis;
-	unsigned int sync_done_on_outb_pcis;
-
-	unsigned int state;
-	spinlock_t setting_up_lock;
-
-	unsigned int no_input_qs;
-	unsigned int no_output_qs;
-
-	unsigned char qdioac;
-
-	qdio_q_t *input_qs[QDIO_MAX_QUEUES_PER_IRQ];
-	qdio_q_t *output_qs[QDIO_MAX_QUEUES_PER_IRQ];
-
-	ccw1_t ccw;
-	int io_result_cstat;
-	int io_result_dstat;
-	int io_result_flags;
-	atomic_t interrupt_has_arrived;
-	atomic_t interrupt_has_been_cleaned;
-	wait_queue_head_t wait_q;
-
-	qdr_t *qdr;
-
-	qdio_cmds_t commands;
-
-	qib_t qib;
-
-	io_handler_func_t original_int_handler;
-
-	struct qdio_irq_t *next;
-} qdio_irq_t;
-
-#define QDIO_CHSC_RESPONSE_CODE_OK 1
-/* flags for st qdio sch data */
-#define CHSC_FLAG_QDIO_CAPABILITY 0x80
-#define CHSC_FLAG_VALIDITY 0x40
-
-#define CHSC_FLAG_SIGA_INPUT_NECESSARY 0x40
-#define CHSC_FLAG_SIGA_OUTPUT_NECESSARY 0x20
-#define CHSC_FLAG_SIGA_SYNC_NECESSARY 0x10
-#define CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS 0x08
-#define CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS 0x04
-
-typedef struct qdio_chsc_area_t {
-	struct {
-		/* word 0 */
-		__u16 command_code1;
-		__u16 command_code2;
-		/* word 1 */
-		__u16 operation_code;
-		__u16 first_sch;
-		/* word 2 */
-		__u8 reserved1;
-		__u8 image_id;
-		__u16 last_sch;
-		/* word 3 */
-		__u32 reserved2;
-
-		/* word 4 */
-		union {
-			struct {
-				/* word 4&5 */
-				__u64 summary_indicator_addr;
-				/* word 6&7 */
-				__u64 subchannel_indicator_addr;
-				/* word 8 */
-				int ks:4;
-				int kc:4;
-				int reserved1:21;
-				int isc:3;
-				/* word 9&10 */
-				__u32 reserved2[2];
-				/* word 11 */
-				__u32 subsystem_id;
-				/* word 12-1015 */
-				__u32 reserved3[1004];
-			} __attribute__ ((packed,aligned(4))) set_chsc;
-			struct {
-				/* word 4&5 */
-				__u32 reserved1[2];	
-				/* word 6 */
-				__u32 delay_target;
-				/* word 7-1015 */
-				__u32 reserved4[1009];
-			} __attribute__ ((packed,aligned(4))) set_chsc_fast;
-			struct {
-				/* word 0 */
-				__u16 length;
-				__u16 response_code;
-				/* word 1 */
-				__u32 reserved1;
-				/* words 2 to 9 for st sch qdio data */
-				__u8 flags;
-				__u8 reserved2;
-				__u16 sch;
-				__u8 qfmt;
-				__u8 reserved3;
-				__u8 qdioac;
-				__u8 sch_class;
-				__u8 reserved4;
-				__u8 icnt;
-				__u8 reserved5;
-				__u8 ocnt;
-				/* plus 5 words of reserved fields */
-			} __attribute__ ((packed,aligned(8)))
-			store_qdio_data_response;
-		} operation_data_area;
-	} __attribute__ ((packed,aligned(8))) request_block;
-	struct {
-		/* word 0 */
-		__u16 length;
-		__u16 response_code;
-		/* word 1 */
-		__u32 reserved1;
-	} __attribute__ ((packed,aligned(8))) response_block;
-} __attribute__ ((packed,aligned(PAGE_SIZE))) qdio_chsc_area_t;
-
-
-#define QDIO_PRINTK_HEADER QDIO_NAME ": "
-
-#if QDIO_VERBOSE_LEVEL>8
-#define QDIO_PRINT_STUPID(x...) printk( KERN_DEBUG QDIO_PRINTK_HEADER x)
-#else
-#define QDIO_PRINT_STUPID(x...)
-#endif
-
-#if QDIO_VERBOSE_LEVEL>7
-#define QDIO_PRINT_ALL(x...) printk( QDIO_PRINTK_HEADER x)
-#else
-#define QDIO_PRINT_ALL(x...)
-#endif
-
-#if QDIO_VERBOSE_LEVEL>6
-#define QDIO_PRINT_INFO(x...) printk( QDIO_PRINTK_HEADER x)
-#else
-#define QDIO_PRINT_INFO(x...)
-#endif
-
-#if QDIO_VERBOSE_LEVEL>5
-#define QDIO_PRINT_WARN(x...) printk( QDIO_PRINTK_HEADER x)
-#else
-#define QDIO_PRINT_WARN(x...)
-#endif
-
-#if QDIO_VERBOSE_LEVEL>4
-#define QDIO_PRINT_ERR(x...) printk( QDIO_PRINTK_HEADER x)
-#else
-#define QDIO_PRINT_ERR(x...)
-#endif
-
-#if QDIO_VERBOSE_LEVEL>3
-#define QDIO_PRINT_CRIT(x...) printk( QDIO_PRINTK_HEADER x)
-#else
-#define QDIO_PRINT_CRIT(x...)
-#endif
-
-#if QDIO_VERBOSE_LEVEL>2
-#define QDIO_PRINT_ALERT(x...) printk( QDIO_PRINTK_HEADER x)
-#else
-#define QDIO_PRINT_ALERT(x...)
-#endif
-
-#if QDIO_VERBOSE_LEVEL>1
-#define QDIO_PRINT_EMERG(x...) printk( QDIO_PRINTK_HEADER x)
-#else
-#define QDIO_PRINT_EMERG(x...)
-#endif
 
 #endif /* __QDIO_H__ */
diff -Nru a/include/asm-s390x/s390dyn.h b/include/asm-s390x/s390dyn.h
--- a/include/asm-s390x/s390dyn.h	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,56 +0,0 @@
-/*
- *  arch/s390/kernel/s390dyn.h
- *   S/390 data definitions for dynamic device attachment
- *
- *  S390 version
- *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Ingo Adlung (adlung@de.ibm.com)
- */
-
-#ifndef __s390dyn_h
-#define __s390dyn_h
-
-#ifndef _LINUX_LIST_H
-#include <linux/list.h>
-#endif
-
-struct _devreg;
-
-typedef  int  (* oper_handler_func_t)( int             irq,
-                                       struct _devreg *dreg);
-
-typedef struct _devreg_hc_t {
-	__u16 ctype;
-	__u8  cmode;
-	__u16 dtype;
-	__u8  dmode;
-   }  __attribute__ ((packed)) devreg_hc_t;
-
-typedef struct _devreg {
-	struct list_head list;
-	union {
-		int devno;
-		devreg_hc_t hc;       /* has controller info */
-	} ci;
-
-	int                  flag;
-	oper_handler_func_t  oper_func;
-} devreg_t;
-
-#define DEVREG_MATCH_CU_TYPE    0x00000001
-#define DEVREG_MATCH_CU_MODEL   0x00000002
-#define DEVREG_MATCH_DEV_TYPE   0x00000004
-#define DEVREG_MATCH_DEV_MODEL  0x00000008
-
-#define DEVREG_EXACT_MATCH      (DEVREG_MATCH_CU_TYPE|DEVREG_MATCH_CU_MODEL|DEVREG_MATCH_DEV_TYPE|DEVREG_MATCH_DEV_MODEL)
-#define DEVREG_NO_CU_INFO       (DEVREG_MATCH_DEV_TYPE|DEVREG_MATCH_DEV_MODEL)
-#define DEVREG_NO_DEV_INFO      (DEVREG_MATCH_CU_TYPE|DEVREG_MATCH_CU_MODEL)
-
-#define DEVREG_TYPE_DEVNO       0x80000000
-#define DEVREG_TYPE_DEVCHARS    0x40000000
-
-int        s390_device_register  ( devreg_t *drinfo );
-int        s390_device_unregister( devreg_t *dreg );
-devreg_t * s390_search_devreg    ( ioinfo_t *ioinfo );
-
-#endif /* __s390dyn */
diff -Nru a/include/asm-s390x/s390io.h b/include/asm-s390x/s390io.h
--- a/include/asm-s390x/s390io.h	Mon Dec  9 18:46:52 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,124 +0,0 @@
-/*
- *  arch/s390/kernel/s390io.h
- *
- *  S390 version
- *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Ingo Adlung (adlung@de.ibm.com)
- */
-
-#ifndef __s390io_h
-#define __s390io_h
-
-#include <linux/device.h>
-
-/*
- * IRQ data structure used by I/O subroutines
- *
- * Note : If bit flags are added, the "unused" value must be
- *        decremented accordingly !
- */
-typedef struct subchannel {
-     unsigned int  irq;           /* aka. subchannel number */
-     spinlock_t    irq_lock;      /* irq lock */
-
-     __u8          st;            /* subchannel type */
-
-     void          *private_data; /* pointer to private data */
-
-     struct subchannel *prev;
-     struct subchannel *next;
-
-     union {
-        unsigned int info;
-        struct {
-           unsigned int  busy      : 1;  /* device currently in use */
-           unsigned int  oper      : 1;  /* device is operational */
-           unsigned int  fast      : 1;  /* post with "channel end", ...    */
-                                         /* ... don't wait for "device end" */
-                                         /* ... from do_IO() parameters     */
-           unsigned int  ready     : 1;  /* interrupt handler registered */
-           unsigned int  haltio    : 1;  /* halt_IO in process */
-           unsigned int  doio      : 1;  /* do_IO in process */
-           unsigned int  doio_q    : 1;  /* do_IO queued - only possible ... */
-                                         /* ... if 'fast' is set too */
-           unsigned int  w4final   : 1;  /* wait for final status, internally */
-                                         /* ... used with 'fast' setting only */
-           unsigned int  repall    : 1;  /* report every interrupt status */
-           unsigned int  unready   : 1;  /* deregister irq handler in process */
-           unsigned int  d_disable : 1;  /* delayed disabling required */
-           unsigned int  w4sense   : 1;  /* SENSE status pending */
-           unsigned int  syncio    : 1;  /* synchronous I/O requested */
-           unsigned int  consns    : 1;  /* concurrent sense is available */
-           unsigned int  delsense  : 1;  /* delayed SENSE required */
-           unsigned int  s_pend    : 1;  /* status pending condition */
-           unsigned int  pgid      : 1;  /* "path group ID" is valid */
-           unsigned int  pgid_supp : 1;  /* "path group ID" command is supported */
-           unsigned int  esid      : 1;  /* Ext. SenseID supported by HW */
-           unsigned int  rcd       : 1;  /* RCD supported by HW */
-           unsigned int  repnone   : 1;  /* don't call IRQ handler on interrupt */
-           unsigned int  dval      : 1;  /* device number valid */
-           unsigned int  unknown   : 1;  /* unknown device - if SenseID failed */
-           unsigned int  unused    : (sizeof(unsigned int)*8 - 23); /* unused */
-              } __attribute__ ((packed)) flags;
-        } ui;
-
-     unsigned long u_intparm;     /* user interruption parameter */
-     senseid_t     senseid;       /* SenseID info */
-     irq_desc_t    irq_desc;      /* irq descriptor */
-     not_oper_handler_func_t nopfunc; 	/* not oper handler */		
-     __u8          ulpm;          /* logical path mask used for I/O */
-     __u8          opm;           /* path mask of operational paths */
-     __u16         devno;         /* device number */
-     pgid_t        pgid;          /* path group ID */
-     schib_t       schib;         /* subchannel information block */
-     orb_t         orb;           /* operation request block */
-     devstat_t     devstat;       /* device status */
-     ccw1_t       *qcpa;          /* queued channel program */
-     ccw1_t        senseccw;      /* ccw for sense command */
-     __u8          sense_data[32];/* buffer for basic sense */
-     unsigned int  stctl;         /* accumulated status control from irb */
-     unsigned long qintparm;      /* queued interruption parameter  */
-     unsigned long qflag;         /* queued flags */
-     __u8          qlpm;          /* queued logical path mask */
-     ssd_info_t    ssd_info;      /* subchannel description */
-     struct device dev;		  /* entry in device tree */
-} __attribute__ ((aligned(8))) ioinfo_t;
-
-
-/*
- * There are four different subchannel types, but we are currently
- * only interested in I/O subchannels. This means there is only
- * one subchannel_driver, other subchannels belonging to css_bus_type
- * are simply ignored.
- */
-struct subchannel_driver {
-	enum {
-		SUBCHANNEL_TYPE_IO      = 0,
-		SUBCHANNEL_TYPE_CHSC    = 1,
-		SUBCHANNEL_TYPE_MESSAGE = 2,
-		SUBCHANNEL_TYPE_ADM     = 3,
-	} st;			  /* subchannel type */
-	struct device_driver drv; /* entry in driver tree */
-};
-extern struct bus_type css_bus_type;
-
-#define IOINFO_FLAGS_BUSY    0x80000000
-#define IOINFO_FLAGS_OPER    0x40000000
-#define IOINFO_FLAGS_FAST    0x20000000
-#define IOINFO_FLAGS_READY   0x10000000
-#define IOINFO_FLAGS_HALTIO  0x08000000
-#define IOINFO_FLAGS_DOIO    0x04000000
-#define IOINFO_FLAGS_DOIO_Q  0x02000000
-#define IOINFO_FLAGS_W4FINAL 0x01000000
-#define IOINFO_FLAGS_REPALL  0x00800000
-
-extern ioinfo_t *ioinfo[];
-int s390_set_private_data(int irq, void * data);
-void * s390_get_private_data(int irq);
-
-#define CHSC_SEI_ACC_CHPID        1
-#define CHSC_SEI_ACC_LINKADDR     2
-#define CHSC_SEI_ACC_FULLLINKADDR 3
-
-#endif  /* __s390io_h */
-
diff -Nru a/include/asm-s390x/s390mach.h b/include/asm-s390x/s390mach.h
--- a/include/asm-s390x/s390mach.h	Mon Dec  9 18:46:36 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,119 +0,0 @@
-/*
- *  arch/s390/kernel/s390mach.h
- *   S/390 data definitions for machine check processing
- *
- *  S390 version
- *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Ingo Adlung (adlung@de.ibm.com)
- */
-
-#ifndef __s390mach_h
-#define __s390mach_h
-
-#include <asm/types.h>
-
-typedef struct _mci {
-	__u32   sd              :  1; /* 00 system damage */
-	__u32   pd              :  1; /* 01 instruction-processing damage */
-	__u32   sr              :  1; /* 02 system recovery */
-	__u32   to_be_defined_1 :  4; /* 03-06 */
-	__u32   dg              :  1; /* 07 degradation */
-	__u32   w               :  1; /* 08 warning pending */
-	__u32   cp              :  1; /* 09 channel-report pending */
-	__u32   to_be_defined_2 :  6; /* 10-15 */
-	__u32   se              :  1; /* 16 storage error uncorrected */
-	__u32   sc              :  1; /* 17 storage error corrected */
-	__u32   ke              :  1; /* 18 storage-key error uncorrected */
-	__u32   ds              :  1; /* 19 storage degradation */
-	__u32	to_be_defined_3 :  4; /* 20-23 */
-	__u32   fa              :  1; /* 24 failing storage address validity */
-	__u32   to_be_defined_4 :  7; /* 25-31 */
-	__u32   ie              :  1; /* 32 indirect storage error */
-	__u32	to_be_defined_5 : 31; /* 33-63 */
-	} mci_t;
-
-//
-// machine-check-interruption code
-//
-typedef struct _mcic {
-   union _mcc {
-      __u64 mcl;	/* machine check int. code - long info */	
-      mci_t mcd;  /* machine check int. code - details   */
-   } mcc;
-} __attribute__ ((packed)) mcic_t;
-
-//
-// Channel Report Word
-//
-typedef struct _crw {
-	__u32 res1    :  1;   /* reserved zero */
-	__u32 slct    :  1;   /* solicited */
-	__u32 oflw    :  1;   /* overflow */
-	__u32 chn     :  1;   /* chained */
-	__u32 rsc     :  4;   /* reporting source code */
-	__u32 anc     :  1;   /* ancillary report */
-	__u32 res2    :  1;   /* reserved zero */
-	__u32 erc     :  6;   /* error-recovery code */
-	__u32 rsid    : 16;   /* reporting-source ID */
-} __attribute__ ((packed)) crw_t;
-
-#define CRW_RSC_MONITOR  0x2  /* monitoring facility */
-#define CRW_RSC_SCH      0x3  /* subchannel */
-#define CRW_RSC_CPATH    0x4  /* channel path */
-#define CRW_RSC_CONFIG   0x9  /* configuration-alert facility */
-#define CRW_RSC_CSS      0xB  /* channel subsystem */
-
-#define CRW_ERC_EVENT    0x00 /* event information pending */
-#define CRW_ERC_AVAIL    0x01 /* available */
-#define CRW_ERC_INIT     0x02 /* initialized */
-#define CRW_ERC_TERROR   0x03 /* temporary error */
-#define CRW_ERC_IPARM    0x04 /* installed parm initialized */
-#define CRW_ERC_TERM     0x05 /* terminal */
-#define CRW_ERC_PERRN    0x06 /* perm. error, fac. not init */
-#define CRW_ERC_PERRI    0x07 /* perm. error, facility init */
-#define CRW_ERC_PMOD     0x08 /* installed parameters modified */
-
-#define MAX_CRW_PENDING  1024
-#define MAX_MACH_PENDING 1024
-
-//
-// CRW Entry
-//
-typedef struct _crwe {
-	crw_t   crw;
-	struct _crwe *crwe_next;
-} __attribute__ ((packed)) crwe_t;
-
-typedef struct _mache {
-	spinlock_t     lock;
-	unsigned int   status;
-	mcic_t         mcic;
-	union _mc {
-	   crwe_t     *crwe;		/* CRW if applicable */
-   } mc;
-	struct _mache *next;
-	struct _mache *prev;
-} mache_t;
-
-#define MCHCHK_STATUS_TO_PROCESS    0x00000001
-#define MCHCHK_STATUS_IN_PROGRESS   0x00000002
-#define MCHCHK_STATUS_WAITING       0x00000004
-
-void s390_init_machine_check( void );
-void s390_do_machine_check  ( void );
-void s390_do_crw_pending    ( crwe_t *pcrwe );
-
-extern __inline__ int stcrw( __u32 *pcrw )
-{
-        int ccode;
-
-        __asm__ __volatile__(
-                "STCRW 0(%1)\n\t"
-                "IPM %0\n\t"
-                "SRL %0,28\n\t"
-                : "=d" (ccode) : "a" (pcrw)
-                : "cc", "1" );
-        return ccode;
-}
-
-#endif /* __s390mach */
diff -Nru a/include/asm-s390x/setup.h b/include/asm-s390x/setup.h
--- a/include/asm-s390x/setup.h	Mon Dec  9 18:46:39 2002
+++ b/include/asm-s390x/setup.h	Mon Dec  9 18:46:39 2002
@@ -37,6 +37,7 @@
  */
 extern unsigned int console_mode;
 extern unsigned int console_device;
+extern unsigned int console_irq;
 
 #define CONSOLE_IS_UNDEFINED	(console_mode == 0)
 #define CONSOLE_IS_SCLP		(console_mode == 1)
diff -Nru a/include/asm-sh/signal.h b/include/asm-sh/signal.h
--- a/include/asm-sh/signal.h	Mon Dec  9 18:46:38 2002
+++ b/include/asm-sh/signal.h	Mon Dec  9 18:46:38 2002
@@ -165,8 +165,6 @@
 #ifdef __KERNEL__
 #include <asm/sigcontext.h>
 
-#define sigmask(sig)	(1UL << ((sig) - 1))
-
 #endif /* __KERNEL__ */
 
 #endif /* __ASM_SH_SIGNAL_H */
diff -Nru a/include/asm-sparc/current.h b/include/asm-sparc/current.h
--- a/include/asm-sparc/current.h	Mon Dec  9 18:46:34 2002
+++ b/include/asm-sparc/current.h	Mon Dec  9 18:46:34 2002
@@ -16,12 +16,7 @@
  * We might want to consider doing the same to shave a few cycles.
  */
 
-// Applications do not include kernel headers anymore, period.
-// #ifdef __KERNEL__
-
-#ifndef _ASM_THREAD_INFO_H
-#include <asm/thread_info.h>
-#endif
+#include <linux/thread_info.h>
 
 struct task_struct;
 
@@ -32,7 +27,5 @@
 	return current_thread_info()->task;
 }
 #define current __get_current()
-
-// #endif /* __KERNEL__ */
 
 #endif /* !(_ASM_CURRENT_H) */
diff -Nru a/include/asm-sparc/elf.h b/include/asm-sparc/elf.h
--- a/include/asm-sparc/elf.h	Mon Dec  9 18:46:50 2002
+++ b/include/asm-sparc/elf.h	Mon Dec  9 18:46:50 2002
@@ -56,7 +56,7 @@
 } elf_fpregset_t;
 
 #define ELF_CORE_COPY_TASK_REGS(__tsk, __elf_regs)	\
-	({ ELF_CORE_COPY_REGS((*(__elf_regs)), (__tsk)->thread_info->kregs); 1; })
+	({ ELF_CORE_COPY_REGS((*(__elf_regs)), (__tsk)->thread.kregs); 1; })
 
 /*
  * This is used to ensure we don't load something for the wrong architecture.
diff -Nru a/include/asm-sparc/hardirq.h b/include/asm-sparc/hardirq.h
--- a/include/asm-sparc/hardirq.h	Mon Dec  9 18:46:52 2002
+++ b/include/asm-sparc/hardirq.h	Mon Dec  9 18:46:52 2002
@@ -11,6 +11,7 @@
 #include <linux/threads.h>
 #include <linux/brlock.h>
 #include <linux/spinlock.h>
+#include <linux/cache.h>
 
 /* entry.S is sensitive to the offsets of these fields */ /* XXX P3 Is it? */
 typedef struct {
diff -Nru a/include/asm-sparc/highmem.h b/include/asm-sparc/highmem.h
--- a/include/asm-sparc/highmem.h	Mon Dec  9 18:46:52 2002
+++ b/include/asm-sparc/highmem.h	Mon Dec  9 18:46:52 2002
@@ -33,6 +33,12 @@
 extern pgprot_t kmap_prot;
 extern pte_t *pkmap_page_table;
 
+/* This gets set in {srmmu,sun4c}_paging_init() */
+extern unsigned long fix_kmap_begin;
+
+/* Only used and set with srmmu? */
+extern unsigned long pkmap_base;
+
 extern void kmap_init(void) __init;
 
 /*
@@ -42,9 +48,9 @@
  */
 #define LAST_PKMAP 1024
 
-#define LAST_PKMAP_MASK (LAST_PKMAP-1)
-#define PKMAP_NR(virt)  ((virt-PKMAP_BASE) >> PAGE_SHIFT)
-#define PKMAP_ADDR(nr)  (PKMAP_BASE + ((nr) << PAGE_SHIFT))
+#define LAST_PKMAP_MASK (LAST_PKMAP - 1)
+#define PKMAP_NR(virt)  ((virt - pkmap_base) >> PAGE_SHIFT)
+#define PKMAP_ADDR(nr)  (pkmap_base + ((nr) << PAGE_SHIFT))
 
 extern void *kmap_high(struct page *page);
 extern void kunmap_high(struct page *page);
@@ -75,10 +81,10 @@
 	unsigned long idx, vaddr = (unsigned long)ptr;
 	pte_t *pte;
 
-	if (vaddr < FIX_KMAP_BEGIN)
+	if (vaddr < fix_kmap_begin)
 		return virt_to_page(ptr);
 
-	idx = ((vaddr - FIX_KMAP_BEGIN) >> PAGE_SHIFT);
+	idx = ((vaddr - fix_kmap_begin) >> PAGE_SHIFT);
 	pte = kmap_pte + idx;
 	return pte_page(*pte);
 }
diff -Nru a/include/asm-sparc/io.h b/include/asm-sparc/io.h
--- a/include/asm-sparc/io.h	Mon Dec  9 18:46:34 2002
+++ b/include/asm-sparc/io.h	Mon Dec  9 18:46:34 2002
@@ -187,9 +187,6 @@
 extern void sbus_iounmap(unsigned long vaddr, unsigned long size);
 
 
-#define virt_to_phys(x) __pa((unsigned long)(x))
-#define phys_to_virt(x) __va((unsigned long)(x))
-
 /*
  * At the moment, we do not use CMOS_READ anywhere outside of rtc.c,
  * so rtc_port is static in it. This should not change unless a new
diff -Nru a/include/asm-sparc/irq.h b/include/asm-sparc/irq.h
--- a/include/asm-sparc/irq.h	Mon Dec  9 18:46:38 2002
+++ b/include/asm-sparc/irq.h	Mon Dec  9 18:46:38 2002
@@ -19,7 +19,7 @@
 BTFIXUPDEF_CALL(char *, __irq_itoa, unsigned int)
 #define __irq_itoa(irq) BTFIXUP_CALL(__irq_itoa)(irq)
 
-#define NR_IRQS    15
+#define NR_IRQS    16
 
 #define irq_cannonicalize(irq)	(irq)
 
diff -Nru a/include/asm-sparc/page.h b/include/asm-sparc/page.h
--- a/include/asm-sparc/page.h	Mon Dec  9 18:46:35 2002
+++ b/include/asm-sparc/page.h	Mon Dec  9 18:46:35 2002
@@ -174,6 +174,9 @@
 #define __pa(x)                 ((unsigned long)(x) - PAGE_OFFSET)
 #define __va(x)                 ((void *)((unsigned long) (x) + PAGE_OFFSET))
 
+#define virt_to_phys(x)		__pa((unsigned long)(x))
+#define phys_to_virt(x)		__va((unsigned long)(x))
+
 #define pfn_to_page(pfn)        (mem_map + (pfn))
 #define page_to_pfn(page)       ((unsigned long)((page) - mem_map))
 #define virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT))
diff -Nru a/include/asm-sparc/pgtsrmmu.h b/include/asm-sparc/pgtsrmmu.h
--- a/include/asm-sparc/pgtsrmmu.h	Mon Dec  9 18:46:35 2002
+++ b/include/asm-sparc/pgtsrmmu.h	Mon Dec  9 18:46:35 2002
@@ -8,7 +8,10 @@
 #define _SPARC_PGTSRMMU_H
 
 #include <asm/page.h>
+
+#ifdef __ASSEMBLY__
 #include <asm/thread_info.h>	/* TI_UWINMASK for WINDOW_FLUSH */
+#endif
 
 /* PMD_SHIFT determines the size of the area a second-level page table entry can map */
 #define SRMMU_PMD_SHIFT         18
diff -Nru a/include/asm-sparc/processor.h b/include/asm-sparc/processor.h
--- a/include/asm-sparc/processor.h	Mon Dec  9 18:46:52 2002
+++ b/include/asm-sparc/processor.h	Mon Dec  9 18:46:52 2002
@@ -139,34 +139,7 @@
 #define release_thread(tsk)		do { } while(0)
 extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
-#define get_wchan(__TSK) \
-({	extern void scheduling_functions_start_here(void); \
-	extern void scheduling_functions_end_here(void); \
-	unsigned long pc, fp, bias = 0; \
-	unsigned long task_base = (unsigned long) (__TSK); \
-        unsigned long __ret = 0; \
-	struct reg_window *rw; \
-	int count = 0; \
-	if (!(__TSK) || (__TSK) == current || \
-            (__TSK)->state == TASK_RUNNING) \
-		goto __out; \
-	fp = (__TSK)->thread_info->ksp + bias; \
-	do { \
-		/* Bogus frame pointer? */ \
-		if (fp < (task_base + sizeof(struct task_struct)) || \
-		    fp >= (task_base + (2 * PAGE_SIZE))) \
-			break; \
-		rw = (struct reg_window *) fp; \
-		pc = rw->ins[7]; \
-		if (pc < ((unsigned long) scheduling_functions_start_here) || \
-                    pc >= ((unsigned long) scheduling_functions_end_here)) { \
-			__ret = pc; \
-			goto __out; \
-		} \
-		fp = rw->ins[6] + bias; \
-	} while (++count < 16); \
-__out:	__ret; \
-})
+extern unsigned long get_wchan(struct task_struct *);
 
 #define KSTK_EIP(tsk)  ((tsk)->thread.kregs->pc)
 #define KSTK_ESP(tsk)  ((tsk)->thread.kregs->u_regs[UREG_FP])
diff -Nru a/include/asm-sparc/system.h b/include/asm-sparc/system.h
--- a/include/asm-sparc/system.h	Mon Dec  9 18:46:50 2002
+++ b/include/asm-sparc/system.h	Mon Dec  9 18:46:50 2002
@@ -9,7 +9,6 @@
 #include <linux/threads.h>	/* NR_CPUS */
 
 #include <asm/segment.h>
-#include <asm/thread_info.h>
 #include <asm/page.h>
 #include <asm/openprom.h>	/* romvec. XXX will be dealt later. Promise. */
 #include <asm/psr.h>
@@ -52,9 +51,6 @@
 extern unsigned long empty_bad_page;
 extern unsigned long empty_bad_page_table;
 extern unsigned long empty_zero_page;
-
-extern struct linux_romvec *romvec;
-#define halt() romvec->pv_halt()
 
 extern void sun_do_break(void);
 extern int serial_console;
diff -Nru a/include/asm-sparc/thread_info.h b/include/asm-sparc/thread_info.h
--- a/include/asm-sparc/thread_info.h	Mon Dec  9 18:46:51 2002
+++ b/include/asm-sparc/thread_info.h	Mon Dec  9 18:46:51 2002
@@ -44,18 +44,23 @@
 	unsigned long kpc;
 	unsigned long kpsr;
 	unsigned long kwim;
+
+	struct restart_block	restart_block;
 };
 
 /*
  * macros/functions for gaining access to the thread information structure
  */
-#define INIT_THREAD_INFO(tsk)			\
-{						\
-	uwinmask:	0,			\
-	task:		&tsk,			\
-	exec_domain:	&default_exec_domain,	\
-	flags:		0,			\
-	cpu:		0,			\
+#define INIT_THREAD_INFO(tsk)				\
+{							\
+	.uwinmask	=	0,			\
+	.task		=	&tsk,			\
+	.exec_domain	=	&default_exec_domain,	\
+	.flags		=	0,			\
+	.cpu		=	0,			\
+	.restart_block	= {				\
+		.fn	=	do_no_restart_syscall,	\
+	},						\
 }
 
 #define init_thread_info	(init_thread_union.thread_info)
@@ -110,6 +115,7 @@
 #define TI_KPC		0x24	/* kpc (ldd'ed with kpc) */
 #define TI_KPSR		0x28	/* kpsr */
 #define TI_KWIM		0x2c	/* kwim (ldd'ed with kpsr) */
+#define TI_RESTART_BLOCK 0x30
 
 #define PREEMPT_ACTIVE		0x4000000
 
diff -Nru a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h
--- a/include/asm-sparc/unistd.h	Mon Dec  9 18:46:34 2002
+++ b/include/asm-sparc/unistd.h	Mon Dec  9 18:46:34 2002
@@ -16,6 +16,7 @@
  * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu)
  */
 
+#define __NR_restart_syscall      0 /* Linux Specific				   */
 #define __NR_exit                 1 /* Common                                      */
 #define __NR_fork                 2 /* Common                                      */
 #define __NR_read                 3 /* Common                                      */
diff -Nru a/include/asm-sparc/vaddrs.h b/include/asm-sparc/vaddrs.h
--- a/include/asm-sparc/vaddrs.h	Mon Dec  9 18:46:34 2002
+++ b/include/asm-sparc/vaddrs.h	Mon Dec  9 18:46:34 2002
@@ -14,23 +14,26 @@
 
 #define SRMMU_MAXMEM		0x0c000000
 
-#define SRMMU_NOCACHE_VADDR	0xfc000000	/* KERNBASE + SRMMU_MAXMEM */
-/* XXX Make this dynamic based on ram size - Anton */
-#define SRMMU_NOCACHE_NPAGES	256
-#define SRMMU_NOCACHE_SIZE	(SRMMU_NOCACHE_NPAGES * PAGE_SIZE)
-#define SRMMU_NOCACHE_END	(SRMMU_NOCACHE_VADDR + SRMMU_NOCACHE_SIZE)
+#define SRMMU_NOCACHE_VADDR	(KERNBASE + SRMMU_MAXMEM)
+				/* = 0x0fc000000 */
 
-#define FIX_KMAP_BEGIN		0xfc100000
-#define FIX_KMAP_END (FIX_KMAP_BEGIN + ((KM_TYPE_NR*NR_CPUS)-1)*PAGE_SIZE)
-
-#define PKMAP_BASE		0xfc140000
-#define PKMAP_BASE_END		(PKMAP_BASE+LAST_PKMAP*PAGE_SIZE)
+/* The following constant is used in mm/srmmu.c::srmmu_nocache_calcsize()
+ * to determine the amount of memory that will be reserved as nocache:
+ *
+ * 256 pages will be taken as nocache per each
+ * SRMMU_NOCACHE_ALCRATIO MB of system memory.
+ *
+ * limits enforced:	nocache minimum = 256 pages
+ *			nocache maximum = 1280 pages
+ */
+#define SRMMU_NOCACHE_ALCRATIO	64	/* 256 pages per 64MB of system RAM */
 
 #define SUN4M_IOBASE_VADDR	0xfd000000 /* Base for mapping pages */
 #define IOBASE_VADDR		0xfe000000
 #define IOBASE_END		0xfe300000
 
 #define VMALLOC_START		0xfe300000
+
 /* XXX Alter this when I get around to fixing sun4c - Anton */
 #define VMALLOC_END		0xffc00000
 
diff -Nru a/include/asm-sparc64/compat.h b/include/asm-sparc64/compat.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-sparc64/compat.h	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,22 @@
+#ifndef _ASM_SPARC64_COMPAT_H
+#define _ASM_SPARC64_COMPAT_H
+/*
+ * Architecture specific compatibility types
+ */
+#include <linux/types.h>
+
+typedef u32		compat_size_t;
+typedef s32		compat_ssize_t;
+typedef s32		compat_time_t;
+
+struct compat_timespec {
+	compat_time_t	tv_sec;
+	s32		tv_nsec;
+};
+
+struct compat_timeval {
+	compat_time_t	tv_sec;
+	s32		tv_usec;
+};
+
+#endif /* _ASM_SPARC64_COMPAT_H */
diff -Nru a/include/asm-sparc64/current.h b/include/asm-sparc64/current.h
--- a/include/asm-sparc64/current.h	Mon Dec  9 18:46:38 2002
+++ b/include/asm-sparc64/current.h	Mon Dec  9 18:46:38 2002
@@ -1,7 +1,7 @@
 #ifndef _SPARC64_CURRENT_H
 #define _SPARC64_CURRENT_H
 
-#include <asm/thread_info.h>
+#include <linux/thread_info.h>
 
 register struct task_struct *current asm("g4");
 
diff -Nru a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h
--- a/include/asm-sparc64/irq.h	Mon Dec  9 18:46:38 2002
+++ b/include/asm-sparc64/irq.h	Mon Dec  9 18:46:38 2002
@@ -11,6 +11,7 @@
 #include <linux/config.h>
 #include <linux/linkage.h>
 #include <linux/kernel.h>
+#include <linux/errno.h>
 #include <asm/pil.h>
 #include <asm/ptrace.h>
 
@@ -110,7 +111,7 @@
 	return buff;
 }
 
-#define NR_IRQS    15
+#define NR_IRQS    16
 
 #define irq_cannonicalize(irq)	(irq)
 extern void disable_irq(unsigned int);
@@ -155,5 +156,26 @@
 			     : "=r" (retval));
 	return retval;
 }
+
+struct notifier_block;
+ 
+#ifdef CONFIG_PROFILING
+ 
+int register_profile_notifier(struct notifier_block *nb);
+int unregister_profile_notifier(struct notifier_block *nb);
+
+#else
+
+static inline int register_profile_notifier(struct notifier_block *nb)
+{
+	return -ENOSYS;
+}
+
+static inline int unregister_profile_notifier(struct notifier_block *nb)
+{
+	return -ENOSYS;
+}
+
+#endif /* CONFIG_PROFILING */
 
 #endif
diff -Nru a/include/asm-sparc64/posix_types.h b/include/asm-sparc64/posix_types.h
--- a/include/asm-sparc64/posix_types.h	Mon Dec  9 18:46:51 2002
+++ b/include/asm-sparc64/posix_types.h	Mon Dec  9 18:46:51 2002
@@ -48,10 +48,7 @@
 } __kernel_fsid_t;
 
 /* Now 32bit compatibility types */
-typedef unsigned int           __kernel_size_t32;
-typedef int                    __kernel_ssize_t32;
 typedef int                    __kernel_ptrdiff_t32;
-typedef int                    __kernel_time_t32;
 typedef int                    __kernel_clock_t32;
 typedef int                    __kernel_pid_t32;
 typedef unsigned short         __kernel_ipc_pid_t32;
diff -Nru a/include/asm-sparc64/processor.h b/include/asm-sparc64/processor.h
--- a/include/asm-sparc64/processor.h	Mon Dec  9 18:46:34 2002
+++ b/include/asm-sparc64/processor.h	Mon Dec  9 18:46:34 2002
@@ -187,36 +187,7 @@
 
 extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
-#define get_wchan(__TSK) \
-({	extern void scheduling_functions_start_here(void); \
-	extern void scheduling_functions_end_here(void); \
-	unsigned long pc, fp, bias = 0; \
-	unsigned long thread_info_base; \
-	struct reg_window *rw; \
-        unsigned long __ret = 0; \
-	int count = 0; \
-	if (!(__TSK) || (__TSK) == current || \
-            (__TSK)->state == TASK_RUNNING) \
-		goto __out; \
-	thread_info_base = (unsigned long) ((__TSK)->thread_info); \
-	bias = STACK_BIAS; \
-	fp = (__TSK)->thread_info->ksp + bias; \
-	do { \
-		/* Bogus frame pointer? */ \
-		if (fp < (thread_info_base + sizeof(struct thread_info)) || \
-		    fp >= (thread_info_base + THREAD_SIZE)) \
-			break; \
-		rw = (struct reg_window *) fp; \
-		pc = rw->ins[7]; \
-		if (pc < ((unsigned long) scheduling_functions_start_here) || \
-		    pc >= ((unsigned long) scheduling_functions_end_here)) { \
-			__ret = pc; \
-			goto __out; \
-		} \
-		fp = rw->ins[6] + bias; \
-	} while (++count < 16); \
-__out:	__ret; \
-})
+extern unsigned long get_wchan(struct task_struct *task);
 
 #define KSTK_EIP(tsk)  ((tsk)->thread_info->kregs->tpc)
 #define KSTK_ESP(tsk)  ((tsk)->thread_info->kregs->u_regs[UREG_FP])
diff -Nru a/include/asm-sparc64/rwsem.h b/include/asm-sparc64/rwsem.h
--- a/include/asm-sparc64/rwsem.h	Mon Dec  9 18:46:50 2002
+++ b/include/asm-sparc64/rwsem.h	Mon Dec  9 18:46:50 2002
@@ -279,7 +279,7 @@
 		"mov		%%g7, %0\n\t"
 		: "=&r" (tmp)
 		: "0" (tmp), "r" (sem)
-		: "g5", "g7", "memory");
+		: "g5", "g7", "memory", "cc");
 
 	return tmp + delta;
 }
diff -Nru a/include/asm-sparc64/signal.h b/include/asm-sparc64/signal.h
--- a/include/asm-sparc64/signal.h	Mon Dec  9 18:46:35 2002
+++ b/include/asm-sparc64/signal.h	Mon Dec  9 18:46:35 2002
@@ -8,6 +8,7 @@
 #ifndef __ASSEMBLY__
 #include <linux/personality.h>
 #include <linux/types.h>
+#include <linux/compat.h>
 #endif
 #endif
 
@@ -250,7 +251,7 @@
 typedef struct sigaltstack32 {
 	u32			ss_sp;
 	int			ss_flags;
-	__kernel_size_t32	ss_size;
+	compat_size_t		ss_size;
 } stack_t32;
 
 #define HAVE_ARCH_GET_SIGNAL_TO_DELIVER
diff -Nru a/include/asm-sparc64/stat.h b/include/asm-sparc64/stat.h
--- a/include/asm-sparc64/stat.h	Mon Dec  9 18:46:52 2002
+++ b/include/asm-sparc64/stat.h	Mon Dec  9 18:46:52 2002
@@ -3,6 +3,7 @@
 #define _SPARC64_STAT_H
 
 #include <linux/types.h>
+#include <linux/compat.h>
 #include <linux/time.h>
 
 struct stat32 {
@@ -14,11 +15,11 @@
 	__kernel_gid_t32   st_gid;
 	__kernel_dev_t32   st_rdev;
 	__kernel_off_t32   st_size;
-	__kernel_time_t32  st_atime;
+	compat_time_t    st_atime;
 	unsigned int       __unused1;
-	__kernel_time_t32  st_mtime;
+	compat_time_t    st_mtime;
 	unsigned int       __unused2;
-	__kernel_time_t32  st_ctime;
+	compat_time_t    st_ctime;
 	unsigned int       __unused3;
 	__kernel_off_t32   st_blksize;
 	__kernel_off_t32   st_blocks;
diff -Nru a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
--- a/include/asm-sparc64/system.h	Mon Dec  9 18:46:34 2002
+++ b/include/asm-sparc64/system.h	Mon Dec  9 18:46:34 2002
@@ -6,7 +6,6 @@
 #include <asm/ptrace.h>
 #include <asm/processor.h>
 #include <asm/visasm.h>
-#include <asm/thread_info.h>
 
 #ifndef __ASSEMBLY__
 /*
@@ -164,6 +163,11 @@
 	 * not preserve it's value.  Hairy, but it lets us remove 2 loads
 	 * and 2 stores in this critical code path.  -DaveM
 	 */
+#if __GNUC__ >= 3
+#define EXTRA_CLOBBER ,"%l1"
+#else
+#define EXTRA_CLOBBER
+#endif
 #define switch_to(prev, next, last)					\
 do {	if (test_thread_flag(TIF_PERFCTR)) {				\
 		unsigned long __tmp;					\
@@ -209,10 +213,11 @@
 	: "0" (next->thread_info),					\
 	  "i" (TI_WSTATE), "i" (TI_KSP), "i" (TI_FLAGS), "i" (TI_CWP),	\
 	  "i" (_TIF_NEWCHILD), "i" (TI_TASK)				\
-	: "cc", "g1", "g2", "g3", "g5", "g7",				\
-	  "l2", "l3", "l4", "l5", "l6", "l7",				\
+	: "cc",								\
+	        "g1", "g2", "g3",       "g5",       "g7",		\
+	              "l2", "l3", "l4", "l5", "l6", "l7",		\
 	  "i0", "i1", "i2", "i3", "i4", "i5",				\
-	  "o0", "o1", "o2", "o3", "o4", "o5", "o7");			\
+	  "o0", "o1", "o2", "o3", "o4", "o5",       "o7" EXTRA_CLOBBER);\
 	/* If you fuck with this, update ret_from_syscall code too. */	\
 	if (test_thread_flag(TIF_PERFCTR)) {				\
 		write_pcr(current_thread_info()->pcr_reg);		\
diff -Nru a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h
--- a/include/asm-sparc64/thread_info.h	Mon Dec  9 18:46:50 2002
+++ b/include/asm-sparc64/thread_info.h	Mon Dec  9 18:46:50 2002
@@ -62,6 +62,8 @@
 
 	__u64			cee_stuff;
 
+	struct restart_block	restart_block;
+
 	unsigned long		fpregs[0] __attribute__ ((aligned(64)));
 };
 
@@ -94,6 +96,7 @@
 #define TI_KERN_CNTD1	0x00000488
 #define TI_PCR		0x00000490
 #define TI_CEE_STUFF	0x00000498
+#define TI_RESTART_BLOCK 0x000004a0
 #define TI_FPREGS	0x000004c0
 
 /* We embed this in the uppermost byte of thread_info->flags */
@@ -121,10 +124,13 @@
 
 #define INIT_THREAD_INFO(tsk)				\
 {							\
-	task:		&tsk,				\
-	flags:		((unsigned long)ASI_P) << TI_FLAG_CURRENT_DS_SHIFT,	\
-	exec_domain:	&default_exec_domain,		\
-	preempt_count:	1,				\
+	.task		=	&tsk,			\
+	.flags		= ((unsigned long)ASI_P) << TI_FLAG_CURRENT_DS_SHIFT,	\
+	.exec_domain	=	&default_exec_domain,	\
+	.preempt_count	=	1,			\
+	.restart_block	= {				\
+		.fn	=	do_no_restart_syscall,	\
+	},						\
 }
 
 #define init_thread_info	(init_thread_union.thread_info)
diff -Nru a/include/asm-sparc64/ttable.h b/include/asm-sparc64/ttable.h
--- a/include/asm-sparc64/ttable.h	Mon Dec  9 18:46:34 2002
+++ b/include/asm-sparc64/ttable.h	Mon Dec  9 18:46:34 2002
@@ -3,8 +3,11 @@
 #define _SPARC64_TTABLE_H
 
 #include <linux/config.h>
-#include <asm/thread_info.h>
 #include <asm/utrap.h>
+
+#ifdef __ASSEMBLY__
+#include <asm/thread_info.h>
+#endif
 
 #define BOOT_KERNEL b sparc64_boot; nop; nop; nop; nop; nop; nop; nop;
 
diff -Nru a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h
--- a/include/asm-sparc64/unistd.h	Mon Dec  9 18:46:35 2002
+++ b/include/asm-sparc64/unistd.h	Mon Dec  9 18:46:35 2002
@@ -16,6 +16,7 @@
  * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu)
  */
 
+#define __NR_restart_syscall      0 /* Linux Specific				   */
 #define __NR_exit                 1 /* Common                                      */
 #define __NR_fork                 2 /* Common                                      */
 #define __NR_read                 3 /* Common                                      */
diff -Nru a/include/asm-x86_64/signal.h b/include/asm-x86_64/signal.h
--- a/include/asm-x86_64/signal.h	Mon Dec  9 18:46:34 2002
+++ b/include/asm-x86_64/signal.h	Mon Dec  9 18:46:34 2002
@@ -193,8 +193,6 @@
 	 __const_sigismember((set),(sig)) :	\
 	 __gen_sigismember((set),(sig)))
 
-#define sigmask(sig)	(1UL << ((sig) - 1))
-
 extern __inline__ int sigfindinword(unsigned long word)
 {
 	__asm__("bsfq %1,%0" : "=r"(word) : "rm"(word) : "cc");
diff -Nru a/include/linux/ac97_codec.h b/include/linux/ac97_codec.h
--- a/include/linux/ac97_codec.h	Mon Dec  9 18:46:34 2002
+++ b/include/linux/ac97_codec.h	Mon Dec  9 18:46:34 2002
@@ -32,7 +32,7 @@
 #define AC97_PCM_FRONT_DAC_RATE   0x002C       /* PCM Front DAC Rate */
 #define AC97_PCM_SURR_DAC_RATE    0x002E       /* PCM Surround DAC Rate */
 #define AC97_PCM_LFE_DAC_RATE     0x0030       /* PCM LFE DAC Rate */
-#define AC97_PCM_LR_ADC_RATE      0x0032       /* PCM LR DAC Rate */
+#define AC97_PCM_LR_ADC_RATE      0x0032       /* PCM LR ADC Rate */
 #define AC97_PCM_MIC_ADC_RATE     0x0034       /* PCM MIC ADC Rate */
 #define AC97_CENTER_LFE_MASTER    0x0036       /* Center + LFE Master Volume */
 #define AC97_SURROUND_MASTER      0x0038       /* Surround (Rear) Master Volume */
@@ -142,6 +142,39 @@
 #define AC97_PWR_PR5              0x2000       /* Internal Clk disable */
 #define AC97_PWR_PR6              0x4000       /* HP amp powerdown */
 #define AC97_PWR_PR7              0x8000       /* Modem off - if supported */
+
+/* extended audio ID register bit defines */
+#define AC97_EXTID_VRA            0x0001
+#define AC97_EXTID_DRA            0x0002
+#define AC97_EXTID_SPDIF          0x0004
+#define AC97_EXTID_VRM            0x0008
+#define AC97_EXTID_DSA0           0x0010
+#define AC97_EXTID_DSA1           0x0020
+#define AC97_EXTID_CDAC           0x0040
+#define AC97_EXTID_SDAC           0x0080
+#define AC97_EXTID_LDAC           0x0100
+#define AC97_EXTID_AMAP           0x0200
+#define AC97_EXTID_REV0           0x0400
+#define AC97_EXTID_REV1           0x0800
+#define AC97_EXTID_ID0            0x4000
+#define AC97_EXTID_ID1            0x8000
+
+/* extended status register bit defines */
+#define AC97_EXTSTAT_VRA          0x0001
+#define AC97_EXTSTAT_DRA          0x0002
+#define AC97_EXTSTAT_SPDIF        0x0004
+#define AC97_EXTSTAT_VRM          0x0008
+#define AC97_EXTSTAT_SPSA0        0x0010
+#define AC97_EXTSTAT_SPSA1        0x0020
+#define AC97_EXTSTAT_CDAC         0x0040
+#define AC97_EXTSTAT_SDAC         0x0080
+#define AC97_EXTSTAT_LDAC         0x0100
+#define AC97_EXTSTAT_MADC         0x0200
+#define AC97_EXTSTAT_SPCV         0x0400
+#define AC97_EXTSTAT_PRI          0x0800
+#define AC97_EXTSTAT_PRJ          0x1000
+#define AC97_EXTSTAT_PRK          0x2000
+#define AC97_EXTSTAT_PRL          0x4000
 
 /* useful power states */
 #define AC97_PWR_D0               0x0000      /* everything on */
diff -Nru a/include/linux/acct.h b/include/linux/acct.h
--- a/include/linux/acct.h	Mon Dec  9 18:46:35 2002
+++ b/include/linux/acct.h	Mon Dec  9 18:46:35 2002
@@ -76,6 +76,7 @@
 #include <linux/config.h>
 
 #ifdef CONFIG_BSD_PROCESS_ACCT
+struct super_block;
 extern void acct_auto_close(struct super_block *sb);
 extern int acct_process(long exitcode);
 #else
diff -Nru a/include/linux/agp_backend.h b/include/linux/agp_backend.h
--- a/include/linux/agp_backend.h	Mon Dec  9 18:46:50 2002
+++ b/include/linux/agp_backend.h	Mon Dec  9 18:46:50 2002
@@ -35,9 +35,6 @@
 #define FALSE 0
 #endif
 
-#define AGPGART_VERSION_MAJOR 0
-#define AGPGART_VERSION_MINOR 99
-
 enum chipset_type {
 	NOT_SUPPORTED,
 	INTEL_GENERIC,
@@ -62,6 +59,8 @@
 	VIA_APOLLO_KX133,
 	VIA_APOLLO_KT133,
 	VIA_APOLLO_KT400,
+	VIA_APOLLO_PRO_266,
+	VIA_VT8605,
 	SIS_GENERIC,
 	AMD_GENERIC,
 	AMD_IRONGATE,
diff -Nru a/include/linux/compat.h b/include/linux/compat.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/compat.h	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,24 @@
+#ifndef _LINUX_COMPAT_H
+#define _LINUX_COMPAT_H
+/*
+ * These are the type definitions for the arhitecure sepcific
+ * compatibility layer.
+ */
+#include <linux/config.h>
+
+#ifdef CONFIG_COMPAT
+
+#include <asm/compat.h>
+
+struct compat_utimbuf {
+	compat_time_t		actime;
+	compat_time_t		modtime;
+};
+
+struct compat_itimerval {
+	struct compat_timeval	it_interval;
+	struct compat_timeval	it_value;
+};
+
+#endif /* CONFIG_COMPAT */
+#endif /* _LINUX_COMPAT_H */
diff -Nru a/include/linux/completion.h b/include/linux/completion.h
--- a/include/linux/completion.h	Mon Dec  9 18:46:50 2002
+++ b/include/linux/completion.h	Mon Dec  9 18:46:50 2002
@@ -29,6 +29,7 @@
 
 extern void FASTCALL(wait_for_completion(struct completion *));
 extern void FASTCALL(complete(struct completion *));
+extern void FASTCALL(complete_all(struct completion *));
 
 #define INIT_COMPLETION(x)	((x).done = 0)
 
diff -Nru a/include/linux/console.h b/include/linux/console.h
--- a/include/linux/console.h	Mon Dec  9 18:46:36 2002
+++ b/include/linux/console.h	Mon Dec  9 18:46:36 2002
@@ -40,6 +40,7 @@
 	int	(*con_switch)(struct vc_data *);
 	int	(*con_blank)(struct vc_data *, int);
 	int	(*con_font_op)(struct vc_data *, struct console_font_op *);
+	int	(*con_resize)(struct vc_data *, unsigned int, unsigned int);
 	int	(*con_set_palette)(struct vc_data *, unsigned char *);
 	int	(*con_scrolldelta)(struct vc_data *, int);
 	int	(*con_set_origin)(struct vc_data *);
diff -Nru a/include/linux/console_struct.h b/include/linux/console_struct.h
--- a/include/linux/console_struct.h	Mon Dec  9 18:46:34 2002
+++ b/include/linux/console_struct.h	Mon Dec  9 18:46:34 2002
@@ -27,6 +27,7 @@
 	unsigned char	vc_halfcolor;		/* Color for half intensity mode */
 	unsigned short	vc_complement_mask;	/* [#] Xor mask for mouse pointer */
 	unsigned short	vc_hi_font_mask;	/* [#] Attribute set for upper 256 chars of font or 0 if not supported */
+	struct console_font_op vc_font;		/* Current VC font set */
 	unsigned short	vc_video_erase_char;	/* Background erase character */
 	unsigned short	vc_s_complement_mask;	/* Saved mouse pointer mask */
 	unsigned int	vc_x, vc_y;		/* Cursor position */
diff -Nru a/include/linux/crypto.h b/include/linux/crypto.h
--- a/include/linux/crypto.h	Mon Dec  9 18:46:35 2002
+++ b/include/linux/crypto.h	Mon Dec  9 18:46:35 2002
@@ -58,7 +58,6 @@
  */
 #define CRYPTO_UNSPEC			0
 #define CRYPTO_MAX_ALG_NAME		64
-#define CRYPTO_MAX_CIPHER_BLOCK_SIZE	16
 
 struct scatterlist;
 
@@ -135,6 +134,7 @@
 	                   struct scatterlist *sg, unsigned int nsg);
 	int (*cit_decrypt)(struct crypto_tfm *tfm,
 	                   struct scatterlist *sg, unsigned int nsg);
+	void (*cit_xor_block)(u8 *dst, const u8 *src);
 };
 
 struct digest_tfm {
@@ -161,7 +161,6 @@
 struct crypto_tfm {
 
 	void *crt_ctx;
-	void *crt_work_block;
 	u32 crt_flags;
 	
 	union {
diff -Nru a/include/linux/devfs_fs_kernel.h b/include/linux/devfs_fs_kernel.h
--- a/include/linux/devfs_fs_kernel.h	Mon Dec  9 18:46:50 2002
+++ b/include/linux/devfs_fs_kernel.h	Mon Dec  9 18:46:50 2002
@@ -11,23 +11,10 @@
 
 #define DEVFS_SUPER_MAGIC                0x1373
 
-#define IS_DEVFS_INODE(inode) (DEVFS_SUPER_MAGIC == (inode)->i_sb->s_magic)
-
-#define DEVFS_MINOR(inode) \
-    ({unsigned int m; /* evil GCC trickery */ \
-      ((inode)->i_sb && \
-       ((inode)->i_sb->s_magic==DEVFS_SUPER_MAGIC) && \
-       (devfs_get_maj_min(devfs_get_handle_from_inode((inode)),NULL,&m)==0) \
-      ) ? m : MINOR((inode)->r_dev); })
-
-
 #define DEVFS_FL_NONE           0x000 /* This helps to make code more readable
 				       */
-#define DEVFS_FL_HIDE           0x001 /* Do not show entry in directory list */
 #define DEVFS_FL_AUTO_DEVNUM    0x002 /* Automatically generate device number
 				       */
-#define DEVFS_FL_AOPEN_NOTIFY   0x004 /* Asynchronously notify devfsd on open
-				       */
 #define DEVFS_FL_REMOVABLE      0x008 /* This is a removable media device    */
 #define DEVFS_FL_WAIT           0x010 /* Wait for devfsd to finish           */
 #define DEVFS_FL_CURRENT_OWNER  0x020 /* Set initial ownership to current    */
@@ -67,40 +54,23 @@
 extern devfs_handle_t devfs_mk_dir (devfs_handle_t dir, const char *name,
 				    void *info);
 extern devfs_handle_t devfs_get_handle (devfs_handle_t dir, const char *name,
-					unsigned int major,unsigned int minor,
-					char type, int traverse_symlinks);
-extern void devfs_find_and_unregister (devfs_handle_t dir, const char *name,
-				       unsigned int major, unsigned int minor,
-				       char type, int traverse_symlinks);
-extern int devfs_get_flags (devfs_handle_t de, unsigned int *flags);
-extern int devfs_set_flags (devfs_handle_t de, unsigned int flags);
-extern int devfs_get_maj_min (devfs_handle_t de, 
-			      unsigned int *major, unsigned int *minor);
+					int traverse_symlinks);
 extern devfs_handle_t devfs_get_handle_from_inode (struct inode *inode);
 extern int devfs_generate_path (devfs_handle_t de, char *path, int buflen);
-extern void *devfs_get_ops (devfs_handle_t de);
-extern void devfs_put_ops (devfs_handle_t de);
 extern int devfs_set_file_size (devfs_handle_t de, unsigned long size);
 extern void *devfs_get_info (devfs_handle_t de);
 extern int devfs_set_info (devfs_handle_t de, void *info);
 extern devfs_handle_t devfs_get_parent (devfs_handle_t de);
 extern devfs_handle_t devfs_get_first_child (devfs_handle_t de);
 extern devfs_handle_t devfs_get_next_sibling (devfs_handle_t de);
-extern void devfs_auto_unregister (devfs_handle_t master,devfs_handle_t slave);
-extern devfs_handle_t devfs_get_unregister_slave (devfs_handle_t master);
 extern const char *devfs_get_name (devfs_handle_t de, unsigned int *namelen);
 extern int devfs_only (void);
 extern int devfs_register_tape (devfs_handle_t de);
 extern void devfs_unregister_tape(int num);
-extern void devfs_register_series (devfs_handle_t dir, const char *format,
-				   unsigned int num_entries,
-				   unsigned int flags, unsigned int major,
-				   unsigned int minor_start,
-				   umode_t mode, void *ops, void *info);
 extern int devfs_alloc_major (char type);
 extern void devfs_dealloc_major (char type, int major);
-extern kdev_t devfs_alloc_devnum (char type);
-extern void devfs_dealloc_devnum (char type, kdev_t devnum);
+extern dev_t devfs_alloc_devnum (char type);
+extern void devfs_dealloc_devnum (char type, dev_t devnum);
 extern int devfs_alloc_unique_number (struct unique_numspace *space);
 extern void devfs_dealloc_unique_number (struct unique_numspace *space,
 					 int number);
@@ -147,36 +117,13 @@
 }
 static inline devfs_handle_t devfs_get_handle (devfs_handle_t dir,
 					       const char *name,
-					       unsigned int major,
-					       unsigned int minor,
-					       char type,
 					       int traverse_symlinks)
 {
     return NULL;
 }
-static inline void devfs_find_and_unregister (devfs_handle_t dir,
-					      const char *name,
-					      unsigned int major,
-					      unsigned int minor,
-					      char type, int traverse_symlinks)
-{
-}
 static inline void devfs_remove(const char *fmt, ...)
 {
 }
-static inline int devfs_get_flags (devfs_handle_t de, unsigned int *flags)
-{
-    return 0;
-}
-static inline int devfs_set_flags (devfs_handle_t de, unsigned int flags)
-{
-    return 0;
-}
-static inline int devfs_get_maj_min (devfs_handle_t de, 
-				     unsigned int *major, unsigned int *minor)
-{
-    return 0;
-}
 static inline devfs_handle_t devfs_get_handle_from_inode (struct inode *inode)
 {
     return NULL;
@@ -186,14 +133,6 @@
 {
     return -ENOSYS;
 }
-static inline void *devfs_get_ops (devfs_handle_t de)
-{
-    return NULL;
-}
-static inline void devfs_put_ops (devfs_handle_t de)
-{
-    return;
-}
 static inline int devfs_set_file_size (devfs_handle_t de, unsigned long size)
 {
     return -ENOSYS;
@@ -218,15 +157,6 @@
 {
     return NULL;
 }
-static inline void devfs_auto_unregister (devfs_handle_t master,
-					  devfs_handle_t slave)
-{
-    return;
-}
-static inline devfs_handle_t devfs_get_unregister_slave (devfs_handle_t master)
-{
-    return NULL;
-}
 static inline const char *devfs_get_name (devfs_handle_t de,
 					  unsigned int *namelen)
 {
@@ -243,17 +173,6 @@
 static inline void devfs_unregister_tape(int num)
 {
 }
-static inline void devfs_register_series (devfs_handle_t dir,
-					  const char *format,
-					  unsigned int num_entries,
-					  unsigned int flags,
-					  unsigned int major,
-					  unsigned int minor_start,
-					  umode_t mode, void *ops, void *info)
-{
-    return;
-}
-
 static inline int devfs_alloc_major (char type)
 {
     return -1;
@@ -264,12 +183,12 @@
     return;
 }
 
-static inline kdev_t devfs_alloc_devnum (char type)
+static inline dev_t devfs_alloc_devnum (char type)
 {
-    return NODEV;
+    return 0;
 }
 
-static inline void devfs_dealloc_devnum (char type, kdev_t devnum)
+static inline void devfs_dealloc_devnum (char type, dev_t devnum)
 {
     return;
 }
diff -Nru a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h	Mon Dec  9 18:46:51 2002
+++ b/include/linux/device.h	Mon Dec  9 18:46:51 2002
@@ -85,6 +85,15 @@
 extern void put_bus(struct bus_type * bus);
 
 
+/* iterator helpers for buses */
+
+int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data,
+		     int (*fn)(struct device *, void *));
+
+int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, 
+		     void * data, int (*fn)(struct device_driver *, void *));
+
+
 /* driverfs interface for exporting bus attributes */
 
 struct bus_attribute {
@@ -159,6 +168,7 @@
 	struct subsystem	devsubsys;
 	struct subsystem	drvsubsys;
 	struct list_head	drivers;
+	struct list_head	devices;
 
 	int	(*add_device)(struct device *);
 	void	(*remove_device)(struct device *);
@@ -207,9 +217,7 @@
 	char			* name;
 	struct device_class	* devclass;
 
-	struct kobject		kobj;
-	struct list_head	devices;
-
+	struct subsystem	subsys;
 	u32			devnum;
 
 	int (*add_device)	(struct device *);
@@ -230,10 +238,11 @@
  * and create a driverfs symlink for it.
  */
 struct intf_data {
-	struct list_head	node;
 	struct device_interface	* intf;
 	struct device		* dev;
 	u32			intf_num;
+	struct list_head	dev_entry;
+	struct kobject		kobj;
 };
 
 extern int interface_add_data(struct intf_data *);
@@ -241,9 +250,9 @@
 
 
 struct device {
-	struct list_head g_list;        /* node in depth-first order list */
 	struct list_head node;		/* node in sibling list */
 	struct list_head bus_list;	/* node in bus's list */
+	struct list_head class_list;
 	struct list_head driver_list;
 	struct list_head children;
 	struct list_head intf_list;
@@ -270,6 +279,7 @@
 					   being off. */
 
 	unsigned char *saved_state;	/* saved device state */
+	u64		*dma_mask;	/* dma mask (if dma'able device) */
 
 	void	(*release)(struct device * dev);
 };
@@ -278,12 +288,6 @@
 list_to_dev(struct list_head *node)
 {
 	return list_entry(node, struct device, node);
-}
-
-static inline struct device *
-g_list_to_dev(struct list_head *g_list)
-{
-	return list_entry(g_list, struct device, g_list);
 }
 
 static inline void *
diff -Nru a/include/linux/elf.h b/include/linux/elf.h
--- a/include/linux/elf.h	Mon Dec  9 18:46:35 2002
+++ b/include/linux/elf.h	Mon Dec  9 18:46:35 2002
@@ -448,6 +448,37 @@
 /* Keep this the last entry.  */
 #define R_390_NUM	27
 
+/* s390 relocations defined by the ABIs */
+#define R_390_NONE	0	       /* No reloc.  */
+#define R_390_8		1	       /* Direct 8 bit.	 */
+#define R_390_12	2	       /* Direct 12 bit.  */
+#define R_390_16	3	       /* Direct 16 bit.  */
+#define R_390_32	4	       /* Direct 32 bit.  */
+#define R_390_PC32	5	       /* PC relative 32 bit.  */
+#define R_390_GOT12	6	       /* 12 bit GOT offset.  */
+#define R_390_GOT32	7	       /* 32 bit GOT offset.  */
+#define R_390_PLT32	8	       /* 32 bit PC relative PLT address.  */
+#define R_390_COPY	9	       /* Copy symbol at runtime.  */
+#define R_390_GLOB_DAT	10	       /* Create GOT entry.  */
+#define R_390_JMP_SLOT	11	       /* Create PLT entry.  */
+#define R_390_RELATIVE	12	       /* Adjust by program base.  */
+#define R_390_GOTOFF	13	       /* 32 bit offset to GOT.	 */
+#define R_390_GOTPC	14	       /* 32 bit PC relative offset to GOT.  */
+#define R_390_GOT16	15	       /* 16 bit GOT offset.  */
+#define R_390_PC16	16	       /* PC relative 16 bit.  */
+#define R_390_PC16DBL	17	       /* PC relative 16 bit shifted by 1.  */
+#define R_390_PLT16DBL	18	       /* 16 bit PC rel. PLT shifted by 1.  */
+#define R_390_PC32DBL	19	       /* PC relative 32 bit shifted by 1.  */
+#define R_390_PLT32DBL	20	       /* 32 bit PC rel. PLT shifted by 1.  */
+#define R_390_GOTPCDBL	21	       /* 32 bit PC rel. GOT shifted by 1.  */
+#define R_390_64	22	       /* Direct 64 bit.  */
+#define R_390_PC64	23	       /* PC relative 64 bit.  */
+#define R_390_GOT64	24	       /* 64 bit GOT offset.  */
+#define R_390_PLT64	25	       /* 64 bit PC relative PLT address.  */
+#define R_390_GOTENT	26	       /* 32 bit PC rel. to GOT entry >> 1. */
+/* Keep this the last entry.  */
+#define R_390_NUM	27
+
 /* Legal values for e_flags field of Elf64_Ehdr.  */
 
 #define EF_ALPHA_32BIT		1	/* All addresses are below 2GB */
diff -Nru a/include/linux/errno.h b/include/linux/errno.h
--- a/include/linux/errno.h	Mon Dec  9 18:46:50 2002
+++ b/include/linux/errno.h	Mon Dec  9 18:46:50 2002
@@ -10,6 +10,7 @@
 #define ERESTARTNOINTR	513
 #define ERESTARTNOHAND	514	/* restart if no handler.. */
 #define ENOIOCTLCMD	515	/* No ioctl command */
+#define ERESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */
 
 /* Defined for the NFSv3 protocol */
 #define EBADHANDLE	521	/* Illegal NFS file handle */
diff -Nru a/include/linux/eventpoll.h b/include/linux/eventpoll.h
--- a/include/linux/eventpoll.h	Mon Dec  9 18:46:36 2002
+++ b/include/linux/eventpoll.h	Mon Dec  9 18:46:36 2002
@@ -16,22 +16,25 @@
 
 
 /* Valid opcodes to issue to sys_epoll_ctl() */
-#define EP_CTL_ADD 1
-#define EP_CTL_DEL 2
-#define EP_CTL_MOD 3
+#define EPOLL_CTL_ADD 1
+#define EPOLL_CTL_DEL 2
+#define EPOLL_CTL_MOD 3
 
+struct epoll_event {
+	__u32 events;
+	__u64 data;
+};
 
 #ifdef __KERNEL__
 
 /* Forward declarations to avoid compiler errors */
 struct file;
-struct pollfd;
 
 
 /* Kernel space functions implementing the user space "epoll" API */
 asmlinkage int sys_epoll_create(int size);
-asmlinkage int sys_epoll_ctl(int epfd, int op, int fd, unsigned int events);
-asmlinkage int sys_epoll_wait(int epfd, struct pollfd *events, int maxevents,
+asmlinkage int sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
+asmlinkage int sys_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
 			      int timeout);
 
 /* Used to initialize the epoll bits inside the "struct file" */
diff -Nru a/include/linux/fb.h b/include/linux/fb.h
--- a/include/linux/fb.h	Mon Dec  9 18:46:35 2002
+++ b/include/linux/fb.h	Mon Dec  9 18:46:35 2002
@@ -3,6 +3,7 @@
 
 #include <linux/tty.h>
 #include <asm/types.h>
+#include <asm/io.h>
 
 /* Definitions of frame buffers						*/
 
@@ -17,6 +18,7 @@
 #define FBIOGETCMAP		0x4604
 #define FBIOPUTCMAP		0x4605
 #define FBIOPAN_DISPLAY		0x4606
+#define FBIO_CURSOR            _IOWR('F', 0x08, struct fb_cursor)
 /* 0x4607-0x460B are defined below */
 /* #define FBIOGET_MONITORSPEC	0x460C */
 /* #define FBIOPUT_MONITORSPEC	0x460D */
@@ -208,7 +210,8 @@
 	__u32 vsync_len;		/* length of vertical sync	*/
 	__u32 sync;			/* see FB_SYNC_*		*/
 	__u32 vmode;			/* see FB_VMODE_*		*/
-	__u32 reserved[6];		/* Reserved for future compatibility */
+	__u32 rotate;			/* angle we rotate counter clockwise */
+	__u32 reserved[5];		/* Reserved for future compatibility */
 };
 
 struct fb_cmap {
@@ -262,12 +265,12 @@
 #define ROP_XOR  1
 
 struct fb_copyarea {
-	__u32 sx;	/* screen-relative */
-	__u32 sy;
-	__u32 width;
-	__u32 height;
 	__u32 dx;
 	__u32 dy;
+	__u32 width;
+	__u32 height;
+	__u32 sx;
+	__u32 sy;
 };
 
 struct fb_fillrect {
@@ -280,23 +283,45 @@
 };
 
 struct fb_image {
-	__u32 width;	/* Size of image */
+	__u32 dx;		/* Where to place image */
+	__u32 dy;
+	__u32 width;		/* Size of image */
 	__u32 height;
-	__u16 dx;	/* Where to place image */
-	__u16 dy;
-	__u32 fg_color;	/* Only used when a mono bitmap */
+	__u32 fg_color;		/* Only used when a mono bitmap */
 	__u32 bg_color;
-	__u8  depth;	/* Dpeth of the image */
-	char  *data;	/* Pointer to image data */
+	__u8  depth;		/* Depth of the image */
+	char  *data;		/* Pointer to image data */
+	struct fb_cmap cmap;	/* color map info */
 };
 
-#ifdef __KERNEL__
+/*
+ * hardware cursor control
+ */
 
-#if 1 /* to go away in 2.5.0 */
-extern int GET_FB_IDX(kdev_t rdev);
-#else
-#define GET_FB_IDX(node)	(minor(node))
-#endif
+#define FB_CUR_SETCUR   0x01
+#define FB_CUR_SETPOS   0x02
+#define FB_CUR_SETHOT   0x04
+#define FB_CUR_SETCMAP  0x08
+#define FB_CUR_SETSHAPE 0x10
+#define FB_CUR_SETDEST	0x20
+#define FB_CUR_SETSIZE	0x40
+#define FB_CUR_SETALL   0xFF
+
+struct fbcurpos {
+	__u16 x, y;
+};
+
+struct fb_cursor {
+	__u16 set;		/* what to set */
+	__u16 enable;		/* cursor on/off */
+	__u16 rop;		/* bitop operation */
+	char *mask;		/* cursor mask bits */
+	char *dest;		/* destination */
+	struct fbcurpos hot;	/* cursor hot spot */
+	struct fb_image	image;	/* Cursor image */
+};
+
+#ifdef __KERNEL__
 
 #include <linux/fs.h>
 #include <linux/poll.h>
@@ -316,15 +341,9 @@
     struct module *owner;
     int (*fb_open)(struct fb_info *info, int user);
     int (*fb_release)(struct fb_info *info, int user);
-    /* set settable parameters */
-    int (*fb_set_var)(struct fb_var_screeninfo *var, int con,
-		      struct fb_info *info);		
-    /* get colormap */
-    int (*fb_get_cmap)(struct fb_cmap *cmap, int kspc, int con,
-		       struct fb_info *info);
-    /* set colormap */
-    int (*fb_set_cmap)(struct fb_cmap *cmap, int kspc, int con,
-		       struct fb_info *info);
+    /* For framebuffers with strange non linear layouts */	
+    ssize_t (*fb_read)(struct file *file, char *buf, size_t count, loff_t *ppos);
+    ssize_t (*fb_write)(struct file *file, const char *buf, size_t count, loff_t *ppos);	
     /* checks var and creates a par based on it */
     int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);
     /* set the video mode according to par */
@@ -335,26 +354,29 @@
     /* blank display */
     int (*fb_blank)(int blank, struct fb_info *info);
     /* pan display */
-    int (*fb_pan_display)(struct fb_var_screeninfo *var, int con, struct fb_info *info);
+    int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);
     /* draws a rectangle */
     void (*fb_fillrect)(struct fb_info *info, struct fb_fillrect *rect); 
     /* Copy data from area to another */
     void (*fb_copyarea)(struct fb_info *info, struct fb_copyarea *region); 
     /* Draws a image to the display */
     void (*fb_imageblit)(struct fb_info *info, struct fb_image *image);
+    /* Draws cursor */
+    int (*fb_cursor)(struct fb_info *info, struct fb_cursor *cursor);
+    /* Rotates the display */
+    void (*fb_rotate)(struct fb_info *info, int angle);
     /* perform polling on fb device */
     int (*fb_poll)(struct fb_info *info, poll_table *wait);
+    /* wait for blit idle, optional */
+    int (*fb_sync)(struct fb_info *info);		
     /* perform fb specific ioctl (optional) */
     int (*fb_ioctl)(struct inode *inode, struct file *file, unsigned int cmd,
-		    unsigned long arg, int con, struct fb_info *info);
+		    unsigned long arg, struct fb_info *info);
     /* perform fb specific mmap */
     int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
-    /* switch to/from raster image mode */
-    int (*fb_rasterimg)(struct fb_info *info, int start);
 };
 
 struct fb_info {
-   char modename[40];			/* default video mode */
    kdev_t node;
    int flags;
    int open;                            /* Has this been open already ? */
@@ -362,20 +384,12 @@
    struct fb_var_screeninfo var;        /* Current var */
    struct fb_fix_screeninfo fix;        /* Current fix */
    struct fb_monspecs monspecs;         /* Current Monitor specs */
+   struct fb_cursor cursor;		/* Current cursor */	
    struct fb_cmap cmap;                 /* Current cmap */
    struct fb_ops *fbops;
    char *screen_base;                   /* Virtual address */
-   struct display *disp;		/* initial display variable */
    struct vc_data *display_fg;		/* Console visible on this display */
    int currcon;				/* Current VC. */	
-   char fontname[40];			/* default font name */
-   devfs_handle_t devfs_handle;         /* Devfs handle for new name         */
-   devfs_handle_t devfs_lhandle;        /* Devfs handle for compat. symlink  */
-   int (*changevar)(int);		/* tell console var has changed */
-   int (*switch_con)(int, struct fb_info*);
-					/* tell fb to switch consoles */
-   int (*updatevar)(int, struct fb_info*);
-					/* tell fb to update the vars */
    void *pseudo_palette;                /* Fake palette of 16 colors and 
 					   the cursor's color for non
                                            palette mode */
@@ -389,31 +403,53 @@
 #define FBINFO_FLAG_DEFAULT	0
 #endif
 
-    /*
-     *  `Generic' versions of the frame buffer device operations
-     */
+#if defined(__sparc__)
 
-extern int gen_set_var(struct fb_var_screeninfo *var, 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 gen_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			struct fb_info *info);
-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); 
-extern void cfb_imageblit(struct fb_info *info, struct fb_image *image);
+/* We map all of our framebuffers such that big-endian accesses
+ * are what we want, so the following is sufficient.
+ */
+
+#define fb_readb sbus_readb
+#define fb_readw sbus_readw
+#define fb_readl sbus_readl
+#define fb_writeb sbus_writeb
+#define fb_writew sbus_writew
+#define fb_writel sbus_writel
+#define fb_memset sbus_memset_io
+
+#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__)
+
+#define fb_readb __raw_readb
+#define fb_readw __raw_readw
+#define fb_readl __raw_readl
+#define fb_writeb __raw_writeb
+#define fb_writew __raw_writew
+#define fb_writel __raw_writel
+#define fb_memset memset_io
+
+#else
+
+#define fb_readb(addr) (*(volatile u8 *) (addr))
+#define fb_readw(addr) (*(volatile u16 *) (addr))
+#define fb_readl(addr) (*(volatile u32 *) (addr))
+#define fb_writeb(b,addr) (*(volatile u8 *) (addr) = (b))
+#define fb_writew(b,addr) (*(volatile u16 *) (addr) = (b))
+#define fb_writel(b,addr) (*(volatile u32 *) (addr) = (b))
+#define fb_memset memset
+
+#endif
 
     /*
-     *  Helper functions
+     *  `Generic' versions of the frame buffer device operations
      */
 
-extern void do_install_cmap(int con, struct fb_info *info);
-extern int gen_update_var(int con, struct fb_info *info);
+extern int fb_set_var(struct fb_var_screeninfo *var, struct fb_info *info); 
+extern int fb_pan_display(struct fb_var_screeninfo *var, 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);
+extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
+extern void cfb_fillrect(struct fb_info *info, struct fb_fillrect *rect); 
+extern void cfb_copyarea(struct fb_info *info, struct fb_copyarea *area); 
+extern void cfb_imageblit(struct fb_info *info, struct fb_image *image);
 
 /* drivers/video/fbmem.c */
 extern int register_framebuffer(struct fb_info *fb_info);
@@ -429,12 +465,9 @@
 
 /* drivers/video/fbcmap.c */
 extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp);
+extern void fb_dealloc_cmap(struct fb_cmap *cmap);
 extern void fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to,
 			 int fsfromto);
-extern int fb_get_cmap(struct fb_cmap *cmap, int kspc,
-		       int (*getcolreg)(u_int, u_int *, u_int *, u_int *,
-					u_int *, struct fb_info *),
-		       struct fb_info *fb_info);
 extern int fb_set_cmap(struct fb_cmap *cmap, int kspc, struct fb_info *fb_info);
 extern struct fb_cmap *fb_default_cmap(int len);
 extern void fb_invert_cmaps(void);
@@ -492,55 +525,5 @@
 #endif
 
 #endif /* __KERNEL__ */
-
-#if 1
-
-#define FBCMD_GET_CURRENTPAR	0xDEAD0005
-#define FBCMD_SET_CURRENTPAR	0xDEAD8005
-
-#endif
-
-
-#if 1 /* Preliminary */
-
-   /*
-    *    Hardware Cursor
-    */
-
-#define FBIOGET_FCURSORINFO     0x4607
-#define FBIOGET_VCURSORINFO     0x4608
-#define FBIOPUT_VCURSORINFO     0x4609
-#define FBIOGET_CURSORSTATE     0x460A
-#define FBIOPUT_CURSORSTATE     0x460B
-
-
-struct fb_fix_cursorinfo {
-	__u16 crsr_width;		/* width and height of the cursor in */
-	__u16 crsr_height;		/* pixels (zero if no cursor)	*/
-	__u16 crsr_xsize;		/* cursor size in display pixels */
-	__u16 crsr_ysize;
-	__u16 crsr_color1;		/* colormap entry for cursor color1 */
-	__u16 crsr_color2;		/* colormap entry for cursor color2 */
-};
-
-struct fb_var_cursorinfo {
-	__u16 width;
-	__u16 height;
-	__u16 xspot;
-	__u16 yspot;
-	__u8 data[1];			/* field with [height][width]        */
-};
-
-struct fb_cursorstate {
-	__s16 xoffset;
-	__s16 yoffset;
-	__u16 mode;
-};
-
-#define FB_CURSOR_OFF		0
-#define FB_CURSOR_ON		1
-#define FB_CURSOR_FLASH		2
-
-#endif /* Preliminary */
 
 #endif /* _LINUX_FB_H */
diff -Nru a/include/linux/hdlcdrv.h b/include/linux/hdlcdrv.h
--- a/include/linux/hdlcdrv.h	Mon Dec  9 18:46:50 2002
+++ b/include/linux/hdlcdrv.h	Mon Dec  9 18:46:50 2002
@@ -214,7 +214,7 @@
 
 	struct hdlcdrv_hdlctx {
 		struct hdlcdrv_hdlcbuffer hbuf;
-		int in_hdlc_tx;
+		long in_hdlc_tx;
 		/*
 		 * 0 = send flags
 		 * 1 = send txtail (flags)
diff -Nru a/include/linux/i2c-id.h b/include/linux/i2c-id.h
--- a/include/linux/i2c-id.h	Mon Dec  9 18:46:34 2002
+++ b/include/linux/i2c-id.h	Mon Dec  9 18:46:34 2002
@@ -20,7 +20,7 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.		     */
 /* ------------------------------------------------------------------------- */
 
-/* $Id: i2c-id.h,v 1.52 2002/07/10 13:28:44 abz Exp $ */
+/* $Id: i2c-id.h,v 1.56 2002/10/13 15:50:02 mds Exp $ */
 
 #ifndef I2C_ID_H
 #define I2C_ID_H
@@ -143,6 +143,8 @@
 #define I2C_DRIVERID_SMSC47M1 1031
 #define I2C_DRIVERID_VT1211 1032
 #define I2C_DRIVERID_LM92 1033
+#define I2C_DRIVERID_VT8231 1034
+#define I2C_DRIVERID_SMARTBATT 1035
 
 /*
  * ---- Adapter types ----------------------------------------------------
@@ -161,6 +163,7 @@
 #define I2C_ALGO_ACB 	0x070000	/* ACCESS.bus algorithm         */
 #define I2C_ALGO_IIC    0x080000 	/* ITE IIC bus */
 #define I2C_ALGO_SAA7134 0x090000
+#define I2C_ALGO_MPC824X 0x0a0000	/* Motorola 8240 / 8245         */
 #define I2C_ALGO_EC     0x100000        /* ACPI embedded controller     */
 
 #define I2C_ALGO_MPC8XX 0x110000	/* MPC8xx PowerPC I2C algorithm */
@@ -206,6 +209,9 @@
 /* --- ACPI Embedded controller algorithms                              */
 #define I2C_HW_ACPI_EC          0x00
 
+/* --- MPC824x PowerPC adapters						*/
+#define I2C_HW_MPC824X 0x00	/* Motorola 8240 / 8245                 */
+
 /* --- MPC8xx PowerPC adapters						*/
 #define I2C_HW_MPC8XX_EPON 0x00	/* Eponymous MPC8xx I2C adapter 	*/
 
@@ -225,6 +231,8 @@
 #define I2C_HW_SMBUS_AMD756	0x05
 #define I2C_HW_SMBUS_SIS5595	0x06
 #define I2C_HW_SMBUS_ALI1535	0x07
+#define I2C_HW_SMBUS_SIS630	0x08
+#define I2C_HW_SMBUS_SIS645	0x09
 
 /* --- ISA pseudo-adapter						*/
 #define I2C_HW_ISA 0x00
diff -Nru a/include/linux/i2c.h b/include/linux/i2c.h
--- a/include/linux/i2c.h	Mon Dec  9 18:46:35 2002
+++ b/include/linux/i2c.h	Mon Dec  9 18:46:35 2002
@@ -66,7 +66,6 @@
 struct i2c_client_address_data;
 union i2c_smbus_data;
 
-
 /*
  * The master routines are the ones normally used to transmit data to devices
  * on a bus (or read from them). Apart from two basic transfer functions to 
diff -Nru a/include/linux/if_wanpipe_common.h b/include/linux/if_wanpipe_common.h
--- a/include/linux/if_wanpipe_common.h	Mon Dec  9 18:46:50 2002
+++ b/include/linux/if_wanpipe_common.h	Mon Dec  9 18:46:50 2002
@@ -33,7 +33,7 @@
 	atomic_t command;
 	atomic_t disconnect;
 	atomic_t driver_busy;
-	unsigned char common_critical;
+	long common_critical;
 	struct timer_list *tx_timer;
 	struct sock *sk;		/* Wanpipe Sock bind's here */ 
 	int   (*func) (struct sk_buff *, netdevice_t *, 
diff -Nru a/include/linux/init.h b/include/linux/init.h
--- a/include/linux/init.h	Mon Dec  9 18:46:34 2002
+++ b/include/linux/init.h	Mon Dec  9 18:46:34 2002
@@ -42,10 +42,15 @@
    discard it in modules) */
 #define __init		__attribute__ ((__section__ (".init.text")))
 #define __initdata	__attribute__ ((__section__ (".init.data")))
-#define __exit		__attribute__ ((__section__(".exit.text")))
 #define __exitdata	__attribute__ ((__section__(".exit.data")))
 #define __exit_call	__attribute__ ((unused,__section__ (".exitcall.exit")))
 
+#ifdef MODULE
+#define __exit		__attribute__ ((__section__(".exit.text")))
+#else
+#define __exit		__attribute__ ((unused,__section__(".exit.text")))
+#endif
+
 /* For assembly routines */
 #define __INIT		.section	".init.text","ax"
 #define __FINIT		.previous
@@ -125,14 +130,6 @@
  */
 #define module_exit(x)	__exitcall(x);
 
-/**
- * no_module_init - code needs no initialization.
- *
- * The equivalent of declaring an empty init function which returns 0.
- * Every module must have exactly one module_init() or no_module_init
- * invocation.  */
-#define no_module_init
-
 #else /* MODULE */
 
 /* Don't use these in modules, but some people do... */
@@ -144,11 +141,6 @@
 #define device_initcall(fn)		module_init(fn)
 #define late_initcall(fn)		module_init(fn)
 
-/* Each module knows its own name. */
-#define __DEFINE_MODULE_NAME						\
-	char __module_name[] __attribute__((section(".modulename"))) =	\
-	__stringify(KBUILD_MODNAME)
-
 /* These macros create a dummy inline: gcc 2.9x does not count alias
  as usage, hence the `unused function' warning when __init functions
  are declared static. We use the dummy __*_module_inline functions
@@ -157,13 +149,10 @@
 
 /* Each module must use one module_init(), or one no_module_init */
 #define module_init(initfn)					\
-	__DEFINE_MODULE_NAME;					\
 	static inline initcall_t __inittest(void)		\
 	{ return initfn; }					\
 	int __initfn(void) __attribute__((alias(#initfn)));
 
-#define no_module_init __DEFINE_MODULE_NAME
-
 /* This is only required if you want to be unloadable. */
 #define module_exit(exitfn)					\
 	static inline exitcall_t __exittest(void)		\
@@ -199,6 +188,12 @@
 #define __devexit_p(x) x
 #else
 #define __devexit_p(x) NULL
+#endif
+
+#ifdef MODULE
+#define __exit_p(x) x
+#else
+#define __exit_p(x) NULL
 #endif
 
 #endif /* _LINUX_INIT_H */
diff -Nru a/include/linux/isdn.h b/include/linux/isdn.h
--- a/include/linux/isdn.h	Mon Dec  9 18:46:52 2002
+++ b/include/linux/isdn.h	Mon Dec  9 18:46:52 2002
@@ -408,14 +408,6 @@
 	struct task_struct *profd;                   /* For iprofd                 */
 	struct semaphore  sem;                       /* serialize list access*/
 	unsigned long     global_features;
-#ifdef CONFIG_DEVFS_FS
-	devfs_handle_t devfs_handle_isdninfo;
-	devfs_handle_t devfs_handle_isdnctrl;
-	devfs_handle_t devfs_handle_isdnctrlX[ISDN_MAX_CHANNELS];
-#ifdef CONFIG_ISDN_PPP
-	devfs_handle_t devfs_handle_ipppX[ISDN_MAX_CHANNELS];
-#endif
-#endif /* CONFIG_DEVFS_FS */
 } isdn_dev;
 
 extern isdn_dev *dev;
diff -Nru a/include/linux/kobject.h b/include/linux/kobject.h
--- a/include/linux/kobject.h	Mon Dec  9 18:46:34 2002
+++ b/include/linux/kobject.h	Mon Dec  9 18:46:34 2002
@@ -60,4 +60,13 @@
 	kobject_put(&s->kobj);
 }
 
+struct subsys_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct subsystem *, char *, size_t, loff_t);
+	ssize_t (*store)(struct subsystem *, const char *, size_t, loff_t); 
+};
+
+extern int subsys_create_file(struct subsystem * , struct subsys_attribute *);
+extern void subsys_remove_file(struct subsystem * , struct subsys_attribute *);
+
 #endif /* _KOBJECT_H_ */
diff -Nru a/include/linux/major.h b/include/linux/major.h
--- a/include/linux/major.h	Mon Dec  9 18:46:35 2002
+++ b/include/linux/major.h	Mon Dec  9 18:46:35 2002
@@ -94,6 +94,14 @@
 #define SCSI_DISK6_MAJOR	70
 #define SCSI_DISK7_MAJOR	71
 
+#define SCSI_DISK8_MAJOR	128
+#define SCSI_DISK9_MAJOR	129
+#define SCSI_DISK10_MAJOR	130
+#define SCSI_DISK11_MAJOR	131
+#define SCSI_DISK12_MAJOR	132
+#define SCSI_DISK13_MAJOR	133
+#define SCSI_DISK14_MAJOR	134
+#define SCSI_DISK15_MAJOR	135
 
 #define COMPAQ_SMART2_MAJOR	72
 #define COMPAQ_SMART2_MAJOR1	73
diff -Nru a/include/linux/mca-legacy.h b/include/linux/mca-legacy.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/mca-legacy.h	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,68 @@
+/* -*- mode: c; c-basic-offset: 8 -*- */
+
+/* This is the function prototypes for the old legacy MCA interface
+ *
+ * Please move your driver to the new sysfs based one instead */
+
+#ifndef _LINUX_MCA_LEGACY_H
+#define _LINUX_MCA_LEGACY_H
+
+/* MCA_NOTFOUND is an error condition.  The other two indicate
+ * motherboard POS registers contain the adapter.  They might be
+ * returned by the mca_find_adapter() function, and can be used as
+ * arguments to mca_read_stored_pos().  I'm not going to allow direct
+ * access to the motherboard registers until we run across an adapter
+ * that requires it.  We don't know enough about them to know if it's
+ * safe.
+ *
+ * See Documentation/mca.txt or one of the existing drivers for
+ * more information.
+ */
+#define MCA_NOTFOUND	(-1)
+
+
+
+/* Returns the slot of the first enabled adapter matching id.  User can
+ * specify a starting slot beyond zero, to deal with detecting multiple
+ * devices.  Returns MCA_NOTFOUND if id not found.  Also checks the
+ * integrated adapters.
+ */
+extern int mca_find_adapter(int id, int start);
+extern int mca_find_unused_adapter(int id, int start);
+
+/* adapter state info - returns 0 if no */
+extern int mca_isadapter(int slot);
+extern int mca_isenabled(int slot);
+
+extern int mca_is_adapter_used(int slot);
+extern int mca_mark_as_used(int slot);
+extern void mca_mark_as_unused(int slot);
+
+/* gets a byte out of POS register (stored in memory) */
+extern unsigned char mca_read_stored_pos(int slot, int reg);
+
+/* This can be expanded later.  Right now, it gives us a way of
+ * getting meaningful information into the MCA_info structure,
+ * so we can have a more interesting /proc/mca.
+ */
+extern void mca_set_adapter_name(int slot, char* name);
+extern char* mca_get_adapter_name(int slot);
+
+/* These routines actually mess with the hardware POS registers.  They
+ * temporarily disable the device (and interrupts), so make sure you know
+ * what you're doing if you use them.  Furthermore, writing to a POS may
+ * result in two devices trying to share a resource, which in turn can
+ * result in multiple devices sharing memory spaces, IRQs, or even trashing
+ * hardware.  YOU HAVE BEEN WARNED.
+ *
+ * You can only access slots with this.  Motherboard registers are off
+ * limits.
+ */
+
+/* read a byte from the specified POS register. */
+extern unsigned char mca_read_pos(int slot, int reg);
+
+/* write a byte to the specified POS register. */
+extern void mca_write_pos(int slot, int reg, unsigned char byte);
+
+#endif
diff -Nru a/include/linux/mca.h b/include/linux/mca.h
--- a/include/linux/mca.h	Mon Dec  9 18:46:35 2002
+++ b/include/linux/mca.h	Mon Dec  9 18:46:35 2002
@@ -6,6 +6,14 @@
 #ifndef _LINUX_MCA_H
 #define _LINUX_MCA_H
 
+/* FIXME: This shouldn't happen, but we need everything that previously
+ * included mca.h to compile.  Take it out later when the MCA #includes
+ * are sorted out */
+#include <linux/device.h>
+
+/* get the platform specific defines */
+#include <asm/mca.h>
+
 /* The detection of MCA bus is done in the real mode (using BIOS).
  * The information is exported to the protected code, where this
  * variable is set to one in case MCA bus was detected.
@@ -14,58 +22,6 @@
 extern int  MCA_bus;
 #endif
 
-/* Maximal number of MCA slots - actually, some machines have less, but
- * they all have sufficient number of POS registers to cover 8.
- */
-#define MCA_MAX_SLOT_NR  8
-
-/* MCA_NOTFOUND is an error condition.  The other two indicate
- * motherboard POS registers contain the adapter.  They might be
- * returned by the mca_find_adapter() function, and can be used as
- * arguments to mca_read_stored_pos().  I'm not going to allow direct
- * access to the motherboard registers until we run across an adapter
- * that requires it.  We don't know enough about them to know if it's
- * safe.
- *
- * See Documentation/mca.txt or one of the existing drivers for
- * more information.
- */
-#define MCA_NOTFOUND	(-1)
-#define MCA_INTEGSCSI	(MCA_MAX_SLOT_NR)
-#define MCA_INTEGVIDEO	(MCA_MAX_SLOT_NR+1)
-#define MCA_MOTHERBOARD (MCA_MAX_SLOT_NR+2)
-
-/* Max number of adapters, including both slots and various integrated
- * things.
- */
-#define MCA_NUMADAPTERS (MCA_MAX_SLOT_NR+3)
-
-/* Returns the slot of the first enabled adapter matching id.  User can
- * specify a starting slot beyond zero, to deal with detecting multiple
- * devices.  Returns MCA_NOTFOUND if id not found.  Also checks the
- * integrated adapters.
- */
-extern int mca_find_adapter(int id, int start);
-extern int mca_find_unused_adapter(int id, int start);
-
-/* adapter state info - returns 0 if no */
-extern int mca_isadapter(int slot);
-extern int mca_isenabled(int slot);
-
-extern int mca_is_adapter_used(int slot);
-extern int mca_mark_as_used(int slot);
-extern void mca_mark_as_unused(int slot);
-
-/* gets a byte out of POS register (stored in memory) */
-extern unsigned char mca_read_stored_pos(int slot, int reg);
-
-/* This can be expanded later.  Right now, it gives us a way of
- * getting meaningful information into the MCA_info structure,
- * so we can have a more interesting /proc/mca.
- */
-extern void mca_set_adapter_name(int slot, char* name);
-extern char* mca_get_adapter_name(int slot);
-
 /* This sets up an information callback for /proc/mca/slot?.  The
  * function is called with the buffer, slot, and device pointer (or
  * some equally informative context information, or nothing, if you
@@ -78,28 +34,115 @@
  * nastiness.
  */
 typedef int (*MCA_ProcFn)(char* buf, int slot, void* dev);
-extern void mca_set_adapter_procfn(int slot, MCA_ProcFn, void* dev);
-
-/* These routines actually mess with the hardware POS registers.  They
- * temporarily disable the device (and interrupts), so make sure you know
- * what you're doing if you use them.  Furthermore, writing to a POS may
- * result in two devices trying to share a resource, which in turn can
- * result in multiple devices sharing memory spaces, IRQs, or even trashing
- * hardware.  YOU HAVE BEEN WARNED.
- *
- * You can only access slots with this.  Motherboard registers are off
- * limits.
- */
-
-/* read a byte from the specified POS register. */
-extern unsigned char mca_read_pos(int slot, int reg);
-
-/* write a byte to the specified POS register. */
-extern void mca_write_pos(int slot, int reg, unsigned char byte);
 
 /* Should only be called by the NMI interrupt handler, this will do some
  * fancy stuff to figure out what might have generated a NMI.
  */
 extern void mca_handle_nmi(void);
+
+enum MCA_AdapterStatus {
+	MCA_ADAPTER_NORMAL = 0,
+	MCA_ADAPTER_NONE = 1,
+	MCA_ADAPTER_DISABLED = 2,
+	MCA_ADAPTER_ERROR = 3
+};
+
+struct mca_device {
+	u64			dma_mask;
+	int			pos_id;
+	int			slot;
+
+	/* index into id_table, set by the bus match routine */
+	int			index;
+
+	/* is there a driver installed? 0 - No, 1 - Yes */
+	int			driver_loaded;
+	/* POS registers */
+	unsigned char		pos[8];
+	/* if a pseudo adapter of the motherboard, this is the motherboard
+	 * register value to use for setup cycles */
+	short			pos_register;
+	
+	enum MCA_AdapterStatus	status;
+#ifdef CONFIG_MCA_PROC_FS
+	/* name of the proc/mca file */
+	char			procname[8];
+	/* /proc info callback */
+	MCA_ProcFn		procfn;
+	/* device/context info for proc callback */
+	void			*proc_dev;
+#endif
+	struct device		dev;
+};
+#define to_mca_device(mdev) container_of(mdev, struct mca_device, dev)
+
+struct mca_bus_accessor_functions {
+	unsigned char	(*mca_read_pos)(struct mca_device *, int reg);
+	void		(*mca_write_pos)(struct mca_device *, int reg,
+					 unsigned char byte);
+	int		(*mca_transform_irq)(struct mca_device *, int irq);
+	int		(*mca_transform_ioport)(struct mca_device *,
+						  int region);
+	void *		(*mca_transform_memory)(struct mca_device *,
+						void *memory);
+};
+
+struct mca_bus {
+	u64			default_dma_mask;
+	int			number;
+	struct mca_bus_accessor_functions f;
+	struct device		dev;
+};
+#define to_mca_bus(mdev) container_of(mdev, struct mca_bus, dev)
+
+struct mca_driver {
+	const short		*id_table;
+	void			*driver_data;
+	struct device_driver	driver;
+};
+#define to_mca_driver(mdriver) container_of(mdriver, struct mca_driver, driver)
+
+/* Ongoing supported API functions */
+extern struct mca_device *mca_find_device_by_slot(int slot);
+extern int mca_system_init(void);
+extern struct mca_bus *mca_attach_bus(int);
+
+extern unsigned char mca_device_read_stored_pos(struct mca_device *mca_dev,
+						int reg);
+extern unsigned char mca_device_read_pos(struct mca_device *mca_dev, int reg);
+extern void mca_device_write_pos(struct mca_device *mca_dev, int reg,
+				 unsigned char byte);
+extern int mca_device_transform_irq(struct mca_device *mca_dev, int irq);
+extern int mca_device_transform_ioport(struct mca_device *mca_dev, int port);
+extern void *mca_device_transform_memory(struct mca_device *mca_dev,
+					 void *mem);
+extern int mca_device_claimed(struct mca_device *mca_dev);
+extern void mca_device_set_claim(struct mca_device *mca_dev, int val);
+extern enum MCA_AdapterStatus mca_device_status(struct mca_device *mca_dev);
+
+extern struct bus_type mca_bus_type;
+
+extern int mca_register_driver(struct mca_driver *drv);
+extern void mca_unregister_driver(struct mca_driver *drv);
+
+/* WARNING: only called by the boot time device setup */
+extern int mca_register_device(int bus, struct mca_device *mca_dev);
+
+#ifdef CONFIG_MCA_LEGACY
+#include <linux/mca-legacy.h>
+#endif
+
+#ifdef CONFIG_MCA_PROC_FS
+extern void mca_do_proc_init(void);
+extern void mca_set_adapter_procfn(int slot, MCA_ProcFn, void* dev);
+#else
+static inline void mca_do_proc_init(void)
+{
+}
+
+static inline void mca_set_adapter_procfn(int slot, MCA_ProcFn *fn, void* dev)
+{
+}
+#endif
 
 #endif /* _LINUX_MCA_H */
diff -Nru a/include/linux/module.h b/include/linux/module.h
--- a/include/linux/module.h	Mon Dec  9 18:46:50 2002
+++ b/include/linux/module.h	Mon Dec  9 18:46:50 2002
@@ -15,6 +15,7 @@
 #include <linux/cache.h>
 #include <linux/kmod.h>
 #include <linux/elf.h>
+#include <linux/stringify.h>
 
 #include <asm/module.h>
 #include <asm/uaccess.h> /* For struct exception_table_entry */
@@ -31,6 +32,11 @@
 #define MODULE_PARM_DESC(var,desc)
 #define print_modules()
 
+/* v850 toolchain uses a `_' prefix for all user symbols */
+#ifndef MODULE_SYMBOL_PREFIX
+#define MODULE_SYMBOL_PREFIX ""
+#endif
+
 #define MODULE_NAME_LEN (64 - sizeof(unsigned long))
 struct kernel_symbol
 {
@@ -40,11 +46,19 @@
 
 #ifdef MODULE
 
-#define MODULE_GENERIC_TABLE(gtype,name)	\
-static const unsigned long __module_##gtype##_size \
-  __attribute__ ((unused)) = sizeof(struct gtype##_id); \
-static const struct gtype##_id * __module_##gtype##_table \
-  __attribute__ ((unused)) = name
+#ifdef KBUILD_MODNAME
+static const char __module_name[MODULE_NAME_LEN] __attribute__((section(".gnu.linkonce.modname"))) = \
+  __stringify(KBUILD_MODNAME);
+#endif
+
+/* For replacement modutils, use an alias not a pointer. */
+#define MODULE_GENERIC_TABLE(gtype,name)			\
+static const unsigned long __module_##gtype##_size		\
+  __attribute__ ((unused)) = sizeof(struct gtype##_id);		\
+static const struct gtype##_id * __module_##gtype##_table	\
+  __attribute__ ((unused)) = name;				\
+extern const struct gtype##_id __mod_##gtype##_table		\
+  __attribute__ ((unused, alias(__stringify(name))))
 
 /* This is magically filled in by the linker, but THIS_MODULE must be
    a constant so it works in initializers. */
@@ -86,13 +100,13 @@
 /* Get/put a kernel symbol (calls must be symmetric) */
 void *__symbol_get(const char *symbol);
 void *__symbol_get_gpl(const char *symbol);
-#define symbol_get(x) ((typeof(&x))(__symbol_get(#x)))
+#define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x)))
 
 /* For every exported symbol, place a struct in the __ksymtab section */
 #define EXPORT_SYMBOL(sym)				\
 	const struct kernel_symbol __ksymtab_##sym	\
 	__attribute__((section("__ksymtab")))		\
-	= { (unsigned long)&sym, #sym }
+	= { (unsigned long)&sym, MODULE_SYMBOL_PREFIX #sym }
 
 #define EXPORT_SYMBOL_NOVERS(sym) EXPORT_SYMBOL(sym)
 #define EXPORT_SYMBOL_GPL(sym) EXPORT_SYMBOL(sym)
@@ -166,7 +180,7 @@
 #ifdef CONFIG_MODULE_UNLOAD
 
 void __symbol_put(const char *symbol);
-#define symbol_put(x) __symbol_put(#x)
+#define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x)
 void symbol_put_addr(void *addr);
 
 /* We only need protection against local interrupts. */
@@ -306,12 +320,7 @@
 /* Old-style "I'll just call it init_module and it'll be run at
    insert".  Use module_init(myroutine) instead. */
 #ifdef MODULE
-/* Used as "int init_module(void) { ... }".  Get funky to insert modname. */
-#define init_module(voidarg)						\
-	__initfn(void);							\
-	char __module_name[] __attribute__((section(".modulename"))) =	\
-	__stringify(KBUILD_MODNAME);					\
-	int __initfn(void)
+#define init_module(voidarg) __initfn(void)
 #define cleanup_module(voidarg) __exitfn(void)
 #endif
 
diff -Nru a/include/linux/mroute.h b/include/linux/mroute.h
--- a/include/linux/mroute.h	Mon Dec  9 18:46:37 2002
+++ b/include/linux/mroute.h	Mon Dec  9 18:46:37 2002
@@ -126,6 +126,8 @@
  */
 
 #ifdef __KERNEL__
+#include <net/sock.h>
+
 extern int ip_mroute_setsockopt(struct sock *, int, char *, int);
 extern int ip_mroute_getsockopt(struct sock *, int, char *, int *);
 extern int ipmr_ioctl(struct sock *sk, int cmd, unsigned long arg);
diff -Nru a/include/linux/msdos_fs_sb.h b/include/linux/msdos_fs_sb.h
--- a/include/linux/msdos_fs_sb.h	Mon Dec  9 18:46:37 2002
+++ b/include/linux/msdos_fs_sb.h	Mon Dec  9 18:46:37 2002
@@ -8,7 +8,7 @@
 struct fat_mount_options {
 	uid_t fs_uid;
 	gid_t fs_gid;
-	unsigned short fs_umask;
+	unsigned short fs_fmask;
 	unsigned short fs_dmask;
 	unsigned short codepage;  /* Codepage for shortname conversions */
 	char *iocharset;          /* Charset used for filename input/display */
diff -Nru a/include/linux/nbd.h b/include/linux/nbd.h
--- a/include/linux/nbd.h	Mon Dec  9 18:46:51 2002
+++ b/include/linux/nbd.h	Mon Dec  9 18:46:51 2002
@@ -26,13 +26,6 @@
 	NBD_CMD_DISC = 2
 };
 
-#ifdef MAJOR_NR
-
-#include <asm/semaphore.h>
-
-#define LOCAL_END_REQUEST
-
-#include <linux/blk.h>
 
 #ifdef PARANOIA
 extern int requests_in;
@@ -41,30 +34,6 @@
 
 #define nbd_cmd(req) ((req)->cmd[0])
 
-static void
-nbd_end_request(struct request *req)
-{
-	struct bio *bio;
-	unsigned nsect;
-	unsigned long flags;
-	int uptodate = (req->errors == 0) ? 1 : 0;
-	request_queue_t *q = req->q;
-
-#ifdef PARANOIA
-	requests_out++;
-#endif
-	spin_lock_irqsave(q->queue_lock, flags);
-	while((bio = req->bio) != NULL) {
-		nsect = bio_sectors(bio);
-		blk_finished_io(nsect);
-		req->bio = bio->bi_next;
-		bio->bi_next = NULL;
-		bio_endio(bio, nsect << 9, uptodate ? 0 : -EIO);
-	}
-	blk_put_request(req);
-	spin_unlock_irqrestore(q->queue_lock, flags);
-}
-
 #define MAX_NBD 128
 
 struct nbd_device {
@@ -84,7 +53,6 @@
 	int blksize_bits;
 	u64 bytesize;
 };
-#endif
 
 /* This now IS in some kind of include file...	*/
 
diff -Nru a/include/linux/netdevice.h b/include/linux/netdevice.h
--- a/include/linux/netdevice.h	Mon Dec  9 18:46:51 2002
+++ b/include/linux/netdevice.h	Mon Dec  9 18:46:51 2002
@@ -207,7 +207,8 @@
 	__LINK_STATE_PRESENT,
 	__LINK_STATE_SCHED,
 	__LINK_STATE_NOCARRIER,
-	__LINK_STATE_RX_SCHED
+	__LINK_STATE_RX_SCHED,
+	__LINK_STATE_LINKWATCH_PENDING
 };
 
 
@@ -631,6 +632,8 @@
  * who is responsible for serialization of these calls.
  */
 
+extern void linkwatch_fire_event(struct net_device *dev);
+
 static inline int netif_carrier_ok(struct net_device *dev)
 {
 	return !test_bit(__LINK_STATE_NOCARRIER, &dev->state);
@@ -640,14 +643,16 @@
 
 static inline void netif_carrier_on(struct net_device *dev)
 {
-	clear_bit(__LINK_STATE_NOCARRIER, &dev->state);
+	if (test_and_clear_bit(__LINK_STATE_NOCARRIER, &dev->state))
+		linkwatch_fire_event(dev);
 	if (netif_running(dev))
 		__netdev_watchdog_up(dev);
 }
 
 static inline void netif_carrier_off(struct net_device *dev)
 {
-	set_bit(__LINK_STATE_NOCARRIER, &dev->state);
+	if (!test_and_set_bit(__LINK_STATE_NOCARRIER, &dev->state))
+		linkwatch_fire_event(dev);
 }
 
 /* Hot-plugging. */
diff -Nru a/include/linux/page-flags.h b/include/linux/page-flags.h
--- a/include/linux/page-flags.h	Mon Dec  9 18:46:50 2002
+++ b/include/linux/page-flags.h	Mon Dec  9 18:46:50 2002
@@ -72,6 +72,7 @@
 
 #define PG_direct		16	/* ->pte_chain points directly at pte */
 #define PG_mappedtodisk		17	/* Has blocks allocated on-disk */
+#define PG_reclaim		18	/* To be recalimed asap */
 
 /*
  * Global page accounting.  One instance per CPU.  Only unsigned longs are
@@ -238,6 +239,11 @@
 #define PageMappedToDisk(page)	test_bit(PG_mappedtodisk, &(page)->flags)
 #define SetPageMappedToDisk(page) set_bit(PG_mappedtodisk, &(page)->flags)
 #define ClearPageMappedToDisk(page) clear_bit(PG_mappedtodisk, &(page)->flags)
+
+#define PageReclaim(page)	test_bit(PG_reclaim, &(page)->flags)
+#define SetPageReclaim(page)	set_bit(PG_reclaim, &(page)->flags)
+#define ClearPageReclaim(page)	clear_bit(PG_reclaim, &(page)->flags)
+#define TestClearPageReclaim(page) test_and_clear_bit(PG_reclaim, &(page)->flags)
 
 /*
  * The PageSwapCache predicate doesn't use a PG_flag at this time,
diff -Nru a/include/linux/pci.h b/include/linux/pci.h
--- a/include/linux/pci.h	Mon Dec  9 18:46:37 2002
+++ b/include/linux/pci.h	Mon Dec  9 18:46:37 2002
@@ -65,9 +65,9 @@
 #define  PCI_HEADER_TYPE_CARDBUS 2
 
 #define PCI_BIST		0x0f	/* 8 bits */
-#define PCI_BIST_CODE_MASK	0x0f	/* Return result */
-#define PCI_BIST_START		0x40	/* 1 to start BIST, 2 secs or less */
-#define PCI_BIST_CAPABLE	0x80	/* 1 if BIST capable */
+#define  PCI_BIST_CODE_MASK	0x0f	/* Return result */
+#define  PCI_BIST_START		0x40	/* 1 to start BIST, 2 secs or less */
+#define  PCI_BIST_CAPABLE	0x80	/* 1 if BIST capable */
 
 /*
  * Base addresses specify locations in memory or I/O space.
@@ -195,6 +195,7 @@
 #define  PCI_CAP_ID_SLOTID	0x04	/* Slot Identification */
 #define  PCI_CAP_ID_MSI		0x05	/* Message Signalled Interrupts */
 #define  PCI_CAP_ID_CHSWP	0x06	/* CompactPCI HotSwap */
+#define  PCI_CAP_ID_PCIX	0x07	/* PCI-X */
 #define PCI_CAP_LIST_NEXT	1	/* Next capability in the list */
 #define PCI_CAP_FLAGS		2	/* Capability defined flags (16 bits) */
 #define PCI_CAP_SIZEOF		4
@@ -251,6 +252,13 @@
 #define  PCI_AGP_COMMAND_RATE1	0x0001	/* Use 1x rate */
 #define PCI_AGP_SIZEOF		12
 
+/* Vital Product Data */
+
+#define PCI_VPD_ADDR		2	/* Address to access (15 bits!) */
+#define  PCI_VPD_ADDR_MASK	0x7fff	/* Address mask */
+#define  PCI_VPD_ADDR_F		0x8000	/* Write 0, 1 indicates completion */
+#define PCI_VPD_DATA		4	/* 32-bits of data returned here */
+
 /* Slot Identification */
 
 #define PCI_SID_ESR		2	/* Expansion Slot Register */
@@ -271,6 +279,37 @@
 #define PCI_MSI_DATA_32		8	/* 16 bits of data for 32-bit devices */
 #define PCI_MSI_DATA_64		12	/* 16 bits of data for 64-bit devices */
 
+/* CompactPCI Hotswap Register */
+
+#define PCI_CHSWP_CSR		2	/* Control and Status Register */
+#define  PCI_CHSWP_DHA		0x01	/* Device Hiding Arm */
+#define  PCI_CHSWP_EIM		0x02	/* ENUM# Signal Mask */
+#define  PCI_CHSWP_PIE		0x04	/* Pending Insert or Extract */
+#define  PCI_CHSWP_LOO		0x08	/* LED On / Off */
+#define  PCI_CHSWP_PI		0x30	/* Programming Interface */
+#define  PCI_CHSWP_EXT		0x40	/* ENUM# status - extraction */
+#define  PCI_CHSWP_INS		0x80	/* ENUM# status - insertion */
+
+/* PCI-X registers */
+
+#define PCI_X_CMD		2	/* Modes & Features */
+#define  PCI_X_CMD_DPERR_E	0x0001	/* Data Parity Error Recovery Enable */
+#define  PCI_X_CMD_ERO		0x0002	/* Enable Relaxed Ordering */
+#define  PCI_X_CMD_MAX_READ	0x000c	/* Max Memory Read Byte Count */
+#define  PCI_X_CMD_MAX_SPLIT	0x0070	/* Max Outstanding Split Transactions */
+#define PCI_X_DEVFN		4	/* A copy of devfn. */
+#define PCI_X_BUSNR		5	/* Bus segment number */
+#define PCI_X_STATUS		6	/* PCI-X capabilities */
+#define  PCI_X_STATUS_64BIT	0x0001	/* 64-bit device */
+#define  PCI_X_STATUS_133MHZ	0x0002	/* 133 MHz capable */
+#define  PCI_X_STATUS_SPL_DISC	0x0004	/* Split Completion Discarded */
+#define  PCI_X_STATUS_UNX_SPL	0x0008	/* Unexpected Split Completion */
+#define  PCI_X_STATUS_COMPLEX	0x0010	/* Device Complexity */
+#define  PCI_X_STATUS_MAX_READ	0x0060	/* Designed Maximum Memory Read Count */
+#define  PCI_X_STATUS_MAX_SPLIT	0x0380	/* Design Max Outstanding Split Trans */
+#define  PCI_X_STATUS_MAX_CUM	0x1c00	/* Designed Max Cumulative Read Size */
+#define  PCI_X_STATUS_SPL_ERR	0x2000	/* Rcvd Split Completion Error Msg */
+
 /* Include the ID list */
 
 #include <linux/pci_ids.h>
@@ -344,7 +383,6 @@
 	u8		rom_base_reg;	/* which config register controls the ROM */
 
 	struct pci_driver *driver;	/* which driver has allocated this device */
-	void		*driver_data;	/* data private to the driver */
 	u64		dma_mask;	/* Mask of the bits of bus address this
 					   device implements.  Normally this is
 					   0xffffffff.  You only need to change
@@ -748,17 +786,17 @@
 	  pci_resource_start((dev),(bar)) + 1))
 
 /* Similar to the helpers above, these manipulate per-pci_dev
- * driver-specific data.  Currently stored as pci_dev::driver_data,
- * a void pointer, but it is not present on older kernels.
+ * driver-specific data.  They are really just a wrapper around
+ * the generic device structure functions of these calls.
  */
 static inline void *pci_get_drvdata (struct pci_dev *pdev)
 {
-	return pdev->driver_data;
+	return dev_get_drvdata(&pdev->dev);
 }
 
 static inline void pci_set_drvdata (struct pci_dev *pdev, void *data)
 {
-	pdev->driver_data = data;
+	dev_set_drvdata(&pdev->dev, data);
 }
 
 /*
diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h
--- a/include/linux/pci_ids.h	Mon Dec  9 18:46:36 2002
+++ b/include/linux/pci_ids.h	Mon Dec  9 18:46:36 2002
@@ -485,7 +485,6 @@
 #define PCI_VENDOR_ID_FD		0x1036
 #define PCI_DEVICE_ID_FD_36C70		0x0000
 
-#define PCI_VENDOR_ID_SIS		0x1039
 #define PCI_VENDOR_ID_SI		0x1039
 #define PCI_DEVICE_ID_SI_5591_AGP	0x0001
 #define PCI_DEVICE_ID_SI_6202		0x0002
@@ -935,12 +934,28 @@
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2	0x0151
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA	0x0152
 #define PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO	0x0153
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_460	0x0170
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440	0x0171
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420	0x0172
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO	0x0174
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO	0x0175
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO_M32 0x0176
+#define PCI_DEVICE_ID_NVIDIA_QUADRO4_500XGL	0x0178
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO_M64 0x0179
+#define PCI_DEVICE_ID_NVIDIA_QUADRO4_200	0x017A
+#define PCI_DEVICE_ID_NVIDIA_QUADRO4_550XGL	0x017B
+#define PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL	0x017C
 #define PCI_DEVICE_ID_NVIDIA_IGEFORCE2		0x01a0
-#define PCI_DEVICE_ID_NVIDIA_NFORCE_IDE		0x01bc
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE3		0x0200
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE3_1		0x0201
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE3_2		0x0202
 #define PCI_DEVICE_ID_NVIDIA_QUADRO_DDC		0x0203
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4600	0x0250
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4400	0x0251
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200	0x0253
+#define PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL	0x0258
+#define PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL	0x0259
+#define PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL	0x025B
 
 #define PCI_VENDOR_ID_IMS		0x10e0
 #define PCI_DEVICE_ID_IMS_8849		0x8849
@@ -1604,6 +1619,7 @@
 #define PCI_DEVICE_ID_TIGON3_5702FE	0x164d
 #define PCI_DEVICE_ID_TIGON3_5702X	0x16a6
 #define PCI_DEVICE_ID_TIGON3_5703X	0x16a7
+#define PCI_DEVICE_ID_BCM4401		0x4401
 
 #define PCI_VENDOR_ID_SYBA		0x1592
 #define PCI_DEVICE_ID_SYBA_2P_EPP	0x0782
diff -Nru a/include/linux/pnp.h b/include/linux/pnp.h
--- a/include/linux/pnp.h	Mon Dec  9 18:46:51 2002
+++ b/include/linux/pnp.h	Mon Dec  9 18:46:51 2002
@@ -1,3 +1,9 @@
+/*
+ * Linux Plug and Play Support
+ * Copyright by Adam Belay <ambx1@neo.rr.com>
+ *
+ */
+
 #ifndef _LINUX_PNP_H
 #define _LINUX_PNP_H
 
@@ -5,110 +11,213 @@
 
 #include <linux/device.h>
 #include <linux/list.h>
+#include <linux/errno.h>
 
 
-/* Device Managemnt */
+/*
+ * Device Managemnt
+ */
 
 #define DEVICE_COUNT_IRQ	2
 #define DEVICE_COUNT_DMA	2
 #define DEVICE_COUNT_RESOURCE	12
+#define MAX_DEVICES		8
 
 struct pnp_resource;
 struct pnp_protocol;
+struct pnp_id;
 
-struct pnp_card {			/* this is for ISAPNP */ 
-	struct list_head node;		/* node in list of cards */
+struct pnp_card {
 	char name[80];
 	unsigned char number;		/* card number */
-	struct list_head ids;		/* stores all supported dev ids */
+	struct list_head global_list;	/* node in global list of cards */
+	struct list_head protocol_list;	/* node in protocol's list of cards */
 	struct list_head devices;	/* devices attached to the card */
+	struct pnp_protocol * protocol;
+	struct pnp_id * id;		/* contains supported EISA IDs*/
+
 	unsigned char	pnpver;		/* Plug & Play version */
 	unsigned char	productver;	/* product version */
 	unsigned int	serial;		/* serial number */
 	unsigned char	checksum;	/* if zero - checksum passed */
+	void	      * protocol_data;	/* Used to store protocol specific data */
+
+	struct pnpc_driver * driver;	/* pointer to the driver bound to this device */
+	struct list_head rdevs;		/* a list of devices requested by the card driver */
 	struct proc_dir_entry *procdir;	/* directory entry in /proc/bus/isapnp */
+	struct	device	dev;		/* Driver Model device interface */
 };
 
-#define to_pnp_card(n) list_entry(n, struct pnp_card, node)
+#define global_to_pnp_card(n) list_entry(n, struct pnp_card, global_list)
+#define protocol_to_pnp_card(n) list_entry(n, struct pnp_card, protocol_list)
+#define to_pnp_card(n) list_entry(n, struct pnp_card, dev)
+#define pnp_for_each_card(card) \
+	for(dev = global_to_pnp_card(pnp_cards.next); \
+	dev != global_to_pnp_card(&cards); \
+	dev = global_to_pnp_card(card>global_list.next))
+
+static inline void *pnpc_get_drvdata (struct pnp_card *pcard)
+{
+	return dev_get_drvdata(&pcard->dev);
+}
+
+static inline void pnpc_set_drvdata (struct pnp_card *pcard, void *data)
+{
+	dev_set_drvdata(&pcard->dev, data);
+}
+
+static inline void *pnpc_get_protodata (struct pnp_card *pcard)
+{
+	return pcard->protocol_data;
+}
+
+static inline void pnpc_set_protodata (struct pnp_card *pcard, void *data)
+{
+	pcard->protocol_data = data;
+}
 
 struct pnp_dev {
 	char name[80];			/* device name */
 	int active;			/* status of the device */
 	int ro;				/* read only */
-	struct list_head dev_list;	/* node in list of device's protocol */
-	struct list_head global_list;
-	struct list_head card_list;
+	struct list_head global_list;	/* node in global list of devices */
+	struct list_head protocol_list;	/* node in list of device's protocol */
+	struct list_head card_list;	/* node in card's list of devices */
+	struct list_head rdev_list;	/* node in cards list of requested devices */
 	struct pnp_protocol * protocol;
-	struct pnp_card *card;
+	struct pnp_card * card;
+	struct pnp_id * id;		/* contains supported EISA IDs*/
 
+	void * protocol_data;		/* Used to store protocol specific data */
 	unsigned char number;		/* must be unique */
 	unsigned short	regs;		/* ISAPnP: supported registers */
-	struct list_head ids;		/* stores all supported dev ids */
+	
 	struct pnp_resources *res;	/* possible resource information */
 	struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */
 	struct resource dma_resource[DEVICE_COUNT_DMA];
 	struct resource irq_resource[DEVICE_COUNT_IRQ];
 
-	struct pnp_driver * driver;	/* which driver has allocated this device */
+	struct pnp_driver * driver;	/* pointer to the driver bound to this device */
 	struct	device	    dev;	/* Driver Model device interface */
-	void  		  * driver_data;/* data private to the driver */
-	void		  * protocol_data;
+	int		    flags;	/* used by protocols */
 	struct proc_dir_entry *procent;	/* device entry in /proc/bus/isapnp */
 };
 
 #define global_to_pnp_dev(n) list_entry(n, struct pnp_dev, global_list)
 #define card_to_pnp_dev(n) list_entry(n, struct pnp_dev, card_list)
-#define protocol_to_pnp_dev(n) list_entry(n, struct pnp_dev, dev_list)
+#define protocol_to_pnp_dev(n) list_entry(n, struct pnp_dev, protocol_list)
 #define	to_pnp_dev(n) container_of(n, struct pnp_dev, dev)
 #define pnp_for_each_dev(dev) \
 	for(dev = global_to_pnp_dev(pnp_global.next); \
 	dev != global_to_pnp_dev(&pnp_global); \
 	dev = global_to_pnp_dev(dev->global_list.next))
 
+static inline void *pnp_get_drvdata (struct pnp_dev *pdev)
+{
+	return dev_get_drvdata(&pdev->dev);
+}
+
+static inline void pnp_set_drvdata (struct pnp_dev *pdev, void *data)
+{
+	dev_set_drvdata(&pdev->dev, data);
+}
+
+static inline void *pnp_get_protodata (struct pnp_dev *pdev)
+{
+	return pdev->protocol_data;
+}
+
+static inline void pnp_set_protodata (struct pnp_dev *pdev, void *data)
+{
+	pdev->protocol_data = data;
+}
+
 struct pnp_fixup {
 	char id[7];
 	void (*quirk_function)(struct pnp_dev *dev);	/* fixup function */
 };
 
+
 /*
- * Linux Plug and Play Support
- * Copyright by Adam Belay <ambx1@neo.rr.com>
- *
+ * Driver Management
  */
 
-/* Driver Management */
-
 struct pnp_id {
 	char id[7];
+	struct pnp_id * next;
+};
+
+struct pnp_device_id {
+	char id[7];
 	unsigned long driver_data;	/* data private to the driver */
-	struct list_head id_list;	/* node in card's or device's list */
 };
 
-#define to_pnp_id(n) list_entry(n, struct pnp_id, id_list)
+struct pnp_card_id {
+	char id[7];
+	unsigned long driver_data;	/* data private to the driver */
+	struct {
+		char id[7];
+	} devs[MAX_DEVICES];		/* logical devices */
+};
 
 struct pnp_driver {
 	struct list_head node;
 	char *name;
-	const struct pnp_id *card_id_table;
-	const struct pnp_id *id_table;
-	int  (*probe)  (struct pnp_dev *dev, const struct pnp_id *card_id,
-		 	const struct pnp_id *dev_id);
+	const struct pnp_device_id *id_table;
+	int  (*probe)  (struct pnp_dev *dev, const struct pnp_device_id *dev_id);
 	void (*remove) (struct pnp_dev *dev);
-	struct device_driver	driver;
+	struct device_driver driver;
 };
 
 #define	to_pnp_driver(drv) container_of(drv,struct pnp_driver, driver)
 
+struct pnpc_driver {
+	struct list_head node;
+	char *name;
+	const struct pnp_card_id *id_table;
+	int  (*probe)  (struct pnp_card *card, const struct pnp_card_id *card_id);
+	void (*remove) (struct pnp_card *card);
+	struct device_driver driver;
+};
+
+#define	to_pnpc_driver(drv) container_of(drv,struct pnpc_driver, driver)
+
+
+/*
+ * Resource Management
+ */
+
+/* Use these instead of directly reading pnp_dev to get resource information */
+#define pnp_port_start(dev,bar)   ((dev)->resource[(bar)].start)
+#define pnp_port_end(dev,bar)     ((dev)->resource[(bar)].end)
+#define pnp_port_flags(dev,bar)   ((dev)->resource[(bar)].flags)
+#define pnp_port_len(dev,bar) \
+	((pnp_port_start((dev),(bar)) == 0 &&	\
+	  pnp_port_end((dev),(bar)) ==		\
+	  pnp_port_start((dev),(bar))) ? 0 :	\
+	  					\
+	 (pnp_port_end((dev),(bar)) -		\
+	  pnp_port_start((dev),(bar)) + 1))
+
+#define pnp_mem_start(dev,bar)   ((dev)->resource[(bar+8)].start)
+#define pnp_mem_end(dev,bar)     ((dev)->resource[(bar+8)].end)
+#define pnp_mem_flags(dev,bar)   ((dev)->resource[(bar+8)].flags)
+#define pnp_mem_len(dev,bar) \
+	((pnp_mem_start((dev),(bar)) == 0 &&	\
+	  pnp_mem_end((dev),(bar)) ==		\
+	  pnp_mem_start((dev),(bar))) ? 0 :	\
+	  					\
+	 (pnp_mem_end((dev),(bar)) -		\
+	  pnp_mem_start((dev),(bar)) + 1))
 
-/* Resource Management */
+#define pnp_irq(dev,bar)	 ((dev)->irq_resource[(bar)].start)
+#define pnp_irq_flags(dev,bar)	 ((dev)->irq_resource[(bar)].flags)
 
-#define DEV_IO(dev, index) (dev->resource[index].start)
-#define DEV_MEM(dev, index) (dev->resource[index+8].start)
-#define DEV_IRQ(dev, index) (dev->irq_resource[index].start)
-#define DEV_DMA(dev, index) (dev->dma_resource[index].start)
+#define pnp_dma(dev,bar)	 ((dev)->dma_resource[(bar)].start)
+#define pnp_dma_flags(dev,bar)	 ((dev)->dma_resource[(bar)].flags)
 
 #define PNP_PORT_FLAG_16BITADDR	(1<<0)
-#define PNP_PORT_FLAG_FIXED		(1<<1)
+#define PNP_PORT_FLAG_FIXED	(1<<1)
 
 struct pnp_port {
 	unsigned short min;		/* min base number */
@@ -182,7 +291,9 @@
 };
 
 
-/* Protocol Management */
+/* 
+ * Protocol Management
+ */
 
 struct pnp_protocol {
 	struct list_head	protocol_list;
@@ -196,18 +307,26 @@
 	/* used by pnp layer only (look but don't touch) */
 	unsigned char		number;		/* protocol number*/
 	struct device		dev;		/* link to driver model */
+	struct list_head	cards;
 	struct list_head	devices;
 };
 
 #define to_pnp_protocol(n) list_entry(n, struct pnp_protocol, protocol_list)
+#define protocol_for_each_card(protocol,card) \
+	for((card) = protocol_to_pnp_card((protocol)->cards.next); \
+	(card) != protocol_to_pnp_card(&(protocol)->cards); \
+	(card) = protocol_to_pnp_card((card)->protocol_list.next))
+#define protocol_for_each_dev(protocol,dev) \
+	for((dev) = protocol_to_pnp_dev((protocol)->devices.next); \
+	(dev) != protocol_to_pnp_dev(&(protocol)->devices); \
+	(dev) = protocol_to_pnp_dev((dev)->protocol_list.next))
 
 
 #if defined(CONFIG_PNP)
 
 /* core */
-int pnp_protocol_register(struct pnp_protocol *protocol);
-void pnp_protocol_unregister(struct pnp_protocol *protocol);
-int pnp_init_device(struct pnp_dev *dev);
+int pnp_register_protocol(struct pnp_protocol *protocol);
+void pnp_unregister_protocol(struct pnp_protocol *protocol);
 int pnp_add_device(struct pnp_dev *dev);
 void pnp_remove_device(struct pnp_dev *dev);
 extern struct list_head pnp_global;
@@ -226,7 +345,7 @@
 int pnp_raw_set_dev(struct pnp_dev *dev, int depnum, int mode);
 
 /* driver */
-int compare_pnp_id(struct list_head * id_list, const char * id);
+int compare_pnp_id(struct pnp_id * pos, const char * id);
 int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev);
 int pnp_register_driver(struct pnp_driver *drv);
 void pnp_unregister_driver(struct pnp_driver *drv);
@@ -234,8 +353,8 @@
 #else
 
 /* just in case anyone decides to call these without PnP Support Enabled */
-static inline int pnp_protocol_register(struct pnp_protocol *protocol) { return -ENODEV; }
-static inline void pnp_protocol_unregister(struct pnp_protocol *protocol) { }
+static inline int pnp_register_protocol(struct pnp_protocol *protocol) { return -ENODEV; }
+static inline void pnp_unregister_protocol(struct pnp_protocol *protocol) { }
 static inline int pnp_init_device(struct pnp_dev *dev) { return -ENODEV; }
 static inline int pnp_add_device(struct pnp_dev *dev) { return -ENODEV; }
 static inline void pnp_remove_device(struct pnp_dev *dev) { }
@@ -250,14 +369,45 @@
 static inline int pnp_activate_dev(struct pnp_dev *dev) { return -ENODEV; }
 static inline int pnp_disable_dev(struct pnp_dev *dev) { return -ENODEV; }
 static inline int pnp_raw_set_dev(struct pnp_dev *dev, int depnum, int mode) { return -ENODEV; }
-static inline int compare_pnp_id(struct list_head * id_list, char * id) { return -ENODEV; }
+static inline int compare_pnp_id(struct list_head * id_list, const char * id) { return -ENODEV; }
 static inline int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev) { return -ENODEV; }
 static inline int pnp_register_driver(struct pnp_driver *drv) { return -ENODEV; }
 static inline void pnp_unregister_driver(struct pnp_driver *drv) { ; }
 
 #endif /* CONFIG_PNP */
 
+
+#if defined(CONFIG_PNP_CARD)
+
+/* card */
+int pnpc_add_card(struct pnp_card *card);
+void pnpc_remove_card(struct pnp_card *card);
+int pnpc_add_device(struct pnp_card *card, struct pnp_dev *dev);
+void pnpc_remove_device(struct pnp_dev *dev);
+struct pnp_dev * pnp_request_card_device(struct pnp_card *card, const char *id, struct pnp_dev *from);
+void pnp_release_card_device(struct pnp_dev *dev);
+int pnpc_register_driver(struct pnpc_driver * drv);
+void pnpc_unregister_driver(struct pnpc_driver *drv);
+int pnpc_add_id(struct pnp_id *id, struct pnp_card *card);
+extern struct list_head pnp_cards;
+
+#else
+
+static inline int pnpc_add_card(struct pnp_card *card) { return -ENODEV; }
+static inline void pnpc_remove_card(struct pnp_card *card) { ; }
+static inline int pnpc_add_device(struct pnp_card *card, struct pnp_dev *dev) { return -ENODEV; }
+static inline void pnpc_remove_device(struct pnp_dev *dev) { ; }
+static inline struct pnp_dev * pnp_request_card_device(struct pnp_card *card, const char *id, struct pnp_dev *from) { return NULL; }
+static inline void pnp_release_card_device(struct pnp_dev *dev) { ; }
+static inline int pnpc_register_driver(struct pnpc_driver *drv) { return -ENODEV; }
+static inline void pnpc_unregister_driver(struct pnpc_driver *drv) { ; }
+static inline int pnpc_add_id(struct pnp_id *id, struct pnp_card *card) { return -ENODEV; }
+
+#endif /* CONFIG_PNP_CARD */
+
+
 #if defined(CONFIG_ISAPNP)
+
 /* compat */
 struct pnp_card *pnp_find_card(unsigned short vendor,
 				 unsigned short device,
diff -Nru a/include/linux/pnpbios.h b/include/linux/pnpbios.h
--- a/include/linux/pnpbios.h	Mon Dec  9 18:46:36 2002
+++ b/include/linux/pnpbios.h	Mon Dec  9 18:46:36 2002
@@ -75,6 +75,19 @@
 #define PNPMSG_POWER_OFF		0x41
 #define PNPMSG_PNP_OS_ACTIVE		0x42
 #define PNPMSG_PNP_OS_INACTIVE		0x43
+/*
+ * Plug and Play BIOS flags
+ */
+#define PNP_NO_DISABLE		0x0001
+#define PNP_NO_CONFIG		0x0002
+#define PNP_OUTPUT		0x0004
+#define PNP_INPUT		0x0008
+#define PNP_BOOTABLE		0x0010
+#define PNP_DOCK		0x0020
+#define PNP_REMOVABLE		0x0040
+#define pnp_is_static(x) (x->flags & 0x0100) == 0x0000
+#define pnp_is_dynamic(x) x->flags & 0x0080
+
 /* 0x8000 through 0xffff are OEM defined */
 
 #pragma pack(1)
diff -Nru a/include/linux/radeonfb.h b/include/linux/radeonfb.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/radeonfb.h	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,15 @@
+#ifndef __LINUX_RADEONFB_H__
+#define __LINUX_RADEONFB_H__
+
+#include <asm/ioctl.h>
+#include <asm/types.h>
+
+#define ATY_RADEON_LCD_ON	0x00000001
+#define ATY_RADEON_CRT_ON	0x00000002
+
+
+#define FBIO_RADEON_GET_MIRROR	_IOR('@', 3, sizeof(__u32*))
+#define FBIO_RADEON_SET_MIRROR	_IOW('@', 4, sizeof(__u32*))
+
+#endif
+
diff -Nru a/include/linux/reboot.h b/include/linux/reboot.h
--- a/include/linux/reboot.h	Mon Dec  9 18:46:52 2002
+++ b/include/linux/reboot.h	Mon Dec  9 18:46:52 2002
@@ -48,13 +48,6 @@
 extern void machine_halt(void);
 extern void machine_power_off(void);
 
-/*
- * Architecture-independent suspend facility
- */
-
-extern void software_suspend(void);
-extern unsigned char software_suspend_enabled;
-
 #endif
 
 #endif /* _LINUX_REBOOT_H */
diff -Nru a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
--- a/include/linux/reiserfs_fs.h	Mon Dec  9 18:46:51 2002
+++ b/include/linux/reiserfs_fs.h	Mon Dec  9 18:46:51 2002
@@ -2062,12 +2062,12 @@
 					      b_blocknr_t *new_blocknrs, int amount_needed)
 {
     reiserfs_blocknr_hint_t hint = {
-	th:tb->transaction_handle,
-	path: tb->tb_path,
-	inode: NULL,
-	key: tb->key,
-	block: 0,
-	formatted_node:1
+	.th = tb->transaction_handle,
+	.path = tb->tb_path,
+	.inode = NULL,
+	.key = tb->key,
+	.block = 0,
+	.formatted_node = 1
     };
     return reiserfs_allocate_blocknrs(&hint, new_blocknrs, amount_needed, 0);
 }
@@ -2077,12 +2077,12 @@
 					     struct path * path, long block)
 {
     reiserfs_blocknr_hint_t hint = {
-	th: th,
-	path: path,
-	inode: NULL,
-	block: block,
-	formatted_node: 0,
-	preallocate: 0
+	.th = th,
+	.path = path,
+	.inode = NULL,
+	.block = block,
+	.formatted_node = 0,
+	.preallocate = 0
     };
     return reiserfs_allocate_blocknrs(&hint, new_blocknrs, 1, 0);
 }
@@ -2094,12 +2094,12 @@
 					     struct path * path, long block)
 {
     reiserfs_blocknr_hint_t hint = {
-	th: th,
-	path: path,
-	inode: inode,
-	block: block,
-	formatted_node: 0,
-	preallocate: 1
+	.th = th,
+	.path = path,
+	.inode = inode,
+	.block = block,
+	.formatted_node = 0,
+	.preallocate = 1
     };
     return reiserfs_allocate_blocknrs(&hint, new_blocknrs, 1, 0);
 }
diff -Nru a/include/linux/sched.h b/include/linux/sched.h
--- a/include/linux/sched.h	Mon Dec  9 18:46:34 2002
+++ b/include/linux/sched.h	Mon Dec  9 18:46:34 2002
@@ -203,9 +203,8 @@
 	mm_context_t context;
 
 	/* coredumping support */
-	struct semaphore core_sem;
-	atomic_t core_waiters;
-	wait_queue_head_t core_wait;
+	int core_waiters;
+	struct completion *core_startup_done, core_done;
 
 	/* aio bits */
 	rwlock_t		ioctx_list_lock;
@@ -397,8 +396,6 @@
 	void *journal_info;
 	struct dentry *proc_dentry;
 	struct backing_dev_info *backing_dev_info;
-/* threaded coredumping support */
-	int core_waiter;
 
 	unsigned long ptrace_message;
 };
diff -Nru a/include/linux/serial.h b/include/linux/serial.h
--- a/include/linux/serial.h	Mon Dec  9 18:46:35 2002
+++ b/include/linux/serial.h	Mon Dec  9 18:46:35 2002
@@ -48,6 +48,7 @@
 	unsigned char	*iomem_base;
 	unsigned short	iomem_reg_shift;
 	unsigned int	port_high;
+	unsigned long	iomap_base;	/* cookie passed into ioremap */
 	int	reserved[1];
 };
 
diff -Nru a/include/linux/serial_core.h b/include/linux/serial_core.h
--- a/include/linux/serial_core.h	Mon Dec  9 18:46:34 2002
+++ b/include/linux/serial_core.h	Mon Dec  9 18:46:34 2002
@@ -186,6 +186,7 @@
 	unsigned int		timeout;		/* character-based timeout */
 	unsigned int		type;			/* port type */
 	struct uart_ops		*ops;
+	unsigned int		custom_divisor;
 	unsigned int		line;			/* port index */
 	unsigned long		mapbase;		/* for ioremap */
 	unsigned char		hub6;			/* this should be in the 8250 driver */
@@ -203,8 +204,6 @@
 
 #define USF_CLOSING_WAIT_INF	(0)
 #define USF_CLOSING_WAIT_NONE	(65535)
-
-	unsigned int		custom_divisor;
 
 	int			count;
 	struct uart_info	*info;
diff -Nru a/include/linux/signal.h b/include/linux/signal.h
--- a/include/linux/signal.h	Mon Dec  9 18:46:35 2002
+++ b/include/linux/signal.h	Mon Dec  9 18:46:35 2002
@@ -60,9 +60,9 @@
 	return ffz(~word);
 }
 
-#define sigmask(sig)	(1UL << ((sig) - 1))
-
 #endif /* __HAVE_ARCH_SIG_BITOPS */
+
+#define sigmask(sig)	(1UL << ((sig) - 1))
 
 #ifndef __HAVE_ARCH_SIG_SETOPS
 #include <linux/string.h>
diff -Nru a/include/linux/sisfb.h b/include/linux/sisfb.h
--- a/include/linux/sisfb.h	Mon Dec  9 18:46:50 2002
+++ b/include/linux/sisfb.h	Mon Dec  9 18:46:50 2002
@@ -1,6 +1,11 @@
 #ifndef _LINUX_SISFB
 #define _LINUX_SISFB
 
+#include <linux/spinlock.h>
+
+#include <asm/ioctl.h>
+#include <asm/types.h>
+
 #define DISPTYPE_CRT1       0x00000008L
 #define DISPTYPE_CRT2       0x00000004L
 #define DISPTYPE_LCD        0x00000002L
@@ -20,6 +25,7 @@
 #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,
@@ -32,10 +38,17 @@
 	SIS_315PRO,
 	SIS_640,
 	SIS_740,
-	SIS_330, 
+	SIS_650,
+	SIS_330,
 	MAX_SIS_CHIP
 } SIS_CHIP_TYPE;
 
+typedef enum _VGA_ENGINE {
+	UNKNOWN_VGA = 0,
+	SIS_300_VGA,
+	SIS_315_VGA,
+} VGA_ENGINE;
+
 typedef enum _TVTYPE {
 	TVMODE_NTSC = 0,
 	TVMODE_PAL,
@@ -81,21 +94,25 @@
 };
 
 struct video_info {
-	int    chip_id;
+	int           chip_id;
 	unsigned int  video_size;
 	unsigned long video_base;
-	char  *video_vbase;
+	char  *       video_vbase;
 	unsigned long mmio_base;
-	char  *mmio_vbase; 
+	char  *       mmio_vbase;
 	unsigned long vga_base;
+	unsigned long mtrr;
+	unsigned long heapstart;
 
 	int    video_bpp;
+	int    video_cmap_len;
 	int    video_width;
 	int    video_height;
 	int    video_vwidth;
 	int    video_vheight;
 	int    org_x;
 	int    org_y;
+	int    video_linelength;
 	unsigned int refresh_rate;
 
 	unsigned long disp_state;
@@ -106,7 +123,40 @@
 	SIS_CHIP_TYPE chip;
 	unsigned char revision_id;
 
+        unsigned short DstColor;		/* TW: For 2d acceleration */
+	unsigned long  SiS310_AccelDepth;
+	unsigned long  CommandReg;
+
+	spinlock_t     lockaccel;
+
 	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__
diff -Nru a/include/linux/sonypi.h b/include/linux/sonypi.h
--- a/include/linux/sonypi.h	Mon Dec  9 18:46:36 2002
+++ b/include/linux/sonypi.h	Mon Dec  9 18:46:36 2002
@@ -91,6 +91,9 @@
 #define SONYPI_EVENT_THUMBPHRASE_PRESSED	51
 #define SONYPI_EVENT_MEYE_FACE			52
 #define SONYPI_EVENT_MEYE_OPPOSITE		53
+#define SONYPI_EVENT_MEMORYSTICK_INSERT		54
+#define SONYPI_EVENT_MEMORYSTICK_EJECT		55
+
 
 /* get/set brightness */
 #define SONYPI_IOCGBRT		_IOR('v', 0, __u8)
diff -Nru a/include/linux/spinlock.h b/include/linux/spinlock.h
--- a/include/linux/spinlock.h	Mon Dec  9 18:46:37 2002
+++ b/include/linux/spinlock.h	Mon Dec  9 18:46:37 2002
@@ -67,16 +67,16 @@
  * If CONFIG_SMP is unset, declare the _raw_* definitions as nops
  */
 #define spin_lock_init(lock)	do { (void)(lock); } while(0)
-#define _raw_spin_lock(lock)	(void)(lock)
+#define _raw_spin_lock(lock)	do { (void)(lock); } while(0)
 #define spin_is_locked(lock)	((void)(lock), 0)
 #define _raw_spin_trylock(lock)	((void)(lock), 1)
 #define spin_unlock_wait(lock)	do { (void)(lock); } while(0)
 #define _raw_spin_unlock(lock)	do { (void)(lock); } while(0)
-#define rwlock_init(lock)	do { } while(0)
-#define _raw_read_lock(lock)	(void)(lock)
-#define _raw_read_unlock(lock)	do { } while(0)
-#define _raw_write_lock(lock)	(void)(lock)
-#define _raw_write_unlock(lock)	do { } while(0)
+#define rwlock_init(lock)	do { (void)(lock); } while(0)
+#define _raw_read_lock(lock)	do { (void)(lock); } while(0)
+#define _raw_read_unlock(lock)	do { (void)(lock); } while(0)
+#define _raw_write_lock(lock)	do { (void)(lock); } while(0)
+#define _raw_write_unlock(lock)	do { (void)(lock); } while(0)
 
 #endif /* !SMP */
 
diff -Nru a/include/linux/sunrpc/stats.h b/include/linux/sunrpc/stats.h
--- a/include/linux/sunrpc/stats.h	Mon Dec  9 18:46:37 2002
+++ b/include/linux/sunrpc/stats.h	Mon Dec  9 18:46:37 2002
@@ -61,16 +61,18 @@
 
 #else
 
+static inline struct proc_dir_entry *rpc_proc_register(struct rpc_stat *s) { return NULL; }
+static inline void rpc_proc_unregister(const char *p) {}
+static inline int rpc_proc_read(char *a, char **b, off_t c, int d, int *e, void *f) { return 0; }
+static inline void rpc_proc_zero(struct rpc_program *p) {}
+
+static inline struct proc_dir_entry *svc_proc_register(struct svc_stat *s) { return NULL; }
 static inline void svc_proc_unregister(const char *p) {}
-static inline struct proc_dir_entry*svc_proc_register(struct svc_stat *s)
-{
-	return NULL;
-}
+static inline int svc_proc_read(char *a, char **b, off_t c, int d, int *e, void *f) { return 0; }
+static inline void svc_proc_zero(struct svc_program *p) {}
+
+#define proc_net_rpc NULL
 
-static inline int svc_proc_read(char *a, char **b, off_t c, int d, int *e, void *f)
-{
-	return 0;
-}
 #endif
 
 #endif /* _LINUX_SUNRPC_STATS_H */
diff -Nru a/include/linux/swap.h b/include/linux/swap.h
--- a/include/linux/swap.h	Mon Dec  9 18:46:34 2002
+++ b/include/linux/swap.h	Mon Dec  9 18:46:34 2002
@@ -150,6 +150,7 @@
 extern void FASTCALL(lru_cache_add_active(struct page *));
 extern void FASTCALL(activate_page(struct page *));
 extern void lru_add_drain(void);
+extern int rotate_reclaimable_page(struct page *page);
 extern void swap_setup(void);
 
 /* linux/mm/vmscan.c */
diff -Nru a/include/linux/thread_info.h b/include/linux/thread_info.h
--- a/include/linux/thread_info.h	Mon Dec  9 18:46:52 2002
+++ b/include/linux/thread_info.h	Mon Dec  9 18:46:52 2002
@@ -7,6 +7,16 @@
 #ifndef _LINUX_THREAD_INFO_H
 #define _LINUX_THREAD_INFO_H
 
+/*
+ * System call restart block. 
+ */
+struct restart_block {
+	long (*fn)(struct restart_block *);
+	unsigned long arg0, arg1, arg2;
+};
+
+extern long do_no_restart_syscall(struct restart_block *parm);
+
 #include <linux/bitops.h>
 #include <asm/thread_info.h>
 
diff -Nru a/include/linux/time.h b/include/linux/time.h
--- a/include/linux/time.h	Mon Dec  9 18:46:49 2002
+++ b/include/linux/time.h	Mon Dec  9 18:46:49 2002
@@ -138,6 +138,8 @@
 #ifdef __KERNEL__
 extern void do_gettimeofday(struct timeval *tv);
 extern void do_settimeofday(struct timeval *tv);
+extern long do_nanosleep(struct timespec *t);
+extern long do_utimes(char * filename, struct timeval * times);
 #endif
 
 #define FD_SETSIZE		__FD_SETSIZE
diff -Nru a/include/linux/tty.h b/include/linux/tty.h
--- a/include/linux/tty.h	Mon Dec  9 18:46:37 2002
+++ b/include/linux/tty.h	Mon Dec  9 18:46:37 2002
@@ -397,6 +397,7 @@
 extern void disassociate_ctty(int priv);
 extern void tty_flip_buffer_push(struct tty_struct *tty);
 extern int tty_get_baud_rate(struct tty_struct *tty);
+extern int tty_termios_baud_rate(struct termios *termios);
 
 /* n_tty.c */
 extern struct tty_ldisc tty_ldisc_N_TTY;
diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h	Mon Dec  9 18:46:36 2002
+++ b/include/linux/usb.h	Mon Dec  9 18:46:36 2002
@@ -414,7 +414,7 @@
  * specific device.
  */
 #define USB_DEVICE(vend,prod) \
-	match_flags: USB_DEVICE_ID_MATCH_DEVICE, idVendor: (vend), idProduct: (prod)
+	.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = (vend), .idProduct = (prod)
 /**
  * USB_DEVICE_VER - macro used to describe a specific usb device with a version range
  * @vend: the 16 bit USB Vendor ID
@@ -426,7 +426,7 @@
  * specific device, with a version range.
  */
 #define USB_DEVICE_VER(vend,prod,lo,hi) \
-	match_flags: USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION, idVendor: (vend), idProduct: (prod), bcdDevice_lo: (lo), bcdDevice_hi: (hi)
+	.match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION, .idVendor = (vend), .idProduct = (prod), .bcdDevice_lo = (lo), .bcdDevice_hi = (hi)
 
 /**
  * USB_DEVICE_INFO - macro used to describe a class of usb devices
@@ -438,7 +438,7 @@
  * specific class of devices.
  */
 #define USB_DEVICE_INFO(cl,sc,pr) \
-	match_flags: USB_DEVICE_ID_MATCH_DEV_INFO, bDeviceClass: (cl), bDeviceSubClass: (sc), bDeviceProtocol: (pr)
+	.match_flags = USB_DEVICE_ID_MATCH_DEV_INFO, .bDeviceClass = (cl), .bDeviceSubClass = (sc), .bDeviceProtocol = (pr)
 
 /**
  * USB_INTERFACE_INFO - macro used to describe a class of usb interfaces 
@@ -450,7 +450,7 @@
  * specific class of interfaces.
  */
 #define USB_INTERFACE_INFO(cl,sc,pr) \
-	match_flags: USB_DEVICE_ID_MATCH_INT_INFO, bInterfaceClass: (cl), bInterfaceSubClass: (sc), bInterfaceProtocol: (pr)
+	.match_flags = USB_DEVICE_ID_MATCH_INT_INFO, .bInterfaceClass = (cl), .bInterfaceSubClass = (sc), .bInterfaceProtocol = (pr)
 
 /* -------------------------------------------------------------------------- */
 
@@ -554,8 +554,9 @@
 };
 
 struct urb;
+struct pt_regs;
 
-typedef void (*usb_complete_t)(struct urb *);
+typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
 
 /**
  * struct urb - USB Request Block
diff -Nru a/include/linux/videodev2.h b/include/linux/videodev2.h
--- a/include/linux/videodev2.h	Mon Dec  9 18:46:50 2002
+++ b/include/linux/videodev2.h	Mon Dec  9 18:46:50 2002
@@ -819,7 +819,7 @@
 #define VIDIOC_G_JPEGCOMP	_IOR  ('V', 61, struct v4l2_jpegcompression)
 #define VIDIOC_S_JPEGCOMP	_IOW  ('V', 62, struct v4l2_jpegcompression)
 #define VIDIOC_QUERYSTD      	_IOR  ('V', 63, v4l2_std_id)
-#define VIDIOC_TRY_FMT      	_IOWR ('V', 63, struct v4l2_format)
+#define VIDIOC_TRY_FMT      	_IOWR ('V', 64, struct v4l2_format)
 
 #define BASE_VIDIOC_PRIVATE	192		/* 192-255 are private */
 
diff -Nru a/include/linux/vt_kern.h b/include/linux/vt_kern.h
--- a/include/linux/vt_kern.h	Mon Dec  9 18:46:51 2002
+++ b/include/linux/vt_kern.h	Mon Dec  9 18:46:51 2002
@@ -10,6 +10,7 @@
 #include <linux/vt.h>
 #include <linux/kd.h>
 #include <linux/tty.h>
+#include <linux/console_struct.h>
 
 /*
  * Presently, a lot of graphics programs do not restore the contents of
@@ -37,14 +38,9 @@
 
 /* console.c */
 
-struct console_font_op;
-
 int vc_allocate(unsigned int console);
 int vc_cons_allocated(unsigned int console);
-int vc_resize(unsigned int lines, unsigned int cols,
-	      unsigned int first, unsigned int last);
-#define vc_resize_all(l, c) vc_resize(l, c, 0, MAX_NR_CONSOLES-1)
-#define vc_resize_con(l, c, x) vc_resize(l, c, x, x)
+int vc_resize(int currcons, unsigned int cols, unsigned int lines);
 void vc_disallocate(unsigned int console);
 void reset_palette(int currcons);
 void set_palette(int currcons);
diff -Nru a/include/linux/wanpipe.h b/include/linux/wanpipe.h
--- a/include/linux/wanpipe.h	Mon Dec  9 18:46:50 2002
+++ b/include/linux/wanpipe.h	Mon Dec  9 18:46:50 2002
@@ -358,7 +358,7 @@
 	char in_isr;			/* interrupt-in-service flag */
 	char buff_int_mode_unbusy;	/* flag for carrying out dev_tint */  
 	char dlci_int_mode_unbusy;	/* flag for carrying out dev_tint */
-	char configured;		/* flag for previous configurations */
+	long configured;		/* flag for previous configurations */
 	
 	unsigned short irq_dis_if_send_count; /* Disabling irqs in if_send*/
 	unsigned short irq_dis_poll_count;   /* Disabling irqs in poll routine*/
diff -Nru a/include/net/irda/vlsi_ir.h b/include/net/irda/vlsi_ir.h
--- a/include/net/irda/vlsi_ir.h	Mon Dec  9 18:46:38 2002
+++ b/include/net/irda/vlsi_ir.h	Mon Dec  9 18:46:38 2002
@@ -27,6 +27,26 @@
 #ifndef IRDA_VLSI_FIR_H
 #define IRDA_VLSI_FIR_H
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,4)
+#ifdef CONFIG_PROC_FS
+/* PDE() introduced in 2.5.4 */
+#define PDE(inode) ((inode)->u.generic_ip)
+#endif
+#endif
+
+/*
+ * #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,xx)
+ *
+ * missing pci-dma api call to give streaming dma buffer back to hw
+ * patch floating on lkml - probably present in 2.5.26 or later
+ * otherwise defining it as noop is ok, since the vlsi-ir is only
+ * used on two oldish x86-based notebooks which are cache-coherent
+ */
+#define pci_dma_prep_single(dev, addr, size, direction)	/* nothing */
+/*
+ * #endif
+ */
+
 /* ================================================================ */
 
 /* non-standard PCI registers */
diff -Nru a/include/net/route.h b/include/net/route.h
--- a/include/net/route.h	Mon Dec  9 18:46:34 2002
+++ b/include/net/route.h	Mon Dec  9 18:46:34 2002
@@ -107,7 +107,7 @@
 extern struct ip_rt_acct *ip_rt_acct;
 
 struct in_device;
-extern void		ip_rt_init(void);
+extern int		ip_rt_init(void);
 extern void		ip_rt_redirect(u32 old_gw, u32 dst, u32 new_gw,
 				       u32 src, u8 tos, struct net_device *dev);
 extern void		ip_rt_advice(struct rtable **rp, int advice);
diff -Nru a/include/video/fbcon-afb.h b/include/video/fbcon-afb.h
--- a/include/video/fbcon-afb.h	Mon Dec  9 18:46:51 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,32 +0,0 @@
-/*
- *  FBcon low-level driver for Amiga bitplanes (afb)
- */
-
-#ifndef _VIDEO_FBCON_AFB_H
-#define _VIDEO_FBCON_AFB_H
-
-#include <linux/config.h>
-
-#ifdef MODULE
-#if defined(CONFIG_FBCON_AFB) || defined(CONFIG_FBCON_AFB_MODULE)
-#define FBCON_HAS_AFB
-#endif
-#else
-#if defined(CONFIG_FBCON_AFB)
-#define FBCON_HAS_AFB
-#endif
-#endif
-
-extern struct display_switch fbcon_afb;
-extern void fbcon_afb_setup(struct display *p);
-extern void fbcon_afb_bmove(struct display *p, int sy, int sx, int dy, int dx,
-			    int height, int width);
-extern void fbcon_afb_clear(struct vc_data *conp, struct display *p, int sy,
-			    int sx, int height, int width);
-extern void fbcon_afb_putc(struct vc_data *conp, struct display *p, int c,
-			   int yy, int xx);
-extern void fbcon_afb_putcs(struct vc_data *conp, struct display *p,
-			    const unsigned short *s, int count, int yy, int xx);
-extern void fbcon_afb_revc(struct display *p, int xx, int yy);
-
-#endif
diff -Nru a/include/video/fbcon-cfb16.h b/include/video/fbcon-cfb16.h
--- a/include/video/fbcon-cfb16.h	Mon Dec  9 18:46:35 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,34 +0,0 @@
-/*
- *  FBcon low-level driver for 16 bpp packed pixel (cfb16)
- */
-
-#ifndef _VIDEO_FBCON_CFB16_H
-#define _VIDEO_FBCON_CFB16_H
-
-#include <linux/config.h>
-
-#ifdef MODULE
-#if defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CFB16_MODULE)
-#define FBCON_HAS_CFB16
-#endif
-#else
-#if defined(CONFIG_FBCON_CFB16)
-#define FBCON_HAS_CFB16
-#endif
-#endif
-
-extern struct display_switch fbcon_cfb16;
-extern void fbcon_cfb16_setup(struct display *p);
-extern void fbcon_cfb16_bmove(struct display *p, int sy, int sx, int dy,
-			      int dx, int height, int width);
-extern void fbcon_cfb16_clear(struct vc_data *conp, struct display *p, int sy,
-			      int sx, int height, int width);
-extern void fbcon_cfb16_putc(struct vc_data *conp, struct display *p, int c,
-			     int yy, int xx);
-extern void fbcon_cfb16_putcs(struct vc_data *conp, struct display *p,
-			      const unsigned short *s, int count, int yy, int xx);
-extern void fbcon_cfb16_revc(struct display *p, int xx, int yy);
-extern void fbcon_cfb16_clear_margins(struct vc_data *conp, struct display *p,
-				      int bottom_only);
-
-#endif /* _VIDEO_FBCON_CFB16_H */
diff -Nru a/include/video/fbcon-cfb2.h b/include/video/fbcon-cfb2.h
--- a/include/video/fbcon-cfb2.h	Mon Dec  9 18:46:34 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,32 +0,0 @@
-/*
- *  FBcon low-level driver for 2 bpp packed pixel (cfb2)
- */
-
-#ifndef _VIDEO_FBCON_CFB2_H
-#define _VIDEO_FBCON_CFB2_H
-
-#include <linux/config.h>
-
-#ifdef MODULE
-#if defined(CONFIG_FBCON_CFB2) || defined(CONFIG_FBCON_CFB2_MODULE)
-#define FBCON_HAS_CFB2
-#endif
-#else
-#if defined(CONFIG_FBCON_CFB2)
-#define FBCON_HAS_CFB2
-#endif
-#endif
-
-extern struct display_switch fbcon_cfb2;
-extern void fbcon_cfb2_setup(struct display *p);
-extern void fbcon_cfb2_bmove(struct display *p, int sy, int sx, int dy, int dx,
-			     int height, int width);
-extern void fbcon_cfb2_clear(struct vc_data *conp, struct display *p, int sy,
-			     int sx, int height, int width);
-extern void fbcon_cfb2_putc(struct vc_data *conp, struct display *p, int c,
-			    int yy, int xx);
-extern void fbcon_cfb2_putcs(struct vc_data *conp, struct display *p,
-			     const unsigned short *s, int count, int yy, int xx);
-extern void fbcon_cfb2_revc(struct display *p, int xx, int yy);
-
-#endif /* _VIDEO_FBCON_CFB2_H */
diff -Nru a/include/video/fbcon-cfb24.h b/include/video/fbcon-cfb24.h
--- a/include/video/fbcon-cfb24.h	Mon Dec  9 18:46:36 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,34 +0,0 @@
-/*
- *  FBcon low-level driver for 24 bpp packed pixel (cfb24)
- */
-
-#ifndef _VIDEO_FBCON_CFB24_H
-#define _VIDEO_FBCON_CFB24_H
-
-#include <linux/config.h>
-
-#ifdef MODULE
-#if defined(CONFIG_FBCON_CFB24) || defined(CONFIG_FBCON_CFB24_MODULE)
-#define FBCON_HAS_CFB24
-#endif
-#else
-#if defined(CONFIG_FBCON_CFB24)
-#define FBCON_HAS_CFB24
-#endif
-#endif
-
-extern struct display_switch fbcon_cfb24;
-extern void fbcon_cfb24_setup(struct display *p);
-extern void fbcon_cfb24_bmove(struct display *p, int sy, int sx, int dy,
-			      int dx, int height, int width);
-extern void fbcon_cfb24_clear(struct vc_data *conp, struct display *p, int sy,
-			      int sx, int height, int width);
-extern void fbcon_cfb24_putc(struct vc_data *conp, struct display *p, int c,
-			     int yy, int xx);
-extern void fbcon_cfb24_putcs(struct vc_data *conp, struct display *p,
-			      const unsigned short *s, int count, int yy, int xx);
-extern void fbcon_cfb24_revc(struct display *p, int xx, int yy);
-extern void fbcon_cfb24_clear_margins(struct vc_data *conp, struct display *p,
-				      int bottom_only);
-
-#endif /* _VIDEO_FBCON_CFB24_H */
diff -Nru a/include/video/fbcon-cfb32.h b/include/video/fbcon-cfb32.h
--- a/include/video/fbcon-cfb32.h	Mon Dec  9 18:46:36 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,34 +0,0 @@
-/*
- *  FBcon low-level driver for 32 bpp packed pixel (cfb32)
- */
-
-#ifndef _VIDEO_FBCON_CFB32_H
-#define _VIDEO_FBCON_CFB32_H
-
-#include <linux/config.h>
-
-#ifdef MODULE
-#if defined(CONFIG_FBCON_CFB32) || defined(CONFIG_FBCON_CFB32_MODULE)
-#define FBCON_HAS_CFB32
-#endif
-#else
-#if defined(CONFIG_FBCON_CFB32)
-#define FBCON_HAS_CFB32
-#endif
-#endif
-
-extern struct display_switch fbcon_cfb32;
-extern void fbcon_cfb32_setup(struct display *p);
-extern void fbcon_cfb32_bmove(struct display *p, int sy, int sx, int dy,
-			      int dx, int height, int width);
-extern void fbcon_cfb32_clear(struct vc_data *conp, struct display *p, int sy,
-			      int sx, int height, int width);
-extern void fbcon_cfb32_putc(struct vc_data *conp, struct display *p, int c,
-			     int yy, int xx);
-extern void fbcon_cfb32_putcs(struct vc_data *conp, struct display *p,
-			      const unsigned short *s, int count, int yy, int xx);
-extern void fbcon_cfb32_revc(struct display *p, int xx, int yy);
-extern void fbcon_cfb32_clear_margins(struct vc_data *conp, struct display *p,
-				      int bottom_only);
-
-#endif /* _VIDEO_FBCON_CFB32_H */
diff -Nru a/include/video/fbcon-cfb4.h b/include/video/fbcon-cfb4.h
--- a/include/video/fbcon-cfb4.h	Mon Dec  9 18:46:51 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,32 +0,0 @@
-/*
- *  FBcon low-level driver for 4 bpp packed pixel (cfb4)
- */
-
-#ifndef _VIDEO_FBCON_CFB4_H
-#define _VIDEO_FBCON_CFB4_H
-
-#include <linux/config.h>
-
-#ifdef MODULE
-#if defined(CONFIG_FBCON_CFB4) || defined(CONFIG_FBCON_CFB4_MODULE)
-#define FBCON_HAS_CFB4
-#endif
-#else
-#if defined(CONFIG_FBCON_CFB4)
-#define FBCON_HAS_CFB4
-#endif
-#endif
-
-extern struct display_switch fbcon_cfb4;
-extern void fbcon_cfb4_setup(struct display *p);
-extern void fbcon_cfb4_bmove(struct display *p, int sy, int sx, int dy, int dx,
-			     int height, int width);
-extern void fbcon_cfb4_clear(struct vc_data *conp, struct display *p, int sy,
-			     int sx, int height, int width);
-extern void fbcon_cfb4_putc(struct vc_data *conp, struct display *p, int c,
-			    int yy, int xx);
-extern void fbcon_cfb4_putcs(struct vc_data *conp, struct display *p,
-			     const unsigned short *s, int count, int yy, int xx);
-extern void fbcon_cfb4_revc(struct display *p, int xx, int yy);
-
-#endif /* _VIDEO_FBCON_CFB4_H */
diff -Nru a/include/video/fbcon-cfb8.h b/include/video/fbcon-cfb8.h
--- a/include/video/fbcon-cfb8.h	Mon Dec  9 18:46:38 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,34 +0,0 @@
-/*
- *  FBcon low-level driver for 8 bpp packed pixel (cfb8)
- */
-
-#ifndef _VIDEO_FBCON_CFB8_H
-#define _VIDEO_FBCON_CFB8_H
-
-#include <linux/config.h>
-
-#ifdef MODULE
-#if defined(CONFIG_FBCON_CFB8) || defined(CONFIG_FBCON_CFB8_MODULE)
-#define FBCON_HAS_CFB8
-#endif
-#else
-#if defined(CONFIG_FBCON_CFB8)
-#define FBCON_HAS_CFB8
-#endif
-#endif
-
-extern struct display_switch fbcon_cfb8;
-extern void fbcon_cfb8_setup(struct display *p);
-extern void fbcon_cfb8_bmove(struct display *p, int sy, int sx, int dy, int dx,
-			     int height, int width);
-extern void fbcon_cfb8_clear(struct vc_data *conp, struct display *p, int sy,
-			     int sx, int height, int width);
-extern void fbcon_cfb8_putc(struct vc_data *conp, struct display *p, int c,
-			    int yy, int xx);
-extern void fbcon_cfb8_putcs(struct vc_data *conp, struct display *p,
-			     const unsigned short *s, int count, int yy, int xx);
-extern void fbcon_cfb8_revc(struct display *p, int xx, int yy);
-extern void fbcon_cfb8_clear_margins(struct vc_data *conp, struct display *p,
-				     int bottom_only);
-
-#endif /* _VIDEO_FBCON_CFB8_H */
diff -Nru a/include/video/fbcon-hga.h b/include/video/fbcon-hga.h
--- a/include/video/fbcon-hga.h	Mon Dec  9 18:46:35 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,32 +0,0 @@
-/*
- *  FBcon low-level driver for Hercules Graphics Adaptor (hga)
- */
-
-#ifndef _VIDEO_FBCON_HGA_H
-#define _VIDEO_FBCON_HGA_H
-
-#include <linux/config.h>
-
-#ifdef MODULE
-#if defined(CONFIG_FBCON_HGA) || defined(CONFIG_FBCON_HGA_MODULE)
-#define FBCON_HAS_HGA
-#endif
-#else
-#if defined(CONFIG_FBCON_HGA)
-#define FBCON_HAS_HGA
-#endif
-#endif
-
-extern struct display_switch fbcon_hga;
-extern void fbcon_hga_setup(struct display *p);
-extern void fbcon_hga_bmove(struct display *p, int sy, int sx, int dy, int dx,
-			    int height, int width);
-extern void fbcon_hga_clear(struct vc_data *conp, struct display *p, int sy,
-			    int sx, int height, int width);
-extern void fbcon_hga_putc(struct vc_data *conp, struct display *p, int c,
-			   int yy, int xx);
-extern void fbcon_hga_putcs(struct vc_data *conp, struct display *p,
-			    const unsigned short *s, int count, int yy, int xx);
-extern void fbcon_hga_revc(struct display *p, int xx, int yy);
-
-#endif /* _VIDEO_FBCON_HGA_H */
diff -Nru a/include/video/fbcon-ilbm.h b/include/video/fbcon-ilbm.h
--- a/include/video/fbcon-ilbm.h	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,32 +0,0 @@
-/*
- *  FBcon low-level driver for Amiga interleaved bitplanes (ilbm)
- */
-
-#ifndef _VIDEO_FBCON_ILBM_H
-#define _VIDEO_FBCON_ILBM_H
-
-#include <linux/config.h>
-
-#ifdef MODULE
-#if defined(CONFIG_FBCON_ILBM) || defined(CONFIG_FBCON_ILBM_MODULE)  
-#define FBCON_HAS_ILBM 
-#endif
-#else
-#if defined(CONFIG_FBCON_ILBM) 
-#define FBCON_HAS_ILBM 
-#endif
-#endif
-
-extern struct display_switch fbcon_ilbm;
-extern void fbcon_ilbm_setup(struct display *p);
-extern void fbcon_ilbm_bmove(struct display *p, int sy, int sx, int dy, int dx,
-			     int height, int width);
-extern void fbcon_ilbm_clear(struct vc_data *conp, struct display *p, int sy,
-			     int sx, int height, int width);
-extern void fbcon_ilbm_putc(struct vc_data *conp, struct display *p, int c,
-			    int yy, int xx);
-extern void fbcon_ilbm_putcs(struct vc_data *conp, struct display *p,
-			     const unsigned short *s, int count, int yy, int xx);
-extern void fbcon_ilbm_revc(struct display *p, int xx, int yy);
-
-#endif /* _VIDEO_FBCON_ILBM_H */
diff -Nru a/include/video/fbcon-iplan2p2.h b/include/video/fbcon-iplan2p2.h
--- a/include/video/fbcon-iplan2p2.h	Mon Dec  9 18:46:36 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,32 +0,0 @@
-/*
- *  FBcon low-level driver for Atari interleaved bitplanes (2 planes) (iplan2p2)
- */
-
-#ifndef _VIDEO_FBCON_IPLAN2P2_H
-#define _VIDEO_FBCON_IPLAN2P2_H
-
-#include <linux/config.h>
-
-#ifdef MODULE
-#if defined(CONFIG_FBCON_IPLAN2P2) || defined(CONFIG_FBCON_IPLAN2P2_MODULE)
-#define FBCON_HAS_IPLAN2P2
-#endif
-#else
-#if defined(CONFIG_FBCON_IPLAN2P2)
-#define FBCON_HAS_IPLAN2P2
-#endif
-#endif
-
-extern struct display_switch fbcon_iplan2p2;
-extern void fbcon_iplan2p2_setup(struct display *p);
-extern void fbcon_iplan2p2_bmove(struct display *p, int sy, int sx, int dy,
-				 int dx, int height, int width);
-extern void fbcon_iplan2p2_clear(struct vc_data *conp, struct display *p,
-				 int sy, int sx, int height, int width);
-extern void fbcon_iplan2p2_putc(struct vc_data *conp, struct display *p, int c,
-				int yy, int xx);
-extern void fbcon_iplan2p2_putcs(struct vc_data *conp, struct display *p,
-				 const unsigned short *s, int count, int yy, int xx);
-extern void fbcon_iplan2p2_revc(struct display *p, int xx, int yy);
-
-#endif /* _VIDEO_FBCON_IPLAN2P2_H */
diff -Nru a/include/video/fbcon-iplan2p4.h b/include/video/fbcon-iplan2p4.h
--- a/include/video/fbcon-iplan2p4.h	Mon Dec  9 18:46:34 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,32 +0,0 @@
-/*
- *  FBcon low-level driver for Atari interleaved bitplanes (4 planes) (iplan2p4)
- */
-
-#ifndef _VIDEO_FBCON_IPLAN2P4_H
-#define _VIDEO_FBCON_IPLAN2P4_H
-
-#include <linux/config.h>
-
-#ifdef MODULE
-#if defined(CONFIG_FBCON_IPLAN2P4) || defined(CONFIG_FBCON_IPLAN2P4_MODULE)
-#define FBCON_HAS_IPLAN2P4
-#endif
-#else
-#if defined(CONFIG_FBCON_IPLAN2P4)
-#define FBCON_HAS_IPLAN2P4
-#endif
-#endif
-
-extern struct display_switch fbcon_iplan2p4;
-extern void fbcon_iplan2p4_setup(struct display *p);
-extern void fbcon_iplan2p4_bmove(struct display *p, int sy, int sx, int dy,
-				 int dx, int height, int width);
-extern void fbcon_iplan2p4_clear(struct vc_data *conp, struct display *p,
-				 int sy, int sx, int height, int width);
-extern void fbcon_iplan2p4_putc(struct vc_data *conp, struct display *p, int c,
-				int yy, int xx);
-extern void fbcon_iplan2p4_putcs(struct vc_data *conp, struct display *p,
-				 const unsigned short *s, int count, int yy, int xx);
-extern void fbcon_iplan2p4_revc(struct display *p, int xx, int yy);
-
-#endif /* _VIDEO_FBCON_IPLAN2P4_H */
diff -Nru a/include/video/fbcon-iplan2p8.h b/include/video/fbcon-iplan2p8.h
--- a/include/video/fbcon-iplan2p8.h	Mon Dec  9 18:46:34 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,32 +0,0 @@
-/*
- *  FBcon low-level driver for Atari interleaved bitplanes (8 planes) (iplan2p8)
- */
-
-#ifndef _VIDEO_FBCON_IPLAN2P8_H
-#define _VIDEO_FBCON_IPLAN2P8_H
-
-#include <linux/config.h>
-
-#ifdef MODULE
-#if defined(CONFIG_FBCON_IPLAN2P8) || defined(CONFIG_FBCON_IPLAN2P8_MODULE)
-#define FBCON_HAS_IPLAN2P8
-#endif
-#else
-#if defined(CONFIG_FBCON_IPLAN2P8)
-#define FBCON_HAS_IPLAN2P8
-#endif
-#endif
-
-extern struct display_switch fbcon_iplan2p8;
-extern void fbcon_iplan2p8_setup(struct display *p);
-extern void fbcon_iplan2p8_bmove(struct display *p, int sy, int sx, int dy,
-				 int dx, int height, int width);
-extern void fbcon_iplan2p8_clear(struct vc_data *conp, struct display *p,
-				 int sy, int sx, int height, int width);
-extern void fbcon_iplan2p8_putc(struct vc_data *conp, struct display *p, int c,
-				int yy, int xx);
-extern void fbcon_iplan2p8_putcs(struct vc_data *conp, struct display *p,
-				 const unsigned short *s, int count, int yy, int xx);
-extern void fbcon_iplan2p8_revc(struct display *p, int xx, int yy);
-
-#endif /* _VIDEO_FBCON_IPLAN2P8_H */
diff -Nru a/include/video/fbcon-mac.h b/include/video/fbcon-mac.h
--- a/include/video/fbcon-mac.h	Mon Dec  9 18:46:35 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,32 +0,0 @@
-/*
- *  FBcon low-level driver for Mac variable bpp packed pixels (mac)
- */
-
-#ifndef _VIDEO_FBCON_MAC_H
-#define _VIDEO_FBCON_MAC_H
-
-#include <linux/config.h>
-
-#ifdef MODULE
-#if defined(CONFIG_FBCON_MAC) || defined(CONFIG_FBCON_MAC_MODULE)
-#define FBCON_HAS_MAC
-#endif
-#else
-#if defined(CONFIG_FBCON_MAC)
-#define FBCON_HAS_MAC
-#endif
-#endif
-
-extern struct display_switch fbcon_mac;
-extern void fbcon_mac_setup(struct display *p);
-extern void fbcon_mac_bmove(struct display *p, int sy, int sx, int dy, int dx,
-			    int height, int width);
-extern void fbcon_mac_clear(struct vc_data *conp, struct display *p, int sy,
-			    int sx, int height, int width);
-extern void fbcon_mac_putc(struct vc_data *conp, struct display *p, int c,
-			   int yy, int xx);
-extern void fbcon_mac_putcs(struct vc_data *conp, struct display *p,
-			    const unsigned short *s, int count, int yy, int xx);
-extern void fbcon_mac_revc(struct display *p, int xx, int yy);
-
-#endif /* _VIDEO_FBCON_MAC_H */
diff -Nru a/include/video/fbcon-mfb.h b/include/video/fbcon-mfb.h
--- a/include/video/fbcon-mfb.h	Mon Dec  9 18:46:51 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,32 +0,0 @@
-/*
- *  FBcon low-level driver for Monochrome (mfb)
- */
-
-#ifndef _VIDEO_FBCON_MFB_H
-#define _VIDEO_FBCON_MFB_H
-
-#include <linux/config.h>
-
-#ifdef MODULE
-#if defined(CONFIG_FBCON_MFB) || defined(CONFIG_FBCON_MFB_MODULE)
-#define FBCON_HAS_MFB
-#endif
-#else
-#if defined(CONFIG_FBCON_MFB)
-#define FBCON_HAS_MFB
-#endif
-#endif
-
-extern struct display_switch fbcon_mfb;
-extern void fbcon_mfb_setup(struct display *p);
-extern void fbcon_mfb_bmove(struct display *p, int sy, int sx, int dy, int dx,
-			    int height, int width);
-extern void fbcon_mfb_clear(struct vc_data *conp, struct display *p, int sy,
-			    int sx, int height, int width);
-extern void fbcon_mfb_putc(struct vc_data *conp, struct display *p, int c,
-			   int yy, int xx);
-extern void fbcon_mfb_putcs(struct vc_data *conp, struct display *p,
-			    const unsigned short *s, int count, int yy, int xx);
-extern void fbcon_mfb_revc(struct display *p, int xx, int yy);
-
-#endif /* _VIDEO_FBCON_MFB_H */
diff -Nru a/include/video/fbcon-vga-planes.h b/include/video/fbcon-vga-planes.h
--- a/include/video/fbcon-vga-planes.h	Mon Dec  9 18:46:38 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,37 +0,0 @@
-/*
- *  FBcon low-level driver for VGA 4-plane modes
- */
-
-#ifndef _VIDEO_FBCON_VGA_PLANES_H
-#define _VIDEO_FBCON_VGA_PLANES_H
-
-#include <linux/config.h>
-
-#ifdef MODULE
-#if defined(CONFIG_FBCON_VGA_PLANES) || defined(CONFIG_FBCON_VGA_PLANES_MODULE)
-#define FBCON_HAS_VGA_PLANES
-#endif
-#else
-#if defined(CONFIG_FBCON_VGA_PLANES)
-#define FBCON_HAS_VGA_PLANES
-#endif
-#endif
-
-extern struct display_switch fbcon_vga_planes;
-extern struct display_switch fbcon_ega_planes;
-extern void fbcon_vga_planes_setup(struct display *p);
-extern void fbcon_vga_planes_bmove(struct display *p, int sy, int sx, int dy, int dx,
-				   int height, int width);
-extern void fbcon_vga_planes_clear(struct vc_data *conp, struct display *p, int sy,
-				   int sx, int height, int width);
-extern void fbcon_vga_planes_putc(struct vc_data *conp, struct display *p, int c,
-				  int yy, int xx);
-extern void fbcon_ega_planes_putc(struct vc_data *conp, struct display *p, int c,
-				  int yy, int xx);
-extern void fbcon_vga_planes_putcs(struct vc_data *conp, struct display *p,
-				   const unsigned short *s, int count, int yy, int xx);
-extern void fbcon_ega_planes_putcs(struct vc_data *conp, struct display *p,
-				   const unsigned short *s, int count, int yy, int xx);
-extern void fbcon_vga_planes_revc(struct display *p, int xx, int yy);
-
-#endif /* _VIDEO_FBCON_VGA_PLANES_H */
diff -Nru a/include/video/fbcon-vga.h b/include/video/fbcon-vga.h
--- a/include/video/fbcon-vga.h	Mon Dec  9 18:46:51 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,32 +0,0 @@
-/*
- *  FBcon low-level driver for VGA characters/attributes
- */
-
-#ifndef _VIDEO_FBCON_VGA_H
-#define _VIDEO_FBCON_VGA_H
-
-#include <linux/config.h>
-
-#ifdef MODULE
-#if defined(CONFIG_FBCON_VGA) || defined(CONFIG_FBCON_VGA_MODULE)
-#define FBCON_HAS_VGA
-#endif
-#else
-#if defined(CONFIG_FBCON_VGA)
-#define FBCON_HAS_VGA
-#endif
-#endif
-
-extern struct display_switch fbcon_vga;
-extern void fbcon_vga_setup(struct display *p);
-extern void fbcon_vga_bmove(struct display *p, int sy, int sx, int dy, int dx,
-			    int height, int width);
-extern void fbcon_vga_clear(struct vc_data *conp, struct display *p, int sy,
-			    int sx, int height, int width);
-extern void fbcon_vga_putc(struct vc_data *conp, struct display *p, int c,
-			   int yy, int xx);
-extern void fbcon_vga_putcs(struct vc_data *conp, struct display *p,
-			    const unsigned short *s, int count, int yy, int xx);
-extern void fbcon_vga_revc(struct display *p, int xx, int yy);
-
-#endif /* _VIDEO_FBCON_VGA_H */
diff -Nru a/include/video/fbcon.h b/include/video/fbcon.h
--- a/include/video/fbcon.h	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,795 +0,0 @@
-/*
- *  linux/drivers/video/fbcon.h -- Low level frame buffer based console driver
- *
- *	Copyright (C) 1997 Geert Uytterhoeven
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive
- *  for more details.
- */
-
-#ifndef _VIDEO_FBCON_H
-#define _VIDEO_FBCON_H
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/console_struct.h>
-#include <linux/vt_buffer.h>
-
-#include <asm/io.h>
-
-
-    /*                                  
-     *  `switch' for the Low Level Operations
-     */
- 
-struct display_switch {                                                
-    void (*setup)(struct display *p);
-    void (*bmove)(struct display *p, int sy, int sx, int dy, int dx,
-		  int height, int width);
-    /* for clear, conp may be NULL, which means use a blanking (black) color */
-    void (*clear)(struct vc_data *conp, struct display *p, int sy, int sx,
-		  int height, int width);
-    void (*putc)(struct vc_data *conp, struct display *p, int c, int yy,
-    		 int xx);
-    void (*putcs)(struct vc_data *conp, struct display *p, const unsigned short *s,
-		  int count, int yy, int xx);     
-    void (*revc)(struct display *p, int xx, int yy);
-    void (*cursor)(struct display *p, int mode, int xx, int yy);
-    int  (*set_font)(struct display *p, int width, int height);
-    void (*clear_margins)(struct vc_data *conp, struct display *p,
-			  int bottom_only);
-    unsigned int fontwidthmask;      /* 1 at (1 << (width - 1)) if width is supported */
-}; 
-
-extern struct display_switch fbcon_dummy;
-
-   /*
-    *    This is the interface between the low-level console driver and the
-    *    low-level frame buffer device
-    */
-
-struct display {
-    /* Filled in by the frame buffer device */
-
-    struct fb_var_screeninfo var;   /* variable infos. yoffset and vmode */
-                                    /* are updated by fbcon.c */
-    struct fb_cmap cmap;            /* colormap */
-    u_short can_soft_blank;         /* zero if no hardware blanking */
-    u_short inverse;                /* != 0 text black on white as default */
-    struct display_switch *dispsw;  /* low level operations */
-    void *dispsw_data;              /* optional dispsw helper data */
-
-#if 0
-    struct fb_fix_cursorinfo fcrsr;
-    struct fb_var_cursorinfo *vcrsr;
-    struct fb_cursorstate crsrstate;
-#endif
-
-    /* Filled in by the low-level console driver */
-    struct vc_data *conp;           /* pointer to console data */
-    struct fb_info *fb_info;        /* frame buffer for this console */
-    int vrows;                      /* number of virtual rows */
-    unsigned short cursor_x;        /* current cursor position */
-    unsigned short cursor_y;
-    int fgcol;                      /* text colors */
-    int bgcol;
-    u_long next_line;               /* offset to one line below */
-    u_long next_plane;              /* offset to next plane */
-    u_char *fontdata;               /* Font associated to this display */
-    unsigned short _fontheightlog;
-    unsigned short _fontwidthlog;
-    unsigned short _fontheight;
-    unsigned short _fontwidth;
-    int userfont;                   /* != 0 if fontdata kmalloc()ed */
-    u_short scrollmode;             /* Scroll Method */
-    short yscroll;                  /* Hardware scrolling */
-    unsigned char fgshift, bgshift;
-    unsigned short charmask;        /* 0xff or 0x1ff */
-};
-
-/* drivers/video/fbcon.c */
-extern struct display fb_display[MAX_NR_CONSOLES];
-extern char con2fb_map[MAX_NR_CONSOLES];
-extern int PROC_CONSOLE(const struct fb_info *info);
-extern void set_con2fb_map(int unit, int newidx);
-extern int set_all_vcs(int fbidx, struct fb_ops *fb,
-		       struct fb_var_screeninfo *var, struct fb_info *info);
-
-#define fontheight(p) ((p)->_fontheight)
-#define fontheightlog(p) ((p)->_fontheightlog)
-
-#ifdef CONFIG_FBCON_FONTWIDTH8_ONLY
-
-/* fontwidth w is supported by dispsw */
-#define FONTWIDTH(w)	(1 << ((8) - 1))
-/* fontwidths w1-w2 inclusive are supported by dispsw */
-#define FONTWIDTHRANGE(w1,w2)	FONTWIDTH(8)
-
-#define fontwidth(p) (8)
-#define fontwidthlog(p) (0)
-
-#else
-
-/* fontwidth w is supported by dispsw */
-#define FONTWIDTH(w)	(1 << ((w) - 1))
-/* fontwidths w1-w2 inclusive are supported by dispsw */
-#define FONTWIDTHRANGE(w1,w2)	(FONTWIDTH(w2+1) - FONTWIDTH(w1))
-
-#define fontwidth(p) ((p)->_fontwidth)
-#define fontwidthlog(p) ((p)->_fontwidthlog)
-
-#endif
-
-    /*
-     *  Attribute Decoding
-     */
-
-/* Color */
-#define attr_fgcol(p,s)    \
-	(((s) >> ((p)->fgshift)) & 0x0f)
-#define attr_bgcol(p,s)    \
-	(((s) >> ((p)->bgshift)) & 0x0f)
-#define	attr_bgcol_ec(p,conp) \
-	((conp) ? (((conp)->vc_video_erase_char >> ((p)->bgshift)) & 0x0f) : 0)
-#define attr_fgcol_ec(p,vc) \
-	((vc) ? (((vc)->vc_video_erase_char >> ((p)->fgshift)) & 0x0f) : 0)
-
-/* Monochrome */
-#define attr_bold(p,s) \
-	((s) & 0x200)
-#define attr_reverse(p,s) \
-	(((s) & 0x800) ^ ((p)->inverse ? 0x800 : 0))
-#define attr_underline(p,s) \
-	((s) & 0x400)
-#define attr_blink(p,s) \
-	((s) & 0x8000)
-	
-    /*
-     *  Scroll Method
-     */
-     
-/* Internal flags */
-#define __SCROLL_YPAN		0x001
-#define __SCROLL_YWRAP		0x002
-#define __SCROLL_YMOVE		0x003
-#define __SCROLL_YREDRAW	0x004
-#define __SCROLL_YMASK		0x00f
-#define __SCROLL_YFIXED		0x010
-#define __SCROLL_YNOMOVE	0x020
-#define __SCROLL_YPANREDRAW	0x040
-#define __SCROLL_YNOPARTIAL	0x080
-
-/* Only these should be used by the drivers */
-/* Which one should you use? If you have a fast card and slow bus,
-   then probably just 0 to indicate fbcon should choose between
-   YWRAP/YPAN+MOVE/YMOVE. On the other side, if you have a fast bus
-   and even better if your card can do fonting (1->8/32bit painting),
-   you should consider either SCROLL_YREDRAW (if your card is
-   able to do neither YPAN/YWRAP), or SCROLL_YNOMOVE.
-   The best is to test it with some real life scrolling (usually, not
-   all lines on the screen are filled completely with non-space characters,
-   and REDRAW performs much better on such lines, so don't cat a file
-   with every line covering all screen columns, it would not be the right
-   benchmark).
- */
-#define SCROLL_YREDRAW		(__SCROLL_YFIXED|__SCROLL_YREDRAW)
-#define SCROLL_YNOMOVE		(__SCROLL_YNOMOVE|__SCROLL_YPANREDRAW)
-
-/* SCROLL_YNOPARTIAL, used in combination with the above, is for video
-   cards which can not handle using panning to scroll a portion of the
-   screen without excessive flicker.  Panning will only be used for
-   whole screens.
- */
-/* Namespace consistency */
-#define SCROLL_YNOPARTIAL	__SCROLL_YNOPARTIAL
-
-
-#if defined(__sparc__)
-
-/* We map all of our framebuffers such that big-endian accesses
- * are what we want, so the following is sufficient.
- */
-
-#define fb_readb sbus_readb
-#define fb_readw sbus_readw
-#define fb_readl sbus_readl
-#define fb_writeb sbus_writeb
-#define fb_writew sbus_writew
-#define fb_writel sbus_writel
-#define fb_memset sbus_memset_io
-
-#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__)
-
-#define fb_readb __raw_readb
-#define fb_readw __raw_readw
-#define fb_readl __raw_readl
-#define fb_writeb __raw_writeb
-#define fb_writew __raw_writew
-#define fb_writel __raw_writel
-#define fb_memset memset_io
-
-#else
-
-#define fb_readb(addr) (*(volatile u8 *) (addr))
-#define fb_readw(addr) (*(volatile u16 *) (addr))
-#define fb_readl(addr) (*(volatile u32 *) (addr))
-#define fb_writeb(b,addr) (*(volatile u8 *) (addr) = (b))
-#define fb_writew(b,addr) (*(volatile u16 *) (addr) = (b))
-#define fb_writel(b,addr) (*(volatile u32 *) (addr) = (b))
-#define fb_memset memset
-
-#endif
-
-
-extern void fbcon_redraw_clear(struct vc_data *, struct display *, int, int, int, int);
-extern void fbcon_redraw_bmove(struct display *, int, int, int, int, int, int);
-
-
-/* ================================================================= */
-/*                      Utility Assembler Functions                  */
-/* ================================================================= */
-
-
-#if defined(__mc68000__)
-
-/* ====================================================================== */
-
-/* Those of a delicate disposition might like to skip the next couple of
- * pages.
- *
- * These functions are drop in replacements for memmove and
- * memset(_, 0, _). However their five instances add at least a kilobyte
- * to the object file. You have been warned.
- *
- * Not a great fan of assembler for the sake of it, but I think
- * that these routines are at least 10 times faster than their C
- * equivalents for large blits, and that's important to the lowest level of
- * a graphics driver. Question is whether some scheme with the blitter
- * would be faster. I suspect not for simple text system - not much
- * asynchrony.
- *
- * Code is very simple, just gruesome expansion. Basic strategy is to
- * increase data moved/cleared at each step to 16 bytes to reduce
- * instruction per data move overhead. movem might be faster still
- * For more than 15 bytes, we try to align the write direction on a
- * longword boundary to get maximum speed. This is even more gruesome.
- * Unaligned read/write used requires 68020+ - think this is a problem?
- *
- * Sorry!
- */
-
-
-/* ++roman: I've optimized Robert's original versions in some minor
- * aspects, e.g. moveq instead of movel, let gcc choose the registers,
- * use movem in some places...
- * For other modes than 1 plane, lots of more such assembler functions
- * were needed (e.g. the ones using movep or expanding color values).
- */
-
-/* ++andreas: more optimizations:
-   subl #65536,d0 replaced by clrw d0; subql #1,d0 for dbcc
-   addal is faster than addaw
-   movep is rather expensive compared to ordinary move's
-   some functions rewritten in C for clarity, no speed loss */
-
-static __inline__ void *fb_memclear_small(void *s, size_t count)
-{
-   if (!count)
-      return(0);
-
-   __asm__ __volatile__(
-         "lsrl   #1,%1 ; jcc 1f ; moveb %2,%0@-\n\t"
-      "1: lsrl   #1,%1 ; jcc 1f ; movew %2,%0@-\n\t"
-      "1: lsrl   #1,%1 ; jcc 1f ; movel %2,%0@-\n\t"
-      "1: lsrl   #1,%1 ; jcc 1f ; movel %2,%0@- ; movel %2,%0@-\n\t"
-      "1:"
-         : "=a" (s), "=d" (count)
-         : "d" (0), "0" ((char *)s+count), "1" (count)
-   );
-   __asm__ __volatile__(
-         "subql  #1,%1 ; jcs 3f\n\t"
-	 "movel %2,%%d4; movel %2,%%d5; movel %2,%%d6\n\t"
-      "2: moveml %2/%%d4/%%d5/%%d6,%0@-\n\t"
-         "dbra %1,2b\n\t"
-      "3:"
-         : "=a" (s), "=d" (count)
-         : "d" (0), "0" (s), "1" (count)
-	 : "d4", "d5", "d6"
-  );
-
-   return(0);
-}
-
-
-static __inline__ void *fb_memclear(void *s, size_t count)
-{
-   if (!count)
-      return(0);
-
-   if (count < 16) {
-      __asm__ __volatile__(
-            "lsrl   #1,%1 ; jcc 1f ; clrb %0@+\n\t"
-         "1: lsrl   #1,%1 ; jcc 1f ; clrw %0@+\n\t"
-         "1: lsrl   #1,%1 ; jcc 1f ; clrl %0@+\n\t"
-         "1: lsrl   #1,%1 ; jcc 1f ; clrl %0@+ ; clrl %0@+\n\t"
-         "1:"
-            : "=a" (s), "=d" (count)
-            : "0" (s), "1" (count)
-     );
-   } else {
-      long tmp;
-      __asm__ __volatile__(
-            "movel %1,%2\n\t"
-            "lsrl   #1,%2 ; jcc 1f ; clrb %0@+ ; subqw #1,%1\n\t"
-            "lsrl   #1,%2 ; jcs 2f\n\t"  /* %0 increased=>bit 2 switched*/
-            "clrw   %0@+  ; subqw  #2,%1 ; jra 2f\n\t"
-         "1: lsrl   #1,%2 ; jcc 2f\n\t"
-            "clrw   %0@+  ; subqw  #2,%1\n\t"
-         "2: movew %1,%2; lsrl #2,%1 ; jeq 6f\n\t"
-            "lsrl   #1,%1 ; jcc 3f ; clrl %0@+\n\t"
-         "3: lsrl   #1,%1 ; jcc 4f ; clrl %0@+ ; clrl %0@+\n\t"
-         "4: subql  #1,%1 ; jcs 6f\n\t"
-         "5: clrl %0@+; clrl %0@+ ; clrl %0@+ ; clrl %0@+\n\t"
-            "dbra %1,5b   ; clrw %1; subql #1,%1; jcc 5b\n\t"
-         "6: movew %2,%1; btst #1,%1 ; jeq 7f ; clrw %0@+\n\t"
-         "7:            ; btst #0,%1 ; jeq 8f ; clrb %0@+\n\t"
-         "8:"
-            : "=a" (s), "=d" (count), "=d" (tmp)
-            : "0" (s), "1" (count)
-     );
-   }
-
-   return(0);
-}
-
-
-static __inline__ void *fb_memset255(void *s, size_t count)
-{
-   if (!count)
-      return(0);
-
-   __asm__ __volatile__(
-         "lsrl   #1,%1 ; jcc 1f ; moveb %2,%0@-\n\t"
-      "1: lsrl   #1,%1 ; jcc 1f ; movew %2,%0@-\n\t"
-      "1: lsrl   #1,%1 ; jcc 1f ; movel %2,%0@-\n\t"
-      "1: lsrl   #1,%1 ; jcc 1f ; movel %2,%0@- ; movel %2,%0@-\n\t"
-      "1:"
-         : "=a" (s), "=d" (count)
-         : "d" (-1), "0" ((char *)s+count), "1" (count)
-   );
-   __asm__ __volatile__(
-         "subql  #1,%1 ; jcs 3f\n\t"
-	 "movel %2,%%d4; movel %2,%%d5; movel %2,%%d6\n\t"
-      "2: moveml %2/%%d4/%%d5/%%d6,%0@-\n\t"
-         "dbra %1,2b\n\t"
-      "3:"
-         : "=a" (s), "=d" (count)
-         : "d" (-1), "0" (s), "1" (count)
-	 : "d4", "d5", "d6"
-  );
-
-   return(0);
-}
-
-
-static __inline__ void *fb_memmove(void *d, const void *s, size_t count)
-{
-   if (d < s) {
-      if (count < 16) {
-         __asm__ __volatile__(
-               "lsrl   #1,%2 ; jcc 1f ; moveb %1@+,%0@+\n\t"
-            "1: lsrl   #1,%2 ; jcc 1f ; movew %1@+,%0@+\n\t"
-            "1: lsrl   #1,%2 ; jcc 1f ; movel %1@+,%0@+\n\t"
-            "1: lsrl   #1,%2 ; jcc 1f ; movel %1@+,%0@+ ; movel %1@+,%0@+\n\t"
-            "1:"
-               : "=a" (d), "=a" (s), "=d" (count)
-               : "0" (d), "1" (s), "2" (count)
-        );
-      } else {
-         long tmp;
-         __asm__ __volatile__(
-               "movel  %0,%3\n\t"
-               "lsrl   #1,%3 ; jcc 1f ; moveb %1@+,%0@+ ; subqw #1,%2\n\t"
-               "lsrl   #1,%3 ; jcs 2f\n\t"  /* %0 increased=>bit 2 switched*/
-               "movew  %1@+,%0@+  ; subqw  #2,%2 ; jra 2f\n\t"
-            "1: lsrl   #1,%3 ; jcc 2f\n\t"
-               "movew  %1@+,%0@+  ; subqw  #2,%2\n\t"
-            "2: movew  %2,%-; lsrl #2,%2 ; jeq 6f\n\t"
-               "lsrl   #1,%2 ; jcc 3f ; movel %1@+,%0@+\n\t"
-            "3: lsrl   #1,%2 ; jcc 4f ; movel %1@+,%0@+ ; movel %1@+,%0@+\n\t"
-            "4: subql  #1,%2 ; jcs 6f\n\t"
-            "5: movel  %1@+,%0@+;movel %1@+,%0@+\n\t"
-               "movel  %1@+,%0@+;movel %1@+,%0@+\n\t"
-               "dbra   %2,5b ; clrw %2; subql #1,%2; jcc 5b\n\t"
-            "6: movew  %+,%2; btst #1,%2 ; jeq 7f ; movew %1@+,%0@+\n\t"
-            "7:              ; btst #0,%2 ; jeq 8f ; moveb %1@+,%0@+\n\t"
-            "8:"
-               : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
-               : "0" (d), "1" (s), "2" (count)
-        );
-      }
-   } else {
-      if (count < 16) {
-         __asm__ __volatile__(
-               "lsrl   #1,%2 ; jcc 1f ; moveb %1@-,%0@-\n\t"
-            "1: lsrl   #1,%2 ; jcc 1f ; movew %1@-,%0@-\n\t"
-            "1: lsrl   #1,%2 ; jcc 1f ; movel %1@-,%0@-\n\t"
-            "1: lsrl   #1,%2 ; jcc 1f ; movel %1@-,%0@- ; movel %1@-,%0@-\n\t"
-            "1:"
-               : "=a" (d), "=a" (s), "=d" (count)
-               : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count)
-        );
-      } else {
-         long tmp;
-         __asm__ __volatile__(
-               "movel %0,%3\n\t"
-               "lsrl   #1,%3 ; jcc 1f ; moveb %1@-,%0@- ; subqw #1,%2\n\t"
-               "lsrl   #1,%3 ; jcs 2f\n\t"  /* %0 increased=>bit 2 switched*/
-               "movew  %1@-,%0@-  ; subqw  #2,%2 ; jra 2f\n\t"
-            "1: lsrl   #1,%3 ; jcc 2f\n\t"
-               "movew  %1@-,%0@-  ; subqw  #2,%2\n\t"
-            "2: movew %2,%-; lsrl #2,%2 ; jeq 6f\n\t"
-               "lsrl   #1,%2 ; jcc 3f ; movel %1@-,%0@-\n\t"
-            "3: lsrl   #1,%2 ; jcc 4f ; movel %1@-,%0@- ; movel %1@-,%0@-\n\t"
-            "4: subql  #1,%2 ; jcs 6f\n\t"
-            "5: movel %1@-,%0@-;movel %1@-,%0@-\n\t"
-               "movel %1@-,%0@-;movel %1@-,%0@-\n\t"
-               "dbra %2,5b ; clrw %2; subql #1,%2; jcc 5b\n\t"
-            "6: movew %+,%2; btst #1,%2 ; jeq 7f ; movew %1@-,%0@-\n\t"
-            "7:              ; btst #0,%2 ; jeq 8f ; moveb %1@-,%0@-\n\t"
-            "8:"
-               : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
-               : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count)
-        );
-      }
-   }
-
-   return(0);
-}
-
-
-/* ++andreas: Simple and fast version of memmove, assumes size is
-   divisible by 16, suitable for moving the whole screen bitplane */
-static __inline__ void fast_memmove(char *dst, const char *src, size_t size)
-{
-  if (!size)
-    return;
-  if (dst < src)
-    __asm__ __volatile__
-      ("1:"
-       "  moveml %0@+,%/d0/%/d1/%/a0/%/a1\n"
-       "  moveml %/d0/%/d1/%/a0/%/a1,%1@\n"
-       "  addql #8,%1; addql #8,%1\n"
-       "  dbra %2,1b\n"
-       "  clrw %2; subql #1,%2\n"
-       "  jcc 1b"
-       : "=a" (src), "=a" (dst), "=d" (size)
-       : "0" (src), "1" (dst), "2" (size / 16 - 1)
-       : "d0", "d1", "a0", "a1", "memory");
-  else
-    __asm__ __volatile__
-      ("1:"
-       "  subql #8,%0; subql #8,%0\n"
-       "  moveml %0@,%/d0/%/d1/%/a0/%/a1\n"
-       "  moveml %/d0/%/d1/%/a0/%/a1,%1@-\n"
-       "  dbra %2,1b\n"
-       "  clrw %2; subql #1,%2\n"
-       "  jcc 1b"
-       : "=a" (src), "=a" (dst), "=d" (size)
-       : "0" (src + size), "1" (dst + size), "2" (size / 16 - 1)
-       : "d0", "d1", "a0", "a1", "memory");
-}
-
-#elif defined(CONFIG_SUN4)
-
-/* You may think that I'm crazy and that I should use generic
-   routines.  No, I'm not: sun4's framebuffer crashes if we std
-   into it, so we cannot use memset.  */
-
-static __inline__ void *sun4_memset(void *s, char val, size_t count)
-{
-    int i;
-    for(i=0; i<count;i++)
-        ((char *) s) [i] = val;
-    return s;
-}
-
-static __inline__ void *fb_memset255(void *s, size_t count)
-{
-    return sun4_memset(s, 255, count);
-}
-
-static __inline__ void *fb_memclear(void *s, size_t count)
-{
-    return sun4_memset(s, 0, count);
-}
-
-static __inline__ void *fb_memclear_small(void *s, size_t count)
-{
-    return sun4_memset(s, 0, count);
-}
-
-/* To be honest, this is slow_memmove :). But sun4 is crappy, so what we can do. */
-static __inline__ void fast_memmove(void *d, const void *s, size_t count)
-{
-    int i;
-    if (d<s) {
-	for (i=0; i<count; i++)
-	    ((char *) d)[i] = ((char *) s)[i];
-    } else
-	for (i=0; i<count; i++)
-	    ((char *) d)[count-i-1] = ((char *) s)[count-i-1];
-}
-
-static __inline__ void *fb_memmove(char *dst, const char *src, size_t size)
-{
-    fast_memmove(dst, src, size);
-    return dst;
-}
-
-#else
-
-static __inline__ void *fb_memclear_small(void *s, size_t count)
-{
-    char *xs = (char *) s;
-
-    while (count--)
-	fb_writeb(0, xs++);
-
-    return s;
-}
-
-static __inline__ void *fb_memclear(void *s, size_t count)
-{
-    unsigned long xs = (unsigned long) s;
-
-    if (count < 8)
-	goto rest;
-
-    if (xs & 1) {
-	fb_writeb(0, xs++);
-	count--;
-    }
-    if (xs & 2) {
-	fb_writew(0, xs);
-	xs += 2;
-	count -= 2;
-    }
-    while (count > 3) {
-	fb_writel(0, xs);
-	xs += 4;
-	count -= 4;
-    }
-rest:
-    while (count--)
-	fb_writeb(0, xs++);
-
-    return s;
-}
-
-static __inline__ void *fb_memset255(void *s, size_t count)
-{
-    unsigned long xs = (unsigned long) s;
-
-    if (count < 8)
-	goto rest;
-
-    if (xs & 1) {
-	fb_writeb(0xff, xs++);
-	count--;
-    }
-    if (xs & 2) {
-	fb_writew(0xffff, xs);
-	xs += 2;
-	count -= 2;
-    }
-    while (count > 3) {
-	fb_writel(0xffffffff, xs);
-	xs += 4;
-	count -= 4;
-    }
-rest:
-    while (count--)
-	fb_writeb(0xff, xs++);
-
-    return s;
-}
-
-#if defined(__i386__)
-
-static __inline__ void fast_memmove(void *d, const void *s, size_t count)
-{
-  int d0, d1, d2, d3;
-    if (d < s) {
-__asm__ __volatile__ (
-	"cld\n\t"
-	"shrl $1,%%ecx\n\t"
-	"jnc 1f\n\t"
-	"movsb\n"
-	"1:\tshrl $1,%%ecx\n\t"
-	"jnc 2f\n\t"
-	"movsw\n"
-	"2:\trep\n\t"
-	"movsl"
-	: "=&c" (d0), "=&D" (d1), "=&S" (d2)
-	:"0"(count),"1"((long)d),"2"((long)s)
-	:"memory");
-    } else {
-__asm__ __volatile__ (
-	"std\n\t"
-	"shrl $1,%%ecx\n\t"
-	"jnc 1f\n\t"
-	"movb 3(%%esi),%%al\n\t"
-	"movb %%al,3(%%edi)\n\t"
-	"decl %%esi\n\t"
-	"decl %%edi\n"
-	"1:\tshrl $1,%%ecx\n\t"
-	"jnc 2f\n\t"
-	"movw 2(%%esi),%%ax\n\t"
-	"movw %%ax,2(%%edi)\n\t"
-	"decl %%esi\n\t"
-	"decl %%edi\n\t"
-	"decl %%esi\n\t"
-	"decl %%edi\n"
-	"2:\trep\n\t"
-	"movsl\n\t"
-	"cld"
-	: "=&c" (d0), "=&D" (d1), "=&S" (d2), "=&a" (d3)
-	:"0"(count),"1"(count-4+(long)d),"2"(count-4+(long)s)
-	:"memory");
-    }
-}
-
-static __inline__ void *fb_memmove(char *dst, const char *src, size_t size)
-{
-    fast_memmove(dst, src, size);
-    return dst;
-}
-
-#else /* !__i386__ */
-
-    /*
-     *  Anyone who'd like to write asm functions for other CPUs?
-     *   (Why are these functions better than those from include/asm/string.h?)
-     */
-
-static __inline__ void *fb_memmove(void *d, const void *s, size_t count)
-{
-    unsigned long dst, src;
-
-    if (d < s) {
-	dst = (unsigned long) d;
-	src = (unsigned long) s;
-
-	if ((count < 8) || ((dst ^ src) & 3))
-	    goto restup;
-
-	if (dst & 1) {
-	    fb_writeb(fb_readb(src++), dst++);
-	    count--;
-	}
-	if (dst & 2) {
-	    fb_writew(fb_readw(src), dst);
-	    src += 2;
-	    dst += 2;
-	    count -= 2;
-	}
-	while (count > 3) {
-	    fb_writel(fb_readl(src), dst);
-	    src += 4;
-	    dst += 4;
-	    count -= 4;
-	}
-
-    restup:
-	while (count--)
-	    fb_writeb(fb_readb(src++), dst++);
-    } else {
-	dst = (unsigned long) d + count;
-	src = (unsigned long) s + count;
-
-	if ((count < 8) || ((dst ^ src) & 3))
-	    goto restdown;
-
-	if (dst & 1) {
-	    src--;
-	    dst--;
-	    count--;
-	    fb_writeb(fb_readb(src), dst);
-	}
-	if (dst & 2) {
-	    src -= 2;
-	    dst -= 2;
-	    count -= 2;
-	    fb_writew(fb_readw(src), dst);
-	}
-	while (count > 3) {
-	    src -= 4;
-	    dst -= 4;
-	    count -= 4;
-	    fb_writel(fb_readl(src), dst);
-	}
-
-    restdown:
-	while (count--) {
-	    src--;
-	    dst--;
-	    fb_writeb(fb_readb(src), dst);
-	}
-    }
-
-    return d;
-}
-
-static __inline__ void fast_memmove(char *d, const char *s, size_t count)
-{
-    unsigned long dst, src;
-
-    if (d < s) {
-	dst = (unsigned long) d;
-	src = (unsigned long) s;
-
-	if ((count < 8) || ((dst ^ src) & 3))
-	    goto restup;
-
-	if (dst & 1) {
-	    fb_writeb(fb_readb(src++), dst++);
-	    count--;
-	}
-	if (dst & 2) {
-	    fb_writew(fb_readw(src), dst);
-	    src += 2;
-	    dst += 2;
-	    count -= 2;
-	}
-	while (count > 3) {
-	    fb_writel(fb_readl(src), dst);
-	    src += 4;
-	    dst += 4;
-	    count -= 4;
-	}
-
-    restup:
-	while (count--)
-	    fb_writeb(fb_readb(src++), dst++);
-    } else {
-	dst = (unsigned long) d + count;
-	src = (unsigned long) s + count;
-
-	if ((count < 8) || ((dst ^ src) & 3))
-	    goto restdown;
-
-	if (dst & 1) {
-	    src--;
-	    dst--;
-	    count--;
-	    fb_writeb(fb_readb(src), dst);
-	}
-	if (dst & 2) {
-	    src -= 2;
-	    dst -= 2;
-	    count -= 2;
-	    fb_writew(fb_readw(src), dst);
-	}
-	while (count > 3) {
-	    src -= 4;
-	    dst -= 4;
-	    count -= 4;
-	    fb_writel(fb_readl(src), dst);
-	}
-
-    restdown:
-	while (count--) {
-	    src--;
-	    dst--;
-	    fb_writeb(fb_readb(src), dst);
-	}
-    }
-}
-
-#endif /* !__i386__ */
-
-#endif /* !__mc68000__ */
-
-#endif /* _VIDEO_FBCON_H */
diff -Nru a/include/video/font.h b/include/video/font.h
--- a/include/video/font.h	Mon Dec  9 18:46:36 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,53 +0,0 @@
-/*
- *  font.h -- `Soft' font definitions
- *
- *  Created 1995 by Geert Uytterhoeven
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive
- *  for more details.
- */
-
-#ifndef _VIDEO_FONT_H
-#define _VIDEO_FONT_H
-
-#include <linux/types.h>
-
-struct fbcon_font_desc {
-    int idx;
-    char *name;
-    int width, height;
-    void *data;
-    int pref;
-};
-
-#define VGA8x8_IDX	0
-#define VGA8x16_IDX	1
-#define PEARL8x8_IDX	2
-#define VGA6x11_IDX	3
-#define SUN8x16_IDX	4
-#define SUN12x22_IDX	5
-#define ACORN8x8_IDX	6
-#define	MINI4x6_IDX	7
-
-extern struct fbcon_font_desc	font_vga_8x8,
-				font_vga_8x16,
-				font_pearl_8x8,
-				font_vga_6x11,
-				font_sun_8x16,
-				font_sun_12x22,
-				font_acorn_8x8,
-				font_mini_4x6;
-
-/* Find a font with a specific name */
-
-extern struct fbcon_font_desc *fbcon_find_font(char *name);
-
-/* Get the default font for a specific screen size */
-
-extern struct fbcon_font_desc *fbcon_get_default_font(int xres, int yres);
-
-/* Max. length for the name of a predefined font */
-#define MAX_FONT_NAME	32
-
-#endif /* _VIDEO_FONT_H */
diff -Nru a/include/video/iga.h b/include/video/iga.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/video/iga.h	Mon Dec  9 18:46:35 2002
@@ -0,0 +1,24 @@
+/* $Id: iga.h,v 1.2 1999/09/11 22:56:31 zaitcev Exp $
+ * iga1682.h: Sparc/PCI iga1682 driver constants etc.
+ *
+ * Copyleft 1998 V. Roganov and G. Raiko
+ */
+
+#ifndef _IGA1682_H
+#define _IGA1682_H 1
+
+#define IGA_ATTR_CTL			0x3C0
+#define   IGA_IDX_VGA_OVERSCAN		0x11
+#define DAC_W_INDEX                     0x03C8
+#define DAC_DATA                        0x03C9
+#define IGA_EXT_CNTRL                   0x3CE
+#define   IGA_IDX_EXT_BUS_CNTL          0x30
+#define     MEM_SIZE_ALIAS              0x3
+#define     MEM_SIZE_1M                 0x0
+#define     MEM_SIZE_2M                 0x1
+#define     MEM_SIZE_4M                 0x2
+#define     MEM_SIZE_RESERVED           0x3
+#define   IGA_IDX_OVERSCAN_COLOR        0x58
+#define   IGA_IDX_EXT_MEM_2             0x72
+
+#endif /* !(_IGA1682_H) */
diff -Nru a/include/video/macmodes.h b/include/video/macmodes.h
--- a/include/video/macmodes.h	Mon Dec  9 18:46:37 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,70 +0,0 @@
-/*
- *  linux/drivers/video/macmodes.h -- Standard MacOS video modes
- *
- *	Copyright (C) 1998 Geert Uytterhoeven
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License. See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-#ifndef _VIDEO_MACMODES_H
-#define _VIDEO_MACMODES_H
-
-    /*
-     *  Video mode values.
-     *  These are supposed to be the same as the values that Apple uses in
-     *  MacOS.
-     */
-
-#define VMODE_NVRAM		0
-#define VMODE_512_384_60I	1	/* 512x384, 60Hz interlaced (NTSC) */
-#define VMODE_512_384_60	2	/* 512x384, 60Hz */
-#define VMODE_640_480_50I	3	/* 640x480, 50Hz interlaced (PAL) */
-#define VMODE_640_480_60I	4	/* 640x480, 60Hz interlaced (NTSC) */
-#define VMODE_640_480_60	5	/* 640x480, 60Hz (VGA) */
-#define VMODE_640_480_67	6	/* 640x480, 67Hz */
-#define VMODE_640_870_75P	7	/* 640x870, 75Hz (portrait) */
-#define VMODE_768_576_50I	8	/* 768x576, 50Hz (PAL full frame) */
-#define VMODE_800_600_56	9	/* 800x600, 56Hz */
-#define VMODE_800_600_60	10	/* 800x600, 60Hz */
-#define VMODE_800_600_72	11	/* 800x600, 72Hz */
-#define VMODE_800_600_75	12	/* 800x600, 75Hz */
-#define VMODE_832_624_75	13	/* 832x624, 75Hz */
-#define VMODE_1024_768_60	14	/* 1024x768, 60Hz */
-#define VMODE_1024_768_70	15	/* 1024x768, 70Hz (or 72Hz?) */
-#define VMODE_1024_768_75V	16	/* 1024x768, 75Hz (VESA) */
-#define VMODE_1024_768_75	17	/* 1024x768, 75Hz */
-#define VMODE_1152_870_75	18	/* 1152x870, 75Hz */
-#define VMODE_1280_960_75	19	/* 1280x960, 75Hz */
-#define VMODE_1280_1024_75	20	/* 1280x1024, 75Hz */
-#define VMODE_1152_768_60	21	/* 1152x768, 60Hz     Titanium PowerBook */
-#define VMODE_1600_1024_60	22	/* 1600x1024, 60Hz 22" Cinema Display */
-#define VMODE_MAX		22
-#define VMODE_CHOOSE		99
-
-#define CMODE_NVRAM		-1
-#define CMODE_CHOOSE		-2
-#define CMODE_8			0	/* 8 bits/pixel */
-#define CMODE_16		1	/* 16 (actually 15) bits/pixel */
-#define CMODE_32		2	/* 32 (actually 24) bits/pixel */
-
-
-extern int mac_vmode_to_var(int vmode, int cmode,
-			    struct fb_var_screeninfo *var);
-extern int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode,
-			    int *cmode);
-extern int mac_map_monitor_sense(int sense);
-extern int __init mac_find_mode(struct fb_var_screeninfo *var,
-				struct fb_info *info, const char *mode_option,
-				unsigned int default_bpp);
-
-
-    /*
-     *  Addresses in NVRAM where video mode and pixel size are stored.
-     */
-
-#define NV_VMODE		0x140f
-#define NV_CMODE		0x1410
-
-#endif /* _VIDEO_MACMODES_H */
diff -Nru a/include/video/neomagic.h b/include/video/neomagic.h
--- a/include/video/neomagic.h	Mon Dec  9 18:46:36 2002
+++ b/include/video/neomagic.h	Mon Dec  9 18:46:36 2002
@@ -176,6 +176,7 @@
   int lcd_stretch;
   int internal_display;
   int external_display;
+  int libretto;
 };
 
 typedef struct {
diff -Nru a/include/video/radeon.h b/include/video/radeon.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/video/radeon.h	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,766 @@
+#ifndef _RADEON_H
+#define _RADEON_H
+
+
+/* radeon PCI ids */
+#define PCI_DEVICE_ID_RADEON_QD		0x5144
+#define PCI_DEVICE_ID_RADEON_QE		0x5145
+#define PCI_DEVICE_ID_RADEON_QF		0x5146
+#define PCI_DEVICE_ID_RADEON_QG		0x5147
+#define PCI_DEVICE_ID_RADEON_QY		0x5159
+#define PCI_DEVICE_ID_RADEON_QZ		0x515a
+#define PCI_DEVICE_ID_RADEON_LW		0x4c57
+#define PCI_DEVICE_ID_RADEON_LY		0x4c59
+#define PCI_DEVICE_ID_RADEON_LZ		0x4c5a
+#define PCI_DEVICE_ID_RADEON_QL		0x514c
+#define PCI_DEVICE_ID_RADEON_QW		0x5157
+
+#define RADEON_REGSIZE			0x4000
+
+
+#define MM_INDEX                               0x0000  
+#define MM_DATA                                0x0004  
+#define BUS_CNTL                               0x0030  
+#define HI_STAT                                0x004C  
+#define BUS_CNTL1                              0x0034
+#define I2C_CNTL_1			       0x0094  
+#define CONFIG_CNTL                            0x00E0  
+#define CONFIG_MEMSIZE                         0x00F8  
+#define CONFIG_APER_0_BASE                     0x0100  
+#define CONFIG_APER_1_BASE                     0x0104  
+#define CONFIG_APER_SIZE                       0x0108  
+#define CONFIG_REG_1_BASE                      0x010C  
+#define CONFIG_REG_APER_SIZE                   0x0110  
+#define PAD_AGPINPUT_DELAY                     0x0164  
+#define PAD_CTLR_STRENGTH                      0x0168  
+#define PAD_CTLR_UPDATE                        0x016C
+#define AGP_CNTL                               0x0174
+#define BM_STATUS                              0x0160
+#define CAP0_TRIG_CNTL			       0x0950
+#define VIPH_CONTROL			       0x0C40
+#define VENDOR_ID                              0x0F00  
+#define DEVICE_ID                              0x0F02  
+#define COMMAND                                0x0F04  
+#define STATUS                                 0x0F06  
+#define REVISION_ID                            0x0F08  
+#define REGPROG_INF                            0x0F09  
+#define SUB_CLASS                              0x0F0A  
+#define BASE_CODE                              0x0F0B  
+#define CACHE_LINE                             0x0F0C  
+#define LATENCY                                0x0F0D  
+#define HEADER                                 0x0F0E  
+#define BIST                                   0x0F0F  
+#define REG_MEM_BASE                           0x0F10  
+#define REG_IO_BASE                            0x0F14  
+#define REG_REG_BASE                           0x0F18
+#define ADAPTER_ID                             0x0F2C
+#define BIOS_ROM                               0x0F30
+#define CAPABILITIES_PTR                       0x0F34  
+#define INTERRUPT_LINE                         0x0F3C  
+#define INTERRUPT_PIN                          0x0F3D  
+#define MIN_GRANT                              0x0F3E  
+#define MAX_LATENCY                            0x0F3F  
+#define ADAPTER_ID_W                           0x0F4C  
+#define PMI_CAP_ID                             0x0F50  
+#define PMI_NXT_CAP_PTR                        0x0F51  
+#define PMI_PMC_REG                            0x0F52  
+#define PM_STATUS                              0x0F54  
+#define PMI_DATA                               0x0F57  
+#define AGP_CAP_ID                             0x0F58  
+#define AGP_STATUS                             0x0F5C  
+#define AGP_COMMAND                            0x0F60  
+#define AIC_CTRL                               0x01D0
+#define AIC_STAT                               0x01D4
+#define AIC_PT_BASE                            0x01D8
+#define AIC_LO_ADDR                            0x01DC  
+#define AIC_HI_ADDR                            0x01E0  
+#define AIC_TLB_ADDR                           0x01E4  
+#define AIC_TLB_DATA                           0x01E8  
+#define DAC_CNTL                               0x0058  
+#define CRTC_GEN_CNTL                          0x0050  
+#define MEM_CNTL                               0x0140  
+#define EXT_MEM_CNTL                           0x0144  
+#define MC_AGP_LOCATION                        0x014C  
+#define MEM_IO_CNTL_A0                         0x0178  
+#define MEM_INIT_LATENCY_TIMER                 0x0154  
+#define MEM_SDRAM_MODE_REG                     0x0158  
+#define AGP_BASE                               0x0170  
+#define MEM_IO_CNTL_A1                         0x017C  
+#define MEM_IO_CNTL_B0                         0x0180
+#define MEM_IO_CNTL_B1                         0x0184
+#define MC_DEBUG                               0x0188
+#define MC_STATUS                              0x0150  
+#define MEM_IO_OE_CNTL                         0x018C  
+#define MC_FB_LOCATION                         0x0148  
+#define HOST_PATH_CNTL                         0x0130  
+#define MEM_VGA_WP_SEL                         0x0038  
+#define MEM_VGA_RP_SEL                         0x003C  
+#define HDP_DEBUG                              0x0138  
+#define SW_SEMAPHORE                           0x013C  
+#define SURFACE_CNTL                           0x0B00  
+#define SURFACE0_LOWER_BOUND                   0x0B04  
+#define SURFACE1_LOWER_BOUND                   0x0B14  
+#define SURFACE2_LOWER_BOUND                   0x0B24  
+#define SURFACE3_LOWER_BOUND                   0x0B34  
+#define SURFACE4_LOWER_BOUND                   0x0B44  
+#define SURFACE5_LOWER_BOUND                   0x0B54
+#define SURFACE6_LOWER_BOUND                   0x0B64
+#define SURFACE7_LOWER_BOUND                   0x0B74
+#define SURFACE0_UPPER_BOUND                   0x0B08  
+#define SURFACE1_UPPER_BOUND                   0x0B18  
+#define SURFACE2_UPPER_BOUND                   0x0B28  
+#define SURFACE3_UPPER_BOUND                   0x0B38  
+#define SURFACE4_UPPER_BOUND                   0x0B48  
+#define SURFACE5_UPPER_BOUND                   0x0B58  
+#define SURFACE6_UPPER_BOUND                   0x0B68  
+#define SURFACE7_UPPER_BOUND                   0x0B78  
+#define SURFACE0_INFO                          0x0B0C  
+#define SURFACE1_INFO                          0x0B1C  
+#define SURFACE2_INFO                          0x0B2C  
+#define SURFACE3_INFO                          0x0B3C  
+#define SURFACE4_INFO                          0x0B4C  
+#define SURFACE5_INFO                          0x0B5C  
+#define SURFACE6_INFO                          0x0B6C
+#define SURFACE7_INFO                          0x0B7C
+#define SURFACE_ACCESS_FLAGS                   0x0BF8
+#define SURFACE_ACCESS_CLR                     0x0BFC  
+#define GEN_INT_CNTL                           0x0040  
+#define GEN_INT_STATUS                         0x0044  
+#define CRTC_EXT_CNTL                          0x0054
+#define RB3D_CNTL			       0x1C3C  
+#define WAIT_UNTIL                             0x1720  
+#define ISYNC_CNTL                             0x1724  
+#define RBBM_GUICNTL                           0x172C  
+#define RBBM_STATUS                            0x0E40  
+#define RBBM_STATUS_alt_1                      0x1740  
+#define RBBM_CNTL                              0x00EC  
+#define RBBM_CNTL_alt_1                        0x0E44  
+#define RBBM_SOFT_RESET                        0x00F0  
+#define RBBM_SOFT_RESET_alt_1                  0x0E48  
+#define NQWAIT_UNTIL                           0x0E50  
+#define RBBM_DEBUG                             0x0E6C
+#define RBBM_CMDFIFO_ADDR                      0x0E70
+#define RBBM_CMDFIFO_DATAL                     0x0E74
+#define RBBM_CMDFIFO_DATAH                     0x0E78  
+#define RBBM_CMDFIFO_STAT                      0x0E7C  
+#define CRTC_STATUS                            0x005C  
+#define GPIO_VGA_DDC                           0x0060  
+#define GPIO_DVI_DDC                           0x0064  
+#define GPIO_MONID                             0x0068  
+#define PALETTE_INDEX                          0x00B0  
+#define PALETTE_DATA                           0x00B4  
+#define PALETTE_30_DATA                        0x00B8  
+#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_DEBUG                             0x021C
+#define CRTC_OFFSET_RIGHT                      0x0220  
+#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 DISPLAY_BASE_ADDR                      0x023C  
+#define SNAPSHOT_VH_COUNTS                     0x0240  
+#define SNAPSHOT_F_COUNT                       0x0244  
+#define N_VIF_COUNT                            0x0248  
+#define SNAPSHOT_VIF_COUNT                     0x024C  
+#define FP_CRTC_H_TOTAL_DISP                   0x0250  
+#define FP_CRTC_V_TOTAL_DISP                   0x0254  
+#define CRT_CRTC_H_SYNC_STRT_WID               0x0258
+#define CRT_CRTC_V_SYNC_STRT_WID               0x025C
+#define CUR_OFFSET                             0x0260
+#define CUR_HORZ_VERT_POSN                     0x0264  
+#define CUR_HORZ_VERT_OFF                      0x0268  
+#define CUR_CLR0                               0x026C  
+#define CUR_CLR1                               0x0270  
+#define FP_HORZ_VERT_ACTIVE                    0x0278  
+#define CRTC_MORE_CNTL                         0x027C  
+#define DAC_EXT_CNTL                           0x0280  
+#define FP_GEN_CNTL                            0x0284  
+#define FP_HORZ_STRETCH                        0x028C  
+#define FP_VERT_STRETCH                        0x0290  
+#define FP_H_SYNC_STRT_WID                     0x02C4  
+#define FP_V_SYNC_STRT_WID                     0x02C8  
+#define AUX_WINDOW_HORZ_CNTL                   0x02D8  
+#define AUX_WINDOW_VERT_CNTL                   0x02DC  
+#define DDA_CONFIG			       0x02e0
+#define DDA_ON_OFF			       0x02e4
+#define GRPH_BUFFER_CNTL                       0x02F0
+#define VGA_BUFFER_CNTL                        0x02F4
+#define OV0_Y_X_START                          0x0400
+#define OV0_Y_X_END                            0x0404  
+#define OV0_PIPELINE_CNTL                      0x0408  
+#define OV0_REG_LOAD_CNTL                      0x0410  
+#define OV0_SCALE_CNTL                         0x0420  
+#define OV0_V_INC                              0x0424  
+#define OV0_P1_V_ACCUM_INIT                    0x0428  
+#define OV0_P23_V_ACCUM_INIT                   0x042C  
+#define OV0_P1_BLANK_LINES_AT_TOP              0x0430  
+#define OV0_P23_BLANK_LINES_AT_TOP             0x0434  
+#define OV0_BASE_ADDR                          0x043C  
+#define OV0_VID_BUF0_BASE_ADRS                 0x0440  
+#define OV0_VID_BUF1_BASE_ADRS                 0x0444  
+#define OV0_VID_BUF2_BASE_ADRS                 0x0448  
+#define OV0_VID_BUF3_BASE_ADRS                 0x044C  
+#define OV0_VID_BUF4_BASE_ADRS                 0x0450
+#define OV0_VID_BUF5_BASE_ADRS                 0x0454
+#define OV0_VID_BUF_PITCH0_VALUE               0x0460
+#define OV0_VID_BUF_PITCH1_VALUE               0x0464  
+#define OV0_AUTO_FLIP_CNTRL                    0x0470  
+#define OV0_DEINTERLACE_PATTERN                0x0474  
+#define OV0_SUBMIT_HISTORY                     0x0478  
+#define OV0_H_INC                              0x0480  
+#define OV0_STEP_BY                            0x0484  
+#define OV0_P1_H_ACCUM_INIT                    0x0488  
+#define OV0_P23_H_ACCUM_INIT                   0x048C  
+#define OV0_P1_X_START_END                     0x0494  
+#define OV0_P2_X_START_END                     0x0498  
+#define OV0_P3_X_START_END                     0x049C  
+#define OV0_FILTER_CNTL                        0x04A0  
+#define OV0_FOUR_TAP_COEF_0                    0x04B0  
+#define OV0_FOUR_TAP_COEF_1                    0x04B4  
+#define OV0_FOUR_TAP_COEF_2                    0x04B8
+#define OV0_FOUR_TAP_COEF_3                    0x04BC
+#define OV0_FOUR_TAP_COEF_4                    0x04C0
+#define OV0_FLAG_CNTRL                         0x04DC  
+#define OV0_SLICE_CNTL                         0x04E0  
+#define OV0_VID_KEY_CLR_LOW                    0x04E4  
+#define OV0_VID_KEY_CLR_HIGH                   0x04E8  
+#define OV0_GRPH_KEY_CLR_LOW                   0x04EC  
+#define OV0_GRPH_KEY_CLR_HIGH                  0x04F0  
+#define OV0_KEY_CNTL                           0x04F4  
+#define OV0_TEST                               0x04F8  
+#define SUBPIC_CNTL                            0x0540  
+#define SUBPIC_DEFCOLCON                       0x0544  
+#define SUBPIC_Y_X_START                       0x054C  
+#define SUBPIC_Y_X_END                         0x0550  
+#define SUBPIC_V_INC                           0x0554  
+#define SUBPIC_H_INC                           0x0558  
+#define SUBPIC_BUF0_OFFSET                     0x055C
+#define SUBPIC_BUF1_OFFSET                     0x0560
+#define SUBPIC_LC0_OFFSET                      0x0564
+#define SUBPIC_LC1_OFFSET                      0x0568  
+#define SUBPIC_PITCH                           0x056C  
+#define SUBPIC_BTN_HLI_COLCON                  0x0570  
+#define SUBPIC_BTN_HLI_Y_X_START               0x0574  
+#define SUBPIC_BTN_HLI_Y_X_END                 0x0578  
+#define SUBPIC_PALETTE_INDEX                   0x057C  
+#define SUBPIC_PALETTE_DATA                    0x0580  
+#define SUBPIC_H_ACCUM_INIT                    0x0584  
+#define SUBPIC_V_ACCUM_INIT                    0x0588  
+#define DISP_MISC_CNTL                         0x0D00  
+#define DAC_MACRO_CNTL                         0x0D04  
+#define DISP_PWR_MAN                           0x0D08  
+#define DISP_TEST_DEBUG_CNTL                   0x0D10  
+#define DISP_HW_DEBUG                          0x0D14  
+#define DAC_CRC_SIG1                           0x0D18
+#define DAC_CRC_SIG2                           0x0D1C
+#define OV0_LIN_TRANS_A                        0x0D20
+#define OV0_LIN_TRANS_B                        0x0D24  
+#define OV0_LIN_TRANS_C                        0x0D28  
+#define OV0_LIN_TRANS_D                        0x0D2C  
+#define OV0_LIN_TRANS_E                        0x0D30  
+#define OV0_LIN_TRANS_F                        0x0D34  
+#define OV0_GAMMA_0_F                          0x0D40  
+#define OV0_GAMMA_10_1F                        0x0D44  
+#define OV0_GAMMA_20_3F                        0x0D48  
+#define OV0_GAMMA_40_7F                        0x0D4C  
+#define OV0_GAMMA_380_3BF                      0x0D50  
+#define OV0_GAMMA_3C0_3FF                      0x0D54  
+#define DISP_MERGE_CNTL                        0x0D60  
+#define DISP_OUTPUT_CNTL                       0x0D64  
+#define DISP_LIN_TRANS_GRPH_A                  0x0D80  
+#define DISP_LIN_TRANS_GRPH_B                  0x0D84
+#define DISP_LIN_TRANS_GRPH_C                  0x0D88
+#define DISP_LIN_TRANS_GRPH_D                  0x0D8C
+#define DISP_LIN_TRANS_GRPH_E                  0x0D90  
+#define DISP_LIN_TRANS_GRPH_F                  0x0D94  
+#define DISP_LIN_TRANS_VID_A                   0x0D98  
+#define DISP_LIN_TRANS_VID_B                   0x0D9C  
+#define DISP_LIN_TRANS_VID_C                   0x0DA0  
+#define DISP_LIN_TRANS_VID_D                   0x0DA4  
+#define DISP_LIN_TRANS_VID_E                   0x0DA8  
+#define DISP_LIN_TRANS_VID_F                   0x0DAC  
+#define RMX_HORZ_FILTER_0TAP_COEF              0x0DB0  
+#define RMX_HORZ_FILTER_1TAP_COEF              0x0DB4  
+#define RMX_HORZ_FILTER_2TAP_COEF              0x0DB8  
+#define RMX_HORZ_PHASE                         0x0DBC  
+#define DAC_EMBEDDED_SYNC_CNTL                 0x0DC0  
+#define DAC_BROAD_PULSE                        0x0DC4  
+#define DAC_SKEW_CLKS                          0x0DC8
+#define DAC_INCR                               0x0DCC
+#define DAC_NEG_SYNC_LEVEL                     0x0DD0
+#define DAC_POS_SYNC_LEVEL                     0x0DD4  
+#define DAC_BLANK_LEVEL                        0x0DD8  
+#define CLOCK_CNTL_INDEX                       0x0008  
+#define CLOCK_CNTL_DATA                        0x000C  
+#define CP_RB_CNTL                             0x0704  
+#define CP_RB_BASE                             0x0700  
+#define CP_RB_RPTR_ADDR                        0x070C  
+#define CP_RB_RPTR                             0x0710  
+#define CP_RB_WPTR                             0x0714  
+#define CP_RB_WPTR_DELAY                       0x0718  
+#define CP_IB_BASE                             0x0738  
+#define CP_IB_BUFSZ                            0x073C  
+#define SCRATCH_REG0                           0x15E0  
+#define GUI_SCRATCH_REG0                       0x15E0  
+#define SCRATCH_REG1                           0x15E4  
+#define GUI_SCRATCH_REG1                       0x15E4  
+#define SCRATCH_REG2                           0x15E8
+#define GUI_SCRATCH_REG2                       0x15E8
+#define SCRATCH_REG3                           0x15EC
+#define GUI_SCRATCH_REG3                       0x15EC  
+#define SCRATCH_REG4                           0x15F0  
+#define GUI_SCRATCH_REG4                       0x15F0  
+#define SCRATCH_REG5                           0x15F4  
+#define GUI_SCRATCH_REG5                       0x15F4  
+#define SCRATCH_UMSK                           0x0770  
+#define SCRATCH_ADDR                           0x0774  
+#define DP_BRUSH_FRGD_CLR                      0x147C  
+#define DP_BRUSH_BKGD_CLR                      0x1478
+#define DST_LINE_START                         0x1600
+#define DST_LINE_END                           0x1604  
+#define SRC_OFFSET                             0x15AC  
+#define SRC_PITCH                              0x15B0
+#define SRC_TILE                               0x1704
+#define SRC_PITCH_OFFSET                       0x1428
+#define SRC_X                                  0x1414  
+#define SRC_Y                                  0x1418  
+#define SRC_X_Y                                0x1590  
+#define SRC_Y_X                                0x1434  
+#define DST_Y_X				       0x1438
+#define DST_WIDTH_HEIGHT		       0x1598
+#define DST_HEIGHT_WIDTH		       0x143c
+#define SRC_CLUT_ADDRESS                       0x1780  
+#define SRC_CLUT_DATA                          0x1784  
+#define SRC_CLUT_DATA_RD                       0x1788  
+#define HOST_DATA0                             0x17C0  
+#define HOST_DATA1                             0x17C4  
+#define HOST_DATA2                             0x17C8  
+#define HOST_DATA3                             0x17CC  
+#define HOST_DATA4                             0x17D0  
+#define HOST_DATA5                             0x17D4  
+#define HOST_DATA6                             0x17D8  
+#define HOST_DATA7                             0x17DC
+#define HOST_DATA_LAST                         0x17E0
+#define DP_SRC_ENDIAN                          0x15D4
+#define DP_SRC_FRGD_CLR                        0x15D8  
+#define DP_SRC_BKGD_CLR                        0x15DC  
+#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 DP_CNTL                                0x16C0  
+#define DP_CNTL_XDIR_YDIR_YMAJOR               0x16D0  
+#define DP_DATATYPE                            0x16C4  
+#define DP_MIX                                 0x16C8  
+#define DP_WRITE_MSK                           0x16CC  
+#define DP_XOP                                 0x17F8  
+#define CLR_CMP_CLR_SRC                        0x15C4
+#define CLR_CMP_CLR_DST                        0x15C8
+#define CLR_CMP_CNTL                           0x15C0
+#define CLR_CMP_MSK                            0x15CC  
+#define DSTCACHE_MODE                          0x1710  
+#define DSTCACHE_CTLSTAT                       0x1714  
+#define DEFAULT_PITCH_OFFSET                   0x16E0  
+#define DEFAULT_SC_BOTTOM_RIGHT                0x16E8  
+#define DP_GUI_MASTER_CNTL                     0x146C  
+#define SC_TOP_LEFT                            0x16EC  
+#define SC_BOTTOM_RIGHT                        0x16F0  
+#define SRC_SC_BOTTOM_RIGHT                    0x16F4  
+#define RB2D_DSTCACHE_CTLSTAT		       0x342C
+#define LVDS_GEN_CNTL			       0x02d0
+#define LVDS_PLL_CNTL			       0x02d4
+#define TMDS_CRC			       0x02a0
+
+#define RADEON_BASE_CODE		       0x0f0b
+#define RADEON_BIOS_0_SCRATCH		       0x0010
+#define RADEON_BIOS_1_SCRATCH		       0x0014
+#define RADEON_BIOS_2_SCRATCH		       0x0018
+#define RADEON_BIOS_3_SCRATCH		       0x001c
+#define RADEON_BIOS_4_SCRATCH		       0x0020
+#define RADEON_BIOS_5_SCRATCH		       0x0024
+#define RADEON_BIOS_6_SCRATCH		       0x0028
+#define RADEON_BIOS_7_SCRATCH		       0x002c
+
+
+#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 M_SPLL_REF_FB_DIV                          0x000a
+#define AGP_PLL_CNTL                               0x000b
+#define SPLL_CNTL                                  0x000c
+#define SCLK_CNTL                                  0x000d
+#define MPLL_CNTL                                  0x000e
+#define MCLK_CNTL                                  0x0012
+#define AGP_PLL_CNTL                               0x000b
+#define PLL_TEST_CNTL                              0x0013
+
+
+/* MCLK_CNTL bit constants */
+#define FORCEON_MCLKA				   (1 << 16)
+#define FORCEON_MCLKB         		   	   (1 << 17)
+#define FORCEON_YCLKA         	    	   	   (1 << 18)
+#define FORCEON_YCLKB         		   	   (1 << 19)
+#define FORCEON_MC            		   	   (1 << 20)
+#define FORCEON_AIC           		   	   (1 << 21)
+
+
+/* BUS_CNTL bit constants */
+#define BUS_DBL_RESYNC                             0x00000001
+#define BUS_MSTR_RESET                             0x00000002
+#define BUS_FLUSH_BUF                              0x00000004
+#define BUS_STOP_REQ_DIS                           0x00000008
+#define BUS_ROTATION_DIS                           0x00000010
+#define BUS_MASTER_DIS                             0x00000040
+#define BUS_ROM_WRT_EN                             0x00000080
+#define BUS_DIS_ROM                                0x00001000
+#define BUS_PCI_READ_RETRY_EN                      0x00002000
+#define BUS_AGP_AD_STEPPING_EN                     0x00004000
+#define BUS_PCI_WRT_RETRY_EN                       0x00008000
+#define BUS_MSTR_RD_MULT                           0x00100000
+#define BUS_MSTR_RD_LINE                           0x00200000
+#define BUS_SUSPEND                                0x00400000
+#define LAT_16X                                    0x00800000
+#define BUS_RD_DISCARD_EN                          0x01000000
+#define BUS_RD_ABORT_EN                            0x02000000
+#define BUS_MSTR_WS                                0x04000000
+#define BUS_PARKING_DIS                            0x08000000
+#define BUS_MSTR_DISCONNECT_EN                     0x10000000
+#define BUS_WRT_BURST                              0x20000000
+#define BUS_READ_BURST                             0x40000000
+#define BUS_RDY_READ_DLY                           0x80000000
+
+
+/* CLOCK_CNTL_INDEX bit constants */
+#define PLL_WR_EN                                  0x00000080
+
+/* CONFIG_CNTL bit constants */
+#define CFG_VGA_RAM_EN                             0x00000100
+
+/* CRTC_EXT_CNTL bit constants */
+#define VGA_ATI_LINEAR                             0x00000008
+#define VGA_128KAP_PAGING                          0x00000010
+#define	XCRT_CNT_EN				   (1 << 6)
+#define CRTC_HSYNC_DIS				   (1 << 8)
+#define CRTC_VSYNC_DIS				   (1 << 9)
+#define CRTC_DISPLAY_DIS			   (1 << 10)
+#define CRTC_CRT_ON				   (1 << 15)
+
+
+/* DSTCACHE_CTLSTAT bit constants */
+#define RB2D_DC_FLUSH				   (3 << 0)
+#define RB2D_DC_FLUSH_ALL			   0xf
+#define RB2D_DC_BUSY				   (1 << 31)
+
+
+/* CRTC_GEN_CNTL bit constants */
+#define CRTC_DBL_SCAN_EN                           0x00000001
+#define CRTC_CUR_EN                                0x00010000
+#define CRTC_INTERLACE_EN			   (1 << 1)
+#define CRTC_EXT_DISP_EN      			   (1 << 24)
+#define CRTC_EN					   (1 << 25)
+
+/* CRTC_STATUS bit constants */
+#define CRTC_VBLANK                                0x00000001
+
+/* CUR_OFFSET, CUR_HORZ_VERT_POSN, CUR_HORZ_VERT_OFF bit constants */
+#define CUR_LOCK                                   0x80000000
+
+
+/* FP bit constants */
+#define FP_CRTC_H_TOTAL_MASK			   0x000003ff
+#define FP_CRTC_H_DISP_MASK			   0x01ff0000
+#define FP_CRTC_V_TOTAL_MASK			   0x00000fff
+#define FP_CRTC_V_DISP_MASK			   0x0fff0000
+#define FP_H_SYNC_STRT_CHAR_MASK		   0x00001ff8
+#define FP_H_SYNC_WID_MASK			   0x003f0000
+#define FP_V_SYNC_STRT_MASK			   0x00000fff
+#define FP_V_SYNC_WID_MASK			   0x001f0000
+#define FP_CRTC_H_TOTAL_SHIFT			   0x00000000
+#define FP_CRTC_H_DISP_SHIFT			   0x00000010
+#define FP_CRTC_V_TOTAL_SHIFT			   0x00000000
+#define FP_CRTC_V_DISP_SHIFT			   0x00000010
+#define FP_H_SYNC_STRT_CHAR_SHIFT		   0x00000003
+#define FP_H_SYNC_WID_SHIFT			   0x00000010
+#define FP_V_SYNC_STRT_SHIFT			   0x00000000
+#define FP_V_SYNC_WID_SHIFT			   0x00000010
+
+/* FP_GEN_CNTL bit constants */
+#define FP_FPON					   (1 << 0)
+#define FP_TMDS_EN				   (1 << 2)
+#define FP_EN_TMDS				   (1 << 7)
+#define FP_DETECT_SENSE				   (1 << 8)
+#define FP_SEL_CRTC2				   (1 << 13)
+#define FP_CRTC_DONT_SHADOW_HPAR		   (1 << 15)
+#define FP_CRTC_DONT_SHADOW_VPAR		   (1 << 16)
+#define FP_CRTC_DONT_SHADOW_HEND		   (1 << 17)
+#define FP_CRTC_USE_SHADOW_VEND			   (1 << 18)
+#define FP_RMX_HVSYNC_CONTROL_EN		   (1 << 20)
+#define FP_DFP_SYNC_SEL				   (1 << 21)
+#define FP_CRTC_LOCK_8DOT			   (1 << 22)
+#define FP_CRT_SYNC_SEL				   (1 << 23)
+#define FP_USE_SHADOW_EN			   (1 << 24)
+#define FP_CRT_SYNC_ALT				   (1 << 26)
+
+/* LVDS_GEN_CNTL bit constants */
+#define LVDS_ON					   (1 << 0)
+#define LVDS_DISPLAY_DIS			   (1 << 1)
+#define LVDS_PANEL_TYPE				   (1 << 2)
+#define LVDS_PANEL_FORMAT			   (1 << 3)
+#define LVDS_EN					   (1 << 7)
+#define LVDS_DIGON				   (1 << 18)
+#define LVDS_BLON				   (1 << 19)
+#define LVDS_SEL_CRTC2				   (1 << 23)
+
+/* LVDS_PLL_CNTL bit constatns */
+#define HSYNC_DELAY_SHIFT			   0x1c
+#define HSYNC_DELAY_MASK			   (0xf << 0x1c)
+
+/* FP_HORZ_STRETCH bit constants */
+#define HORZ_STRETCH_RATIO_MASK			   0xffff
+#define HORZ_STRETCH_RATIO_MAX			   4096
+#define HORZ_PANEL_SIZE				   (0x1ff << 16)
+#define HORZ_PANEL_SHIFT			   16
+#define HORZ_STRETCH_PIXREP			   (0 << 25)
+#define HORZ_STRETCH_BLEND			   (1 << 26)
+#define HORZ_STRETCH_ENABLE			   (1 << 25)
+#define HORZ_AUTO_RATIO				   (1 << 27)
+#define HORZ_FP_LOOP_STRETCH			   (0x7 << 28)
+#define HORZ_AUTO_RATIO_INC			   (1 << 31)
+
+
+/* FP_VERT_STRETCH bit constants */
+#define VERT_STRETCH_RATIO_MASK			   0xfff
+#define VERT_STRETCH_RATIO_MAX			   4096
+#define VERT_PANEL_SIZE				   (0xfff << 12)
+#define VERT_PANEL_SHIFT			   12
+#define VERT_STRETCH_LINREP			   (0 << 26)
+#define VERT_STRETCH_BLEND			   (1 << 26)
+#define VERT_STRETCH_ENABLE			   (1 << 25)
+#define VERT_AUTO_RATIO_EN			   (1 << 27)
+#define VERT_FP_LOOP_STRETCH			   (0x7 << 28)
+#define VERT_STRETCH_RESERVED			   0xf1000000
+
+/* DAC_CNTL bit constants */   
+#define DAC_8BIT_EN                                0x00000100
+#define DAC_4BPP_PIX_ORDER                         0x00000200
+#define DAC_CRC_EN                                 0x00080000
+#define DAC_MASK_ALL				   (0xff << 24)
+#define DAC_VGA_ADR_EN				   (1 << 13)
+#define DAC_RANGE_CNTL				   (3 << 0)
+#define DAC_BLANKING				   (1 << 2)
+
+/* 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
+
+/* MEM_CNTL bit constants */
+#define MEM_CTLR_STATUS_IDLE                       0x00000000
+#define MEM_CTLR_STATUS_BUSY                       0x00100000
+#define MEM_SEQNCR_STATUS_IDLE                     0x00000000
+#define MEM_SEQNCR_STATUS_BUSY                     0x00200000
+#define MEM_ARBITER_STATUS_IDLE                    0x00000000
+#define MEM_ARBITER_STATUS_BUSY                    0x00400000
+#define MEM_REQ_UNLOCK                             0x00000000
+#define MEM_REQ_LOCK                               0x00800000
+
+
+/* RBBM_SOFT_RESET bit constants */
+#define SOFT_RESET_CP           		   (1 <<  0)
+#define SOFT_RESET_HI           		   (1 <<  1)
+#define SOFT_RESET_SE           		   (1 <<  2)
+#define SOFT_RESET_RE           		   (1 <<  3)
+#define SOFT_RESET_PP           		   (1 <<  4)
+#define SOFT_RESET_E2           		   (1 <<  5)
+#define SOFT_RESET_RB           		   (1 <<  6)
+#define SOFT_RESET_HDP          		   (1 <<  7)
+
+/* SURFACE_CNTL bit consants */
+#define SURF_TRANSLATION_DIS			   (1 << 8)
+#define NONSURF_AP0_SWP_16BPP			   (1 << 20)
+#define NONSURF_AP0_SWP_32BPP			   (1 << 21)
+
+/* DEFAULT_SC_BOTTOM_RIGHT bit constants */
+#define DEFAULT_SC_RIGHT_MAX			   (0x1fff << 0)
+#define DEFAULT_SC_BOTTOM_MAX			   (0x1fff << 16)
+
+/* MM_INDEX bit constants */
+#define MM_APER                                    0x80000000
+
+/* CLR_CMP_CNTL bit constants */
+#define COMPARE_SRC_FALSE                          0x00000000
+#define COMPARE_SRC_TRUE                           0x00000001
+#define COMPARE_SRC_NOT_EQUAL                      0x00000004
+#define COMPARE_SRC_EQUAL                          0x00000005
+#define COMPARE_SRC_EQUAL_FLIP                     0x00000007
+#define COMPARE_DST_FALSE                          0x00000000
+#define COMPARE_DST_TRUE                           0x00000100
+#define COMPARE_DST_NOT_EQUAL                      0x00000400
+#define COMPARE_DST_EQUAL                          0x00000500
+#define COMPARE_DESTINATION                        0x00000000
+#define COMPARE_SOURCE                             0x01000000
+#define COMPARE_SRC_AND_DST                        0x02000000
+
+
+/* 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_CNTL_YDIR_XDIR_YMAJOR bit constants (short version of DP_CNTL) */
+#define DST_X_MAJOR_S                              0x00000000
+#define DST_Y_MAJOR_S                              0x00000001
+#define DST_Y_BOTTOM_TO_TOP_S                      0x00000000
+#define DST_Y_TOP_TO_BOTTOM_S                      0x00008000
+#define DST_X_RIGHT_TO_LEFT_S                      0x00000000
+#define DST_X_LEFT_TO_RIGHT_S                      0x80000000
+
+
+/* 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 DST_8BPP_RGB332                            0x00000007
+#define DST_8BPP_Y8                                0x00000008
+#define DST_8BPP_RGB8                              0x00000009
+#define DST_16BPP_VYUY422                          0x0000000b
+#define DST_16BPP_YVYU422                          0x0000000c
+#define DST_32BPP_AYUV444                          0x0000000e
+#define DST_16BPP_ARGB4444                         0x0000000f
+#define BRUSH_SOLIDCOLOR                           0x00000d00
+#define SRC_MONO                                   0x00000000
+#define SRC_MONO_LBKGD                             0x00010000
+#define SRC_DSTCOLOR                               0x00030000
+#define BYTE_ORDER_MSB_TO_LSB                      0x00000000
+#define BYTE_ORDER_LSB_TO_MSB                      0x40000000
+#define DP_CONVERSION_TEMP                         0x80000000
+#define HOST_BIG_ENDIAN_EN			   (1 << 29)
+
+
+/* DP_GUI_MASTER_CNTL bit constants */
+#define GMC_SRC_PITCH_OFFSET_DEFAULT               0x00000000
+#define GMC_SRC_PITCH_OFFSET_LEAVE                 0x00000001
+#define GMC_DST_PITCH_OFFSET_DEFAULT               0x00000000
+#define GMC_DST_PITCH_OFFSET_LEAVE                 0x00000002
+#define GMC_SRC_CLIP_DEFAULT                       0x00000000
+#define GMC_SRC_CLIP_LEAVE                         0x00000004
+#define GMC_DST_CLIP_DEFAULT                       0x00000000
+#define GMC_DST_CLIP_LEAVE                         0x00000008
+#define GMC_BRUSH_8x8MONO                          0x00000000
+#define GMC_BRUSH_8x8MONO_LBKGD                    0x00000010
+#define GMC_BRUSH_8x1MONO                          0x00000020
+#define GMC_BRUSH_8x1MONO_LBKGD                    0x00000030
+#define GMC_BRUSH_1x8MONO                          0x00000040
+#define GMC_BRUSH_1x8MONO_LBKGD                    0x00000050
+#define GMC_BRUSH_32x1MONO                         0x00000060
+#define GMC_BRUSH_32x1MONO_LBKGD                   0x00000070
+#define GMC_BRUSH_32x32MONO                        0x00000080
+#define GMC_BRUSH_32x32MONO_LBKGD                  0x00000090
+#define GMC_BRUSH_8x8COLOR                         0x000000a0
+#define GMC_BRUSH_8x1COLOR                         0x000000b0
+#define GMC_BRUSH_1x8COLOR                         0x000000c0
+#define GMC_BRUSH_SOLID_COLOR                       0x000000d0
+#define GMC_DST_8BPP                               0x00000200
+#define GMC_DST_15BPP                              0x00000300
+#define GMC_DST_16BPP                              0x00000400
+#define GMC_DST_24BPP                              0x00000500
+#define GMC_DST_32BPP                              0x00000600
+#define GMC_DST_8BPP_RGB332                        0x00000700
+#define GMC_DST_8BPP_Y8                            0x00000800
+#define GMC_DST_8BPP_RGB8                          0x00000900
+#define GMC_DST_16BPP_VYUY422                      0x00000b00
+#define GMC_DST_16BPP_YVYU422                      0x00000c00
+#define GMC_DST_32BPP_AYUV444                      0x00000e00
+#define GMC_DST_16BPP_ARGB4444                     0x00000f00
+#define GMC_SRC_MONO                               0x00000000
+#define GMC_SRC_MONO_LBKGD                         0x00001000
+#define GMC_SRC_DSTCOLOR                           0x00003000
+#define GMC_BYTE_ORDER_MSB_TO_LSB                  0x00000000
+#define GMC_BYTE_ORDER_LSB_TO_MSB                  0x00004000
+#define GMC_DP_CONVERSION_TEMP_9300                0x00008000
+#define GMC_DP_CONVERSION_TEMP_6500                0x00000000
+#define GMC_DP_SRC_RECT                            0x02000000
+#define GMC_DP_SRC_HOST                            0x03000000
+#define GMC_DP_SRC_HOST_BYTEALIGN                  0x04000000
+#define GMC_3D_FCN_EN_CLR                          0x00000000
+#define GMC_3D_FCN_EN_SET                          0x08000000
+#define GMC_DST_CLR_CMP_FCN_LEAVE                  0x00000000
+#define GMC_DST_CLR_CMP_FCN_CLEAR                  0x10000000
+#define GMC_AUX_CLIP_LEAVE                         0x00000000
+#define GMC_AUX_CLIP_CLEAR                         0x20000000
+#define GMC_WRITE_MASK_LEAVE                       0x00000000
+#define GMC_WRITE_MASK_SET                         0x40000000
+#define GMC_CLR_CMP_CNTL_DIS      		   (1 << 28)
+#define GMC_SRC_DATATYPE_COLOR			   (3 << 12)
+#define ROP3_S                			   0x00cc0000
+#define ROP3_SRCCOPY				   0x00cc0000
+#define ROP3_P                			   0x00f00000
+#define ROP3_PATCOPY				   0x00f00000
+#define DP_SRC_SOURCE_MASK        		   (7    << 24)
+#define GMC_BRUSH_NONE            		   (15   <<  4)
+#define DP_SRC_SOURCE_MEMORY			   (2    << 24)
+#define GMC_BRUSH_SOLIDCOLOR			   0x000000d0
+
+/* DP_MIX bit constants */
+#define DP_SRC_RECT                                0x00000200
+#define DP_SRC_HOST                                0x00000300
+#define DP_SRC_HOST_BYTEALIGN                      0x00000400
+
+
+/* masks */
+
+#define CONFIG_MEMSIZE_MASK		0x1f000000
+#define MEM_CFG_TYPE			0x40000000
+#define DST_OFFSET_MASK			0x003fffff
+#define DST_PITCH_MASK			0x3fc00000
+#define DEFAULT_TILE_MASK		0xc0000000
+#define	PPLL_DIV_SEL_MASK		0x00000300
+#define	PPLL_RESET			0x00000001
+#define PPLL_ATOMIC_UPDATE_EN		0x00010000
+#define PPLL_REF_DIV_MASK		0x000003ff
+#define	PPLL_FB3_DIV_MASK		0x000007ff
+#define	PPLL_POST3_DIV_MASK		0x00070000
+#define PPLL_ATOMIC_UPDATE_R		0x00008000
+#define PPLL_ATOMIC_UPDATE_W		0x00008000
+#define	PPLL_VGA_ATOMIC_UPDATE_EN	0x00020000
+
+#define GUI_ACTIVE			0x80000000
+
+#endif	/* _RADEON_H */
+
diff -Nru a/include/video/vga.h b/include/video/vga.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/video/vga.h	Mon Dec  9 18:46:50 2002
@@ -0,0 +1,480 @@
+/*
+ * linux/include/video/vga.h -- standard VGA chipset interaction
+ *
+ * Copyright 1999 Jeff Garzik <jgarzik@pobox.com>
+ * 
+ * Copyright history from vga16fb.c:
+ *	Copyright 1999 Ben Pfaff and Petr Vandrovec
+ *	Based on VGA info at http://www.goodnet.com/~tinara/FreeVGA/home.htm
+ *	Based on VESA framebuffer (c) 1998 Gerd Knorr
+ *
+ * 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 __linux_video_vga_h__
+#define __linux_video_vga_h__
+
+#include <linux/config.h>
+#include <linux/types.h>
+#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>
+
+
+/* Some of the code below is taken from SVGAlib.  The original,
+   unmodified copyright notice for that code is below. */
+/* VGAlib version 1.2 - (c) 1993 Tommy Frandsen                    */
+/*                                                                 */
+/* This library is free software; you can redistribute it and/or   */
+/* modify it without any restrictions. This library is distributed */
+/* in the hope that it will be useful, but without any warranty.   */
+
+/* Multi-chipset support Copyright 1993 Harm Hanemaayer */
+/* partially copyrighted (C) 1993 by Hartmut Schirmer */
+
+/* VGA data register ports */
+#define VGA_CRT_DC  	0x3D5	/* CRT Controller Data Register - color emulation */
+#define VGA_CRT_DM  	0x3B5	/* CRT Controller Data Register - mono emulation */
+#define VGA_ATT_R   	0x3C1	/* Attribute Controller Data Read Register */
+#define VGA_ATT_W   	0x3C0	/* Attribute Controller Data Write Register */
+#define VGA_GFX_D   	0x3CF	/* Graphics Controller Data Register */
+#define VGA_SEQ_D   	0x3C5	/* Sequencer Data Register */
+#define VGA_MIS_R   	0x3CC	/* Misc Output Read Register */
+#define VGA_MIS_W   	0x3C2	/* Misc Output Write Register */
+#define VGA_FTC_R	0x3CA	/* Feature Control Read Register */
+#define VGA_IS1_RC  	0x3DA	/* Input Status Register 1 - color emulation */
+#define VGA_IS1_RM  	0x3BA	/* Input Status Register 1 - mono emulation */
+#define VGA_PEL_D   	0x3C9	/* PEL Data Register */
+#define VGA_PEL_MSK 	0x3C6	/* PEL mask register */
+
+/* EGA-specific registers */
+#define EGA_GFX_E0	0x3CC	/* Graphics enable processor 0 */
+#define EGA_GFX_E1	0x3CA	/* Graphics enable processor 1 */
+
+/* VGA index register ports */
+#define VGA_CRT_IC  	0x3D4	/* CRT Controller Index - color emulation */
+#define VGA_CRT_IM  	0x3B4	/* CRT Controller Index - mono emulation */
+#define VGA_ATT_IW  	0x3C0	/* Attribute Controller Index & Data Write Register */
+#define VGA_GFX_I   	0x3CE	/* Graphics Controller Index */
+#define VGA_SEQ_I   	0x3C4	/* Sequencer Index */
+#define VGA_PEL_IW  	0x3C8	/* PEL Write Index */
+#define VGA_PEL_IR  	0x3C7	/* PEL Read Index */
+
+/* standard VGA indexes max counts */
+#define VGA_CRT_C   	0x19	/* Number of CRT Controller Registers */
+#define VGA_ATT_C   	0x15	/* Number of Attribute Controller Registers */
+#define VGA_GFX_C   	0x09	/* Number of Graphics Controller Registers */
+#define VGA_SEQ_C   	0x05	/* Number of Sequencer Registers */
+#define VGA_MIS_C   	0x01	/* Number of Misc Output Register */
+
+/* VGA misc register bit masks */
+#define VGA_MIS_COLOR		0x01
+#define VGA_MIS_ENB_MEM_ACCESS	0x02
+#define VGA_MIS_DCLK_28322_720	0x04
+#define VGA_MIS_ENB_PLL_LOAD	(0x04 | 0x08)
+#define VGA_MIS_SEL_HIGH_PAGE	0x20
+
+/* VGA CRT controller register indices */
+#define VGA_CRTC_H_TOTAL	0
+#define VGA_CRTC_H_DISP		1
+#define VGA_CRTC_H_BLANK_START	2
+#define VGA_CRTC_H_BLANK_END	3
+#define VGA_CRTC_H_SYNC_START	4
+#define VGA_CRTC_H_SYNC_END	5
+#define VGA_CRTC_V_TOTAL	6
+#define VGA_CRTC_OVERFLOW	7
+#define VGA_CRTC_PRESET_ROW	8
+#define VGA_CRTC_MAX_SCAN	9
+#define VGA_CRTC_CURSOR_START	0x0A
+#define VGA_CRTC_CURSOR_END	0x0B
+#define VGA_CRTC_START_HI	0x0C
+#define VGA_CRTC_START_LO	0x0D
+#define VGA_CRTC_CURSOR_HI	0x0E
+#define VGA_CRTC_CURSOR_LO	0x0F
+#define VGA_CRTC_V_SYNC_START	0x10
+#define VGA_CRTC_V_SYNC_END	0x11
+#define VGA_CRTC_V_DISP_END	0x12
+#define VGA_CRTC_OFFSET		0x13
+#define VGA_CRTC_UNDERLINE	0x14
+#define VGA_CRTC_V_BLANK_START	0x15
+#define VGA_CRTC_V_BLANK_END	0x16
+#define VGA_CRTC_MODE		0x17
+#define VGA_CRTC_LINE_COMPARE	0x18
+#define VGA_CRTC_REGS		VGA_CRT_C
+
+/* VGA CRT controller bit masks */
+#define VGA_CR11_LOCK_CR0_CR7	0x80 /* lock writes to CR0 - CR7 */
+#define VGA_CR17_H_V_SIGNALS_ENABLED 0x80
+
+/* VGA attribute controller register indices */
+#define VGA_ATC_PALETTE0	0x00
+#define VGA_ATC_PALETTE1	0x01
+#define VGA_ATC_PALETTE2	0x02
+#define VGA_ATC_PALETTE3	0x03
+#define VGA_ATC_PALETTE4	0x04
+#define VGA_ATC_PALETTE5	0x05
+#define VGA_ATC_PALETTE6	0x06
+#define VGA_ATC_PALETTE7	0x07
+#define VGA_ATC_PALETTE8	0x08
+#define VGA_ATC_PALETTE9	0x09
+#define VGA_ATC_PALETTEA	0x0A
+#define VGA_ATC_PALETTEB	0x0B
+#define VGA_ATC_PALETTEC	0x0C
+#define VGA_ATC_PALETTED	0x0D
+#define VGA_ATC_PALETTEE	0x0E
+#define VGA_ATC_PALETTEF	0x0F
+#define VGA_ATC_MODE		0x10
+#define VGA_ATC_OVERSCAN	0x11
+#define VGA_ATC_PLANE_ENABLE	0x12
+#define VGA_ATC_PEL		0x13
+#define VGA_ATC_COLOR_PAGE	0x14
+
+#define VGA_AR_ENABLE_DISPLAY	0x20
+
+/* VGA sequencer register indices */
+#define VGA_SEQ_RESET		0x00
+#define VGA_SEQ_CLOCK_MODE	0x01
+#define VGA_SEQ_PLANE_WRITE	0x02
+#define VGA_SEQ_CHARACTER_MAP	0x03
+#define VGA_SEQ_MEMORY_MODE	0x04
+
+/* VGA sequencer register bit masks */
+#define VGA_SR01_CHAR_CLK_8DOTS	0x01 /* bit 0: character clocks 8 dots wide are generated */
+#define VGA_SR01_SCREEN_OFF	0x20 /* bit 5: Screen is off */
+#define VGA_SR02_ALL_PLANES	0x0F /* bits 3-0: enable access to all planes */
+#define VGA_SR04_EXT_MEM	0x02 /* bit 1: allows complete mem access to 256K */
+#define VGA_SR04_SEQ_MODE	0x04 /* bit 2: directs system to use a sequential addressing mode */
+#define VGA_SR04_CHN_4M		0x08 /* bit 3: selects modulo 4 addressing for CPU access to display memory */
+
+/* VGA graphics controller register indices */
+#define VGA_GFX_SR_VALUE	0x00
+#define VGA_GFX_SR_ENABLE	0x01
+#define VGA_GFX_COMPARE_VALUE	0x02
+#define VGA_GFX_DATA_ROTATE	0x03
+#define VGA_GFX_PLANE_READ	0x04
+#define VGA_GFX_MODE		0x05
+#define VGA_GFX_MISC		0x06
+#define VGA_GFX_COMPARE_MASK	0x07
+#define VGA_GFX_BIT_MASK	0x08
+
+/* VGA graphics controller bit masks */
+#define VGA_GR06_GRAPHICS_MODE	0x01
+
+/* macro for composing an 8-bit VGA register index and value
+ * into a single 16-bit quantity */
+#define VGA_OUT16VAL(v, r)       (((v) << 8) | (r))
+
+/* decide whether we should enable the faster 16-bit VGA register writes */
+#ifdef __LITTLE_ENDIAN
+#define VGA_OUTW_WRITE
+#endif
+
+/* VGA State Save and Restore */
+#define VGA_SAVE_FONT0 1  /* save/restore plane 2 fonts	  */
+#define VGA_SAVE_FONT1 2  /* save/restore plane 3 fonts   */
+#define VGA_SAVE_TEXT  4  /* save/restore plane 0/1 fonts */
+#define VGA_SAVE_FONTS 7  /* save/restore all fonts	  */
+#define VGA_SAVE_MODE  8  /* save/restore video mode 	  */
+#define VGA_SAVE_CMAP  16 /* save/restore color map/DAC   */
+
+struct vgastate {
+	caddr_t vgabase;	/* mmio base, if supported 		   */
+	__u32 flags;		/* what state[s] to save (see VGA_SAVE_*)  */
+	__u32 membase;		/* VGA window base, 0 for default - 0xA000 */
+	__u32 memsize;		/* VGA window size, 0 for default 64K	   */
+	__u32 depth;		/* current fb depth, not important	   */
+	__u32 num_attr;		/* number of att registers, 0 for default  */
+	__u32 num_crtc;		/* number of crt registers, 0 for default  */
+	__u32 num_gfx;		/* number of gfx registers, 0 for default  */
+	__u32 num_seq;		/* number of seq registers, 0 for default  */
+	void *vidstate;
+};	
+
+extern int save_vga(struct vgastate *state);
+extern int restore_vga(struct vgastate *state);
+
+/*
+ * generic VGA port read/write
+ */
+ 
+static inline unsigned char vga_io_r (unsigned short port)
+{
+	return inb (port);
+}
+
+static inline void vga_io_w (unsigned short port, unsigned char val)
+{
+	outb (val, port);
+}
+
+static inline void vga_io_w_fast (unsigned short port, unsigned char reg,
+				  unsigned char val)
+{
+	outw (VGA_OUT16VAL (val, reg), port);
+}
+
+static inline unsigned char vga_mm_r (caddr_t regbase, unsigned short port)
+{
+	return readb (regbase + port);
+}
+
+static inline void vga_mm_w (caddr_t regbase, unsigned short port, unsigned char val)
+{
+	writeb (val, regbase + port);
+}
+
+static inline void vga_mm_w_fast (caddr_t regbase, unsigned short port,
+				  unsigned char reg, unsigned char val)
+{
+	writew (VGA_OUT16VAL (val, reg), regbase + port);
+}
+
+static inline unsigned char vga_r (caddr_t regbase, unsigned short port)
+{
+	if (regbase)
+		return vga_mm_r (regbase, port);
+	else
+		return vga_io_r (port);
+}
+
+static inline void vga_w (caddr_t regbase, unsigned short port, unsigned char val)
+{
+	if (regbase)
+		vga_mm_w (regbase, port, val);
+	else
+		vga_io_w (port, val);
+}
+
+
+static inline void vga_w_fast (caddr_t regbase, unsigned short port,
+			       unsigned char reg, unsigned char val)
+{
+	if (regbase)
+		vga_mm_w_fast (regbase, port, reg, val);
+	else
+		vga_io_w_fast (port, reg, val);
+}
+
+
+/*
+ * VGA CRTC register read/write
+ */
+ 
+static inline unsigned char vga_rcrt (caddr_t regbase, unsigned char reg)
+{
+        vga_w (regbase, VGA_CRT_IC, reg);
+        return vga_r (regbase, VGA_CRT_DC);
+}
+
+static inline void vga_wcrt (caddr_t regbase, unsigned char reg, unsigned char val)
+{
+#ifdef VGA_OUTW_WRITE
+	vga_w_fast (regbase, VGA_CRT_IC, reg, val);
+#else
+        vga_w (regbase, VGA_CRT_IC, reg);
+        vga_w (regbase, VGA_CRT_DC, val);
+#endif /* VGA_OUTW_WRITE */
+}
+
+static inline unsigned char vga_io_rcrt (unsigned char reg)
+{
+        vga_io_w (VGA_CRT_IC, reg);
+        return vga_io_r (VGA_CRT_DC);
+}
+
+static inline void vga_io_wcrt (unsigned char reg, unsigned char val)
+{
+#ifdef VGA_OUTW_WRITE
+	vga_io_w_fast (VGA_CRT_IC, reg, val);
+#else
+        vga_io_w (VGA_CRT_IC, reg);
+        vga_io_w (VGA_CRT_DC, val);
+#endif /* VGA_OUTW_WRITE */
+}
+
+static inline unsigned char vga_mm_rcrt (caddr_t regbase, unsigned char reg)
+{
+        vga_mm_w (regbase, VGA_CRT_IC, reg);
+        return vga_mm_r (regbase, VGA_CRT_DC);
+}
+
+static inline void vga_mm_wcrt (caddr_t regbase, unsigned char reg, unsigned char val)
+{
+#ifdef VGA_OUTW_WRITE
+	vga_mm_w_fast (regbase, VGA_CRT_IC, reg, val);
+#else
+        vga_mm_w (regbase, VGA_CRT_IC, reg);
+        vga_mm_w (regbase, VGA_CRT_DC, val);
+#endif /* VGA_OUTW_WRITE */
+}
+
+
+/*
+ * VGA sequencer register read/write
+ */
+ 
+static inline unsigned char vga_rseq (caddr_t regbase, unsigned char reg)
+{
+        vga_w (regbase, VGA_SEQ_I, reg);
+        return vga_r (regbase, VGA_SEQ_D);
+}
+
+static inline void vga_wseq (caddr_t regbase, unsigned char reg, unsigned char val)
+{
+#ifdef VGA_OUTW_WRITE
+	vga_w_fast (regbase, VGA_SEQ_I, reg, val);
+#else
+        vga_w (regbase, VGA_SEQ_I, reg);
+        vga_w (regbase, VGA_SEQ_D, val);
+#endif /* VGA_OUTW_WRITE */
+}
+
+static inline unsigned char vga_io_rseq (unsigned char reg)
+{
+        vga_io_w (VGA_SEQ_I, reg);
+        return vga_io_r (VGA_SEQ_D);
+}
+
+static inline void vga_io_wseq (unsigned char reg, unsigned char val)
+{
+#ifdef VGA_OUTW_WRITE
+	vga_io_w_fast (VGA_SEQ_I, reg, val);
+#else
+        vga_io_w (VGA_SEQ_I, reg);
+        vga_io_w (VGA_SEQ_D, val);
+#endif /* VGA_OUTW_WRITE */
+}
+
+static inline unsigned char vga_mm_rseq (caddr_t regbase, unsigned char reg)
+{
+        vga_mm_w (regbase, VGA_SEQ_I, reg);
+        return vga_mm_r (regbase, VGA_SEQ_D);
+}
+
+static inline void vga_mm_wseq (caddr_t regbase, unsigned char reg, unsigned char val)
+{
+#ifdef VGA_OUTW_WRITE
+	vga_mm_w_fast (regbase, VGA_SEQ_I, reg, val);
+#else
+        vga_mm_w (regbase, VGA_SEQ_I, reg);
+        vga_mm_w (regbase, VGA_SEQ_D, val);
+#endif /* VGA_OUTW_WRITE */
+}
+
+
+
+/*
+ * VGA graphics controller register read/write
+ */
+ 
+static inline unsigned char vga_rgfx (caddr_t regbase, unsigned char reg)
+{
+        vga_w (regbase, VGA_GFX_I, reg);
+        return vga_r (regbase, VGA_GFX_D);
+}
+
+static inline void vga_wgfx (caddr_t regbase, unsigned char reg, unsigned char val)
+{
+#ifdef VGA_OUTW_WRITE
+	vga_w_fast (regbase, VGA_GFX_I, reg, val);
+#else
+        vga_w (regbase, VGA_GFX_I, reg);
+        vga_w (regbase, VGA_GFX_D, val);
+#endif /* VGA_OUTW_WRITE */
+}
+
+static inline unsigned char vga_io_rgfx (unsigned char reg)
+{
+        vga_io_w (VGA_GFX_I, reg);
+        return vga_io_r (VGA_GFX_D);
+}
+
+static inline void vga_io_wgfx (unsigned char reg, unsigned char val)
+{
+#ifdef VGA_OUTW_WRITE
+	vga_io_w_fast (VGA_GFX_I, reg, val);
+#else
+        vga_io_w (VGA_GFX_I, reg);
+        vga_io_w (VGA_GFX_D, val);
+#endif /* VGA_OUTW_WRITE */
+}
+
+static inline unsigned char vga_mm_rgfx (caddr_t regbase, unsigned char reg)
+{
+        vga_mm_w (regbase, VGA_GFX_I, reg);
+        return vga_mm_r (regbase, VGA_GFX_D);
+}
+
+static inline void vga_mm_wgfx (caddr_t regbase, unsigned char reg, unsigned char val)
+{
+#ifdef VGA_OUTW_WRITE
+	vga_mm_w_fast (regbase, VGA_GFX_I, reg, val);
+#else
+        vga_mm_w (regbase, VGA_GFX_I, reg);
+        vga_mm_w (regbase, VGA_GFX_D, val);
+#endif /* VGA_OUTW_WRITE */
+}
+
+
+/*
+ * VGA attribute controller register read/write
+ */
+ 
+static inline unsigned char vga_rattr (caddr_t regbase, unsigned char reg)
+{
+        vga_w (regbase, VGA_ATT_IW, reg);
+        return vga_r (regbase, VGA_ATT_R);
+}
+
+static inline void vga_wattr (caddr_t regbase, unsigned char reg, unsigned char val)
+{
+        vga_w (regbase, VGA_ATT_IW, reg);
+        vga_w (regbase, VGA_ATT_W, val);
+}
+
+static inline unsigned char vga_io_rattr (unsigned char reg)
+{
+        vga_io_w (VGA_ATT_IW, reg);
+        return vga_io_r (VGA_ATT_R);
+}
+
+static inline void vga_io_wattr (unsigned char reg, unsigned char val)
+{
+        vga_io_w (VGA_ATT_IW, reg);
+        vga_io_w (VGA_ATT_W, val);
+}
+
+static inline unsigned char vga_mm_rattr (caddr_t regbase, unsigned char reg)
+{
+        vga_mm_w (regbase, VGA_ATT_IW, reg);
+        return vga_mm_r (regbase, VGA_ATT_R);
+}
+
+static inline void vga_mm_wattr (caddr_t regbase, unsigned char reg, unsigned char val)
+{
+        vga_mm_w (regbase, VGA_ATT_IW, reg);
+        vga_mm_w (regbase, VGA_ATT_W, val);
+}
+
+
+
+
+#endif /* __linux_video_vga_h__ */
diff -Nru a/init/do_mounts.c b/init/do_mounts.c
--- a/init/do_mounts.c	Mon Dec  9 18:46:36 2002
+++ b/init/do_mounts.c	Mon Dec  9 18:46:36 2002
@@ -597,7 +597,7 @@
 #ifdef CONFIG_BLK_DEV_RAM
 	int in_fd, out_fd;
 	unsigned long rd_blocks, devblocks;
-	int nblocks, i;
+	int nblocks, i, disk;
 	char *buf;
 	unsigned short rotate = 0;
 #if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
@@ -640,7 +640,7 @@
 		rd_blocks >>= 1;
 
 	if (nblocks > rd_blocks) {
-		printk("RAMDISK: image too big! (%d/%d blocks)\n",
+		printk("RAMDISK: image too big! (%d/%ld blocks)\n",
 		       nblocks, rd_blocks);
 		goto done;
 	}
@@ -667,23 +667,23 @@
 		goto done;
 	}
 
-	printk(KERN_NOTICE "RAMDISK: Loading %d blocks [%d disk%s] into ram disk... ", 
+	printk(KERN_NOTICE "RAMDISK: Loading %d blocks [%ld disk%s] into ram disk... ", 
 		nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : "");
-	for (i=0; i < nblocks; i++) {
+	for (i = 0, disk = 1; i < nblocks; i++) {
 		if (i && (i % devblocks == 0)) {
-			printk("done disk #%d.\n", i/devblocks);
+			printk("done disk #%d.\n", disk++);
 			rotate = 0;
 			if (close(in_fd)) {
 				printk("Error closing the disk.\n");
 				goto noclose_input;
 			}
-			change_floppy("disk #%d", i/devblocks+1);
+			change_floppy("disk #%d", disk);
 			in_fd = open(from, O_RDONLY, 0);
 			if (in_fd < 0)  {
 				printk("Error opening disk.\n");
 				goto noclose_input;
 			}
-			printk("Loading disk #%d... ", i/devblocks+1);
+			printk("Loading disk #%d... ", disk);
 		}
 		read(in_fd, buf, BLOCK_SIZE);
 		write(out_fd, buf, BLOCK_SIZE);
@@ -920,6 +920,7 @@
 static unsigned inptr;   /* index of next byte to be processed in inbuf */
 static unsigned outcnt;  /* bytes in output buffer */
 static int exit_code;
+static int unzip_error;
 static long bytes_out;
 static int crd_infd, crd_outfd;
 
@@ -967,13 +968,17 @@
 /* ===========================================================================
  * Fill the input buffer. This is called only when the buffer is empty
  * and at least one byte is really needed.
+ * Returning -1 does not guarantee that gunzip() will ever return.
  */
 static int __init fill_inbuf(void)
 {
 	if (exit_code) return -1;
 	
 	insize = read(crd_infd, inbuf, INBUFSIZ);
-	if (insize == 0) return -1;
+	if (insize == 0) {
+		error("RAMDISK: ran out of compressed data\n");
+		return -1;
+	}
 
 	inptr = 1;
 
@@ -987,10 +992,15 @@
 static void __init flush_window(void)
 {
     ulg c = crc;         /* temporary variable */
-    unsigned n;
+    unsigned n, written;
     uch *in, ch;
     
-    write(crd_outfd, window, outcnt);
+    written = write(crd_outfd, window, outcnt);
+    if (written != outcnt && unzip_error == 0) {
+	printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n",
+	       written, outcnt, bytes_out);
+	unzip_error = 1;
+    }
     in = window;
     for (n = 0; n < outcnt; n++) {
 	    ch = *in++;
@@ -1005,6 +1015,7 @@
 {
 	printk(KERN_ERR "%s", x);
 	exit_code = 1;
+	unzip_error = 1;
 }
 
 static int __init crd_load(int in_fd, int out_fd)
@@ -1033,6 +1044,8 @@
 	}
 	makecrc();
 	result = gunzip();
+	if (unzip_error)
+		result = 1;
 	kfree(inbuf);
 	kfree(window);
 	return result;
diff -Nru a/init/main.c b/init/main.c
--- a/init/main.c	Mon Dec  9 18:46:35 2002
+++ b/init/main.c	Mon Dec  9 18:46:35 2002
@@ -37,10 +37,6 @@
 #include <asm/io.h>
 #include <asm/bugs.h>
 
-#if defined(CONFIG_ARCH_S390)
-#include <asm/s390mach.h>
-#endif
-
 #ifdef CONFIG_X86_LOCAL_APIC
 #include <asm/smp.h>
 #endif
diff -Nru a/ipc/msg.c b/ipc/msg.c
--- a/ipc/msg.c	Mon Dec  9 18:46:34 2002
+++ b/ipc/msg.c	Mon Dec  9 18:46:34 2002
@@ -23,6 +23,8 @@
 #include <linux/proc_fs.h>
 #include <linux/list.h>
 #include <linux/security.h>
+#include <linux/sched.h>
+#include <asm/current.h>
 #include <asm/uaccess.h>
 #include "util.h"
 
@@ -101,7 +103,8 @@
 	msq->q_perm.key = key;
 
 	msq->q_perm.security = NULL;
-	if ((retval = security_msg_queue_alloc(msq))) {
+	retval = security_msg_queue_alloc(msq);
+	if (retval) {
 		ipc_rcu_free(msq, sizeof(*msq));
 		return retval;
 	}
diff -Nru a/ipc/sem.c b/ipc/sem.c
--- a/ipc/sem.c	Mon Dec  9 18:46:36 2002
+++ b/ipc/sem.c	Mon Dec  9 18:46:36 2002
@@ -136,7 +136,8 @@
 	sma->sem_perm.key = key;
 
 	sma->sem_perm.security = NULL;
-	if ((retval = security_sem_alloc(sma))) {
+	retval = security_sem_alloc(sma);
+	if (retval) {
 		ipc_rcu_free(sma, size);
 		return retval;
 	}
diff -Nru a/ipc/shm.c b/ipc/shm.c
--- a/ipc/shm.c	Mon Dec  9 18:46:37 2002
+++ b/ipc/shm.c	Mon Dec  9 18:46:37 2002
@@ -188,7 +188,8 @@
 	shp->shm_flags = (shmflg & S_IRWXUGO);
 
 	shp->shm_perm.security = NULL;
-	if ((error = security_shm_alloc(shp))) {
+	error = security_shm_alloc(shp);
+	if (error) {
 		ipc_rcu_free(shp, sizeof(*shp));
 		return error;
 	}
diff -Nru a/ipc/util.c b/ipc/util.c
--- a/ipc/util.c	Mon Dec  9 18:46:36 2002
+++ b/ipc/util.c	Mon Dec  9 18:46:36 2002
@@ -98,6 +98,10 @@
 	struct kern_ipc_perm* p;
 	int max_id = ids->max_id;
 
+	/*
+	 * read_barrier_depends is not needed here
+	 * since ipc_ids.sem is held
+	 */
 	for (id = 0; id <= max_id; id++) {
 		p = ids->entries[id].p;
 		if(p==NULL)
@@ -134,12 +138,12 @@
 
 	/*
 	 * before setting the ids->entries to the new array, there must be a
-	 * wmb() to make sure that the memcpyed contents of the new array are
+	 * smp_wmb() to make sure the memcpyed contents of the new array are
 	 * visible before the new array becomes visible.
 	 */
-	wmb();
+	smp_wmb();	/* prevent seeing new array uninitialized. */
 	ids->entries = new;
-	wmb();
+	smp_wmb();	/* prevent indexing into old array based on new size. */
 	ids->size = newsize;
 
 	ipc_rcu_free(old, sizeof(struct ipc_id)*i);
@@ -156,6 +160,8 @@
  *	initialised and the first free entry is set up and the id assigned
  *	is returned. The list is returned in a locked state on success.
  *	On failure the list is not locked and -1 is returned.
+ *
+ *	Called with ipc_ids.sem held.
  */
  
 int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
@@ -163,6 +169,11 @@
 	int id;
 
 	size = grow_ary(ids,size);
+
+	/*
+	 * read_barrier_depends() is not needed here since
+	 * ipc_ids.sem is held
+	 */
 	for (id = 0; id < size; id++) {
 		if(ids->entries[id].p == NULL)
 			goto found;
@@ -207,7 +218,11 @@
 	int lid = id % SEQ_MULTIPLIER;
 	if(lid >= ids->size)
 		BUG();
-	
+
+	/* 
+	 * do not need a read_barrier_depends() here to force ordering
+	 * on Alpha, since the ipc_ids.sem is held.
+	 */	
 	p = ids->entries[lid].p;
 	ids->entries[lid].p = NULL;
 	if(p==NULL)
@@ -414,15 +429,15 @@
 }
 
 /*
- * ipc_get() requires ipc_ids.sem down, otherwise we need a rmb() here
- * to sync with grow_ary();
- *
- * So far only shm_get_stat() uses ipc_get() via shm_get().  So ipc_get()
- * is called with shm_ids.sem locked.  Thus a rmb() is not needed here,
- * as grow_ary() also requires shm_ids.sem down(for shm).
+ * So far only shm_get_stat() calls ipc_get() via shm_get(), so ipc_get()
+ * is called with shm_ids.sem locked.  Since grow_ary() is also called with
+ * shm_ids.sem down(for Shared Memory), there is no need to add read 
+ * barriers here to gurantee the writes in grow_ary() are seen in order 
+ * here (for Alpha).
  *
- * But if ipc_get() is used in the future without ipc_ids.sem down,
- * we need to add a rmb() before accessing the entries array
+ * However ipc_get() itself does not necessary require ipc_ids.sem down. So
+ * if in the future ipc_get() is used by other places without ipc_ids.sem
+ * down, then ipc_get() needs read memery barriers as ipc_lock() does.
  */
 struct kern_ipc_perm* ipc_get(struct ipc_ids* ids, int id)
 {
@@ -430,7 +445,6 @@
 	int lid = id % SEQ_MULTIPLIER;
 	if(lid >= ids->size)
 		return NULL;
-	rmb();
 	out = ids->entries[lid].p;
 	return out;
 }
@@ -439,6 +453,7 @@
 {
 	struct kern_ipc_perm* out;
 	int lid = id % SEQ_MULTIPLIER;
+	struct ipc_id* entries;
 
 	rcu_read_lock();
 	if(lid >= ids->size) {
@@ -446,9 +461,18 @@
 		return NULL;
 	}
 
-	/* we need a barrier here to sync with grow_ary() */
-	rmb();
-	out = ids->entries[lid].p;
+	/* 
+	 * Note: The following two read barriers are corresponding
+	 * to the two write barriers in grow_ary(). They guarantee 
+	 * the writes are seen in the same order on the read side. 
+	 * smp_rmb() has effect on all CPUs.  read_barrier_depends() 
+	 * is used if there are data dependency between two reads, and 
+	 * has effect only on Alpha.
+	 */
+	smp_rmb(); /* prevent indexing old array with new size */
+	entries = ids->entries;
+	read_barrier_depends(); /*prevent seeing new array unitialized */
+	out = entries[lid].p;
 	if(out == NULL) {
 		rcu_read_unlock();
 		return NULL;
diff -Nru a/kernel/Makefile b/kernel/Makefile
--- a/kernel/Makefile	Mon Dec  9 18:46:35 2002
+++ b/kernel/Makefile	Mon Dec  9 18:46:35 2002
@@ -21,6 +21,7 @@
 obj-$(CONFIG_CPU_FREQ) += cpufreq.o
 obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
 obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o
+obj-$(CONFIG_COMPAT) += compat.o
 
 ifneq ($(CONFIG_IA64),y)
 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff -Nru a/kernel/acct.c b/kernel/acct.c
--- a/kernel/acct.c	Mon Dec  9 18:46:38 2002
+++ b/kernel/acct.c	Mon Dec  9 18:46:38 2002
@@ -223,7 +223,8 @@
 		}
 	}
 
-	if ((error = security_acct(file)))
+	error = security_acct(file);
+	if (error)
 		return error;
 
 	spin_lock(&acct_globals.lock);
diff -Nru a/kernel/compat.c b/kernel/compat.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/kernel/compat.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,163 @@
+/*
+ *  linux/kernel/compat.c
+ *
+ *  Kernel compatibililty routines for e.g. 32 bit syscall support
+ *  on 64 bit kernels.
+ *
+ *  Copyright (C) 2002 Stephen Rothwell, IBM Corporation
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+#include <linux/compat.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+
+#include <asm/uaccess.h>
+
+static long compat_nanosleep_restart(struct restart_block *restart)
+{
+	unsigned long expire = restart->arg0, now = jiffies;
+	struct timespec *rmtp = (struct timespec *) restart->arg1;
+	long ret;
+
+	/* Did it expire while we handled signals? */
+	if (!time_after(expire, now))
+		return 0;
+
+	current->state = TASK_INTERRUPTIBLE;
+	expire = schedule_timeout(expire - now);
+
+	ret = 0;
+	if (expire) {
+		struct compat_timespec ct;
+		struct timespec t;
+
+		jiffies_to_timespec(expire, &t);
+		ct.tv_sec = t.tv_sec;
+		ct.tv_nsec = t.tv_nsec;
+
+		ret = -ERESTART_RESTARTBLOCK;
+		if (copy_to_user(rmtp, &ct, sizeof(ct)))
+			ret = -EFAULT;
+		/* The 'restart' block is already filled in */
+	}
+	return ret;
+}
+
+asmlinkage long compat_sys_nanosleep(struct compat_timespec *rqtp,
+		struct compat_timespec *rmtp)
+{
+	struct compat_timespec ct;
+	struct timespec t;
+	unsigned long expire;
+	s32 ret;
+
+	if (copy_from_user(&ct, rqtp, sizeof(ct)))
+		return -EFAULT;
+	t.tv_sec = ct.tv_sec;
+	t.tv_nsec = ct.tv_nsec;
+
+	if ((t.tv_nsec >= 1000000000L) || (t.tv_nsec < 0) || (t.tv_sec < 0))
+		return -EINVAL;
+
+	expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
+	current->state = TASK_INTERRUPTIBLE;
+	expire = schedule_timeout(expire);
+
+	ret = 0;
+	if (expire) {
+		struct restart_block *restart;
+
+		jiffies_to_timespec(expire, &t);
+		ct.tv_sec = t.tv_sec;
+		ct.tv_nsec = t.tv_nsec;
+
+		if (copy_to_user(rmtp, &ct, sizeof(ct)))
+			return -EFAULT;
+
+		restart = &current_thread_info()->restart_block;
+		restart->fn = compat_nanosleep_restart;
+		restart->arg0 = jiffies + expire;
+		restart->arg1 = (unsigned long) rmtp;
+		ret = -ERESTART_RESTARTBLOCK;
+	}
+	return ret;
+}
+
+/*
+ * Not all architectures have sys_utime, so implement this in terms
+ * of sys_utimes.
+ */
+asmlinkage long compat_sys_utime(char *filename, struct compat_utimbuf *t)
+{
+	struct timeval tv[2];
+
+	if (t) {
+		if (get_user(tv[0].tv_sec, &t->actime) ||
+		    get_user(tv[1].tv_sec, &t->modtime))
+			return -EFAULT;
+		tv[0].tv_usec = 0;
+		tv[1].tv_usec = 0;
+	}
+	return do_utimes(filename, t ? tv : NULL);
+}
+
+
+static inline long get_compat_itimerval(struct itimerval *o,
+		struct compat_itimerval *i)
+{
+	return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
+		(__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
+		 __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
+		 __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
+		 __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
+}
+
+static inline long put_compat_itimerval(struct compat_itimerval *o,
+		struct itimerval *i)
+{
+	return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
+		(__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
+		 __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
+		 __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
+		 __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
+}
+
+extern int do_getitimer(int which, struct itimerval *value);
+
+asmlinkage long compat_sys_getitimer(int which, struct compat_itimerval *it)
+{
+	struct itimerval kit;
+	int error;
+
+	error = do_getitimer(which, &kit);
+	if (!error && put_compat_itimerval(it, &kit))
+		error = -EFAULT;
+	return error;
+}
+
+extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
+
+asmlinkage long compat_sys_setitimer(int which, struct compat_itimerval *in,
+		struct compat_itimerval *out)
+{
+	struct itimerval kin, kout;
+	int error;
+
+	if (in) {
+		if (get_compat_itimerval(&kin, in))
+			return -EFAULT;
+	} else
+		memset(&kin, 0, sizeof(kin));
+
+	error = do_setitimer(which, &kin, out ? &kout : NULL);
+	if (error || !out)
+		return error;
+	if (put_compat_itimerval(out, &kout))
+		return -EFAULT;
+	return 0;
+}
diff -Nru a/kernel/exit.c b/kernel/exit.c
--- a/kernel/exit.c	Mon Dec  9 18:46:51 2002
+++ b/kernel/exit.c	Mon Dec  9 18:46:51 2002
@@ -425,14 +425,13 @@
 	/*
 	 * Serialize with any possible pending coredump:
 	 */
-	if (!mm->dumpable) {
-		current->core_waiter = 1;
-		atomic_inc(&mm->core_waiters);
-		if (atomic_read(&mm->core_waiters) ==atomic_read(&mm->mm_users))
-			wake_up(&mm->core_wait);
-		down(&mm->core_sem);
-		up(&mm->core_sem);
-		atomic_dec(&mm->core_waiters);
+	if (mm->core_waiters) {
+		down_write(&mm->mmap_sem);
+		if (!--mm->core_waiters)
+			complete(mm->core_startup_done);
+		up_write(&mm->mmap_sem);
+
+		wait_for_completion(&mm->core_done);
 	}
 	atomic_inc(&mm->mm_count);
 	if (mm != tsk->active_mm) BUG();
diff -Nru a/kernel/fork.c b/kernel/fork.c
--- a/kernel/fork.c	Mon Dec  9 18:46:34 2002
+++ b/kernel/fork.c	Mon Dec  9 18:46:34 2002
@@ -328,9 +328,7 @@
 	atomic_set(&mm->mm_users, 1);
 	atomic_set(&mm->mm_count, 1);
 	init_rwsem(&mm->mmap_sem);
-	init_MUTEX(&mm->core_sem);
-	init_waitqueue_head(&mm->core_wait);
-	atomic_set(&mm->core_waiters, 0);
+	mm->core_waiters = 0;
 	mm->page_table_lock = SPIN_LOCK_UNLOCKED;
 	mm->ioctx_list_lock = RW_LOCK_UNLOCKED;
 	mm->default_kioctx = (struct kioctx)INIT_KIOCTX(mm->default_kioctx, *mm);
@@ -717,7 +715,8 @@
 	if ((clone_flags & CLONE_DETACHED) && !(clone_flags & CLONE_THREAD))
 		return ERR_PTR(-EINVAL);
 
-	if ((retval = security_task_create(clone_flags)))
+	retval = security_task_create(clone_flags);
+	if (retval)
 		goto fork_out;
 
 	retval = -ENOMEM;
@@ -799,7 +798,6 @@
 	p->start_time = jiffies;
 	p->security = NULL;
 
-	p->core_waiter = 0;
 	retval = -ENOMEM;
 	if (security_task_alloc(p))
 		goto bad_fork_cleanup;
diff -Nru a/kernel/kallsyms.c b/kernel/kallsyms.c
--- a/kernel/kallsyms.c	Mon Dec  9 18:46:51 2002
+++ b/kernel/kallsyms.c	Mon Dec  9 18:46:51 2002
@@ -45,14 +45,11 @@
 		for (i = 0; i < best; i++)
 			name += strlen(name)+1;
 
-		/* Base symbol size on next symbol, but beware aliases. */
-		symbol_end = (unsigned long)_etext;
-		for (i = best+1; i < kallsyms_num_syms; i++) {
-			if (kallsyms_addresses[i] != kallsyms_addresses[best]){
-				symbol_end = kallsyms_addresses[i];
-				break;
-			}
-		}
+		/* Base symbol size on next symbol. */
+		if (best + 1 < kallsyms_num_syms)
+			symbol_end = kallsyms_addresses[best + 1];
+		else
+			symbol_end = (unsigned long)_etext;
 
 		*symbolsize = symbol_end - kallsyms_addresses[best];
 		*modname = NULL;
diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c
--- a/kernel/ksyms.c	Mon Dec  9 18:46:34 2002
+++ b/kernel/ksyms.c	Mon Dec  9 18:46:34 2002
@@ -54,6 +54,7 @@
 #include <linux/smp_lock.h>
 #include <linux/dnotify.h>
 #include <linux/mount.h>
+#include <linux/ptrace.h>
 #include <asm/checksum.h>
 
 #if defined(CONFIG_PROC_FS)
@@ -353,13 +354,8 @@
 EXPORT_SYMBOL(iov_shorten);
 
 /* tty routines */
-EXPORT_SYMBOL(tty_hangup);
 EXPORT_SYMBOL(tty_wait_until_sent);
-EXPORT_SYMBOL(tty_check_change);
-EXPORT_SYMBOL(tty_hung_up_p);
 EXPORT_SYMBOL(tty_flip_buffer_push);
-EXPORT_SYMBOL(tty_get_baud_rate);
-EXPORT_SYMBOL(do_SAK);
 
 /* filesystem registration */
 EXPORT_SYMBOL(register_filesystem);
@@ -594,5 +590,6 @@
 
 /* debug */
 EXPORT_SYMBOL(dump_stack);
+EXPORT_SYMBOL(ptrace_notify);
 
 EXPORT_SYMBOL(current_kernel_time); 
diff -Nru a/kernel/module.c b/kernel/module.c
--- a/kernel/module.c	Mon Dec  9 18:46:50 2002
+++ b/kernel/module.c	Mon Dec  9 18:46:50 2002
@@ -37,6 +37,9 @@
 #define DEBUGP(fmt , a...)
 #endif
 
+#define symbol_is(literal, string)				\
+	(strcmp(MODULE_SYMBOL_PREFIX literal, (string)) == 0)
+
 /* List of modules, protected by module_mutex */
 static DECLARE_MUTEX(module_mutex);
 LIST_HEAD(modules); /* FIXME: Accessed w/o lock on oops by some archs */
@@ -630,10 +633,10 @@
 	unsigned int i;
 
 	for (i = 1; i < sechdrs[symbolsec].sh_size/sizeof(*sym); i++) {
-		if (strcmp("__initfn", strtab + sym[i].st_name) == 0)
+		if (symbol_is("__initfn", strtab + sym[i].st_name))
 			mod->init = (void *)sym[i].st_value;
 #ifdef CONFIG_MODULE_UNLOAD
-		if (strcmp("__exitfn", strtab + sym[i].st_name) == 0)
+		if (symbol_is("__exitfn", strtab + sym[i].st_name))
 			mod->exit = (void *)sym[i].st_value;
 #endif
 	}
@@ -770,7 +773,7 @@
 						       mod,
 						       &ksg);
 			/* We fake up "__this_module" */
-			if (strcmp(strtab+sym[i].st_name, "__this_module")==0)
+			if (symbol_is("__this_module", strtab+sym[i].st_name))
 				sym[i].st_value = (unsigned long)mod;
 		}
 	}
@@ -864,8 +867,8 @@
 			/* Internal symbols */
 			DEBUGP("Symbol table in section %u\n", i);
 			symindex = i;
-		} else if (strcmp(secstrings+sechdrs[i].sh_name, ".modulename")
-			   == 0) {
+		} else if (strcmp(secstrings+sechdrs[i].sh_name,
+				  ".gnu.linkonce.modname") == 0) {
 			/* This module's name */
 			DEBUGP("Module name in section %u\n", i);
 			modnameindex = i;
@@ -892,7 +895,7 @@
 		}
 #ifdef CONFIG_KALLSYMS
 		/* symbol and string tables for decoding later. */
-		if (sechdrs[i].sh_type == SHT_SYMTAB || i == hdr->e_shstrndx)
+		if (sechdrs[i].sh_type == SHT_SYMTAB || i == strindex)
 			sechdrs[i].sh_flags |= SHF_ALLOC;
 #endif
 #ifndef CONFIG_MODULE_UNLOAD
@@ -1165,7 +1168,14 @@
 			       unsigned long *size,
 			       unsigned long *offset)
 {
-	unsigned int i, next = 0, best = 0;
+	unsigned int i, best = 0;
+	unsigned long nextval;
+
+	/* At worse, next value is at end of module */
+	if (inside_core(mod, addr))
+		nextval = (unsigned long)mod->module_core+mod->core_size;
+	else 
+		nextval = (unsigned long)mod->module_init+mod->init_size;
 
 	/* Scan for closest preceeding symbol, and next symbol. (ELF
            starts real symbols at 1). */
@@ -1177,22 +1187,14 @@
 		    && mod->symtab[i].st_value > mod->symtab[best].st_value)
 			best = i;
 		if (mod->symtab[i].st_value > addr
-		    && mod->symtab[i].st_value < mod->symtab[next].st_value)
-			next = i;
+		    && mod->symtab[i].st_value < nextval)
+			nextval = mod->symtab[i].st_value;
 	}
 
 	if (!best)
 		return NULL;
 
-	if (!next) {
-		/* Last symbol?  It ends at the end of the module then. */
-		if (inside_core(mod, addr))
-			*size = mod->module_core+mod->core_size - (void*)addr;
-		else
-			*size = mod->module_init+mod->init_size - (void*)addr;
-	} else
-		*size = mod->symtab[next].st_value - addr;
-
+	*size = nextval - mod->symtab[best].st_value;
 	*offset = addr - mod->symtab[best].st_value;
 	return mod->strtab + mod->symtab[best].st_name;
 }
diff -Nru a/kernel/printk.c b/kernel/printk.c
--- a/kernel/printk.c	Mon Dec  9 18:46:52 2002
+++ b/kernel/printk.c	Mon Dec  9 18:46:52 2002
@@ -560,6 +560,7 @@
 		schedule();
 	}
 }
+EXPORT_SYMBOL(console_conditional_schedule);
 
 void console_print(const char *s)
 {
diff -Nru a/kernel/ptrace.c b/kernel/ptrace.c
--- a/kernel/ptrace.c	Mon Dec  9 18:46:52 2002
+++ b/kernel/ptrace.c	Mon Dec  9 18:46:52 2002
@@ -101,7 +101,8 @@
 	/* the same process cannot be attached many times */
 	if (task->ptrace & PT_PTRACED)
 		goto bad;
-	if ((retval = security_ptrace(current, task)))
+	retval = security_ptrace(current, task);
+	if (retval)
 		goto bad;
 
 	/* Go */
diff -Nru a/kernel/sched.c b/kernel/sched.c
--- a/kernel/sched.c	Mon Dec  9 18:46:50 2002
+++ b/kernel/sched.c	Mon Dec  9 18:46:50 2002
@@ -1192,6 +1192,16 @@
 	spin_unlock_irqrestore(&x->wait.lock, flags);
 }
 
+void complete_all(struct completion *x)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&x->wait.lock, flags);
+	x->done += UINT_MAX/2;
+	__wake_up_common(&x->wait, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 0, 0);
+	spin_unlock_irqrestore(&x->wait.lock, flags);
+}
+
 void wait_for_completion(struct completion *x)
 {
 	might_sleep();
@@ -1348,7 +1358,8 @@
 	if (nice > 19)
 		nice = 19;
 
-	if ((retval = security_task_setnice(current, nice)))
+	retval = security_task_setnice(current, nice);
+	if (retval)
 		return retval;
 
 	set_user_nice(current, nice);
@@ -1469,7 +1480,8 @@
 	    !capable(CAP_SYS_NICE))
 		goto out_unlock;
 
-	if ((retval = security_task_setscheduler(p, policy, &lp)))
+	retval = security_task_setscheduler(p, policy, &lp);
+	if (retval)
 		goto out_unlock;
 
 	array = p->array;
@@ -1532,7 +1544,8 @@
 	read_lock(&tasklist_lock);
 	p = find_process_by_pid(pid);
 	if (p) {
-		if (!(retval = security_task_getscheduler(p)))
+		retval = security_task_getscheduler(p);
+		if (!retval)
 			retval = p->policy;
 	}
 	read_unlock(&tasklist_lock);
@@ -1561,7 +1574,8 @@
 	if (!p)
 		goto out_unlock;
 
-	if ((retval = security_task_getscheduler(p)))
+	retval = security_task_getscheduler(p);
+	if (retval)
 		goto out_unlock;
 
 	lp.sched_priority = p->rt_priority;
@@ -1820,7 +1834,8 @@
 	if (!p)
 		goto out_unlock;
 
-	if ((retval = security_task_getscheduler(p)))
+	retval = security_task_getscheduler(p);
+	if (retval)
 		goto out_unlock;
 
 	jiffies_to_timespec(p->policy & SCHED_FIFO ?
diff -Nru a/kernel/signal.c b/kernel/signal.c
--- a/kernel/signal.c	Mon Dec  9 18:46:36 2002
+++ b/kernel/signal.c	Mon Dec  9 18:46:36 2002
@@ -739,7 +739,8 @@
 	ret = -EPERM;
 	if (bad_signal(sig, info, t))
 		goto out;
-	if ((ret = security_task_kill(t, info, sig)))
+	ret = security_task_kill(t, info, sig);
+	if (ret)
 		goto out;
 
 	/* The null signal is a permissions and process existence probe.
@@ -1349,6 +1350,18 @@
 /*
  * System call entry points.
  */
+
+asmlinkage long sys_restart_syscall(void)
+{
+	struct restart_block *restart = &current_thread_info()->restart_block;
+	return restart->fn(restart);
+}
+
+long do_no_restart_syscall(struct restart_block *param)
+{
+	return -EINTR;
+}
+
 
 /*
  * We don't need to get the kernel lock - this is all local to this
diff -Nru a/kernel/suspend.c b/kernel/suspend.c
--- a/kernel/suspend.c	Mon Dec  9 18:46:35 2002
+++ b/kernel/suspend.c	Mon Dec  9 18:46:35 2002
@@ -80,9 +80,9 @@
 #endif
 
 #define TIMEOUT	(6 * HZ)			/* Timeout for stopping processes */
-#define ADDRESS(x) ((unsigned long) phys_to_virt(((x) << PAGE_SHIFT)))
-
-extern int C_A_D;
+#define __ADDRESS(x)  ((unsigned long) phys_to_virt(x))
+#define ADDRESS(x) __ADDRESS((x) << PAGE_SHIFT)
+#define ADDRESS2(x) __ADDRESS(__pa(x))		/* Needed for x86-64 where some pages are in memory twice */
 
 /* References to section boundaries */
 extern char _text, _etext, _edata, __bss_start, _end;
@@ -145,10 +145,10 @@
 /*
  * Debug
  */
-#undef	DEBUG_DEFAULT
+#define	DEBUG_DEFAULT
 #undef	DEBUG_PROCESS
 #undef	DEBUG_SLOW
-#define TEST_SWSUSP 1		/* Set to 1 to reboot instead of halt machine after suspension */
+#define TEST_SWSUSP 0		/* Set to 1 to reboot instead of halt machine after suspension */
 
 #ifdef DEBUG_DEFAULT
 # define PRINTK(f, a...)       printk(f, ## a)
@@ -235,6 +235,7 @@
 	} while(todo);
 	
 	printk( "|\n" );
+	BUG_ON(in_atomic());
 	return 0;
 }
 
@@ -322,20 +323,20 @@
 	rw_swap_page_sync(READ, entry, page);
 
 	if (mode == MARK_SWAP_RESUME) {
-	  	if (!memcmp("SUSP1R",cur->swh.magic.magic,6))
+	  	if (!memcmp("S1",cur->swh.magic.magic,2))
 		  	memcpy(cur->swh.magic.magic,"SWAP-SPACE",10);
-		else if (!memcmp("SUSP2R",cur->swh.magic.magic,6))
+		else if (!memcmp("S2",cur->swh.magic.magic,2))
 			memcpy(cur->swh.magic.magic,"SWAPSPACE2",10);
 		else printk("%sUnable to find suspended-data signature (%.10s - misspelled?\n", 
 		      	name_resume, cur->swh.magic.magic);
 	} else {
 	  	if ((!memcmp("SWAP-SPACE",cur->swh.magic.magic,10)))
-		  	memcpy(cur->swh.magic.magic,"SUSP1R....",10);
+		  	memcpy(cur->swh.magic.magic,"S1SUSP....",10);
 		else if ((!memcmp("SWAPSPACE2",cur->swh.magic.magic,10)))
-			memcpy(cur->swh.magic.magic,"SUSP2R....",10);
+			memcpy(cur->swh.magic.magic,"S2SUSP....",10);
 		else panic("\nSwapspace is not swapspace (%.10s)\n", cur->swh.magic.magic);
 		cur->link.next = prev; /* prev is the first/last swap page of the resume area */
-		/* link.next lies *no more* in last 4 bytes of magic */
+		/* link.next lies *no more* in last 4/8 bytes of magic */
 	}
 	rw_swap_page_sync(WRITE, entry, page);
 	__free_page(page);
@@ -489,7 +490,6 @@
 			if (PageNosave(page))
 				continue;
 
-
 			if ((chunk_size=is_head_of_free_region(page))!=0) {
 				pfn += chunk_size - 1;
 				continue;
@@ -500,10 +500,9 @@
 			/*
 			 * Just copy whole code segment. Hopefully it is not that big.
 			 */
-			if (ADDRESS(pfn) >= (unsigned long)
-				&__nosave_begin && ADDRESS(pfn) < 
-				(unsigned long)&__nosave_end) {
-				PRINTK("[nosave %x]", ADDRESS(pfn));
+			if ((ADDRESS(pfn) >= (unsigned long) ADDRESS2(&__nosave_begin)) && 
+			    (ADDRESS(pfn) <  (unsigned long) ADDRESS2(&__nosave_end))) {
+				PRINTK("[nosave %lx]", ADDRESS(pfn));
 				continue;
 			}
 			/* Hmm, perhaps copying all reserved pages is not too healthy as they may contain 
@@ -513,7 +512,7 @@
 		nr_copy_pages++;
 		if (pagedir_p) {
 			pagedir_p->orig_address = ADDRESS(pfn);
-			copy_page(pagedir_p->address, pagedir_p->orig_address);
+			copy_page((void *) pagedir_p->address, (void *) pagedir_p->orig_address);
 			pagedir_p++;
 		}
 	}
@@ -549,7 +548,7 @@
 
 	pagedir_order = get_bitmask_order(SUSPEND_PD_PAGES(nr_copy_pages));
 
-	p = pagedir = (suspend_pagedir_t *)__get_free_pages(GFP_ATOMIC, pagedir_order);
+	p = pagedir = (suspend_pagedir_t *)__get_free_pages(GFP_ATOMIC | __GFP_COLD, pagedir_order);
 	if(!pagedir)
 		return NULL;
 
@@ -558,11 +557,12 @@
 		SetPageNosave(page++);
 		
 	while(nr_copy_pages--) {
-		p->address = get_zeroed_page(GFP_ATOMIC);
+		p->address = get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
 		if(!p->address) {
 			free_suspend_pagedir((unsigned long) pagedir);
 			return NULL;
 		}
+		printk(".");
 		SetPageNosave(virt_to_page(p->address));
 		p->orig_address = 0;
 		p++;
@@ -623,7 +623,7 @@
 static void free_some_memory(void)
 {
 	printk("Freeing memory: ");
-	while (try_to_free_pages(&contig_page_data.node_zones[ZONE_HIGHMEM], GFP_KSWAPD, 0))
+	while (shrink_all_memory(10000))
 		printk(".");
 	printk("|\n");
 }
@@ -676,7 +676,7 @@
 	}
 }
 
-static int suspend_save_image(void)
+static int suspend_prepare_image(void)
 {
 	struct sysinfo i;
 	unsigned int nr_needed_pages = 0;
@@ -725,9 +725,15 @@
 	 *
 	 * Following line enforces not writing to disk until we choose.
 	 */
-	drivers_unsuspend();
-	spin_unlock_irq(&suspend_pagedir_lock);
+
 	printk( "critical section/: done (%d pages copied)\n", nr_copy_pages );
+	spin_unlock_irq(&suspend_pagedir_lock);
+	return 0;
+}
+
+static void suspend_save_image(void)
+{
+	drivers_unsuspend();
 
 	lock_swapdevices();
 	write_suspend_image();
@@ -738,11 +744,11 @@
 	 * filesystem clean: it is not. (And it does not matter, if we resume
 	 * correctly, we'll mark system clean, anyway.)
 	 */
-	return 0;
 }
 
-void suspend_power_down(void)
+static void suspend_power_down(void)
 {
+	extern int C_A_D;
 	C_A_D = 0;
 	printk(KERN_EMERG "%s%s Trying to power down.\n", name_suspend, TEST_SWSUSP ? "Disable TEST_SWSUSP. NOT ": "");
 #ifdef CONFIG_VT
@@ -788,8 +794,8 @@
 
 	PRINTK( "Freeing prev allocated pagedir\n" );
 	free_suspend_pagedir((unsigned long) pagedir_save);
-	drivers_resume(RESUME_ALL_PHASES);
 	spin_unlock_irq(&suspend_pagedir_lock);
+	drivers_resume(RESUME_ALL_PHASES);
 
 	PRINTK( "Fixing swap signatures... " );
 	mark_swapfiles(((swp_entry_t) {0}), MARK_SWAP_RESUME);
@@ -804,14 +810,17 @@
 {
 	mb();
 	barrier();
+	BUG_ON(in_atomic());
 	spin_lock_irq(&suspend_pagedir_lock);
 }
 
 void do_magic_suspend_2(void)
 {
 	read_swapfiles();
-	if (!suspend_save_image())
+	if (!suspend_prepare_image()) {	/* suspend_save_image realeses suspend_pagedir_lock */
+		suspend_save_image();
 		suspend_power_down();	/* FIXME: if suspend_power_down is commented out, console is lost after few suspends ?! */
+	}
 
 	printk(KERN_EMERG "%sSuspend failed, trying to recover...\n", name_suspend);
 	MDELAY(1000); /* So user can wait and report us messages if armageddon comes :-) */
@@ -827,7 +836,7 @@
 	PRINTK(KERN_WARNING "%sLeaving do_magic_suspend_2...\n", name_suspend);	
 }
 
-void do_software_suspend(void)
+static void do_software_suspend(void)
 {
 	arch_prepare_suspend();
 	if (prepare_suspend_console())
@@ -1069,9 +1078,9 @@
 
 	PREPARENEXT; /* We have to read next position before we overwrite it */
 
-	if (!memcmp("SUSP1R",cur->swh.magic.magic,6))
+	if (!memcmp("S1",cur->swh.magic.magic,2))
 		memcpy(cur->swh.magic.magic,"SWAP-SPACE",10);
-	else if (!memcmp("SUSP2R",cur->swh.magic.magic,6))
+	else if (!memcmp("S2",cur->swh.magic.magic,2))
 		memcpy(cur->swh.magic.magic,"SWAPSPACE2",10);
 	else {
 		panic("%sUnable to find suspended-data signature (%.10s - misspelled?\n", 
diff -Nru a/kernel/sys.c b/kernel/sys.c
--- a/kernel/sys.c	Mon Dec  9 18:46:34 2002
+++ b/kernel/sys.c	Mon Dec  9 18:46:34 2002
@@ -21,6 +21,7 @@
 #include <linux/times.h>
 #include <linux/security.h>
 #include <linux/dcookies.h>
+#include <linux/suspend.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -485,7 +486,8 @@
 	int new_egid = old_egid;
 	int retval;
 
-	if ((retval = security_task_setgid(rgid, egid, (gid_t)-1, LSM_SETID_RE)))
+	retval = security_task_setgid(rgid, egid, (gid_t)-1, LSM_SETID_RE);
+	if (retval)
 		return retval;
 
 	if (rgid != (gid_t) -1) {
@@ -530,7 +532,8 @@
 	int old_egid = current->egid;
 	int retval;
 
-	if ((retval = security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_ID)))
+	retval = security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_ID);
+	if (retval)
 		return retval;
 
 	if (capable(CAP_SETGID))
@@ -603,7 +606,8 @@
 	int old_ruid, old_euid, old_suid, new_ruid, new_euid;
 	int retval;
 
-	if ((retval = security_task_setuid(ruid, euid, (uid_t)-1, LSM_SETID_RE)))
+	retval = security_task_setuid(ruid, euid, (uid_t)-1, LSM_SETID_RE);
+	if (retval)
 		return retval;
 
 	new_ruid = old_ruid = current->uid;
@@ -663,7 +667,8 @@
 	int old_ruid, old_suid, new_ruid, new_suid;
 	int retval;
 
-	if ((retval = security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_ID)))
+	retval = security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_ID);
+	if (retval)
 		return retval;
 
 	old_ruid = new_ruid = current->uid;
@@ -700,7 +705,8 @@
 	int old_suid = current->suid;
 	int retval;
 
-	if ((retval = security_task_setuid(ruid, euid, suid, LSM_SETID_RES)))
+	retval = security_task_setuid(ruid, euid, suid, LSM_SETID_RES);
+	if (retval)
 		return retval;
 
 	if (!capable(CAP_SETUID)) {
@@ -751,7 +757,8 @@
 {
 	int retval;
 
-	if ((retval = security_task_setgid(rgid, egid, sgid, LSM_SETID_RES)))
+	retval = security_task_setgid(rgid, egid, sgid, LSM_SETID_RES);
+	if (retval)
 		return retval;
 
 	if (!capable(CAP_SETGID)) {
@@ -804,7 +811,8 @@
 	int old_fsuid;
 	int retval;
 
-	if ((retval = security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS)))
+	retval = security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS);
+	if (retval)
 		return retval;
 
 	old_fsuid = current->fsuid;
@@ -820,7 +828,8 @@
 		current->fsuid = uid;
 	}
 
-	if ((retval = security_task_post_setuid(old_fsuid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS)))
+	retval = security_task_post_setuid(old_fsuid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS);
+	if (retval)
 		return retval;
 
 	return old_fsuid;
@@ -834,7 +843,8 @@
 	int old_fsgid;
 	int retval;
 
-	if ((retval = security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_FS)))
+	retval = security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_FS);
+	if (retval)
 		return retval;
 
 	old_fsgid = current->fsgid;
@@ -959,7 +969,8 @@
 
 		retval = -ESRCH;
 		if (p) {
-			if (!(retval = security_task_getpgid(p)))
+			retval = security_task_getpgid(p);
+			if (!retval)
 				retval = p->pgrp;
 		}
 		read_unlock(&tasklist_lock);
@@ -986,7 +997,8 @@
 
 		retval = -ESRCH;
 		if(p) {
-			if (!(retval = security_task_getsid(p)))
+			retval = security_task_getsid(p);
+			if (!retval)
 				retval = p->session;
 		}
 		read_unlock(&tasklist_lock);
@@ -1067,7 +1079,8 @@
 		return -EINVAL;
 	if(copy_from_user(groups, grouplist, gidsetsize * sizeof(gid_t)))
 		return -EFAULT;
-	if ((retval = security_task_setgroups(gidsetsize, groups)))
+	retval = security_task_setgroups(gidsetsize, groups);
+	if (retval)
 		return retval;
 	memcpy(current->groups, groups, gidsetsize * sizeof(gid_t));
 	current->ngroups = gidsetsize;
@@ -1220,6 +1233,8 @@
 		return -EINVAL;
 	if(copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
 		return -EFAULT;
+       if (new_rlim.rlim_cur > new_rlim.rlim_max)
+               return -EINVAL;
 	old_rlim = current->rlim + resource;
 	if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
 	     (new_rlim.rlim_max > old_rlim->rlim_max)) &&
@@ -1230,7 +1245,8 @@
 			return -EPERM;
 	}
 
-	if ((retval = security_task_setrlimit(resource, &new_rlim)))
+	retval = security_task_setrlimit(resource, &new_rlim);
+	if (retval)
 		return retval;
 
 	*old_rlim = new_rlim;
@@ -1304,7 +1320,8 @@
 	int error = 0;
 	int sig;
 
-	if ((error = security_task_prctl(option, arg2, arg3, arg4, arg5)))
+	error = security_task_prctl(option, arg2, arg3, arg4, arg5);
+	if (error)
 		return error;
 
 	switch (option) {
diff -Nru a/kernel/timer.c b/kernel/timer.c
--- a/kernel/timer.c	Mon Dec  9 18:46:35 2002
+++ b/kernel/timer.c	Mon Dec  9 18:46:35 2002
@@ -25,6 +25,7 @@
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/notifier.h>
+#include <linux/thread_info.h>
 
 #include <asm/uaccess.h>
 
@@ -862,8 +863,8 @@
 }
 
 /*
- * This is not strictly SMP safe: p_opptr could change
- * from under us. However, rather than getting any lock
+ * Accessing ->group_leader->real_parent is not SMP-safe, it could
+ * change from under us. However, rather than getting any lock
  * we can use an optimistic algorithm: get the parent
  * pid, and go back and check that the parent is still
  * the same. If it has changed (which is extremely unlikely
@@ -871,33 +872,31 @@
  *
  * NOTE! This depends on the fact that even if we _do_
  * get an old value of "parent", we can happily dereference
- * the pointer: we just can't necessarily trust the result
+ * the pointer (it was and remains a dereferencable kernel pointer
+ * no matter what): we just can't necessarily trust the result
  * until we know that the parent pointer is valid.
  *
- * The "mb()" macro is a memory barrier - a synchronizing
- * event. It also makes sure that gcc doesn't optimize
- * away the necessary memory references.. The barrier doesn't
- * have to have all that strong semantics: on x86 we don't
- * really require a synchronizing instruction, for example.
- * The barrier is more important for code generation than
- * for any real memory ordering semantics (even if there is
- * a small window for a race, using the old pointer is
- * harmless for a while).
+ * NOTE2: ->group_leader never changes from under us.
  */
 asmlinkage long sys_getppid(void)
 {
 	int pid;
-	struct task_struct * me = current;
-	struct task_struct * parent;
+	struct task_struct *me = current;
+	struct task_struct *parent;
 
-	parent = me->real_parent;
+	parent = me->group_leader->real_parent;
 	for (;;) {
-		pid = parent->pid;
+		pid = parent->tgid;
 #if CONFIG_SMP
 {
 		struct task_struct *old = parent;
-		mb();
-		parent = me->real_parent;
+
+		/*
+		 * Make sure we read the pid before re-reading the
+		 * parent pointer:
+		 */
+		rmb();
+		parent = me->group_leader->real_parent;
 		if (old != parent)
 			continue;
 }
@@ -1022,31 +1021,62 @@
 	return current->pid;
 }
 
+static long nanosleep_restart(struct restart_block *restart)
+{
+	unsigned long expire = restart->arg0, now = jiffies;
+	struct timespec *rmtp = (struct timespec *) restart->arg1;
+	long ret;
+
+	/* Did it expire while we handled signals? */
+	if (!time_after(expire, now))
+		return 0;
+
+	current->state = TASK_INTERRUPTIBLE;
+	expire = schedule_timeout(expire - now);
+
+	ret = 0;
+	if (expire) {
+		struct timespec t;
+		jiffies_to_timespec(expire, &t);
+
+		ret = -ERESTART_RESTARTBLOCK;
+		if (copy_to_user(rmtp, &t, sizeof(t)))
+			ret = -EFAULT;
+		/* The 'restart' block is already filled in */
+	}
+	return ret;
+}
+
 asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp)
 {
 	struct timespec t;
 	unsigned long expire;
+	long ret;
 
-	if(copy_from_user(&t, rqtp, sizeof(struct timespec)))
+	if (copy_from_user(&t, rqtp, sizeof(t)))
 		return -EFAULT;
 
-	if (t.tv_nsec >= 1000000000L || t.tv_nsec < 0 || t.tv_sec < 0)
+	if ((t.tv_nsec >= 1000000000L) || (t.tv_nsec < 0) || (t.tv_sec < 0))
 		return -EINVAL;
 
 	expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
-
 	current->state = TASK_INTERRUPTIBLE;
 	expire = schedule_timeout(expire);
 
+	ret = 0;
 	if (expire) {
-		if (rmtp) {
-			jiffies_to_timespec(expire, &t);
-			if (copy_to_user(rmtp, &t, sizeof(struct timespec)))
-				return -EFAULT;
-		}
-		return -EINTR;
+		struct restart_block *restart;
+		jiffies_to_timespec(expire, &t);
+		if (copy_to_user(rmtp, &t, sizeof(t)))
+			return -EFAULT;
+
+		restart = &current_thread_info()->restart_block;
+		restart->fn = nanosleep_restart;
+		restart->arg0 = jiffies + expire;
+		restart->arg1 = (unsigned long) rmtp;
+		ret = -ERESTART_RESTARTBLOCK;
 	}
-	return 0;
+	return ret;
 }
 
 /*
diff -Nru a/kernel/uid16.c b/kernel/uid16.c
--- a/kernel/uid16.c	Mon Dec  9 18:46:38 2002
+++ b/kernel/uid16.c	Mon Dec  9 18:46:38 2002
@@ -140,7 +140,8 @@
 		return -EFAULT;
 	for (i = 0 ; i < gidsetsize ; i++)
 		new_groups[i] = (gid_t)groups[i];
-	if ((i = security_task_setgroups(gidsetsize, new_groups)))
+	i = security_task_setgroups(gidsetsize, new_groups);
+	if (i)
 		return i;
 	memcpy(current->groups, new_groups, gidsetsize * sizeof(gid_t));
 	current->ngroups = gidsetsize;
diff -Nru a/lib/kobject.c b/lib/kobject.c
--- a/lib/kobject.c	Mon Dec  9 18:46:51 2002
+++ b/lib/kobject.c	Mon Dec  9 18:46:51 2002
@@ -110,8 +110,7 @@
 	if (kobj) {
 		kobject_init(kobj);
 		error = kobject_add(kobj);
-		if (error)
-			kobject_cleanup(kobj);
+		WARN_ON(error);
 	} else
 		error = -EINVAL;
 	return error;
@@ -229,6 +228,38 @@
 }
 
 
+/**
+ *	subsystem_create_file - export sysfs attribute file.
+ *	@s:	subsystem.
+ *	@a:	subsystem attribute descriptor.
+ */
+
+int subsys_create_file(struct subsystem * s, struct subsys_attribute * a)
+{
+	int error = 0;
+	if (subsys_get(s)) {
+		error = sysfs_create_file(&s->kobj,&a->attr);
+		subsys_put(s);
+	}
+	return error;
+}
+
+
+/**
+ *	subsystem_remove_file - remove sysfs attribute file.
+ *	@s:	subsystem.
+ *	@a:	attribute desciptor.
+ */
+
+void subsys_remove_file(struct subsystem * s, struct subsys_attribute * a)
+{
+	if (subsys_get(s)) {
+		sysfs_remove_file(&s->kobj,&a->attr);
+		subsys_put(s);
+	}
+}
+
+
 EXPORT_SYMBOL(kobject_init);
 EXPORT_SYMBOL(kobject_register);
 EXPORT_SYMBOL(kobject_unregister);
@@ -238,3 +269,5 @@
 EXPORT_SYMBOL(subsystem_init);
 EXPORT_SYMBOL(subsystem_register);
 EXPORT_SYMBOL(subsystem_unregister);
+EXPORT_SYMBOL(subsys_create_file);
+EXPORT_SYMBOL(subsys_remove_file);
diff -Nru a/lib/zlib_deflate/deflate_syms.c b/lib/zlib_deflate/deflate_syms.c
--- a/lib/zlib_deflate/deflate_syms.c	Mon Dec  9 18:46:38 2002
+++ b/lib/zlib_deflate/deflate_syms.c	Mon Dec  9 18:46:38 2002
@@ -19,5 +19,3 @@
 EXPORT_SYMBOL(zlib_deflateCopy);
 EXPORT_SYMBOL(zlib_deflateParams);
 MODULE_LICENSE("GPL");
-
-no_module_init;
diff -Nru a/lib/zlib_inflate/inflate_syms.c b/lib/zlib_inflate/inflate_syms.c
--- a/lib/zlib_inflate/inflate_syms.c	Mon Dec  9 18:46:38 2002
+++ b/lib/zlib_inflate/inflate_syms.c	Mon Dec  9 18:46:38 2002
@@ -20,5 +20,3 @@
 EXPORT_SYMBOL(zlib_inflateSyncPoint);
 EXPORT_SYMBOL(zlib_inflateIncomp); 
 MODULE_LICENSE("GPL");
-
-no_module_init;
diff -Nru a/mm/Makefile b/mm/Makefile
--- a/mm/Makefile	Mon Dec  9 18:46:49 2002
+++ b/mm/Makefile	Mon Dec  9 18:46:49 2002
@@ -4,12 +4,13 @@
 
 export-objs := shmem.o filemap.o mempool.o page_alloc.o page-writeback.o
 
-obj-y	 := memory.o mmap.o filemap.o fremap.o mprotect.o mlock.o mremap.o \
-	    vmalloc.o slab.o bootmem.o swap.o vmscan.o page_alloc.o \
-	    oom_kill.o shmem.o highmem.o mempool.o msync.o mincore.o \
-	    readahead.o pdflush.o page-writeback.o rmap.o madvise.o \
-	    vcache.o truncate.o
+mmu-y			:= nommu.o
+mmu-$(CONFIG_MMU)	:= fremap.o highmem.o madvise.o memory.o mincore.o \
+			   mlock.o mmap.o mprotect.o mremap.o msync.o rmap.o \
+			   shmem.o vmalloc.o
 
-obj-$(CONFIG_SWAP)	+= page_io.o swap_state.o swapfile.o
+obj-y			:= bootmem.o filemap.o mempool.o oom_kill.o \
+			   page_alloc.o page-writeback.o pdflush.o readahead.o \
+			   slab.o swap.o truncate.o vcache.o vmscan.o $(mmu-y)
 
-include $(TOPDIR)/Rules.make
+obj-$(CONFIG_SWAP)	+= page_io.o swap_state.o swapfile.o
diff -Nru a/mm/filemap.c b/mm/filemap.c
--- a/mm/filemap.c	Mon Dec  9 18:46:35 2002
+++ b/mm/filemap.c	Mon Dec  9 18:46:35 2002
@@ -323,10 +323,13 @@
 void end_page_writeback(struct page *page)
 {
 	wait_queue_head_t *waitqueue = page_waitqueue(page);
-	smp_mb__before_clear_bit();
-	if (!TestClearPageWriteback(page))
-		BUG();
-	smp_mb__after_clear_bit(); 
+
+	if (!TestClearPageReclaim(page) || rotate_reclaimable_page(page)) {
+		smp_mb__before_clear_bit();
+		if (!TestClearPageWriteback(page))
+			BUG();
+		smp_mb__after_clear_bit();
+	}
 	if (waitqueue_active(waitqueue))
 		wake_up_all(waitqueue);
 }
diff -Nru a/mm/memory.c b/mm/memory.c
--- a/mm/memory.c	Mon Dec  9 18:46:36 2002
+++ b/mm/memory.c	Mon Dec  9 18:46:36 2002
@@ -405,6 +405,8 @@
 
 	BUG_ON(address >= end);
 
+	lru_add_drain();
+
 	dir = pgd_offset(vma->vm_mm, address);
 	tlb_start_vma(tlb, vma);
 	do {
@@ -446,6 +448,8 @@
 		zap_hugepage_range(vma, address, size);
 		return;
 	}
+
+	lru_add_drain();
 
 	spin_lock(&mm->page_table_lock);
 
diff -Nru a/mm/mmap.c b/mm/mmap.c
--- a/mm/mmap.c	Mon Dec  9 18:46:49 2002
+++ b/mm/mmap.c	Mon Dec  9 18:46:49 2002
@@ -504,7 +504,8 @@
 		}
 	}
 
-	if ((error = security_file_mmap(file, prot, flags)))
+	error = security_file_mmap(file, prot, flags);
+	if (error)
 		return error;
 		
 	/* Clear old maps */
diff -Nru a/mm/mprotect.c b/mm/mprotect.c
--- a/mm/mprotect.c	Mon Dec  9 18:46:36 2002
+++ b/mm/mprotect.c	Mon Dec  9 18:46:36 2002
@@ -263,7 +263,8 @@
 			goto out;
 		}
 
-		if ((error = security_file_mprotect(vma, prot)))
+		error = security_file_mprotect(vma, prot);
+		if (error)
 			goto out;
 
 		if (vma->vm_end > end) {
diff -Nru a/mm/nommu.c b/mm/nommu.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/mm/nommu.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,557 @@
+/*
+ *  linux/mm/nommu.c
+ *
+ *  Replacement code for mm functions to support CPU's that don't
+ *  have any form of memory management unit (thus no virtual memory).
+ *
+ *  Copyright (c) 2000-2002 David McCullough <davidm@snapgear.com>
+ *  Copyright (c) 2000-2001 D Jeff Dionne <jeff@uClinux.org>
+ *  Copyright (c) 2002      Greg Ungerer <gerg@snapgear.com>
+ */
+
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/swap.h>
+#include <linux/smp_lock.h>
+#include <linux/highmem.h>
+#include <linux/pagemap.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/blkdev.h>
+
+#include <asm/pgalloc.h>
+#include <asm/uaccess.h>
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+
+void *high_memory;
+struct page *mem_map = NULL;
+unsigned long max_mapnr;
+unsigned long num_physpages;
+unsigned long askedalloc, realalloc;
+atomic_t vm_committed_space = ATOMIC_INIT(0);
+
+/*
+ * Handle all mappings that got truncated by a "truncate()"
+ * system call.
+ *
+ * NOTE! We have to be ready to update the memory sharing
+ * between the file and the memory map for a potential last
+ * incomplete page.  Ugly, but necessary.
+ */
+int vmtruncate(struct inode *inode, loff_t offset)
+{
+	struct address_space *mapping = inode->i_mapping;
+	unsigned long limit;
+
+	if (inode->i_size < offset)
+		goto do_expand;
+	inode->i_size = offset;
+
+	truncate_inode_pages(mapping, offset);
+	goto out_truncate;
+
+do_expand:
+	limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
+	if (limit != RLIM_INFINITY && offset > limit)
+		goto out_sig;
+	if (offset > inode->i_sb->s_maxbytes)
+		goto out;
+	inode->i_size = offset;
+
+out_truncate:
+	if (inode->i_op && inode->i_op->truncate) {
+		lock_kernel();
+		inode->i_op->truncate(inode);
+		unlock_kernel();
+	}
+	return 0;
+out_sig:
+	send_sig(SIGXFSZ, current, 0);
+out:
+	return -EFBIG;
+}
+
+/*
+ * Return the total memory allocated for this pointer, not
+ * just what the caller asked for.
+ *
+ * Doesn't have to be accurate, i.e. may have races.
+ */
+unsigned int kobjsize(const void *objp)
+{
+	struct page *page;
+
+	if (!objp || !((page = virt_to_page(objp))))
+		return 0;
+
+	if (PageSlab(page))
+		return ksize(objp);
+
+	BUG_ON(page->index < 0);
+	BUG_ON(page->index >= MAX_ORDER);
+
+	return (PAGE_SIZE << page->index);
+}
+
+/*
+ * The nommu dodgy version :-)
+ */
+int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+	unsigned long start, int len, int write, int force,
+	struct page **pages, struct vm_area_struct **vmas)
+{
+	int i;
+
+	for (i = 0; i < len; i++) {
+		if (pages) {
+			pages[i] = virt_to_page(start);
+			if (pages[i])
+				page_cache_get(pages[i]);
+		}
+		start += PAGE_SIZE;
+	}
+	return(i);
+}
+
+rwlock_t vmlist_lock = RW_LOCK_UNLOCKED;
+struct vm_struct *vmlist;
+
+void vfree(void *addr)
+{
+	kfree(addr);
+}
+
+void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot)
+{
+	/*
+	 * kmalloc doesn't like __GFP_HIGHMEM for some reason
+	 */
+	return kmalloc(size, gfp_mask & ~__GFP_HIGHMEM);
+}
+
+long vread(char *buf, char *addr, unsigned long count)
+{
+	memcpy(buf, addr, count);
+	return count;
+}
+
+long vwrite(char *buf, char *addr, unsigned long count)
+{
+	/* Don't allow overflow */
+	if ((unsigned long) addr + count < count)
+		count = -(unsigned long) addr;
+	
+	memcpy(addr, buf, count);
+	return(count);
+}
+
+/*
+ *	vmalloc  -  allocate virtually continguos memory
+ *
+ *	@size:		allocation size
+ *
+ *	Allocate enough pages to cover @size from the page level
+ *	allocator and map them into continguos kernel virtual space.
+ *
+ *	For tight cotrol over page level allocator and protection flags
+ *	use __vmalloc() instead.
+ */
+void *vmalloc(unsigned long size)
+{
+       return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
+}
+
+/*
+ *	vmalloc_32  -  allocate virtually continguos memory (32bit addressable)
+ *
+ *	@size:		allocation size
+ *
+ *	Allocate enough 32bit PA addressable pages to cover @size from the
+ *	page level allocator and map them into continguos kernel virtual space.
+ */
+void *vmalloc_32(unsigned long size)
+{
+	return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL);
+}
+
+void *vmap(struct page **pages, unsigned int count)
+{
+	BUG();
+	return NULL;
+}
+
+void vunmap(void *addr)
+{
+	BUG();
+}
+
+/*
+ *  sys_brk() for the most part doesn't need the global kernel
+ *  lock, except when an application is doing something nasty
+ *  like trying to un-brk an area that has already been mapped
+ *  to a regular file.  in this case, the unmapping will need
+ *  to invoke file system routines that need the global lock.
+ */
+asmlinkage unsigned long sys_brk(unsigned long brk)
+{
+	struct mm_struct *mm = current->mm;
+
+	if (brk < mm->end_code || brk < mm->start_brk || brk > mm->context.end_brk)
+		return mm->brk;
+
+	if (mm->brk == brk)
+		return mm->brk;
+
+	/*
+	 * Always allow shrinking brk
+	 */
+	if (brk <= mm->brk) {
+		mm->brk = brk;
+		return brk;
+	}
+
+	/*
+	 * Ok, looks good - let it rip.
+	 */
+	return mm->brk = brk;
+}
+
+/*
+ * Combine the mmap "prot" and "flags" argument into one "vm_flags" used
+ * internally. Essentially, translate the "PROT_xxx" and "MAP_xxx" bits
+ * into "VM_xxx".
+ */
+static inline unsigned long calc_vm_flags(unsigned long prot, unsigned long flags)
+{
+#define _trans(x,bit1,bit2) \
+((bit1==bit2)?(x&bit1):(x&bit1)?bit2:0)
+
+	unsigned long prot_bits, flag_bits;
+	prot_bits =
+		_trans(prot, PROT_READ, VM_READ) |
+		_trans(prot, PROT_WRITE, VM_WRITE) |
+		_trans(prot, PROT_EXEC, VM_EXEC);
+	flag_bits =
+		_trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN) |
+		_trans(flags, MAP_DENYWRITE, VM_DENYWRITE) |
+		_trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE);
+	return prot_bits | flag_bits;
+#undef _trans
+}
+
+#ifdef DEBUG
+static void show_process_blocks(void)
+{
+	struct mm_tblock_struct * tblock, *tmp;
+	
+	printk("Process blocks %d:", current->pid);
+	
+	tmp = current->mm->context.tblock;
+	while (tmp) {
+		printk(" %p: %p", tmp, tmp->rblock);
+		if (tmp->rblock)
+			printk(" (%d @%p #%d)", kobjsize(tmp->rblock->kblock),
+				tmp->rblock->kblock, tmp->rblock->refcount);
+		if (tmp->next)
+			printk(" ->");
+		else
+			printk(".");
+		tmp = tmp->next;
+	}
+	printk("\n");
+}
+#endif /* DEBUG */
+
+unsigned long do_mmap_pgoff(
+	struct file * file,
+	unsigned long addr,
+	unsigned long len,
+	unsigned long prot,
+	unsigned long flags,
+	unsigned long pgoff)
+{
+	void * result;
+	struct mm_tblock_struct * tblock;
+	unsigned int vm_flags;
+
+	/*
+	 * Get the !CONFIG_MMU specific checks done first
+	 */
+	if ((flags & MAP_SHARED) && (prot & PROT_WRITE) && (file)) {
+		printk("MAP_SHARED not supported (cannot write mappings to disk)\n");
+		return -EINVAL;
+	}
+	
+	if ((prot & PROT_WRITE) && (flags & MAP_PRIVATE)) {
+		printk("Private writable mappings not supported\n");
+		return -EINVAL;
+	}
+	
+	/*
+	 *	now all the standard checks
+	 */
+	if (file && (!file->f_op || !file->f_op->mmap))
+		return -ENODEV;
+
+	if (PAGE_ALIGN(len) == 0)
+		return addr;
+
+	if (len > TASK_SIZE)
+		return -EINVAL;
+
+	/* offset overflow? */
+	if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
+		return -EINVAL;
+
+	/* Do simple checking here so the lower-level routines won't have
+	 * to. we assume access permissions have been handled by the open
+	 * of the memory object, so we don't do any here.
+	 */
+	vm_flags = calc_vm_flags(prot,flags) /* | mm->def_flags */ | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
+
+	/*
+	 * determine the object being mapped and call the appropriate
+	 * specific mapper. 
+	 */
+	if (file) {
+		struct vm_area_struct vma;
+		int error;
+
+		if (!file->f_op)
+			return -ENODEV;
+
+		vma.vm_start = addr;
+		vma.vm_end = addr + len;
+		vma.vm_flags = vm_flags;
+		vma.vm_pgoff = pgoff;
+
+#ifdef MAGIC_ROM_PTR
+		/* First, try simpler routine designed to give us a ROM pointer. */
+
+		if (file->f_op->romptr && !(prot & PROT_WRITE)) {
+			error = file->f_op->romptr(file, &vma);
+#ifdef DEBUG
+			printk("romptr mmap returned %d, start 0x%.8x\n", error,
+					vma.vm_start);
+#endif
+			if (!error)
+				return vma.vm_start;
+			else if (error != -ENOSYS)
+				return error;
+		} else
+#endif /* MAGIC_ROM_PTR */
+		/* Then try full mmap routine, which might return a RAM pointer,
+		   or do something truly complicated. */
+		   
+		if (file->f_op->mmap) {
+			error = file->f_op->mmap(file, &vma);
+				   
+#ifdef DEBUG
+			printk("mmap mmap returned %d /%x\n", error, vma.vm_start);
+#endif
+			if (!error)
+				return vma.vm_start;
+			else if (error != -ENOSYS)
+				return error;
+		} else
+			return -ENODEV; /* No mapping operations defined */
+
+		/* An ENOSYS error indicates that mmap isn't possible (as opposed to
+		   tried but failed) so we'll fall through to the copy. */
+	}
+
+	tblock = (struct mm_tblock_struct *)
+                        kmalloc(sizeof(struct mm_tblock_struct), GFP_KERNEL);
+	if (!tblock) {
+		printk("Allocation of tblock for %lu byte allocation from process %d failed\n", len, current->pid);
+		show_free_areas();
+		return -ENOMEM;
+	}
+
+	tblock->rblock = (struct mm_rblock_struct *)
+			kmalloc(sizeof(struct mm_rblock_struct), GFP_KERNEL);
+
+	if (!tblock->rblock) {
+		printk("Allocation of rblock for %lu byte allocation from process %d failed\n", len, current->pid);
+		show_free_areas();
+		kfree(tblock);
+		return -ENOMEM;
+	}
+
+	result = kmalloc(len, GFP_KERNEL);
+	if (!result) {
+		printk("Allocation of length %lu from process %d failed\n", len,
+				current->pid);
+		show_free_areas();
+		kfree(tblock->rblock);
+		kfree(tblock);
+		return -ENOMEM;
+	}
+
+	tblock->rblock->refcount = 1;
+	tblock->rblock->kblock = result;
+	tblock->rblock->size = len;
+	
+	realalloc += kobjsize(result);
+	askedalloc += len;
+
+#ifdef WARN_ON_SLACK	
+	if ((len+WARN_ON_SLACK) <= kobjsize(result))
+		printk("Allocation of %lu bytes from process %d has %lu bytes of slack\n", len, current->pid, kobjsize(result)-len);
+#endif
+	
+	if (file) {
+		int error;
+		mm_segment_t old_fs = get_fs();
+		set_fs(KERNEL_DS);
+		error = file->f_op->read(file, (char *) result, len, &file->f_pos);
+		set_fs(old_fs);
+		if (error < 0) {
+			kfree(result);
+			kfree(tblock->rblock);
+			kfree(tblock);
+			return error;
+		}
+		if (error < len)
+			memset(result+error, '\0', len-error);
+	} else {
+		memset(result, '\0', len);
+	}
+
+	realalloc += kobjsize(tblock);
+	askedalloc += sizeof(struct mm_tblock_struct);
+
+	realalloc += kobjsize(tblock->rblock);
+	askedalloc += sizeof(struct mm_rblock_struct);
+
+	tblock->next = current->mm->context.tblock.next;
+	current->mm->context.tblock.next = tblock;
+
+#ifdef DEBUG
+	printk("do_mmap:\n");
+	show_process_blocks();
+#endif	  
+
+	return (unsigned long)result;
+}
+
+int do_munmap(struct mm_struct * mm, unsigned long addr, size_t len)
+{
+	struct mm_tblock_struct * tblock, *tmp;
+
+#ifdef MAGIC_ROM_PTR
+	/*
+	 * For efficiency's sake, if the pointer is obviously in ROM,
+	 * don't bother walking the lists to free it.
+	 */
+	if (is_in_rom(addr))
+		return 0;
+#endif
+
+#ifdef DEBUG
+	printk("do_munmap:\n");
+#endif
+
+	tmp = &mm->context.tblock; /* dummy head */
+	while ((tblock=tmp->next) && tblock->rblock &&
+			tblock->rblock->kblock != (void*)addr) 
+		tmp = tblock;
+		
+	if (!tblock) {
+		printk("munmap of non-mmaped memory by process %d (%s): %p\n",
+				current->pid, current->comm, (void*)addr);
+		return -EINVAL;
+	}
+	if (tblock->rblock) {
+		if (!--tblock->rblock->refcount) {
+			if (tblock->rblock->kblock) {
+				realalloc -= kobjsize(tblock->rblock->kblock);
+				askedalloc -= tblock->rblock->size;
+				kfree(tblock->rblock->kblock);
+			}
+			
+			realalloc -= kobjsize(tblock->rblock);
+			askedalloc -= sizeof(struct mm_rblock_struct);
+			kfree(tblock->rblock);
+		}
+	}
+	tmp->next = tblock->next;
+	realalloc -= kobjsize(tblock);
+	askedalloc -= sizeof(struct mm_tblock_struct);
+	kfree(tblock);
+
+#ifdef DEBUG
+	show_process_blocks();
+#endif	  
+
+	return -EINVAL;
+}
+
+/* Release all mmaps. */
+void exit_mmap(struct mm_struct * mm)
+{
+	struct mm_tblock_struct *tmp;
+
+	if (!mm)
+		return;
+
+#ifdef DEBUG
+	printk("Exit_mmap:\n");
+#endif
+
+	while((tmp = mm->context.tblock.next)) {
+		if (tmp->rblock) {
+			if (!--tmp->rblock->refcount) {
+				if (tmp->rblock->kblock) {
+					realalloc -= kobjsize(tmp->rblock->kblock);
+					askedalloc -= tmp->rblock->size;
+					kfree(tmp->rblock->kblock);
+				}
+				realalloc -= kobjsize(tmp->rblock);
+				askedalloc -= sizeof(struct mm_rblock_struct);
+				kfree(tmp->rblock);
+			}
+			tmp->rblock = 0;
+		}
+		mm->context.tblock.next = tmp->next;
+		realalloc -= kobjsize(tmp);
+		askedalloc -= sizeof(struct mm_tblock_struct);
+		kfree(tmp);
+	}
+
+#ifdef DEBUG
+	show_process_blocks();
+#endif	  
+}
+
+asmlinkage long sys_munmap(unsigned long addr, size_t len)
+{
+	int ret;
+	struct mm_struct *mm = current->mm;
+
+	down_write(&mm->mmap_sem);
+	ret = do_munmap(mm, addr, len);
+	up_write(&mm->mmap_sem);
+	return ret;
+}
+
+unsigned long do_brk(unsigned long addr, unsigned long len)
+{
+	return -ENOMEM;
+}
+
+struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr)
+{
+	return NULL;
+}
+
+unsigned long get_unmapped_area(struct file *file, unsigned long addr,
+	unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+	return -ENOMEM;
+}
+
+void pte_chain_init(void)
+{
+}
diff -Nru a/mm/page_alloc.c b/mm/page_alloc.c
--- a/mm/page_alloc.c	Mon Dec  9 18:46:34 2002
+++ b/mm/page_alloc.c	Mon Dec  9 18:46:34 2002
@@ -157,6 +157,7 @@
 			1 << PG_private |
 			1 << PG_locked	|
 			1 << PG_active	|
+			1 << PG_reclaim	|
 			1 << PG_writeback )))
 		bad_page(function, page);
 	if (PageDirty(page))
@@ -260,6 +261,7 @@
 			1 << PG_lru	|
 			1 << PG_active	|
 			1 << PG_dirty	|
+			1 << PG_reclaim	|
 			1 << PG_writeback )))
 		bad_page(__FUNCTION__, page);
 
@@ -441,7 +443,6 @@
 	unsigned long min;
 	struct zone **zones, *classzone;
 	struct page *page;
-	int cflags;
 	int i;
 	int cold;
 
@@ -512,10 +513,9 @@
 		goto nopage;
 
 	inc_page_state(allocstall);
-	cflags = current->flags;
 	current->flags |= PF_MEMALLOC;
 	try_to_free_pages(classzone, gfp_mask, order);
-	current->flags = cflags;
+	current->flags &= ~PF_MEMALLOC;
 
 	/* go through the zonelist yet one more time */
 	min = 1UL << order;
diff -Nru a/mm/pdflush.c b/mm/pdflush.c
--- a/mm/pdflush.c	Mon Dec  9 18:46:52 2002
+++ b/mm/pdflush.c	Mon Dec  9 18:46:52 2002
@@ -15,7 +15,6 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/suspend.h>
-#include <linux/sched.h>	// Needed by writeback.h
 #include <linux/fs.h>		// Needed by writeback.h
 #include <linux/writeback.h>	// Prototypes pdflush_operation()
 
diff -Nru a/mm/slab.c b/mm/slab.c
--- a/mm/slab.c	Mon Dec  9 18:46:50 2002
+++ b/mm/slab.c	Mon Dec  9 18:46:50 2002
@@ -1191,6 +1191,8 @@
  * cache being allocated each time a module is loaded and unloaded, if the
  * module doesn't have persistent in-kernel storage across loads and unloads.
  *
+ * The cache must be empty before calling this function.
+ *
  * The caller must guarantee that noone will allocate memory from the cache
  * during the kmem_cache_destroy().
  */
diff -Nru a/mm/swap.c b/mm/swap.c
--- a/mm/swap.c	Mon Dec  9 18:46:36 2002
+++ b/mm/swap.c	Mon Dec  9 18:46:36 2002
@@ -28,6 +28,47 @@
 int page_cluster;
 
 /*
+ * Writeback is about to end against a page whic has been marked for immediate
+ * reclaim.  If it still appears to be reclaimable, move it to the tail of the
+ * inactive list.  The page still has PageWriteback set, which will pin it.
+ *
+ * We don't expect many pages to come through here, so don't bother batching
+ * things up.
+ *
+ * To avoid placing the page at the tail of the LRU while PG_writeback is still
+ * set, this function will clear PG_writeback before performing the page
+ * motion.  Do that inside the lru lock because once PG_writeback is cleared
+ * we may not touch the page.
+ *
+ * Returns zero if it cleared PG_writeback.
+ */
+int rotate_reclaimable_page(struct page *page)
+{
+	struct zone *zone;
+	unsigned long flags;
+
+	if (PageLocked(page))
+		return 1;
+	if (PageDirty(page))
+		return 1;
+	if (PageActive(page))
+		return 1;
+	if (!PageLRU(page))
+		return 1;
+
+	zone = page_zone(page);
+	spin_lock_irqsave(&zone->lru_lock, flags);
+	if (PageLRU(page) && !PageActive(page)) {
+		list_del(&page->lru);
+		list_add_tail(&page->lru, &zone->inactive_list);
+	}
+	if (!TestClearPageWriteback(page))
+		BUG();
+	spin_unlock_irqrestore(&zone->lru_lock, flags);
+	return 0;
+}
+
+/*
  * FIXME: speed this up?
  */
 void activate_page(struct page *page)
@@ -170,8 +211,19 @@
 	pagevec_free(&pages_to_free);
 }
 
+/*
+ * The pages which we're about to release may be in the deferred lru-addition
+ * queues.  That would prevent them from really being freed right now.  That's
+ * OK from a correctness point of view but is inefficient - those pages may be
+ * cache-warm and we want to give them back to the page allocator ASAP.
+ *
+ * So __pagevec_release() will drain those queues here.  __pagevec_lru_add()
+ * and __pagevec_lru_add_active() call release_pages() directly to avoid
+ * mutual recursion.
+ */
 void __pagevec_release(struct pagevec *pvec)
 {
+	lru_add_drain();
 	release_pages(pvec->pages, pagevec_count(pvec), pvec->cold);
 	pagevec_reinit(pvec);
 }
@@ -224,7 +276,8 @@
 	}
 	if (zone)
 		spin_unlock_irq(&zone->lru_lock);
-	pagevec_release(pvec);
+	release_pages(pvec->pages, pvec->nr, pvec->cold);
+	pagevec_reinit(pvec);
 }
 
 void __pagevec_lru_add_active(struct pagevec *pvec)
@@ -250,7 +303,8 @@
 	}
 	if (zone)
 		spin_unlock_irq(&zone->lru_lock);
-	pagevec_release(pvec);
+	release_pages(pvec->pages, pvec->nr, pvec->cold);
+	pagevec_reinit(pvec);
 }
 
 /*
diff -Nru a/mm/swap_state.c b/mm/swap_state.c
--- a/mm/swap_state.c	Mon Dec  9 18:46:36 2002
+++ b/mm/swap_state.c	Mon Dec  9 18:46:36 2002
@@ -120,6 +120,7 @@
 {
 	swp_entry_t entry;
 	int pf_flags;
+	int err;
 
 	if (!PageLocked(page))
 		BUG();
@@ -149,9 +150,15 @@
 		/*
 		 * Add it to the swap cache and mark it dirty
 		 */
-		switch (add_to_page_cache(page, &swapper_space, entry.val)) {
+		err = add_to_page_cache(page, &swapper_space, entry.val);
+
+		if (!(pf_flags & PF_NOWARN))
+			current->flags &= ~PF_NOWARN;
+		if (pf_flags & PF_MEMALLOC)
+			current->flags |= PF_MEMALLOC;
+
+		switch (err) {
 		case 0:				/* Success */
-			current->flags = pf_flags;
 			SetPageUptodate(page);
 			ClearPageDirty(page);
 			set_page_dirty(page);
@@ -159,13 +166,11 @@
 			return 1;
 		case -EEXIST:
 			/* Raced with "speculative" read_swap_cache_async */
-			current->flags = pf_flags;
 			INC_CACHE_INFO(exist_race);
 			swap_free(entry);
 			continue;
 		default:
 			/* -ENOMEM radix-tree allocation failure */
-			current->flags = pf_flags;
 			swap_free(entry);
 			return 0;
 		}
@@ -295,6 +300,7 @@
 	const int chunk = 16;
 	struct page **pagep = pages;
 
+	lru_add_drain();
 	while (nr) {
 		int todo = min(chunk, nr);
 		int i;
diff -Nru a/mm/truncate.c b/mm/truncate.c
--- a/mm/truncate.c	Mon Dec  9 18:46:51 2002
+++ b/mm/truncate.c	Mon Dec  9 18:46:51 2002
@@ -115,6 +115,9 @@
 	pgoff_t next;
 	int i;
 
+	if (mapping->nrpages == 0)
+		return;
+
 	pagevec_init(&pvec, 0);
 	next = start;
 	while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
diff -Nru a/mm/vmscan.c b/mm/vmscan.c
--- a/mm/vmscan.c	Mon Dec  9 18:46:35 2002
+++ b/mm/vmscan.c	Mon Dec  9 18:46:35 2002
@@ -238,17 +238,8 @@
 		may_enter_fs = (gfp_mask & __GFP_FS) ||
 				(PageSwapCache(page) && (gfp_mask & __GFP_IO));
 
-		/*
-		 * If the page is mapped into pagetables then wait on it, to
-		 * throttle this allocator to the rate at which we can clear
-		 * MAP_SHARED data.  This will also throttle against swapcache
-		 * writes.
-		 */
-		if (PageWriteback(page)) {
-			if (may_enter_fs && page_mapped(page))
-				wait_on_page_writeback(page);
+		if (PageWriteback(page))
 			goto keep_locked;
-		}
 
 		pte_chain_lock(page);
 		if (page_referenced(page) && page_mapping_inuse(page)) {
@@ -318,6 +309,8 @@
 				goto keep_locked;
 			if (!mapping)
 				goto keep_locked;
+			if (mapping->a_ops->writepage == fail_writepage)
+				goto activate_locked;
 			if (!may_enter_fs)
 				goto keep_locked;
 			bdi = mapping->backing_dev_info;
@@ -325,12 +318,25 @@
 					bdi_write_congested(bdi))
 				goto keep_locked;
 			if (test_clear_page_dirty(page)) {
+				int res;
+
 				write_lock(&mapping->page_lock);
 				list_move(&page->list, &mapping->locked_pages);
 				write_unlock(&mapping->page_lock);
 
-				if (mapping->a_ops->writepage(page) == -EAGAIN)
+				SetPageReclaim(page);
+				res = mapping->a_ops->writepage(page);
+
+				if (res == -EAGAIN) {
+					ClearPageReclaim(page);
 					__set_page_dirty_nobuffers(page);
+				} else if (!PageWriteback(page)) {
+					/*
+					 * synchronous writeout or broken
+					 * a_ops?
+					 */
+					ClearPageReclaim(page);
+				}
 				goto keep;
 			}
 		}
@@ -358,7 +364,7 @@
 		 */
 		if (PagePrivate(page)) {
 			if (!try_to_release_page(page, gfp_mask))
-				goto keep_locked;
+				goto activate_locked;
 			if (!mapping && page_count(page) == 1)
 				goto free_it;
 		}
diff -Nru a/net/802/tr.c b/net/802/tr.c
--- a/net/802/tr.c	Mon Dec  9 18:46:34 2002
+++ b/net/802/tr.c	Mon Dec  9 18:46:34 2002
@@ -465,6 +465,7 @@
 	off_t pos=0;
 	int size,i,j,rcf_len,segment,brdgnmb;
 	unsigned long now=jiffies;
+	unsigned long flags;
 
 	rif_cache entry;
 
@@ -473,7 +474,7 @@
 	pos+=size;
 	len+=size;
 
-	spin_lock_bh(&rif_lock);
+	spin_lock_irqsave(&rif_lock,flags);
 	for(i=0;i < RIF_TABLE_SIZE;i++) 
 	{
 		for(entry=rif_table[i];entry;entry=entry->next) {
@@ -522,7 +523,7 @@
 		if(pos>offset+length)
 			break;
 	}
-	spin_unlock_bh(&rif_lock);
+	spin_unlock_irqrestore(&rif_lock,flags);
 
 	*start=buffer+(offset-begin); /* Start of wanted data */
 	len-=(offset-begin);    /* Start slop */
diff -Nru a/net/atm/mpc.c b/net/atm/mpc.c
--- a/net/atm/mpc.c	Mon Dec  9 18:46:50 2002
+++ b/net/atm/mpc.c	Mon Dec  9 18:46:50 2002
@@ -736,23 +736,15 @@
 }
 
 static struct atmdev_ops mpc_ops = { /* only send is required */
-	.close =mpoad_close,
-	.send =	msg_from_mpoad
+	.close	= mpoad_close,
+	.send	= msg_from_mpoad
 };
 
 static struct atm_dev mpc_dev = {
-	&mpc_ops,       /* device operations    */
-	NULL,           /* PHY operations       */
-	"mpc",          /* device type name     */
-	42,             /* device index (dummy) */
-	NULL,           /* VCC table            */
-	NULL,           /* last VCC             */
-	NULL,           /* per-device data      */
-	NULL,           /* private PHY data     */
-	{ 0 },          /* device flags         */
-	NULL,           /* local ATM address    */
-	{ 0 }           /* no ESI               */
-	/* rest of the members will be 0 */
+	.ops	= &mpc_ops,
+	.type	= "mpc",
+	.number	= 42,
+	/* members not explicitely initialised will be 0 */
 };
 
 int atm_mpoa_mpoad_attach (struct atm_vcc *vcc, int arg)
diff -Nru a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
--- a/net/ax25/ax25_route.c	Mon Dec  9 18:46:50 2002
+++ b/net/ax25/ax25_route.c	Mon Dec  9 18:46:50 2002
@@ -18,7 +18,6 @@
 #include <linux/in.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/timer.h>
 #include <linux/string.h>
 #include <linux/sockios.h>
 #include <linux/net.h>
diff -Nru a/net/bridge/br_if.c b/net/bridge/br_if.c
--- a/net/bridge/br_if.c	Mon Dec  9 18:46:51 2002
+++ b/net/bridge/br_if.c	Mon Dec  9 18:46:51 2002
@@ -145,7 +145,7 @@
 	int i;
 	struct net_bridge_port *p;
 
-	p = kmalloc(sizeof(*p), GFP_KERNEL);
+	p = kmalloc(sizeof(*p), GFP_ATOMIC);
 	if (p == NULL)
 		return p;
 
diff -Nru a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
--- a/net/bridge/br_netfilter.c	Mon Dec  9 18:46:51 2002
+++ b/net/bridge/br_netfilter.c	Mon Dec  9 18:46:51 2002
@@ -4,7 +4,7 @@
  *
  *	Authors:
  *	Lennert Buytenhek               <buytenh@gnu.org>
- *	Bart De Schuymer		<bart.de.schuymer@pandora.be>
+ *	Bart De Schuymer		<bdschuym@pandora.be>
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
@@ -49,20 +49,20 @@
  * require us to fill additional fields.
  */
 static struct net_device __fake_net_device = {
-	hard_header_len:	ETH_HLEN
+	.hard_header_len	= ETH_HLEN
 };
 
 static struct rtable __fake_rtable = {
-	u: {
-		dst: {
-			__refcnt:		ATOMIC_INIT(1),
-			dev:			&__fake_net_device,
-			path:			&__fake_rtable.u.dst,
-			metrics:		{[RTAX_MTU] 1500},
+	.u = {
+		.dst = {
+			.__refcnt		= ATOMIC_INIT(1),
+			.dev			= &__fake_net_device,
+			.path			= &__fake_rtable.u.dst,
+			.metrics		= {[RTAX_MTU - 1] = 1500},
 		}
 	},
 
-	rt_flags:	0
+	.rt_flags	= 0
 };
 
 
@@ -328,10 +328,7 @@
 /* This is the 'purely bridged' case.  We pass the packet to
  * netfilter with indev and outdev set to the bridge device,
  * but we are still able to filter on the 'real' indev/outdev
- * because another bit of the bridge-nf patch overloads the
- * '-i' and '-o' iptables interface checks to take
- * skb->phys{in,out}dev into account as well (so both the real
- * device and the bridge device will match).
+ * because of the ipt_physdev.c module.
  */
 static unsigned int br_nf_forward(unsigned int hook, struct sk_buff **pskb,
    const struct net_device *in, const struct net_device *out,
@@ -379,11 +376,10 @@
 /* This function sees both locally originated IP packets and forwarded
  * IP packets (in both cases the destination device is a bridge
  * device). It also sees bridged-and-DNAT'ed packets.
- * For the sake of interface transparency (i.e. properly
- * overloading the '-o' option), we steal packets destined to
- * a bridge device away from the PF_INET/FORWARD and PF_INET/OUTPUT hook
- * functions, and give them back later, when we have determined the real
- * output device. This is done in here.
+ * To be able to filter on the physical bridge devices (with the ipt_physdev.c
+ * module), we steal packets destined to a bridge device away from the
+ * PF_INET/FORWARD and PF_INET/OUTPUT hook functions, and give them back later,
+ * when we have determined the real output device. This is done in here.
  *
  * If (nf_bridge->mask & BRNF_BRIDGED_DNAT) then the packet is bridged
  * and we fake the PF_BRIDGE/FORWARD hook. The function br_nf_forward()
diff -Nru a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
--- a/net/bridge/netfilter/Kconfig	Mon Dec  9 18:46:35 2002
+++ b/net/bridge/netfilter/Kconfig	Mon Dec  9 18:46:35 2002
@@ -70,7 +70,7 @@
 	  <file:Documentation/modules.txt>.  If unsure, say `N'.
 
 config BRIDGE_EBT_VLANF
-	tristate "ebt: 802.1Q VLAN filter support (EXPERIMENTAL)"
+	tristate "ebt: 802.1Q VLAN filter support"
 	depends on BRIDGE_NF_EBTABLES
 	help
 	  This option adds the 802.1Q vlan match, which allows the filtering of
diff -Nru a/net/bridge/netfilter/ebt_vlan.c b/net/bridge/netfilter/ebt_vlan.c
--- a/net/bridge/netfilter/ebt_vlan.c	Mon Dec  9 18:46:38 2002
+++ b/net/bridge/netfilter/ebt_vlan.c	Mon Dec  9 18:46:38 2002
@@ -25,17 +25,17 @@
 #include <linux/netfilter_bridge/ebt_vlan.h>
 
 static unsigned char debug;
-#define MODULE_VERSION "0.4 (" __DATE__ " " __TIME__ ")"
+#define MODULE_VERSION "0.6"
 
-MODULE_PARM (debug, "0-1b");
-MODULE_PARM_DESC (debug, "debug=1 is turn on debug messages");
-MODULE_AUTHOR ("Nick Fedchik <nick@fedchik.org.ua>");
-MODULE_DESCRIPTION ("802.1Q match module (ebtables extension), v"
-		    MODULE_VERSION);
-MODULE_LICENSE ("GPL");
+MODULE_PARM(debug, "0-1b");
+MODULE_PARM_DESC(debug, "debug=1 is turn on debug messages");
+MODULE_AUTHOR("Nick Fedchik <nick@fedchik.org.ua>");
+MODULE_DESCRIPTION("802.1Q match module (ebtables extension), v"
+		   MODULE_VERSION);
+MODULE_LICENSE("GPL");
 
 
-#define DEBUG_MSG(...) if (debug) printk (KERN_DEBUG __FILE__ ":" __VA_ARGS__)
+#define DEBUG_MSG(...) if (debug) printk (KERN_DEBUG "ebt_vlan: " __VA_ARGS__)
 #define INV_FLAG(_inv_flag_) (info->invflags & _inv_flag_) ? "!" : ""
 #define GET_BITMASK(_BIT_MASK_) info->bitmask & _BIT_MASK_
 #define SET_BITMASK(_BIT_MASK_) info->bitmask |= _BIT_MASK_
@@ -59,11 +59,10 @@
  * 1 - miss (rule params not acceptable to the parsed frame)
  */
 static int
-ebt_filter_vlan (const struct sk_buff *skb,
-		 const struct net_device *in,
-		 const struct net_device *out,
-		 const void *data,
-		 unsigned int datalen)
+ebt_filter_vlan(const struct sk_buff *skb,
+		const struct net_device *in,
+		const struct net_device *out,
+		const void *data, unsigned int datalen)
 {
 	struct ebt_vlan_info *info = (struct ebt_vlan_info *) data;	/* userspace data */
 	struct vlan_ethhdr *frame = (struct vlan_ethhdr *) skb->mac.raw;	/* Passed tagged frame */
@@ -75,62 +74,35 @@
 
 	/*
 	 * Tag Control Information (TCI) consists of the following elements:
-	 * - User_priority. This field allows the tagged frame to carry user_priority
-	 * information across Bridged LANs in which individual LAN segments may be unable to signal
-	 * priority information (e.g., 802.3/Ethernet segments). 
-	 * The user_priority field is three bits in length, 
-	 * interpreted as a binary number. The user_priority is therefore
-	 * capable of representing eight priority levels, 0 through 7. 
-	 * The use and interpretation of this field is defined in ISO/IEC 15802-3.
-	 * - Canonical Format Indicator (CFI). This field is used,
-	 * in 802.3/Ethernet, to signal the presence or absence
-	 * of a RIF field, and, in combination with the Non-canonical Format Indicator (NCFI) carried
-	 * in the RIF, to signal the bit order of address information carried in the encapsulated
-	 * frame. The Canonical Format Indicator (CFI) is a single bit flag value.
-	 * - VLAN Identifier (VID). This field uniquely identifies the VLAN to
-	 * which the frame belongs. The twelve-bit VLAN Identifier (VID) field 
-	 * uniquely identify the VLAN to which the frame belongs. 
-	 * The VID is encoded as an unsigned binary number. 
-	 */
-	TCI = ntohs (frame->h_vlan_TCI);
-	id = TCI & 0xFFF;
-	prio = TCI >> 13;
+	 * - User_priority. The user_priority field is three bits in length, 
+	 * interpreted as a binary number. 
+	 * - Canonical Format Indicator (CFI). The Canonical Format Indicator 
+	 * (CFI) is a single bit flag value. Currently ignored.
+	 * - VLAN Identifier (VID). The VID is encoded as 
+	 * an unsigned binary number. 
+	 */
+	TCI = ntohs(frame->h_vlan_TCI);
+	id = TCI & VLAN_VID_MASK;
+	prio = (TCI >> 13) & 0x7;
 	encap = frame->h_vlan_encapsulated_proto;
 
 	/*
-	 * First step is to check is null VLAN ID present
-	 * in the parsed frame
+	 * Checking VLAN Identifier (VID)
 	 */
-	if (!(id)) {
-		/*
-		 * Checking VLAN Identifier (VID)
-		 */
-		if (GET_BITMASK (EBT_VLAN_ID)) {	/* Is VLAN ID parsed? */
-			EXIT_ON_MISMATCH (id, EBT_VLAN_ID);
-			DEBUG_MSG
-			    ("matched rule id=%s%d for frame id=%d\n",
-			     INV_FLAG (EBT_VLAN_ID), info->id, id);
-		}
-	} else {
-		/*
-		 * Checking user_priority
-		 */
-		if (GET_BITMASK (EBT_VLAN_PRIO)) {	/* Is VLAN user_priority parsed? */
-			EXIT_ON_MISMATCH (prio, EBT_VLAN_PRIO);
-			DEBUG_MSG
-			    ("matched rule prio=%s%d for frame prio=%d\n",
-			     INV_FLAG (EBT_VLAN_PRIO), info->prio,
-			     prio);
-		}
+	if (GET_BITMASK(EBT_VLAN_ID)) {	/* Is VLAN ID parsed? */
+		EXIT_ON_MISMATCH(id, EBT_VLAN_ID);
+	}
+	/*
+	 * Checking user_priority
+	 */
+	if (GET_BITMASK(EBT_VLAN_PRIO)) {	/* Is VLAN user_priority parsed? */
+		EXIT_ON_MISMATCH(prio, EBT_VLAN_PRIO);
 	}
 	/*
 	 * Checking Encapsulated Proto (Length/Type) field
 	 */
-	if (GET_BITMASK (EBT_VLAN_ENCAP)) {	/* Is VLAN Encap parsed? */
-		EXIT_ON_MISMATCH (encap, EBT_VLAN_ENCAP);
-		DEBUG_MSG ("matched encap=%s%2.4X for frame encap=%2.4X\n",
-			   INV_FLAG (EBT_VLAN_ENCAP),
-			   ntohs (info->encap), ntohs (encap));
+	if (GET_BITMASK(EBT_VLAN_ENCAP)) {	/* Is VLAN Encap parsed? */
+		EXIT_ON_MISMATCH(encap, EBT_VLAN_ENCAP);
 	}
 	/*
 	 * All possible extension parameters was parsed.
@@ -141,7 +113,7 @@
 
 /*
  * Function description: ebt_vlan_check() is called when userspace 
- * delivers the table to the kernel, 
+ * delivers the table entry to the kernel, 
  * and to check that userspace doesn't give a bad table.
  * Parameters:
  * const char *tablename - table name string
@@ -154,29 +126,29 @@
  * 1 - miss (rule params is out of range, invalid, incompatible, etc.)
  */
 static int
-ebt_check_vlan (const char *tablename,
-		unsigned int hooknr,
-		const struct ebt_entry *e, void *data,
-		unsigned int datalen)
+ebt_check_vlan(const char *tablename,
+	       unsigned int hooknr,
+	       const struct ebt_entry *e, void *data, unsigned int datalen)
 {
 	struct ebt_vlan_info *info = (struct ebt_vlan_info *) data;
 
 	/*
 	 * Parameters buffer overflow check 
 	 */
-	if (datalen != sizeof (struct ebt_vlan_info)) {
+	if (datalen != sizeof(struct ebt_vlan_info)) {
 		DEBUG_MSG
-		    ("params size %d is not eq to ebt_vlan_info (%d)\n",
-		     datalen, sizeof (struct ebt_vlan_info));
+		    ("passed size %d is not eq to ebt_vlan_info (%d)\n",
+		     datalen, sizeof(struct ebt_vlan_info));
 		return -EINVAL;
 	}
 
 	/*
 	 * Is it 802.1Q frame checked?
 	 */
-	if (e->ethproto != __constant_htons (ETH_P_8021Q)) {
-		DEBUG_MSG ("passed entry proto %2.4X is not 802.1Q (8100)\n",
-			   (unsigned short) ntohs (e->ethproto));
+	if (e->ethproto != __constant_htons(ETH_P_8021Q)) {
+		DEBUG_MSG
+		    ("passed entry proto %2.4X is not 802.1Q (8100)\n",
+		     (unsigned short) ntohs(e->ethproto));
 		return -EINVAL;
 	}
 
@@ -185,8 +157,8 @@
 	 * True if even one bit is out of mask
 	 */
 	if (info->bitmask & ~EBT_VLAN_MASK) {
-		DEBUG_MSG ("bitmask %2X is out of mask (%2X)\n",
-			   info->bitmask, EBT_VLAN_MASK);
+		DEBUG_MSG("bitmask %2X is out of mask (%2X)\n",
+			  info->bitmask, EBT_VLAN_MASK);
 		return -EINVAL;
 	}
 
@@ -194,91 +166,62 @@
 	 * Check for inversion flags range 
 	 */
 	if (info->invflags & ~EBT_VLAN_MASK) {
-		DEBUG_MSG ("inversion flags %2X is out of mask (%2X)\n",
-			   info->invflags, EBT_VLAN_MASK);
+		DEBUG_MSG("inversion flags %2X is out of mask (%2X)\n",
+			  info->invflags, EBT_VLAN_MASK);
 		return -EINVAL;
 	}
 
 	/*
 	 * Reserved VLAN ID (VID) values
 	 * -----------------------------
-	 * 0 - The null VLAN ID. Indicates that the tag header contains only user_priority information;
-	 * no VLAN identifier is present in the frame. This VID value shall not be
-	 * configured as a PVID, configured in any Filtering Database entry, or used in any
-	 * Management operation.
-	 * 
-	 * 1 - The default Port VID (PVID) value used for classifying frames on ingress through a Bridge
-	 * Port. The PVID value can be changed by management on a per-Port basis.
-	 * 
-	 * 0x0FFF - Reserved for implementation use. This VID value shall not be configured as a
-	 * PVID or transmitted in a tag header.
-	 * 
-	 * The remaining values of VID are available for general use as VLAN identifiers.
-	 * A Bridge may implement the ability to support less than the full range of VID values; 
-	 * i.e., for a given implementation,
-	 * an upper limit, N, is defined for the VID values supported, where N is less than or equal to 4094.
-	 * All implementations shall support the use of all VID values in the range 0 through their defined maximum
-	 * VID, N.
-	 * 
-	 * For Linux, N = 4094.
+	 * 0 - The null VLAN ID. 
+	 * 1 - The default Port VID (PVID)
+	 * 0x0FFF - Reserved for implementation use. 
+	 * if_vlan.h: VLAN_GROUP_ARRAY_LEN 4096.
 	 */
-	if (GET_BITMASK (EBT_VLAN_ID)) {	/* when vlan-id param was spec-ed */
+	if (GET_BITMASK(EBT_VLAN_ID)) {	/* when vlan-id param was spec-ed */
 		if (!!info->id) {	/* if id!=0 => check vid range */
-			if (info->id > 4094) {	/* check if id > than (0x0FFE) */
+			if (info->id > VLAN_GROUP_ARRAY_LEN) {
 				DEBUG_MSG
-				    ("vlan id %d is out of range (1-4094)\n",
+				    ("id %d is out of range (1-4096)\n",
 				     info->id);
 				return -EINVAL;
 			}
 			/*
 			 * Note: This is valid VLAN-tagged frame point.
-			 * Any value of user_priority are acceptable, but could be ignored
-			 * according to 802.1Q Std.
-			 */
-		} else {
-			/*
-			 * if id=0 (null VLAN ID)  => Check for user_priority range 
-			 */
-			if (GET_BITMASK (EBT_VLAN_PRIO)) {
-				if ((unsigned char) info->prio > 7) {
-					DEBUG_MSG
-					    ("prio %d is out of range (0-7)\n",
-					     info->prio);
-					return -EINVAL;
-				}
-			}
-			/*
-			 * Note2: This is valid priority-tagged frame point
-			 * with null VID field.
+			 * Any value of user_priority are acceptable, 
+			 * but should be ignored according to 802.1Q Std.
+			 * So we just drop the prio flag. 
 			 */
+			info->bitmask &= ~EBT_VLAN_PRIO;
 		}
-	} else {		/* VLAN Id not set */
-		if (GET_BITMASK (EBT_VLAN_PRIO)) {	/* But user_priority is set - abnormal! */
-			info->id = 0;	/* Set null VID (case for Priority-tagged frames) */
-			SET_BITMASK (EBT_VLAN_ID);	/* and set id flag */
+		/*
+		 * Else, id=0 (null VLAN ID)  => user_priority range (any?)
+		 */
+	}
+
+	if (GET_BITMASK(EBT_VLAN_PRIO)) {
+		if ((unsigned char) info->prio > 7) {
+			DEBUG_MSG
+			    ("prio %d is out of range (0-7)\n",
+			     info->prio);
+			return -EINVAL;
 		}
 	}
 	/*
-	 * Check for encapsulated proto range - it is possible to be any value for u_short range.
-	 * When relaying a tagged frame between 802.3/Ethernet MACs, 
-	 * a Bridge may adjust the padding field such that
-	 * the minimum size of a transmitted tagged frame is 68 octets (7.2).
+	 * Check for encapsulated proto range - it is possible to be 
+	 * any value for u_short range.
 	 * if_ether.h:  ETH_ZLEN        60   -  Min. octets in frame sans FCS
 	 */
-	if (GET_BITMASK (EBT_VLAN_ENCAP)) {
-		if ((unsigned short) ntohs (info->encap) < ETH_ZLEN) {
+	if (GET_BITMASK(EBT_VLAN_ENCAP)) {
+		if ((unsigned short) ntohs(info->encap) < ETH_ZLEN) {
 			DEBUG_MSG
-			    ("encap packet length %d is less than minimal %d\n",
-			     ntohs (info->encap), ETH_ZLEN);
+			    ("encap frame length %d is less than minimal\n",
+			     ntohs(info->encap));
 			return -EINVAL;
 		}
 	}
 
-	/*
-	 * Otherwise is all correct 
-	 */
-	DEBUG_MSG ("802.1Q tagged frame checked (%s table, %d hook)\n",
-		   tablename, hooknr);
 	return 0;
 }
 
@@ -293,24 +236,22 @@
 
 /*
  * Module initialization function.
- * Called when module is loaded to kernelspace
  */
-static int __init init (void)
+static int __init init(void)
 {
-	DEBUG_MSG ("ebtables 802.1Q extension module v"
-		   MODULE_VERSION "\n");
-	DEBUG_MSG ("module debug=%d\n", !!debug);
-	return ebt_register_match (&filter_vlan);
+	DEBUG_MSG("ebtables 802.1Q extension module v"
+		  MODULE_VERSION "\n");
+	DEBUG_MSG("module debug=%d\n", !!debug);
+	return ebt_register_match(&filter_vlan);
 }
 
 /*
  * Module "finalization" function
- * Called when download module from kernelspace
  */
-static void __exit fini (void)
+static void __exit fini(void)
 {
-	ebt_unregister_match (&filter_vlan);
+	ebt_unregister_match(&filter_vlan);
 }
 
-module_init (init);
-module_exit (fini);
+module_init(init);
+module_exit(fini);
diff -Nru a/net/core/Makefile b/net/core/Makefile
--- a/net/core/Makefile	Mon Dec  9 18:46:51 2002
+++ b/net/core/Makefile	Mon Dec  9 18:46:51 2002
@@ -12,7 +12,7 @@
 
 obj-$(CONFIG_FILTER) += filter.o
 
-obj-$(CONFIG_NET) += dev.o dev_mcast.o dst.o neighbour.o rtnetlink.o utils.o
+obj-$(CONFIG_NET) += dev.o dev_mcast.o dst.o neighbour.o rtnetlink.o utils.o link_watch.o
 
 obj-$(CONFIG_NETFILTER) += netfilter.o
 obj-$(CONFIG_NET_DIVERT) += dv.o
diff -Nru a/net/core/dev.c b/net/core/dev.c
--- a/net/core/dev.c	Mon Dec  9 18:46:37 2002
+++ b/net/core/dev.c	Mon Dec  9 18:46:37 2002
@@ -94,6 +94,7 @@
 #include <net/sock.h>
 #include <linux/rtnetlink.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/stat.h>
 #include <linux/if_bridge.h>
 #include <linux/divert.h>
@@ -114,6 +115,7 @@
 extern int plip_init(void);
 #endif
 
+#include <asm/current.h>
 
 /* This define, if set, will randomly drop a packet when congestion
  * is more than moderate.  It helps fairness in the multi-interface
@@ -262,6 +264,7 @@
 	br_write_unlock_bh(BR_NETPROTO_LOCK);
 }
 
+extern void linkwatch_run_queue(void);
 
 /**
  *	dev_remove_pack	 - remove packet handler
@@ -1719,128 +1722,196 @@
 	return copy_to_user(arg, &ifc, sizeof(struct ifconf)) ? -EFAULT : 0;
 }
 
+#ifdef CONFIG_PROC_FS
 /*
  *	This is invoked by the /proc filesystem handler to display a device
  *	in detail.
  */
+static __inline__ struct net_device *dev_get_idx(struct seq_file *seq,
+						 loff_t pos)
+{
+	struct net_device *dev;
+	loff_t i;
 
-#ifdef CONFIG_PROC_FS
+	for (i = 0, dev = dev_base; dev && i < pos; dev = dev->next);
+
+	return i == pos ? dev : NULL;
+}
+
+void *dev_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	read_lock(&dev_base_lock);
+	return *pos ? dev_get_idx(seq, *pos) : (void *)1;
+}
 
-static int sprintf_stats(char *buffer, struct net_device *dev)
+void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	return v == (void *)1 ? dev_base : ((struct net_device *)v)->next;
+}
+
+void dev_seq_stop(struct seq_file *seq, void *v)
+{
+	read_unlock(&dev_base_lock);
+}
+
+static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
 {
 	struct net_device_stats *stats = dev->get_stats ? dev->get_stats(dev) :
 							  NULL;
-	int size;
-
 	if (stats)
-		size = sprintf(buffer, "%6s:%8lu %7lu %4lu %4lu %4lu %5lu "
-				       "%10lu %9lu %8lu %7lu %4lu %4lu %4lu "
-				       "%5lu %7lu %10lu\n",
- 		   dev->name,
-		   stats->rx_bytes,
-		   stats->rx_packets, stats->rx_errors,
-		   stats->rx_dropped + stats->rx_missed_errors,
-		   stats->rx_fifo_errors,
-		   stats->rx_length_errors + stats->rx_over_errors +
-		   	stats->rx_crc_errors + stats->rx_frame_errors,
-		   stats->rx_compressed, stats->multicast,
-		   stats->tx_bytes,
-		   stats->tx_packets, stats->tx_errors, stats->tx_dropped,
-		   stats->tx_fifo_errors, stats->collisions,
-		   stats->tx_carrier_errors + stats->tx_aborted_errors +
-		   	stats->tx_window_errors + stats->tx_heartbeat_errors,
-		   stats->tx_compressed);
+		seq_printf(seq, "%6s:%8lu %7lu %4lu %4lu %4lu %5lu %10lu %9lu "
+				"%8lu %7lu %4lu %4lu %4lu %5lu %7lu %10lu\n",
+			   dev->name, stats->rx_bytes, stats->rx_packets,
+			   stats->rx_errors,
+			   stats->rx_dropped + stats->rx_missed_errors,
+			   stats->rx_fifo_errors,
+			   stats->rx_length_errors + stats->rx_over_errors +
+			     stats->rx_crc_errors + stats->rx_frame_errors,
+			   stats->rx_compressed, stats->multicast,
+			   stats->tx_bytes, stats->tx_packets,
+			   stats->tx_errors, stats->tx_dropped,
+			   stats->tx_fifo_errors, stats->collisions,
+			   stats->tx_carrier_errors +
+			     stats->tx_aborted_errors +
+			     stats->tx_window_errors +
+			     stats->tx_heartbeat_errors,
+			   stats->tx_compressed);
 	else
-		size = sprintf(buffer, "%6s: No statistics available.\n",
-			       dev->name);
-
-	return size;
+		seq_printf(seq, "%6s: No statistics available.\n", dev->name);
 }
 
 /*
  *	Called from the PROCfs module. This now uses the new arbitrary sized
  *	/proc/net interface to create /proc/net/dev
  */
-static int dev_get_info(char *buffer, char **start, off_t offset, int length)
+static int dev_seq_show(struct seq_file *seq, void *v)
 {
-	int len = 0;
-	off_t begin = 0;
-	off_t pos = 0;
-	int size;
-	struct net_device *dev;
-
-	size = sprintf(buffer,
-		"Inter-|   Receive                                                |  Transmit\n"
-		" face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed\n");
+	if (v == (void *)1)
+		seq_printf(seq, "Inter-|   Receive                            "
+				"                    |  Transmit\n"
+				" face |bytes    packets errs drop fifo frame "
+				"compressed multicast|bytes    packets errs "
+				"drop fifo colls carrier compressed\n");
+	else
+		dev_seq_printf_stats(seq, v);
+	return 0;
+}
 
-	pos += size;
-	len += size;
+static struct netif_rx_stats *softnet_get_online(loff_t *pos)
+{
+	struct netif_rx_stats *rc = NULL;
 
-	read_lock(&dev_base_lock);
-	for (dev = dev_base; dev; dev = dev->next) {
-		size = sprintf_stats(buffer+len, dev);
-		len += size;
-		pos = begin + len;
-
-		if (pos < offset) {
-			len = 0;
-			begin = pos;
-		}
-		if (pos > offset + length)
+	while (*pos < NR_CPUS)
+	       	if (cpu_online(*pos)) {
+			rc = &netdev_rx_stat[*pos];
 			break;
-	}
-	read_unlock(&dev_base_lock);
+		} else
+			++*pos;
+	return rc;
+}
 
-	*start = buffer + (offset - begin);	/* Start of wanted data */
-	len -= offset - begin;			/* Start slop */
-	if (len > length)
-		len = length;			/* Ending slop */
-	if (len < 0)
-		len = 0;
-	return len;
+static void *softnet_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	return softnet_get_online(pos);
 }
 
-static int dev_proc_stats(char *buffer, char **start, off_t offset,
-			  int length, int *eof, void *data)
+static void *softnet_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-	int i;
-	int len = 0;
+	++*pos;
+	return softnet_get_online(pos);
+}
 
-	for (i = 0; i < NR_CPUS; i++) {
-		if (!cpu_online(i))
-			continue;
+static void softnet_seq_stop(struct seq_file *seq, void *v)
+{
+}
+
+static int softnet_seq_show(struct seq_file *seq, void *v)
+{
+	struct netif_rx_stats *s = v;
 
-		len += sprintf(buffer + len, "%08x %08x %08x %08x %08x %08x "
-					     "%08x %08x %08x\n",
-			       netdev_rx_stat[i].total,
-			       netdev_rx_stat[i].dropped,
-			       netdev_rx_stat[i].time_squeeze,
-			       netdev_rx_stat[i].throttled,
-			       netdev_rx_stat[i].fastroute_hit,
-			       netdev_rx_stat[i].fastroute_success,
-			       netdev_rx_stat[i].fastroute_defer,
-			       netdev_rx_stat[i].fastroute_deferred_out,
+	seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x %08x\n",
+		   s->total, s->dropped, s->time_squeeze, s->throttled,
+		   s->fastroute_hit, s->fastroute_success, s->fastroute_defer,
+		   s->fastroute_deferred_out,
 #if 0
-			       netdev_rx_stat[i].fastroute_latency_reduction
+		   s->fastroute_latency_reduction
 #else
-			       netdev_rx_stat[i].cpu_collision
+		   s->cpu_collision
 #endif
-			       );
-	}
+		  );
+	return 0;
+}
+
+static struct seq_operations dev_seq_ops = {
+	.start = dev_seq_start,
+	.next  = dev_seq_next,
+	.stop  = dev_seq_stop,
+	.show  = dev_seq_show,
+};
 
-	len -= offset;
+static int dev_seq_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &dev_seq_ops);
+}
 
-	if (len > length)
-		len = length;
-	if (len < 0)
-		len = 0;
+static struct file_operations dev_seq_fops = {
+	.open    = dev_seq_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = seq_release,
+};
 
-	*start = buffer + offset;
-	*eof = 1;
+static struct seq_operations softnet_seq_ops = {
+	.start = softnet_seq_start,
+	.next  = softnet_seq_next,
+	.stop  = softnet_seq_stop,
+	.show  = softnet_seq_show,
+};
 
-	return len;
+static int softnet_seq_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &softnet_seq_ops);
 }
 
+static struct file_operations softnet_seq_fops = {
+	.open    = softnet_seq_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = seq_release,
+};
+
+#ifdef WIRELESS_EXT
+extern int wireless_proc_init(void);
+#else
+#define wireless_proc_init() 0
+#endif
+
+static int __init dev_proc_init(void)
+{
+	struct proc_dir_entry *p;
+	int rc = -ENOMEM;
+
+	p = create_proc_entry("dev", S_IRUGO, proc_net);
+	if (!p)
+		goto out;
+	p->proc_fops = &dev_seq_fops;
+	p = create_proc_entry("softnet_stat", S_IRUGO, proc_net);
+	if (!p)
+		goto out_dev;
+	p->proc_fops = &softnet_seq_fops;
+	if (wireless_proc_init())
+		goto out_softnet;
+	rc = 0;
+out:
+	return rc;
+out_softnet:
+	remove_proc_entry("softnet_stat", proc_net);
+out_dev:
+	remove_proc_entry("dev", proc_net);
+	goto out;
+}
+#else
+#define dev_proc_init() 0
 #endif	/* CONFIG_PROC_FS */
 
 
@@ -2642,6 +2713,15 @@
 			/* Rebroadcast unregister notification */
 			notifier_call_chain(&netdev_chain,
 					    NETDEV_UNREGISTER, dev);
+
+			if (test_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state)) {
+				/* We must not have linkwatch events pending
+				 * on unregister. If this happens, we simply
+				 * run the queue unscheduled, resulting in a
+				 * noop for this device
+				 */
+				linkwatch_run_queue();
+			}
 		}
 		current->state = TASK_INTERRUPTIBLE;
 		schedule_timeout(HZ / 4);
@@ -2680,10 +2760,13 @@
 static int __init net_dev_init(void)
 {
 	struct net_device *dev, **dp;
-	int i;
+	int i, rc = -ENOMEM;
 
 	BUG_ON(!dev_boot_phase);
 
+	if (dev_proc_init())
+		goto out;
+
 #ifdef CONFIG_NET_DIVERT
 	dv_init();
 #endif /* CONFIG_NET_DIVERT */
@@ -2787,15 +2870,6 @@
 		}
 	}
 
-#ifdef CONFIG_PROC_FS
-	proc_net_create("dev", 0, dev_get_info);
-	create_proc_read_entry("net/softnet_stat", 0, 0, dev_proc_stats, NULL);
-#ifdef WIRELESS_EXT
-	/* Available in net/core/wireless.c */
-	proc_net_create("wireless", 0, dev_get_wireless_info);
-#endif	/* WIRELESS_EXT */
-#endif	/* CONFIG_PROC_FS */
-
 	dev_boot_phase = 0;
 
 	open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL);
@@ -2812,8 +2886,9 @@
 	 */
 
 	net_device_init();
-
-	return 0;
+	rc = 0;
+out:
+	return rc;
 }
 
 subsys_initcall(net_dev_init);
diff -Nru a/net/core/link_watch.c b/net/core/link_watch.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/core/link_watch.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,134 @@
+/*
+ * Linux network device link state notifaction
+ *
+ * Author:
+ *     Stefan Rompf <sux@loplof.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/workqueue.h>
+#include <linux/config.h>
+#include <linux/netdevice.h>
+#include <linux/if.h>
+#include <linux/rtnetlink.h>
+#include <linux/jiffies.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <asm/bitops.h>
+#include <asm/types.h>
+
+
+enum lw_bits {
+	LW_RUNNING = 0,
+	LW_SE_USED
+};
+
+static unsigned long linkwatch_flags = 0;
+static unsigned long linkwatch_nextevent = 0;
+
+static void linkwatch_event(void *dummy);
+static DECLARE_WORK(linkwatch_work, linkwatch_event, NULL);
+
+static LIST_HEAD(lweventlist);
+static spinlock_t lweventlist_lock = SPIN_LOCK_UNLOCKED;
+
+struct lw_event {
+	struct list_head list;
+	struct net_device *dev;
+};
+
+/* Avoid kmalloc() for most systems */
+static struct lw_event singleevent;
+
+/* Must be called with the rtnl semaphore held */
+void linkwatch_run_queue(void) {
+	LIST_HEAD(head);
+	struct list_head *n, *next;
+
+	spin_lock_irq(&lweventlist_lock);
+	list_splice_init(&lweventlist, &head);
+	spin_unlock_irq(&lweventlist_lock);
+
+	list_for_each_safe(n, next, &head) {
+		struct lw_event *event = list_entry(n, struct lw_event, list);
+		struct net_device *dev = event->dev;
+
+		if (event == &singleevent) {
+			clear_bit(LW_SE_USED, &linkwatch_flags);
+		} else {
+			kfree(event);
+		}
+
+		/* We are about to handle this device,
+		 * so new events can be accepted
+		 */
+		clear_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state);
+
+		if (dev->flags & IFF_UP) {
+			netdev_state_change(dev);
+		}
+
+		dev_put(dev);
+	}
+}       
+
+
+static void linkwatch_event(void *dummy)
+{
+	/* Limit the number of linkwatch events to one
+	 * per second so that a runaway driver does not
+	 * cause a storm of messages on the netlink
+	 * socket
+	 */	
+	linkwatch_nextevent = jiffies + HZ;
+	clear_bit(LW_RUNNING, &linkwatch_flags);
+
+	rtnl_lock();
+	linkwatch_run_queue();
+	rtnl_unlock();
+}
+
+
+void linkwatch_fire_event(struct net_device *dev)
+{
+	if (!test_and_set_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state)) {
+		unsigned long flags;
+		struct lw_event *event;
+
+		if (test_and_set_bit(LW_SE_USED, &linkwatch_flags)) {
+			event = kmalloc(sizeof(struct lw_event), GFP_ATOMIC);
+
+			if (unlikely(event == NULL)) {
+				clear_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state);
+				return;
+			}
+		} else {
+			event = &singleevent;
+		}
+
+		dev_hold(dev);
+		event->dev = dev;
+
+		spin_lock_irqsave(&lweventlist_lock, flags);
+		list_add_tail(&event->list, &lweventlist);
+		spin_unlock_irqrestore(&lweventlist_lock, flags);
+
+		if (!test_and_set_bit(LW_RUNNING, &linkwatch_flags)) {
+			unsigned long thisevent = jiffies;
+
+			if (thisevent >= linkwatch_nextevent) {
+				schedule_work(&linkwatch_work);
+			} else {
+				schedule_delayed_work(&linkwatch_work, linkwatch_nextevent - thisevent);
+			}
+		}
+	}
+}
+
diff -Nru a/net/core/scm.c b/net/core/scm.c
--- a/net/core/scm.c	Mon Dec  9 18:46:36 2002
+++ b/net/core/scm.c	Mon Dec  9 18:46:36 2002
@@ -217,7 +217,8 @@
 	for (i=0, cmfptr=(int*)CMSG_DATA(cm); i<fdmax; i++, cmfptr++)
 	{
 		int new_fd;
-		if ((err = security_file_receive(fp[i])))
+		err = security_file_receive(fp[i]);
+		if (err)
 			break;
 		err = get_unused_fd();
 		if (err < 0)
diff -Nru a/net/core/wireless.c b/net/core/wireless.c
--- a/net/core/wireless.c	Mon Dec  9 18:46:50 2002
+++ b/net/core/wireless.c	Mon Dec  9 18:46:50 2002
@@ -47,15 +47,18 @@
 
 /***************************** INCLUDES *****************************/
 
-#include <asm/uaccess.h>		/* copy_to_user() */
 #include <linux/config.h>		/* Not needed ??? */
 #include <linux/types.h>		/* off_t */
 #include <linux/netdevice.h>		/* struct ifreq, dev_get_by_name() */
+#include <linux/proc_fs.h>
 #include <linux/rtnetlink.h>		/* rtnetlink stuff */
-
+#include <linux/seq_file.h>
 #include <linux/wireless.h>		/* Pretty obvious */
+
 #include <net/iw_handler.h>		/* New driver API */
 
+#include <asm/uaccess.h>		/* copy_to_user() */
+
 /**************************** CONSTANTS ****************************/
 
 /* Enough lenience, let's make sure things are proper... */
@@ -330,83 +333,78 @@
 /*
  * Print one entry (line) of /proc/net/wireless
  */
-static inline int sprintf_wireless_stats(char *buffer, struct net_device *dev)
+static __inline__ void wireless_seq_printf_stats(struct seq_file *seq,
+						 struct net_device *dev)
 {
 	/* Get stats from the driver */
-	struct iw_statistics *stats;
-	int size;
+	struct iw_statistics *stats = get_wireless_stats(dev);
 
-	stats = get_wireless_stats(dev);
-	if (stats != (struct iw_statistics *) NULL) {
-		size = sprintf(buffer,
-			       "%6s: %04x  %3d%c  %3d%c  %3d%c  %6d %6d %6d %6d %6d   %6d\n",
-			       dev->name,
-			       stats->status,
-			       stats->qual.qual,
-			       stats->qual.updated & 1 ? '.' : ' ',
-			       ((__u8) stats->qual.level),
-			       stats->qual.updated & 2 ? '.' : ' ',
-			       ((__u8) stats->qual.noise),
-			       stats->qual.updated & 4 ? '.' : ' ',
-			       stats->discard.nwid,
-			       stats->discard.code,
-			       stats->discard.fragment,
-			       stats->discard.retries,
-			       stats->discard.misc,
-			       stats->miss.beacon);
+	if (stats) {
+		seq_printf(seq, "%6s: %04x  %3d%c  %3d%c  %3d%c  %6d %6d %6d "
+				"%6d %6d   %6d\n",
+			   dev->name, stats->status, stats->qual.qual,
+			   stats->qual.updated & 1 ? '.' : ' ',
+			   ((__u8) stats->qual.level),
+			   stats->qual.updated & 2 ? '.' : ' ',
+			   ((__u8) stats->qual.noise),
+			   stats->qual.updated & 4 ? '.' : ' ',
+			   stats->discard.nwid, stats->discard.code,
+			   stats->discard.fragment, stats->discard.retries,
+			   stats->discard.misc, stats->miss.beacon);
 		stats->qual.updated = 0;
 	}
-	else
-		size = 0;
-
-	return size;
 }
 
 /* ---------------------------------------------------------------- */
 /*
  * Print info for /proc/net/wireless (print all entries)
  */
-int dev_get_wireless_info(char * buffer, char **start, off_t offset,
-			  int length)
+static int wireless_seq_show(struct seq_file *seq, void *v)
 {
-	int		len = 0;
-	off_t		begin = 0;
-	off_t		pos = 0;
-	int		size;
-	
-	struct net_device *	dev;
-
-	size = sprintf(buffer,
-		       "Inter-| sta-|   Quality        |   Discarded packets               | Missed\n"
-		       " face | tus | link level noise |  nwid  crypt   frag  retry   misc | beacon\n"
-			);
-	
-	pos += size;
-	len += size;
-
-	read_lock(&dev_base_lock);
-	for (dev = dev_base; dev != NULL; dev = dev->next) {
-		size = sprintf_wireless_stats(buffer + len, dev);
-		len += size;
-		pos = begin + len;
-
-		if (pos < offset) {
-			len = 0;
-			begin = pos;
-		}
-		if (pos > offset + length)
-			break;
-	}
-	read_unlock(&dev_base_lock);
+	if (v == (void *)1)
+		seq_printf(seq, "Inter-| sta-|   Quality        |   Discarded "
+				"packets               | Missed\n"
+				" face | tus | link level noise |  nwid  "
+				"crypt   frag  retry   misc | beacon\n");
+	else
+		wireless_seq_printf_stats(seq, v);
+	return 0;
+}
 
-	*start = buffer + (offset - begin);	/* Start of wanted data */
-	len -= (offset - begin);		/* Start slop */
-	if (len > length)
-		len = length;			/* Ending slop */
-	if (len < 0)
-		len = 0;
+extern void *dev_seq_start(struct seq_file *seq, loff_t *pos);
+extern void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos);
+extern void dev_seq_stop(struct seq_file *seq, void *v);
+
+static struct seq_operations wireless_seq_ops = {
+	.start = dev_seq_start,
+	.next  = dev_seq_next,
+	.stop  = dev_seq_stop,
+	.show  = wireless_seq_show,
+};
 
-	return len;
+static int wireless_seq_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &wireless_seq_ops);
+}
+
+static struct file_operations wireless_seq_fops = {
+	.open    = wireless_seq_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = seq_release,
+};
+
+int __init wireless_proc_init(void)
+{
+	struct proc_dir_entry *p;
+	int rc = 0;
+
+	p = create_proc_entry("wireless", S_IRUGO, proc_net);
+	if (p)
+		p->proc_fops = &wireless_seq_fops;
+	else
+		rc = -ENOMEM;
+	return rc;
 }
 #endif	/* CONFIG_PROC_FS */
 
diff -Nru a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
--- a/net/ipv4/af_inet.c	Mon Dec  9 18:46:35 2002
+++ b/net/ipv4/af_inet.c	Mon Dec  9 18:46:35 2002
@@ -103,8 +103,6 @@
 #include <net/tcp.h>
 #include <net/udp.h>
 #include <linux/skbuff.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
 #include <net/sock.h>
 #include <net/raw.h>
 #include <net/icmp.h>
@@ -1165,7 +1163,8 @@
 extern int  ip_misc_proc_init(void);
 extern int  raw_proc_init(void);
 extern void raw_proc_exit(void);
-extern int  tcp_get_info(char *buffer, char **start, off_t offset, int length);
+extern int  tcp_proc_init(void);
+extern void tcp_proc_exit(void);
 extern int  udp_proc_init(void);
 extern void udp_proc_exit(void);
 
@@ -1175,7 +1174,7 @@
 
 	if (raw_proc_init())
 		goto out_raw;
-	if (!proc_net_create("tcp", 0, tcp_get_info))
+	if (tcp_proc_init())
 		goto out_tcp;
 	if (udp_proc_init())
 		goto out_udp;
@@ -1190,7 +1189,7 @@
 out_fib:
 	udp_proc_exit();
 out_udp:
-	proc_net_remove("tcp");
+	tcp_proc_exit();
 out_tcp:
 	raw_proc_exit();
 out_raw:
diff -Nru a/net/ipv4/arp.c b/net/ipv4/arp.c
--- a/net/ipv4/arp.c	Mon Dec  9 18:46:51 2002
+++ b/net/ipv4/arp.c	Mon Dec  9 18:46:51 2002
@@ -1282,7 +1282,7 @@
 {
 	struct arp_iter_state* state = seq->private;
 
-	if (!state->is_pneigh)
+	if (!state->is_pneigh && v != (void *)1)
 		read_unlock_bh(&arp_tbl.lock);
 }
 
diff -Nru a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
--- a/net/ipv4/inetpeer.c	Mon Dec  9 18:46:51 2002
+++ b/net/ipv4/inetpeer.c	Mon Dec  9 18:46:51 2002
@@ -75,9 +75,9 @@
 
 #define node_height(x) x->avl_height
 static struct inet_peer peer_fake_node = {
-	avl_left : &peer_fake_node,
-	avl_right : &peer_fake_node,
-	avl_height : 0
+	.avl_left	= &peer_fake_node,
+	.avl_right	= &peer_fake_node,
+	.avl_height	= 0
 };
 #define peer_avl_empty (&peer_fake_node)
 static struct inet_peer *peer_root = peer_avl_empty;
diff -Nru a/net/ipv4/raw.c b/net/ipv4/raw.c
--- a/net/ipv4/raw.c	Mon Dec  9 18:46:34 2002
+++ b/net/ipv4/raw.c	Mon Dec  9 18:46:34 2002
@@ -55,6 +55,7 @@
 #include <linux/sockios.h>
 #include <linux/socket.h>
 #include <linux/in.h>
+#include <linux/mroute.h>
 #include <linux/netdevice.h>
 #include <linux/in_route.h>
 #include <linux/route.h>
diff -Nru a/net/ipv4/route.c b/net/ipv4/route.c
--- a/net/ipv4/route.c	Mon Dec  9 18:46:52 2002
+++ b/net/ipv4/route.c	Mon Dec  9 18:46:52 2002
@@ -53,6 +53,7 @@
  *	Vladimir V. Ivanov	:	IP rule info (flowid) is really useful.
  *		Marc Boucher	:	routing by fwmark
  *	Robert Olsson		:	Added rt_cache statistics
+ *	Arnaldo C. Melo		:	Convert proc stuff to seq_file
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
@@ -208,74 +209,107 @@
 	return (hash ^ (hash >> 8)) & rt_hash_mask;
 }
 
-static int rt_cache_get_info(char *buffer, char **start, off_t offset,
-				int length)
+#ifdef CONFIG_PROC_FS
+struct rt_cache_iter_state {
+	int bucket;
+};
+
+static struct rtable *rt_cache_get_first(struct seq_file *seq)
 {
-	int len = 0;
-	off_t pos = 128;
-	char temp[256];
-	struct rtable *r;
-	int i;
+	struct rtable *r = NULL;
+	struct rt_cache_iter_state *st = seq->private;
 
-	if (offset < 128) {
-		sprintf(buffer, "%-127s\n",
-			"Iface\tDestination\tGateway \tFlags\t\tRefCnt\tUse\t"
-			"Metric\tSource\t\tMTU\tWindow\tIRTT\tTOS\tHHRef\t"
-			"HHUptod\tSpecDst");
-		len = 128;
-  	}
-	
-	for (i = rt_hash_mask; i >= 0; i--) {
-		read_lock_bh(&rt_hash_table[i].lock);
-		for (r = rt_hash_table[i].chain; r; r = r->u.rt_next) {
-			/*
-			 *	Spin through entries until we are ready
-			 */
-			pos += 128;
+	for (st->bucket = rt_hash_mask; st->bucket >= 0; --st->bucket) {
+		read_lock_bh(&rt_hash_table[st->bucket].lock);
+		r = rt_hash_table[st->bucket].chain;
+		if (r)
+			break;
+		read_unlock_bh(&rt_hash_table[st->bucket].lock);
+	}
+	return r;
+}
 
-			if (pos <= offset) {
-				len = 0;
-				continue;
-			}
-			sprintf(temp, "%s\t%08lX\t%08lX\t%8X\t%d\t%u\t%d\t"
-				"%08lX\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X",
-				r->u.dst.dev ? r->u.dst.dev->name : "*",
-				(unsigned long)r->rt_dst,
-				(unsigned long)r->rt_gateway,
-				r->rt_flags,
-				atomic_read(&r->u.dst.__refcnt),
-				r->u.dst.__use,
-				0,
-				(unsigned long)r->rt_src,
-				(dst_metric(&r->u.dst, RTAX_ADVMSS) ?
-				 (int) dst_metric(&r->u.dst, RTAX_ADVMSS) + 40 : 0),
-				dst_metric(&r->u.dst, RTAX_WINDOW),
-				(int)((dst_metric(&r->u.dst, RTAX_RTT) >> 3)
-				      + dst_metric(&r->u.dst, RTAX_RTTVAR)),
-				r->fl.fl4_tos,
-				r->u.dst.hh ?
-					atomic_read(&r->u.dst.hh->hh_refcnt) :
-					-1,
-				r->u.dst.hh ?
-			       		(r->u.dst.hh->hh_output ==
-					 dev_queue_xmit) : 0,
-				r->rt_spec_dst);
-			sprintf(buffer + len, "%-127s\n", temp);
-			len += 128;
-			if (pos >= offset+length) {
-				read_unlock_bh(&rt_hash_table[i].lock);
-				goto done;
-			}
-		}
-		read_unlock_bh(&rt_hash_table[i].lock);
-        }
+static struct rtable *rt_cache_get_next(struct seq_file *seq, struct rtable *r)
+{
+	struct rt_cache_iter_state *st = seq->private;
 
-done:
-  	*start = buffer + len - (pos - offset);
-  	len = pos - offset;
-  	if (len > length)
-  		len = length;
-  	return len;
+	r = r->u.rt_next;
+	while (!r) {
+		read_unlock_bh(&rt_hash_table[st->bucket].lock);
+		if (--st->bucket < 0)
+			break;
+		read_lock_bh(&rt_hash_table[st->bucket].lock);
+		r = rt_hash_table[st->bucket].chain;
+	}
+	return r;
+}
+
+static struct rtable *rt_cache_get_idx(struct seq_file *seq, loff_t pos)
+{
+	struct rtable *r = rt_cache_get_first(seq);
+
+	if (r)
+		while (pos && (r = rt_cache_get_next(seq, r)))
+			--pos;
+	return pos ? NULL : r;
+}
+
+static void *rt_cache_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	return *pos ? rt_cache_get_idx(seq, *pos) : (void *)1;
+}
+
+static void *rt_cache_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	struct rtable *r = NULL;
+
+	if (v == (void *)1)
+		r = rt_cache_get_first(seq);
+	else
+		r = rt_cache_get_next(seq, v);
+	++*pos;
+	return r;
+}
+
+static void rt_cache_seq_stop(struct seq_file *seq, void *v)
+{
+	if (v && v != (void *)1) {
+		struct rt_cache_iter_state *st = seq->private;
+
+		read_unlock_bh(&rt_hash_table[st->bucket].lock);
+	}
+}
+
+static int rt_cache_seq_show(struct seq_file *seq, void *v)
+{
+	if (v == (void *)1)
+		seq_printf(seq, "%-127s\n",
+			   "Iface\tDestination\tGateway \tFlags\t\tRefCnt\tUse\t"
+			   "Metric\tSource\t\tMTU\tWindow\tIRTT\tTOS\tHHRef\t"
+			   "HHUptod\tSpecDst");
+	else {
+		struct rtable *r = v;
+		char temp[256];
+
+		sprintf(temp, "%s\t%08lX\t%08lX\t%8X\t%d\t%u\t%d\t"
+			      "%08lX\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X",
+			r->u.dst.dev ? r->u.dst.dev->name : "*",
+			(unsigned long)r->rt_dst, (unsigned long)r->rt_gateway,
+			r->rt_flags, atomic_read(&r->u.dst.__refcnt),
+			r->u.dst.__use, 0, (unsigned long)r->rt_src,
+			(dst_metric(&r->u.dst, RTAX_ADVMSS) ?
+			     (int)dst_metric(&r->u.dst, RTAX_ADVMSS) + 40 : 0),
+			dst_metric(&r->u.dst, RTAX_WINDOW),
+			(int)((dst_metric(&r->u.dst, RTAX_RTT) >> 3) +
+			      dst_metric(&r->u.dst, RTAX_RTTVAR)),
+			r->fl.fl4_tos,
+			r->u.dst.hh ? atomic_read(&r->u.dst.hh->hh_refcnt) : -1,
+			r->u.dst.hh ? (r->u.dst.hh->hh_output ==
+				       dev_queue_xmit) : 0,
+			r->rt_spec_dst);
+		seq_printf(seq, "%-127s\n", temp);
+        }
+  	return 0;
 }
 
 static int rt_cache_stat_get_info(char *buffer, char **start, off_t offset, int length)
@@ -316,6 +350,59 @@
 	*start = buffer + offset;
   	return len;
 }
+
+static struct seq_operations rt_cache_seq_ops = {
+	.start  = rt_cache_seq_start,
+	.next   = rt_cache_seq_next,
+	.stop   = rt_cache_seq_stop,
+	.show   = rt_cache_seq_show,
+};
+
+static int rt_cache_seq_open(struct inode *inode, struct file *file)
+{
+	struct seq_file *seq;
+	int rc = -ENOMEM;
+	struct rt_cache_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+
+	if (!s)
+		goto out;
+	rc = seq_open(file, &rt_cache_seq_ops);
+	if (rc)
+		goto out_kfree;
+	seq          = file->private_data;
+	seq->private = s;
+	memset(s, 0, sizeof(*s));
+out:
+	return rc;
+out_kfree:
+	kfree(s);
+	goto out;
+}
+
+static struct file_operations rt_cache_seq_fops = {
+	.open	 = rt_cache_seq_open,
+	.read	 = seq_read,
+	.llseek	 = seq_lseek,
+	.release = ip_seq_release,
+};
+
+int __init rt_cache_proc_init(void)
+{
+	int rc = 0;
+	struct proc_dir_entry *p = create_proc_entry("rt_cache", S_IRUGO,
+						     proc_net);
+	if (p)
+		p->proc_fops = &rt_cache_seq_fops;
+	else
+		rc = -ENOMEM;
+	return rc;
+}
+
+void __init rt_cache_proc_exit(void)
+{
+	remove_proc_entry("rt_cache", proc_net);
+}
+#endif /* CONFIG_PROC_FS */
   
 static __inline__ void rt_free(struct rtable *rt)
 {
@@ -2456,6 +2543,7 @@
 /* IP route accounting ptr for this logical cpu number. */
 #define IP_RT_ACCT_CPU(i) (ip_rt_acct + i * 256)
 
+#ifdef CONFIG_PROC_FS
 static int ip_rt_acct_read(char *buffer, char **start, off_t offset,
 			   int length, int *eof, void *data)
 {
@@ -2488,11 +2576,12 @@
 	}
 	return length;
 }
-#endif
+#endif /* CONFIG_PROC_FS */
+#endif /* CONFIG_NET_CLS_ROUTE */
 
-void __init ip_rt_init(void)
+int __init ip_rt_init(void)
 {
-	int i, order, goal;
+	int i, order, goal, rc = 0;
 
 #ifdef CONFIG_NET_CLS_ROUTE
 	for (order = 0;
@@ -2560,10 +2649,16 @@
 					ip_rt_gc_interval;
 	add_timer(&rt_periodic_timer);
 
-	proc_net_create ("rt_cache", 0, rt_cache_get_info);
+	if (rt_cache_proc_init())
+		goto out_enomem;
 	proc_net_create ("rt_cache_stat", 0, rt_cache_stat_get_info);
 #ifdef CONFIG_NET_CLS_ROUTE
 	create_proc_read_entry("net/rt_acct", 0, 0, ip_rt_acct_read, NULL);
 #endif
 	xfrm_init();
+out:
+	return rc;
+out_enomem:
+	rc = -ENOMEM;
+	goto out;
 }
diff -Nru a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
--- a/net/ipv4/tcp_ipv4.c	Mon Dec  9 18:46:35 2002
+++ b/net/ipv4/tcp_ipv4.c	Mon Dec  9 18:46:35 2002
@@ -69,6 +69,8 @@
 #include <linux/inet.h>
 #include <linux/ipv6.h>
 #include <linux/stddef.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 
 extern int sysctl_ip_dynaddr;
 extern int sysctl_ip_default_ttl;
@@ -2131,7 +2133,295 @@
 	return 0;
 }
 
+#ifdef CONFIG_PROC_FS
 /* Proc filesystem TCP sock list dumping. */
+
+enum tcp_seq_states {
+	TCP_SEQ_STATE_LISTENING,
+	TCP_SEQ_STATE_OPENREQ,
+	TCP_SEQ_STATE_ESTABLISHED,
+	TCP_SEQ_STATE_TIME_WAIT,
+};
+
+struct tcp_iter_state {
+	enum tcp_seq_states state;
+	struct sock	   *syn_wait_sk;
+	int		    bucket, sbucket, num, uid;
+};
+
+static void *listening_get_first(struct seq_file *seq)
+{
+	struct tcp_iter_state* st = seq->private;
+	void *rc = NULL;
+
+	for (st->bucket = 0; st->bucket < TCP_LHTABLE_SIZE; ++st->bucket) {
+		struct open_request *req;
+		struct tcp_opt *tp;
+		struct sock *sk = tcp_listening_hash[st->bucket];
+
+		if (!sk)
+			continue;
+		++st->num;
+		if (TCP_INET_FAMILY(sk->family)) {
+			rc = sk;
+			goto out;
+		}
+	       	tp = tcp_sk(sk);
+		read_lock_bh(&tp->syn_wait_lock);
+		if (tp->listen_opt && tp->listen_opt->qlen) {
+			st->uid		= sock_i_uid(sk);
+			st->syn_wait_sk = sk;
+			st->state	= TCP_SEQ_STATE_OPENREQ;
+			for (st->sbucket = 0; st->sbucket < TCP_SYNQ_HSIZE;
+			     ++st->sbucket) {
+				for (req = tp->listen_opt->syn_table[st->sbucket];
+				     req; req = req->dl_next, ++st->num) {
+					if (!TCP_INET_FAMILY(req->class->family))
+						continue;
+					rc = req;
+					goto out;
+				}
+			}
+			st->state = TCP_SEQ_STATE_LISTENING;
+		}
+		read_unlock_bh(&tp->syn_wait_lock);
+	}
+out:
+	return rc;
+}
+
+static void *listening_get_next(struct seq_file *seq, void *cur)
+{
+	struct tcp_opt *tp;
+	struct sock *sk = cur;
+	struct tcp_iter_state* st = seq->private;
+
+	if (st->state == TCP_SEQ_STATE_OPENREQ) {
+		struct open_request *req = cur;
+
+	       	tp = tcp_sk(st->syn_wait_sk);
+		req = req->dl_next;
+		while (1) {
+			while (req) {
+				++st->num;
+				if (TCP_INET_FAMILY(req->class->family)) {
+					cur = req;
+					goto out;
+				}
+				req = req->dl_next;
+			}
+			if (++st->sbucket >= TCP_SYNQ_HSIZE)
+				break;
+get_req:
+			req = tp->listen_opt->syn_table[st->sbucket];
+		}
+		sk	  = st->syn_wait_sk->next;
+		st->state = TCP_SEQ_STATE_LISTENING;
+		read_unlock_bh(&tp->syn_wait_lock);
+	} else
+		sk = sk->next;
+get_sk:
+	while (sk) {
+		if (TCP_INET_FAMILY(sk->family)) {
+			cur = sk;
+			goto out;
+		}
+	       	tp = tcp_sk(sk);
+		read_lock_bh(&tp->syn_wait_lock);
+		if (tp->listen_opt && tp->listen_opt->qlen) {
+			st->uid		= sock_i_uid(sk);
+			st->syn_wait_sk = sk;
+			st->state	= TCP_SEQ_STATE_OPENREQ;
+			st->sbucket	= 0;
+			goto get_req;
+		}
+		read_unlock_bh(&tp->syn_wait_lock);
+	}
+	if (++st->bucket < TCP_LHTABLE_SIZE) {
+		sk = tcp_listening_hash[st->bucket];
+		goto get_sk;
+	}
+	cur = NULL;
+out:
+	return cur;
+}
+
+static void *listening_get_idx(struct seq_file *seq, loff_t *pos)
+{
+	void *rc = listening_get_first(seq);
+
+	if (rc)
+		while (*pos && (rc = listening_get_next(seq, rc)))
+			--*pos;
+	return *pos ? NULL : rc;
+}
+
+static void *established_get_first(struct seq_file *seq)
+{
+	struct tcp_iter_state* st = seq->private;
+	void *rc = NULL;
+
+	for (st->bucket = 0; st->bucket < tcp_ehash_size; ++st->bucket) {
+		struct sock *sk;
+		struct tcp_tw_bucket *tw;
+	       
+		read_lock(&tcp_ehash[st->bucket].lock);
+		for (sk = tcp_ehash[st->bucket].chain; sk;
+		     sk = sk->next, ++st->num) {
+			if (!TCP_INET_FAMILY(sk->family))
+				continue;
+			rc = sk;
+			goto out;
+		}
+		st->state = TCP_SEQ_STATE_TIME_WAIT;
+		for (tw = (struct tcp_tw_bucket *)
+				tcp_ehash[st->bucket + tcp_ehash_size].chain;
+		     tw; tw = (struct tcp_tw_bucket *)tw->next, ++st->num) {
+			if (!TCP_INET_FAMILY(tw->family))
+				continue;
+			rc = tw;
+			goto out;
+		}
+		read_unlock(&tcp_ehash[st->bucket].lock);
+		st->state = TCP_SEQ_STATE_ESTABLISHED;
+	}
+out:
+	return rc;
+}
+
+static void *established_get_next(struct seq_file *seq, void *cur)
+{
+	struct sock *sk = cur;
+	struct tcp_tw_bucket *tw;
+	struct tcp_iter_state* st = seq->private;
+
+	if (st->state == TCP_SEQ_STATE_TIME_WAIT) {
+		tw = cur;
+		tw = (struct tcp_tw_bucket *)tw->next;
+get_tw:
+		while (tw && !TCP_INET_FAMILY(tw->family)) {
+			++st->num;
+			tw = (struct tcp_tw_bucket *)tw->next;
+		}
+		if (tw) {
+			cur = tw;
+			goto out;
+		}
+		read_unlock(&tcp_ehash[st->bucket].lock);
+		st->state = TCP_SEQ_STATE_ESTABLISHED;
+		if (++st->bucket < tcp_ehash_size) {
+			read_lock(&tcp_ehash[st->bucket].lock);
+			sk = tcp_ehash[st->bucket].chain;
+		} else {
+			cur = NULL;
+			goto out;
+		}
+	} else
+		sk = sk->next;
+
+	while (sk && !TCP_INET_FAMILY(sk->family)) {
+		++st->num;
+		sk = sk->next;
+	}
+	if (!sk) {
+		st->state = TCP_SEQ_STATE_TIME_WAIT;
+		tw = (struct tcp_tw_bucket *)
+				tcp_ehash[st->bucket + tcp_ehash_size].chain;
+		goto get_tw;
+	}
+	cur = sk;
+out:
+	return cur;
+}
+
+static void *established_get_idx(struct seq_file *seq, loff_t pos)
+{
+	void *rc = established_get_first(seq);
+
+	if (rc)
+		while (pos && (rc = established_get_next(seq, rc)))
+			--pos;
+	return pos ? NULL : rc;
+}
+
+static void *tcp_get_idx(struct seq_file *seq, loff_t pos)
+{
+	void *rc;
+	struct tcp_iter_state* st = seq->private;
+
+	tcp_listen_lock();
+	st->state = TCP_SEQ_STATE_LISTENING;
+	rc	  = listening_get_idx(seq, &pos);
+
+	if (!rc) {
+		tcp_listen_unlock();
+		local_bh_disable();
+		st->state = TCP_SEQ_STATE_ESTABLISHED;
+		rc	  = established_get_idx(seq, pos);
+	}
+
+	return rc;
+}
+
+static void *tcp_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	return *pos ? tcp_get_idx(seq, *pos - 1) : (void *)1;
+}
+
+static void *tcp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	void *rc = NULL;
+	struct tcp_iter_state* st;
+
+	if (v == (void *)1) {
+		rc = tcp_get_idx(seq, 0);
+		goto out;
+	}
+	st = seq->private;
+
+	switch (st->state) {
+	case TCP_SEQ_STATE_OPENREQ:
+	case TCP_SEQ_STATE_LISTENING:
+		rc = listening_get_next(seq, v);
+		if (!rc) {
+			tcp_listen_unlock();
+			local_bh_disable();
+			st->state = TCP_SEQ_STATE_ESTABLISHED;
+			rc	  = established_get_first(seq);
+		}
+		break;
+	case TCP_SEQ_STATE_ESTABLISHED:
+	case TCP_SEQ_STATE_TIME_WAIT:
+		rc = established_get_next(seq, v);
+		break;
+	}
+out:
+	++*pos;
+	return rc;
+}
+
+static void tcp_seq_stop(struct seq_file *seq, void *v)
+{
+	struct tcp_iter_state* st = seq->private;
+
+	switch (st->state) {
+	case TCP_SEQ_STATE_OPENREQ:
+		if (v) {
+			struct tcp_opt *tp = tcp_sk(st->syn_wait_sk);
+			read_unlock_bh(&tp->syn_wait_lock);
+		}
+	case TCP_SEQ_STATE_LISTENING:
+		tcp_listen_unlock();
+		break;
+	case TCP_SEQ_STATE_TIME_WAIT:
+	case TCP_SEQ_STATE_ESTABLISHED:
+		if (v)
+			read_unlock(&tcp_ehash[st->bucket].lock);
+		local_bh_enable();
+		break;
+	}
+}
+
 static void get_openreq(struct sock *sk, struct open_request *req,
 			char *tmpbuf, int i, int uid)
 {
@@ -2219,137 +2509,89 @@
 
 #define TMPSZ 150
 
-int tcp_get_info(char *buffer, char **start, off_t offset, int length)
+static int tcp_seq_show(struct seq_file *seq, void *v)
 {
-	int len = 0, num = 0, i;
-	off_t begin, pos = 0;
+	struct tcp_iter_state* st;
 	char tmpbuf[TMPSZ + 1];
 
-	if (offset < TMPSZ)
-		len += sprintf(buffer, "%-*s\n", TMPSZ - 1,
-			       "  sl  local_address rem_address   st tx_queue "
-			       "rx_queue tr tm->when retrnsmt   uid  timeout "
-			       "inode");
-
-	pos = TMPSZ;
-
-	/* First, walk listening socket table. */
-	tcp_listen_lock();
-	for (i = 0; i < TCP_LHTABLE_SIZE; i++) {
-		struct sock *sk;
-		struct tcp_listen_opt *lopt;
-		int k;
-
-		for (sk = tcp_listening_hash[i]; sk; sk = sk->next, num++) {
-			struct open_request *req;
-			int uid;
-			struct tcp_opt *tp = tcp_sk(sk);
-
-			if (!TCP_INET_FAMILY(sk->family))
-				goto skip_listen;
+	if (v == (void *)1) {
+		seq_printf(seq, "%-*s\n", TMPSZ - 1,
+			   "  sl  local_address rem_address   st tx_queue "
+			   "rx_queue tr tm->when retrnsmt   uid  timeout "
+			   "inode");
+		goto out;
+	}
+	st = seq->private;
 
-			pos += TMPSZ;
-			if (pos >= offset) {
-				get_tcp_sock(sk, tmpbuf, num);
-				len += sprintf(buffer + len, "%-*s\n",
-					       TMPSZ - 1, tmpbuf);
-				if (pos >= offset + length) {
-					tcp_listen_unlock();
-					goto out_no_bh;
-				}
-			}
+	switch (st->state) {
+	case TCP_SEQ_STATE_LISTENING:
+	case TCP_SEQ_STATE_ESTABLISHED:
+		get_tcp_sock(v, tmpbuf, st->num);
+		break;
+	case TCP_SEQ_STATE_OPENREQ:
+		get_openreq(st->syn_wait_sk, v, tmpbuf, st->num, st->uid);
+		break;
+	case TCP_SEQ_STATE_TIME_WAIT:
+		get_timewait_sock(v, tmpbuf, st->num);
+		break;
+	}
+	seq_printf(seq, "%-*s\n", TMPSZ - 1, tmpbuf);
+out:
+	return 0;
+}
 
-skip_listen:
-			uid = sock_i_uid(sk);
-			read_lock_bh(&tp->syn_wait_lock);
-			lopt = tp->listen_opt;
-			if (lopt && lopt->qlen) {
-				for (k = 0; k < TCP_SYNQ_HSIZE; k++) {
-					for (req = lopt->syn_table[k];
-					     req; req = req->dl_next, num++) {
-						if (!TCP_INET_FAMILY(req->class->family))
-							continue;
-
-						pos += TMPSZ;
-						if (pos <= offset)
-							continue;
-						get_openreq(sk, req, tmpbuf,
-							    num, uid);
-						len += sprintf(buffer + len,
-							       "%-*s\n",
-							       TMPSZ - 1,
-							       tmpbuf);
-						if (pos >= offset + length) {
-							read_unlock_bh(&tp->syn_wait_lock);
-							tcp_listen_unlock();
-							goto out_no_bh;
-						}
-					}
-				}
-			}
-			read_unlock_bh(&tp->syn_wait_lock);
+static struct seq_operations tcp_seq_ops = {
+	.start  = tcp_seq_start,
+	.next   = tcp_seq_next,
+	.stop   = tcp_seq_stop,
+	.show   = tcp_seq_show,
+};
 
-			/* Completed requests are in normal socket hash table */
-		}
-	}
-	tcp_listen_unlock();
+static int tcp_seq_open(struct inode *inode, struct file *file)
+{
+	struct seq_file *seq;
+	int rc = -ENOMEM;
+	struct tcp_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
 
-	local_bh_disable();
+	if (!s)
+		goto out;
+	rc = seq_open(file, &tcp_seq_ops);
+	if (rc)
+		goto out_kfree;
+	seq	     = file->private_data;
+	seq->private = s;
+	memset(s, 0, sizeof(*s));
+out:
+	return rc;
+out_kfree:
+	kfree(s);
+	goto out;
+}
 
-	/* Next, walk established hash chain. */
-	for (i = 0; i < tcp_ehash_size; i++) {
-		struct tcp_ehash_bucket *head = &tcp_ehash[i];
-		struct sock *sk;
-		struct tcp_tw_bucket *tw;
+static struct file_operations tcp_seq_fops = {
+	.open           = tcp_seq_open,
+	.read           = seq_read,
+	.llseek         = seq_lseek,
+	.release	= ip_seq_release,
+};
 
-		read_lock(&head->lock);
-		for (sk = head->chain; sk; sk = sk->next, num++) {
-			if (!TCP_INET_FAMILY(sk->family))
-				continue;
-			pos += TMPSZ;
-			if (pos <= offset)
-				continue;
-			get_tcp_sock(sk, tmpbuf, num);
-			len += sprintf(buffer + len, "%-*s\n",
-				       TMPSZ - 1, tmpbuf);
-			if (pos >= offset + length) {
-				read_unlock(&head->lock);
-				goto out;
-			}
-		}
-		for (tw = (struct tcp_tw_bucket *)tcp_ehash[i +
-							  tcp_ehash_size].chain;
-		     tw;
-		     tw = (struct tcp_tw_bucket *)tw->next, num++) {
-			if (!TCP_INET_FAMILY(tw->family))
-				continue;
-			pos += TMPSZ;
-			if (pos <= offset)
-				continue;
-			get_timewait_sock(tw, tmpbuf, num);
-			len += sprintf(buffer + len, "%-*s\n",
-				       TMPSZ - 1, tmpbuf);
-			if (pos >= offset + length) {
-				read_unlock(&head->lock);
-				goto out;
-			}
-		}
-		read_unlock(&head->lock);
-	}
+int __init tcp_proc_init(void)
+{
+	int rc = 0;
+	struct proc_dir_entry *p = create_proc_entry("tcp", S_IRUGO, proc_net);
 
-out:
-	local_bh_enable();
-out_no_bh:
+	if (p)
+		p->proc_fops = &tcp_seq_fops;
+	else
+		rc = -ENOMEM;
+	return rc;
+}
 
-	begin = len - (pos - offset);
-	*start = buffer + begin;
-	len -= begin;
-	if (len > length)
-		len = length;
-	if (len < 0)
-		len = 0;
-	return len;
+void __init tcp_proc_exit(void)
+{
+	remove_proc_entry("tcp", proc_net);
 }
+#endif /* CONFIG_PROC_FS */
 
 struct proto tcp_prot = {
 	.name =		"TCP",
diff -Nru a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
--- a/net/netlink/af_netlink.c	Mon Dec  9 18:46:37 2002
+++ b/net/netlink/af_netlink.c	Mon Dec  9 18:46:37 2002
@@ -281,8 +281,8 @@
 	skb_queue_purge(&sk->write_queue);
 
 	if (nlk->pid && !nlk->groups) {
-		struct netlink_notify n = { protocol:sk->protocol,
-		                            pid:nlk->pid };
+		struct netlink_notify n = { .protocol = sk->protocol,
+		                            .pid = nlk->pid };
 		notifier_call_chain(&netlink_chain, NETLINK_URELEASE, &n);
 	}	
 	
diff -Nru a/net/netlink/netlink_dev.c b/net/netlink/netlink_dev.c
--- a/net/netlink/netlink_dev.c	Mon Dec  9 18:46:36 2002
+++ b/net/netlink/netlink_dev.c	Mon Dec  9 18:46:36 2002
@@ -170,11 +170,21 @@
 	.release =	netlink_release,
 };
 
-static devfs_handle_t devfs_handle;
+static struct { char *name; int minor; } entries[] = {
+	{"route", 0},
+	{"skip", 1},
+	{"usersock", 2},
+	{"fwmonitor", 3},
+	{"tcpdiag", 4},
+	{"arpd", 8},
+	{"route6", 11},
+	{"ip6_fw", 13},
+	{"dnrtmsg", 13},
+};
 
 static void __init make_devfs_entries (const char *name, int minor)
 {
-	devfs_register (devfs_handle, name, DEVFS_FL_DEFAULT,
+	devfs_register (NULL, name, DEVFS_FL_DEFAULT,
 			NETLINK_MAJOR, minor,
 			S_IFCHR | S_IRUSR | S_IWUSR,
 			&netlink_fops, NULL);
@@ -182,25 +192,24 @@
 
 int __init init_netlink(void)
 {
+	int i;
+
 	if (register_chrdev(NETLINK_MAJOR,"netlink", &netlink_fops)) {
 		printk(KERN_ERR "netlink: unable to get major %d\n", NETLINK_MAJOR);
 		return -EIO;
 	}
-	devfs_handle = devfs_mk_dir (NULL, "netlink", NULL);
+	devfs_mk_dir (NULL, "netlink", NULL);
 	/*  Someone tell me the official names for the uppercase ones  */
-	make_devfs_entries ("route", 0);
-	make_devfs_entries ("skip", 1);
-	make_devfs_entries ("usersock", 2);
-	make_devfs_entries ("fwmonitor", 3);
-	make_devfs_entries ("tcpdiag", 4);
-	make_devfs_entries ("arpd", 8);
-	make_devfs_entries ("route6", 11);
-	make_devfs_entries ("ip6_fw", 13);
-	make_devfs_entries ("dnrtmsg", 13);
-	devfs_register_series (devfs_handle, "tap%u", 16, DEVFS_FL_DEFAULT,
-			       NETLINK_MAJOR, 16,
-			       S_IFCHR | S_IRUSR | S_IWUSR,
-			       &netlink_fops, NULL);
+	for (i = 0; i < sizeof(entries)/sizeof(entries[0]); i++) {
+		char name[20];
+		sprintf(name, "netlink/%s", entries[i].name);
+		make_devfs_entries(name, entries[i].minor);
+	}
+	for (i = 0; i < 16; i++) {
+		char name[20];
+		sprintf(name, "netlink/tap%d", i);
+		make_devfs_entries(name, i + 16);
+	}
 	return 0;
 }
 
@@ -216,7 +225,13 @@
 
 void cleanup_module(void)
 {
-	devfs_unregister (devfs_handle);
+	int i;
+
+	for (i = 0; i < sizeof(entries)/sizeof(entries[0]); i++)
+		devfs_remove("netlink/%s", entries[i].name);
+	for (i = 0; i < 16; i++)
+		devfs_remove("netlink/tap%d", i);
+	devfs_remove("netlink");
 	unregister_chrdev(NETLINK_MAJOR, "netlink");
 }
 
diff -Nru a/net/netsyms.c b/net/netsyms.c
--- a/net/netsyms.c	Mon Dec  9 18:46:36 2002
+++ b/net/netsyms.c	Mon Dec  9 18:46:36 2002
@@ -632,4 +632,6 @@
 EXPORT_SYMBOL(wireless_send_event);
 #endif	/* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */
 
+EXPORT_SYMBOL(linkwatch_fire_event);
+
 #endif  /* CONFIG_NET */
diff -Nru a/net/rxrpc/connection.c b/net/rxrpc/connection.c
--- a/net/rxrpc/connection.c	Mon Dec  9 18:46:38 2002
+++ b/net/rxrpc/connection.c	Mon Dec  9 18:46:38 2002
@@ -39,7 +39,7 @@
 }
 
 static const struct rxrpc_timer_ops rxrpc_conn_timer_ops = {
-	timed_out:	__rxrpc_conn_timeout,
+	.timed_out	= __rxrpc_conn_timeout,
 };
 
 /*****************************************************************************/
diff -Nru a/net/sched/sch_atm.c b/net/sched/sch_atm.c
--- a/net/sched/sch_atm.c	Mon Dec  9 18:46:36 2002
+++ b/net/sched/sch_atm.c	Mon Dec  9 18:46:36 2002
@@ -19,9 +19,6 @@
 
 
 extern struct socket *sockfd_lookup(int fd, int *err); /* @@@ fix this */
-#define sockfd_put(sock) fput((sock)->file)	/* @@@ copied because it's
-						   __inline__ in socket.c */
-
 
 #if 0 /* control */
 #define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
diff -Nru a/net/sched/sch_prio.c b/net/sched/sch_prio.c
--- a/net/sched/sch_prio.c	Mon Dec  9 18:46:36 2002
+++ b/net/sched/sch_prio.c	Mon Dec  9 18:46:36 2002
@@ -383,22 +383,22 @@
 
 struct Qdisc_ops prio_qdisc_ops =
 {
-	next:		NULL,
-	cl_ops:		&prio_class_ops,
-	id:		"prio",
-	priv_size:	sizeof(struct prio_sched_data),
+	.next		= NULL,
+	.cl_ops		= &prio_class_ops,
+	.id		= "prio",
+	.priv_size	= sizeof(struct prio_sched_data),
 
-	enqueue:	prio_enqueue,
-	dequeue:	prio_dequeue,
-	requeue:	prio_requeue,
-	drop:		prio_drop,
+	.enqueue	= prio_enqueue,
+	.dequeue	= prio_dequeue,
+	.requeue	= prio_requeue,
+	.drop		= prio_drop,
 
-	init:		prio_init,
-	reset:		prio_reset,
-	destroy:	prio_destroy,
-	change:		prio_tune,
+	.init		= prio_init,
+	.reset		= prio_reset,
+	.destroy	= prio_destroy,
+	.change		= prio_tune,
 
-	dump:		prio_dump,
+	.dump		= prio_dump,
 };
 
 #ifdef MODULE
diff -Nru a/net/sctp/output.c b/net/sctp/output.c
--- a/net/sctp/output.c	Mon Dec  9 18:46:35 2002
+++ b/net/sctp/output.c	Mon Dec  9 18:46:35 2002
@@ -56,7 +56,6 @@
 #endif /* TEST_FRAME (not defined) */
 
 #include <linux/socket.h> /* for sa_family_t */
-#include <linux/types.h> /* For NULL, etc... */
 #include <net/sock.h>
 
 #include <net/sctp/sctp.h>
diff -Nru a/net/sunrpc/svc.c b/net/sunrpc/svc.c
--- a/net/sunrpc/svc.c	Mon Dec  9 18:46:51 2002
+++ b/net/sunrpc/svc.c	Mon Dec  9 18:46:51 2002
@@ -398,7 +398,7 @@
 
 err_short_len:
 #ifdef RPC_PARANOIA
-	printk("svc: short len %d, dropping request\n", argv->iov_len);
+	printk("svc: short len %Zd, dropping request\n", argv->iov_len);
 #endif
 	goto dropit;			/* drop request */
 
diff -Nru a/scripts/Makefile b/scripts/Makefile
--- a/scripts/Makefile	Mon Dec  9 18:46:38 2002
+++ b/scripts/Makefile	Mon Dec  9 18:46:38 2002
@@ -8,31 +8,11 @@
 # docproc: 	 Preprocess .tmpl file in order to generate .sgml documentation
 # conmakehash:	 Create arrays for initializing the kernel console tables
 
-EXTRA_TARGETS := fixdep split-include docproc conmakehash
+host-progs    := fixdep split-include conmakehash docproc kallsyms
+build-targets := $(host-progs)
 
+# Let clean descend into subdirs
 subdir-	:= lxdialog kconfig
 
-# Yikes. We need to build this stuff here even if the user only wants
-# modules.
-
-KBUILD_BUILTIN := 1
-
-# The following temporary rule will make sure that people's
-# trees get updated to the right permissions, since patch(1)
-# can't do it
-# ---------------------------------------------------------------------------
-
-host-progs := fixdep split-include conmakehash docproc
-
-include $(TOPDIR)/Rules.make
-
-
-# ---------------------------------------------------------------------------
-# Targets hardcoded and wellknow in top-level makefile
-.PHONY: lxdialog
-lxdialog:
-	$(call descend,scripts/lxdialog,)
-
 # fixdep is needed to compile other host programs
-$(obj)/split-include $(obj)/docproc \
-$(obj)/conmakehash lxdialog: $(obj)/fixdep
+$(addprefix $(obj)/,$(filter-out fixdep,$(host-progs))): $(obj)/fixdep
diff -Nru a/scripts/Makefile.build b/scripts/Makefile.build
--- a/scripts/Makefile.build	Mon Dec  9 18:46:50 2002
+++ b/scripts/Makefile.build	Mon Dec  9 18:46:50 2002
@@ -40,12 +40,14 @@
 ifdef L_TARGET
 L_TARGET := $(obj)/$(L_TARGET)
 else
+ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-)),)
 O_TARGET := $(obj)/built-in.o
 endif
+endif
 
 __build: $(if $(KBUILD_BUILTIN),$(O_TARGET) $(L_TARGET) $(EXTRA_TARGETS)) \
-	 $(if $(KBUILD_MODULES),$(obj-m)) \
-	 $(subdir-ym)
+	 $(if $(KBUILD_MODULES),$(obj-m:.o=.ko)) \
+	 $(subdir-ym) $(build-targets)
 	@:
 
 # Compile C sources (.c)
@@ -103,7 +105,9 @@
 	$(call if_changed_dep,cc_o_c)
 
 quiet_cmd_cc_lst_c = MKLST   $@
-cmd_cc_lst_c       = $(CC) $(c_flags) -g -c -o $*.o $< && sh scripts/makelst $*.o System.map $(OBJDUMP) > $@
+      cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \
+		     $(CONFIG_SHELL) $(src)/scripts/makelst $*.o \
+				     System.map $(OBJDUMP) > $@
 
 %.lst: %.c FORCE
 	$(call if_changed_dep,cc_lst_c)
@@ -116,9 +120,6 @@
 $(real-objs-m)      : modkern_aflags := $(AFLAGS_MODULE)
 $(real-objs-m:.o=.s): modkern_aflags := $(AFLAGS_MODULE)
 
-a_flags = -Wp,-MD,$(depfile) $(AFLAGS) $(NOSTDINC_FLAGS) \
-	  $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o)
-
 quiet_cmd_as_s_S = CPP $(quiet_modtag) $@
 cmd_as_s_S       = $(CPP) $(a_flags)   -o $@ $< 
 
@@ -171,21 +172,29 @@
 #
 # Rule to link composite objects
 #
+quiet_cmd_link_multi-y = LD      $@
+cmd_link_multi-y = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -r -o $@ $(filter $(addprefix $(obj)/,$($(subst $(obj)/,,$(@:.o=-objs))) $($(subst $(obj)/,,$(@:.o=-y)))),$^)
 
-quiet_cmd_link_multi = LD $(quiet_modtag)  $@
-cmd_link_multi = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -r -o $@ $(filter $(addprefix $(obj)/,$($(subst $(obj)/,,$(@:.o=-objs))) $($(subst $(obj)/,,$(@:.o=-y)))),$^)
+quiet_cmd_link_multi-m = LD [M]  $@
+cmd_link_multi-m = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_MODULE) -o $@ $(filter $(addprefix $(obj)/,$($(subst $(obj)/,,$(@:.ko=-objs))) $($(subst $(obj)/,,$(@:.ko=-y)))),$^)
+
+quiet_cmd_link_single-m = LD [M]  $@
+cmd_link_single-m = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_MODULE) -o $@ $<
 
 # We would rather have a list of rules like
 # 	foo.o: $(foo-objs)
 # but that's not so easy, so we rather make all composite objects depend
 # on the set of all their parts
 $(multi-used-y) : %.o: $(multi-objs-y) FORCE
-	$(call if_changed,link_multi)
+	$(call if_changed,link_multi-y)
+
+$(multi-used-m:.o=.ko) : %.ko: $(multi-objs-m) FORCE
+	$(call if_changed,link_multi-m)
 
-$(multi-used-m) : %.o: $(multi-objs-m) FORCE
-	$(call if_changed,link_multi)
+$(single-used-m:.o=.ko) : %.ko: %.o FORCE
+	$(call if_changed,link_single-m)
 
-targets += $(multi-used-y) $(multi-used-m)
+targets += $(multi-used-y) $(multi-used-m:.o=.ko) $(single-used-m:.o=.ko)
 
 # Compile programs on the host
 # ===========================================================================
@@ -217,9 +226,7 @@
 # Create executable from a single .c file
 # host-csingle -> Executable
 quiet_cmd_host-csingle 	= HOSTCC  $@
-      cmd_host-csingle	= $(HOSTCC) -Wp,-MD,$(depfile) \
-			  $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) \
-			  $(HOST_LOADLIBES) -o $@ $<
+      cmd_host-csingle	= $(HOSTCC) $(hostc_flags) $(HOST_LOADLIBES) -o $@ $<
 $(host-csingle): %: %.c FORCE
 	$(call if_changed_dep,host-csingle)
 
@@ -235,9 +242,7 @@
 # Create .o file from a single .c file
 # host-cobjs -> .o
 quiet_cmd_host-cobjs	= HOSTCC  $@
-      cmd_host-cobjs	= $(HOSTCC) -Wp,-MD,$(depfile) \
-			  $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) \
-			  $(HOSTCFLAGS_$(@F)) -c -o $@ $<
+      cmd_host-cobjs	= $(HOSTCC) $(hostc_flags) -c -o $@ $<
 $(host-cobjs): %.o: %.c FORCE
 	$(call if_changed_dep,host-cobjs)
 
@@ -253,18 +258,14 @@
 
 # Create .o file from a single .cc (C++) file
 quiet_cmd_host-cxxobjs	= HOSTCXX $@
-      cmd_host-cxxobjs	= $(HOSTCXX) -Wp,-MD,$(depfile) \
-			  $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \
-			  $(HOSTCXXFLAGS_$(@F)) -c -o $@ $<
+      cmd_host-cxxobjs	= $(HOSTCXX) $(hostcxx_flags) -c -o $@ $<
 $(host-cxxobjs): %.o: %.cc FORCE
 	$(call if_changed_dep,host-cxxobjs)
 
 # Compile .c file, create position independent .o file
 # host-cshobjs -> .o
 quiet_cmd_host-cshobjs	= HOSTCC  -fPIC $@
-      cmd_host-cshobjs	= $(HOSTCC) -Wp,-MD,$(depfile) -fPIC\
-			  $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) \
-			  $(HOSTCFLAGS_$(@F)) -c -o $@ $<
+      cmd_host-cshobjs	= $(HOSTCC) $(hostc_flags) -fPIC -c -o $@ $<
 $(host-cshobjs): %.o: %.c FORCE
 	$(call if_changed_dep,host-cshobjs)
 
diff -Nru a/scripts/Makefile.lib b/scripts/Makefile.lib
--- a/scripts/Makefile.lib	Mon Dec  9 18:46:37 2002
+++ b/scripts/Makefile.lib	Mon Dec  9 18:46:37 2002
@@ -43,6 +43,7 @@
 multi-used-y := $(sort $(foreach m,$(__obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m))))
 multi-used-m := $(sort $(foreach m,$(__obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m))))
 multi-used   := $(multi-used-y) $(multi-used-m)
+single-used-m := $(sort $(filter-out $(multi-used-m),$(obj-m)))
 
 # Build list of the parts of our composite objects, our composite
 # objects depend on those (obviously)
@@ -92,12 +93,14 @@
 # Add subdir path
 
 EXTRA_TARGETS	:= $(addprefix $(obj)/,$(EXTRA_TARGETS))
+build-targets	:= $(addprefix $(obj)/,$(build-targets))
 obj-y		:= $(addprefix $(obj)/,$(obj-y))
 obj-m		:= $(addprefix $(obj)/,$(obj-m))
 export-objs	:= $(addprefix $(obj)/,$(export-objs))
 subdir-obj-y	:= $(addprefix $(obj)/,$(subdir-obj-y))
 real-objs-y	:= $(addprefix $(obj)/,$(real-objs-y))
 real-objs-m	:= $(addprefix $(obj)/,$(real-objs-m))
+single-used-m	:= $(addprefix $(obj)/,$(single-used-m))
 multi-used-y	:= $(addprefix $(obj)/,$(multi-used-y))
 multi-used-m	:= $(addprefix $(obj)/,$(multi-used-m))
 multi-objs-y	:= $(addprefix $(obj)/,$(multi-objs-y))
@@ -124,14 +127,20 @@
 #       than one module. In that case KBUILD_MODNAME will be set to foo_bar,
 #       where foo and bar are the name of the modules.
 basename_flags = -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F)))
-modname_flags  = -DKBUILD_MODNAME=$(subst $(comma),_,$(subst -,_,$(modname)))
+modname_flags  = $(if $(filter 1,$(words $(modname))),-DKBUILD_MODNAME=$(subst $(comma),_,$(subst -,_,$(modname))))
 c_flags        = -Wp,-MD,$(depfile) $(CFLAGS) $(NOSTDINC_FLAGS) \
 	         $(modkern_cflags) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) \
 	         $(basename_flags) $(modname_flags) $(export_flags) 
+a_flags        = -Wp,-MD,$(depfile) $(AFLAGS) $(NOSTDINC_FLAGS)\
+		 $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o)
+hostc_flags    = -Wp,-MD,$(depfile) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS)\
+		 $(HOSTCFLAGS_$(*F).o)
+hostcxx_flags  = -Wp,-MD,$(depfile) $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS)\
+		 $(HOSTCXXFLAGS_$(*F).o)
 
 # Finds the multi-part object the current object will be linked into
-modname-multi = $(subst $(space),_,$(sort $(foreach m,$(multi-used),\
-		$(if $(filter $(subst $(obj)/,,$*.o), $($(m:.o=-objs)) $($(m:.o=-y))),$(m:.o=)))))
+modname-multi = $(sort $(foreach m,$(multi-used),\
+		$(if $(filter $(subst $(obj)/,,$*.o), $($(m:.o=-objs)) $($(m:.o=-y))),$(m:.o=))))
 
 # Shipped files
 # ===========================================================================
@@ -139,7 +148,7 @@
 quiet_cmd_shipped = SHIPPED $@
 cmd_shipped = cat $< > $@
 
-%:: %_shipped
+$(obj)/%:: $(src)/%_shipped
 	$(call cmd,shipped)
 
 # Commands useful for building a boot image
@@ -236,4 +245,4 @@
 #	$(call descend,<dir>,<target>)
 #	Recursively call a sub-make in <dir> with target <target> 
 
-descend = $(Q)$(MAKE) -f scripts/Makefile.build obj=$(1) $(2)
+descend =$(Q)$(MAKE) -f scripts/Makefile.build obj=$(1) $(2)
diff -Nru a/scripts/Makefile.modinst b/scripts/Makefile.modinst
--- a/scripts/Makefile.modinst	Mon Dec  9 18:46:38 2002
+++ b/scripts/Makefile.modinst	Mon Dec  9 18:46:38 2002
@@ -15,12 +15,12 @@
 
 # ==========================================================================
 
-quiet_cmd_modules_install = INSTALL $(obj-m)
+quiet_cmd_modules_install = INSTALL $(obj-m:.o=.ko)
       cmd_modules_install = mkdir -p $(MODLIB)/kernel && \
-		      cp $(obj-m) $(MODLIB)/kernel/
+		      cp $(obj-m:.o=.ko) $(MODLIB)/kernel/
 
 modules_install: $(subdir-ym)
-ifneq ($(obj-m),)
+ifneq ($(obj-m:.o=.ko),)
 	$(call cmd,modules_install)
 else
 	@:
diff -Nru a/scripts/kallsyms b/scripts/kallsyms
--- a/scripts/kallsyms	Mon Dec  9 18:46:50 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,40 +0,0 @@
-#! /bin/sh
-# Written by Rusty Russell <rusty@rustcorp.com.au> 2002.
-
-if [ $# -ne 2 ]; then
-    echo Usage: kallsyms vmlinux objfile >&2
-
-    echo Adds a .kallsyms section containing symbol info.
-    exit 1
-fi
-
-set -e
-
-# Clean up on exit.
-trap "rm -f kallsyms.map kallsyms.c $2" 0
-
-# Takes nm output from $1, produces a .c file on standard output.
-encode_symbols()
-{
-    # First take addresses.
-    echo "unsigned long kallsyms_addresses[] = {"
-    sed 's/^[	]*\([A-Fa-f0-9]*\).*/0x\1UL,/' < $1
-    echo "};"
-
-    # Now output size.
-    echo "unsigned long kallsyms_num_syms = `wc -l < $1`;"
-
-    # Now output names.
-    echo "char kallsyms_names[] = ";
-    sed 's/^[         ]*[A-Fa-f0-9]*[         ]*.[    ]\(.*\)/"\1\\0"/' < $1
-    echo ";"
-}
-
-# FIXME: Use System.map as input, and regenerate each time in Makefile.
-$NM $1 | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > kallsyms.map
-
-encode_symbols kallsyms.map > kallsyms.c
-$CC $CFLAGS -c -o $2 kallsyms.c
-
-trap "rm -f kallsyms.map kallsyms.c" 0
-exit 0
diff -Nru a/scripts/kallsyms.c b/scripts/kallsyms.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/scripts/kallsyms.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,148 @@
+/* Generate assembler source containing symbol information
+ *
+ * Copyright 2002       by Kai Germaschewski
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ * Usage: nm -n vmlinux | scripts/kallsyms > symbols.S
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct sym_entry {
+	unsigned long long addr;
+	char type;
+	char *sym;
+};
+
+
+static struct sym_entry *table;
+static int size, cnt;
+static unsigned long long _stext, _etext;
+
+static void
+usage(void)
+{
+	fprintf(stderr, "Usage: kallsyms < in.map > out.S\n");
+	exit(1);
+}
+
+static int
+read_symbol(FILE *in, struct sym_entry *s)
+{
+	char str[500];
+	int rc;
+
+	rc = fscanf(in, "%llx %c %499s\n", &s->addr, &s->type, str);
+	if (rc != 3) {
+		if (rc != EOF) {
+			/* skip line */
+			fgets(str, 500, in);
+		}
+		return -1;
+	}
+	s->sym = strdup(str);
+	return 0;
+}
+
+static int
+symbol_valid(struct sym_entry *s)
+{
+	if (s->addr < _stext)
+		return 0;
+
+	if (s->addr > _etext)
+		return 0;
+
+	if (strstr(s->sym, "_compiled."))
+		return 0;
+
+	return 1;
+}
+
+static void
+read_map(FILE *in)
+{
+	int i;
+
+	while (!feof(in)) {
+		if (cnt >= size) {
+			size += 10000;
+			table = realloc(table, sizeof(*table) * size);
+			if (!table) {
+				fprintf(stderr, "out of memory\n");
+				exit (1);
+			}
+		}
+		if (read_symbol(in, &table[cnt]) == 0)
+			cnt++;
+	}
+	for (i = 0; i < cnt; i++) {
+		if (strcmp(table[i].sym, "_stext") == 0)
+			_stext = table[i].addr;
+		if (strcmp(table[i].sym, "_etext") == 0)
+			_etext = table[i].addr;
+	}
+}
+
+static void
+write_src(void)
+{
+	unsigned long long last_addr;
+	int i, valid = 0;
+
+	printf(".data\n");
+
+	printf(".globl kallsyms_addresses\n");
+	printf("\t.align 8\n");
+	printf("kallsyms_addresses:\n");
+	for (i = 0, last_addr = 0; i < cnt; i++) {
+		if (!symbol_valid(&table[i]))
+			continue;
+		
+		if (table[i].addr == last_addr)
+			continue;
+
+		printf("\t.long\t%#llx\n", table[i].addr);
+		valid++;
+		last_addr = table[i].addr;
+	}
+	printf("\n");
+
+	printf(".globl kallsyms_num_syms\n");
+	printf("\t.align 8\n");
+	printf("kallsyms_num_syms:\n");
+	printf("\t.long\t%d\n", valid);
+	printf("\n");
+
+	printf(".globl kallsyms_names\n");
+	printf("\t.align 8\n");
+	printf("kallsyms_names:\n");
+	for (i = 0, last_addr = 0; i < cnt; i++) {
+		if (!symbol_valid(&table[i]))
+			continue;
+		
+		if (table[i].addr == last_addr)
+			continue;
+
+		printf("\t.string\t\"%s\"\n", table[i].sym);
+		last_addr = table[i].addr;
+	}
+	printf("\n");
+}
+
+int
+main(int argc, char **argv)
+{
+	if (argc != 1)
+		usage();
+
+	read_map(stdin);
+	write_src();
+
+	return 0;
+}
+
diff -Nru a/scripts/lxdialog/Makefile b/scripts/lxdialog/Makefile
--- a/scripts/lxdialog/Makefile	Mon Dec  9 18:46:50 2002
+++ b/scripts/lxdialog/Makefile	Mon Dec  9 18:46:50 2002
@@ -15,19 +15,15 @@
 endif
 endif
 
-host-progs := lxdialog
+host-progs    := lxdialog
+build-targets := $(host-progs)
 
 lxdialog-objs := checklist.o menubox.o textbox.o yesno.o inputbox.o \
 		 util.o lxdialog.o msgbox.o
 
-EXTRA_TARGETS := lxdialog
-
 first_rule: ncurses
 
-include $(TOPDIR)/Rules.make
-
 .PHONY: ncurses
-
 ncurses:
 	@echo "main() {}" > lxtemp.c
 	@if $(HOSTCC) lxtemp.c  $(HOST_LOADLIBES); then \
diff -Nru a/security/Kconfig b/security/Kconfig
--- a/security/Kconfig	Mon Dec  9 18:46:50 2002
+++ b/security/Kconfig	Mon Dec  9 18:46:50 2002
@@ -22,5 +22,15 @@
 	  This enables the "default" Linux capabilities functionality.
 	  If you are unsure how to answer this question, answer Y.
 
+config SECURITY_ROOTPLUG
+	tristate "Root Plug Support"
+	depends on SECURITY!=n
+	help
+	  This is a sample LSM module that should only be used as such.
+	  It enables control over processes being created by root users
+	  if a specific USB device is not present in the system.
+	  
+	  If you are unsure how to answer this question, answer N.
+
 endmenu
 
diff -Nru a/security/Makefile b/security/Makefile
--- a/security/Makefile	Mon Dec  9 18:46:50 2002
+++ b/security/Makefile	Mon Dec  9 18:46:50 2002
@@ -13,5 +13,6 @@
 # Object file lists
 obj-$(CONFIG_SECURITY)			+= security.o dummy.o
 obj-$(CONFIG_SECURITY_CAPABILITIES)	+= capability.o
+obj-$(CONFIG_SECURITY_ROOTPLUG)		+= root_plug.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/security/capability.c b/security/capability.c
--- a/security/capability.c	Mon Dec  9 18:46:36 2002
+++ b/security/capability.c	Mon Dec  9 18:46:36 2002
@@ -279,550 +279,20 @@
 
 #ifdef CONFIG_SECURITY
 
-static int cap_quotactl (int cmds, int type, int id, struct super_block *sb)
-{
-	return 0;
-}
-
-static int cap_quota_on (struct file *f)
-{
-	return 0;
-}
-
-static int cap_acct (struct file *file)
-{
-	return 0;
-}
-
-static int cap_bprm_alloc_security (struct linux_binprm *bprm)
-{
-	return 0;
-}
-
-static int cap_bprm_check_security (struct linux_binprm *bprm)
-{
-	return 0;
-}
-
-static void cap_bprm_free_security (struct linux_binprm *bprm)
-{
-	return;
-}
-
-static int cap_sb_alloc_security (struct super_block *sb)
-{
-	return 0;
-}
-
-static void cap_sb_free_security (struct super_block *sb)
-{
-	return;
-}
-
-static int cap_sb_statfs (struct super_block *sb)
-{
-	return 0;
-}
-
-static int cap_mount (char *dev_name, struct nameidata *nd, char *type,
-		      unsigned long flags, void *data)
-{
-	return 0;
-}
-
-static int cap_check_sb (struct vfsmount *mnt, struct nameidata *nd)
-{
-	return 0;
-}
-
-static int cap_umount (struct vfsmount *mnt, int flags)
-{
-	return 0;
-}
-
-static void cap_umount_close (struct vfsmount *mnt)
-{
-	return;
-}
-
-static void cap_umount_busy (struct vfsmount *mnt)
-{
-	return;
-}
-
-static void cap_post_remount (struct vfsmount *mnt, unsigned long flags,
-			      void *data)
-{
-	return;
-}
-
-static void cap_post_mountroot (void)
-{
-	return;
-}
-
-static void cap_post_addmount (struct vfsmount *mnt, struct nameidata *nd)
-{
-	return;
-}
-
-static int cap_pivotroot (struct nameidata *old_nd, struct nameidata *new_nd)
-{
-	return 0;
-}
-
-static void cap_post_pivotroot (struct nameidata *old_nd, struct nameidata *new_nd)
-{
-	return;
-}
-
-static int cap_inode_alloc_security (struct inode *inode)
-{
-	return 0;
-}
-
-static void cap_inode_free_security (struct inode *inode)
-{
-	return;
-}
-
-static int cap_inode_create (struct inode *inode, struct dentry *dentry,
-			     int mask)
-{
-	return 0;
-}
-
-static void cap_inode_post_create (struct inode *inode, struct dentry *dentry,
-				   int mask)
-{
-	return;
-}
-
-static int cap_inode_link (struct dentry *old_dentry, struct inode *inode,
-			   struct dentry *new_dentry)
-{
-	return 0;
-}
-
-static void cap_inode_post_link (struct dentry *old_dentry, struct inode *inode,
-				 struct dentry *new_dentry)
-{
-	return;
-}
-
-static int cap_inode_unlink (struct inode *inode, struct dentry *dentry)
-{
-	return 0;
-}
-
-static int cap_inode_symlink (struct inode *inode, struct dentry *dentry,
-			      const char *name)
-{
-	return 0;
-}
-
-static void cap_inode_post_symlink (struct inode *inode, struct dentry *dentry,
-				    const char *name)
-{
-	return;
-}
-
-static int cap_inode_mkdir (struct inode *inode, struct dentry *dentry,
-			    int mask)
-{
-	return 0;
-}
-
-static void cap_inode_post_mkdir (struct inode *inode, struct dentry *dentry,
-				  int mask)
-{
-	return;
-}
-
-static int cap_inode_rmdir (struct inode *inode, struct dentry *dentry)
-{
-	return 0;
-}
-
-static int cap_inode_mknod (struct inode *inode, struct dentry *dentry,
-			    int mode, dev_t dev)
-{
-	return 0;
-}
-
-static void cap_inode_post_mknod (struct inode *inode, struct dentry *dentry,
-				  int mode, dev_t dev)
-{
-	return;
-}
-
-static int cap_inode_rename (struct inode *old_inode, struct dentry *old_dentry,
-			     struct inode *new_inode, struct dentry *new_dentry)
-{
-	return 0;
-}
-
-static void cap_inode_post_rename (struct inode *old_inode,
-				   struct dentry *old_dentry,
-				   struct inode *new_inode,
-				   struct dentry *new_dentry)
-{
-	return;
-}
-
-static int cap_inode_readlink (struct dentry *dentry)
-{
-	return 0;
-}
-
-static int cap_inode_follow_link (struct dentry *dentry,
-				  struct nameidata *nameidata)
-{
-	return 0;
-}
-
-static int cap_inode_permission (struct inode *inode, int mask)
-{
-	return 0;
-}
-
-static int cap_inode_permission_lite (struct inode *inode, int mask)
-{
-	return 0;
-}
-
-static int cap_inode_setattr (struct dentry *dentry, struct iattr *iattr)
-{
-	return 0;
-}
-
-static int cap_inode_getattr (struct vfsmount *mnt, struct dentry *dentry)
-{
-	return 0;
-}
-
-static void cap_post_lookup (struct inode *ino, struct dentry *d)
-{
-	return;
-}
-
-static void cap_delete (struct inode *ino)
-{
-	return;
-}
-
-static int cap_inode_setxattr (struct dentry *dentry, char *name, void *value,
-				size_t size, int flags)
-{
-	return 0;
-}
-
-static int cap_inode_getxattr (struct dentry *dentry, char *name)
-{
-	return 0;
-}
-
-static int cap_inode_listxattr (struct dentry *dentry)
-{
-	return 0;
-}
-
-static int cap_inode_removexattr (struct dentry *dentry, char *name)
-{
-	return 0;
-}
-
-static int cap_file_permission (struct file *file, int mask)
-{
-	return 0;
-}
-
-static int cap_file_alloc_security (struct file *file)
-{
-	return 0;
-}
-
-static void cap_file_free_security (struct file *file)
-{
-	return;
-}
-
-static int cap_file_ioctl (struct file *file, unsigned int command,
-			   unsigned long arg)
-{
-	return 0;
-}
-
-static int cap_file_mmap (struct file *file, unsigned long prot,
-			  unsigned long flags)
-{
-	return 0;
-}
-
-static int cap_file_mprotect (struct vm_area_struct *vma, unsigned long prot)
-{
-	return 0;
-}
-
-static int cap_file_lock (struct file *file, unsigned int cmd)
-{
-	return 0;
-}
-
-static int cap_file_fcntl (struct file *file, unsigned int cmd,
-			   unsigned long arg)
-{
-	return 0;
-}
-
-static int cap_file_set_fowner (struct file *file)
-{
-	return 0;
-}
-
-static int cap_file_send_sigiotask (struct task_struct *tsk,
-				    struct fown_struct *fown, int fd,
-				    int reason)
-{
-	return 0;
-}
-
-static int cap_file_receive (struct file *file)
-{
-	return 0;
-}
-
-static int cap_task_create (unsigned long clone_flags)
-{
-	return 0;
-}
-
-static int cap_task_alloc_security (struct task_struct *p)
-{
-	return 0;
-}
-
-static void cap_task_free_security (struct task_struct *p)
-{
-	return;
-}
-
-static int cap_task_setuid (uid_t id0, uid_t id1, uid_t id2, int flags)
-{
-	return 0;
-}
-
-static int cap_task_setgid (gid_t id0, gid_t id1, gid_t id2, int flags)
-{
-	return 0;
-}
-
-static int cap_task_setpgid (struct task_struct *p, pid_t pgid)
-{
-	return 0;
-}
-
-static int cap_task_getpgid (struct task_struct *p)
-{
-	return 0;
-}
-
-static int cap_task_getsid (struct task_struct *p)
-{
-	return 0;
-}
-
-static int cap_task_setgroups (int gidsetsize, gid_t * grouplist)
-{
-	return 0;
-}
-
-static int cap_task_setnice (struct task_struct *p, int nice)
-{
-	return 0;
-}
-
-static int cap_task_setrlimit (unsigned int resource, struct rlimit *new_rlim)
-{
-	return 0;
-}
-
-static int cap_task_setscheduler (struct task_struct *p, int policy,
-				  struct sched_param *lp)
-{
-	return 0;
-}
-
-static int cap_task_getscheduler (struct task_struct *p)
-{
-	return 0;
-}
-
-static int cap_task_wait (struct task_struct *p)
-{
-	return 0;
-}
-
-static int cap_task_kill (struct task_struct *p, struct siginfo *info, int sig)
-{
-	return 0;
-}
-
-static int cap_task_prctl (int option, unsigned long arg2, unsigned long arg3,
-			   unsigned long arg4, unsigned long arg5)
-{
-	return 0;
-}
-
-static int cap_ipc_permission (struct kern_ipc_perm *ipcp, short flag)
-{
-	return 0;
-}
-
-static int cap_msg_queue_alloc_security (struct msg_queue *msq)
-{
-	return 0;
-}
-
-static void cap_msg_queue_free_security (struct msg_queue *msq)
-{
-	return;
-}
-
-static int cap_shm_alloc_security (struct shmid_kernel *shp)
-{
-	return 0;
-}
-
-static void cap_shm_free_security (struct shmid_kernel *shp)
-{
-	return;
-}
-
-static int cap_sem_alloc_security (struct sem_array *sma)
-{
-	return 0;
-}
-
-static void cap_sem_free_security (struct sem_array *sma)
-{
-	return;
-}
-
-static int cap_register (const char *name, struct security_operations *ops)
-{
-	return -EINVAL;
-}
-
-static int cap_unregister (const char *name, struct security_operations *ops)
-{
-	return -EINVAL;
-}
 
 static struct security_operations capability_ops = {
 	.ptrace =			cap_ptrace,
 	.capget =			cap_capget,
 	.capset_check =			cap_capset_check,
 	.capset_set =			cap_capset_set,
-	.acct =				cap_acct,
 	.capable =			cap_capable,
-	.quotactl =			cap_quotactl,
-	.quota_on =			cap_quota_on,
 
-	.bprm_alloc_security =		cap_bprm_alloc_security,
-	.bprm_free_security =		cap_bprm_free_security,
 	.bprm_compute_creds =		cap_bprm_compute_creds,
 	.bprm_set_security =		cap_bprm_set_security,
-	.bprm_check_security =		cap_bprm_check_security,
-
-	.sb_alloc_security =		cap_sb_alloc_security,
-	.sb_free_security =		cap_sb_free_security,
-	.sb_statfs =			cap_sb_statfs,
-	.sb_mount =			cap_mount,
-	.sb_check_sb =			cap_check_sb,
-	.sb_umount =			cap_umount,
-	.sb_umount_close =		cap_umount_close,
-	.sb_umount_busy =		cap_umount_busy,
-	.sb_post_remount =		cap_post_remount,
-	.sb_post_mountroot =		cap_post_mountroot,
-	.sb_post_addmount =		cap_post_addmount,
-	.sb_pivotroot =			cap_pivotroot,
-	.sb_post_pivotroot =		cap_post_pivotroot,
-	
-	.inode_alloc_security =		cap_inode_alloc_security,
-	.inode_free_security =		cap_inode_free_security,
-	.inode_create =			cap_inode_create,
-	.inode_post_create =		cap_inode_post_create,
-	.inode_link =			cap_inode_link,
-	.inode_post_link =		cap_inode_post_link,
-	.inode_unlink =			cap_inode_unlink,
-	.inode_symlink =		cap_inode_symlink,
-	.inode_post_symlink =		cap_inode_post_symlink,
-	.inode_mkdir =			cap_inode_mkdir,
-	.inode_post_mkdir =		cap_inode_post_mkdir,
-	.inode_rmdir =			cap_inode_rmdir,
-	.inode_mknod =			cap_inode_mknod,
-	.inode_post_mknod =		cap_inode_post_mknod,
-	.inode_rename =			cap_inode_rename,
-	.inode_post_rename =		cap_inode_post_rename,
-	.inode_readlink =		cap_inode_readlink,
-	.inode_follow_link =		cap_inode_follow_link,
-	.inode_permission =		cap_inode_permission,
-	.inode_permission_lite =	cap_inode_permission_lite,
-	.inode_setattr =		cap_inode_setattr,
-	.inode_getattr =		cap_inode_getattr,
-	.inode_post_lookup =		cap_post_lookup,
-	.inode_delete =			cap_delete,
-	.inode_setxattr =		cap_inode_setxattr,
-	.inode_getxattr =		cap_inode_getxattr,
-	.inode_listxattr =		cap_inode_listxattr,
-	.inode_removexattr =		cap_inode_removexattr,
-	
-	.file_permission =		cap_file_permission,
-	.file_alloc_security =		cap_file_alloc_security,
-	.file_free_security =		cap_file_free_security,
-	.file_ioctl =			cap_file_ioctl,
-	.file_mmap =			cap_file_mmap,
-	.file_mprotect =		cap_file_mprotect,
-	.file_lock =			cap_file_lock,
-	.file_fcntl =			cap_file_fcntl,
-	.file_set_fowner =		cap_file_set_fowner,
-	.file_send_sigiotask =		cap_file_send_sigiotask,
-	.file_receive =			cap_file_receive,
 
-	.task_create =			cap_task_create,
-	.task_alloc_security =		cap_task_alloc_security,
-	.task_free_security =		cap_task_free_security,
-	.task_setuid =			cap_task_setuid,
 	.task_post_setuid =		cap_task_post_setuid,
-	.task_setgid =			cap_task_setgid,
-	.task_setpgid =			cap_task_setpgid,
-	.task_getpgid =			cap_task_getpgid,
-	.task_getsid =			cap_task_getsid,
-	.task_setgroups =		cap_task_setgroups,
-	.task_setnice =			cap_task_setnice,
-	.task_setrlimit =		cap_task_setrlimit,
-	.task_setscheduler =		cap_task_setscheduler,
-	.task_getscheduler =		cap_task_getscheduler,
-	.task_wait =			cap_task_wait,
-	.task_kill =			cap_task_kill,
-	.task_prctl =			cap_task_prctl,
 	.task_kmod_set_label =		cap_task_kmod_set_label,
 	.task_reparent_to_init =	cap_task_reparent_to_init,
-
-	.ipc_permission =		cap_ipc_permission,
-
-	.msg_queue_alloc_security =	cap_msg_queue_alloc_security,
-	.msg_queue_free_security =	cap_msg_queue_free_security,
-	
-	.shm_alloc_security =		cap_shm_alloc_security,
-	.shm_free_security =		cap_shm_free_security,
-	
-	.sem_alloc_security =		cap_sem_alloc_security,
-	.sem_free_security =		cap_sem_free_security,
-
-	.register_security =		cap_register,
-	.unregister_security =		cap_unregister,
 };
 
 #if defined(CONFIG_SECURITY_CAPABILITIES_MODULE)
diff -Nru a/security/dummy.c b/security/dummy.c
--- a/security/dummy.c	Mon Dec  9 18:46:35 2002
+++ b/security/dummy.c	Mon Dec  9 18:46:35 2002
@@ -12,6 +12,8 @@
  *	(at your option) any later version.
  */
 
+#undef DEBUG
+
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -19,6 +21,7 @@
 #include <linux/skbuff.h>
 #include <linux/netlink.h>
 
+
 static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
 {
 	return 0;
@@ -122,55 +125,55 @@
 	return 0;
 }
 
-static int dummy_mount (char *dev_name, struct nameidata *nd, char *type,
-			unsigned long flags, void *data)
+static int dummy_sb_mount (char *dev_name, struct nameidata *nd, char *type,
+			   unsigned long flags, void *data)
 {
 	return 0;
 }
 
-static int dummy_check_sb (struct vfsmount *mnt, struct nameidata *nd)
+static int dummy_sb_check_sb (struct vfsmount *mnt, struct nameidata *nd)
 {
 	return 0;
 }
 
-static int dummy_umount (struct vfsmount *mnt, int flags)
+static int dummy_sb_umount (struct vfsmount *mnt, int flags)
 {
 	return 0;
 }
 
-static void dummy_umount_close (struct vfsmount *mnt)
+static void dummy_sb_umount_close (struct vfsmount *mnt)
 {
 	return;
 }
 
-static void dummy_umount_busy (struct vfsmount *mnt)
+static void dummy_sb_umount_busy (struct vfsmount *mnt)
 {
 	return;
 }
 
-static void dummy_post_remount (struct vfsmount *mnt, unsigned long flags,
-				void *data)
+static void dummy_sb_post_remount (struct vfsmount *mnt, unsigned long flags,
+				   void *data)
 {
 	return;
 }
 
 
-static void dummy_post_mountroot (void)
+static void dummy_sb_post_mountroot (void)
 {
 	return;
 }
 
-static void dummy_post_addmount (struct vfsmount *mnt, struct nameidata *nd)
+static void dummy_sb_post_addmount (struct vfsmount *mnt, struct nameidata *nd)
 {
 	return;
 }
 
-static int dummy_pivotroot (struct nameidata *old_nd, struct nameidata *new_nd)
+static int dummy_sb_pivotroot (struct nameidata *old_nd, struct nameidata *new_nd)
 {
 	return 0;
 }
 
-static void dummy_post_pivotroot (struct nameidata *old_nd, struct nameidata *new_nd)
+static void dummy_sb_post_pivotroot (struct nameidata *old_nd, struct nameidata *new_nd)
 {
 	return;
 }
@@ -303,12 +306,12 @@
 	return 0;
 }
 
-static void dummy_post_lookup (struct inode *ino, struct dentry *d)
+static void dummy_inode_post_lookup (struct inode *ino, struct dentry *d)
 {
 	return;
 }
 
-static void dummy_delete (struct inode *ino)
+static void dummy_inode_delete (struct inode *ino)
 {
 	return;
 }
@@ -529,12 +532,12 @@
 	return;
 }
 
-static int dummy_register (const char *name, struct security_operations *ops)
+static int dummy_register_security (const char *name, struct security_operations *ops)
 {
 	return -EINVAL;
 }
 
-static int dummy_unregister (const char *name, struct security_operations *ops)
+static int dummy_unregister_security (const char *name, struct security_operations *ops)
 {
 	return -EINVAL;
 }
@@ -558,16 +561,16 @@
 	.sb_alloc_security =		dummy_sb_alloc_security,
 	.sb_free_security =		dummy_sb_free_security,
 	.sb_statfs =			dummy_sb_statfs,
-	.sb_mount =			dummy_mount,
-	.sb_check_sb =			dummy_check_sb,
-	.sb_umount =			dummy_umount,
-	.sb_umount_close =		dummy_umount_close,
-	.sb_umount_busy =		dummy_umount_busy,
-	.sb_post_remount =		dummy_post_remount,
-	.sb_post_mountroot =		dummy_post_mountroot,
-	.sb_post_addmount =		dummy_post_addmount,
-	.sb_pivotroot =			dummy_pivotroot,
-	.sb_post_pivotroot =		dummy_post_pivotroot,
+	.sb_mount =			dummy_sb_mount,
+	.sb_check_sb =			dummy_sb_check_sb,
+	.sb_umount =			dummy_sb_umount,
+	.sb_umount_close =		dummy_sb_umount_close,
+	.sb_umount_busy =		dummy_sb_umount_busy,
+	.sb_post_remount =		dummy_sb_post_remount,
+	.sb_post_mountroot =		dummy_sb_post_mountroot,
+	.sb_post_addmount =		dummy_sb_post_addmount,
+	.sb_pivotroot =			dummy_sb_pivotroot,
+	.sb_post_pivotroot =		dummy_sb_post_pivotroot,
 	
 	.inode_alloc_security =		dummy_inode_alloc_security,
 	.inode_free_security =		dummy_inode_free_security,
@@ -591,8 +594,8 @@
 	.inode_permission_lite =	dummy_inode_permission_lite,
 	.inode_setattr =		dummy_inode_setattr,
 	.inode_getattr =		dummy_inode_getattr,
-	.inode_post_lookup =		dummy_post_lookup,
-	.inode_delete =			dummy_delete,
+	.inode_post_lookup =		dummy_inode_post_lookup,
+	.inode_delete =			dummy_inode_delete,
 	.inode_setxattr =		dummy_inode_setxattr,
 	.inode_getxattr =		dummy_inode_getxattr,
 	.inode_listxattr =		dummy_inode_listxattr,
@@ -641,7 +644,113 @@
 	.sem_alloc_security =		dummy_sem_alloc_security,
 	.sem_free_security =		dummy_sem_free_security,
 
-	.register_security =		dummy_register,
-	.unregister_security =		dummy_unregister,
+	.register_security =		dummy_register_security,
+	.unregister_security =		dummy_unregister_security,
 };
+
+#define set_to_dummy_if_null(ops, function)				\
+	do {								\
+		if (!ops->function) {					\
+			ops->function = dummy_##function;		\
+			pr_debug("Had to override the " #function	\
+				 " security operation with the dummy one.\n");\
+			}						\
+	} while (0)
+
+void security_fixup_ops (struct security_operations *ops)
+{
+	set_to_dummy_if_null(ops, ptrace);
+	set_to_dummy_if_null(ops, capget);
+	set_to_dummy_if_null(ops, capset_check);
+	set_to_dummy_if_null(ops, capset_set);
+	set_to_dummy_if_null(ops, acct);
+	set_to_dummy_if_null(ops, capable);
+	set_to_dummy_if_null(ops, quotactl);
+	set_to_dummy_if_null(ops, quota_on);
+	set_to_dummy_if_null(ops, bprm_alloc_security);
+	set_to_dummy_if_null(ops, bprm_free_security);
+	set_to_dummy_if_null(ops, bprm_compute_creds);
+	set_to_dummy_if_null(ops, bprm_set_security);
+	set_to_dummy_if_null(ops, bprm_check_security);
+	set_to_dummy_if_null(ops, sb_alloc_security);
+	set_to_dummy_if_null(ops, sb_free_security);
+	set_to_dummy_if_null(ops, sb_statfs);
+	set_to_dummy_if_null(ops, sb_mount);
+	set_to_dummy_if_null(ops, sb_check_sb);
+	set_to_dummy_if_null(ops, sb_umount);
+	set_to_dummy_if_null(ops, sb_umount_close);
+	set_to_dummy_if_null(ops, sb_umount_busy);
+	set_to_dummy_if_null(ops, sb_post_remount);
+	set_to_dummy_if_null(ops, sb_post_mountroot);
+	set_to_dummy_if_null(ops, sb_post_addmount);
+	set_to_dummy_if_null(ops, sb_pivotroot);
+	set_to_dummy_if_null(ops, sb_post_pivotroot);
+	set_to_dummy_if_null(ops, inode_alloc_security);
+	set_to_dummy_if_null(ops, inode_free_security);
+	set_to_dummy_if_null(ops, inode_create);
+	set_to_dummy_if_null(ops, inode_post_create);
+	set_to_dummy_if_null(ops, inode_link);
+	set_to_dummy_if_null(ops, inode_post_link);
+	set_to_dummy_if_null(ops, inode_unlink);
+	set_to_dummy_if_null(ops, inode_symlink);
+	set_to_dummy_if_null(ops, inode_post_symlink);
+	set_to_dummy_if_null(ops, inode_mkdir);
+	set_to_dummy_if_null(ops, inode_post_mkdir);
+	set_to_dummy_if_null(ops, inode_rmdir);
+	set_to_dummy_if_null(ops, inode_mknod);
+	set_to_dummy_if_null(ops, inode_post_mknod);
+	set_to_dummy_if_null(ops, inode_rename);
+	set_to_dummy_if_null(ops, inode_post_rename);
+	set_to_dummy_if_null(ops, inode_readlink);
+	set_to_dummy_if_null(ops, inode_follow_link);
+	set_to_dummy_if_null(ops, inode_permission);
+	set_to_dummy_if_null(ops, inode_permission_lite);
+	set_to_dummy_if_null(ops, inode_setattr);
+	set_to_dummy_if_null(ops, inode_getattr);
+	set_to_dummy_if_null(ops, inode_post_lookup);
+	set_to_dummy_if_null(ops, inode_delete);
+	set_to_dummy_if_null(ops, inode_setxattr);
+	set_to_dummy_if_null(ops, inode_getxattr);
+	set_to_dummy_if_null(ops, inode_listxattr);
+	set_to_dummy_if_null(ops, inode_removexattr);
+	set_to_dummy_if_null(ops, file_permission);
+	set_to_dummy_if_null(ops, file_alloc_security);
+	set_to_dummy_if_null(ops, file_free_security);
+	set_to_dummy_if_null(ops, file_ioctl);
+	set_to_dummy_if_null(ops, file_mmap);
+	set_to_dummy_if_null(ops, file_mprotect);
+	set_to_dummy_if_null(ops, file_lock);
+	set_to_dummy_if_null(ops, file_fcntl);
+	set_to_dummy_if_null(ops, file_set_fowner);
+	set_to_dummy_if_null(ops, file_send_sigiotask);
+	set_to_dummy_if_null(ops, file_receive);
+	set_to_dummy_if_null(ops, task_create);
+	set_to_dummy_if_null(ops, task_alloc_security);
+	set_to_dummy_if_null(ops, task_free_security);
+	set_to_dummy_if_null(ops, task_setuid);
+	set_to_dummy_if_null(ops, task_post_setuid);
+	set_to_dummy_if_null(ops, task_setgid);
+	set_to_dummy_if_null(ops, task_setpgid);
+	set_to_dummy_if_null(ops, task_getpgid);
+	set_to_dummy_if_null(ops, task_getsid);
+	set_to_dummy_if_null(ops, task_setgroups);
+	set_to_dummy_if_null(ops, task_setnice);
+	set_to_dummy_if_null(ops, task_setrlimit);
+	set_to_dummy_if_null(ops, task_setscheduler);
+	set_to_dummy_if_null(ops, task_getscheduler);
+	set_to_dummy_if_null(ops, task_wait);
+	set_to_dummy_if_null(ops, task_kill);
+	set_to_dummy_if_null(ops, task_prctl);
+	set_to_dummy_if_null(ops, task_kmod_set_label);
+	set_to_dummy_if_null(ops, task_reparent_to_init);
+	set_to_dummy_if_null(ops, ipc_permission);
+	set_to_dummy_if_null(ops, msg_queue_alloc_security);
+	set_to_dummy_if_null(ops, msg_queue_free_security);
+	set_to_dummy_if_null(ops, shm_alloc_security);
+	set_to_dummy_if_null(ops, shm_free_security);
+	set_to_dummy_if_null(ops, sem_alloc_security);
+	set_to_dummy_if_null(ops, sem_free_security);
+	set_to_dummy_if_null(ops, register_security);
+	set_to_dummy_if_null(ops, unregister_security);
+}
 
diff -Nru a/security/root_plug.c b/security/root_plug.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/security/root_plug.c	Mon Dec  9 18:46:52 2002
@@ -0,0 +1,189 @@
+/*
+ * Root Plug sample LSM module
+ *
+ * Originally written for a Linux Journal.
+ *
+ * Copyright (C) 2002 Greg Kroah-Hartman <greg@kroah.com>
+ *
+ * Prevents any programs running with egid == 0 if a specific USB device
+ * is not present in the system.  Yes, it can be gotten around, but is a
+ * nice starting point for people to play with, and learn the LSM
+ * interface.
+ *
+ * If you want to turn this into something with a semblance of security,
+ * you need to hook the task_* functions also.
+ *
+ *	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, version 2 of the
+ *	License.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/security.h>
+#include <linux/usb.h>
+
+/* flag to keep track of how we were registered */
+static int secondary;
+
+/* default is a generic type of usb to serial converter */
+static int vendor_id = 0x0557;
+static int product_id = 0x2008;
+
+MODULE_PARM(vendor_id, "h");
+MODULE_PARM_DESC(vendor_id, "USB Vendor ID of device to look for");
+
+MODULE_PARM(product_id, "h");
+MODULE_PARM_DESC(product_id, "USB Product ID of device to look for");
+
+/* should we print out debug messages */
+static int debug = 0;
+
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+
+#if defined(CONFIG_SECURITY_ROOTPLUG_MODULE)
+#define MY_NAME THIS_MODULE->name
+#else
+#define MY_NAME "root_plug"
+#endif
+
+#define dbg(fmt, arg...)					\
+	do {							\
+		if (debug)					\
+			printk(KERN_DEBUG "%s: %s: " fmt ,	\
+				MY_NAME , __FUNCTION__ , 	\
+				## arg);			\
+	} while (0)
+
+extern struct list_head usb_bus_list;
+extern struct semaphore usb_bus_list_lock;
+
+static int match_device (struct usb_device *dev)
+{
+	int retval = -ENODEV;
+	int child;
+
+	dbg ("looking at vendor %d, product %d\n",
+	     dev->descriptor.idVendor,
+	     dev->descriptor.idProduct);
+
+	/* see if this device matches */
+	if ((dev->descriptor.idVendor == vendor_id) &&
+	    (dev->descriptor.idProduct == product_id)) {
+		dbg ("found the device!\n");
+		retval = 0;
+		goto exit;
+	}
+
+	/* look through all of the children of this device */
+	for (child = 0; child < dev->maxchild; ++child) {
+		if (dev->children[child]) {
+			retval = match_device (dev->children[child]);
+			if (retval == 0)
+				goto exit;
+		}
+	}
+exit:
+	return retval;
+}
+
+static int find_usb_device (void)
+{
+	struct list_head *buslist;
+	struct usb_bus *bus;
+	int retval = -ENODEV;
+	
+	down (&usb_bus_list_lock);
+	for (buslist = usb_bus_list.next;
+	     buslist != &usb_bus_list; 
+	     buslist = buslist->next) {
+		bus = container_of (buslist, struct usb_bus, bus_list);
+		retval = match_device(bus->root_hub);
+		if (retval == 0)
+			goto exit;
+	}
+exit:
+	up (&usb_bus_list_lock);
+	return retval;
+}
+	
+
+static int rootplug_bprm_check_security (struct linux_binprm *bprm)
+{
+	dbg ("file %s, e_uid = %d, e_gid = %d\n",
+	     bprm->filename, bprm->e_uid, bprm->e_gid);
+
+	if (bprm->e_gid == 0) {
+		if (find_usb_device() != 0) {
+			dbg ("e_gid = 0, and device not found, "
+				"task not allowed to run...\n");
+			return -EPERM;
+		}
+	}
+
+	return 0;
+}
+
+static struct security_operations rootplug_security_ops = {
+	/* Use the capability functions for some of the hooks */
+	.ptrace =			cap_ptrace,
+	.capget =			cap_capget,
+	.capset_check =			cap_capset_check,
+	.capset_set =			cap_capset_set,
+	.capable =			cap_capable,
+
+	.bprm_compute_creds =		cap_bprm_compute_creds,
+	.bprm_set_security =		cap_bprm_set_security,
+
+	.task_post_setuid =		cap_task_post_setuid,
+	.task_kmod_set_label =		cap_task_kmod_set_label,
+	.task_reparent_to_init =	cap_task_reparent_to_init,
+
+	.bprm_check_security =		rootplug_bprm_check_security,
+};
+
+static int __init rootplug_init (void)
+{
+	/* register ourselves with the security framework */
+	if (register_security (&rootplug_security_ops)) {
+		printk (KERN_INFO 
+			"Failure registering Root Plug module with the kernel\n");
+		/* try registering with primary module */
+		if (mod_reg_security (MY_NAME, &rootplug_security_ops)) {
+			printk (KERN_INFO "Failure registering Root Plug "
+				" module with primary security module.\n");
+			return -EINVAL;
+		}
+		secondary = 1;
+	}
+	printk (KERN_INFO "Root Plug module initialized, "
+		"vendor_id = %4.4x, product id = %4.4x\n", vendor_id, product_id);
+	return 0;
+}
+
+static void __exit rootplug_exit (void)
+{
+	/* remove ourselves from the security framework */
+	if (secondary) {
+		if (mod_unreg_security (MY_NAME, &rootplug_security_ops))
+			printk (KERN_INFO "Failure unregistering Root Plug "
+				" module with primary module.\n");
+	} else { 
+		if (unregister_security (&rootplug_security_ops)) {
+			printk (KERN_INFO "Failure unregistering Root Plug "
+				"module with the kernel\n");
+		}
+	}
+	printk (KERN_INFO "Root Plug module removed\n");
+}
+
+module_init (rootplug_init);
+module_exit (rootplug_exit);
+
+MODULE_DESCRIPTION("Root Plug sample LSM module, written for Linux Journal article");
+MODULE_LICENSE("GPL");
+
diff -Nru a/security/security.c b/security/security.c
--- a/security/security.c	Mon Dec  9 18:46:34 2002
+++ b/security/security.c	Mon Dec  9 18:46:34 2002
@@ -20,59 +20,21 @@
 
 #define SECURITY_SCAFFOLD_VERSION	"1.0.0"
 
-extern struct security_operations dummy_security_ops;	/* lives in dummy.c */
+/* things that live in dummy.c */
+extern struct security_operations dummy_security_ops;
+extern void security_fixup_ops (struct security_operations *ops);
 
 struct security_operations *security_ops;	/* Initialized to NULL */
 
-/* This macro checks that all pointers in a struct are non-NULL.  It 
- * can be fooled by struct padding for object tile alignment and when
- * pointers to data and pointers to functions aren't the same size.
- * Yes it's ugly, we'll replace it if it becomes a problem.
- */
-#define VERIFY_STRUCT(struct_type, s, e) \
-	do { \
-		unsigned long * __start = (unsigned long *)(s); \
-		unsigned long * __end = __start + \
-				sizeof(struct_type)/sizeof(unsigned long *); \
-		while (__start != __end) { \
-			if (!*__start) { \
-				printk(KERN_INFO "%s is missing something\n",\
-					#struct_type); \
-				e++; \
-				break; \
-			} \
-			__start++; \
-		} \
-	} while (0)
-
-static int inline verify (struct security_operations *ops)
+static inline int verify (struct security_operations *ops)
 {
-	int err;
-
 	/* verify the security_operations structure exists */
 	if (!ops) {
 		printk (KERN_INFO "Passed a NULL security_operations "
 			"pointer, %s failed.\n", __FUNCTION__);
 		return -EINVAL;
 	}
-
-	/* Perform a little sanity checking on our inputs */
-	err = 0;
-
-	/* This first check scans the whole security_ops struct for
-	 * missing structs or functions.
-	 *
-	 * (There is no further check now, but will leave as is until
-	 *  the lazy registration stuff is done -- JM).
-	 */
-	VERIFY_STRUCT(struct security_operations, ops, err);
-
-	if (err) {
-		printk (KERN_INFO "Not enough functions specified in the "
-			"security_operation structure, %s failed.\n",
-			__FUNCTION__);
-		return -EINVAL;
-	}
+	security_fixup_ops (ops);
 	return 0;
 }
 
@@ -106,12 +68,12 @@
  */
 int register_security (struct security_operations *ops)
 {
-
 	if (verify (ops)) {
 		printk (KERN_INFO "%s could not verify "
 			"security_operations structure.\n", __FUNCTION__);
 		return -EINVAL;
 	}
+
 	if (security_ops != &dummy_security_ops) {
 		printk (KERN_INFO "There is already a security "
 			"framework initialized, %s failed.\n", __FUNCTION__);
diff -Nru a/sound/arm/sa11xx-uda1341.c b/sound/arm/sa11xx-uda1341.c
--- a/sound/arm/sa11xx-uda1341.c	Mon Dec  9 18:46:34 2002
+++ b/sound/arm/sa11xx-uda1341.c	Mon Dec  9 18:46:34 2002
@@ -555,11 +555,11 @@
 				   SNDRV_PCM_RATE_KNOT),
 	.rate_min		= 8000,
 	.rate_max		= 48000,
-	.channels_min:		= 2,
-	.channels_max:		= 2,
-	.buffer_bytes_max:	= 16380,
-	.period_bytes_min:	= 64,
-	.period_bytes_max:	= 8190, /* <= MAX_DMA_SIZE from ams/arch-sa1100/dma.h */
+	.channels_min		= 2,
+	.channels_max		= 2,
+	.buffer_bytes_max	= 16380,
+	.period_bytes_min	= 64,
+	.period_bytes_max	= 8190, /* <= MAX_DMA_SIZE from ams/arch-sa1100/dma.h */
 	.periods_min		= 2,
 	.periods_max		= 255,
 	.fifo_size		= 0,
diff -Nru a/sound/core/ioctl32/ioctl32.c b/sound/core/ioctl32/ioctl32.c
--- a/sound/core/ioctl32/ioctl32.c	Mon Dec  9 18:46:35 2002
+++ b/sound/core/ioctl32/ioctl32.c	Mon Dec  9 18:46:35 2002
@@ -24,6 +24,7 @@
 #include <linux/init.h>
 #include <linux/time.h>
 #include <linux/slab.h>
+#include <linux/fs.h>
 #include <linux/init.h>
 #include <sound/core.h>
 #include <sound/control.h>
diff -Nru a/sound/core/ioctl32/rawmidi32.c b/sound/core/ioctl32/rawmidi32.c
--- a/sound/core/ioctl32/rawmidi32.c	Mon Dec  9 18:46:37 2002
+++ b/sound/core/ioctl32/rawmidi32.c	Mon Dec  9 18:46:37 2002
@@ -20,6 +20,7 @@
 
 #include <sound/driver.h>
 #include <linux/time.h>
+#include <linux/fs.h>
 #include <sound/core.h>
 #include <sound/rawmidi.h>
 #include <asm/uaccess.h>
diff -Nru a/sound/core/ioctl32/seq32.c b/sound/core/ioctl32/seq32.c
--- a/sound/core/ioctl32/seq32.c	Mon Dec  9 18:46:52 2002
+++ b/sound/core/ioctl32/seq32.c	Mon Dec  9 18:46:52 2002
@@ -20,6 +20,7 @@
 
 #include <sound/driver.h>
 #include <linux/time.h>
+#include <linux/fs.h>
 #include <sound/core.h>
 #include <sound/timer.h>
 #include <asm/uaccess.h>
diff -Nru a/sound/core/ioctl32/timer32.c b/sound/core/ioctl32/timer32.c
--- a/sound/core/ioctl32/timer32.c	Mon Dec  9 18:46:38 2002
+++ b/sound/core/ioctl32/timer32.c	Mon Dec  9 18:46:38 2002
@@ -20,6 +20,7 @@
 
 #include <sound/driver.h>
 #include <linux/time.h>
+#include <linux/fs.h>
 #include <sound/core.h>
 #include <sound/timer.h>
 #include <asm/uaccess.h>
diff -Nru a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
--- a/sound/isa/cs423x/cs4236.c	Mon Dec  9 18:46:34 2002
+++ b/sound/isa/cs423x/cs4236.c	Mon Dec  9 18:46:34 2002
@@ -161,22 +161,22 @@
 #define ISAPNP_CS4232(_va, _vb, _vc, _device, _wss, _ctrl, _mpu401) \
 	{ \
 		ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
-		devs : { ISAPNP_DEVICE_ID(_va, _vb, _vc, _wss), \
-                         ISAPNP_DEVICE_ID(_va, _vb, _vc, _ctrl), \
-			 ISAPNP_DEVICE_ID(_va, _vb, _vc, _mpu401) } \
+		.devs = { ISAPNP_DEVICE_ID(_va, _vb, _vc, _wss), \
+                          ISAPNP_DEVICE_ID(_va, _vb, _vc, _ctrl), \
+			  ISAPNP_DEVICE_ID(_va, _vb, _vc, _mpu401) } \
         }
 #define ISAPNP_CS4232_1(_va, _vb, _vc, _device, _wss, _ctrl, _mpu401) \
 	{ \
 		ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
-		devs : { ISAPNP_DEVICE_ID(_va, _vb, _vc, _wss), \
-                         ISAPNP_DEVICE_ID(_va, _vb, _vc, _ctrl), \
-			 ISAPNP_DEVICE_ID('P', 'N', 'P', _mpu401) } \
+		.devs = { ISAPNP_DEVICE_ID(_va, _vb, _vc, _wss), \
+                          ISAPNP_DEVICE_ID(_va, _vb, _vc, _ctrl), \
+		 	  ISAPNP_DEVICE_ID('P', 'N', 'P', _mpu401) } \
         }
 #define ISAPNP_CS4232_WOMPU(_va, _vb, _vc, _device, _wss, _ctrl) \
 	{ \
 		ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
-		devs : { ISAPNP_DEVICE_ID(_va, _vb, _vc, _wss), \
-                         ISAPNP_DEVICE_ID(_va, _vb, _vc, _ctrl) } \
+		.devs = { ISAPNP_DEVICE_ID(_va, _vb, _vc, _wss), \
+                          ISAPNP_DEVICE_ID(_va, _vb, _vc, _ctrl) } \
         }
 
 
diff -Nru a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
--- a/sound/isa/opl3sa2.c	Mon Dec  9 18:46:51 2002
+++ b/sound/isa/opl3sa2.c	Mon Dec  9 18:46:51 2002
@@ -24,11 +24,7 @@
 #include <linux/interrupt.h>
 #include <linux/pm.h>
 #include <linux/slab.h>
-#ifndef LINUX_ISAPNP_H
-#include <linux/isapnp.h>
-#define isapnp_card pci_bus
-#define isapnp_dev pci_dev
-#endif
+#include <linux/pnp.h>
 #include <sound/core.h>
 #include <sound/cs4231.h>
 #include <sound/mpu401.h>
@@ -51,7 +47,7 @@
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
-#ifdef __ISAPNP__
+#ifdef CONFIG_PNP
 static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
 #endif
 static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;	/* 0xf86,0x370,0x100 */
@@ -73,7 +69,7 @@
 MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
 MODULE_PARM_DESC(enable, "Enable OPL3-SA soundcard.");
 MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
-#ifdef __ISAPNP__
+#ifdef CONFIG_PNP
 MODULE_PARM(isapnp, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
 MODULE_PARM_DESC(isapnp, "ISA PnP detection for specified soundcard.");
 MODULE_PARM_SYNTAX(isapnp, SNDRV_ISAPNP_DESC);
@@ -147,8 +143,8 @@
 	snd_hwdep_t *synth;
 	snd_rawmidi_t *rmidi;
 	cs4231_t *cs4231;
-#ifdef __ISAPNP__
-	struct isapnp_dev *dev;
+#ifdef CONFIG_PNP
+	struct pnp_dev *dev;
 #endif
 	unsigned char ctlregs[0x20];
 	int ymode;		/* SL added */
@@ -163,33 +159,27 @@
 
 static snd_card_t *snd_opl3sa2_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
 
-#ifdef __ISAPNP__
-
-static struct isapnp_card *snd_opl3sa2_isapnp_cards[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_PTR;
-static const struct isapnp_card_id *snd_opl3sa2_isapnp_id[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_PTR;
+#ifdef CONFIG_PNP
 
-#define ISAPNP_OPL3SA2(_va, _vb, _vc, _device, _function) \
-        { \
-                ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
-                devs : { ISAPNP_DEVICE_ID(_va, _vb, _vc, _function), } \
-        }
+static struct pnp_card *snd_opl3sa2_isapnp_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
+static const struct pnp_card_id *snd_opl3sa2_isapnp_id[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
 
-static struct isapnp_card_id snd_opl3sa2_pnpids[] __devinitdata = {
+static struct pnp_card_id snd_opl3sa2_pnpids[] = {
 	/* Yamaha YMF719E-S (Genius Sound Maker 3DX) */
-	ISAPNP_OPL3SA2('Y','M','H',0x0020,0x0021),
+	{.id = "YMH0020", .driver_data = 0, devs : { {.id="YMH0021"}, } },
 	/* Yamaha OPL3-SA3 (integrated on Intel's Pentium II AL440LX motherboard) */
-	ISAPNP_OPL3SA2('Y','M','H',0x0030,0x0021),
+	{.id = "YMH0030", .driver_data = 0, devs : { {.id="YMH0021"}, } },
 	/* Yamaha OPL3-SA2 */
-	ISAPNP_OPL3SA2('Y','M','H',0x0800,0x0021),
+	{.id = "YMH0800", .driver_data = 0, devs : { {.id="YMH0021"}, } },
 	/* NeoMagic MagicWave 3DX */
-	ISAPNP_OPL3SA2('N','M','X',0x2200,0x2210),
+	{.id = "NMX2200", .driver_data = 0, devs : { {.id="NMX2210"}, } },
 	/* --- */
-	{ ISAPNP_CARD_END, }	/* end */
+	{.id = "", } /* end */
 };
 
-ISAPNP_CARD_TABLE(snd_opl3sa2_pnpids);
+/*PNP_CARD_TABLE(snd_opl3sa2_pnpids);*/
 
-#endif /* __ISAPNP__ */
+#endif /* CONFIG_PNP */
 
 
 /* read control port (w/o spinlock) */
@@ -634,41 +624,18 @@
 
 #endif /* CONFIG_PM */
 
-#ifdef __ISAPNP__
+#ifdef CONFIG_PNP
 static int __init snd_opl3sa2_isapnp(int dev, opl3sa2_t *chip)
 {
-        const struct isapnp_card_id *id = snd_opl3sa2_isapnp_id[dev];
-        struct isapnp_card *card = snd_opl3sa2_isapnp_cards[dev];
-	struct isapnp_dev *pdev;
-
-	chip->dev = isapnp_find_dev(card, id->devs[0].vendor, id->devs[0].function, NULL);
-	if (chip->dev->active) {
-		chip->dev = NULL;
-		return -EBUSY;
-	}
-	/* PnP initialization */
+        const struct pnp_card_id *id = snd_opl3sa2_isapnp_id[dev];
+        struct pnp_card *card = snd_opl3sa2_isapnp_cards[dev];
+	struct pnp_dev *pdev;
+
+	chip->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
 	pdev = chip->dev;
-	if (pdev->prepare(pdev)<0)
-		return -EAGAIN;
-	if (sb_port[dev] != SNDRV_AUTO_PORT)
-		isapnp_resource_change(&pdev->resource[0], sb_port[dev], 16);
-	if (wss_port[dev] != SNDRV_AUTO_PORT)
-		isapnp_resource_change(&pdev->resource[1], wss_port[dev], 8);
-	if (fm_port[dev] != SNDRV_AUTO_PORT)
-		isapnp_resource_change(&pdev->resource[2], fm_port[dev], 4);
-	if (midi_port[dev] != SNDRV_AUTO_PORT)
-		isapnp_resource_change(&pdev->resource[3], midi_port[dev], 2);
-	if (port[dev] != SNDRV_AUTO_PORT)
-		isapnp_resource_change(&pdev->resource[4], port[dev], 2);
-	if (dma1[dev] != SNDRV_AUTO_DMA)
-		isapnp_resource_change(&pdev->dma_resource[0], dma1[dev], 1);
-	if (dma2[dev] != SNDRV_AUTO_DMA)
-		isapnp_resource_change(&pdev->dma_resource[1], dma2[dev], 1);
-	if (irq[dev] != SNDRV_AUTO_IRQ)
-		isapnp_resource_change(&pdev->irq_resource[0], irq[dev], 1);
-	if (pdev->activate(pdev)<0) {
-		snd_printk("isapnp configure failure (out of resources?)\n");
-		return -EBUSY;
+	if (!pdev){
+		snd_printdd("isapnp OPL3-SA: a card was found but it did not contain the needed devices\n");
+		return -ENODEV;
 	}
 	sb_port[dev] = pdev->resource[0].start;
 	wss_port[dev] = pdev->resource[1].start;
@@ -685,19 +652,12 @@
 	return 0;
 }
 
-static void snd_opl3sa2_deactivate(opl3sa2_t *chip)
-{
-	if (chip->dev) {
-		chip->dev->deactivate(chip->dev);
-		chip->dev = NULL;
-	}
-}
-#endif /* __ISAPNP__ */
+#endif /* CONFIG_PNP */
 
 static int snd_opl3sa2_free(opl3sa2_t *chip)
 {
-#ifdef __ISAPNP__
-	snd_opl3sa2_deactivate(chip);
+#ifdef CONFIG_PNP
+	chip->dev = NULL;
 #endif
 #ifdef CONFIG_PM
 	if (chip->pm_dev)
@@ -731,7 +691,7 @@
 	};
 	int err;
 
-#ifdef __ISAPNP__
+#ifdef CONFIG_PNP
 	if (!isapnp[dev]) {
 #endif
 		if (port[dev] == SNDRV_AUTO_PORT) {
@@ -750,7 +710,7 @@
 			snd_printk("specify midi_port\n");
 			return -EINVAL;
 		}
-#ifdef __ISAPNP__
+#ifdef CONFIG_PNP
 	}
 #endif
 	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
@@ -766,7 +726,7 @@
 	chip->irq = -1;
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0)
 		goto __error;
-#ifdef __ISAPNP__
+#ifdef CONFIG_PNP
 	if (isapnp[dev] && (err = snd_opl3sa2_isapnp(dev, chip)) < 0)
 		goto __error;
 #endif
@@ -854,9 +814,9 @@
 	return err;
 }
 
-#ifdef __ISAPNP__
-static int __init snd_opl3sa2_isapnp_detect(struct isapnp_card *card,
-					    const struct isapnp_card_id *id)
+#ifdef CONFIG_PNP
+static int __init snd_opl3sa2_isapnp_detect(struct pnp_card *card,
+					    const struct pnp_card_id *id)
 {
         static int dev;
         int res;
@@ -874,7 +834,20 @@
         }
         return -ENODEV;
 }
-#endif /* __ISAPNP__ */
+
+static void snd_opl3sa2_isapnp_remove(struct pnp_card * card)
+{
+/* FIXME */
+}
+
+static struct pnpc_driver opl3sa2_pnpc_driver = {
+	.name		= "opl3sa2",
+	.id_table	= snd_opl3sa2_pnpids,
+	.probe		= snd_opl3sa2_isapnp_detect,
+	.remove		= snd_opl3sa2_isapnp_remove,
+};
+
+#endif /* CONFIG_PNP */
 
 static int __init alsa_card_opl3sa2_init(void)
 {
@@ -883,15 +856,15 @@
 	for (dev = 0; dev < SNDRV_CARDS; dev++) {
 		if (!enable[dev])
 			continue;
-#ifdef __ISAPNP__
+#ifdef CONFIG_PNP
 		if (isapnp[dev])
 			continue;
 #endif
 		if (snd_opl3sa2_probe(dev) >= 0)
 			cards++;
 	}
-#ifdef __ISAPNP__
-	cards += isapnp_probe_cards(snd_opl3sa2_pnpids, snd_opl3sa2_isapnp_detect);
+#ifdef CONFIG_PNP
+	cards += pnpc_register_driver(&opl3sa2_pnpc_driver);
 #endif
 	if (!cards) {
 #ifdef MODULE
@@ -940,7 +913,7 @@
 	       get_option(&str,&dma1[nr_dev]) == 2 &&
 	       get_option(&str,&dma2[nr_dev]) == 2 &&
 	       get_option(&str,&opl3sa3_ymode[nr_dev]) == 2);
-#ifdef __ISAPNP__
+#ifdef CONFIG_PNP
 	if (pnp != INT_MAX)
 		isapnp[nr_dev] = pnp;
 #endif
diff -Nru a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c
--- a/sound/oss/ac97_codec.c	Mon Dec  9 18:46:35 2002
+++ b/sound/oss/ac97_codec.c	Mon Dec  9 18:46:35 2002
@@ -52,6 +52,8 @@
 #include <linux/ac97_codec.h>
 #include <asm/uaccess.h>
 
+#define CODEC_ID_BUFSZ 14
+
 static int ac97_read_mixer(struct ac97_codec *codec, int oss_channel);
 static void ac97_write_mixer(struct ac97_codec *codec, int oss_channel, 
 			     unsigned int left, unsigned int right);
@@ -113,7 +115,7 @@
 	{0x41445340, "Analog Devices AD1881",	&null_ops},
 	{0x41445348, "Analog Devices AD1881A",	&null_ops},
 	{0x41445360, "Analog Devices AD1885",	&default_ops},
-	{0x41445361, "Analog Devices AD1886",	&default_ops},
+	{0x41445361, "Analog Devices AD1886",	&ad1886_ops},
 	{0x41445460, "Analog Devices AD1885",	&default_ops},
 	{0x41445461, "Analog Devices AD1886",	&ad1886_ops},
 	{0x414B4D00, "Asahi Kasei AK4540",	&null_ops},
@@ -654,6 +656,29 @@
 }
 
 /**
+ *	codec_id	-  Turn id1/id2 into a PnP string
+ *	@id1: Vendor ID1
+ *	@id2: Vendor ID2
+ *	@buf: CODEC_ID_BUFSZ byte buffer
+ *
+ *	Fills buf with a zero terminated PnP ident string for the id1/id2
+ *	pair. For convenience the return is the passed in buffer pointer.
+ */
+ 
+static char *codec_id(u16 id1, u16 id2, char *buf)
+{
+	if(id1&0x8080) {
+		snprintf(buf, CODEC_ID_BUFSZ, "0x%04x:0x%04x", id1, id2);
+	} else {
+		buf[0] = (id1 >> 8);
+		buf[1] = (id1 & 0xFF);
+		buf[2] = (id2 >> 8);
+		snprintf(buf+3, CODEC_ID_BUFSZ - 3, "%d", id2&0xFF);
+	}
+	return buf;
+}
+ 
+/**
  *	ac97_probe_codec - Initialize and setup AC97-compatible codec
  *	@codec: (in/out) Kernel info for a single AC97 codec
  *
@@ -681,6 +706,7 @@
 	u16 id1, id2;
 	u16 audio, modem;
 	int i;
+	char cidbuf[CODEC_ID_BUFSZ];
 
 	/* probing AC97 codec, AC97 2.0 says that bit 15 of register 0x00 (reset) should 
 	 * be read zero.
@@ -698,13 +724,16 @@
 
 	if ((audio = codec->codec_read(codec, AC97_RESET)) & 0x8000) {
 		printk(KERN_ERR "ac97_codec: %s ac97 codec not present\n",
-		       codec->id ? "Secondary" : "Primary");
+		       (codec->id & 0x2) ? (codec->id&1 ? "4th" : "Tertiary") 
+		       : (codec->id&1 ? "Secondary":  "Primary"));
 		return 0;
 	}
 
 	/* probe for Modem Codec */
 	codec->codec_write(codec, AC97_EXTENDED_MODEM_ID, 0L);
-	modem = codec->codec_read(codec, AC97_EXTENDED_MODEM_ID);
+	modem = codec->codec_read(codec, AC97_EXTENDED_MODEM_ID) & 1;
+	modem |= (audio&2);
+	audio &= ~2;
 
 	codec->name = NULL;
 	codec->codec_ops = &null_ops;
@@ -721,9 +750,9 @@
 	}
 	if (codec->name == NULL)
 		codec->name = "Unknown";
-	printk(KERN_INFO "ac97_codec: AC97 %s codec, id: 0x%04x:"
-	       "0x%04x (%s)\n", audio ? "Audio" : (modem ? "Modem" : ""),
-	       id1, id2, codec->name);
+	printk(KERN_INFO "ac97_codec: AC97 %s codec, id: %s (%s)\n", 
+		modem ? "Modem" : (audio ? "Audio" : ""),
+	       codec_id(id1, id2, cidbuf), codec->name);
 
 	return ac97_init_mixer(codec);
 }
@@ -746,10 +775,10 @@
 
 	/* detect bit resolution */
 	codec->codec_write(codec, AC97_MASTER_VOL_STEREO, 0x2020);
-	if(codec->codec_read(codec, AC97_MASTER_VOL_STEREO) == 0x1f1f)
-		codec->bit_resolution = 5;
-	else
+	if(codec->codec_read(codec, AC97_MASTER_VOL_STEREO) == 0x2020)
 		codec->bit_resolution = 6;
+	else
+		codec->bit_resolution = 5;
 
 	/* generic OSS to AC97 wrapper */
 	codec->read_mixer = ac97_read_mixer;
@@ -917,7 +946,7 @@
 
 /* 
  *	Presario700 workaround 
- * 	for Jack Sense/SPDIF Register misetting causing
+ * 	for Jack Sense/SPDIF Register mis-setting causing
  *	no audible output
  *	by Santiago Nullo 04/05/2002
  */
diff -Nru a/sound/oss/gus_wave.c b/sound/oss/gus_wave.c
--- a/sound/oss/gus_wave.c	Mon Dec  9 18:46:35 2002
+++ b/sound/oss/gus_wave.c	Mon Dec  9 18:46:35 2002
@@ -226,8 +226,6 @@
 
 static void gus_poke(long addr, unsigned char data)
 {				/* Writes a byte to the DRAM */
-	unsigned long   flags;
-
 	outb((0x43), u_Command);
 	outb((addr & 0xff), u_DataLo);
 	outb(((addr >> 8) & 0xff), u_DataHi);
diff -Nru a/sound/oss/i810_audio.c b/sound/oss/i810_audio.c
--- a/sound/oss/i810_audio.c	Mon Dec  9 18:46:50 2002
+++ b/sound/oss/i810_audio.c	Mon Dec  9 18:46:50 2002
@@ -65,29 +65,41 @@
  *	If you need to force a specific rate set the clocking= option
  *
  *	This driver is cursed. (Ben LaHaise)
+ *
+ *
+ *  ICH 4 caveats
+ *
+ *      The ICH4 has the feature, that the codec ID doesn't have to be 
+ *      congruent with the IO connection.
+ * 
+ *      Therefore, from driver version 0.23 on, there is a "codec ID" <->
+ *      "IO register base offset" mapping (card->ac97_id_map) field.
+ *   
+ *      Juergen "George" Sawinski (jsaw) 
  */
  
 #include <linux/module.h>
 #include <linux/version.h>
 #include <linux/string.h>
-#include <linux/interrupt.h>
+#include <linux/ctype.h>
 #include <linux/ioport.h>
-#include <linux/wait.h>
+#include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/sound.h>
 #include <linux/slab.h>
 #include <linux/soundcard.h>
 #include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+#include <asm/dma.h>
 #include <linux/init.h>
 #include <linux/poll.h>
 #include <linux/spinlock.h>
 #include <linux/smp_lock.h>
 #include <linux/ac97_codec.h>
 #include <linux/wrapper.h>
-
-#include <asm/io.h>
-#include <asm/page.h>
 #include <asm/uaccess.h>
+#include <asm/hardirq.h>
 
 #ifndef PCI_DEVICE_ID_INTEL_82801
 #define PCI_DEVICE_ID_INTEL_82801	0x2415
@@ -113,9 +125,18 @@
 #ifndef PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO
 #define PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO	0x01b1
 #endif
+#ifndef PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO
+#define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO	0x006a
+#endif
+#ifndef PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO
+#define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO	0x00da
+#endif
 #ifndef PCI_DEVICE_ID_AMD_768_AUDIO
 #define PCI_DEVICE_ID_AMD_768_AUDIO	0x7445
 #endif
+#ifndef PCI_DEVICE_ID_AMD_8111_AC97
+#define PCI_DEVICE_ID_AMD_8111_AC97	0x746d
+#endif
 
 static int ftsodell=0;
 static int strict_clocking=0;
@@ -126,6 +147,7 @@
 //#define DEBUG2
 //#define DEBUG_INTERRUPTS
 //#define DEBUG_MMAP
+//#define DEBUG_MMIO
 
 #define ADC_RUNNING	1
 #define DAC_RUNNING	2
@@ -168,6 +190,11 @@
  * each dma engine has controlling registers.  These goofy
  * names are from the datasheet, but make it easy to write
  * code while leafing through it.
+ *
+ * ICH4 has 6 dma engines, pcm in, pcm out, mic, pcm in 2, 
+ * mic in 2, s/pdif.   Of special interest is the fact that
+ * the upper 3 DMA engines on the ICH4 *must* be accessed
+ * via mmio access instead of pio access.
  */
 
 #define ENUM_ENGINE(PRE,DIG) 									\
@@ -192,6 +219,14 @@
 	CAS	 = 	0x34			/* Codec Write Semaphore Register */
 };
 
+ENUM_ENGINE(MC2,4);     /* Mic In 2 */
+ENUM_ENGINE(PI2,5);     /* PCM In 2 */
+ENUM_ENGINE(SP,6);      /* S/PDIF */
+
+enum {
+	SDM =           0x80                    /* SDATA_IN Map Register */
+};
+
 /* interrupts for a dma engine */
 #define DMA_INT_FIFO		(1<<4)  /* fifo under/over flow */
 #define DMA_INT_COMPLETE	(1<<3)  /* buffer read/write complete and ioc set */
@@ -211,8 +246,7 @@
 #define INT_GPI		(1<<0)
 #define INT_MASK (INT_SEC|INT_PRI|INT_MC|INT_PO|INT_PI|INT_MO|INT_NI|INT_GPI)
 
-
-#define DRIVER_VERSION "0.21"
+#define DRIVER_VERSION "0.24"
 
 /* magic numbers to protect our data structures */
 #define I810_CARD_MAGIC		0x5072696E /* "Prin" */
@@ -221,7 +255,7 @@
 #define NR_HW_CH		3
 
 /* maxinum number of AC97 codecs connected, AC97 2.0 defined 4 */
-#define NR_AC97		2
+#define NR_AC97                 4
 
 /* Please note that an 8bit mono stream is not valid on this card, you must have a 16bit */
 /* stream at a minimum for this card to be happy */
@@ -256,6 +290,25 @@
 	"AMD-8111 IOHub"
 };
 
+/* These are capabilities (and bugs) the chipsets _can_ have */
+static struct {
+	int16_t      nr_ac97;
+#define CAP_MMIO                 0x0001
+#define CAP_20BIT_AUDIO_SUPPORT  0x0002
+	u_int16_t flags;
+} card_cap[] = {
+	{  1, 0x0000 }, /* ICH82801AA */
+	{  1, 0x0000 }, /* ICH82901AB */
+	{  1, 0x0000 }, /* INTEL440MX */
+	{  1, 0x0000 }, /* INTELICH2 */
+	{  2, 0x0000 }, /* INTELICH3 */
+        {  3, 0x0003 }, /* INTELICH4 */
+	/*@FIXME to be verified*/	{  2, 0x0000 }, /* SI7012 */
+	/*@FIXME to be verified*/	{  2, 0x0000 }, /* NVIDIA_NFORCE */
+	/*@FIXME to be verified*/	{  2, 0x0000 }, /* AMD768 */
+	/*@FIXME to be verified*/	{  3, 0x0001 }, /* AMD8111 */
+};
+
 static struct pci_device_id i810_pci_tbl [] __initdata = {
 	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801,
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, ICH82801AA},
@@ -273,9 +326,13 @@
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, SI7012},
 	{PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO,
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, NVIDIA_NFORCE},
+	{PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO,
+	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, NVIDIA_NFORCE},
+	{PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO,
+	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, NVIDIA_NFORCE},
 	{PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_768_AUDIO,
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, AMD768},
-	{PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_AUDIO,
+	{PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_AC97,
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, AMD8111},
 	{0,}
 };
@@ -365,6 +422,7 @@
 	/* PCI device stuff */
 	struct pci_dev * pci_dev;
 	u16 pci_id;
+	u16 pci_id_internal; /* used to access card_cap[] */
 #ifdef CONFIG_PM	
 	u16 pm_suspended;
 	u32 pm_save_state[64/sizeof(u32)];
@@ -374,6 +432,7 @@
 	int dev_audio;
 
 	/* structures for abstraction of hardware facilities, codecs, banks and channels*/
+	u16    ac97_id_map[NR_AC97];
 	struct ac97_codec *ac97_codec[NR_AC97];
 	struct i810_state *states[NR_HW_CH];
 	struct i810_channel *channel;	/* 1:1 to states[] but diff. lifetime */
@@ -384,9 +443,16 @@
 	u16 channels;
 	
 	/* hardware resources */
-	unsigned long iobase;
 	unsigned long ac97base;
+	unsigned long iobase;
 	u32 irq;
+
+	unsigned long ac97base_mmio_phys;
+	unsigned long iobase_mmio_phys;
+	u_int8_t *ac97base_mmio;
+	u_int8_t *iobase_mmio;
+
+	int           use_mmio;
 	
 	/* Function support */
 	struct i810_channel *(*alloc_pcm_channel)(struct i810_card *);
@@ -399,6 +465,12 @@
 	int initializing;
 };
 
+/* extract register offset from codec struct */
+#define IO_REG_OFF(codec) (((struct i810_card *) codec->private_data)->ac97_id_map[codec->id])
+
+/* set LVI from CIV */
+#define CIV_TO_LVI(port, off) outb((inb(port+OFF_CIV)+off) & 31, port+OFF_LVI)
+
 static struct i810_card *devs = NULL;
 
 static int i810_open_mixdev(struct inode *inode, struct file *file);
@@ -406,6 +478,10 @@
 			     unsigned int cmd, unsigned long arg);
 static u16 i810_ac97_get(struct ac97_codec *dev, u8 reg);
 static void i810_ac97_set(struct ac97_codec *dev, u8 reg, u16 data);
+static u16 i810_ac97_get_mmio(struct ac97_codec *dev, u8 reg);
+static void i810_ac97_set_mmio(struct ac97_codec *dev, u8 reg, u16 data);
+static u16 i810_ac97_get_io(struct ac97_codec *dev, u8 reg);
+static void i810_ac97_set_io(struct ac97_codec *dev, u8 reg, u16 data);
 
 static struct i810_channel *i810_alloc_pcm_channel(struct i810_card *card)
 {
@@ -757,7 +833,8 @@
 	if (dmabuf->count < dmabuf->dmasize && dmabuf->ready && !dmabuf->enable &&
 	    (dmabuf->trigger & PCM_ENABLE_INPUT)) {
 		dmabuf->enable |= ADC_RUNNING;
-		outb((1<<4) | (1<<2) | 1, state->card->iobase + PI_CR);
+		// Interrupt enable, LVI enable, DMA enable
+		outb(0x10 | 0x04 | 0x01, state->card->iobase + PI_CR);
 	}
 }
 
@@ -806,7 +883,8 @@
 	if (dmabuf->count > 0 && dmabuf->ready && !dmabuf->enable &&
 	    (dmabuf->trigger & PCM_ENABLE_OUTPUT)) {
 		dmabuf->enable |= DAC_RUNNING;
-		outb((1<<4) | (1<<2) | 1, state->card->iobase + PO_CR);
+		// Interrupt enable, LVI enable, DMA enable
+		outb(0x10 | 0x04 | 0x01, state->card->iobase + PO_CR);
 	}
 }
 static void start_dac(struct i810_state *state)
@@ -973,11 +1051,11 @@
 		}
 		spin_lock_irqsave(&state->card->lock, flags);
 		outb(2, state->card->iobase+c->port+OFF_CR);   /* reset DMA machine */
+		while( inb(state->card->iobase+c->port+OFF_CR) & 0x02 ) ;
 		outl((u32)state->card->chandma +
 		    c->num*sizeof(struct i810_channel),
 		    state->card->iobase+c->port+OFF_BDBAR);
-		outb(0, state->card->iobase+c->port+OFF_CIV);
-		outb(0, state->card->iobase+c->port+OFF_LVI);
+		CIV_TO_LVI(state->card->iobase+c->port, 0);
 
 		spin_unlock_irqrestore(&state->card->lock, flags);
 
@@ -1023,13 +1101,13 @@
 		if(rec && dmabuf->count < dmabuf->dmasize &&
 		   (dmabuf->trigger & PCM_ENABLE_INPUT))
 		{
-			outb((inb(port+OFF_CIV)+1)&31, port+OFF_LVI);
+			CIV_TO_LVI(port, 1);
 			__start_adc(state);
 			while( !(inb(port + OFF_CR) & ((1<<4) | (1<<2))) ) ;
 		} else if (!rec && dmabuf->count &&
 			   (dmabuf->trigger & PCM_ENABLE_OUTPUT))
 		{
-			outb((inb(port+OFF_CIV)+1)&31, port+OFF_LVI);
+			CIV_TO_LVI(port, 1);
 			__start_dac(state);
 			while( !(inb(port + OFF_CR) & ((1<<4) | (1<<2))) ) ;
 		}
@@ -1297,7 +1375,6 @@
 				if (dmabuf->enable & ADC_RUNNING)
 					__stop_adc(state);
 				dmabuf->enable = 0;
-				wake_up(&dmabuf->wait);
 #ifdef DEBUG_INTERRUPTS
 				printk(" STOP ");
 #endif
@@ -1743,11 +1820,12 @@
 		}
 		if (c != NULL) {
 			outb(2, state->card->iobase+c->port+OFF_CR);   /* reset DMA machine */
+			while ( inb(state->card->iobase+c->port+OFF_CR) & 2 )
+				cpu_relax();
 			outl((u32)state->card->chandma +
 			    c->num*sizeof(struct i810_channel),
 			    state->card->iobase+c->port+OFF_BDBAR);
-			outb(0, state->card->iobase+c->port+OFF_CIV);
-			outb(0, state->card->iobase+c->port+OFF_LVI);
+			CIV_TO_LVI(state->card->iobase+c->port, 0);
 		}
 
 		spin_unlock_irqrestore(&state->card->lock, flags);
@@ -1868,7 +1946,8 @@
 		}
 
 		/* ICH and ICH0 only support 2 channels */
-		if ( state->card->pci_id == 0x2415 || state->card->pci_id == 0x2425 ) 
+		if ( state->card->pci_id == PCI_DEVICE_ID_INTEL_82801 
+		     || state->card->pci_id == PCI_DEVICE_ID_INTEL_82901) 
 			return put_user(2, (int *)arg);
 	
 		/* Multi-channel support was added with ICH2. Bits in */
@@ -1887,12 +1966,14 @@
 
 		switch ( val ) {
 			case 2: /* 2 channels is always supported */
-				outl(state->card->iobase + GLOB_CNT, (i_glob_cnt & 0xcfffff));
+				outl(i_glob_cnt & 0xffcfffff,
+				     state->card->iobase + GLOB_CNT);
 				/* Do we need to change mixer settings????  */
 				break;
 			case 4: /* Supported on some chipsets, better check first */
 				if ( state->card->channels >= 4 ) {
-					outl(state->card->iobase + GLOB_CNT, ((i_glob_cnt & 0xcfffff) | 0x0100000));
+					outl((i_glob_cnt & 0xffcfffff) | 0x100000,
+					      state->card->iobase + GLOB_CNT);
 					/* Do we need to change mixer settings??? */
 				} else {
 					val = ret;
@@ -1900,7 +1981,8 @@
 				break;
 			case 6: /* Supported on some chipsets, better check first */
 				if ( state->card->channels >= 6 ) {
-					outl(state->card->iobase + GLOB_CNT, ((i_glob_cnt & 0xcfffff) | 0x0200000));
+					outl((i_glob_cnt & 0xffcfffff) | 0x200000,
+					      state->card->iobase + GLOB_CNT);
 					/* Do we need to change mixer settings??? */
 				} else {
 					val = ret;
@@ -2037,9 +2119,7 @@
 		printk("SNDCTL_DSP_GETOPTR %d, %d, %d, %d\n", cinfo.bytes,
 			cinfo.blocks, cinfo.ptr, dmabuf->count);
 #endif
-		if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
-			return -EFAULT;
-		return 0;
+		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
 	case SNDCTL_DSP_GETISPACE:
 		if (!(file->f_mode & FMODE_READ))
@@ -2078,9 +2158,8 @@
 		printk("SNDCTL_DSP_GETIPTR %d, %d, %d, %d\n", cinfo.bytes,
 			cinfo.blocks, cinfo.ptr, dmabuf->count);
 #endif
-		if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
-			return -EFAULT;
-		return 0;
+		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
+
 	case SNDCTL_DSP_NONBLOCK:
 #ifdef DEBUG
 		printk("SNDCTL_DSP_NONBLOCK\n");
@@ -2421,6 +2500,9 @@
 			i810_set_spdif_output(state, AC97_EA_SPSA_3_4, spdif_locked);
 		} else {
 			i810_set_dac_rate(state, 8000);
+			/* Put the ACLink in 2 channel mode by default */
+			i = inl(card->iobase + GLOB_CNT);
+			outl(i & 0xffcfffff, card->iobase + GLOB_CNT);
 		}
 	}
 		
@@ -2485,27 +2567,86 @@
 
 /* Write AC97 codec registers */
 
-static u16 i810_ac97_get(struct ac97_codec *dev, u8 reg)
+static u16 i810_ac97_get_mmio(struct ac97_codec *dev, u8 reg)
 {
 	struct i810_card *card = dev->private_data;
 	int count = 100;
-	u8 reg_set = ((dev->id)?((reg&0x7f)|0x80):(reg&0x7f));
+	u16 reg_set = IO_REG_OFF(dev) | (reg&0x7f);
+	
+	while(count-- && (readb(card->iobase_mmio + CAS) & 1)) 
+		udelay(1);
+	
+#ifdef DEBUG_MMIO
+	{
+		u16 ans = readw(card->ac97base_mmio + reg_set);
+		printk(KERN_DEBUG "i810_audio: ac97_get_mmio(%d) -> 0x%04X\n", ((int) reg_set) & 0xffff, (u32) ans);
+		return ans;
+	}
+#else
+	return readw(card->ac97base_mmio + reg_set);
+#endif
+}
 
+static u16 i810_ac97_get_io(struct ac97_codec *dev, u8 reg)
+{
+	struct i810_card *card = dev->private_data;
+	int count = 100;
+	u16 reg_set = IO_REG_OFF(dev) | (reg&0x7f);
+	
 	while(count-- && (inb(card->iobase + CAS) & 1)) 
 		udelay(1);
 	
 	return inw(card->ac97base + reg_set);
 }
 
-static void i810_ac97_set(struct ac97_codec *dev, u8 reg, u16 data)
+static void i810_ac97_set_mmio(struct ac97_codec *dev, u8 reg, u16 data)
 {
 	struct i810_card *card = dev->private_data;
 	int count = 100;
-	u8 reg_set = ((dev->id)?((reg&0x7f)|0x80):(reg&0x7f));
+	u16 reg_set = IO_REG_OFF(dev) | (reg&0x7f);
+	
+	while(count-- && (readb(card->iobase_mmio + CAS) & 1)) 
+		udelay(1);
+	
+	writew(data, card->ac97base_mmio + reg_set);
+
+#ifdef DEBUG_MMIO
+	printk(KERN_DEBUG "i810_audio: ac97_set_mmio(0x%04X, %d)\n", (u32) data, ((int) reg_set) & 0xffff);
+#endif
+}
 
+static void i810_ac97_set_io(struct ac97_codec *dev, u8 reg, u16 data)
+{
+	struct i810_card *card = dev->private_data;
+	int count = 100;
+	u16 reg_set = IO_REG_OFF(dev) | (reg&0x7f);
+	
 	while(count-- && (inb(card->iobase + CAS) & 1)) 
 		udelay(1);
-	outw(data, card->ac97base + reg_set);
+	
+        outw(data, card->ac97base + reg_set);
+}
+
+static u16 i810_ac97_get(struct ac97_codec *dev, u8 reg)
+{
+	struct i810_card *card = dev->private_data;
+	if (card->use_mmio) {
+		return i810_ac97_get_mmio(dev, reg);
+	}
+	else {
+		return i810_ac97_get_io(dev, reg);
+	}
+}
+
+static void i810_ac97_set(struct ac97_codec *dev, u8 reg, u16 data)
+{
+	struct i810_card *card = dev->private_data;
+	if (card->use_mmio) {
+		i810_ac97_set_mmio(dev, reg, data);
+	}
+	else {
+		i810_ac97_set_io(dev, reg, data);
+	}
 }
 
 
@@ -2514,7 +2655,7 @@
 static int i810_open_mixdev(struct inode *inode, struct file *file)
 {
 	int i;
-	unsigned int minor = minor(inode->i_rdev);
+	int minor = minor(inode->i_rdev);
 	struct i810_card *card = devs;
 
 	for (card = devs; card != NULL; card = card->next) {
@@ -2530,7 +2671,7 @@
 			set_current_state(TASK_UNINTERRUPTIBLE);
 			schedule_timeout(HZ/20);
 		}
-		for (i = 0; i < NR_AC97 && card && !card->initializing; i++)
+		for (i = 0; i < NR_AC97 && card && !card->initializing; i++) 
 			if (card->ac97_codec[i] != NULL &&
 			    card->ac97_codec[i]->dev_mixer == minor) {
 				file->private_data = card->ac97_codec[i];
@@ -2558,10 +2699,18 @@
 /* AC97 codec initialisation.  These small functions exist so we don't
    duplicate code between module init and apm resume */
 
-static inline int i810_ac97_exists(struct i810_card *card,int ac97_number)
+static inline int i810_ac97_exists(struct i810_card *card, int ac97_number)
 {
 	u32 reg = inl(card->iobase + GLOB_STA);
-	return (reg & (0x100 << ac97_number));
+	switch (ac97_number) {
+	case 0:
+		return reg & (1<<8);
+	case 1: 
+		return reg & (1<<9);
+	case 2:
+		return reg & (1<<28);
+	}
+	return 0;
 }
 
 static inline int i810_ac97_enable_variable_rate(struct ac97_codec *codec)
@@ -2584,10 +2733,9 @@
 	/* power it all up */
 	i810_ac97_set(codec, AC97_POWER_CONTROL,
 		      i810_ac97_get(codec, AC97_POWER_CONTROL) & ~0x7f00);
+
 	/* wait for analog ready */
-	for (i=10;
-	     i && ((i810_ac97_get(codec, AC97_POWER_CONTROL) & 0xf) != 0xf);
-	     i--)
+	for (i=10; i && ((i810_ac97_get(codec, AC97_POWER_CONTROL) & 0xf) != 0xf); i--)
 	{
 		set_current_state(TASK_UNINTERRUPTIBLE);
 		schedule_timeout(HZ/20);
@@ -2595,11 +2743,18 @@
 	return i;
 }
 
-/* if I knew what this did, I'd give it a better name */
-static int i810_ac97_random_init_stuff(struct i810_card *card)
+/**
+ *	i810_ac97_power_up_bus	-	bring up AC97 link
+ *	@card : ICH audio device to power up
+ *
+ *	Bring up the ACLink AC97 codec bus
+ */
+ 
+static int i810_ac97_power_up_bus(struct i810_card *card)
 {	
 	u32 reg = inl(card->iobase + GLOB_CNT);
 	int i;
+	int primary_codec_id = 0;
 
 	if((reg&2)==0)	/* Cold required */
 		reg|=2;
@@ -2607,8 +2762,13 @@
 		reg|=4;	/* Warm */
 		
 	reg&=~8;	/* ACLink on */
-	outl(reg , card->iobase + GLOB_CNT);
 	
+	/* At this point we deassert AC_RESET # */
+	outl(reg , card->iobase + GLOB_CNT);
+
+	/* We must now allow time for the Codec initialisation.
+	   600mS is the specified time */
+	   	
 	for(i=0;i<10;i++)
 	{
 		if((inl(card->iobase+GLOB_CNT)&4)==0)
@@ -2625,7 +2785,31 @@
 
 	set_current_state(TASK_UNINTERRUPTIBLE);
 	schedule_timeout(HZ/2);
-	reg = inl(card->iobase + GLOB_STA);
+
+	/*
+	 *	See if the primary codec comes ready. This must happen
+	 *	before we start doing DMA stuff
+	 */	
+	/* see i810_ac97_init for the next 7 lines (jsaw) */
+	inw(card->ac97base);
+	if ((card->pci_id == PCI_DEVICE_ID_INTEL_ICH4)
+	    && (card->use_mmio)) {
+		primary_codec_id = (int) readl(card->iobase_mmio + SDM) & 0x3;
+		printk(KERN_INFO "i810_audio: Primary codec has ID %d\n",
+		       primary_codec_id);
+	}
+
+	if(! i810_ac97_exists(card, primary_codec_id))
+	{
+		printk(KERN_INFO "i810_audio: Codec not ready.. wait.. ");
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(HZ);	/* actually 600mS by the spec */
+
+		if(i810_ac97_exists(card, primary_codec_id))
+			printk("OK\n");
+		else 
+			printk("no response.\n");
+	}
 	inw(card->ac97base);
 	return 1;
 }
@@ -2633,12 +2817,14 @@
 static int __init i810_ac97_init(struct i810_card *card)
 {
 	int num_ac97 = 0;
+	int ac97_id;
 	int total_channels = 0;
+	int nr_ac97_max = card_cap[card->pci_id_internal].nr_ac97;
 	struct ac97_codec *codec;
 	u16 eid;
 	u32 reg;
 
-	if(!i810_ac97_random_init_stuff(card)) return 0;
+	if(!i810_ac97_power_up_bus(card)) return 0;
 
 	/* Number of channels supported */
 	/* What about the codec?  Just because the ICH supports */
@@ -2654,26 +2840,47 @@
 		card->channels = 6;
 	else if ( reg & 0x0100000 )
 		card->channels = 4;
-	printk("i810_audio: Audio Controller supports %d channels.\n", card->channels);
+	printk(KERN_INFO "i810_audio: Audio Controller supports %d channels.\n", card->channels);
+	printk(KERN_INFO "i810_audio: Defaulting to base 2 channel mode.\n");
+	reg = inl(card->iobase + GLOB_CNT);
+	outl(reg & 0xffcfffff, card->iobase + GLOB_CNT);
 		
-	inw(card->ac97base);
+	for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) 
+		card->ac97_codec[num_ac97] = NULL;
 
-	for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) {
+	/*@FIXME I don't know, if I'm playing to safe here... (jsaw) */
+	if ((nr_ac97_max > 2) && !card->use_mmio) nr_ac97_max = 2;
 
-		/* Assume codec isn't available until we go through the
-		 * gauntlet below */
-		card->ac97_codec[num_ac97] = NULL;
+	for (num_ac97 = 0; num_ac97 < nr_ac97_max; num_ac97++) {
+		/* codec reset */
+		printk(KERN_INFO "i810_audio: Resetting connection %d\n", num_ac97);
+		if (card->use_mmio) readw(card->ac97base_mmio + 0x80*num_ac97);
+		else inw(card->ac97base + 0x80*num_ac97);
+
+		/* If we have the SDATA_IN Map Register, as on ICH4, we
+		   do not loop thru all possible codec IDs but thru all 
+		   possible IO channels. Bit 0:1 of SDM then holds the 
+		   last codec ID spoken to. 
+		*/
+		if ((card->pci_id == PCI_DEVICE_ID_INTEL_ICH4)
+		    && (card->use_mmio)) {
+			ac97_id = (int) readl(card->iobase_mmio + SDM) & 0x3;
+			printk(KERN_INFO "i810_audio: Connection %d with codec id %d\n",
+			       num_ac97, ac97_id);
+		}
+		else {
+			ac97_id = num_ac97;
+		}
 
 		/* The ICH programmer's reference says you should   */
 		/* check the ready status before probing. So we chk */
 		/*   What do we do if it's not ready?  Wait and try */
 		/*   again, or abort?                               */
-		if (!i810_ac97_exists(card,num_ac97)) {
+		if (!i810_ac97_exists(card, ac97_id)) {
 			if(num_ac97 == 0)
 				printk(KERN_ERR "i810_audio: Primary codec not ready.\n");
-			break; /* I think this works, if not ready stop */
 		}
-
+		
 		if ((codec = kmalloc(sizeof(struct ac97_codec), GFP_KERNEL)) == NULL)
 			return -ENOMEM;
 		memset(codec, 0, sizeof(struct ac97_codec));
@@ -2681,13 +2888,20 @@
 		/* initialize some basic codec information, other fields will be filled
 		   in ac97_probe_codec */
 		codec->private_data = card;
-		codec->id = num_ac97;
+		codec->id = ac97_id;
+		card->ac97_id_map[ac97_id] = num_ac97 * 0x80;
 
-		codec->codec_read = i810_ac97_get;
-		codec->codec_write = i810_ac97_set;
+		if (card->use_mmio) {	
+			codec->codec_read = i810_ac97_get_mmio;
+			codec->codec_write = i810_ac97_set_mmio;
+		}
+		else {
+			codec->codec_read = i810_ac97_get_io;
+			codec->codec_write = i810_ac97_set_io;
+		}
 	
 		if(!i810_ac97_probe_and_powerup(card,codec)) {
-			printk("i810_audio: timed out waiting for codec %d analog ready.\n", num_ac97);
+			printk(KERN_ERR "i810_audio: timed out waiting for codec %d analog ready.\n", ac97_id);
 			kfree(codec);
 			break;	/* it didn't work */
 		}
@@ -2696,7 +2910,7 @@
 		
 		/* Don't attempt to get eid until powerup is complete */
 		eid = i810_ac97_get(codec, AC97_EXTENDED_ID);
-		
+
 		if(eid==0xFFFFFF)
 		{
 			printk(KERN_WARNING "i810_audio: no codec attached ?\n");
@@ -2704,16 +2918,27 @@
 			break;
 		}
 		
+		/* Check for an AC97 1.0 soft modem (ID1) */
+		
+		if(codec->codec_read(codec, AC97_RESET) & 2)
+		{
+			printk(KERN_WARNING "i810_audio: codec %d is an AC97 1.0 softmodem - skipping.\n", ac97_id);
+			kfree(codec);
+			continue;
+		}
+		
+		/* Check for an AC97 2.x soft modem */
+		
 		codec->codec_write(codec, AC97_EXTENDED_MODEM_ID, 0L);
-		if(codec->codec_read(codec, AC97_EXTENDED_MODEM_ID))
+		if(codec->codec_read(codec, AC97_EXTENDED_MODEM_ID) & 1)
 		{
-			printk(KERN_WARNING "i810_audio: codec %d is a softmodem - skipping.\n", num_ac97);
+			printk(KERN_WARNING "i810_audio: codec %d is an AC97 2.x softmodem - skipping.\n", ac97_id);
 			kfree(codec);
 			continue;
 		}
 	
 		card->ac97_features = eid;
-				
+
 		/* Now check the codec for useful features to make up for
 		   the dumbness of the 810 hardware engine */
 
@@ -2727,6 +2952,11 @@
 			}			
 		}
    		
+		/* Turn on the amplifier */
+
+		codec->codec_write(codec, AC97_POWER_CONTROL, 
+			 codec->codec_read(codec, AC97_POWER_CONTROL) & ~0x8000);
+				
 		/* Determine how many channels the codec(s) support   */
 		/*   - The primary codec always supports 2            */
 		/*   - If the codec supports AMAP, surround DACs will */
@@ -2752,7 +2982,7 @@
 				total_channels += 2;
 			if (eid & 0x0140) /* LFE and Center channels */
 				total_channels += 2;
-			printk("i810_audio: AC'97 codec %d supports AMAP, total channels = %d\n", num_ac97, total_channels);
+			printk("i810_audio: AC'97 codec %d supports AMAP, total channels = %d\n", ac97_id, total_channels);
 		} else if (eid & 0x0400) {  /* this only works on 2.2 compliant codecs */
 			eid &= 0xffcf;
 			if((eid & 0xc000) != 0)	{
@@ -2774,14 +3004,14 @@
 			}
 			i810_ac97_set(codec, AC97_EXTENDED_ID, eid);
 			eid = i810_ac97_get(codec, AC97_EXTENDED_ID);
-			printk("i810_audio: AC'97 codec %d, new EID value = 0x%04x\n", num_ac97, eid);
+			printk("i810_audio: AC'97 codec %d, new EID value = 0x%04x\n", ac97_id, eid);
 			if (eid & 0x0080) /* L/R Surround channels */
 				total_channels += 2;
 			if (eid & 0x0140) /* LFE and Center channels */
 				total_channels += 2;
-			printk("i810_audio: AC'97 codec %d, DAC map configured, total channels = %d\n", num_ac97, total_channels);
+			printk("i810_audio: AC'97 codec %d, DAC map configured, total channels = %d\n", ac97_id, total_channels);
 		} else {
-			printk("i810_audio: AC'97 codec %d Unable to map surround DAC's (or DAC's not present), total channels = %d\n", num_ac97, total_channels);
+			printk("i810_audio: AC'97 codec %d Unable to map surround DAC's (or DAC's not present), total channels = %d\n", ac97_id, total_channels);
 		}
 
 		if ((codec->dev_mixer = register_sound_mixer(&i810_mixer_fops, -1)) < 0) {
@@ -2830,6 +3060,8 @@
 		init_MUTEX(&state->open_sem);
 		dmabuf->fmt = I810_FMT_STEREO | I810_FMT_16BIT;
 		dmabuf->trigger = PCM_ENABLE_OUTPUT;
+		i810_set_spdif_output(state, -1, 0);
+		i810_set_dac_channels(state, 2);
 		i810_set_dac_rate(state, 48000);
 		if(prog_dmabuf(state, 0) != 0) {
 			goto config_out_nodmabuf;
@@ -2838,17 +3070,16 @@
 			goto config_out;
 		}
 		dmabuf->count = dmabuf->dmasize;
-		outb(31,card->iobase+dmabuf->write_channel->port+OFF_LVI);
+		CIV_TO_LVI(card->iobase+dmabuf->write_channel->port, 31);
 		local_irq_save(flags);
 		start_dac(state);
 		offset = i810_get_dma_addr(state, 0);
 		mdelay(50);
 		new_offset = i810_get_dma_addr(state, 0);
 		stop_dac(state);
-		outb(2,card->iobase+dmabuf->write_channel->port+OFF_CR);
 		local_irq_restore(flags);
 		i = new_offset - offset;
-#ifdef DEBUG
+#ifdef DEBUG_INTERRUPTS
 		printk("i810_audio: %d bytes in 50 milliseconds\n", i);
 #endif
 		if(i == 0)
@@ -2890,10 +3121,25 @@
 	memset(card, 0, sizeof(*card));
 
 	card->initializing = 1;
-	card->iobase = pci_resource_start (pci_dev, 1);
-	card->ac97base = pci_resource_start (pci_dev, 0);
 	card->pci_dev = pci_dev;
 	card->pci_id = pci_id->device;
+	card->ac97base = pci_resource_start (pci_dev, 0);
+	card->iobase = pci_resource_start (pci_dev, 1);
+
+	/* if chipset could have mmio capability, check it */ 
+	if (card_cap[pci_id->driver_data].flags & CAP_MMIO) {
+		card->ac97base_mmio_phys = pci_resource_start (pci_dev, 2);
+		card->iobase_mmio_phys = pci_resource_start (pci_dev, 3);
+
+		if ((card->ac97base_mmio_phys) && (card->iobase_mmio_phys)) {
+			card->use_mmio = 1;
+		}
+		else {
+			card->ac97base_mmio_phys = 0;
+			card->iobase_mmio_phys = 0;
+		}
+	}
+
 	card->irq = pci_dev->irq;
 	card->next = devs;
 	card->magic = I810_CARD_MAGIC;
@@ -2905,8 +3151,11 @@
 
 	pci_set_master(pci_dev);
 
-	printk(KERN_INFO "i810: %s found at IO 0x%04lx and 0x%04lx, IRQ %d\n",
-	       card_names[pci_id->driver_data], card->iobase, card->ac97base, 
+	printk(KERN_INFO "i810: %s found at IO 0x%04lx and 0x%04lx, "
+	       "MEM 0x%04lx and 0x%04lx, IRQ %d\n",
+	       card_names[pci_id->driver_data], 
+	       card->iobase, card->ac97base, 
+	       card->ac97base_mmio_phys, card->iobase_mmio_phys,
 	       card->irq);
 
 	card->alloc_pcm_channel = i810_alloc_pcm_channel;
@@ -2941,17 +3190,42 @@
 	if (request_irq(card->irq, &i810_interrupt, SA_SHIRQ,
 			card_names[pci_id->driver_data], card)) {
 		printk(KERN_ERR "i810_audio: unable to allocate irq %d\n", card->irq);
-		release_region(card->iobase, 64);
-		release_region(card->ac97base, 256);
-		goto out_chan;
+		goto out_pio;
+	}
+
+	if (card->use_mmio) {
+		if (request_mem_region(card->ac97base_mmio_phys, 512, "ich_audio MMBAR")) {
+			if ((card->ac97base_mmio = ioremap(card->ac97base_mmio_phys, 512))) { /*@FIXME can ioremap fail? don't know (jsaw) */
+				if (request_mem_region(card->iobase_mmio_phys, 256, "ich_audio MBBAR")) {
+					if ((card->iobase_mmio = ioremap(card->iobase_mmio_phys, 256))) {
+						printk(KERN_INFO "i810: %s mmio at 0x%04lx and 0x%04lx\n",
+						       card_names[pci_id->driver_data], 
+						       (unsigned long) card->ac97base_mmio, 
+						       (unsigned long) card->iobase_mmio); 
+					}
+					else {
+						iounmap(card->ac97base_mmio);
+						release_mem_region(card->ac97base_mmio_phys, 512);
+						release_mem_region(card->iobase_mmio_phys, 512);
+						card->use_mmio = 0;
+					}
+				}
+				else {
+					iounmap(card->ac97base_mmio);
+					release_mem_region(card->ac97base_mmio_phys, 512);
+					card->use_mmio = 0;
+				}
+			}
+		}
+		else {
+			card->use_mmio = 0;
+		}
 	}
 
 	/* initialize AC97 codec and register /dev/mixer */
 	if (i810_ac97_init(card) <= 0) {
-		release_region(card->iobase, 64);
-		release_region(card->ac97base, 256);
 		free_irq(card->irq, card);
-		goto out_chan;
+		goto out_iospace;
 	}
 	pci_set_drvdata(pci_dev, card);
 
@@ -2964,23 +3238,31 @@
 	if ((card->dev_audio = register_sound_dsp(&i810_audio_fops, -1)) < 0) {
 		int i;
 		printk(KERN_ERR "i810_audio: couldn't register DSP device!\n");
-		release_region(card->iobase, 64);
-		release_region(card->ac97base, 256);
 		free_irq(card->irq, card);
 		for (i = 0; i < NR_AC97; i++)
 		if (card->ac97_codec[i] != NULL) {
 			unregister_sound_mixer(card->ac97_codec[i]->dev_mixer);
 			kfree (card->ac97_codec[i]);
 		}
-		goto out_chan;
+		goto out_iospace;
 	}
+
  	card->initializing = 0;
 	return 0;
 
- out_chan:
+out_iospace:
+	if (card->use_mmio) {
+		iounmap(card->ac97base_mmio);
+		iounmap(card->iobase_mmio);
+		release_mem_region(card->ac97base_mmio_phys, 512);
+		release_mem_region(card->iobase_mmio_phys, 256);
+	}
+out_pio:	
+	release_region(card->iobase, 64);
+	release_region(card->ac97base, 256);
 	pci_free_consistent(pci_dev, sizeof(struct i810_channel)*NR_HW_CH,
 	    card->channel, card->chandma);
- out_mem:
+out_mem:
 	kfree(card);
 	return -ENODEV;
 }
@@ -2993,6 +3275,12 @@
 	free_irq(card->irq, devs);
 	release_region(card->iobase, 64);
 	release_region(card->ac97base, 256);
+	if (card->use_mmio) {
+		iounmap(card->ac97base_mmio);
+		iounmap(card->iobase_mmio);
+		release_mem_region(card->ac97base_mmio_phys, 512);
+		release_mem_region(card->iobase_mmio_phys, 256);
+	}
 
 	/* unregister audio devices */
 	for (i = 0; i < NR_AC97; i++)
@@ -3075,7 +3363,7 @@
 	   hardware has to be more or less completely reinitialized from
 	   scratch after an apm suspend.  Works For Me.   -dan */
 
-	i810_ac97_random_init_stuff(card);
+	i810_ac97_power_up_bus(card);
 
 	for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) {
 		struct ac97_codec *codec = card->ac97_codec[num_ac97];
@@ -3160,7 +3448,6 @@
 
 	printk(KERN_INFO "Intel 810 + AC97 Audio, version "
 	       DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
-	printk(KERN_WARNING "This driver is deprecated, please use the ALSA drivers.\n");
 
 	if (!pci_register_driver(&i810_pci_driver)) {
 		pci_unregister_driver(&i810_pci_driver);
diff -Nru a/sound/oss/maui.c b/sound/oss/maui.c
--- a/sound/oss/maui.c	Mon Dec  9 18:46:50 2002
+++ b/sound/oss/maui.c	Mon Dec  9 18:46:50 2002
@@ -24,6 +24,7 @@
  *					* Older versions will cause problems.
  */
 
+#include <linux/interrupt.h>
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/init.h>
diff -Nru a/sound/oss/mpu401.h b/sound/oss/mpu401.h
--- a/sound/oss/mpu401.h	Mon Dec  9 18:46:36 2002
+++ b/sound/oss/mpu401.h	Mon Dec  9 18:46:36 2002
@@ -7,7 +7,7 @@
 
 /*	From mpu401.c */
 int probe_mpu401(struct address_info *hw_config);
-void attach_mpu401(struct address_info * hw_config, struct module *owner);
+int attach_mpu401(struct address_info * hw_config, struct module *owner);
 void unload_mpu401(struct address_info *hw_info);
 
 int intchk_mpu401(void *dev_id);
diff -Nru a/sound/oss/opl3sa2.c b/sound/oss/opl3sa2.c
--- a/sound/oss/opl3sa2.c	Mon Dec  9 18:46:34 2002
+++ b/sound/oss/opl3sa2.c	Mon Dec  9 18:46:34 2002
@@ -841,10 +841,9 @@
 	{.id = ""}
 };
 
-/*MODULE_DEVICE_TABLE(isapnp, isapnp_opl3sa2_list);*/
+MODULE_DEVICE_TABLE(pnp, pnp_opl3sa2_list);
 
-static int opl3sa2_pnp_probe(struct pnp_dev *dev, const struct pnp_id *card_id,
-			     const struct pnp_id *dev_id)
+static int opl3sa2_pnp_probe(struct pnp_dev *dev, const struct pnp_id *dev_id)
 {
 	int card = opl3sa2_cards_num;
 	if (opl3sa2_cards_num == OPL3SA2_CARDS_MAX)
@@ -883,7 +882,6 @@
 
 static struct pnp_driver opl3sa2_driver = {
 	.name		= "opl3sa2",
-	.card_id_table	= NULL,
 	.id_table	= pnp_opl3sa2_list,
 	.probe		= opl3sa2_pnp_probe,
 };
diff -Nru a/sound/oss/sb_ess.c b/sound/oss/sb_ess.c
--- a/sound/oss/sb_ess.c	Mon Dec  9 18:46:36 2002
+++ b/sound/oss/sb_ess.c	Mon Dec  9 18:46:36 2002
@@ -186,6 +186,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/interrupt.h>
 #include <linux/spinlock.h>
 
 #include "sound_config.h"
diff -Nru a/sound/oss/wf_midi.c b/sound/oss/wf_midi.c
--- a/sound/oss/wf_midi.c	Mon Dec  9 18:46:34 2002
+++ b/sound/oss/wf_midi.c	Mon Dec  9 18:46:34 2002
@@ -50,6 +50,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/spinlock.h>
 #include "sound_config.h"
 
diff -Nru a/sound/sound_core.c b/sound/sound_core.c
--- a/sound/sound_core.c	Mon Dec  9 18:46:51 2002
+++ b/sound/sound_core.c	Mon Dec  9 18:46:51 2002
@@ -149,13 +149,11 @@
  *	list. Acquires locks as needed
  */
 
-static devfs_handle_t devfs_handle;
- 
 static int sound_insert_unit(struct sound_unit **list, struct file_operations *fops, int index, int low, int top, const char *name, umode_t mode)
 {
 	int r;
 	struct sound_unit *s=(struct sound_unit *)kmalloc(sizeof(struct sound_unit), GFP_KERNEL);
-	char name_buf[16];
+	char name_buf[32];
 
 	if(s==NULL)
 		return -ENOMEM;
@@ -171,10 +169,10 @@
 	}
 	
 	if (r < SOUND_STEP)
-		sprintf (name_buf, "%s", name);
+		sprintf (name_buf, "sound/%s", name);
 	else
-		sprintf (name_buf, "%s%d", name, r / SOUND_STEP);
-	s->de = devfs_register (devfs_handle, name_buf,
+		sprintf (name_buf, "sound/%s%d", name, r / SOUND_STEP);
+	s->de = devfs_register (NULL, name_buf,
 				DEVFS_FL_NONE, SOUND_MAJOR, s->unit_minor,
 				S_IFCHR | mode, fops, NULL);
 	return r;
@@ -560,7 +558,7 @@
 	/* We have nothing to really do here - we know the lists must be
 	   empty */
 	unregister_chrdev(SOUND_MAJOR, "sound");
-	devfs_unregister (devfs_handle);
+	devfs_remove("sound");
 }
 
 static int __init init_soundcore(void)
@@ -569,7 +567,7 @@
 		printk(KERN_ERR "soundcore: sound device already in use.\n");
 		return -EBUSY;
 	}
-	devfs_handle = devfs_mk_dir (NULL, "sound", NULL);
+	devfs_mk_dir (NULL, "sound", NULL);
 
 	return 0;
 }
diff -Nru a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
--- a/sound/sparc/cs4231.c	Mon Dec  9 18:46:34 2002
+++ b/sound/sparc/cs4231.c	Mon Dec  9 18:46:34 2002
@@ -314,9 +314,8 @@
 };
 
 static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
-	count: 14,
-	list: rates,
-	mask: 0,
+	.count	= 14,
+	.list	= rates,
 };
 
 static int snd_cs4231_xrate(snd_pcm_runtime_t *runtime)
@@ -1418,44 +1417,42 @@
 
 static snd_pcm_hardware_t snd_cs4231_playback =
 {
-	info:			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+	.info			= (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START),
-	formats:		(SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
+	.formats		= (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
 				 SNDRV_PCM_FMTBIT_IMA_ADPCM |
 				 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
 				 SNDRV_PCM_FMTBIT_S16_BE),
-	rates:			SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
-	rate_min:		5510,
-	rate_max:		48000,
-	channels_min:		1,
-	channels_max:		2,
-	buffer_bytes_max:	(32*1024),
-	period_bytes_min:	4096,
-	period_bytes_max:	(32*1024),
-	periods_min:		1,
-	periods_max:		1024,
-	fifo_size:		0,
+	.rates			= SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
+	.rate_min		= 5510,
+	.rate_max		= 48000,
+	.channels_min		= 1,
+	.channels_max		= 2,
+	.buffer_bytes_max	= (32*1024),
+	.period_bytes_min	= 4096,
+	.period_bytes_max	= (32*1024),
+	.periods_min		= 1,
+	.periods_max		= 1024,
 };
 
 static snd_pcm_hardware_t snd_cs4231_capture =
 {
-	info:			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+	.info			= (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START),
-	formats:		(SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
+	.formats		= (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
 				 SNDRV_PCM_FMTBIT_IMA_ADPCM |
 				 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
 				 SNDRV_PCM_FMTBIT_S16_BE),
-	rates:			SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
-	rate_min:		5510,
-	rate_max:		48000,
-	channels_min:		1,
-	channels_max:		2,
-	buffer_bytes_max:	(32*1024),
-	period_bytes_min:	4096,
-	period_bytes_max:	(32*1024),
-	periods_min:		1,
-	periods_max:		1024,
-	fifo_size:		0,
+	.rates			= SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
+	.rate_min		= 5510,
+	.rate_max		= 48000,
+	.channels_min		= 1,
+	.channels_max		= 2,
+	.buffer_bytes_max	= (32*1024),
+	.period_bytes_min	= 4096,
+	.period_bytes_max	= (32*1024),
+	.periods_min		= 1,
+	.periods_max		= 1024,
 };
 
 static int snd_cs4231_playback_open(snd_pcm_substream_t *substream)
@@ -1821,16 +1818,16 @@
 #define CS4231_CONTROLS (sizeof(snd_cs4231_controls)/sizeof(snd_kcontrol_new_t))
 
 #define CS4231_SINGLE(xname, xindex, reg, shift, mask, invert) \
-{ iface: SNDRV_CTL_ELEM_IFACE_MIXER, name: xname, index: xindex, \
-  info: snd_cs4231_info_single, \
-  get: snd_cs4231_get_single, put: snd_cs4231_put_single, \
-  private_value: reg | (shift << 8) | (mask << 16) | (invert << 24) }
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
+  .info = snd_cs4231_info_single, \
+  .get = snd_cs4231_get_single, .put = snd_cs4231_put_single, \
+  .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
 
 #define CS4231_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
-{ iface: SNDRV_CTL_ELEM_IFACE_MIXER, name: xname, index: xindex, \
-  info: snd_cs4231_info_double, \
-  get: snd_cs4231_get_double, put: snd_cs4231_put_double, \
-  private_value: left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
+  .info = snd_cs4231_info_double, \
+  .get = snd_cs4231_get_double, .put = snd_cs4231_put_double, \
+  .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
 
 static snd_kcontrol_new_t snd_cs4231_controls[] = {
 CS4231_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
@@ -1847,11 +1844,11 @@
 CS4231_SINGLE("Mono Output Playback Bypass", 0, CS4231_MONO_CTRL, 5, 1, 0),
 CS4231_DOUBLE("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0),
 {
-	iface: SNDRV_CTL_ELEM_IFACE_MIXER,
-	name: "Capture Source",
-	info: snd_cs4231_info_mux,
-	get: snd_cs4231_get_mux,
-	put: snd_cs4231_put_mux,
+	.iface	= SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name	= "Capture Source",
+	.info	= snd_cs4231_info_mux,
+	.get	= snd_cs4231_get_mux,
+	.put	= snd_cs4231_put_mux,
 },
 CS4231_DOUBLE("Mic Boost", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
 CS4231_SINGLE("Loopback Capture Switch", 0, CS4231_LOOPBACK, 0, 1, 0),
diff -Nru a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
--- a/sound/usb/usbmidi.c	Mon Dec  9 18:46:51 2002
+++ b/sound/usb/usbmidi.c	Mon Dec  9 18:46:51 2002
@@ -168,7 +168,7 @@
 /*
  * Processes the data read from the device.
  */
-static void snd_usbmidi_in_urb_complete(struct urb* urb)
+static void snd_usbmidi_in_urb_complete(struct urb* urb, struct pt_regs *regs)
 {
 	snd_usb_midi_in_endpoint_t* ep = snd_magic_cast(snd_usb_midi_in_endpoint_t, urb->context, return);
 
@@ -191,7 +191,7 @@
 /*
  * Converts the data read from a Midiman device to standard USB MIDI packets.
  */
-static void snd_usbmidi_in_midiman_complete(struct urb* urb)
+static void snd_usbmidi_in_midiman_complete(struct urb* urb, struct pt_regs *regs)
 {
 	if (urb->status == 0) {
 		uint8_t* buffer = (uint8_t*)urb->transfer_buffer;
@@ -217,10 +217,10 @@
 			}
 		}
 	}
-	snd_usbmidi_in_urb_complete(urb);
+	snd_usbmidi_in_urb_complete(urb, regs);
 }
 
-static void snd_usbmidi_out_urb_complete(struct urb* urb)
+static void snd_usbmidi_out_urb_complete(struct urb* urb, struct pt_regs *regs)
 {
 	snd_usb_midi_out_endpoint_t* ep = snd_magic_cast(snd_usb_midi_out_endpoint_t, urb->context, return);
 
